Esempio n. 1
0
        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;
                }
            }
        }
Esempio n. 2
0
        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));
                    }
                }
            }
        }
Esempio n. 3
0
        public void TestBasicReconnectFunctionality()
        {
            Options opts = Context.GetTestOptions(Context.Server1.Port);

            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 = NATSServer.Create(Context.Server1.Port);

            using (IConnection c = Context.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 = NATSServer.Create(Context.Server1.Port))
                {
                    lock (msgLock)
                    {
                        c.Flush(50000);
                        Assert.True(Monitor.Wait(msgLock, 10000));
                    }

                    Assert.True(c.Stats.Reconnects == 1);
                }
            }
        }
Esempio n. 4
0
        public void TestReconnectAllowedFlags()
        {
            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.MaxReconnect  = 2;
            opts.ReconnectWait = 1000;

            AutoResetEvent Closed       = new AutoResetEvent(false);
            AutoResetEvent Disconnected = new AutoResetEvent(false);

            opts.DisconnectedEventHandler = (sender, args) => Disconnected.Set();
            opts.ClosedEventHandler       = (sender, args) => Closed.Set();

            using (NATSServer ns = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    ns.Shutdown();
                    Assert.True(Disconnected.WaitOne(1000));
                    Assert.False(Closed.WaitOne(1000));
                    Assert.True(c.State == ConnState.RECONNECTING);
                    c.Opts.ClosedEventHandler = null;
                }
            }
        }
Esempio n. 5
0
        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());
                }
            }
        }
Esempio n. 6
0
        public void TestTlsReconnectAuthTimeout()
        {
            AutoResetEvent ev = new AutoResetEvent(false);

            using (NATSServer s1 = NATSServer.CreateWithConfig(Context.Server1.Port, "auth_tls.conf"),
                   s2 = NATSServer.CreateWithConfig(Context.Server2.Port, "auth_tls_timeout.conf"),
                   s3 = NATSServer.CreateWithConfig(Context.Server3.Port, "auth_tls.conf"))
            {
                Options opts = Context.GetTestOptions();
                opts.Secure      = true;
                opts.NoRandomize = true;
                opts.TLSRemoteCertificationValidationCallback = verifyServerCert;

                opts.Servers = new[] {
                    $"nats://*****:*****@localhost:{Context.Server1.Port}",
                    $"nats://*****:*****@localhost:{Context.Server2.Port}",
                    $"nats://*****:*****@localhost:{Context.Server3.Port}"
                };

                opts.ReconnectedEventHandler += (sender, args) =>
                {
                    ev.Set();
                };

                using (Context.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));
                }
            }
        }
Esempio n. 7
0
        public void TestClose()
        {
            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.AllowReconnect = true;
            opts.MaxReconnect   = 60;

            using (NATSServer s1 = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.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 = NATSServer.Create(Context.Server1.Port))
                    {
                        Thread.Sleep(1000);
                        Assert.False(c.IsClosed());

                        c.Close();
                        Assert.True(c.IsClosed());
                    }
                }
            }
        }
Esempio n. 8
0
        public void TestReconnectDisallowedFlags()
        {
            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.AllowReconnect = false;

            Object testLock = new Object();

            opts.ClosedEventHandler = (sender, args) =>
            {
                lock (testLock)
                {
                    Monitor.Pulse(testLock);
                }
            };

            using (NATSServer ns = NATSServer.Create(Context.Server1.Port))
            {
                using (IConnection c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    lock (testLock)
                    {
                        ns.Shutdown();
                        Assert.True(Monitor.Wait(testLock, 1000));
                    }
                }
            }
        }
Esempio n. 9
0
        public void TestRespondFailsWithServerClosed()
        {
            Msg m;

            using (NATSServer ns = NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                Options options = Context.GetTestOptions(Context.Server1.Port);
                options.AllowReconnect = false;

                using (var c = Context.ConnectionFactory.CreateConnection(options))
                {
                    using (var 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));
                    }
                }
            }
        }
