Skip to content

Commit 29a8892

Browse files
authored
CSHARP-2862: Check that max pool size is never less than min pool size in connection string (#1926)
1 parent 3c03123 commit 29a8892

6 files changed

Lines changed: 64 additions & 16 deletions

File tree

src/MongoDB.Driver/Core/Configuration/ConnectionString.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -958,6 +958,11 @@ private void Parse()
958958
throw new MongoConfigurationException("proxyUsername and proxyPassword must both be specified or neither.");
959959
}
960960

961+
if (_minPoolSize > _maxPoolSize)
962+
{
963+
throw new MongoConfigurationException("maxPoolSize must be greater than or equal to minPoolSize.");
964+
}
965+
961966
string ProtectConnectionString(string connectionString)
962967
{
963968
var protectedString = Regex.Replace(connectionString, @"(?<=://)[^/]*(?=@)", "<hidden>");
@@ -1055,7 +1060,7 @@ private void ParseOption(string name, string value)
10551060
{
10561061
throw new MongoConfigurationException("Multiple proxyHost options are not allowed.");
10571062
}
1058-
1063+
10591064
_proxyHost = value;
10601065
if (_proxyHost.Length == 0)
10611066
{

src/MongoDB.Driver/MongoClientSettings.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1366,6 +1366,11 @@ private void ThrowIfSettingsAreInvalid()
13661366
throw new InvalidOperationException("Load balanced mode cannot be used with direct connection.");
13671367
}
13681368
}
1369+
1370+
if (_maxConnectionPoolSize < _minConnectionPoolSize)
1371+
{
1372+
throw new InvalidOperationException("MaxConnectionPoolSize must be greater than or equal to MinConnectionPoolSize.");
1373+
}
13691374
}
13701375
}
13711376
}

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,28 @@ public void Invalid_srvMaxHosts_configuration_should_throw(string connectionStri
13201320
exception.Should().BeOfType<MongoConfigurationException>();
13211321
}
13221322

1323+
[Theory]
1324+
[InlineData("mongodb://localhost?maxPoolSize=5&minPoolSize=10", true)]
1325+
[InlineData("mongodb://localhost?maxPoolSize=10&minPoolSize=10", false)]
1326+
[InlineData("mongodb://localhost?maxPoolSize=10&minPoolSize=5", false)]
1327+
[InlineData("mongodb://localhost?maxPoolSize=10", false)]
1328+
[InlineData("mongodb://localhost?minPoolSize=5", false)]
1329+
public void MaxPoolSize_less_than_MinPoolSize_should_throw(string connectionString, bool shouldThrow)
1330+
{
1331+
var exception = Record.Exception(() => new ConnectionString(connectionString));
1332+
1333+
if (shouldThrow)
1334+
{
1335+
exception.Should().BeOfType<MongoConfigurationException>();
1336+
exception.Message.Should().Contain("maxPoolSize must be greater than or equal to minPoolSize.");
1337+
1338+
}
1339+
else
1340+
{
1341+
exception.Should().BeNull();
1342+
}
1343+
}
1344+
13231345
[Fact]
13241346
public void When_calling_resolve_on_a_srv_connection_string()
13251347
{

tests/MongoDB.Driver.Tests/MongoClientSettingsTests.cs

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ public void TestClone()
8888
var connectionString =
8989
"mongodb://user1:password1@somehost/?appname=app;" +
9090
"connect=direct;connectTimeout=123;ipv6=true;heartbeatInterval=1m;heartbeatTimeout=2m;localThreshold=128;loadBalanced=false;" +
91-
"maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=126;minPoolSize=127;readConcernLevel=majority;" +
91+
"maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=127;minPoolSize=126;readConcernLevel=majority;" +
9292
"readPreference=secondary;readPreferenceTags=a:1,b:2;readPreferenceTags=c:3,d:4;socketTimeout=129;" +
9393
"serverMonitoringMode=Stream;serverSelectionTimeout=20s;ssl=true;sslVerifyCertificate=false;waitqueuesize=130;waitQueueTimeout=131;" +
9494
"w=1;fsync=true;journal=true;w=2;wtimeout=131;gssapiServiceName=other;tlsInsecure=true";
@@ -586,7 +586,7 @@ public void TestFromUrl()
586586
var connectionString =
587587
"mongodb://user1:password1@somehost/?appname=app1;authSource=db;authMechanismProperties=CANONICALIZE_HOST_NAME:true;" +
588588
"compressors=zlib,snappy;zlibCompressionLevel=9;connectTimeout=123;directConnection=true;ipv6=true;heartbeatInterval=1m;heartbeatTimeout=2m;loadBalanced=false;localThreshold=128;" +
589-
"maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=126;minPoolSize=127;readConcernLevel=majority;" +
589+
"maxConnecting=3;maxIdleTime=124;maxLifeTime=125;maxPoolSize=127;minPoolSize=126;readConcernLevel=majority;" +
590590
"readPreference=secondary;readPreferenceTags=a:1,b:2;readPreferenceTags=c:3,d:4;retryReads=false;retryWrites=true;socketTimeout=129;" +
591591
"serverMonitoringMode=Stream;serverSelectionTimeout=20s;tls=true;sslVerifyCertificate=false;waitqueuesize=130;waitQueueTimeout=131;" +
592592
"w=1;fsync=true;journal=true;w=2;wtimeout=131;gssapiServiceName=other" +
@@ -929,7 +929,7 @@ public void TestMinConnectionPoolSize()
929929
var settings = new MongoClientSettings();
930930
Assert.Equal(MongoDefaults.MinConnectionPoolSize, settings.MinConnectionPoolSize);
931931

932-
var minConnectionPoolSize = 123;
932+
var minConnectionPoolSize = 90;
933933
settings.MinConnectionPoolSize = minConnectionPoolSize;
934934
Assert.Equal(minConnectionPoolSize, settings.MinConnectionPoolSize);
935935

@@ -938,6 +938,22 @@ public void TestMinConnectionPoolSize()
938938
Assert.Throws<InvalidOperationException>(() => { settings.MinConnectionPoolSize = minConnectionPoolSize; });
939939
}
940940

