@@ -16,10 +16,6 @@ final class SDAMTests: MongoSwiftTestCase {
1616 expect ( desc. passives) . to ( haveCount ( 0 ) )
1717 }
1818
19- func checkUnknownServerType( _ desc: ServerDescription ) {
20- expect ( desc. type) . to ( equal ( ServerDescription . ServerType. unknown) )
21- }
22-
2319 // Basic test based on the "standalone" spec test for SDAM monitoring:
2420 // swiftlint:disable line_length
2521 // https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/tests/monitoring/standalone.json
@@ -51,54 +47,100 @@ final class SDAMTests: MongoSwiftTestCase {
5147 }
5248 let hostAddress = try ServerAddress ( host)
5349
54- // check event count and that events are of the expected types
55- expect ( receivedEvents. count) . to ( beGreaterThanOrEqualTo ( 5 ) )
50+ expect ( receivedEvents. count) . to ( equal ( 4 ) )
5651 expect ( receivedEvents [ 0 ] . topologyOpeningValue) . toNot ( beNil ( ) )
57- expect ( receivedEvents [ 1 ] . topologyDescriptionChangedValue) . toNot ( beNil ( ) )
58- expect ( receivedEvents [ 2 ] . serverOpeningValue) . toNot ( beNil ( ) )
59- expect ( receivedEvents [ 3 ] . serverDescriptionChangedValue) . toNot ( beNil ( ) )
60- expect ( receivedEvents [ 4 ] . topologyDescriptionChangedValue) . toNot ( beNil ( ) )
52+ expect ( receivedEvents [ 1 ] . serverOpeningValue) . toNot ( beNil ( ) )
53+ expect ( receivedEvents [ 2 ] . serverDescriptionChangedValue) . toNot ( beNil ( ) )
54+ expect ( receivedEvents [ 3 ] . topologyDescriptionChangedValue) . toNot ( beNil ( ) )
6155
62- // verify that data in ServerDescription and TopologyDescription looks reasonable
6356 let event0 = receivedEvents [ 0 ] . topologyOpeningValue!
64- expect ( event0. topologyID) . toNot ( beNil ( ) )
6557
66- let event1 = receivedEvents [ 1 ] . topologyDescriptionChangedValue !
58+ let event1 = receivedEvents [ 1 ] . serverOpeningValue !
6759 expect ( event1. topologyID) . to ( equal ( event0. topologyID) )
68- expect ( event1. previousDescription. type) . to ( equal ( TopologyDescription . TopologyType. unknown) )
69- expect ( event1. newDescription. type) . to ( equal ( TopologyDescription . TopologyType. single) )
70- // This is a bit of a deviation from the SDAM spec tests linked above. However, this is how mongoc responds so
71- // there is no other way to get around this.
72- expect ( event1. newDescription. servers) . to ( beEmpty ( ) )
60+ expect ( event1. serverAddress) . to ( equal ( hostAddress) )
7361
74- let event2 = receivedEvents [ 2 ] . serverOpeningValue !
62+ let event2 = receivedEvents [ 2 ] . serverDescriptionChangedValue !
7563 expect ( event2. topologyID) . to ( equal ( event1. topologyID) )
76- expect ( event2. serverAddress) . to ( equal ( hostAddress) )
7764
78- let event3 = receivedEvents [ 3 ] . serverDescriptionChangedValue!
79- expect ( event3. topologyID) . to ( equal ( event2. topologyID) )
80- let prevServer = event3. previousDescription
81- expect ( prevServer. address) . to ( equal ( hostAddress) )
82- self . checkEmptyLists ( prevServer)
83- self . checkUnknownServerType ( prevServer)
65+ let prevServer = event2. previousDescription
66+ let newServer = event2. newDescription
8467
85- let newServer = event3 . newDescription
68+ expect ( prevServer . address ) . to ( equal ( hostAddress ) )
8669 expect ( newServer. address) . to ( equal ( hostAddress) )
70+
71+ self . checkEmptyLists ( prevServer)
8772 self . checkEmptyLists ( newServer)
88- expect ( newServer. type) . to ( equal ( ServerDescription . ServerType. standalone) )
8973
90- let event4 = receivedEvents [ 4 ] . topologyDescriptionChangedValue!
91- expect ( event4. topologyID) . to ( equal ( event3. topologyID) )
92- let prevTopology = event4. previousDescription
93- expect ( prevTopology. type) . to ( equal ( TopologyDescription . TopologyType. single) )
74+ expect ( prevServer. type) . to ( equal ( . unknown) )
75+ expect ( newServer. type) . to ( equal ( . standalone) )
76+
77+ let event3 = receivedEvents [ 3 ] . topologyDescriptionChangedValue!
78+ expect ( event3. topologyID) . to ( equal ( event2. topologyID) )
79+
80+ let prevTopology = event3. previousDescription
81+ let newTopology = event3. newDescription
82+
83+ expect ( prevTopology. type) . to ( equal ( . unknown) )
84+ expect ( newTopology. type) . to ( equal ( . single) )
85+
9486 expect ( prevTopology. servers) . to ( beEmpty ( ) )
87+ expect ( newTopology. servers) . to ( haveCount ( 1 ) )
9588
96- let newTopology = event4. newDescription
97- expect ( newTopology. type) . to ( equal ( TopologyDescription . TopologyType. single) )
9889 expect ( newTopology. servers [ 0 ] . address) . to ( equal ( hostAddress) )
99- expect ( newTopology. servers [ 0 ] . type) . to ( equal ( ServerDescription . ServerType. standalone) )
90+ expect ( newTopology. servers [ 0 ] . type) . to ( equal ( . standalone) )
91+
10092 self . checkEmptyLists ( newTopology. servers [ 0 ] )
10193 }
94+
95+ func testInitialReplicaSetDiscovery( ) throws {
96+ guard MongoSwiftTestCase . topologyType == . replicaSetWithPrimary else {
97+ print ( unsupportedTopologyMessage ( testName: self . name) )
98+ return
99+ }
100+
101+ let hostURIs = Self . getConnectionStringPerHost ( )
102+
103+ let optsFalse = MongoClientOptions ( directConnection: false )
104+ let optsTrue = MongoClientOptions ( directConnection: true )
105+
106+ // We should succeed in discovering the primary in all of these cases:
107+ let testClientsShouldSucceed = try
108+ hostURIs. map { try MongoClient . makeTestClient ( $0) } + // option unspecified
109+ hostURIs. map { try MongoClient . makeTestClient ( " \( $0) &directConnection=false " ) } + // false in URI
110+ hostURIs. map { try MongoClient . makeTestClient ( $0, options: optsFalse) } // false in options struct
111+
112+ // separately connect to each host and verify we are able to perform a write, meaning
113+ // that the primary is successfully discovered no matter which host we start with
114+ for client in testClientsShouldSucceed {
115+ try withTestNamespace ( client: client) { _, collection in
116+ expect ( try collection. insertOne ( [ " x " : 1 ] ) ) . toNot ( throwError ( ) )
117+ }
118+ }
119+
120+ let testClientsShouldMostlyFail = try
121+ hostURIs. map { try MongoClient . makeTestClient ( " \( $0) &directConnection=true " ) } + // true in URI
122+ hostURIs. map { try MongoClient . makeTestClient ( $0, options: optsTrue) } // true in options struct
123+
124+ // 4 of 6 attempts to perform writes should fail assuming these are 3-node replica sets, since in 2 cases we
125+ // will directly connect to the primary, and in the other 4 we will directly connect to a secondary.
126+
127+ var failures = 0
128+ for client in testClientsShouldMostlyFail {
129+ do {
130+ _ = try withTestNamespace ( client: client) { _, collection in
131+ try collection. insertOne ( [ " x " : 1 ] )
132+ }
133+ } catch {
134+ expect ( error) . to ( beAnInstanceOf ( MongoError . CommandError. self) )
135+ failures += 1
136+ }
137+ }
138+
139+ expect ( failures) . to (
140+ equal ( 4 ) ,
141+ description: " Writes should fail when connecting to secondaries with directConnection=true "
142+ )
143+ }
102144}
103145
104146/// SDAM monitoring event handler that behaves similarly to the `TestCommandMonitor`
0 commit comments