PageRenderTime 59ms CodeModel.GetById 18ms RepoModel.GetById 0ms app.codeStats 1ms

/tests/MongoDB.Driver.Core.Tests/Core/Configuration/ConnectionStringTests.cs

http://github.com/mongodb/mongo-csharp-driver
C# | 1117 lines | 931 code | 168 blank | 18 comment | 9 complexity | fd52a1f55a376d1b92949fb3ff1d0a3c 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.Net.Sockets;
  20. using System.Threading.Tasks;
  21. using FluentAssertions;
  22. using MongoDB.Bson;
  23. using MongoDB.Bson.TestHelpers;
  24. using MongoDB.Driver.Core.Clusters;
  25. using MongoDB.Driver.Core.Compression;
  26. using Xunit;
  27. namespace MongoDB.Driver.Core.Configuration
  28. {
  29. [Trait("Category", "ConnectionString")]
  30. public class ConnectionStringTests
  31. {
  32. [Theory]
  33. [InlineData("mongodb://localhost", true)]
  34. [InlineData("mongodb+srv://localhost", false)]
  35. public void constructor_should_initialize_isResolved(string connectionString, bool expectedIsResolved)
  36. {
  37. var subject = new ConnectionString(connectionString);
  38. subject.IsResolved.Should().Be(expectedIsResolved);
  39. }
  40. [Theory]
  41. [InlineData("mongodb://localhost", true)]
  42. [InlineData("mongodb+srv://localhost", false)]
  43. [InlineData("mongodb+srv://localhost", true)]
  44. public void constructor_with_isResolved_should_initialize_isResolved(string connectionString, bool isResolved)
  45. {
  46. var subject = new ConnectionString(connectionString, isResolved);
  47. subject.IsResolved.Should().Be(isResolved);
  48. }
  49. [Fact]
  50. public void constructor_should_throw_when_isResolved_is_invalid()
  51. {
  52. var exception = Record.Exception(() => new ConnectionString("mongodb://localhost", false));
  53. var e = exception.Should().BeOfType<ArgumentException>().Subject;
  54. e.ParamName.Should().Be("isResolved");
  55. }
  56. [Theory]
  57. [InlineData("mongodb://test5.test.build.10gen.cc", "mongodb://test5.test.build.10gen.cc", false)]
  58. [InlineData("mongodb://test5.test.build.10gen.cc", "mongodb://test5.test.build.10gen.cc", true)]
  59. [InlineData("mongodb+srv://test5.test.build.10gen.cc", "mongodb://localhost.test.build.10gen.cc:27017/?replicaSet=repl0&authSource=thisDB&tls=true", false)]
  60. [InlineData("mongodb+srv://test5.test.build.10gen.cc", "mongodb://localhost.test.build.10gen.cc:27017/?replicaSet=repl0&authSource=thisDB&tls=true", true)]
  61. public void Resolve_should_return_expected_result(string connectionString, string expectedResult, bool async)
  62. {
  63. var subject = new ConnectionString(connectionString);
  64. ConnectionString result;
  65. if (async)
  66. {
  67. result = subject.Resolve();
  68. }
  69. else
  70. {
  71. result = subject.ResolveAsync().GetAwaiter().GetResult();
  72. }
  73. result.IsResolved.Should().BeTrue();
  74. result.ToString().Should().Be(expectedResult);
  75. }
  76. [Theory]
  77. [InlineData("mongodb://test5.test.build.10gen.cc", false, "mongodb://test5.test.build.10gen.cc", false)]
  78. [InlineData("mongodb://test5.test.build.10gen.cc", false, "mongodb://test5.test.build.10gen.cc", true)]
  79. [InlineData("mongodb://test5.test.build.10gen.cc", true, "mongodb://test5.test.build.10gen.cc", false)]
  80. [InlineData("mongodb://test5.test.build.10gen.cc", true, "mongodb://test5.test.build.10gen.cc", true)]
  81. [InlineData("mongodb+srv://test5.test.build.10gen.cc", false, "mongodb+srv://test5.test.build.10gen.cc/?replicaSet=repl0&authSource=thisDB&tls=true", false)]
  82. [InlineData("mongodb+srv://test5.test.build.10gen.cc", false, "mongodb+srv://test5.test.build.10gen.cc/?replicaSet=repl0&authSource=thisDB&tls=true", true)]
  83. [InlineData("mongodb+srv://test5.test.build.10gen.cc", true, "mongodb://localhost.test.build.10gen.cc:27017/?replicaSet=repl0&authSource=thisDB&tls=true", false)]
  84. [InlineData("mongodb+srv://test5.test.build.10gen.cc", true, "mongodb://localhost.test.build.10gen.cc:27017/?replicaSet=repl0&authSource=thisDB&tls=true", true)]
  85. public void Resolve_with_resolveHosts_should_return_expected_result(string connectionString, bool resolveHosts, string expectedResult, bool async)
  86. {
  87. var subject = new ConnectionString(connectionString);
  88. ConnectionString result;
  89. if (async)
  90. {
  91. result = subject.Resolve(resolveHosts);
  92. }
  93. else
  94. {
  95. result = subject.ResolveAsync(resolveHosts).GetAwaiter().GetResult();
  96. }
  97. result.IsResolved.Should().BeTrue();
  98. result.ToString().Should().Be(expectedResult);
  99. }
  100. [Theory]
  101. [InlineData("mongodb://test5.test.build.10gen.cc?tlsInsecure=true&tlsInsecure=false", true)]
  102. [InlineData("mongodb://test5.test.build.10gen.cc?tlsInsecure=false&tlsInsecure=true", true)]
  103. [InlineData("mongodb://test5.test.build.10gen.cc?tlsInsecure=true&tlsInsecure=true", false)]
  104. public void With_more_then_one_tlsInsecure(string connectionString, bool shouldThrow)
  105. {
  106. var exception = Record.Exception(() => { var _ = new ConnectionString(connectionString); });
  107. if (shouldThrow)
  108. {
  109. var e = exception.Should().BeOfType<MongoConfigurationException>().Subject;
  110. e.Message.Should().Be("tlsInsecure has already been configured with a different value.");
  111. }
  112. else
  113. {
  114. exception.Should().BeNull();
  115. }
  116. }
  117. [Theory]
  118. [InlineData("mongodb://test5.test.build.10gen.cc?tls=true&tls=false", true)]
  119. [InlineData("mongodb://test5.test.build.10gen.cc?ssl=false&ssl=true", true)]
  120. [InlineData("mongodb://test5.test.build.10gen.cc?ssl=false&tls=true", true)]
  121. [InlineData("mongodb://test5.test.build.10gen.cc?tls=false&ssl=true", true)]
  122. [InlineData("mongodb://test5.test.build.10gen.cc?ssl=false&ssl=false", false)]
  123. [InlineData("mongodb://test5.test.build.10gen.cc?tls=false&tls=false", false)]
  124. [InlineData("mongodb://test5.test.build.10gen.cc?ssl=true&ssl=true", false)]
  125. [InlineData("mongodb://test5.test.build.10gen.cc?tls=true&tls=true", false)]
  126. public void With_more_then_one_tls_or_ssl(string connectionString, bool shouldThrow)
  127. {
  128. var exception = Record.Exception(() => { var _ = new ConnectionString(connectionString); });
  129. if (shouldThrow)
  130. {
  131. var e = exception.Should().BeOfType<MongoConfigurationException>().Subject;
  132. e.Message.Should().Be("tls has already been configured with a different value.");
  133. }
  134. else
  135. {
  136. exception.Should().BeNull();
  137. }
  138. }
  139. [Fact]
  140. public void With_one_host_and_no_port()
  141. {
  142. var subject = new ConnectionString("mongodb://localhost");
  143. subject.Hosts.Count().Should().Be(1);
  144. subject.Hosts.Single().Should().Be(new DnsEndPoint("localhost", 27017));
  145. }
  146. [Fact]
  147. public void With_one_host_and_port()
  148. {
  149. var subject = new ConnectionString("mongodb://localhost:27092");
  150. subject.Hosts.Count().Should().Be(1);
  151. subject.Hosts.Single().Should().Be(new DnsEndPoint("localhost", 27092));
  152. }
  153. [Fact]
  154. public void With_two_hosts_and_one_port()
  155. {
  156. var subject = new ConnectionString("mongodb://localhost:27092,remote");
  157. subject.Hosts.Count().Should().Be(2);
  158. subject.Hosts[0].Should().Be(new DnsEndPoint("localhost", 27092));
  159. subject.Hosts[1].Should().Be(new DnsEndPoint("remote", 27017));
  160. }
  161. [Fact]
  162. public void With_two_hosts_and_one_port2()
  163. {
  164. var subject = new ConnectionString("mongodb://localhost,remote:27092");
  165. subject.Hosts.Count().Should().Be(2);
  166. subject.Hosts[0].Should().Be(new DnsEndPoint("localhost", 27017));
  167. subject.Hosts[1].Should().Be(new DnsEndPoint("remote", 27092));
  168. }
  169. [Fact]
  170. public void With_two_hosts_and_two_ports()
  171. {
  172. var subject = new ConnectionString("mongodb://localhost:30000,remote:27092");
  173. subject.Hosts.Count().Should().Be(2);
  174. subject.Hosts[0].Should().Be(new DnsEndPoint("localhost", 30000));
  175. subject.Hosts[1].Should().Be(new DnsEndPoint("remote", 27092));
  176. }
  177. [Fact]
  178. public void With_an_ipv4_host()
  179. {
  180. var subject = new ConnectionString("mongodb://127.0.0.1");
  181. subject.Hosts.Count().Should().Be(1);
  182. subject.Hosts[0].Should().Be(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 27017));
  183. }
  184. [Fact]
  185. public void With_an_ipv4_host_and_port()
  186. {
  187. var subject = new ConnectionString("mongodb://127.0.0.1:28017");
  188. subject.Hosts.Count().Should().Be(1);
  189. subject.Hosts[0].Should().Be(new IPEndPoint(IPAddress.Parse("127.0.0.1"), 28017));
  190. }
  191. [Fact]
  192. public void With_an_ipv6_host()
  193. {
  194. var subject = new ConnectionString("mongodb://[::1]");
  195. subject.Hosts.Count().Should().Be(1);
  196. subject.Hosts[0].Should().Be(new IPEndPoint(IPAddress.Parse("[::1]"), 27017));
  197. }
  198. [Fact]
  199. public void With_a_2_ipv6_hosts()
  200. {
  201. var subject = new ConnectionString("mongodb://[::1],[::2]");
  202. subject.Hosts.Count().Should().Be(2);
  203. subject.Hosts[0].Should().Be(new IPEndPoint(IPAddress.Parse("[::1]"), 27017));
  204. subject.Hosts[1].Should().Be(new IPEndPoint(IPAddress.Parse("[::2]"), 27017));
  205. }
  206. [Fact]
  207. public void With_an_ipv6_host_and_port()
  208. {
  209. var subject = new ConnectionString("mongodb://[::1]:28017");
  210. subject.Hosts.Count().Should().Be(1);
  211. subject.Hosts[0].Should().Be(new IPEndPoint(IPAddress.Parse("[::1]"), 28017));
  212. }
  213. [Fact]
  214. public void With_three_hosts_of_different_types()
  215. {
  216. var subject = new ConnectionString("mongodb://localhost,10.0.0.1:30000,[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]:28017");
  217. subject.Hosts.Count().Should().Be(3);
  218. subject.Hosts[0].Should().Be(new DnsEndPoint("localhost", 27017, AddressFamily.Unspecified));
  219. subject.Hosts[1].Should().Be(new IPEndPoint(IPAddress.Parse("10.0.0.1"), 30000));
  220. subject.Hosts[2].Should().Be(new IPEndPoint(IPAddress.Parse("[FE80:0000:0000:0000:0202:B3FF:FE1E:8329]"), 28017));
  221. }
  222. [Theory]
  223. [InlineData("mongodb://localhost")]
  224. [InlineData("mongodb://localhost/")]
  225. public void When_nothing_is_specified(string connectionString)
  226. {
  227. var subject = new ConnectionString(connectionString);
  228. subject.ApplicationName.Should().BeNull();
  229. subject.AuthMechanism.Should().BeNull();
  230. subject.AuthSource.Should().BeNull();
  231. subject.Compressors.Should().BeEmpty();
  232. subject.Connect.Should().Be(ClusterConnectionMode.Automatic);
  233. subject.ConnectTimeout.Should().Be(null);
  234. subject.DatabaseName.Should().BeNull();
  235. subject.FSync.Should().Be(null);
  236. subject.HeartbeatInterval.Should().NotHaveValue();
  237. subject.HeartbeatTimeout.Should().NotHaveValue();
  238. subject.Ipv6.Should().Be(null);
  239. subject.Journal.Should().Be(null);
  240. subject.MaxIdleTime.Should().Be(null);
  241. subject.MaxLifeTime.Should().Be(null);
  242. subject.MaxPoolSize.Should().Be(null);
  243. subject.MinPoolSize.Should().Be(null);
  244. subject.Password.Should().BeNull();
  245. subject.ReadConcernLevel.Should().BeNull();
  246. subject.ReadPreference.Should().BeNull();
  247. subject.ReadPreferenceTags.Should().BeNull();
  248. subject.ReplicaSet.Should().BeNull();
  249. subject.LocalThreshold.Should().Be(null);
  250. subject.SocketTimeout.Should().Be(null);
  251. #pragma warning disable 618
  252. subject.Ssl.Should().Be(null);
  253. subject.SslVerifyCertificate.Should().Be(null);
  254. #pragma warning restore 618
  255. subject.Tls.Should().Be(null);
  256. subject.TlsInsecure.Should().Be(null);
  257. subject.Username.Should().BeNull();
  258. subject.UuidRepresentation.Should().BeNull();
  259. #pragma warning disable 618
  260. subject.WaitQueueMultiple.Should().Be(null);
  261. subject.WaitQueueSize.Should().Be(null);
  262. #pragma warning restore 618
  263. subject.WaitQueueTimeout.Should().Be(null);
  264. subject.W.Should().BeNull();
  265. subject.WTimeout.Should().Be(null);
  266. }
  267. [Fact]
  268. public void When_everything_is_specified()
  269. {
  270. var connectionString = @"mongodb://user:pass@localhost1,localhost2:30000/test?" +
  271. "appname=app;" +
  272. "authMechanism=GSSAPI;" +
  273. "authMechanismProperties=CANONICALIZE_HOST_NAME:true;" +
  274. "authSource=admin;" +
  275. "compressors=snappy,zlib;" +
  276. "zlibCompressionLevel=4;" +
  277. "connect=replicaSet;" +
  278. "connectTimeout=15ms;" +
  279. "fsync=true;" +
  280. "heartbeatInterval=1m;" +
  281. "heartbeatTimeout=2m;" +
  282. "ipv6=false;" +
  283. "j=true;" +
  284. "maxIdleTime=10ms;" +
  285. "maxLifeTime=5ms;" +
  286. "maxPoolSize=20;" +
  287. "minPoolSize=15;" +
  288. "readConcernLevel=majority;" +
  289. "readPreference=primary;" +
  290. "readPreferenceTags=dc:1;" +
  291. "replicaSet=funny;" +
  292. "retryReads=false;" +
  293. "retryWrites=true;" +
  294. "localThreshold=50ms;" +
  295. "socketTimeout=40ms;" +
  296. "ssl=false;" +
  297. "sslVerifyCertificate=true;" +
  298. "uuidRepresentation=standard;" +
  299. "waitQueueMultiple=10;" +
  300. "waitQueueSize=30;" +
  301. "waitQueueTimeout=60ms;" +
  302. "w=4;" +
  303. "wtimeout=20ms";
  304. var subject = new ConnectionString(connectionString);
  305. subject.ApplicationName.Should().Be("app");
  306. subject.AuthMechanism.Should().Be("GSSAPI");
  307. subject.AuthMechanismProperties.Count.Should().Be(1);
  308. subject.AuthMechanismProperties["canonicalize_host_name"].Should().Be("true");
  309. subject.AuthSource.Should().Be("admin");
  310. var expectedCompressorTypes = new[] { CompressorType.Snappy, CompressorType.Zlib };
  311. subject.Compressors.Select(x => x.Type).Should().Equal(expectedCompressorTypes);
  312. subject.Compressors.Single(x => x.Type == CompressorType.Zlib).Properties["Level"].Should().Be(4);
  313. subject.Connect.Should().Be(ClusterConnectionMode.ReplicaSet);
  314. subject.ConnectTimeout.Should().Be(TimeSpan.FromMilliseconds(15));
  315. subject.DatabaseName.Should().Be("test");
  316. subject.FSync.Should().BeTrue();
  317. subject.HeartbeatInterval.Should().Be(TimeSpan.FromMinutes(1));
  318. subject.HeartbeatTimeout.Should().Be(TimeSpan.FromMinutes(2));
  319. subject.Ipv6.Should().BeFalse();
  320. subject.Journal.Should().BeTrue();
  321. subject.MaxIdleTime.Should().Be(TimeSpan.FromMilliseconds(10));
  322. subject.MaxLifeTime.Should().Be(TimeSpan.FromMilliseconds(5));
  323. subject.MaxPoolSize.Should().Be(20);
  324. subject.MinPoolSize.Should().Be(15);
  325. subject.Password.Should().Be("pass");
  326. subject.ReadConcernLevel.Should().Be(ReadConcernLevel.Majority);
  327. subject.ReadPreference.Should().Be(ReadPreferenceMode.Primary);
  328. subject.ReadPreferenceTags.Single().Should().Be(new TagSet(new[] { new Tag("dc", "1") }));
  329. subject.ReplicaSet.Should().Be("funny");
  330. subject.RetryReads.Should().BeFalse();
  331. subject.RetryWrites.Should().BeTrue();
  332. subject.LocalThreshold.Should().Be(TimeSpan.FromMilliseconds(50));
  333. subject.SocketTimeout.Should().Be(TimeSpan.FromMilliseconds(40));
  334. #pragma warning disable 618
  335. subject.Ssl.Should().BeFalse();
  336. subject.SslVerifyCertificate.Should().Be(true);
  337. #pragma warning restore 618
  338. subject.Tls.Should().BeFalse();
  339. subject.TlsInsecure.Should().Be(false);
  340. subject.Username.Should().Be("user");
  341. subject.UuidRepresentation.Should().Be(GuidRepresentation.Standard);
  342. #pragma warning disable 618
  343. subject.WaitQueueMultiple.Should().Be(10);
  344. subject.WaitQueueSize.Should().Be(30);
  345. #pragma warning restore 618
  346. subject.WaitQueueTimeout.Should().Be(TimeSpan.FromMilliseconds(60));
  347. subject.W.Should().Be(WriteConcern.WValue.Parse("4"));
  348. subject.WTimeout.Should().Be(TimeSpan.FromMilliseconds(20));
  349. }
  350. [Theory]
  351. [InlineData("mongodb://localhost?appname=app1", "app1")]
  352. [InlineData("mongodb://localhost?appname=app2", "app2")]
  353. public void When_appname_is_specified(string connectionString, string applicationName)
  354. {
  355. var subject = new ConnectionString(connectionString);
  356. subject.ApplicationName.Should().Be(applicationName);
  357. }
  358. [Fact]
  359. public void When_appname_is_too_long()
  360. {
  361. var connectionString = $"mongodb://localhost?appname={new string('x', 129)}";
  362. var exception = Record.Exception(() => new ConnectionString(connectionString));
  363. exception.Should().BeOfType<MongoConfigurationException>();
  364. }
  365. [Theory]
  366. [InlineData("mongodb://localhost?authMechanism=GSSAPI", "GSSAPI")]
  367. [InlineData("mongodb://localhost?authMechanism=MONGODB-CR", "MONGODB-CR")]
  368. [InlineData("mongodb://localhost?authMechanism=PLAIN", "PLAIN")]
  369. [InlineData("mongodb://localhost?authMechanism=MONGODB-X509", "MONGODB-X509")]
  370. public void When_authMechanism_is_specified(string connectionString, string authMechanism)
  371. {
  372. var subject = new ConnectionString(connectionString);
  373. subject.AuthMechanism.Should().Be(authMechanism);
  374. }
  375. [Fact]
  376. public void When_authMechanismProperties_is_specified()
  377. {
  378. var connectionString = "mongodb://localhost?authMechanismProperties=ONE:1,TWO:2";
  379. var subject = new ConnectionString(connectionString);
  380. subject.AuthMechanismProperties.Count.Should().Be(2);
  381. subject.AuthMechanismProperties["one"].Should().Be("1");
  382. subject.AuthMechanismProperties["TWO"].Should().Be("2");
  383. }
  384. [Theory]
  385. [InlineData("mongodb://localhost?authSource=admin", "admin")]
  386. [InlineData("mongodb://localhost?authSource=awesome", "awesome")]
  387. public void When_authSource_is_specified(string connectionString, string authSource)
  388. {
  389. var subject = new ConnectionString(connectionString);
  390. subject.AuthSource.Should().Be(authSource);
  391. }
  392. [Theory]
  393. [InlineData("mongodb://localhost?compressors=zlib", CompressorType.Zlib)]
  394. public void When_compressor_is_specified(string connectionString, CompressorType compressor)
  395. {
  396. var subject = new ConnectionString(connectionString);
  397. subject.Compressors.Should().Contain(x => x.Type == compressor);
  398. }
  399. [Theory]
  400. [InlineData("mongodb://localhost?compressors=unsupported")]
  401. public void When_compressor_is_specified_with_unsupported_value_the_value_should_be_ignored(string connectionString)
  402. {
  403. var subject = new ConnectionString(connectionString);
  404. subject.Compressors.Should().BeEmpty();
  405. }
  406. [Theory]
  407. [InlineData("mongodb://nam!@#$%^&*())e:password@localhost", "mongodb://<hidden>@localhost")]
  408. [InlineData("://nam!@#$%^&*())e:password@loc", "://<hidden>@loc")]
  409. [InlineData("://nam!@#$%^&*())e@loc", "://<hidden>@loc")]
  410. [InlineData("mongodb://nameloc@", "mongodb://<hidden>@")]
  411. [InlineData("mongodb+srv://nameloc@", "mongodb+srv://<hidden>@")]
  412. [InlineData("ongodb://username:password@localhost/?replicaSet=@x", "ongodb://<hidden>@localhost/?replicaSet=@x")]
  413. public void When_connectionstring_invalid_security_data_should_be_protected(string connectionString, string protectedConnectionString)
  414. {
  415. var exception = Record.Exception(() => new ConnectionString(connectionString));
  416. var e = exception.Should().BeOfType<MongoConfigurationException>().Subject;
  417. e.Message.Should().StartWith($"The connection string '{protectedConnectionString}'");
  418. }
  419. [Theory]
  420. [InlineData("mongodb://localhost?connect=automatic", ClusterConnectionMode.Automatic)]
  421. [InlineData("mongodb://localhost?connect=direct", ClusterConnectionMode.Direct)]
  422. [InlineData("mongodb://localhost?connect=replicaSet", ClusterConnectionMode.ReplicaSet)]
  423. [InlineData("mongodb://localhost?connect=sharded", ClusterConnectionMode.Sharded)]
  424. [InlineData("mongodb://localhost?connect=ShardRouter", ClusterConnectionMode.Sharded)]
  425. [InlineData("mongodb://localhost?connect=sTaNdAlOnE", ClusterConnectionMode.Standalone)]
  426. public void When_connect_is_specified(string connectionString, ClusterConnectionMode connect)
  427. {
  428. var subject = new ConnectionString(connectionString);
  429. subject.Connect.Should().Be(connect);
  430. }
  431. [Theory]
  432. [InlineData("mongodb://localhost?connectTimeout=15ms", 15)]
  433. [InlineData("mongodb://localhost?connectTimeoutMS=15", 15)]
  434. [InlineData("mongodb://localhost?connectTimeout=15", 1000 * 15)]
  435. [InlineData("mongodb://localhost?connectTimeout=15s", 1000 * 15)]
  436. [InlineData("mongodb://localhost?connectTimeout=15m", 1000 * 60 * 15)]
  437. [InlineData("mongodb://localhost?connectTimeout=15h", 1000 * 60 * 60 * 15)]
  438. public void When_connect_timeout_is_specified(string connectionString, int milliseconds)
  439. {
  440. var subject = new ConnectionString(connectionString);
  441. subject.ConnectTimeout.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  442. }
  443. [Theory]
  444. [InlineData("mongodb://localhost/awesome", "awesome")]
  445. [InlineData("mongodb://localhost/awesome/", "awesome")]
  446. public void When_a_database_name_is_specified(string connectionString, string db)
  447. {
  448. var subject = new ConnectionString(connectionString);
  449. subject.DatabaseName.Should().Be(db);
  450. }
  451. [Theory]
  452. [InlineData("mongodb://localhost/?directConnection=true&replicaSet=yeah", true, ClusterConnectionMode.Direct)]
  453. [InlineData("mongodb://localhost/?directConnection=true", true, ClusterConnectionMode.Direct)]
  454. [InlineData("mongodb://localhost/?directConnection=false&replicaSet=yeah", false, ClusterConnectionMode.ReplicaSet)]
  455. [InlineData("mongodb://localhost/?directConnection=false", false, ClusterConnectionMode.Automatic)]
  456. public void When_a_directConenction_is_specified(string connectionString, bool directConnection, ClusterConnectionMode connect)
  457. {
  458. var subject = new ConnectionString(connectionString);
  459. subject.Connect.Should().Be(connect);
  460. subject._directConnection().Should().Be(directConnection);
  461. }
  462. [Theory]
  463. [InlineData("mongodb+srv://localhost/?directConnection=false", false)]
  464. [InlineData("mongodb+srv://localhost/?directConnection=true", true)]
  465. public void When_a_directConnection_is_specified_with_a_srv_scheme(string connectionString, bool shouldThrow)
  466. {
  467. ConnectionString subject = null;
  468. var exception = Record.Exception(() => subject = new ConnectionString(connectionString));
  469. if (shouldThrow)
  470. {
  471. exception.Should().BeOfType<MongoConfigurationException>();
  472. }
  473. else
  474. {
  475. exception.Should().BeNull();
  476. subject._directConnection().Should().BeFalse();
  477. }
  478. }
  479. [Theory]
  480. [InlineData("mongodb://localhost1,localhost2/?directConnection=false", false)]
  481. [InlineData("mongodb://localhost1,localhost2/?directConnection=true", true)]
  482. public void When_a_directConnection_is_specified_with_multiple_hosts(string connectionString, bool shouldThrow)
  483. {
  484. ConnectionString subject = null;
  485. var exception = Record.Exception(() => subject = new ConnectionString(connectionString));
  486. if (shouldThrow)
  487. {
  488. exception.Should().BeOfType<MongoConfigurationException>();
  489. }
  490. else
  491. {
  492. exception.Should().BeNull();
  493. subject._directConnection().Should().BeFalse();
  494. }
  495. }
  496. [Theory]
  497. [InlineData("mongodb://localhost?fsync=true", true)]
  498. [InlineData("mongodb://localhost?fsync=false", false)]
  499. public void When_fsync_is_specified(string connectionString, bool fsync)
  500. {
  501. var subject = new ConnectionString(connectionString);
  502. subject.FSync.Should().Be(fsync);
  503. }
  504. [Theory]
  505. [InlineData("mongodb://localhost?gssapiServiceName=serviceName", "serviceName")]
  506. [InlineData("mongodb://localhost?gssapiServiceName=mongodb", "mongodb")]
  507. [InlineData("mongodb://localhost?authMechanismProperties=SERVICE_NAME:serviceName", "serviceName")]
  508. public void When_gssapiServiceName_is_specified(string connectionString, string gssapiServiceName)
  509. {
  510. var subject = new ConnectionString(connectionString);
  511. subject.AuthMechanismProperties["service_name"].Should().Be(gssapiServiceName);
  512. }
  513. [Theory]
  514. [InlineData("mongodb://localhost?heartbeatInterval=15ms", 15)]
  515. [InlineData("mongodb://localhost?heartbeatIntervalMS=15", 15)]
  516. [InlineData("mongodb://localhost?heartbeatInterval=15", 1000 * 15)]
  517. [InlineData("mongodb://localhost?heartbeatInterval=15s", 1000 * 15)]
  518. [InlineData("mongodb://localhost?heartbeatInterval=15m", 1000 * 60 * 15)]
  519. [InlineData("mongodb://localhost?heartbeatInterval=15h", 1000 * 60 * 60 * 15)]
  520. [InlineData("mongodb://localhost?heartbeatFrequency=15ms", 15)]
  521. [InlineData("mongodb://localhost?heartbeatFrequencyMS=15", 15)]
  522. [InlineData("mongodb://localhost?heartbeatFrequency=15", 1000 * 15)]
  523. [InlineData("mongodb://localhost?heartbeatFrequency=15s", 1000 * 15)]
  524. [InlineData("mongodb://localhost?heartbeatFrequency=15m", 1000 * 60 * 15)]
  525. [InlineData("mongodb://localhost?heartbeatFrequency=15h", 1000 * 60 * 60 * 15)]
  526. public void When_heartbeat_interval_is_specified(string connectionString, int milliseconds)
  527. {
  528. var subject = new ConnectionString(connectionString);
  529. subject.HeartbeatInterval.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  530. }
  531. [Theory]
  532. [InlineData("mongodb://localhost?heartbeatTimeout=15ms", 15)]
  533. [InlineData("mongodb://localhost?heartbeatTimeoutMS=15", 15)]
  534. [InlineData("mongodb://localhost?heartbeatTimeout=15", 1000 * 15)]
  535. [InlineData("mongodb://localhost?heartbeatTimeout=15s", 1000 * 15)]
  536. [InlineData("mongodb://localhost?heartbeatTimeout=15m", 1000 * 60 * 15)]
  537. [InlineData("mongodb://localhost?heartbeatTimeout=15h", 1000 * 60 * 60 * 15)]
  538. public void When_heartbeat_timeout_is_specified(string connectionString, int milliseconds)
  539. {
  540. var subject = new ConnectionString(connectionString);
  541. subject.HeartbeatTimeout.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  542. }
  543. [Theory]
  544. [InlineData("mongodb://localhost?ipv6=true", true)]
  545. [InlineData("mongodb://localhost?ipv6=false", false)]
  546. public void When_ipv6_is_specified(string connectionString, bool ipv6)
  547. {
  548. var subject = new ConnectionString(connectionString);
  549. subject.Ipv6.Should().Be(ipv6);
  550. }
  551. [Theory]
  552. [InlineData("mongodb://localhost?j=true", true)]
  553. [InlineData("mongodb://localhost?j=false", false)]
  554. public void When_j_is_specified(string connectionString, bool j)
  555. {
  556. var subject = new ConnectionString(connectionString);
  557. subject.Journal.Should().Be(j);
  558. }
  559. [Theory]
  560. [InlineData("mongodb://localhost?maxIdleTime=15ms", 15)]
  561. [InlineData("mongodb://localhost?maxIdleTimeMS=15", 15)]
  562. [InlineData("mongodb://localhost?maxIdleTime=15", 1000 * 15)]
  563. [InlineData("mongodb://localhost?maxIdleTime=15s", 1000 * 15)]
  564. [InlineData("mongodb://localhost?maxIdleTime=15m", 1000 * 60 * 15)]
  565. [InlineData("mongodb://localhost?maxIdleTime=15h", 1000 * 60 * 60 * 15)]
  566. public void When_maxIdleTime_is_specified(string connectionString, int milliseconds)
  567. {
  568. var subject = new ConnectionString(connectionString);
  569. subject.MaxIdleTime.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  570. }
  571. [Theory]
  572. [InlineData("mongodb://localhost?maxLifeTime=15ms", 15)]
  573. [InlineData("mongodb://localhost?maxLifeTimeMS=15", 15)]
  574. [InlineData("mongodb://localhost?maxLifeTime=15", 1000 * 15)]
  575. [InlineData("mongodb://localhost?maxLifeTime=15s", 1000 * 15)]
  576. [InlineData("mongodb://localhost?maxLifeTime=15m", 1000 * 60 * 15)]
  577. [InlineData("mongodb://localhost?maxLifeTime=15h", 1000 * 60 * 60 * 15)]
  578. public void When_maxLifeTime_is_specified(string connectionString, int milliseconds)
  579. {
  580. var subject = new ConnectionString(connectionString);
  581. subject.MaxLifeTime.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  582. }
  583. [Theory]
  584. [InlineData("mongodb://localhost?maxPoolSize=-1", -1)]
  585. [InlineData("mongodb://localhost?maxPoolSize=0", 0)]
  586. [InlineData("mongodb://localhost?maxPoolSize=1", 1)]
  587. [InlineData("mongodb://localhost?maxPoolSize=20", 20)]
  588. public void When_maxPoolSize_is_specified(string connectionString, int maxPoolSize)
  589. {
  590. var subject = new ConnectionString(connectionString);
  591. subject.MaxPoolSize.Should().Be(maxPoolSize);
  592. }
  593. [Theory]
  594. [InlineData("mongodb://localhost?maxStaleness=15ms", 15)]
  595. [InlineData("mongodb://localhost?maxStalenessSeconds=0.015", 15)]
  596. [InlineData("mongodb://localhost?maxStaleness=15", 1000 * 15)]
  597. [InlineData("mongodb://localhost?maxStaleness=15s", 1000 * 15)]
  598. [InlineData("mongodb://localhost?maxStaleness=15m", 1000 * 60 * 15)]
  599. [InlineData("mongodb://localhost?maxStaleness=15h", 1000 * 60 * 60 * 15)]
  600. public void When_maxStaleness_is_specified(string connectionString, int milliseconds)
  601. {
  602. var subject = new ConnectionString(connectionString);
  603. subject.MaxStaleness.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  604. }
  605. [Theory]
  606. [InlineData("mongodb://localhost")]
  607. [InlineData("mongodb://localhost?maxStalenessSeconds=-1")]
  608. [InlineData("mongodb://localhost?maxStaleness=-1")]
  609. [InlineData("mongodb://localhost?maxStaleness=-1s")]
  610. [InlineData("mongodb://localhost?maxStaleness=-1000ms")]
  611. public void When_no_maxStaleness_is_specified(string connectionString)
  612. {
  613. var subject = new ConnectionString(connectionString);
  614. subject.MaxStaleness.Should().NotHaveValue();
  615. }
  616. [Theory]
  617. [InlineData("mongodb://localhost?minPoolSize=-1", -1)]
  618. [InlineData("mongodb://localhost?minPoolSize=0", 0)]
  619. [InlineData("mongodb://localhost?minPoolSize=1", 1)]
  620. [InlineData("mongodb://localhost?minPoolSize=20", 20)]
  621. public void When_minPoolSize_is_specified(string connectionString, int minPoolSize)
  622. {
  623. var subject = new ConnectionString(connectionString);
  624. subject.MinPoolSize.Should().Be(minPoolSize);
  625. }
  626. [Theory]
  627. [InlineData("mongodb://a:yes@localhost", "yes")]
  628. [InlineData("mongodb://a:password@localhost", "password")]
  629. [InlineData("mongodb://a:@localhost", "")]
  630. public void When_password_is_specified(string connectionString, string password)
  631. {
  632. var subject = new ConnectionString(connectionString);
  633. subject.Password.Should().Be(password);
  634. }
  635. [Theory]
  636. [InlineData("mongodb://localhost?readConcernLevel=available", ReadConcernLevel.Available)]
  637. [InlineData("mongodb://localhost?readConcernLevel=linearizable", ReadConcernLevel.Linearizable)]
  638. [InlineData("mongodb://localhost?readConcernLevel=local", ReadConcernLevel.Local)]
  639. [InlineData("mongodb://localhost?readConcernLevel=majority", ReadConcernLevel.Majority)]
  640. [InlineData("mongodb://localhost?readConcernLevel=snapshot", ReadConcernLevel.Snapshot)]
  641. public void When_readConcernLevel_is_specified(string connectionString, ReadConcernLevel readConcernLevel)
  642. {
  643. var subject = new ConnectionString(connectionString);
  644. subject.ReadConcernLevel.Should().Be(readConcernLevel);
  645. }
  646. [Theory]
  647. [InlineData("mongodb://localhost?readPreference=primary", ReadPreferenceMode.Primary)]
  648. [InlineData("mongodb://localhost?readPreference=primaryPreferred", ReadPreferenceMode.PrimaryPreferred)]
  649. [InlineData("mongodb://localhost?readPreference=secondaryPreferred", ReadPreferenceMode.SecondaryPreferred)]
  650. [InlineData("mongodb://localhost?readPreference=secondary", ReadPreferenceMode.Secondary)]
  651. [InlineData("mongodb://localhost?readPreference=nearest", ReadPreferenceMode.Nearest)]
  652. public void When_readPreference_is_specified(string connectionString, ReadPreferenceMode readPreference)
  653. {
  654. var subject = new ConnectionString(connectionString);
  655. subject.ReadPreference.Should().Be(readPreference);
  656. }
  657. [Fact]
  658. public void When_one_set_of_readPreferenceTags_is_specified()
  659. {
  660. var subject = new ConnectionString("mongodb://localhost?readPreferenceTags=dc:east,rack:1");
  661. var tagSet = new TagSet(new List<Tag>
  662. {
  663. new Tag("dc", "east"),
  664. new Tag("rack", "1")
  665. });
  666. subject.ReadPreferenceTags.Count.Should().Be(1);
  667. Assert.Equal(tagSet, subject.ReadPreferenceTags.Single());
  668. }
  669. [Fact]
  670. public void When_two_sets_of_readPreferenceTags_are_specified()
  671. {
  672. var subject = new ConnectionString("mongodb://localhost?readPreferenceTags=dc:east,rack:1&readPreferenceTags=dc:west,rack:2");
  673. var tagSet1 = new TagSet(new List<Tag>
  674. {
  675. new Tag("dc", "east"),
  676. new Tag("rack", "1")
  677. });
  678. var tagSet2 = new TagSet(new List<Tag>
  679. {
  680. new Tag("dc", "west"),
  681. new Tag("rack", "2")
  682. });
  683. subject.ReadPreferenceTags.Count.Should().Be(2);
  684. subject.ReadPreferenceTags[0].Should().Be(tagSet1);
  685. subject.ReadPreferenceTags[1].Should().Be(tagSet2);
  686. }
  687. [Theory]
  688. [InlineData("mongodb://localhost?replicaSet=yeah", "yeah")]
  689. public void When_replicaSet_is_specified(string connectionString, string replicaSet)
  690. {
  691. var subject = new ConnectionString(connectionString);
  692. subject.ReplicaSet.Should().Be(replicaSet);
  693. }
  694. [Theory]
  695. [InlineData("mongodb://localhost", null)]
  696. [InlineData("mongodb://localhost?retryReads=true", true)]
  697. [InlineData("mongodb://localhost?retryReads=false", false)]
  698. public void When_retryReads_is_specified(string connectionString, bool? retryReads)
  699. {
  700. var subject = new ConnectionString(connectionString);
  701. subject.RetryReads.Should().Be(retryReads);
  702. }
  703. [Theory]
  704. [InlineData("mongodb://localhost", null)]
  705. [InlineData("mongodb://localhost?retryWrites=true", true)]
  706. [InlineData("mongodb://localhost?retryWrites=false", false)]
  707. public void When_retryWrites_is_specified(string connectionString, bool? retryWrites)
  708. {
  709. var subject = new ConnectionString(connectionString);
  710. subject.RetryWrites.Should().Be(retryWrites);
  711. }
  712. [Theory]
  713. [InlineData("mongodb://localhost/?safe=false", 0)]
  714. [InlineData("mongodb://localhost/?w=1;safe=false", 0)]
  715. [InlineData("mongodb://localhost/?w=2;safe=false", 0)]
  716. [InlineData("mongodb://localhost/?w=mode;safe=false", 0)]
  717. [InlineData("mongodb://localhost/?safe=true", 1)]
  718. [InlineData("mongodb://localhost/?w=0;safe=true", 1)]
  719. [InlineData("mongodb://localhost/?w=2;safe=true", 2)]
  720. [InlineData("mongodb://localhost/?w=mode;safe=true", "mode")]
  721. public void When_safe_is_specified(string connectionString, object wobj)
  722. {
  723. var expectedW = (wobj == null) ? null : (wobj is int) ? (WriteConcern.WValue)(int)wobj : (string)wobj;
  724. var subject = new ConnectionString(connectionString);
  725. subject.W.Should().Be(expectedW);
  726. }
  727. [Theory]
  728. [InlineData("mongodb://localhost?localThreshold=15ms", 15)]
  729. [InlineData("mongodb://localhost?localThresholdMS=15", 15)]
  730. [InlineData("mongodb://localhost?localThreshold=15", 1000 * 15)]
  731. [InlineData("mongodb://localhost?localThreshold=15s", 1000 * 15)]
  732. [InlineData("mongodb://localhost?localThreshold=15m", 1000 * 60 * 15)]
  733. [InlineData("mongodb://localhost?localThreshold=15h", 1000 * 60 * 60 * 15)]
  734. public void When_localThreshold_is_specified(string connectionString, int milliseconds)
  735. {
  736. var subject = new ConnectionString(connectionString);
  737. subject.LocalThreshold.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  738. }
  739. [Theory]
  740. [InlineData("mongodb://localhost?secondaryAcceptableLatency=15ms", 15)]
  741. [InlineData("mongodb://localhost?secondaryAcceptableLatencyMS=15", 15)]
  742. [InlineData("mongodb://localhost?secondaryAcceptableLatency=15", 1000 * 15)]
  743. [InlineData("mongodb://localhost?secondaryAcceptableLatency=15s", 1000 * 15)]
  744. [InlineData("mongodb://localhost?secondaryAcceptableLatency=15m", 1000 * 60 * 15)]
  745. [InlineData("mongodb://localhost?secondaryAcceptableLatency=15h", 1000 * 60 * 60 * 15)]
  746. public void When_secondaryAcceptableLatency_is_specified(string connectionString, int milliseconds)
  747. {
  748. var subject = new ConnectionString(connectionString);
  749. subject.LocalThreshold.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  750. }
  751. [Theory]
  752. [InlineData("mongodb://localhost?serverSelectionTimeout=15ms", 15)]
  753. [InlineData("mongodb://localhost?serverSelectionTimeoutMS=15", 15)]
  754. [InlineData("mongodb://localhost?serverSelectionTimeout=15", 1000 * 15)]
  755. [InlineData("mongodb://localhost?serverSelectionTimeout=15s", 1000 * 15)]
  756. [InlineData("mongodb://localhost?serverSelectionTimeout=15m", 1000 * 60 * 15)]
  757. [InlineData("mongodb://localhost?serverSelectionTimeout=15h", 1000 * 60 * 60 * 15)]
  758. public void When_serverSelectionTimeout_is_specified(string connectionString, int milliseconds)
  759. {
  760. var subject = new ConnectionString(connectionString);
  761. subject.ServerSelectionTimeout.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  762. }
  763. [Theory]
  764. [InlineData("mongodb://localhost?socketTimeout=15ms", 15)]
  765. [InlineData("mongodb://localhost?socketTimeoutMS=15", 15)]
  766. [InlineData("mongodb://localhost?socketTimeout=15", 1000 * 15)]
  767. [InlineData("mongodb://localhost?socketTimeout=15s", 1000 * 15)]
  768. [InlineData("mongodb://localhost?socketTimeout=15m", 1000 * 60 * 15)]
  769. [InlineData("mongodb://localhost?socketTimeout=15h", 1000 * 60 * 60 * 15)]
  770. public void When_socketTimeout_is_specified(string connectionString, int milliseconds)
  771. {
  772. var subject = new ConnectionString(connectionString);
  773. subject.SocketTimeout.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  774. }
  775. [Theory]
  776. [InlineData("mongodb://localhost?ssl=true", true)]
  777. [InlineData("mongodb://localhost?ssl=false", false)]
  778. public void When_ssl_is_specified(string connectionString, bool ssl)
  779. {
  780. var subject = new ConnectionString(connectionString);
  781. #pragma warning disable 618
  782. subject.Ssl.Should().Be(ssl);
  783. #pragma warning restore 618
  784. }
  785. [Theory]
  786. [InlineData("mongodb://localhost?sslVerifyCertificate=true", true)]
  787. [InlineData("mongodb://localhost?sslVerifyCertificate=false", false)]
  788. public void When_sslVerifyCertificate_is_specified(string connectionString, bool sslVerifyCertificate)
  789. {
  790. var subject = new ConnectionString(connectionString);
  791. #pragma warning disable 618
  792. subject.SslVerifyCertificate.Should().Be(sslVerifyCertificate);
  793. #pragma warning restore 618
  794. }
  795. [Theory]
  796. [InlineData("mongodb://localhost?tls=true", true)]
  797. [InlineData("mongodb://localhost?tls=false", false)]
  798. public void When_tls_is_specified(string connectionString, bool tls)
  799. {
  800. var subject = new ConnectionString(connectionString);
  801. subject.Tls.Should().Be(tls);
  802. }
  803. [Theory]
  804. [InlineData("mongodb://localhost?tlsInsecure=true", true)]
  805. [InlineData("mongodb://localhost?tlsInsecure=false", false)]
  806. public void When_tlsInsecure_is_specified(string connectionString, bool tlsInsecure)
  807. {
  808. var subject = new ConnectionString(connectionString);
  809. subject.TlsInsecure.Should().Be(tlsInsecure);
  810. }
  811. [Theory]
  812. [InlineData("mongodb://yes@localhost", "yes")]
  813. [InlineData("mongodb://username@localhost", "username")]
  814. public void When_username_is_specified(string connectionString, string username)
  815. {
  816. var subject = new ConnectionString(connectionString);
  817. subject.Username.Should().Be(username);
  818. }
  819. [Theory]
  820. [InlineData("mongodb://localhost?uuidRepresentation=standard", GuidRepresentation.Standard)]
  821. [InlineData("mongodb://localhost?guids=standard", GuidRepresentation.Standard)]
  822. [InlineData("mongodb://localhost?uuidRepresentation=csharpLegacy", GuidRepresentation.CSharpLegacy)]
  823. [InlineData("mongodb://localhost?guids=csharpLegacy", GuidRepresentation.CSharpLegacy)]
  824. [InlineData("mongodb://localhost?uuidRepresentation=javaLegacy", GuidRepresentation.JavaLegacy)]
  825. [InlineData("mongodb://localhost?guids=javaLegacy", GuidRepresentation.JavaLegacy)]
  826. [InlineData("mongodb://localhost?uuidRepresentation=pythonLegacy", GuidRepresentation.PythonLegacy)]
  827. [InlineData("mongodb://localhost?guids=pythonLegacy", GuidRepresentation.PythonLegacy)]
  828. public void When_uuidRepresentation_is_specified(string connectionString, GuidRepresentation representation)
  829. {
  830. var subject = new ConnectionString(connectionString);
  831. subject.UuidRepresentation.Should().Be(representation);
  832. }
  833. [Theory]
  834. [InlineData("mongodb://localhost?w=0", "0")]
  835. [InlineData("mongodb://localhost?w=1", "1")]
  836. [InlineData("mongodb://localhost?w=majority", "majority")]
  837. public void When_w_is_specified(string connectionString, string w)
  838. {
  839. var subject = new ConnectionString(connectionString);
  840. var expectedW = WriteConcern.WValue.Parse(w);
  841. subject.W.Should().Be(expectedW);
  842. }
  843. [Theory]
  844. [InlineData("mongodb://localhost?wtimeout=15ms", 15)]
  845. [InlineData("mongodb://localhost?wtimeoutMS=15", 15)]
  846. [InlineData("mongodb://localhost?wtimeout=15", 1000 * 15)]
  847. [InlineData("mongodb://localhost?wtimeout=15s", 1000 * 15)]
  848. [InlineData("mongodb://localhost?wtimeout=15m", 1000 * 60 * 15)]
  849. [InlineData("mongodb://localhost?wtimeout=15h", 1000 * 60 * 60 * 15)]
  850. public void When_wtimeout_is_specified(string connectionString, int milliseconds)
  851. {
  852. var subject = new ConnectionString(connectionString);
  853. subject.WTimeout.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  854. }
  855. [Theory]
  856. [InlineData("mongodb://localhost?waitQueueMultiple=-1", -1)]
  857. [InlineData("mongodb://localhost?waitQueueMultiple=0", 0)]
  858. [InlineData("mongodb://localhost?waitQueueMultiple=1", 1)]
  859. [InlineData("mongodb://localhost?waitQueueMultiple=20", 20)]
  860. [InlineData("mongodb://localhost?waitQueueMultiple=2.3", 2.3)]
  861. public void When_waitQueueMultiple_is_specified(string connectionString, double waitQueueMultiple)
  862. {
  863. var subject = new ConnectionString(connectionString);
  864. #pragma warning disable 618
  865. subject.WaitQueueMultiple.Should().Be(waitQueueMultiple);
  866. #pragma warning restore 618
  867. }
  868. [Theory]
  869. [InlineData("mongodb://localhost?waitQueueSize=-1", -1)]
  870. [InlineData("mongodb://localhost?waitQueueSize=0", 0)]
  871. [InlineData("mongodb://localhost?waitQueueSize=1", 1)]
  872. [InlineData("mongodb://localhost?waitQueueSize=20", 20)]
  873. public void When_waitQueueSize_is_specified(string connectionString, int waitQueueSize)
  874. {
  875. var subject = new ConnectionString(connectionString);
  876. #pragma warning disable 618
  877. subject.WaitQueueSize.Should().Be(waitQueueSize);
  878. #pragma warning restore 618
  879. }
  880. [Theory]
  881. [InlineData("mongodb://localhost?waitQueueTimeout=15ms", 15)]
  882. [InlineData("mongodb://localhost?waitQueueTimeoutMS=15", 15)]
  883. [InlineData("mongodb://localhost?waitQueueTimeout=15", 1000 * 15)]
  884. [InlineData("mongodb://localhost?waitQueueTimeout=15s", 1000 * 15)]
  885. [InlineData("mongodb://localhost?waitQueueTimeout=15m", 1000 * 60 * 15)]
  886. [InlineData("mongodb://localhost?waitQueueTimeout=15h", 1000 * 60 * 60 * 15)]
  887. public void When_waitQueueTimeout_is_specified(string connectionString, int milliseconds)
  888. {
  889. var subject = new ConnectionString(connectionString);
  890. subject.WaitQueueTimeout.Should().Be(TimeSpan.FromMilliseconds(milliseconds));
  891. }
  892. [Fact]
  893. public void When_uknown_options_exist()
  894. {
  895. var subject = new ConnectionString("mongodb://localhost?one=1;two=2");
  896. subject.AllUnknownOptionNames.Count().Should().Be(2);
  897. subject.AllUnknownOptionNames.Should().Contain("one");
  898. subject.AllUnknownOptionNames.Should().Contain("two");
  899. subject.GetOption("one").Should().Be("1");
  900. subject.GetOption("two").Should().Be("2");
  901. }
  902. [Fact]
  903. public void When_multiple_hosts_are_provided_with_a_srv_scheme()
  904. {
  905. var connectionString = "mongodb+srv://localhost1,localhost2";
  906. var exception = Record.Exception(() => new ConnectionString(connectionString));
  907. exception.Should().BeOfType<MongoConfigurationException>();
  908. }
  909. [Fact]
  910. public void When_a_port_is_specified_with_a_srv_scheme()
  911. {
  912. var connectionString = "mongodb+srv://localhost1:53";
  913. var exception = Record.Exception(() => new ConnectionString(connectionString));
  914. exception.Should().BeOfType<MongoConfigurationException>();
  915. }
  916. [Fact]
  917. public void When_calling_resolve_on_a_srv_connection_string()
  918. {
  919. // NOTE: this requires SRV and TXT records in DNS as specified here:
  920. // https://github.com/mongodb/specifications/tree/master/source/initial-dns-seedlist-discovery
  921. var connectionString = "mongodb+srv://user%40GSSAPI.COM:password@test5.test.build.10gen.cc/funny?replicaSet=rs0";
  922. var subject = new ConnectionString(connectionString);
  923. var resolved = subject.Resolve();
  924. resolved.ToString().Should().Be("mongodb://user%40GSSAPI.COM:password@localhost.test.build.10gen.cc:27017/funny/?authSource=thisDB&replicaSet=rs0&tls=true");
  925. }
  926. [Fact]
  927. public async Task When_calling_resolve_async_on_a_srv_connection_string()
  928. {
  929. // NOTE: this requires SRV and TXT records in DNS as specified here:
  930. // https://github.com/mongodb/specifications/tree/master/source/initial-dns-seedlist-discovery
  931. var connectionString = "mongodb+srv://user%40GSSAPI.COM:password@test5.test.build.10gen.cc/funny?replicaSet=rs0";
  932. var subject = new Connec

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