Esempio n. 10
0
        public void TestReconnectAuthTimeout()
        {
            AutoResetEvent ev = new AutoResetEvent(false);

            using (NATSServer s1 = util.CreateServerWithConfig("auth_1222.conf"),
                   s2 = util.CreateServerWithConfig("auth_1223_timeout.conf"),
                   s3 = util.CreateServerWithConfig("auth_1224.conf"))
            {
                Options opts = util.DefaultTestOptions;

                opts.Servers = new string[] {
                    "nats://*****:*****@localhost:1222",
                    "nats://*****:*****@localhost:1223",
                    "nats://*****:*****@localhost:1224"
                };
                opts.NoRandomize = true;

                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));
            }
        }
Esempio n. 11
0
        public void TestReconnectAllowedFlags()
        {
            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.MaxReconnect  = 2;
            opts.ReconnectWait = 1000;

            Object testLock = new Object();

            opts.ClosedEventHandler = (sender, args) =>
            {
                lock (testLock)
                {
                    Monitor.Pulse(testLock);
                }
            };

            using (NATSServer ns = NATSServer.Create(Context.Server1.Port))
            {
                using (IConnection c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    lock (testLock)
                    {
                        ns.Shutdown();
                        Assert.False(Monitor.Wait(testLock, 1000));
                    }

                    Assert.True(c.State == ConnState.RECONNECTING);
                    c.Opts.ClosedEventHandler = null;
                }
            }
        }
Esempio n. 12
0
        public void TestHotSpotReconnect()
        {
            int numClients = 10;

            SimClient[] clients = new SimClient[100];

            Options opts = Context.GetTestOptions();

            opts.Servers = Context.GetTestServersUrls();

            NATSServer s1 = NATSServer.Create(Context.Server1.Port);

            Task[] waitgroup = new Task[numClients];


            for (int i = 0; i < numClients; i++)
            {
                clients[i]   = new SimClient();
                waitgroup[i] = Task.Run(() => {
                    clients[i].Connect(Context.GetTestServersUrls());
                    clients[i].waitForReconnect();
                });
            }


            NATSServer s3 = NATSServer.Create(Context.Server3.Port);
            NATSServer s5 = NATSServer.Create(Context.Server5.Port);

            s1.Shutdown();
            Task.WaitAll(waitgroup);

            int s3Count = 0;
            int s5Count = 0;
            int unknown = 0;

            for (int i = 0; i < numClients; i++)
            {
                if (Context.Server3.Url.Equals(clients[i].ConnectedUrl))
                {
                    s3Count++;
                }
                else if (Context.Server5.Url.Equals(clients[i].ConnectedUrl))
                {
                    s5Count++;
                }
                else
                {
                    unknown++;
                }
            }

            Assert.True(unknown == 0);
            int delta = Math.Abs(s3Count - s5Count);
            int range = numClients / 30;

            Assert.False(delta > range, string.Format("Connected clients to servers out of range: {0}/{0}", delta, range));
        }
Esempio n. 13
0
        // TODO:  Create smaller variant [Fact]
        private 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();
                waitgroup[i] = Task.Run(() => {
                    clients[i].Connect(testServers);
                    clients[i].waitForReconnect();
                });
            }


            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));
        }
Esempio n. 14
0
        public void TestQueueSubsOnReconnect()
        {
            AutoResetEvent reconnectEvent = new AutoResetEvent(false);
            Options        opts           = getReconnectOptions();

            opts.MaxReconnect = 32;

            string subj   = "foo.bar";
            string qgroup = "workers";

            opts.ReconnectedEventHandler += (sender, args) =>
            {
                reconnectEvent.Set();
            };

            using (NATSServer ns = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.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);

                    ns.Shutdown();

                    // give the OS time to shut it down.
                    Thread.Sleep(1000);

                    // start back up
                    using (NATSServer.Create(Context.Server1.Port))
                    {
                        // wait for reconnect
                        Assert.True(reconnectEvent.WaitOne(6000));

                        sendAndCheckMsgs(c, subj, 10);
                    }
                }
            }
        }
Esempio n. 15
0
        public void TestProperReconnectDelay()
        {
            Object  mu   = new Object();
            Options opts = Context.GetTestOptions();

            opts.Servers     = Context.GetTestServersUrls();
            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 = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.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);
                    }
                }
            }
        }
