diff --git a/src/MongoDB.Driver/Core/Configuration/ConnectionSettings.cs b/src/MongoDB.Driver/Core/Configuration/ConnectionSettings.cs index 6d66cd85995..4edcdecfdbe 100644 --- a/src/MongoDB.Driver/Core/Configuration/ConnectionSettings.cs +++ b/src/MongoDB.Driver/Core/Configuration/ConnectionSettings.cs @@ -59,7 +59,7 @@ public ConnectionSettings( _connectionIdLocalValueProvider = LongIdGenerator.GetNextId; _libraryInfo = libraryInfo.WithDefault(null); _loadBalanced = loadBalanced.WithDefault(false); - _maxIdleTime = Ensure.IsGreaterThanZero(maxIdleTime.WithDefault(TimeSpan.FromMinutes(10)), "maxIdleTime"); + _maxIdleTime = Ensure.IsGreaterThanOrEqualToZero(maxIdleTime.WithDefault(TimeSpan.FromMinutes(10)), "maxIdleTime"); _maxLifeTime = Ensure.IsGreaterThanZero(maxLifeTime.WithDefault(TimeSpan.FromMinutes(30)), "maxLifeTime"); _applicationName = ApplicationNameHelper.EnsureApplicationNameIsValid(applicationName.WithDefault(null), nameof(applicationName)); } @@ -79,7 +79,7 @@ internal ConnectionSettings( _connectionIdLocalValueProvider = connectionIdLocalValueProvider.WithDefault(LongIdGenerator.GetNextId); _libraryInfo = libraryInfo.WithDefault(null); _loadBalanced = loadBalanced.WithDefault(false); - _maxIdleTime = Ensure.IsGreaterThanZero(maxIdleTime.WithDefault(TimeSpan.FromMinutes(10)), "maxIdleTime"); + _maxIdleTime = Ensure.IsGreaterThanOrEqualToZero(maxIdleTime.WithDefault(TimeSpan.FromMinutes(10)), "maxIdleTime"); _maxLifeTime = Ensure.IsGreaterThanZero(maxLifeTime.WithDefault(TimeSpan.FromMinutes(30)), "maxLifeTime"); _applicationName = ApplicationNameHelper.EnsureApplicationNameIsValid(applicationName.WithDefault(null), nameof(applicationName)); } diff --git a/src/MongoDB.Driver/Core/Connections/BinaryConnection.cs b/src/MongoDB.Driver/Core/Connections/BinaryConnection.cs index 43a5723dab1..3f9cfd24a35 100644 --- a/src/MongoDB.Driver/Core/Connections/BinaryConnection.cs +++ b/src/MongoDB.Driver/Core/Connections/BinaryConnection.cs @@ -123,7 +123,7 @@ public bool IsExpired } // connection has been idle for too long - if (_settings.MaxIdleTime.TotalMilliseconds > -1 && now > _lastUsedAtUtc.Add(_settings.MaxIdleTime)) + if (_settings.MaxIdleTime.TotalMilliseconds > 0 && now > _lastUsedAtUtc.Add(_settings.MaxIdleTime)) { return true; } diff --git a/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionSettingsTests.cs b/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionSettingsTests.cs index c98f479dda4..a97a46ed968 100644 --- a/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionSettingsTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Configuration/ConnectionSettingsTests.cs @@ -61,17 +61,21 @@ public void constructor_should_throw_when_compressors_is_null() e.ParamName.Should().Be("compressors"); } - [Theory] - [ParameterAttributeData] - public void constructor_should_throw_when_maxIdleTime_is_negative_or_zero( - [Values(-1, 0)] - int maxIdleTime) + [Fact] + public void constructor_should_throw_when_maxIdleTime_is_negative() { - Action action = () => new ConnectionSettings(maxIdleTime: TimeSpan.FromSeconds(maxIdleTime)); + Action action = () => new ConnectionSettings(maxIdleTime: TimeSpan.FromSeconds(-1)); action.ShouldThrow().And.ParamName.Should().Be("maxIdleTime"); } + [Fact] + public void constructor_should_not_throw_when_maxIdleTime_is_zero() + { + var subject = new ConnectionSettings(maxIdleTime: TimeSpan.FromSeconds(0)); + subject.MaxIdleTime.Should().Be(TimeSpan.Zero); + } + [Theory] [ParameterAttributeData] public void constructor_should_throw_when_maxLifeTime_is_negative_or_zero( diff --git a/tests/MongoDB.Driver.Tests/Core/Connections/BinaryConnectionTests.cs b/tests/MongoDB.Driver.Tests/Core/Connections/BinaryConnectionTests.cs index cfe214d5707..58d25aec012 100644 --- a/tests/MongoDB.Driver.Tests/Core/Connections/BinaryConnectionTests.cs +++ b/tests/MongoDB.Driver.Tests/Core/Connections/BinaryConnectionTests.cs @@ -713,6 +713,44 @@ public async Task SendMessage_should_put_the_message_on_the_stream_and_raise_the } } + [Fact] + public void IsExpired_should_return_false_when_maxIdleTime_has_no_limit() + { + var subject = new BinaryConnection( + serverId: _serverId, + endPoint: _endPoint, + settings: new ConnectionSettings(maxIdleTime: TimeSpan.FromMilliseconds(0)), + streamFactory: _mockStreamFactory.Object, + connectionInitializer: _mockConnectionInitializer.Object, + eventSubscriber: _capturedEvents, + loggerFactory: LoggerFactory, + tracingOptions: null, + socketReadTimeout: TimeSpan.FromMilliseconds(1000), + socketWriteTimeout: TimeSpan.FromMilliseconds(1000)); + + subject.Open(OperationContext.NoTimeout); + subject.IsExpired.Should().BeFalse(); + } + + [Fact] + public void IsExpired_should_return_true_when_maxIdleTime_is_exceeded() + { + var subject = new BinaryConnection( + serverId: _serverId, + endPoint: _endPoint, + settings: new ConnectionSettings(maxIdleTime: TimeSpan.FromMilliseconds(10), maxLifeTime: TimeSpan.FromMinutes(10)), + streamFactory: _mockStreamFactory.Object, + connectionInitializer: _mockConnectionInitializer.Object, + eventSubscriber: _capturedEvents, + loggerFactory: LoggerFactory, + tracingOptions: null, + socketReadTimeout: TimeSpan.FromMilliseconds(1000), + socketWriteTimeout: TimeSpan.FromMilliseconds(1000)); + + subject.Open(OperationContext.NoTimeout); + subject.IsExpired.Should().BeTrue(); + } + private void SetupStreamRead(Mock streamMock, TaskCompletionSource tcs) { streamMock.Setup(s => s.Read(It.IsAny(), It.IsAny(), It.IsAny())) diff --git a/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs b/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs index 9fb3c0159cf..457c1dfe1fa 100644 --- a/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs +++ b/tests/MongoDB.Driver.Tests/MongoUrlBuilderTests.cs @@ -700,6 +700,7 @@ public void TestMaxConnecting([Values(0, -1)] int incorrectMaxConnecting) [Theory] [InlineData(null, "mongodb://localhost", new[] { "" })] + [InlineData(0, "mongodb://localhost/?maxIdleTime{0}", new[] { "=0h", "MS=0", "=0ms", "=0" })] [InlineData(500, "mongodb://localhost/?maxIdleTime{0}", new[] { "=500ms", "=0.5", "=0.5s", "=00:00:00.5", "MS=500" })] [InlineData(30000, "mongodb://localhost/?maxIdleTime{0}", new[] { "=30s", "=30000ms", "=30", "=0.5m", "=00:00:30", "MS=30000" })] [InlineData(1800000, "mongodb://localhost/?maxIdleTime{0}", new[] { "=30m", "=1800000ms", "=1800", "=1800s", "=0.5h", "=00:30:00", "MS=1800000" })]