941+
[Fact]
942+
public void TestMaxAndMinConnectionPoolSize()
943+
{
944+
var settings = new MongoClientSettings();
945+
Assert.Equal(MongoDefaults.MinConnectionPoolSize, settings.MinConnectionPoolSize);
946+
947+
var minConnectionPoolSize = 10;
948+
var maxConnectionPoolSize = 5;
949+
settings.MinConnectionPoolSize = minConnectionPoolSize;
950+
settings.MaxConnectionPoolSize = maxConnectionPoolSize;
951+
Assert.Equal(minConnectionPoolSize, settings.MinConnectionPoolSize);
952+
Assert.Equal(maxConnectionPoolSize, settings.MaxConnectionPoolSize);
953+
954+
Assert.Throws<InvalidOperationException>(() => { settings.Freeze(); });
955+
}
956+
941957
[Fact]
942958
public void TestReadConcern()
943959
{

tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,8 @@ public void TestAll()
8181
MaxConnecting = 3,
8282
MaxConnectionIdleTime = TimeSpan.FromSeconds(2),
8383
MaxConnectionLifeTime = TimeSpan.FromSeconds(3),
84-
MaxConnectionPoolSize = 4,
85-
MinConnectionPoolSize = 5,
84+
MaxConnectionPoolSize = 5,
85+
MinConnectionPoolSize = 4,
8686
Password = "password",
8787
ReadConcernLevel = ReadConcernLevel.Majority,
8888
ReadPreference = readPreference,
@@ -138,8 +138,8 @@ public void TestAll()
138138
"maxConnecting=3",
139139
"maxIdleTime=2s",
140140
"maxLifeTime=3s",
141-
"maxPoolSize=4",
142-
"minPoolSize=5",
141+
"maxPoolSize=5",
142+
"minPoolSize=4",
143143
"serverMonitoringMode=Poll",
144144
"serverSelectionTimeout=10s",
145145
"socketTimeout=7s",
@@ -177,8 +177,8 @@ public void TestAll()
177177
Assert.Equal(TimeSpan.FromSeconds(2), builder.MaxConnectionIdleTime);
178178
Assert.Equal(TimeSpan.FromSeconds(3), builder.MaxConnectionLifeTime);
179179
Assert.Equal(3, builder.MaxConnecting);
180-
Assert.Equal(4, builder.MaxConnectionPoolSize);
181-
Assert.Equal(5, builder.MinConnectionPoolSize);
180+
Assert.Equal(4, builder.MinConnectionPoolSize);
181+
Assert.Equal(5, builder.MaxConnectionPoolSize);
182182
Assert.Equal("password", builder.Password);
183183
Assert.Equal(ReadConcernLevel.Majority, builder.ReadConcernLevel);
184184
Assert.Equal(readPreference, builder.ReadPreference);

tests/MongoDB.Driver.Tests/MongoUrlTests.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -172,8 +172,8 @@ public void TestAll()
172172
MaxConnecting = 3,
173173
MaxConnectionIdleTime = TimeSpan.FromSeconds(2),
174174
MaxConnectionLifeTime = TimeSpan.FromSeconds(3),
175-
MaxConnectionPoolSize = 4,
176-
MinConnectionPoolSize = 5,
175+
MaxConnectionPoolSize = 5,
176+
MinConnectionPoolSize = 4,
177177
Password = "password",
178178
ReadConcernLevel = ReadConcernLevel.Majority,
179179
ReadPreference = readPreference,
@@ -223,8 +223,8 @@ public void TestAll()
223223
"maxConnecting=3",
224224
"maxIdleTime=2s",
225225
"maxLifeTime=3s",
226-
"maxPoolSize=4",
227-
"minPoolSize=5",
226+
"maxPoolSize=5",
227+
"minPoolSize=4",
228228
"serverMonitoringMode=Poll",
229229
"serverSelectionTimeout=10s",
230230
"socketTimeout=7s",
@@ -260,8 +260,8 @@ public void TestAll()
260260
Assert.Equal(3, url.MaxConnecting);
261261
Assert.Equal(TimeSpan.FromSeconds(2), url.MaxConnectionIdleTime);
262262
Assert.Equal(TimeSpan.FromSeconds(3), url.MaxConnectionLifeTime);
263-
Assert.Equal(4, url.MaxConnectionPoolSize);
264-
Assert.Equal(5, url.MinConnectionPoolSize);
263+
Assert.Equal(5, url.MaxConnectionPoolSize);
264+
Assert.Equal(4, url.MinConnectionPoolSize);
265265
Assert.Equal("password", url.Password);
266266
Assert.Equal(ReadConcernLevel.Majority, url.ReadConcernLevel);
267267
Assert.Equal(readPreference, url.ReadPreference);

0 commit comments

Comments
 (0)