Esempio n. 16
0
        private 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));
                        }
                    }
                }
            }
        }
Esempio n. 17
0
        public void TestTlsReconnectAuthTimeoutLateClose()
        {
            AutoResetEvent ev = new AutoResetEvent(false);

            using (NATSServer s1 = NATSServer.CreateWithConfig(Context.Server1.Port, "auth_tls.conf"),
                   s2 = NATSServer.CreateWithConfig(Context.Server2.Port, "auth_tls.conf"))
            {
                Options opts = Context.GetTestOptions();
                opts.Secure      = true;
                opts.NoRandomize = true;
                opts.TLSRemoteCertificationValidationCallback = verifyServerCert;

                opts.Servers = new string[] {
                    $"nats://*****:*****@localhost:{Context.Server1.Port}",
                    $"nats://*****:*****@localhost:{Context.Server2.Port}"
                };

                opts.ReconnectedEventHandler += (sender, args) =>
                {
                    ev.Set();
                };

                using (var c = Context.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));
                }
            }
        }
Esempio n. 18
0
        public void TestTlsReconnect()
        {
            AutoResetEvent ev = new AutoResetEvent(false);

            using (NATSServer
                   srv = NATSServer.CreateWithConfig(Context.Server1.Port, "tls.conf"),
                   srv2 = NATSServer.CreateWithConfig(Context.Server2.Port, "tls.conf"))
            {
                Thread.Sleep(1000);

                Options opts = Context.GetTestOptions();
                opts.Secure      = true;
                opts.NoRandomize = true;
                opts.TLSRemoteCertificationValidationCallback = verifyServerCert;
                opts.Servers = new[] { Context.Server1.Url, Context.Server2.Url };
                opts.ReconnectedEventHandler += (sender, obj) =>
                {
                    ev.Set();
                };

                using (IConnection c = Context.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();
                    }
                }
            }
        }
Esempio n. 19
0
        public void TestReconnectVerbose()
        {
            // an exception stops and fails the test.
            Object reconnectLock = new Object();
            bool   reconnected   = false;

            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.Verbose = true;

            opts.ReconnectedEventHandler += (sender, args) =>
            {
                lock (reconnectLock)
                {
                    reconnected = true;
                    Monitor.Pulse(reconnectLock);
                }
            };

            using (NATSServer s = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    c.Flush();

                    s.Shutdown();

                    using (NATSServer.Create(Context.Server1.Port))
                    {
                        lock (reconnectLock)
                        {
                            if (!reconnected)
                            {
                                Monitor.Wait(reconnectLock, 5000);
                            }
                        }

                        c.Flush();
                    }
                }
            }
        }
Esempio n. 20
0
        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();
                    }
                }
            }
        }
Esempio n. 21
0
        public void TestReconnectAllowedFlags()
        {
            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.MaxReconnect  = 2;
            opts.ReconnectWait = 1000;

            AutoResetEvent Closed       = new AutoResetEvent(false);
            AutoResetEvent Disconnected = new AutoResetEvent(false);

            var sw = new Stopwatch();

            opts.DisconnectedEventHandler = (sender, args) =>
            {
                _testOutputHelper.WriteLine($"Disconnected event handler invoked after: {sw.ElapsedMilliseconds}ms");
                Disconnected.Set();
            };
            opts.ClosedEventHandler = (sender, args) =>
            {
                _testOutputHelper.WriteLine($"Closed event handler invoked after: {sw.ElapsedMilliseconds}ms");
                Closed.Set();
            };
            opts.ReconnectedEventHandler = (_, __) =>
            {
                _testOutputHelper.WriteLine($"Reconnect event handler invoked after: {sw.ElapsedMilliseconds}ms");
            };

            using (NATSServer ns = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    sw.Start();
                    ns.Shutdown();
                    Assert.True(Disconnected.WaitOne(1000), "Disconnected event did not receive a signal");
                    Assert.False(Closed.WaitOne(1000), "Closed event did receive a signal");
                    Assert.True(c.State == ConnState.RECONNECTING, $"Expected {ConnState.RECONNECTING} but got {c.State} after {sw.ElapsedMilliseconds} ms");
                    c.Opts.ClosedEventHandler = null;
                }
            }
        }
