public void TestTlsSuccessWithCert() { using (NATSServer srv = util.CreateServerWithConfig("tls_1222_verify.conf")) { Options opts = util.DefaultTestOptions; opts.Secure = true; opts.Url = "nats://localhost:1222"; opts.TLSRemoteCertificationValidationCallback = verifyServerCert; // .NET requires the private key and cert in the // same file. 'client.pfx' is generated from: // // openssl pkcs12 -export -out client.pfx // -inkey client-key.pem -in client-cert.pem X509Certificate2 cert = new X509Certificate2( UnitTestUtilities.GetFullCertificatePath("client.pfx"), "password"); opts.AddCertificate(cert); using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { using (ISyncSubscription s = c.SubscribeSync("foo")) { c.Publish("foo", null); c.Flush(); Msg m = s.NextMessage(); } } } }
public void TestTlsReconnectAuthTimeout() { AutoResetEvent ev = new AutoResetEvent(false); using (NATSServer s1 = util.CreateServerWithConfig("auth_tls_1222.conf"), s2 = util.CreateServerWithConfig("auth_tls_1223_timeout.conf"), s3 = util.CreateServerWithConfig("auth_tls_1224.conf")) { Options opts = util.DefaultTestOptions; opts.Secure = true; opts.NoRandomize = true; opts.TLSRemoteCertificationValidationCallback = verifyServerCert; opts.Servers = new string[] { "nats://*****:*****@localhost:1222", "nats://*****:*****@localhost:1223", "nats://*****:*****@localhost:1224" }; opts.ReconnectedEventHandler += (sender, args) => { ev.Set(); }; IConnection c = new ConnectionFactory().CreateConnection(opts); s1.Shutdown(); // This should fail over to S2 where an authorization timeout occurs // then successfully reconnect to S3. Assert.True(ev.WaitOne(20000)); } }
public void TestTlsFailWithBadAuth() { using (NATSServer srv = util.CreateServerWithConfig(TestContext, "tls_1222_user.conf")) { Options opts = ConnectionFactory.GetDefaultOptions(); opts.Secure = true; opts.Url = "nats://*****:*****@localhost:1222"; opts.TLSRemoteCertificationValidationCallback = verifyServerCert; // this will fail, because it's not complete - missing the private // key. opts.AddCertificate(UnitTestUtilities.GetFullCertificatePath( TestContext, "client-cert.pem")); try { new ConnectionFactory().CreateConnection(opts); } catch (NATSException nae) { System.Console.WriteLine("Caught expected exception: " + nae.Message); System.Console.WriteLine("Exception output:" + nae); return; } Assert.Fail("Did not receive exception."); } }
public void TestAuthServers() { string[] plainServers = new string[] { "nats://*****:*****@localhost:1224" }; opts.Servers = authServers; using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { Assert.Equal(authServers[1], c.ConnectedUrl); } } }
public void TestServersOption() { IConnection c = null; ConnectionFactory cf = new ConnectionFactory(); Options o = utils.DefaultTestOptions; o.NoRandomize = true; Assert.ThrowsAny <NATSNoServersException>(() => cf.CreateConnection()); o.Servers = testServers; Assert.ThrowsAny <NATSNoServersException>(() => cf.CreateConnection(o)); // Make sure we can connect to first server if running using (NATSServer ns = utils.CreateServerOnPort(1222)) { c = cf.CreateConnection(o); Assert.Equal(testServers[0], c.ConnectedUrl); c.Close(); } // make sure we can connect to a non-first server. using (NATSServer ns = utils.CreateServerOnPort(1227)) { c = cf.CreateConnection(o); Assert.Equal(testServers[5], c.ConnectedUrl); c.Close(); } }
public void TestAuthServers() { string[] plainServers = new string[] { "nats://*****:*****@localhost:1224" }; opts.Servers = authServers; using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { Assert.IsTrue(c.ConnectedUrl.Equals(authServers[1])); } } }
public void TestServersOption() { IConnection c = null; ConnectionFactory cf = new ConnectionFactory(); Options o = ConnectionFactory.GetDefaultOptions(); o.NoRandomize = true; UnitTestUtilities.testExpectedException( () => { cf.CreateConnection(); }, typeof(NATSNoServersException)); o.Servers = testServers; UnitTestUtilities.testExpectedException( () => { cf.CreateConnection(o); }, typeof(NATSNoServersException)); // Make sure we can connect to first server if running using (NATSServer ns = utils.CreateServerOnPort(1222)) { c = cf.CreateConnection(o); Assert.IsTrue(testServers[0].Equals(c.ConnectedUrl)); c.Close(); } // make sure we can connect to a non-first server. using (NATSServer ns = utils.CreateServerOnPort(1227)) { c = cf.CreateConnection(o); Assert.IsTrue(testServers[5].Equals(c.ConnectedUrl)); c.Close(); } }
public void TestReconnectAllowedFlags() { Options opts = ConnectionFactory.GetDefaultOptions(); opts.Url = "nats://localhost:22222"; opts.MaxReconnect = 2; opts.ReconnectWait = 1000; Object testLock = new Object(); opts.ClosedEventHandler = (sender, args) => { lock (testLock) { Monitor.Pulse(testLock); } }; using (NATSServer ns = utils.CreateServerOnPort(22222)) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { lock (testLock) { ns.Shutdown(); Assert.IsFalse(Monitor.Wait(testLock, 1000)); } Assert.IsTrue(c.State == ConnState.RECONNECTING); c.Opts.ClosedEventHandler = null; } } }
public void TestReconnectDisallowedFlags() { Options opts = ConnectionFactory.GetDefaultOptions(); opts.Url = "nats://localhost:22222"; opts.AllowReconnect = false; Object testLock = new Object(); opts.ClosedEventHandler = (sender, args) => { lock (testLock) { Monitor.Pulse(testLock); } }; using (NATSServer ns = utils.CreateServerOnPort(22222)) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { lock (testLock) { ns.Shutdown(); Assert.IsTrue(Monitor.Wait(testLock, 1000)); } } } }
public void TestQueueSubsOnReconnect() { Object reconnectLock = new Object(); Options opts = reconnectOptions; IEncodedConnection ec; string subj = "foo.bar"; string qgroup = "workers"; opts.ReconnectedEventHandler += (sender, args) => { lock (reconnectLock) { Monitor.Pulse(reconnectLock); } }; using (NATSServer ns = utils.CreateServerOnPort(22222)) { ec = new ConnectionFactory().CreateEncodedConnection(opts); EventHandler <EncodedMessageEventArgs> eh = (sender, args) => { int seq = ((NumberObj)args.ReceivedObject).v; lock (results) { if (results.ContainsKey(seq) == false) { results.Add(seq, true); } } }; // Create Queue Subscribers ec.SubscribeAsync(subj, qgroup, eh); ec.SubscribeAsync(subj, qgroup, eh); ec.Flush(); sendAndCheckMsgs(ec, subj, 10); } // server should stop... // give the OS time to shut it down. Thread.Sleep(500); // start back up using (NATSServer ns = utils.CreateServerOnPort(22222)) { // wait for reconnect lock (reconnectLock) { Assert.IsTrue(Monitor.Wait(reconnectLock, 3000)); } sendAndCheckMsgs(ec, subj, 10); } }
// TODO: Create smaller variant [Fact] public void TestHotSpotReconnect() { int numClients = 10; SimClient[] clients = new SimClient[100]; Options opts = utils.DefaultTestOptions; opts.Servers = testServers; NATSServer s1 = utils.CreateServerOnPort(1222); Task[] waitgroup = new Task[numClients]; for (int i = 0; i < numClients; i++) { clients[i] = new SimClient(); Task t = new Task(() => { clients[i].Connect(testServers); clients[i].waitForReconnect(); }); t.Start(); waitgroup[i] = t; } NATSServer s2 = utils.CreateServerOnPort(1224); NATSServer s3 = utils.CreateServerOnPort(1226); s1.Shutdown(); Task.WaitAll(waitgroup); int s2Count = 0; int s3Count = 0; int unknown = 0; for (int i = 0; i < numClients; i++) { if (testServers[3].Equals(clients[i].ConnectedUrl)) { s2Count++; } else if (testServers[5].Equals(clients[i].ConnectedUrl)) { s3Count++; } else { unknown++; } } Assert.True(unknown == 0); int delta = Math.Abs(s2Count - s3Count); int range = numClients / 30; Assert.False(delta > range, string.Format("Connected clients to servers out of range: {0}/{0}", delta, range)); }
public void StopDefaultServer() { lock (mu) { defaultServer.Shutdown(); defaultServer = null; } }
public void TestAuthSuccess() { using (NATSServer s = util.CreateServerWithConfig("auth_1222.conf")) { IConnection c = new ConnectionFactory().CreateConnection("nats://*****:*****@localhost:1222"); c.Close(); } }
public void TestAuthFailure() { using (NATSServer s = util.CreateServerWithConfig("auth_1222.conf")) { connectAndFail("nats://username@localhost:1222"); connectAndFail("nats://*****:*****@localhost:1222"); connectAndFail("nats://*****:*****@localhost:1222"); } }
public void TestAuthToken() { using (NATSServer s = util.CreateServerWithArgs("-auth S3Cr3T0k3n!")) { connectAndFail("nats://*****:*****@localhost:4222"); new ConnectionFactory().CreateConnection("nats://S3Cr3T0k3n!@localhost:4222").Close(); } }
public void StartDefaultServer() { lock (mu) { if (defaultServer == null) { defaultServer = new NATSServer(); } } }
public void TestSubDelTaskCountReconnect() { bool disconnected = false; AutoResetEvent reconnectEv = new AutoResetEvent(false); var opts = utils.DefaultTestOptions; opts.SubscriberDeliveryTaskCount = 2; opts.DisconnectedEventHandler = (obj, args) => { disconnected = true; }; opts.ReconnectedEventHandler = (obj, args) => { reconnectEv.Set(); }; using (var server = new NATSServer()) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { long received = 0; int max = 10; AutoResetEvent ev = new AutoResetEvent(false); using (var s = c.SubscribeAsync("foo", (obj, args) => { received++; if (received == max) { ev.Set(); } })) { for (int i = 0; i < max / 2; i++) { c.Publish("foo", null); } c.Flush(); // bounce the server, we should reconnect, then // be able to receive messages. server.Bounce(100); Assert.True(reconnectEv.WaitOne(20000)); Assert.True(disconnected); for (int i = 0; i < max / 2; i++) { c.Publish("foo", null); } c.Flush(); Assert.True(ev.WaitOne(10000)); Assert.True(received == max); } } } }
public void TestQueueSubsOnReconnect() { AutoResetEvent reconnectEvent = new AutoResetEvent(false); Options opts = reconnectOptions; IConnection c; string subj = "foo.bar"; string qgroup = "workers"; opts.ReconnectedEventHandler += (sender, args) => { reconnectEvent.Set(); }; using (NATSServer ns = utils.CreateServerOnPort(22222)) { c = new ConnectionFactory().CreateConnection(opts); EventHandler <MsgHandlerEventArgs> eh = (sender, args) => { int seq = Convert.ToInt32(Encoding.UTF8.GetString(args.Message.Data)); lock (results) { if (results.ContainsKey(seq) == false) { results.Add(seq, true); } } }; // Create Queue Subscribers c.SubscribeAsync(subj, qgroup, eh); c.SubscribeAsync(subj, qgroup, eh); c.Flush(); sendAndCheckMsgs(c, subj, 10); } // server should stop... // give the OS time to shut it down. Thread.Sleep(1000); // start back up using (NATSServer ns = utils.CreateServerOnPort(22222)) { // wait for reconnect Assert.True(reconnectEvent.WaitOne(6000)); sendAndCheckMsgs(c, subj, 10); } }
public void TestInfineReconnect() { var reconnectEv = new AutoResetEvent(false); var closedEv = new AutoResetEvent(false); var opts = ConnectionFactory.GetDefaultOptions(); opts.Timeout = 500; opts.ReconnectWait = 10; opts.ReconnectedEventHandler = (obj, args) => { reconnectEv.Set(); }; opts.ClosedEventHandler = (obj, args) => { closedEv.Set(); }; using (var s = new NATSServer()) { // first test a reconnect failure... opts.MaxReconnect = 1; using (var c = new ConnectionFactory().CreateConnection(opts)) { // we should just close - our one reconnect attempt failed. s.Bounce(opts.Timeout * (opts.MaxReconnect + 1) + 500); // we are closed, and not reconnected. Assert.True(closedEv.WaitOne(10000)); Assert.False(reconnectEv.WaitOne(100)); } } closedEv.Reset(); reconnectEv.Reset(); using (var s = new NATSServer()) { // reconnect forever... opts.MaxReconnect = Options.ReconnectForever; using (var c = new ConnectionFactory().CreateConnection(opts)) { // with a timeout of 10ms, and a reconnectWait of 10 ms, we should have many // reconnect attempts. s.Bounce(20000); // Assert that we reconnected and are not closed. Assert.True(reconnectEv.WaitOne(10000)); Assert.False(closedEv.WaitOne(100)); } } }
public void StopDefaultServer() { lock (mu) { try { defaultServer.Shutdown(); } catch (Exception) { } defaultServer = null; } }
public void TestAsyncInfoProtocolUpdate() { AutoResetEvent evReconnect = new AutoResetEvent(false); var opts = utils.DefaultTestOptions; opts.Url = "nats://*****:*****@127.0.0.1:4223"; string newUrl = null; opts.ReconnectedEventHandler = (obj, args) => { newUrl = args.Conn.ConnectedUrl; evReconnect.Set(); }; // Specify localhost - the 127.0.0.1 should prevent one of the urls // from being added - for adding servers, 127.0.0.1 matches localhost. using (NATSServer s1 = new NATSServer("-a localhost -p 4223 --cluster nats://127.0.0.1:4555 --routes nats://127.0.0.1:4666")) { var c = new ConnectionFactory().CreateConnection(opts); Assert.True(c.Servers.Length == 1); // check that credentials are stripped. Assert.True(c.Servers[0].Equals("nats://127.0.0.1:4223")); using (NATSServer s2 = new NATSServer("-a localhost -p 4224 --cluster nats://127.0.0.1:4666 --routes nats://127.0.0.1:4555")) { // wait until the servers are routed and the conn has the updated // server list. for (int i = 0; i < 5; i++) { Thread.Sleep(500 * i); if (c.Servers.Length >= 2) { break; } } s1.Shutdown(); Assert.True(evReconnect.WaitOne(10000)); Assert.True(c.Servers.Length == 2); Assert.True(c.DiscoveredServers.Length == 1); Assert.True("nats://localhost:4224".Equals(c.DiscoveredServers[0])); Assert.True(newUrl != null); Assert.False(newUrl.Equals(opts.Url)); } c.Close(); } }
public void TestProperReconnectDelay() { Object mu = new Object(); Options opts = utils.DefaultTestOptions; opts.Servers = testServers; opts.NoRandomize = true; bool disconnectHandlerCalled = false; opts.DisconnectedEventHandler = (sender, args) => { opts.DisconnectedEventHandler = null; disconnectHandlerCalled = true; lock (mu) { disconnectHandlerCalled = true; Monitor.Pulse(mu); } }; bool closedCbCalled = false; opts.ClosedEventHandler = (sender, args) => { closedCbCalled = true; }; using (NATSServer s1 = utils.CreateServerOnPort(1222)) { IConnection c = new ConnectionFactory().CreateConnection(opts); lock (mu) { s1.Shutdown(); // wait for disconnect Assert.True(Monitor.Wait(mu, 10000)); // Wait, want to make sure we don't spin on //reconnect to non-existant servers. Thread.Sleep(1000); Assert.False(closedCbCalled); Assert.True(disconnectHandlerCalled); Assert.True(c.State == ConnState.RECONNECTING); } } }
//[Fact] public void TestPingReconnect() { /// Work in progress int RECONNECTS = 4; Options opts = utils.DefaultTestOptions; Object mu = new Object(); opts.Servers = testServersShortList; opts.NoRandomize = true; opts.ReconnectWait = 200; opts.PingInterval = 50; opts.MaxPingsOut = -1; opts.Timeout = 1000; Stopwatch disconnectedTimer = new Stopwatch(); opts.DisconnectedEventHandler = (sender, args) => { disconnectedTimer.Reset(); disconnectedTimer.Start(); }; opts.ReconnectedEventHandler = (sender, args) => { lock (mu) { args.Conn.Opts.MaxPingsOut = 500; disconnectedTimer.Stop(); Monitor.Pulse(mu); } }; using (NATSServer s1 = utils.CreateServerOnPort(1222)) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { s1.Shutdown(); for (int i = 0; i < RECONNECTS; i++) { lock (mu) { Assert.True(Monitor.Wait(mu, 100000)); } } } } }
public void TestServerDiscoveredHandler() { IConnection c = null; ConnectionFactory cf = new ConnectionFactory(); Options o = utils.DefaultTestOptions; o.NoRandomize = true; o.Servers = testServers; bool serverDiscoveredCalled = false; o.ServerDiscoveredEventHandler += (sender, e) => { serverDiscoveredCalled = true; }; string seedServerArgs = @"-p 1222 -cluster nats://127.0.0.1:1333"; string secondClusterMemberArgs = @"-p 1223 -cluster nats://127.0.0.1:1334 -routes nats://127.0.0.1:1333"; // create the seed server for a cluster... using (NATSServer ns1 = utils.CreateServerWithArgs(seedServerArgs)) { // ...then connect to it... using (c = cf.CreateConnection(o)) { Assert.True(testServers[0].Equals(c.ConnectedUrl)); // ...then while connected, start up a second server... using (NATSServer ns2 = utils.CreateServerWithArgs(secondClusterMemberArgs)) { // ...waiting up to 30 seconds for the second server to start... for (int ii = 0; ii < 6; ii++) { Thread.Sleep(5000); // ...taking an early out if we detected the startup... if (serverDiscoveredCalled) { break; } } // ...and by then we should have received notification of // its awakening. Assert.True(serverDiscoveredCalled); } } } }
public void TestAsyncInfoProtocolUpdate() { AutoResetEvent evReconnect = new AutoResetEvent(false); var opts = utils.DefaultTestOptions; opts.Url = "nats://*****:*****@127.0.0.1:4223"; string newUrl = null; opts.ReconnectedEventHandler = (obj, args) => { newUrl = args.Conn.ConnectedUrl; evReconnect.Set(); }; // Specify localhost - the 127.0.0.1 should prevent one of the urls // from being added - for adding servers, 127.0.0.1 matches localhost. using (NATSServer s1 = new NATSServer("-a localhost -p 4223 --cluster nats://127.0.0.1:4555 --routes nats://127.0.0.1:4666")) { var c = new ConnectionFactory().CreateConnection(opts); Assert.True(c.Servers.Length == 1); // check that credentials are stripped. Assert.True(c.Servers[0].Equals("nats://127.0.0.1:4223")); // build an independent cluster using (NATSServer s2 = new NATSServer("-a localhost -p 4224 --cluster nats://127.0.0.1:4666 --routes nats://127.0.0.1:4555")) { // wait until the servers are routed and the conn has the updated // server list. assureClusterFormed(c, 2); // Ensure the first server remains in place and has not been // randomized. Assert.True(c.Servers[0].Equals("nats://127.0.0.1:4223")); Assert.True(c.Servers.Length == 2); Assert.True(c.DiscoveredServers.Length == 1); // sanity check to ensure we can connect to another server. s1.Shutdown(); Assert.True(evReconnect.WaitOne(10000)); Assert.True(newUrl != null); Assert.False(newUrl.Equals(opts.Url)); } c.Close(); } }
public void TestTlsReconnectAuthTimeoutLateClose() { AutoResetEvent ev = new AutoResetEvent(false); using (NATSServer s1 = util.CreateServerWithConfig("auth_tls_1222.conf"), s2 = util.CreateServerWithConfig("auth_tls_1224.conf")) { Options opts = util.DefaultTestOptions; opts.Secure = true; opts.NoRandomize = true; opts.TLSRemoteCertificationValidationCallback = verifyServerCert; opts.Servers = new string[] { "nats://*****:*****@localhost:1222", "nats://*****:*****@localhost:1224" }; opts.ReconnectedEventHandler += (sender, args) => { ev.Set(); }; IConnection c = new ConnectionFactory().CreateConnection(opts); // inject an authorization timeout, as if it were processed by an incoming server message. // this is done at the parser level so that parsing is also tested, // therefore it needs reflection since Parser is an internal type. Type parserType = typeof(Connection).Assembly.GetType("NATS.Client.Parser"); Assert.NotNull(parserType); BindingFlags flags = BindingFlags.NonPublic | BindingFlags.Instance; object parser = Activator.CreateInstance(parserType, flags, null, new object[] { c }, null); Assert.NotNull(parser); MethodInfo parseMethod = parserType.GetMethod("parse", flags); Assert.NotNull(parseMethod); byte[] bytes = "-ERR 'Authorization Timeout'\r\n".ToCharArray().Select(ch => (byte)ch).ToArray(); parseMethod.Invoke(parser, new object[] { bytes, bytes.Length }); // sleep to allow the client to process the error, then shutdown the server. Thread.Sleep(250); s1.Shutdown(); // Wait for a reconnect. Assert.True(ev.WaitOne(20000)); } }
public void TestTlsFailWithBadAuth() { using (NATSServer srv = util.CreateServerWithConfig("tls_1222_user.conf")) { Options opts = util.DefaultTestOptions; opts.Secure = true; opts.Url = "nats://*****:*****@localhost:1222"; opts.TLSRemoteCertificationValidationCallback = verifyServerCert; // this will fail, because it's not complete - missing the private // key. opts.AddCertificate(UnitTestUtilities.GetFullCertificatePath("client-cert.pem")); Assert.ThrowsAny <NATSException>(() => new ConnectionFactory().CreateConnection(opts)); } }
public void TestAuthFailure() { try { using (NATSServer s = util.CreateServerWithConfig(TestContext, "auth_1222.conf")) { connectAndFail("nats://username@localhost:1222"); connectAndFail("nats://*****:*****@localhost:1222"); connectAndFail("nats://*****:*****@localhost:1222"); } } catch (Exception e) { System.Console.WriteLine(e); throw e; } }
public void TestAuthToken() { try { using (NATSServer s = util.CreateServerWithArgs(TestContext, "-auth S3Cr3T0k3n!")) { connectAndFail("nats://*****:*****@localhost:4222"); new ConnectionFactory().CreateConnection("nats://S3Cr3T0k3n!@localhost:4222").Close(); } } catch (Exception e) { System.Console.WriteLine(e); throw e; } }
public void TestReconnectVerbose() { // an exception stops and fails the test. IConnection c = null; Object reconnectLock = new Object(); bool reconnected = false; Options opts = utils.DefaultTestOptions; opts.Verbose = true; opts.ReconnectedEventHandler += (sender, args) => { lock (reconnectLock) { reconnected = true; Monitor.Pulse(reconnectLock); } }; using (NATSServer s = utils.CreateServerOnPort(4222)) { c = new ConnectionFactory().CreateConnection(opts); c.Flush(); // exit the block and enter a new server block - this // restarts the server. } using (NATSServer s = utils.CreateServerOnPort(4222)) { lock (reconnectLock) { if (!reconnected) { Monitor.Wait(reconnectLock, 5000); } } c.Flush(); } }
public void TestSubDelTaskCountReconnect() { bool disconnected = false; AutoResetEvent reconnectEv = new AutoResetEvent(false); var opts = utils.DefaultTestOptions; opts.SubscriberDeliveryTaskCount = 2; opts.DisconnectedEventHandler = (obj, args) => { disconnected = true;}; opts.ReconnectedEventHandler = (obj, args) => { reconnectEv.Set(); }; using (var server = new NATSServer()) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { long received = 0; int max = 10; AutoResetEvent ev = new AutoResetEvent(false); using (var s = c.SubscribeAsync("foo", (obj, args) => { received++; if (received == max) ev.Set(); })) { for (int i = 0; i < max / 2; i++) { c.Publish("foo", null); } c.Flush(); // bounce the server, we should reconnect, then // be able to receive messages. server.Bounce(100); Assert.True(reconnectEv.WaitOne(20000)); Assert.True(disconnected); for (int i = 0; i < max / 2; i++) { c.Publish("foo", null); } c.Flush(); Assert.True(ev.WaitOne(10000)); Assert.True(received == max); } } } }
public void TestPublishErrorsDuringReconnect() { AutoResetEvent connectedEv = new AutoResetEvent(false); using (var server = new NATSServer()) { Task t = new Task(() => { connectedEv.WaitOne(10000); Random r = new Random(); // increase this count for a longer running test. for (int i = 0; i < 10; i++) { server.Bounce(r.Next(500)); } }, TaskCreationOptions.LongRunning); t.Start(); byte[] payload = Encoding.UTF8.GetBytes("hello"); using (var c = utils.DefaultTestConnection) { connectedEv.Set(); while (t.IsCompleted == false) { try { c.Publish("foo", payload); } catch (Exception e) { Assert.IsNotType<NATSConnectionClosedException>(e); Assert.False(c.IsClosed()); } } } } }