public void TestReconnectAllowedFlags() { Options opts = utils.DefaultTestOptions; 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.False(Monitor.Wait(testLock, 1000)); } Assert.True(c.State == ConnState.RECONNECTING); c.Opts.ClosedEventHandler = null; } } }
public void TestReconnectDisallowedFlags() { Options opts = utils.DefaultTestOptions; 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.True(Monitor.Wait(testLock, 1000)); } } } }
public void TestClose() { Options opts = ConnectionFactory.GetDefaultOptions(); opts.Url = "nats://localhost:22222"; opts.AllowReconnect = true; opts.MaxReconnect = 60; using (NATSServer s1 = utils.CreateServerOnPort(22222)) { IConnection c = new ConnectionFactory().CreateConnection(opts); Assert.IsFalse(c.IsClosed()); s1.Shutdown(); Thread.Sleep(100); if (c.IsClosed()) { Assert.Fail("Invalid state, expecting not closed, received: " + c.State.ToString()); } using (NATSServer s2 = utils.CreateServerOnPort(22222)) { Thread.Sleep(1000); Assert.IsFalse(c.IsClosed()); c.Close(); Assert.IsTrue(c.IsClosed()); } } }
public void TestFlush() { using (var server = new NATSServer()) { var cf = new ConnectionFactory(); var opts = utils.DefaultTestOptions; opts.AllowReconnect = false; var c = cf.CreateConnection(opts); using (ISyncSubscription s = c.SubscribeSync("foo")) { c.Publish("foo", "reply", omsg); c.Flush(); } // Test a timeout, locally this may actually succeed, // so allow for that. // TODO: find a way to debug/pause the server to allow // for timeouts. try { c.Flush(1); } catch (NATSTimeoutException) {} Assert.Throws <ArgumentOutOfRangeException>(() => { c.Flush(-1); }); // test a closed connection c.Close(); Assert.Throws <NATSConnectionClosedException>(() => { c.Flush(); }); // test a lost connection c = cf.CreateConnection(opts); server.Shutdown(); Thread.Sleep(500); Assert.Throws <NATSConnectionClosedException>(() => { c.Flush(); }); } }
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 TestClose() { Options opts = utils.DefaultTestOptions; opts.Url = "nats://localhost:22222"; opts.AllowReconnect = true; opts.MaxReconnect = 60; using (NATSServer s1 = utils.CreateServerOnPort(22222)) { IConnection c = new ConnectionFactory().CreateConnection(opts); Assert.False(c.IsClosed()); s1.Shutdown(); Thread.Sleep(100); Assert.False(c.IsClosed(), string.Format("Invalid state, expecting not closed, received: {0}", c.State)); using (NATSServer s2 = utils.CreateServerOnPort(22222)) { Thread.Sleep(1000); Assert.False(c.IsClosed()); c.Close(); Assert.True(c.IsClosed()); } } }
// 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 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(); } }
//[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 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); } } }
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 async void testRequestAsyncTimeout(bool useOldRequestStyle) { using (var server = new NATSServer()) { var sw = new Stopwatch(); var opts = ConnectionFactory.GetDefaultOptions(); opts.AllowReconnect = false; opts.UseOldRequestStyle = useOldRequestStyle; var conn = new ConnectionFactory().CreateConnection(opts); // success condition var sub = conn.SubscribeAsync("foo", (obj, args) => { conn.Publish(args.Message.Reply, new byte[0]); }); sw.Start(); await conn.RequestAsync("foo", new byte[0], 5000); sw.Stop(); Assert.True(sw.ElapsedMilliseconds < 5000, "Unexpected timeout behavior"); sub.Unsubscribe(); // valid connection, but no response sw.Restart(); await Assert.ThrowsAsync <NATSTimeoutException>(() => { return(conn.RequestAsync("test", new byte[0], 500)); }); sw.Stop(); long elapsed = sw.ElapsedMilliseconds; Assert.True(elapsed >= 500, string.Format("Unexpected value (should be > 500): {0}", elapsed)); long variance = elapsed - 500; #if DEBUG Assert.True(variance < 250, string.Format("Invalid timeout variance: {0}", variance)); #else Assert.True(variance < 100, string.Format("Invalid timeout variance: {0}", variance)); #endif // Test an invalid connection server.Shutdown(); Thread.Sleep(500); await Assert.ThrowsAsync <NATSConnectionClosedException>(() => { return(conn.RequestAsync("test", new byte[0], 1000)); }); } }
public void TestTlsReconnect() { AutoResetEvent ev = new AutoResetEvent(false); using (NATSServer srv = util.CreateServerWithConfig("tls_1222.conf"), srv2 = util.CreateServerWithConfig("tls_1224.conf")) { Thread.Sleep(1000); 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, obj) => { ev.Set(); }; using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { // send a message to be sure. using (ISyncSubscription s = c.SubscribeSync("foo")) { c.Publish("foo", null); c.Flush(); s.NextMessage(); // shutdown the server srv.Shutdown(); // wait for reconnect Assert.True(ev.WaitOne(30000)); c.Publish("foo", null); c.Flush(); s.NextMessage(); } } } }
public void TestRespondFailsWithServerClosed() { IConnection c = null; ISyncSubscription s = null; try { Msg m; using (NATSServer ns = new NATSServer()) { Options options = utils.DefaultTestOptions; options.AllowReconnect = false; c = new ConnectionFactory().CreateConnection(options); s = c.SubscribeSync("foo"); string replyTo = c.NewInbox(); c.Publish("foo", replyTo, Encoding.UTF8.GetBytes("message")); m = s.NextMessage(1000); Assert.NotNull(m); Assert.Equal(replyTo, m.Reply); ns.Shutdown(); } // Give the server time to close Thread.Sleep(2000); byte[] reply = Encoding.UTF8.GetBytes("reply"); Assert.ThrowsAny <NATSConnectionClosedException>(() => m.Respond(reply)); } finally { c?.Dispose(); s?.Dispose(); } }
public void TestProperFalloutAfterMaxAttempts() { Options opts = utils.DefaultTestOptions; Object dmu = new Object(); Object cmu = new Object(); opts.Servers = this.testServersShortList; opts.NoRandomize = true; opts.MaxReconnect = 2; opts.ReconnectWait = 25; // millis opts.Timeout = 500; bool disconnectHandlerCalled = false; opts.DisconnectedEventHandler = (sender, args) => { lock (dmu) { disconnectHandlerCalled = true; Monitor.Pulse(dmu); } }; bool closedHandlerCalled = false; opts.ClosedEventHandler = (sender, args) => { lock (cmu) { closedHandlerCalled = true; Monitor.Pulse(cmu); } }; using (NATSServer s1 = utils.CreateServerOnPort(1222)) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { s1.Shutdown(); lock (dmu) { if (!disconnectHandlerCalled) { Assert.True(Monitor.Wait(dmu, 20000)); } } lock (cmu) { if (!closedHandlerCalled) { Assert.True(Monitor.Wait(cmu, 60000)); } } Assert.True(disconnectHandlerCalled); Assert.True(closedHandlerCalled); Assert.True(c.IsClosed()); } } }
public void TestBasicClusterReconnect() { string[] plainServers = new string[] { "nats://localhost:1222", "nats://localhost:1224" }; Options opts = utils.DefaultTestOptions; opts.MaxReconnect = 2; opts.ReconnectWait = 1000; opts.NoRandomize = true; opts.Servers = plainServers; Object disconnectLock = new Object(); opts.DisconnectedEventHandler += (sender, args) => { // Suppress any additional calls opts.DisconnectedEventHandler = null; lock (disconnectLock) { Monitor.Pulse(disconnectLock); } }; Object reconnectLock = new Object(); opts.ReconnectedEventHandler = (sender, args) => { // Suppress any additional calls lock (reconnectLock) { Monitor.Pulse(reconnectLock); } }; opts.Timeout = 1000; using (NATSServer s1 = utils.CreateServerOnPort(1222), s2 = utils.CreateServerOnPort(1224)) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { Stopwatch reconnectSw = new Stopwatch(); lock (disconnectLock) { s1.Shutdown(); Assert.True(Monitor.Wait(disconnectLock, 20000)); } reconnectSw.Start(); lock (reconnectLock) { Assert.True(Monitor.Wait(reconnectLock, 20000)); } Assert.True(c.ConnectedUrl.Equals(testServers[2])); reconnectSw.Stop(); // Make sure we did not wait on reconnect for default time. // Reconnect should be fast since it will be a switch to the // second server and not be dependent on server restart time. // TODO: .NET connect timeout is exceeding long compared to // GO's. Look shortening it, or living with it. //if (reconnectSw.ElapsedMilliseconds > opts.ReconnectWait) //{ // Assert.Fail("Reconnect time took to long: {0} millis.", // reconnectSw.ElapsedMilliseconds); //} } } }
public void TestExtendedReconnectFunctionality() { Options opts = reconnectOptions; Object disconnectedLock = new Object(); Object msgLock = new Object(); Object reconnectedLock = new Object(); opts.DisconnectedEventHandler = (sender, args) => { System.Console.WriteLine("Disconnected."); lock (disconnectedLock) { Monitor.Pulse(disconnectedLock); } }; opts.ReconnectedEventHandler = (sender, args) => { System.Console.WriteLine("Reconnected."); lock (reconnectedLock) { Monitor.Pulse(reconnectedLock); } }; byte[] payload = Encoding.UTF8.GetBytes("bar"); NATSServer ns = utils.CreateServerOnPort(22222); using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { IAsyncSubscription s1 = c.SubscribeAsync("foo"); IAsyncSubscription s2 = c.SubscribeAsync("foobar"); s1.MessageHandler += incrReceivedMessageHandler; s2.MessageHandler += incrReceivedMessageHandler; s1.Start(); s2.Start(); received = 0; c.Publish("foo", payload); c.Flush(); lock (disconnectedLock) { ns.Shutdown(); // server is stopped here. Assert.IsTrue(Monitor.Wait(disconnectedLock, 20000)); } // subscribe to bar while connected. IAsyncSubscription s3 = c.SubscribeAsync("bar"); s3.MessageHandler += incrReceivedMessageHandler; s3.Start(); // Unsub foobar while disconnected s2.Unsubscribe(); c.Publish("foo", payload); c.Publish("bar", payload); // server is restarted here... using (NATSServer ts = utils.CreateServerOnPort(22222)) { // wait for reconnect lock (reconnectedLock) { Assert.IsTrue(Monitor.Wait(reconnectedLock, 60000)); } c.Publish("foobar", payload); c.Publish("foo", payload); using (IAsyncSubscription s4 = c.SubscribeAsync("done")) { Object doneLock = new Object(); s4.MessageHandler += (sender, args) => { System.Console.WriteLine("Recieved done message."); lock (doneLock) { Monitor.Pulse(doneLock); } }; s4.Start(); lock (doneLock) { c.Publish("done", payload); Assert.IsTrue(Monitor.Wait(doneLock, 2000)); } } } // NATSServer if (received != 4) { Assert.Fail("Expected 4, received {0}.", received); } } }
//[Fact] // This test works locally, but fails in AppVeyor some of the time // TODO: Work to identify why this happens... private void TestCallbacksOrder() { bool firstDisconnect = true; long orig = DateTime.Now.Ticks; long dtime1 = orig; long dtime2 = orig; long rtime = orig; long atime1 = orig; long atime2 = orig; long ctime = orig; AutoResetEvent reconnected = new AutoResetEvent(false); AutoResetEvent closed = new AutoResetEvent(false); AutoResetEvent asyncErr1 = new AutoResetEvent(false); AutoResetEvent asyncErr2 = new AutoResetEvent(false); AutoResetEvent recvCh = new AutoResetEvent(false); AutoResetEvent recvCh1 = new AutoResetEvent(false); AutoResetEvent recvCh2 = new AutoResetEvent(false); using (NATSServer s = utils.CreateServerWithConfig("auth_1222.conf"), def = new NATSServer()) { Options o = utils.DefaultTestOptions; o.DisconnectedEventHandler += (sender, args) => { Thread.Sleep(100); if (firstDisconnect) { firstDisconnect = false; dtime1 = DateTime.Now.Ticks; } else { dtime2 = DateTime.Now.Ticks; } }; o.ReconnectedEventHandler += (sender, args) => { Thread.Sleep(100); rtime = DateTime.Now.Ticks; reconnected.Set(); }; o.AsyncErrorEventHandler += (sender, args) => { Thread.Sleep(100); if (args.Subscription.Subject.Equals("foo")) { atime1 = DateTime.Now.Ticks; asyncErr1.Set(); } else { atime2 = DateTime.Now.Ticks; asyncErr2.Set(); } }; o.ClosedEventHandler += (sender, args) => { ctime = DateTime.Now.Ticks; closed.Set(); }; o.ReconnectWait = 500; o.NoRandomize = true; o.Servers = new string[] { "nats://localhost:4222", "nats://localhost:1222" }; o.SubChannelLength = 1; using (IConnection nc = new ConnectionFactory().CreateConnection(o), ncp = utils.DefaultTestConnection) { // On hosted environments, some threads/tasks can start before others // due to resource constraints. Allow time to start. Thread.Sleep(1000); def.Bounce(1000); Thread.Sleep(1000); Assert.True(reconnected.WaitOne(3000)); object asyncLock = new object(); EventHandler <MsgHandlerEventArgs> eh = (sender, args) => { lock (asyncLock) { recvCh.Set(); if (args.Message.Subject.Equals("foo")) { recvCh1.Set(); } else { recvCh2.Set(); } } }; IAsyncSubscription sub1 = nc.SubscribeAsync("foo", eh); IAsyncSubscription sub2 = nc.SubscribeAsync("bar", eh); nc.Flush(); ncp.Publish("foo", System.Text.Encoding.UTF8.GetBytes("hello")); ncp.Publish("bar", System.Text.Encoding.UTF8.GetBytes("hello")); ncp.Flush(); recvCh.WaitOne(3000); for (int i = 0; i < 3; i++) { ncp.Publish("foo", System.Text.Encoding.UTF8.GetBytes("hello")); ncp.Publish("bar", System.Text.Encoding.UTF8.GetBytes("hello")); } ncp.Flush(); Assert.True(asyncErr1.WaitOne(3000)); Assert.True(asyncErr2.WaitOne(3000)); def.Shutdown(); Thread.Sleep(1000); closed.Reset(); nc.Close(); Assert.True(closed.WaitOne(3000)); } if (dtime1 == orig || dtime2 == orig || rtime == orig || atime1 == orig || atime2 == orig || ctime == orig) { Console.WriteLine("Error = callback didn't fire: {0}\n{1}\n{2}\n{3}\n{4}\n{5}\n", dtime1, dtime2, rtime, atime1, atime2, ctime); throw new Exception("Callback didn't fire."); } if (rtime < dtime1 || dtime2 < rtime || ctime < atime2) { Console.WriteLine("Wrong callback order:\n" + "dtime1: {0}\n" + "rtime: {1}\n" + "atime1: {2}\n" + "atime2: {3}\n" + "dtime2: {4}\n" + "ctime: {5}\n", dtime1, rtime, atime1, atime2, dtime2, ctime); throw new Exception("Invalid callback order."); } } }
public void TestProperFalloutAfterMaxAttemptsWithAuthMismatch() { Options opts = utils.DefaultTestOptions; Object dmu = new Object(); Object cmu = new Object(); opts.Servers = new string[] { "nats://localhost:1220", "nats://localhost:1222" }; opts.NoRandomize = true; opts.MaxReconnect = 2; opts.ReconnectWait = 25; // millis opts.Timeout = 1000; bool disconnectHandlerCalled = false; opts.DisconnectedEventHandler = (sender, args) => { lock (dmu) { disconnectHandlerCalled = true; Monitor.Pulse(dmu); } }; bool closedHandlerCalled = false; opts.ClosedEventHandler = (sender, args) => { lock (cmu) { closedHandlerCalled = true; Monitor.Pulse(cmu); } }; using (NATSServer s1 = utils.CreateServerOnPort(1220), s2 = utils.CreateServerWithConfig("tls_1222_verify.conf")) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { s1.Shutdown(); lock (dmu) { if (!disconnectHandlerCalled) { Assert.True(Monitor.Wait(dmu, 20000)); } } lock (cmu) { if (!closedHandlerCalled) { Assert.True(Monitor.Wait(cmu, 600000)); } } Assert.True(c.Stats.Reconnects != opts.MaxReconnect); Assert.True(disconnectHandlerCalled); Assert.True(closedHandlerCalled); Assert.True(c.IsClosed()); } } }
public void TestTimeoutOnNoServers() { Options opts = utils.DefaultTestOptions; Object dmu = new Object(); Object cmu = new Object(); opts.Servers = testServersShortList; opts.NoRandomize = true; opts.MaxReconnect = 2; opts.ReconnectWait = 100; // millis bool disconnectHandlerCalled = false; bool closedHandlerCalled = false; opts.DisconnectedEventHandler = (sender, args) => { lock (dmu) { disconnectHandlerCalled = true; Monitor.Pulse(dmu); } }; opts.ClosedEventHandler = (sender, args) => { lock (cmu) { closedHandlerCalled = true; Monitor.Pulse(cmu); } }; using (NATSServer s1 = utils.CreateServerOnPort(1222)) { using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { s1.Shutdown(); lock (dmu) { if (!disconnectHandlerCalled) { Assert.True(Monitor.Wait(dmu, 20000)); } } Stopwatch sw = new Stopwatch(); sw.Start(); lock (cmu) { if (!closedHandlerCalled) { Assert.True(Monitor.Wait(cmu, 60000)); } } sw.Stop(); int expected = opts.MaxReconnect * opts.ReconnectWait; // .NET has long connect times, so revisit this after // a connect timeout has been added. //Assert.IsTrue(sw.ElapsedMilliseconds < (expected + 500)); Assert.True(disconnectHandlerCalled); Assert.True(closedHandlerCalled); Assert.True(c.IsClosed()); } } }
public void TestBasicReconnectFunctionality() { Options opts = utils.DefaultTestOptions; opts.Url = "nats://localhost:22222"; opts.MaxReconnect = 2; opts.ReconnectWait = 1000; Object testLock = new Object(); Object msgLock = new Object(); opts.DisconnectedEventHandler = (sender, args) => { lock (testLock) { Monitor.Pulse(testLock); } }; opts.ReconnectedEventHandler = (sender, args) => { // NOOP }; NATSServer ns = utils.CreateServerOnPort(22222); using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { IAsyncSubscription s = c.SubscribeAsync("foo"); s.MessageHandler += (sender, args) => { lock (msgLock) { Monitor.Pulse(msgLock); } }; s.Start(); c.Flush(); lock (testLock) { ns.Shutdown(); Assert.True(Monitor.Wait(testLock, 100000)); } c.Publish("foo", Encoding.UTF8.GetBytes("Hello")); // restart the server. using (ns = utils.CreateServerOnPort(22222)) { lock (msgLock) { c.Flush(50000); Assert.True(Monitor.Wait(msgLock, 10000)); } Assert.True(c.Stats.Reconnects == 1); } } }
public void TestExtendedReconnectFunctionality() { Options opts = reconnectOptions; Object msgLock = new Object(); AutoResetEvent disconnectedEvent = new AutoResetEvent(false); AutoResetEvent reconnectedEvent = new AutoResetEvent(false); opts.DisconnectedEventHandler = (sender, args) => { disconnectedEvent.Set(); }; opts.ReconnectedEventHandler = (sender, args) => { reconnectedEvent.Set(); }; byte[] payload = Encoding.UTF8.GetBytes("bar"); NATSServer ns = utils.CreateServerOnPort(22222); using (IConnection c = new ConnectionFactory().CreateConnection(opts)) { IAsyncSubscription s1 = c.SubscribeAsync("foo"); IAsyncSubscription s2 = c.SubscribeAsync("foobar"); s1.MessageHandler += incrReceivedMessageHandler; s2.MessageHandler += incrReceivedMessageHandler; s1.Start(); s2.Start(); received = 0; c.Publish("foo", payload); c.Flush(); ns.Shutdown(); // server is stopped here. Assert.True(disconnectedEvent.WaitOne(20000)); // subscribe to bar while connected. IAsyncSubscription s3 = c.SubscribeAsync("bar"); s3.MessageHandler += incrReceivedMessageHandler; s3.Start(); // Unsub foobar while disconnected s2.Unsubscribe(); c.Publish("foo", payload); c.Publish("bar", payload); // server is restarted here... using (NATSServer ts = utils.CreateServerOnPort(22222)) { // wait for reconnect Assert.True(reconnectedEvent.WaitOne(60000)); c.Publish("foobar", payload); c.Publish("foo", payload); using (IAsyncSubscription s4 = c.SubscribeAsync("done")) { AutoResetEvent doneEvent = new AutoResetEvent(false); s4.MessageHandler += (sender, args) => { doneEvent.Set(); }; s4.Start(); c.Publish("done", payload); Assert.True(doneEvent.WaitOne(4000)); } } // NATSServer Assert.Equal(4, received); } }