Esempio n. 22
0
        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();
            }
        }
Esempio n. 23
0
        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());
                }
            }
        }
Esempio n. 24
0
        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.Equal(c.ConnectedUrl, 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);
                    //}
                }
            }
        }
Esempio n. 25
0
        public void TestProperFalloutAfterMaxAttemptsWithAuthMismatch()
        {
            Options opts = Context.GetTestOptions();

            Object dmu = new Object();
            Object cmu = new Object();

            opts.Servers = new [] {
                Context.Server8.Url,
                Context.Server1.Url
            };

            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 = NATSServer.Create(Context.Server8.Port),
                   s2 = NATSServer.CreateWithConfig(Context.Server1.Port, "tls_verify.conf"))
            {
                using (IConnection c = Context.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());
                }
            }
        }
Esempio n. 26
0
        public void TestIsReconnectingAndStatus()
        {
            bool   disconnected     = false;
            object disconnectedLock = new object();

            bool   reconnected     = false;
            object reconnectedLock = new object();

            Options opts = Context.GetTestOptions(Context.Server1.Port);

            opts.AllowReconnect = true;
            opts.MaxReconnect   = 10000;
            opts.ReconnectWait  = 100;

            opts.DisconnectedEventHandler += (sender, args) =>
            {
                lock (disconnectedLock)
                {
                    disconnected = true;
                    Monitor.Pulse(disconnectedLock);
                }
            };

            opts.ReconnectedEventHandler += (sender, args) =>
            {
                lock (reconnectedLock)
                {
                    reconnected = true;
                    Monitor.Pulse(reconnectedLock);
                }
            };

            using (NATSServer s = NATSServer.Create(Context.Server1.Port))
            {
                using (var c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    Assert.True(c.State == ConnState.CONNECTED);
                    Assert.True(c.IsReconnecting() == false);

                    s.Shutdown();

                    lock (disconnectedLock)
                    {
                        if (!disconnected)
                        {
                            Assert.True(Monitor.Wait(disconnectedLock, 10000));
                        }
                    }

                    Assert.True(c.State == ConnState.RECONNECTING);
                    Assert.True(c.IsReconnecting() == true);

                    // restart the server
                    using (NATSServer.Create(Context.Server1.Port))
                    {
                        lock (reconnectedLock)
                        {
                            // may have reconnected, if not, wait
                            if (!reconnected)
                            {
                                Assert.True(Monitor.Wait(reconnectedLock, 10000));
                            }
                        }

                        Assert.True(c.IsReconnecting() == false);
                        Assert.True(c.State == ConnState.CONNECTED);

                        c.Close();
                    }

                    Assert.True(c.IsReconnecting() == false);
                    Assert.True(c.State == ConnState.CLOSED);
                }
            }
        }
Esempio n. 27
0
        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());
                }
            }
        }
Esempio n. 28
0
        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());
                }
            }
        }
Esempio n. 29
0
        // This test works locally, but fails in AppVeyor some of the time
        // TODO:  Work to identify why this happens...
        public 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
                   serverAuth = NATSServer.CreateWithConfig(Context.Server1.Port, "auth.conf"),
                   serverNoAuth = NATSServer.CreateFastAndVerify(Context.Server2.Port))
            {
                Options o = Context.GetTestOptions(Context.Server2.Port);

                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 [] { Context.Server2.Url, Context.Server1.Url };
                o.SubChannelLength = 1;

                using (IConnection
                       nc = Context.ConnectionFactory.CreateConnection(o),
                       ncp = Context.OpenConnection(Context.Server1.Port))
                {
                    // On hosted environments, some threads/tasks can start before others
                    // due to resource constraints.  Allow time to start.
                    Thread.Sleep(1000);

                    serverNoAuth.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));

                    serverNoAuth.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.");
                }
            }
        }
Esempio n. 30
0
        public void TestExtendedReconnectFunctionality()
        {
            Options opts = getReconnectOptions();

            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      = NATSServer.Create(Context.Server1.Port);

            using (IConnection c = Context.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 = NATSServer.Create(Context.Server1.Port))
                {
                    // 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);
            }
        }