public void TestWithConnectionFactoryDefaults() { var mockConnectionFactory = new Mock <ConnectionFactory>(); var mockConnection = new Mock <IConnection>(); var mockChannel = new Mock <IModel>(); mockConnectionFactory.Setup(factory => factory.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(connection => connection.CreateModel()).Returns(mockChannel.Object); mockChannel.Setup(chan => chan.IsOpen).Returns(true); mockConnection.Setup(conn => conn.IsOpen).Returns(true); var ccf = new CachingConnectionFactory(mockConnectionFactory.Object); var con = ccf.CreateConnection(); var channel = con.CreateChannel(false); channel.Close(); // should be ignored, and placed into channel cache. con.Close(); // should be ignored var con2 = ccf.CreateConnection(); /* * will retrieve same channel object that was just put into channel cache */ var channel2 = con2.CreateChannel(false); channel2.Close(); // should be ignored con2.Close(); // should be ignored Assert.AreSame(con, con2); Assert.AreSame(channel, channel2); mockConnection.Verify(conn => conn.Close(), Times.Never()); mockChannel.Verify(chan => chan.Close(), Times.Never()); }
public void TestChannelCache() { var channelCf = new CachingConnectionFactory("localhost") { ServiceName = "testChannelCache", ChannelCacheSize = 4 }; var c1 = channelCf.CreateConnection(); var c2 = channelCf.CreateConnection(); Assert.Same(c1, c2); var ch1 = c1.CreateChannel(false); var ch2 = c1.CreateChannel(false); var ch3 = c1.CreateChannel(true); var ch4 = c1.CreateChannel(true); var ch5 = c1.CreateChannel(true); ch1.Close(); ch2.Close(); ch3.Close(); ch4.Close(); ch5.Close(); var props = channelCf.GetCacheProperties(); Assert.StartsWith("testChannelCache", (string)props["connectionName"]); Assert.Equal(4, props["channelCacheSize"]); Assert.Equal(2, props["idleChannelsNotTx"]); Assert.Equal(3, props["idleChannelsTx"]); Assert.Equal(2, props["idleChannelsNotTxHighWater"]); Assert.Equal(3, props["idleChannelsTxHighWater"]); ch1 = c1.CreateChannel(false); ch3 = c1.CreateChannel(true); props = channelCf.GetCacheProperties(); Assert.Equal(1, props["idleChannelsNotTx"]); Assert.Equal(2, props["idleChannelsTx"]); Assert.Equal(2, props["idleChannelsNotTxHighWater"]); Assert.Equal(3, props["idleChannelsTxHighWater"]); ch1 = c1.CreateChannel(false); ch2 = c1.CreateChannel(false); ch3 = c1.CreateChannel(true); ch4 = c1.CreateChannel(true); ch5 = c1.CreateChannel(true); var ch6 = c1.CreateChannel(true); var ch7 = c1.CreateChannel(true); // #5 ch1.Close(); ch2.Close(); ch3.Close(); ch4.Close(); ch5.Close(); ch6.Close(); ch7.Close(); props = channelCf.GetCacheProperties(); Assert.Equal(2, props["idleChannelsNotTx"]); Assert.Equal(4, props["idleChannelsTx"]); Assert.Equal(2, props["idleChannelsNotTxHighWater"]); Assert.Equal(4, props["idleChannelsTxHighWater"]); }
public static void CreateConnection_WhenCalledTwice_OnlyCreatesConnectionOnce() { var factory = new Mock <IDbConnectionFactory>(); factory.Setup(f => f.CreateConnection()).Returns(Mock.Of <IDbConnection>); var cachingFactory = new CachingConnectionFactory(factory.Object); _ = cachingFactory.CreateConnection(); _ = cachingFactory.CreateConnection(); factory.Verify(f => f.CreateConnection(), Times.Once); }
public void TestTransactionalAndNonTransactionalChannelsSegregated() { var mockConnectionFactory = new Mock <ConnectionFactory>(); var mockConnection = new Mock <IConnection>(); var mockChannel1 = new Mock <IModel>(); var mockChannel2 = new Mock <IModel>(); mockConnectionFactory.Setup(c => c.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(c => c.CreateModel()).ReturnsInOrder(mockChannel1.Object, mockChannel2.Object); mockConnection.Setup(c => c.IsOpen).Returns(true); // Called during physical close mockChannel1.Setup(c => c.IsOpen).Returns(true); mockChannel2.Setup(c => c.IsOpen).Returns(true); var ccf = new CachingConnectionFactory(mockConnectionFactory.Object); ccf.ChannelCacheSize = 1; var con = ccf.CreateConnection(); var channel1 = con.CreateChannel(true); channel1.TxSelect(); channel1.Close(); // should be ignored, and add last into channel cache. /* * When a channel is created as non-transactional we should create a new one. */ var channel2 = con.CreateChannel(false); channel2.Close(); // should be ignored, and add last into channel cache. Assert.AreNotSame(channel1, channel2); var ch1 = con.CreateChannel(true); // remove first entry in cache (channel1) var ch2 = con.CreateChannel(false); // create new channel Assert.AreNotSame(ch1, ch2); Assert.AreSame(ch1, channel1); // The non-transactional one Assert.AreSame(ch2, channel2); ch1.Close(); ch2.Close(); mockConnection.Verify(c => c.CreateModel(), Times.Exactly(2)); con.Close(); // should be ignored mockConnection.Verify(c => c.Close(), Times.Never()); mockChannel1.Verify(c => c.Close(), Times.Never()); mockChannel2.Verify(c => c.Close(), Times.Never()); var notxlist = (LinkedList <IChannelProxy>)ReflectionUtils.GetInstanceFieldValue(ccf, "cachedChannelsNonTransactional"); Assert.AreEqual(1, notxlist.Count); var txlist = (LinkedList <IChannelProxy>)ReflectionUtils.GetInstanceFieldValue(ccf, "cachedChannelsTransactional"); Assert.AreEqual(1, txlist.Count); }
public void TestRetry() { var connectionFactory = new Mock <RC.IConnectionFactory>(); var connection = new Mock <RC.IConnection>(); connection.Setup(c => c.IsOpen).Returns(true); connectionFactory.Setup((f) => f.CreateConnection(It.IsAny <string>())).Returns(connection.Object); var channel1 = new Mock <RC.IModel>(); channel1.Setup(c => c.IsOpen).Returns(true); connection.Setup(c => c.CreateModel()).Returns(channel1.Object); channel1.Setup((c) => c.QueueDeclare(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >())).Throws <Exception>(); var ccf = new CachingConnectionFactory(connectionFactory.Object); var rtt = new PollyRetryTemplate(new Dictionary <Type, bool>(), 3, true, 1, 1, 1); var serviceCollection = CreateContainer(); serviceCollection.AddSingleton <IConnectionFactory>(ccf); serviceCollection.AddRabbitAdmin((p, a) => { a.RetryTemplate = rtt; }); var foo = new Config.AnonymousQueue("foo"); serviceCollection.AddRabbitQueue(foo); var provider = serviceCollection.BuildServiceProvider(); var admin = provider.GetRabbitAdmin(); Assert.Throws <RabbitUncategorizedException>(() => ccf.CreateConnection()); channel1.Verify((c) => c.QueueDeclare(It.IsAny <string>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <bool>(), It.IsAny <IDictionary <string, object> >()), Times.Exactly(3)); }
public void TestConnectionCache() { var connectionCf = new CachingConnectionFactory("localhost") { ChannelCacheSize = 10, ConnectionCacheSize = 5, CacheMode = CachingMode.CONNECTION, ServiceName = "testConnectionCache" }; var c1 = connectionCf.CreateConnection(); var c2 = connectionCf.CreateConnection(); var ch1 = c1.CreateChannel(false); var ch2 = c1.CreateChannel(false); var ch3 = c2.CreateChannel(true); var ch4 = c2.CreateChannel(true); var ch5 = c2.CreateChannel(false); ch1.Close(); ch2.Close(); ch3.Close(); ch4.Close(); ch5.Close(); c1.Close(); var props = connectionCf.GetCacheProperties(); Assert.Equal(10, props["channelCacheSize"]); Assert.Equal(5, props["connectionCacheSize"]); Assert.Equal(2, props["openConnections"]); Assert.Equal(1, props["idleConnections"]); c2.Close(); props = connectionCf.GetCacheProperties(); Assert.Equal(2, props["idleConnections"]); Assert.Equal(2, props["idleConnectionsHighWater"]); var c1Port = c1.LocalPort; var c2Port = c2.LocalPort; Assert.StartsWith("testConnectionCache:1", (string)props["connectionName:" + c1Port]); Assert.StartsWith("testConnectionCache:2", (string)props["connectionName:" + c2Port]); Assert.Equal(2, props["idleChannelsNotTx:" + c1Port]); Assert.Equal(0, props["idleChannelsTx:" + c1Port]); Assert.Equal(2, props["idleChannelsNotTxHighWater:" + c1Port]); Assert.Equal(0, props["idleChannelsTxHighWater:" + c1Port]); Assert.Equal(1, props["idleChannelsNotTx:" + c2Port]); Assert.Equal(2, props["idleChannelsTx:" + c2Port]); Assert.Equal(1, props["idleChannelsNotTxHighWater:" + c2Port]); Assert.Equal(2, props["idleChannelsTxHighWater:" + c2Port]); }
public void TestCacheSizeExceeded() { var mockConnectionFactory = new Mock <ConnectionFactory>(); var mockConnection = new Mock <IConnection>(); var mockChannel1 = new Mock <IModel>(); var mockChannel2 = new Mock <IModel>(); var mockChannel3 = new Mock <IModel>(); mockConnectionFactory.Setup(c => c.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(c => c.CreateModel()).ReturnsInOrder(mockChannel1.Object, mockChannel2.Object, mockChannel3.Object); mockConnection.Setup(c => c.IsOpen).Returns(true); // Called during physical close mockChannel1.Setup(c => c.IsOpen).Returns(true); mockChannel2.Setup(c => c.IsOpen).Returns(true); mockChannel3.Setup(c => c.IsOpen).Returns(true); var ccf = new CachingConnectionFactory(mockConnectionFactory.Object); ccf.ChannelCacheSize = 1; var con = ccf.CreateConnection(); var channel1 = con.CreateChannel(false); // cache size is 1, but the other connection is not released yet so this creates a new one var channel2 = con.CreateChannel(false); Assert.AreNotSame(channel1, channel2); // should be ignored, and added last into channel cache. channel1.Close(); // should be physically closed channel2.Close(); // remove first entry in cache (channel1) var ch1 = con.CreateChannel(false); // create a new channel var ch2 = con.CreateChannel(false); Assert.AreNotSame(ch1, ch2); Assert.AreSame(ch1, channel1); Assert.AreNotSame(ch2, channel2); ch1.Close(); ch2.Close(); mockConnection.Verify(c => c.CreateModel(), Times.Exactly(3)); con.Close(); // should be ignored mockConnection.Verify(c => c.Close(), Times.Never()); mockChannel1.Verify(c => c.Close(), Times.Never()); mockChannel2.Verify(c => c.Close(), Times.AtLeastOnce()); mockChannel3.Verify(c => c.Close(), Times.AtLeastOnce()); }
protected CachingConnectionFactory GetResource() { if (CachingConnectionFactory == null) { CachingConnectionFactory = new CachingConnectionFactory("localhost"); CachingConnectionFactory.CreateConnection().Close(); } return(CachingConnectionFactory); }
public void TestUninterruptibleListenerDMLC() { var cf = new CachingConnectionFactory("localhost"); var admin = new RabbitAdmin(cf); admin.DeclareQueue(new Config.Queue("test.shutdown")); var container = new DirectMessageListenerContainer(null, cf) { ShutdownTimeout = 500 }; container.SetQueueNames("test.shutdown"); var latch = new CountdownEvent(1); var testEnded = new CountdownEvent(1); var listener = new TestListener(latch, testEnded); container.MessageListener = listener; var connection = cf.CreateConnection() as ChannelCachingConnectionProxy; // var channels = TestUtils.getPropertyValue(connection, "target.delegate._channelManager._channelMap"); var field = typeof(RC.Framing.Impl.Connection) .GetField("m_sessionManager", BindingFlags.Instance | BindingFlags.NonPublic); Assert.NotNull(field); var channels = (SessionManager)field.GetValue(connection.Target.Connection); Assert.NotNull(channels); container.Start(); Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10))); try { var template = new RabbitTemplate(cf); template.Execute(c => { var properties = c.CreateBasicProperties(); var bytes = EncodingUtils.GetDefaultEncoding().GetBytes("foo"); c.BasicPublish(string.Empty, "test.shutdown", false, properties, bytes); RabbitUtils.SetPhysicalCloseRequired(c, false); }); Assert.True(latch.Wait(TimeSpan.FromSeconds(30))); Assert.Equal(2, channels.Count); } finally { container.Stop(); Assert.Equal(1, channels.Count); cf.Destroy(); testEnded.Signal(); admin.DeleteQueue("test.shutdown"); } }
public void TestNoDeclareWithCachedConnections() { var services = new ServiceCollection(); var config = new ConfigurationBuilder().Build(); services.AddLogging(b => { b.AddDebug(); b.AddConsole(); }); services.AddSingleton <IConfiguration>(config); services.AddRabbitHostingServices(); var mockConnectionFactory = new Mock <RC.IConnectionFactory>(); var mockConnections = new List <RC.IConnection>(); var mockChannels = new List <RC.IModel>(); var connectionNumber = new AtomicInteger(-1); var channelNumber = new AtomicInteger(-1); mockConnectionFactory.Setup(f => f.CreateConnection(It.IsAny <string>())) .Callback(() => { var connection = new Mock <RC.IConnection>(); var connectionNum = connectionNumber.IncrementAndGet(); mockConnections.Add(connection.Object); connection.Setup(c => c.IsOpen).Returns(true); connection.Setup(c => c.ToString()).Returns("mockConnection" + connectionNum); connection.Setup(c => c.CreateModel()) .Callback(() => { var channel = new Mock <RC.IModel>(); mockChannels.Add(channel.Object); channel.Setup(c => c.IsOpen).Returns(true); var channelNum = channelNumber.IncrementAndGet(); channel.Setup(c => c.ToString()).Returns("mockChannel" + channelNum); }) .Returns(() => mockChannels[channelNumber.Value]); }) .Returns(() => mockConnections[connectionNumber.Value]); var ccf = new CachingConnectionFactory(mockConnectionFactory.Object, false, CachingConnectionFactory.CachingMode.CONNECTION); var queue = new Queue("foo"); services.AddRabbitQueue(queue); var provider = services.BuildServiceProvider(); var context = provider.GetApplicationContext(); var admin = new RabbitAdmin(context, ccf); ccf.CreateConnection().Close(); ccf.Destroy(); Assert.Empty(mockChannels); }
public async Task TestReleaseConsumerRace() { var connectionFactory = new CachingConnectionFactory("localhost"); var container = new DirectReplyToMessageListenerContainer(null, connectionFactory); var latch = new CountdownEvent(1); container.MessageListener = new EmptyListener(); var mockMessageListener = new MockChannelAwareMessageListener(container.MessageListener, latch); container.SetChannelAwareMessageListener(mockMessageListener); var foobytes = EncodingUtils.GetDefaultEncoding().GetBytes("foo"); var barbytes = EncodingUtils.GetDefaultEncoding().GetBytes("bar"); await container.Start(); Assert.True(container._startedLatch.Wait(TimeSpan.FromSeconds(10))); var channel1 = container.GetChannelHolder(); var props = channel1.Channel.CreateBasicProperties(); props.ReplyTo = Address.AMQ_RABBITMQ_REPLY_TO; RC.IModelExensions.BasicPublish(channel1.Channel, string.Empty, TEST_RELEASE_CONSUMER_Q, props, foobytes); var replyChannel = connectionFactory.CreateConnection().CreateChannel(false); var request = replyChannel.BasicGet(TEST_RELEASE_CONSUMER_Q, true); var n = 0; while (n++ < 100 && request == null) { Thread.Sleep(100); request = replyChannel.BasicGet(TEST_RELEASE_CONSUMER_Q, true); } Assert.NotNull(request); props = channel1.Channel.CreateBasicProperties(); RC.IModelExensions.BasicPublish(replyChannel, string.Empty, request.BasicProperties.ReplyTo, props, barbytes); replyChannel.Close(); Assert.True(latch.Wait(TimeSpan.FromSeconds(10))); var channel2 = container.GetChannelHolder(); Assert.Same(channel1.Channel, channel2.Channel); container.ReleaseConsumerFor(channel1, false, null); // simulate race for future timeout/cancel and onMessage() var inUse = container._inUseConsumerChannels; Assert.Single(inUse); container.ReleaseConsumerFor(channel2, false, null); Assert.Empty(inUse); await container.Stop(); connectionFactory.Destroy(); }
public void TestAck() { var config = new ConfigurationBuilder().Build(); var services = new ServiceCollection().BuildServiceProvider(); var context = new GenericApplicationContext(services, config); var channel = new Mock <R.IModel>(); channel.Setup(c => c.IsOpen).Returns(true); var props = new MockRabbitBasicProperties(); var getResponse = new R.BasicGetResult(123Ul, false, "ex", "rk", 0, props, Encoding.UTF8.GetBytes("foo")); channel.Setup(c => c.BasicGet("foo", false)).Returns(getResponse); var connection = new Mock <R.IConnection>(); connection.Setup(c => c.IsOpen).Returns(true); connection.Setup(c => c.CreateModel()).Returns(channel.Object); var connectionFactory = new Mock <R.IConnectionFactory>(); connectionFactory.Setup(f => f.CreateConnection(It.IsAny <string>())).Returns(connection.Object); var ccf = new CachingConnectionFactory(connectionFactory.Object); var source = new RabbitMessageSource(context, ccf, "foo"); source.RawMessageHeader = true; var received = source.Receive(); var rawMessage = received.Headers.Get <IMessage>(RabbitMessageHeaderErrorMessageStrategy.AMQP_RAW_MESSAGE); var sourceData = received.Headers.Get <IMessage>(IntegrationMessageHeaderAccessor.SOURCE_DATA); Assert.NotNull(rawMessage); Assert.Same(rawMessage, sourceData); Assert.Equal("foo", received.Headers.Get <string>(RabbitMessageHeaders.CONSUMER_QUEUE)); // make sure channel is not cached var conn = ccf.CreateConnection(); var notCached = conn.CreateChannel(false); connection.Verify(c => c.CreateModel(), Times.Exactly(2)); var callback = received.Headers.Get <IAcknowledgmentCallback>(IntegrationMessageHeaderAccessor.ACKNOWLEDGMENT_CALLBACK); callback.Acknowledge(Status.ACCEPT); channel.Verify(c => c.BasicAck(123ul, false)); var cached = conn.CreateChannel(false); // should have been "closed" connection.Verify(c => c.CreateModel(), Times.Exactly(2)); notCached.Close(); cached.Close(); ccf.Destroy(); channel.Verify(c => c.Close(), Times.Exactly(2)); connection.Verify(c => c.Close(30000)); }
public void TestWithConnectionFactoryCacheSize() { var mockConnectionFactory = new Mock <ConnectionFactory>(); var mockConnection = new Mock <IConnection>(); var mockChannel1 = new Mock <IModel>(); var mockChannel2 = new Mock <IModel>(); mockConnectionFactory.Setup(a => a.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(a => a.IsOpen).Returns(true); mockConnection.Setup(a => a.CreateModel()).ReturnsInOrder(mockChannel1.Object, mockChannel2.Object); mockChannel1.Setup(a => a.BasicGet("foo", false)).Returns(new BasicGetResult(0, false, null, null, 1, null, null)); mockChannel2.Setup(a => a.BasicGet("bar", false)).Returns(new BasicGetResult(0, false, null, null, 1, null, null)); mockChannel1.Setup(a => a.IsOpen).Returns(true); mockChannel2.Setup(a => a.IsOpen).Returns(true); var ccf = new CachingConnectionFactory(mockConnectionFactory.Object); ccf.ChannelCacheSize = 2; var con = ccf.CreateConnection(); var channel1 = con.CreateChannel(false); var channel2 = con.CreateChannel(false); channel1.BasicGet("foo", true); channel2.BasicGet("bar", true); channel1.Close(); // should be ignored, and add last into channel cache. channel2.Close(); // should be ignored, and add last into channel cache. var ch1 = con.CreateChannel(false); // remove first entry in cache (channel1) var ch2 = con.CreateChannel(false); // remove first entry in cache (channel2) Assert.AreNotSame(ch1, ch2); Assert.AreSame(ch1, channel1); Assert.AreSame(ch2, channel2); ch1.Close(); ch2.Close(); mockConnection.Verify(conn => conn.CreateModel(), Times.Exactly(2)); con.Close(); // should be ignored mockConnection.Verify(c => c.Close(), Times.Never()); mockChannel1.Verify(c => c.Close(), Times.Never()); mockChannel2.Verify(c => c.Close(), Times.Never()); }
public void TestWithConnectionFactoryDestroy() { var mockConnectionFactory = new Mock <ConnectionFactory>(); var mockConnection = new Mock <IConnection>(); var mockChannel1 = new Mock <IModel>(); mockChannel1.Setup(m => m.GetHashCode()).Returns(1); var mockChannel2 = new Mock <IModel>(); mockChannel1.Setup(m => m.GetHashCode()).Returns(2); Logger.Debug(m => m("Channel1 Hashcode: {0}", mockChannel1.Object.GetHashCode())); Logger.Debug(m => m("Channel2 Hashcode: {0}", mockChannel2.Object.GetHashCode())); Assert.AreNotSame(mockChannel1, mockChannel2); mockConnectionFactory.Setup(c => c.CreateConnection()).Returns(mockConnection.Object); mockConnection.Setup(c => c.CreateModel()).ReturnsInOrder(mockChannel1.Object, mockChannel2.Object); mockConnection.Setup(c => c.IsOpen).Returns(true); // Called during physical close mockChannel1.Setup(c => c.IsOpen).Returns(true); mockChannel2.Setup(c => c.IsOpen).Returns(true); var ccf = new CachingConnectionFactory(mockConnectionFactory.Object); ccf.ChannelCacheSize = 2; var con = ccf.CreateConnection(); // This will return a proxy that surpresses calls to close var channel1 = con.CreateChannel(false); var channel2 = con.CreateChannel(false); // Should be ignored, and add last into channel cache. channel1.Close(); channel2.Close(); // remove first entry in cache (channel1) var ch1 = con.CreateChannel(false); // remove first entry in cache (channel2) var ch2 = con.CreateChannel(false); Assert.AreSame(ch1, channel1); Assert.AreSame(ch2, channel2); var target1 = ((IChannelProxy)ch1).GetTargetChannel(); var target2 = ((IChannelProxy)ch2).GetTargetChannel(); // make sure Moq returned different mocks for the channel Assert.AreNotSame(target1, target2); ch1.Close(); ch2.Close(); con.Close(); // should be ignored ccf.Dispose(); // should call close on connection and channels in cache mockConnection.Verify(c => c.CreateModel(), Times.Exactly(2)); mockConnection.Verify(c => c.Close(), Times.Exactly(1)); // verify(mockChannel1).close(); mockChannel2.Verify(c => c.Close(), Times.Exactly(1)); // After destroy we can get a new connection var con1 = ccf.CreateConnection(); Assert.AreNotSame(con, con1); // This will return a proxy that surpresses calls to close var channel3 = con.CreateChannel(false); Assert.AreNotSame(channel3, channel1); Assert.AreNotSame(channel3, channel2); }
public void TestCachedConnections() { connectionFactory.CacheMode = CachingMode.CONNECTION; connectionFactory.ConnectionCacheSize = 5; var connections = new List <IConnection> { connectionFactory.CreateConnection(), connectionFactory.CreateConnection() }; Assert.NotSame(connections[0], connections[1]); connections.Add(connectionFactory.CreateConnection()); connections.Add(connectionFactory.CreateConnection()); connections.Add(connectionFactory.CreateConnection()); connections.Add(connectionFactory.CreateConnection()); var allocatedConnections = connectionFactory._allocatedConnections; Assert.Equal(6, allocatedConnections.Count); foreach (var c in allocatedConnections) { c.Close(); } var idleConnections = connectionFactory._idleConnections; Assert.Equal(6, idleConnections.Count); connections.Clear(); connections.Add(connectionFactory.CreateConnection()); connections.Add(connectionFactory.CreateConnection()); allocatedConnections = connectionFactory._allocatedConnections; Assert.Equal(6, allocatedConnections.Count); idleConnections = connectionFactory._idleConnections; Assert.Equal(4, idleConnections.Count); foreach (var c in connections) { c.Close(); } }