diff --git a/src/MongoDB.Driver/Core/Configuration/ConnectionString.cs b/src/MongoDB.Driver/Core/Configuration/ConnectionString.cs index 73e9279ec4f..573329bf2db 100644 --- a/src/MongoDB.Driver/Core/Configuration/ConnectionString.cs +++ b/src/MongoDB.Driver/Core/Configuration/ConnectionString.cs @@ -958,6 +958,11 @@ private void Parse() throw new MongoConfigurationException("proxyUsername and proxyPassword must both be specified or neither."); } + if (_minPoolSize > _maxPoolSize) + { + throw new MongoConfigurationException("maxPoolSize must be greater than or equal to minPoolSize."); + } + string ProtectConnectionString(string connectionString) { var protectedString = Regex.Replace(connectionString, @"(?<=://)[^/]*(?=@)", ""); @@ -1055,7 +1060,7 @@ private void ParseOption(string name, string value) { throw new MongoConfigurationException("Multiple proxyHost options are not allowed."); } - + _proxyHost = value; if (_proxyHost.Length == 0) { diff --git a/src/MongoDB.Driver/MongoClientSettings.cs b/src/MongoDB.Driver/MongoClientSettings.cs index 90122b08aff..27e1e7f71d3 100644 --- a/src/MongoDB.Driver/MongoClientSettings.cs +++ b/src/MongoDB.Driver/MongoClientSettings.cs @@ -1366,6 +1366,11 @@ private void ThrowIfSettingsAreInvalid() throw new InvalidOperationException("Load balanced mode cannot be used with direct connection."); } } + + if (_maxConnectionPoolSize < _minConnectionPoolSize) + { + throw new InvalidOperationException("MaxConnectionPoolSize must be greater than or equal to MinConnectionPoolSize."); + } } } } diff --git a/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionStringTests.cs b/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionStringTests.cs index 8ea1d64ac31..33dbe586c53 100644 --- a/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionStringTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionStringTests.cs @@ -1320,6 +1320,28 @@ public void Invalid_srvMaxHosts_configuration_should_throw(string connectionStri exception.Should().BeOfType(); } + [Theory] + [InlineData("mongodb://localhost?maxPoolSize=5&minPoolSize=10", true)] + [InlineData("mongodb://localhost?maxPoolSize=10&minPoolSize=10", false)] + [InlineData("mongodb://localhost?maxPoolSize=10&minPoolSize=5", false)] + [InlineData("mongodb://localhost?maxPoolSize=10", false)] + [InlineData("mongodb://localhost?minPoolSize=5", false)] + public void MaxPoolSize_less_than_MinPoolSize_should_throw(string connectionString, bool shouldThrow) + { + var exception = Record.Exception(() => new ConnectionString(connectionString)); + + if (shouldThrow) + { + exception.Should().BeOfType(); + exception.Message.Should().Contain("maxPoolSize must be greater than or equal to minPoolSize."); + + } + else + { + exception.Should().BeNull(); + } + } + [Fact] public void When_calling_resolve_on_a_srv_connection_string() { diff --git a/tests/MongoDB.Driver.Tests/MongoClientSettingsTests.cs b/tests/MongoDB.Driver.Tests/MongoClientSettingsTests.cs index 48bf2608fcb..8d5d99cada2 100644 --- a/tests/MongoDB.Driver.Tests/MongoClientSettingsTests.cs +++ b/tests/MongoDB.Driver.Tests/MongoClientSettingsTests.cs @@ -88,7 +88,7 @@ public void TestClone() var connectionString = "mongodb://user1:password1@somehost/?appname=app;" + "connect=direct;connectTimeout=123;ipv6=true;heartbeatInterval=1m;heartbeatTimeout=2m;localThreshold=128;loadBalanced=false;" + - "maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=126;minPoolSize=127;readConcernLevel=majority;" + + "maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=127;minPoolSize=126;readConcernLevel=majority;" + "readPreference=secondary;readPreferenceTags=a:1,b:2;readPreferenceTags=c:3,d:4;socketTimeout=129;" + "serverMonitoringMode=Stream;serverSelectionTimeout=20s;ssl=true;sslVerifyCertificate=false;waitqueuesize=130;waitQueueTimeout=131;" + "w=1;fsync=true;journal=true;w=2;wtimeout=131;gssapiServiceName=other;tlsInsecure=true"; @@ -586,7 +586,7 @@ public void TestFromUrl() var connectionString = "mongodb://user1:password1@somehost/?appname=app1;authSource=db;authMechanismProperties=CANONICALIZE_HOST_NAME:true;" + "compressors=zlib,snappy;zlibCompressionLevel=9;connectTimeout=123;directConnection=true;ipv6=true;heartbeatInterval=1m;heartbeatTimeout=2m;loadBalanced=false;localThreshold=128;" + - "maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=126;minPoolSize=127;readConcernLevel=majority;" + + "maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=127;minPoolSize=126;readConcernLevel=majority;" + "readPreference=secondary;readPreferenceTags=a:1,b:2;readPreferenceTags=c:3,d:4;retryReads=false;retryWrites=true;socketTimeout=129;" + "serverMonitoringMode=Stream;serverSelectionTimeout=20s;tls=true;sslVerifyCertificate=false;waitqueuesize=130;waitQueueTimeout=131;" + "w=1;fsync=true;journal=true;w=2;wtimeout=131;gssapiServiceName=other" + @@ -929,7 +929,7 @@ public void TestMinConnectionPoolSize() var settings = new MongoClientSettings(); Assert.Equal(MongoDefaults.MinConnectionPoolSize, settings.MinConnectionPoolSize); - var minConnectionPoolSize = 123; + var minConnectionPoolSize = 90; settings.MinConnectionPoolSize = minConnectionPoolSize; Assert.Equal(minConnectionPoolSize, settings.MinConnectionPoolSize); @@ -938,6 +938,22 @@ public void TestMinConnectionPoolSize() Assert.Throws(() => { settings.MinConnectionPoolSize = minConnectionPoolSize; }); } + [Fact] + public void TestMaxAndMinConnectionPoolSize() + { + var settings = new MongoClientSettings(); + Assert.Equal(MongoDefaults.MinConnectionPoolSize, settings.MinConnectionPoolSize); + + var minConnectionPoolSize = 10; + var maxConnectionPoolSize = 5; + settings.MinConnectionPoolSize = minConnectionPoolSize; + settings.MaxConnectionPoolSize = maxConnectionPoolSize; + Assert.Equal(minConnectionPoolSize, settings.MinConnectionPoolSize); + Assert.Equal(maxConnectionPoolSize, settings.MaxConnectionPoolSize); + + Assert.Throws(() => { settings.Freeze(); }); + } + [Fact] public void TestReadConcern() { diff --git a/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs b/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs index 8b09cce9b32..9fb3c0159cf 100644 --- a/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs +++ b/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs @@ -81,8 +81,8 @@ public void TestAll() MaxConnecting = 3, MaxConnectionIdleTime = TimeSpan.FromSeconds(2), MaxConnectionLifeTime = TimeSpan.FromSeconds(3), - MaxConnectionPoolSize = 4, - MinConnectionPoolSize = 5, + MaxConnectionPoolSize = 5, + MinConnectionPoolSize = 4, Password = "password", ReadConcernLevel = ReadConcernLevel.Majority, ReadPreference = readPreference, @@ -138,8 +138,8 @@ public void TestAll() "maxConnecting=3", "maxIdleTime=2s", "maxLifeTime=3s", - "maxPoolSize=4", - "minPoolSize=5", + "maxPoolSize=5", + "minPoolSize=4", "serverMonitoringMode=Poll", "serverSelectionTimeout=10s", "socketTimeout=7s", @@ -177,8 +177,8 @@ public void TestAll() Assert.Equal(TimeSpan.FromSeconds(2), builder.MaxConnectionIdleTime); Assert.Equal(TimeSpan.FromSeconds(3), builder.MaxConnectionLifeTime); Assert.Equal(3, builder.MaxConnecting); - Assert.Equal(4, builder.MaxConnectionPoolSize); - Assert.Equal(5, builder.MinConnectionPoolSize); + Assert.Equal(4, builder.MinConnectionPoolSize); + Assert.Equal(5, builder.MaxConnectionPoolSize); Assert.Equal("password", builder.Password); Assert.Equal(ReadConcernLevel.Majority, builder.ReadConcernLevel); Assert.Equal(readPreference, builder.ReadPreference); diff --git a/tests/MongoDB.Driver.Tests/MongoUrlTests.cs b/tests/MongoDB.Driver.Tests/MongoUrlTests.cs index 96a23b8240b..a4fd5f8e13b 100644 --- a/tests/MongoDB.Driver.Tests/MongoUrlTests.cs +++ b/tests/MongoDB.Driver.Tests/MongoUrlTests.cs @@ -172,8 +172,8 @@ public void TestAll() MaxConnecting = 3, MaxConnectionIdleTime = TimeSpan.FromSeconds(2), MaxConnectionLifeTime = TimeSpan.FromSeconds(3), - MaxConnectionPoolSize = 4, - MinConnectionPoolSize = 5, + MaxConnectionPoolSize = 5, + MinConnectionPoolSize = 4, Password = "password", ReadConcernLevel = ReadConcernLevel.Majority, ReadPreference = readPreference, @@ -223,8 +223,8 @@ public void TestAll() "maxConnecting=3", "maxIdleTime=2s", "maxLifeTime=3s", - "maxPoolSize=4", - "minPoolSize=5", + "maxPoolSize=5", + "minPoolSize=4", "serverMonitoringMode=Poll", "serverSelectionTimeout=10s", "socketTimeout=7s", @@ -260,8 +260,8 @@ public void TestAll() Assert.Equal(3, url.MaxConnecting); Assert.Equal(TimeSpan.FromSeconds(2), url.MaxConnectionIdleTime); Assert.Equal(TimeSpan.FromSeconds(3), url.MaxConnectionLifeTime); - Assert.Equal(4, url.MaxConnectionPoolSize); - Assert.Equal(5, url.MinConnectionPoolSize); + Assert.Equal(5, url.MaxConnectionPoolSize); + Assert.Equal(4, url.MinConnectionPoolSize); Assert.Equal("password", url.Password); Assert.Equal(ReadConcernLevel.Majority, url.ReadConcernLevel); Assert.Equal(readPreference, url.ReadPreference);