PageRenderTime 107ms CodeModel.GetById 25ms RepoModel.GetById 1ms app.codeStats 0ms

/tests/MongoDB.Driver.Core.Tests/Core/Clusters/MultiServerClusterTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 1225 lines | 997 code | 212 blank | 16 comment | 2 complexity | 7ab95e79abc2ea4b459d630980aaa26b MD5 | raw file
Possible License(s): Apache-2.0

Large files files are truncated, but you can click here to view the full file

  1. /* Copyright 2013-present MongoDB Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. using System;
  16. using System.Collections.Generic;
  17. using System.Linq;
  18. using System.Net;
  19. using System.Threading;
  20. using FluentAssertions;
  21. using MongoDB.Bson.TestHelpers;
  22. using MongoDB.Driver.Core.Configuration;
  23. using MongoDB.Driver.Core.Events;
  24. using MongoDB.Driver.Core.Misc;
  25. using MongoDB.Driver.Core.Servers;
  26. using MongoDB.Driver.Core.Helpers;
  27. using Moq;
  28. using Xunit;
  29. using MongoDB.Bson;
  30. using MongoDB.Driver.Core.Tests.Core.Clusters;
  31. using System.Threading.Tasks;
  32. namespace MongoDB.Driver.Core.Clusters
  33. {
  34. public class MultiServerClusterTests
  35. {
  36. private EventCapturer _capturedEvents;
  37. private MockClusterableServerFactory _serverFactory;
  38. private ClusterSettings _settings;
  39. private EndPoint _firstEndPoint = new DnsEndPoint("localhost", 27017);
  40. private EndPoint _secondEndPoint = new DnsEndPoint("localhost", 27018);
  41. private EndPoint _thirdEndPoint = new DnsEndPoint("localhost", 27019);
  42. private IEqualityComparer<ServerDescription> _serverDescriptionComparer = ServerDescriptionWithSimilarLastUpdateTimestampEqualityComparer.Instance;
  43. public MultiServerClusterTests()
  44. {
  45. _settings = new ClusterSettings();
  46. _serverFactory = new MockClusterableServerFactory();
  47. _capturedEvents = new EventCapturer();
  48. }
  49. [Fact]
  50. public void constructor_should_initialize_instance()
  51. {
  52. var settings = new ClusterSettings(replicaSetName: "rs");
  53. var serverFactory = Mock.Of<IClusterableServerFactory>();
  54. var mockEventSubscriber = new Mock<IEventSubscriber>();
  55. var dnsMonitorFactory = Mock.Of<IDnsMonitorFactory>();
  56. var result = new MultiServerCluster(settings, serverFactory, mockEventSubscriber.Object, dnsMonitorFactory);
  57. result._dnsMonitorFactory().Should().BeSameAs(dnsMonitorFactory);
  58. result._eventSubscriber().Should().BeSameAs(mockEventSubscriber.Object);
  59. result._replicaSetName().Should().BeSameAs(settings.ReplicaSetName);
  60. result._state().Value.Should().Be(0); // State.Initial
  61. AssertTryGetEventHandlerWasCalled<ClusterClosingEvent>(mockEventSubscriber);
  62. AssertTryGetEventHandlerWasCalled<ClusterClosedEvent>(mockEventSubscriber);
  63. AssertTryGetEventHandlerWasCalled<ClusterOpeningEvent>(mockEventSubscriber);
  64. AssertTryGetEventHandlerWasCalled<ClusterOpenedEvent>(mockEventSubscriber);
  65. AssertTryGetEventHandlerWasCalled<ClusterAddingServerEvent>(mockEventSubscriber);
  66. AssertTryGetEventHandlerWasCalled<ClusterAddedServerEvent>(mockEventSubscriber);
  67. AssertTryGetEventHandlerWasCalled<ClusterRemovingServerEvent>(mockEventSubscriber);
  68. AssertTryGetEventHandlerWasCalled<ClusterRemovedServerEvent>(mockEventSubscriber);
  69. AssertTryGetEventHandlerWasCalled<SdamInformationEvent>(mockEventSubscriber);
  70. }
  71. [Fact]
  72. public void Constructor_should_throw_if_no_endpoints_are_specified()
  73. {
  74. var settings = new ClusterSettings(endPoints: new EndPoint[0]);
  75. Action act = () => new MultiServerCluster(settings, _serverFactory, _capturedEvents);
  76. act.ShouldThrow<ArgumentOutOfRangeException>();
  77. }
  78. [Theory]
  79. [InlineData(ClusterConnectionMode.Direct)]
  80. [InlineData(ClusterConnectionMode.Standalone)]
  81. public void Constructor_should_throw_if_cluster_connection_mode_is_not_supported(ClusterConnectionMode mode)
  82. {
  83. var settings = new ClusterSettings(
  84. endPoints: new[] { new DnsEndPoint("localhost", 27017) },
  85. connectionMode: mode);
  86. Action act = () => new MultiServerCluster(settings, _serverFactory, _capturedEvents);
  87. act.ShouldThrow<ArgumentException>();
  88. }
  89. [Fact]
  90. public void constructor_should_use_default_DnsMonitorFactory_when_dnsMonitorFactory_is_null()
  91. {
  92. var settings = new ClusterSettings();
  93. var serverFactory = Mock.Of<IClusterableServerFactory>();
  94. var eventSubscriber = Mock.Of<IEventSubscriber>();
  95. var result = new MultiServerCluster(settings, serverFactory, eventSubscriber, dnsMonitorFactory: null);
  96. var dnsMonitorFactory = result._dnsMonitorFactory().Should().BeOfType<DnsMonitorFactory>().Subject;
  97. dnsMonitorFactory._eventSubscriber().Should().BeSameAs(eventSubscriber);
  98. }
  99. [Fact]
  100. public void Description_should_be_correct_after_initialization()
  101. {
  102. _settings = _settings.With(endPoints: new[] { _firstEndPoint });
  103. var subject = CreateSubject();
  104. subject.Initialize();
  105. var description = subject.Description;
  106. description.State.Should().Be(ClusterState.Disconnected);
  107. description.Type.Should().Be(ClusterType.Unknown);
  108. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint), _serverDescriptionComparer);
  109. _capturedEvents.Next().Should().BeOfType<ClusterOpeningEvent>();
  110. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  111. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  112. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  113. _capturedEvents.Next().Should().BeOfType<ClusterOpenedEvent>();
  114. _capturedEvents.Any().Should().BeFalse();
  115. }
  116. [Fact]
  117. public void Initialize_should_throw_when_already_disposed()
  118. {
  119. _settings = _settings.With(endPoints: new[] { _firstEndPoint });
  120. var subject = CreateSubject();
  121. subject.Dispose();
  122. Action act = () => subject.Initialize();
  123. act.ShouldThrow<ObjectDisposedException>();
  124. }
  125. [Fact]
  126. public void Initialize_should_call_base_Initialize()
  127. {
  128. using (var subject = CreateSubject())
  129. {
  130. subject.Initialize();
  131. // if the base class's _state changed from 0 to 1 that is evidence that base.Initialize was called
  132. var subjectBase = (Cluster)subject;
  133. subjectBase._state().Value.Should().Be(1); // State.Open
  134. }
  135. }
  136. [Fact]
  137. public void Initialize_should_change_state_to_Open()
  138. {
  139. using (var subject = CreateSubject())
  140. {
  141. subject.Initialize();
  142. subject._state().Value.Should().Be(1); // State.Open
  143. }
  144. }
  145. [Fact]
  146. public void Initialize_should_raise_ClusterOpeningEvent()
  147. {
  148. using (var subject = CreateSubject())
  149. {
  150. subject.Initialize();
  151. var clusterOpeningEvent = ShouldHaveOneEventOfType<ClusterOpeningEvent>(_capturedEvents);
  152. clusterOpeningEvent.ClusterId.Should().Be(subject.Description.ClusterId);
  153. clusterOpeningEvent.ClusterSettings.Should().BeSameAs(subject.Settings);
  154. }
  155. }
  156. [Fact]
  157. public void Initialize_should_raise_ClusterAddingServerEvent()
  158. {
  159. using (var subject = CreateSubject())
  160. {
  161. subject.Initialize();
  162. var clusterAddingServerEvent = ShouldHaveOneEventOfType<ClusterAddingServerEvent>(_capturedEvents);
  163. clusterAddingServerEvent.ClusterId.Should().Be(subject.Description.ClusterId);
  164. clusterAddingServerEvent.EndPoint.Should().Be(subject.Settings.EndPoints[0]);
  165. }
  166. }
  167. [Fact]
  168. public void Initialize_should_raise_ClusterAddedServerEvent()
  169. {
  170. using (var subject = CreateSubject())
  171. {
  172. subject.Initialize();
  173. var clusterAddedServerEvent = ShouldHaveOneEventOfType<ClusterAddedServerEvent>(_capturedEvents);
  174. clusterAddedServerEvent.ClusterId.Should().Be(subject.Description.ClusterId);
  175. TimeSpanShouldBeShort(clusterAddedServerEvent.Duration);
  176. }
  177. }
  178. [Fact]
  179. public void Initialize_should_raise_ClusterDescriptionChangedEvent()
  180. {
  181. using (var subject = CreateSubject())
  182. {
  183. subject.Initialize();
  184. var clusterDescriptionChangedEvent = ShouldHaveOneEventOfType<ClusterDescriptionChangedEvent>(_capturedEvents);
  185. var oldClusterDescription = clusterDescriptionChangedEvent.OldDescription;
  186. var newClusterDescription = clusterDescriptionChangedEvent.NewDescription;
  187. oldClusterDescription.Servers.Should().HaveCount(0);
  188. newClusterDescription.Servers.Should().HaveCount(1);
  189. var newServer = newClusterDescription.Servers[0];
  190. newServer.EndPoint.Should().Be(subject.Settings.EndPoints[0]);
  191. }
  192. }
  193. [Fact]
  194. public void Initialize_should_raise_ClusterOpenedEvent()
  195. {
  196. using (var subject = CreateSubject())
  197. {
  198. subject.Initialize();
  199. var clusterOpenedEvent = ShouldHaveOneEventOfType<ClusterOpenedEvent>(_capturedEvents);
  200. clusterOpenedEvent.ClusterId.Should().Be(subject.Description.ClusterId);
  201. clusterOpenedEvent.ClusterSettings.Should().BeSameAs(subject.Settings);
  202. TimeSpanShouldBeShort(clusterOpenedEvent.Duration);
  203. }
  204. }
  205. [Fact]
  206. public void Initialize_should_raise_expected_events()
  207. {
  208. using (var subject = CreateSubject())
  209. {
  210. subject.Initialize();
  211. var eventTypes = _capturedEvents.Events.Select(e => e.GetType()).ToList();
  212. var expectedEventTypes = new[]
  213. {
  214. typeof(ClusterOpeningEvent),
  215. typeof(ClusterAddingServerEvent),
  216. typeof(ClusterAddedServerEvent),
  217. typeof(ClusterDescriptionChangedEvent),
  218. typeof(ClusterOpenedEvent),
  219. };
  220. eventTypes.Should().Equal(expectedEventTypes);
  221. }
  222. }
  223. [Fact]
  224. public void Initialize_should_initialize_all_servers()
  225. {
  226. using (var subject = CreateSubject())
  227. {
  228. subject.Initialize();
  229. foreach (var server in subject._servers())
  230. {
  231. var mockServer = Mock.Get<IClusterableServer>(server);
  232. mockServer.Verify(m => m.Initialize(), Times.Once);
  233. }
  234. }
  235. }
  236. [Fact]
  237. public void Initialize_should_not_start_dns_monitor_thread_when_scheme_is_MongoDB()
  238. {
  239. using (var subject = CreateSubject())
  240. {
  241. subject.Initialize();
  242. subject._dnsMonitorThread().Should().BeNull();
  243. }
  244. }
  245. [Fact]
  246. public void Initialize_should_start_dns_monitor_thread_when_scheme_is_MongoDBPlusSrv()
  247. {
  248. var settings = new ClusterSettings(
  249. scheme: ConnectionStringScheme.MongoDBPlusSrv,
  250. endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  251. using (var subject = CreateSubject(settings))
  252. {
  253. subject.Initialize();
  254. subject._dnsMonitorThread().Should().NotBeNull();
  255. }
  256. }
  257. [Theory]
  258. [InlineData(-1, -1, ClusterType.Standalone, ServerType.ReplicaSetArbiter, false)]
  259. [InlineData(-1, -1, ClusterType.Standalone, ServerType.ReplicaSetGhost, false)]
  260. [InlineData(-1, -1, ClusterType.Standalone, ServerType.ReplicaSetOther, false)]
  261. [InlineData(-1, -1, ClusterType.Standalone, ServerType.ReplicaSetPrimary, false)]
  262. [InlineData(-1, -1, ClusterType.Standalone, ServerType.ReplicaSetSecondary, false)]
  263. [InlineData(-1, -1, ClusterType.Standalone, ServerType.ShardRouter, false)]
  264. [InlineData(-1, -1, ClusterType.Standalone, ServerType.Standalone, true)]
  265. [InlineData(-1, -1, ClusterType.Standalone, ServerType.Unknown, false)]
  266. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.ReplicaSetArbiter, true)]
  267. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.ReplicaSetGhost, true)]
  268. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.ReplicaSetOther, true)]
  269. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.ReplicaSetPrimary, true)]
  270. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.ReplicaSetSecondary, true)]
  271. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.ShardRouter, false)]
  272. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.Standalone, false)]
  273. [InlineData(-1, -1, ClusterType.ReplicaSet, ServerType.Unknown, false)]
  274. [InlineData(-1, -1, ClusterType.Sharded, ServerType.ReplicaSetArbiter, false)]
  275. [InlineData(-1, -1, ClusterType.Sharded, ServerType.ReplicaSetGhost, false)]
  276. [InlineData(-1, -1, ClusterType.Sharded, ServerType.ReplicaSetOther, false)]
  277. [InlineData(-1, -1, ClusterType.Sharded, ServerType.ReplicaSetPrimary, false)]
  278. [InlineData(-1, -1, ClusterType.Sharded, ServerType.ReplicaSetSecondary, false)]
  279. [InlineData(-1, -1, ClusterType.Sharded, ServerType.ShardRouter, true)]
  280. [InlineData(-1, -1, ClusterType.Sharded, ServerType.Standalone, false)]
  281. [InlineData(-1, -1, ClusterType.Sharded, ServerType.Unknown, false)]
  282. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.ReplicaSetArbiter, true)]
  283. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.ReplicaSetGhost, true)]
  284. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.ReplicaSetOther, true)]
  285. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.ReplicaSetPrimary, true)]
  286. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.ReplicaSetSecondary, true)]
  287. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.ShardRouter, true)]
  288. [InlineData(ConnectionStringScheme.MongoDB, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.Standalone, false)]
  289. [InlineData(ConnectionStringScheme.MongoDBPlusSrv, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.Standalone, true)]
  290. [InlineData(-1, ClusterConnectionMode.Automatic, ClusterType.Unknown, ServerType.Unknown, false)]
  291. public void IsServerValidForCluster_should_return_expected_result(ConnectionStringScheme scheme, ClusterConnectionMode connectionMode, ClusterType clusterType, ServerType serverType, bool expectedResult)
  292. {
  293. var settings = new ClusterSettings(scheme: scheme);
  294. using (var subject = CreateSubject(settings: settings))
  295. {
  296. var result = subject.IsServerValidForCluster(clusterType, connectionMode, serverType);
  297. result.Should().Be(expectedResult);
  298. }
  299. }
  300. [Theory]
  301. [InlineData(-1, ClusterConnectionMode.Automatic)]
  302. [InlineData(ClusterType.Unknown, -1)]
  303. public void IsServerValidForCluster_should_throw_when_any_argument_value_is_unexpected(ClusterType clusterType, ClusterConnectionMode connectionMode)
  304. {
  305. using (var subject = CreateSubject())
  306. {
  307. var exception = Record.Exception(() => subject.IsServerValidForCluster(clusterType, connectionMode, ServerType.Unknown));
  308. exception.Should().BeOfType<MongoInternalException>();
  309. }
  310. }
  311. [Fact]
  312. public void ProcessStandaloneChange_should_not_remove_server_when_type_is_unknown()
  313. {
  314. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  315. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  316. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  317. {
  318. subject.Initialize();
  319. PublishDnsResults(subject, _firstEndPoint);
  320. PublishDescription(subject, _firstEndPoint, ServerType.Standalone);
  321. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint);
  322. PublishDisconnectedDescription(subject, _firstEndPoint);
  323. subject.Description.Type.Should().Be(ClusterType.Standalone);
  324. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint);
  325. }
  326. }
  327. [Theory]
  328. [InlineData(0)]
  329. [InlineData(1)]
  330. [InlineData(2)]
  331. public void ProcessStandaloneChange_should_remove_all_other_servers_when_one_server_is_discovered_to_be_a_standalone(int standaloneIndex)
  332. {
  333. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  334. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  335. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  336. {
  337. subject.Initialize();
  338. var endPoints = new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint };
  339. var standAloneEndpoint = endPoints[standaloneIndex];
  340. PublishDnsResults(subject, endPoints);
  341. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(endPoints);
  342. PublishDescription(subject, standAloneEndpoint, ServerType.Standalone);
  343. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(standAloneEndpoint);
  344. }
  345. }
  346. [Fact]
  347. public void ProcessStandaloneChange_should_remove_only_server_when_it_is_no_longer_a_standalone()
  348. {
  349. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  350. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  351. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  352. {
  353. subject.Initialize();
  354. PublishDnsResults(subject, _firstEndPoint);
  355. PublishDescription(subject, _firstEndPoint, ServerType.Standalone);
  356. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint);
  357. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary);
  358. subject.Description.Servers.Should().HaveCount(0);
  359. }
  360. }
  361. [Fact]
  362. public void ProcessDnsException_should_update_cluster_description()
  363. {
  364. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  365. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  366. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  367. {
  368. subject.Initialize();
  369. var exception = new Exception("Dns exception");
  370. PublishDnsException(subject, exception);
  371. subject.Description.DnsMonitorException.Should().BeSameAs(exception);
  372. }
  373. }
  374. [Fact]
  375. public void ProcessDnsResults_should_ignore_empty_end_points_list()
  376. {
  377. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  378. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  379. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  380. {
  381. subject.Initialize();
  382. var endPoints = new EndPoint[0];
  383. var originalDescription = subject.Description;
  384. PublishDnsResults(subject, endPoints);
  385. subject.Description.Should().BeSameAs(originalDescription);
  386. }
  387. }
  388. [Fact]
  389. public void ProcessDnsResults_should_add_missing_servers()
  390. {
  391. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  392. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  393. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  394. {
  395. subject.Initialize();
  396. PublishDnsResults(subject, _firstEndPoint);
  397. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint);
  398. PublishDnsResults(subject, _firstEndPoint, _secondEndPoint);
  399. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint, _secondEndPoint);
  400. }
  401. }
  402. [Fact]
  403. public void ProcessDnsResults_should_remove_extra_servers()
  404. {
  405. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  406. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  407. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  408. {
  409. subject.Initialize();
  410. PublishDnsResults(subject, _firstEndPoint, _secondEndPoint);
  411. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint, _secondEndPoint);
  412. PublishDnsResults(subject, _firstEndPoint);
  413. subject.Description.Servers.Select(s => s.EndPoint).Should().Equal(_firstEndPoint);
  414. }
  415. }
  416. [Fact]
  417. public void ProcessDnsResults_should_clear_dns_monitor_exception()
  418. {
  419. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  420. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  421. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  422. {
  423. subject.Initialize();
  424. var exception = new Exception("Dns exception");
  425. PublishDnsException(subject, exception);
  426. subject.Description.DnsMonitorException.Should().BeSameAs(exception);
  427. PublishDnsResults(subject, _firstEndPoint);
  428. subject.Description.DnsMonitorException.Should().BeNull();
  429. }
  430. }
  431. [Theory]
  432. [InlineData(1)]
  433. [InlineData(2)]
  434. [InlineData(3)]
  435. public void ProcessDnsResults_should_call_Initialize_on_added_servers(int numberOfServers)
  436. {
  437. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  438. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  439. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  440. {
  441. subject.Initialize();
  442. var endPoints = new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint }.Take(numberOfServers).ToArray();
  443. PublishDnsResults(subject, endPoints);
  444. foreach (var server in subject._servers())
  445. {
  446. var mockServer = Mock.Get<IClusterableServer>(server);
  447. mockServer.Verify(m => m.Initialize(), Times.Once);
  448. }
  449. }
  450. }
  451. [Theory]
  452. [InlineData(ServerType.Unknown, ClusterType.Unknown, false)]
  453. [InlineData(ServerType.Standalone, ClusterType.Standalone, true)]
  454. [InlineData(ServerType.ReplicaSetPrimary, ClusterType.ReplicaSet, true)]
  455. [InlineData(ServerType.ShardRouter, ClusterType.Sharded, false)]
  456. public void ShouldMonitorStop_should_return_expected_result(ServerType serverType, ClusterType clusterType, bool expectedResult)
  457. {
  458. var settings = new ClusterSettings(scheme: ConnectionStringScheme.MongoDBPlusSrv, endPoints: new[] { new DnsEndPoint("a.b.com", 53) });
  459. var mockDnsMonitorFactory = CreateMockDnsMonitorFactory();
  460. using (var subject = CreateSubject(settings: settings, dnsMonitorFactory: mockDnsMonitorFactory.Object))
  461. {
  462. subject.Initialize();
  463. PublishDnsResults(subject, _firstEndPoint);
  464. PublishDescription(subject, _firstEndPoint, serverType);
  465. subject.Description.Type.Should().Be(clusterType);
  466. var result = ((IDnsMonitoringCluster)subject).ShouldDnsMonitorStop();
  467. result.Should().Be(expectedResult);
  468. }
  469. }
  470. [Fact]
  471. public void Should_discover_all_servers_in_the_cluster_reported_by_the_primary()
  472. {
  473. _settings = _settings.With(endPoints: new[] { _firstEndPoint });
  474. var subject = CreateSubject();
  475. subject.Initialize();
  476. _capturedEvents.Clear();
  477. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary);
  478. var description = subject.Description;
  479. description.State.Should().Be(ClusterState.Connected);
  480. description.Type.Should().Be(ClusterType.ReplicaSet);
  481. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  482. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  483. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  484. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  485. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  486. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  487. _capturedEvents.Any().Should().BeFalse();
  488. }
  489. [Fact]
  490. public void Should_discover_all_servers_in_the_cluster_when_notified_by_a_secondary()
  491. {
  492. _settings = _settings.With(endPoints: new[] { _firstEndPoint });
  493. var subject = CreateSubject();
  494. subject.Initialize();
  495. _capturedEvents.Clear();
  496. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetSecondary);
  497. var description = subject.Description;
  498. description.State.Should().Be(ClusterState.Connected);
  499. description.Type.Should().Be(ClusterType.ReplicaSet);
  500. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  501. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  502. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  503. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  504. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  505. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  506. _capturedEvents.Any().Should().BeFalse();
  507. }
  508. [Fact]
  509. public void Should_remove_a_server_that_is_no_longer_in_the_primary_host_list()
  510. {
  511. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  512. var subject = CreateSubject();
  513. subject.Initialize();
  514. _capturedEvents.Clear();
  515. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary,
  516. hosts: new[] { _firstEndPoint, _secondEndPoint });
  517. var description = subject.Description;
  518. description.State.Should().Be(ClusterState.Connected);
  519. description.Type.Should().Be(ClusterType.ReplicaSet);
  520. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint), _serverDescriptionComparer);
  521. _capturedEvents.Next().Should().BeOfType<ClusterRemovingServerEvent>();
  522. _capturedEvents.Next().Should().BeOfType<ClusterRemovedServerEvent>();
  523. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  524. _capturedEvents.Any().Should().BeFalse();
  525. }
  526. [Fact]
  527. public void Should_remove_a_server_whose_canonical_end_point_does_not_match_its_provided_end_point()
  528. {
  529. var nonCanonicalEndPoint = new DnsEndPoint("wrong", 27017);
  530. _settings = _settings.With(endPoints: new[] { nonCanonicalEndPoint, _secondEndPoint });
  531. var subject = CreateSubject();
  532. subject.Initialize();
  533. _capturedEvents.Clear();
  534. PublishDescription(subject, nonCanonicalEndPoint, ServerType.ReplicaSetPrimary,
  535. hosts: new[] { _firstEndPoint, _secondEndPoint },
  536. canonicalEndPoint: _firstEndPoint);
  537. SpinWait.SpinUntil(() => !subject.Description.Servers.Any(d => ((DnsEndPoint)d.EndPoint).Host == "wrong"), TimeSpan.FromSeconds(5)).Should().BeTrue();
  538. var description = subject.Description;
  539. description.State.Should().Be(ClusterState.Disconnected);
  540. description.Type.Should().Be(ClusterType.ReplicaSet);
  541. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint), _serverDescriptionComparer);
  542. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  543. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  544. _capturedEvents.Next().Should().BeOfType<ClusterRemovingServerEvent>();
  545. _capturedEvents.Next().Should().BeOfType<ClusterRemovedServerEvent>();
  546. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  547. _capturedEvents.Any().Should().BeFalse();
  548. }
  549. [Fact]
  550. public void Should_not_remove_a_server_that_is_no_longer_in_a_secondaries_host_list()
  551. {
  552. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  553. var subject = CreateSubject();
  554. subject.Initialize();
  555. _capturedEvents.Clear();
  556. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetSecondary,
  557. hosts: new[] { _firstEndPoint, _secondEndPoint });
  558. var description = subject.Description;
  559. description.State.Should().Be(ClusterState.Connected);
  560. description.Type.Should().Be(ClusterType.ReplicaSet);
  561. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  562. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  563. _capturedEvents.Any().Should().BeFalse();
  564. }
  565. [Fact]
  566. public void Should_not_remove_a_server_that_is_disconnected()
  567. {
  568. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  569. var subject = CreateSubject();
  570. subject.Initialize();
  571. _capturedEvents.Clear();
  572. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary);
  573. PublishDisconnectedDescription(subject, _secondEndPoint);
  574. var description = subject.Description;
  575. description.State.Should().Be(ClusterState.Connected);
  576. description.Type.Should().Be(ClusterType.ReplicaSet);
  577. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  578. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  579. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  580. _capturedEvents.Any().Should().BeFalse();
  581. }
  582. [Fact]
  583. public void Should_not_add_a_new_server_from_a_secondary_when_a_primary_exists()
  584. {
  585. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint });
  586. var subject = CreateSubject();
  587. subject.Initialize();
  588. _capturedEvents.Clear();
  589. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary,
  590. hosts: new[] { _firstEndPoint, _secondEndPoint });
  591. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetSecondary,
  592. hosts: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  593. var description = subject.Description;
  594. description.State.Should().Be(ClusterState.Connected);
  595. description.Type.Should().Be(ClusterType.ReplicaSet);
  596. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint), _serverDescriptionComparer);
  597. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  598. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  599. _capturedEvents.Any().Should().BeFalse();
  600. }
  601. [Theory]
  602. [InlineData(ClusterConnectionMode.ReplicaSet, ServerType.ShardRouter)]
  603. [InlineData(ClusterConnectionMode.ReplicaSet, ServerType.Standalone)]
  604. [InlineData(ClusterConnectionMode.Sharded, ServerType.ReplicaSetArbiter)]
  605. [InlineData(ClusterConnectionMode.Sharded, ServerType.ReplicaSetGhost)]
  606. [InlineData(ClusterConnectionMode.Sharded, ServerType.ReplicaSetOther)]
  607. [InlineData(ClusterConnectionMode.Sharded, ServerType.ReplicaSetPrimary)]
  608. [InlineData(ClusterConnectionMode.Sharded, ServerType.ReplicaSetSecondary)]
  609. [InlineData(ClusterConnectionMode.Sharded, ServerType.Standalone)]
  610. public void Should_hide_a_seedlist_server_of_the_wrong_type(ClusterConnectionMode connectionMode, ServerType wrongType)
  611. {
  612. _settings = _settings.With(
  613. endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint },
  614. connectionMode: connectionMode);
  615. var subject = CreateSubject();
  616. subject.Initialize();
  617. _capturedEvents.Clear();
  618. PublishDescription(subject, _secondEndPoint, wrongType);
  619. var description = subject.Description;
  620. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  621. _capturedEvents.Next().Should().BeOfType<ClusterRemovingServerEvent>();
  622. _capturedEvents.Next().Should().BeOfType<ClusterRemovedServerEvent>();
  623. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  624. _capturedEvents.Any().Should().BeFalse();
  625. }
  626. [Theory]
  627. [InlineData(ServerType.ShardRouter)]
  628. [InlineData(ServerType.Standalone)]
  629. public void Should_hide_a_discovered_server_of_the_wrong_type(ServerType wrongType)
  630. {
  631. _settings = _settings.With(endPoints: new[] { _firstEndPoint });
  632. var subject = CreateSubject();
  633. subject.Initialize();
  634. _capturedEvents.Clear();
  635. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary);
  636. PublishDescription(subject, _secondEndPoint, wrongType);
  637. var description = subject.Description;
  638. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  639. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  640. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  641. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  642. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  643. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  644. _capturedEvents.Next().Should().BeOfType<ClusterRemovingServerEvent>();
  645. _capturedEvents.Next().Should().BeOfType<ClusterRemovedServerEvent>();
  646. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  647. _capturedEvents.Any().Should().BeFalse();
  648. }
  649. [Fact]
  650. public void Should_ignore_changes_from_a_ReplicaSetGhost()
  651. {
  652. _settings = _settings.With(endPoints: new[] { _firstEndPoint });
  653. var subject = CreateSubject();
  654. subject.Initialize();
  655. _capturedEvents.Clear();
  656. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetGhost,
  657. hosts: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  658. var description = subject.Description;
  659. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint), _serverDescriptionComparer);
  660. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  661. _capturedEvents.Any().Should().BeFalse();
  662. }
  663. [Fact]
  664. public void Should_remove_a_server_reporting_the_wrong_set_name()
  665. {
  666. _settings = _settings.With(
  667. endPoints: new[] { _firstEndPoint, _secondEndPoint },
  668. replicaSetName: "test");
  669. var subject = CreateSubject();
  670. subject.Initialize();
  671. _capturedEvents.Clear();
  672. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetSecondary,
  673. hosts: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint },
  674. setName: "funny");
  675. var description = subject.Description;
  676. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_secondEndPoint), _serverDescriptionComparer);
  677. _capturedEvents.Next().Should().BeOfType<ClusterRemovingServerEvent>();
  678. _capturedEvents.Next().Should().BeOfType<ClusterRemovedServerEvent>();
  679. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  680. _capturedEvents.Any().Should().BeFalse();
  681. }
  682. [Fact]
  683. public void Should_remove_server_from_the_seed_list_that_is_not_in_the_hosts_lists()
  684. {
  685. var alternateEndPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 27017);
  686. _settings = _settings.With(endPoints: new[] { alternateEndPoint });
  687. var subject = CreateSubject();
  688. subject.Initialize();
  689. _capturedEvents.Clear();
  690. PublishDescription(subject, alternateEndPoint, ServerType.ReplicaSetPrimary);
  691. var description = subject.Description;
  692. description.Servers.Should().BeEquivalentToWithComparer(GetDescriptions(_firstEndPoint, _secondEndPoint, _thirdEndPoint), _serverDescriptionComparer);
  693. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  694. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  695. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  696. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  697. _capturedEvents.Next().Should().BeOfType<ClusterAddingServerEvent>();
  698. _capturedEvents.Next().Should().BeOfType<ClusterAddedServerEvent>();
  699. _capturedEvents.Next().Should().BeOfType<ClusterRemovingServerEvent>();
  700. _capturedEvents.Next().Should().BeOfType<ClusterRemovedServerEvent>();
  701. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  702. _capturedEvents.Any().Should().BeFalse();
  703. }
  704. [Fact]
  705. public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_and_current_set_version_and_election_id_are_null()
  706. {
  707. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  708. var subject = CreateSubject();
  709. subject.Initialize();
  710. _capturedEvents.Clear();
  711. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary);
  712. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetPrimary);
  713. var description = subject.Description;
  714. description.Servers.Should().BeEquivalentToWithComparer(
  715. new[] { GetDisconnectedDescription(_firstEndPoint) }.Concat(GetDescriptions(_secondEndPoint, _thirdEndPoint)),
  716. _serverDescriptionComparer);
  717. var mockServer = Mock.Get(_serverFactory.GetServer(_firstEndPoint));
  718. mockServer.Verify(s => s.Invalidate("NoLongerPrimary"), Times.Once);
  719. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  720. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  721. _capturedEvents.Any().Should().BeFalse();
  722. }
  723. [Fact]
  724. public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_an_election_id_and_current_set_version_and_election_id_are_null()
  725. {
  726. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  727. var subject = CreateSubject();
  728. subject.Initialize();
  729. _capturedEvents.Clear();
  730. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary);
  731. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
  732. var description = subject.Description;
  733. description.Servers.Should().BeEquivalentToWithComparer(
  734. new[] { GetDisconnectedDescription(_firstEndPoint) }.Concat(GetDescriptions(_secondEndPoint, _thirdEndPoint)),
  735. _serverDescriptionComparer);
  736. var mockServer = Mock.Get(_serverFactory.GetServer(_firstEndPoint));
  737. mockServer.Verify(s => s.Invalidate("NoLongerPrimary"), Times.Once);
  738. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  739. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  740. .Subject.Message.Should().Contain("Initializing (maxSetVersion, maxElectionId)");
  741. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  742. _capturedEvents.Any().Should().BeFalse();
  743. }
  744. [Fact]
  745. public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_a_higher_set_version()
  746. {
  747. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  748. var subject = CreateSubject();
  749. subject.Initialize();
  750. _capturedEvents.Clear();
  751. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.Empty));
  752. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 2, electionId: new ElectionId(ObjectId.Empty));
  753. var description = subject.Description;
  754. description.Servers.Should().BeEquivalentToWithComparer(
  755. new[] { GetDisconnectedDescription(_firstEndPoint) }.Concat(GetDescriptions(_secondEndPoint, _thirdEndPoint)),
  756. _serverDescriptionComparer);
  757. var mockServer = Mock.Get(_serverFactory.GetServer(_firstEndPoint));
  758. mockServer.Verify(s => s.Invalidate("NoLongerPrimary"), Times.Once);
  759. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  760. .Subject.Message.Should().Contain("Initializing (maxSetVersion, maxElectionId)");
  761. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  762. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  763. .Subject.Message.Should().Contain("Updating stale setVersion");
  764. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  765. _capturedEvents.Any().Should().BeFalse();
  766. }
  767. [Fact]
  768. public void Should_invalidate_existing_primary_when_a_new_primary_shows_up_with_the_same_set_version_and_a_higher_election_id()
  769. {
  770. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  771. var subject = CreateSubject();
  772. subject.Initialize();
  773. _capturedEvents.Clear();
  774. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.Empty));
  775. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
  776. var description = subject.Description;
  777. description.Servers.Should().BeEquivalentToWithComparer(
  778. new[] { GetDisconnectedDescription(_firstEndPoint) }.Concat(GetDescriptions(_secondEndPoint, _thirdEndPoint)),
  779. _serverDescriptionComparer);
  780. var mockServer = Mock.Get(_serverFactory.GetServer(_firstEndPoint));
  781. mockServer.Verify(s => s.Invalidate("NoLongerPrimary"), Times.Once);
  782. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  783. .Subject.Message.Should().Contain("Initializing (maxSetVersion, maxElectionId)");
  784. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  785. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  786. .Subject.Message.Should().Contain("Updating stale electionId");
  787. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  788. _capturedEvents.Any().Should().BeFalse();
  789. }
  790. [Fact]
  791. public void Should_invalidate_new_primary_when_it_shows_up_with_a_lesser_set_version()
  792. {
  793. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  794. var subject = CreateSubject();
  795. subject.Initialize();
  796. _capturedEvents.Clear();
  797. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 2, electionId: new ElectionId(ObjectId.Empty));
  798. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
  799. var description = subject.Description;
  800. description.Servers.Should().BeEquivalentToWithComparer(
  801. new[] { GetDisconnectedDescription(_secondEndPoint) }.Concat(GetDescriptions(_firstEndPoint, _thirdEndPoint)),
  802. _serverDescriptionComparer);
  803. var mockServer = Mock.Get(_serverFactory.GetServer(_secondEndPoint));
  804. mockServer.Verify(s => s.Invalidate("ReportedPrimaryIsStale"), Times.Once);
  805. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  806. .Subject.Message.Should().Contain("Initializing (maxSetVersion, maxElectionId)");
  807. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  808. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()
  809. .Subject.Message.Should().Contain("Invalidating server");
  810. _capturedEvents.Next().Should().BeOfType<ClusterDescriptionChangedEvent>();
  811. _capturedEvents.Any().Should().BeFalse();
  812. }
  813. [Fact]
  814. public void Should_invalidate_new_primary_when_it_shows_up_with_the_same_set_version_and_a_lesser_election_id()
  815. {
  816. _settings = _settings.With(endPoints: new[] { _firstEndPoint, _secondEndPoint, _thirdEndPoint });
  817. var subject = CreateSubject();
  818. subject.Initialize();
  819. _capturedEvents.Clear();
  820. PublishDescription(subject, _firstEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.GenerateNewId()));
  821. PublishDescription(subject, _secondEndPoint, ServerType.ReplicaSetPrimary, setVersion: 1, electionId: new ElectionId(ObjectId.Empty));
  822. var description = subject.Description;
  823. description.Servers.Should().BeEquivalentToWithComparer(
  824. new[] { GetDisconnectedDescription(_secondEndPoint) }.Concat(GetDescriptions(_firstEndPoint, _thirdEndPoint)),
  825. _serverDescriptionComparer);
  826. var mockServer = Mock.Get(_serverFactory.GetServer(_secondEndPoint));
  827. mockServer.Verify(s => s.Invalidate("ReportedPrimaryIsStale"), Times.Once);
  828. _capturedEvents.Next().Should().BeOfType<SdamInformationEvent>()

Large files files are truncated, but you can click here to view the full file