Example #1
0
        public void TestRespondFailsWithClosedConnection()
        {
            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                using (IConnection c = Context.OpenConnection(Context.Server1.Port))
                {
                    ISyncSubscription s = c.SubscribeSync("foo");

                    string replyTo = c.NewInbox();
                    c.Publish("foo", replyTo, Encoding.UTF8.GetBytes("message"));

                    Msg m = s.NextMessage(1000);
                    Assert.NotNull(m);
                    Assert.Equal(replyTo, m.Reply);

                    c.Close();

                    byte[] reply = Encoding.UTF8.GetBytes("reply");
                    Assert.ThrowsAny <NATSConnectionClosedException>(() => m.Respond(reply));

                    s.Dispose();
                }
            }
        }
Example #2
0
        public void TestRespondWithCustomInbox()
        {
            var opts = Context.GetTestOptionsWithDefaultTimeout(Context.Server1.Port);

            opts.CustomInboxPrefix = "_TEST.";

            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                using (var cn = Context.ConnectionFactory.CreateConnection(opts))
                    using (var requestSub = cn.SubscribeSync("foo"))
                    {
                        var replyTo = cn.NewInbox();
                        Assert.StartsWith("_TEST.", replyTo);

                        using (var responderSub = cn.SubscribeSync(replyTo))
                        {
                            cn.Publish("foo", replyTo, SamplePayload.Random());

                            var request = requestSub.NextMessage(1000);
                            Assert.NotNull(request);
                            Assert.Equal(replyTo, request.Reply);

                            var reply = SamplePayload.Random();
                            request.Respond(reply);

                            var response = responderSub.NextMessage(1000);
                            Assert.NotNull(response);
                            Assert.Equal(replyTo, response.Subject);
                            Assert.Equal(reply, response.Data);

                            requestSub.Unsubscribe();
                            responderSub.Unsubscribe();
                        }
                    }
            }
        }
Example #3
0
        public void TestCloseSubRelease()
        {
            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                using (IConnection c = Context.OpenConnection(Context.Server1.Port))
                {
                    using (ISyncSubscription s = c.SubscribeSync("foo"))
                    {
                        Stopwatch sw = new Stopwatch();
                        sw.Start();
                        try
                        {
                            Task.Run(() => { Thread.Sleep(100); c.Close(); });
                            s.NextMessage(10000);
                        }
                        catch (Exception) { /* ignore */ }

                        sw.Stop();

                        Assert.True(sw.ElapsedMilliseconds < 10000);
                    }
                }
            }
        }
Example #4
0
        public void TestCloseDisconnectedHandler()
        {
            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                bool   disconnected = false;
                Object mu           = new Object();

                var o = Context.GetTestOptions(Context.Server1.Port);
                o.AllowReconnect            = false;
                o.DisconnectedEventHandler += (sender, args) =>
                {
                    lock (mu)
                    {
                        disconnected = true;
                        Monitor.Pulse(mu);
                    }
                };

                IConnection c = Context.ConnectionFactory.CreateConnection(o);
                lock (mu)
                {
                    c.Close();
                    Monitor.Wait(mu, 20000);
                }
                Assert.True(disconnected);

                // now test using.
                disconnected = false;
                lock (mu)
                {
                    using (c = Context.ConnectionFactory.CreateConnection(o)) { };
                    Monitor.Wait(mu, 20000);
                }
                Assert.True(disconnected);
            }
        }
Example #5
0
        public void EnsureAutoUnsubscribeForAsyncSub()
        {
            var subject  = "0be903f6c9c14c10973e78ce03ad47e1";
            var recieved = new ConcurrentQueue <Msg>();

            AsyncContext.Run(async() =>
            {
                using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
                {
                    using (var sync = TestSync.SingleActor())
                    {
                        using (var cn = Context.ConnectionFactory.CreateConnection(Context.Server1.Url))
                        {
                            using (var sub = cn.SubscribeAsync(subject, (_, m) =>
                            {
                                recieved.Enqueue(m.Message);
                                sync.SignalComplete();
                            }))
                            {
                                sub.AutoUnsubscribe(1);

                                cn.Publish(subject, new byte[0]);
                                cn.Publish(subject, new byte[0]);

                                sync.WaitForAll();

                                await Task.Delay(100);
                                Assert.Equal(1, sub.Delivered);
                            }
                        }

                        Assert.Single(recieved);
                    }
                }
            });
        }
Example #6
0
        public void EnsurePubSubWithAsyncHandler()
        {
            var subject  = "236c9af7eae044f585973503e9803f4a";
            var recieved = new ConcurrentQueue <Msg>();

            AsyncContext.Run(() =>
            {
                using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
                {
                    using (var sync = TestSync.SingleActor())
                    {
                        using (var cn = Context.ConnectionFactory.CreateConnection(Context.Server1.Url))
                        {
                            using (cn.SubscribeAsync(subject, (_, m) =>
                            {
                                recieved.Enqueue(m.Message);
                                if (recieved.Count == 5)
                                {
                                    sync.SignalComplete();
                                }
                            }))
                            {
                                for (var i = 0; i < 5; i++)
                                {
                                    cn.Publish(subject, new[] { (byte)i });
                                }

                                sync.WaitForAll();
                            }
                        }

                        Assert.Equal(5, recieved.Count);
                    }
                }
            });
        }
Example #7
0
        public void EnsureRequestAsyncResponder()
        {
            var subject = "6f7c177f910c4ce587d886cc7212a00f";
            var replies = new ConcurrentQueue <Msg>();

            AsyncContext.Run(async() =>
            {
                using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
                {
                    using (var cn = Context.ConnectionFactory.CreateConnection(Context.Server1.Url))
                    {
                        using (cn.SubscribeAsync(subject, (_, m) => m.Message.Respond(m.Message.Data)))
                        {
                            for (var i = 0; i < 5; i++)
                            {
                                replies.Enqueue(await cn.RequestAsync(subject, new[] { (byte)i }));
                            }
                        }
                    }

                    Assert.Equal(5, replies.Count);
                }
            });
        }
Example #8
0
        public void EnsureRequestResponder()
        {
            var subject = "751182b093ea42b68d79b69353bf6266";
            var replies = new ConcurrentQueue <Msg>();

            AsyncContext.Run(() =>
            {
                using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
                {
                    using (var cn = Context.ConnectionFactory.CreateConnection(Context.Server1.Url))
                    {
                        using (cn.SubscribeAsync(subject, (_, m) => m.Message.Respond(m.Message.Data)))
                        {
                            for (var i = 0; i < 5; i++)
                            {
                                replies.Enqueue(cn.Request(subject, new[] { (byte)i }));
                            }
                        }
                    }

                    Assert.Equal(5, replies.Count);
                }
            });
        }
Example #9
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.");
                }
            }
        }
Example #10
0
        public void TestSubDelTaskCountBasic()
        {
            var opts = Context.GetTestOptions(Context.Server1.Port);

            Assert.Throws <ArgumentOutOfRangeException>(
                () => { opts.SubscriberDeliveryTaskCount = -1; });

            opts.SubscriberDeliveryTaskCount = 2;

            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                using (IConnection c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    int s1Count = 0;
                    int s2Count = 0;
                    int COUNT   = 10;

                    AutoResetEvent ev1 = new AutoResetEvent(false);
                    AutoResetEvent ev2 = new AutoResetEvent(false);

                    using (var s1 = c.SubscribeAsync("foo", (obj, args) =>
                    {
                        s1Count++;
                        if (s1Count == COUNT)
                        {
                            ev1.Set();
                        }
                    }))
                    {
                        using (var s2 = c.SubscribeAsync("bar", (obj, args) =>
                        {
                            s2Count++;
                            if (s2Count >= COUNT)
                            {
                                ev2.Set();
                            }
                        }))
                        {
                            for (int i = 0; i < 10; i++)
                            {
                                c.Publish("foo", null);
                                c.Publish("bar", null);
                            }

                            c.Flush();

                            Assert.True(ev1.WaitOne(10000));
                            Assert.True(ev2.WaitOne(10000));
                            s1.Unsubscribe();

                            Assert.True(s1Count == COUNT);
                            Assert.True(s2Count == COUNT);

                            ev2.Reset();

                            c.Publish("bar", null);
                            c.Flush();

                            Assert.True(ev2.WaitOne(10000));
                            Assert.True(s2Count == COUNT + 1);

                            s2.Unsubscribe();
                        }
                    }
                }
            }
        }
Example #11
0
        public void TestAsyncPendingSubscriptionBatchSizeExactlyOne()
        {
            int total         = 10;
            int receivedCount = 0;

            AutoResetEvent   evSubDone = new AutoResetEvent(false);
            ManualResetEvent evStart   = new ManualResetEvent(false);

            byte[] data = Encoding.UTF8.GetBytes("0123456789");

            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                var opts = Context.GetTestOptions(Context.Server1.Port);
                opts.SubscriptionBatchSize = 1;

                using (IConnection c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    using (var s = c.SubscribeAsync("foo", (sender, args) =>
                    {
                        evStart.WaitOne(60000);

                        receivedCount++;
                        if (receivedCount == total)
                        {
                            evSubDone.Set();
                        }
                    }))
                    {
                        for (int i = 0; i < total; i++)
                        {
                            c.Publish("foo", data);
                        }

                        c.Flush();

                        Thread.Sleep(1000);

                        int expectedPendingCount = total - 1;

                        // Exactly 1 message will be dequeued
                        Assert.True(s.QueuedMessageCount == expectedPendingCount);

                        Assert.True((s.MaxPendingBytes == (data.Length * total)) ||
                                    (s.MaxPendingBytes == (data.Length * expectedPendingCount)));
                        Assert.True((s.MaxPendingMessages == total) ||
                                    (s.MaxPendingMessages == expectedPendingCount));
                        Assert.True((s.PendingBytes == (data.Length * total)) ||
                                    (s.PendingBytes == (data.Length * expectedPendingCount)));

                        long pendingBytes;
                        long pendingMsgs;

                        s.GetPending(out pendingBytes, out pendingMsgs);
                        Assert.True(pendingBytes == s.PendingBytes);
                        Assert.True(pendingMsgs == s.PendingMessages);

                        long maxPendingBytes;
                        long maxPendingMsgs;
                        s.GetMaxPending(out maxPendingBytes, out maxPendingMsgs);
                        Assert.True(maxPendingBytes == s.MaxPendingBytes);
                        Assert.True(maxPendingMsgs == s.MaxPendingMessages);


                        Assert.True((s.PendingMessages == total) ||
                                    (s.PendingMessages == expectedPendingCount));

                        Assert.True(s.Delivered == 1);
                        Assert.True(s.Dropped == 0);

                        evStart.Set();
                        evSubDone.WaitOne(10000);

                        Assert.True(s.QueuedMessageCount == 0);

                        Assert.True((s.MaxPendingBytes == (data.Length * total)) ||
                                    (s.MaxPendingBytes == (data.Length * expectedPendingCount)));
                        Assert.True((s.MaxPendingMessages == total) ||
                                    (s.MaxPendingMessages == expectedPendingCount));

                        Assert.True(s.PendingMessages == 0);
                        Assert.True(s.PendingBytes == 0);

                        Assert.True(s.Delivered == total);
                        Assert.True(s.Dropped == 0);

                        s.Unsubscribe();
                    }
                }
            }
        }
Example #12
0
        public void TestAsyncErrHandler()
        {
            object             subLock  = new object();
            object             testLock = new object();
            IAsyncSubscription s;

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

            opts.SubChannelLength = 10;

            bool handledError = false;

            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                using (IConnection c = Context.ConnectionFactory.CreateConnection(opts))
                {
                    using (s = c.SubscribeAsync("foo"))
                    {
                        c.Opts.AsyncErrorEventHandler = (sender, args) =>
                        {
                            lock (subLock)
                            {
                                if (handledError)
                                {
                                    return;
                                }

                                handledError = true;

                                Assert.True(args.Subscription == s);
                                Assert.Contains("Slow", args.Error);

                                // release the subscriber
                                Monitor.Pulse(subLock);
                            }

                            // release the test
                            lock (testLock) { Monitor.Pulse(testLock); }
                        };

                        bool blockedOnSubscriber = false;
                        s.MessageHandler += (sender, args) =>
                        {
                            lock (subLock)
                            {
                                if (blockedOnSubscriber)
                                {
                                    return;
                                }

                                Assert.True(Monitor.Wait(subLock, 500));
                                blockedOnSubscriber = true;
                            }
                        };

                        s.Start();

                        lock (testLock)
                        {
                            for (int i = 0; i < (opts.SubChannelLength + 100); i++)
                            {
                                c.Publish("foo", null);
                            }

                            try
                            {
                                c.Flush(1000);
                            }
                            catch (Exception)
                            {
                                // ignore - we're testing the error handler, not flush.
                            }

                            Assert.True(Monitor.Wait(testLock, 1000));
                        }
                    }
                }
            }
        }
Example #13
0
        public void TestAsyncSubscriptionPending()
        {
            int total         = 100;
            int receivedCount = 0;

            AutoResetEvent   evSubDone = new AutoResetEvent(false);
            ManualResetEvent evStart   = new ManualResetEvent(false);

            byte[] data = Encoding.UTF8.GetBytes("0123456789");

            using (NATSServer.CreateFastAndVerify(Context.Server1.Port))
            {
                using (IConnection c = Context.OpenConnection(Context.Server1.Port))
                {
                    ISubscription s = c.SubscribeAsync("foo", (sender, args) =>
                    {
                        evStart.WaitOne(60000);

                        receivedCount++;
                        if (receivedCount == total)
                        {
                            evSubDone.Set();
                        }
                    });

                    for (int i = 0; i < total; i++)
                    {
                        c.Publish("foo", data);
                    }
                    c.Flush();

                    Thread.Sleep(1000);

                    int expectedPendingCount = total - 1;

                    // At least 1 message will be dequeued
                    Assert.True(s.QueuedMessageCount <= expectedPendingCount);

                    Assert.True((s.MaxPendingBytes == (data.Length * total)) ||
                                (s.MaxPendingBytes == (data.Length * expectedPendingCount)));
                    Assert.True((s.MaxPendingMessages == total) ||
                                (s.MaxPendingMessages == expectedPendingCount));
                    Assert.True((s.PendingBytes == (data.Length * total)) ||
                                (s.PendingBytes == (data.Length * expectedPendingCount)));

                    long pendingBytes;
                    long pendingMsgs;

                    s.GetPending(out pendingBytes, out pendingMsgs);
                    Assert.True(pendingBytes == s.PendingBytes);
                    Assert.True(pendingMsgs == s.PendingMessages);

                    long maxPendingBytes;
                    long maxPendingMsgs;
                    s.GetMaxPending(out maxPendingBytes, out maxPendingMsgs);
                    Assert.True(maxPendingBytes == s.MaxPendingBytes);
                    Assert.True(maxPendingMsgs == s.MaxPendingMessages);


                    Assert.True((s.PendingMessages == total) ||
                                (s.PendingMessages == expectedPendingCount));

                    Assert.True(s.Delivered == 1);
                    Assert.True(s.Dropped == 0);

                    evStart.Set();
                    evSubDone.WaitOne(10000);

                    Assert.True(s.QueuedMessageCount == 0);

                    Assert.True((s.MaxPendingBytes == (data.Length * total)) ||
                                (s.MaxPendingBytes == (data.Length * expectedPendingCount)));
                    Assert.True((s.MaxPendingMessages == total) ||
                                (s.MaxPendingMessages == expectedPendingCount));

                    Assert.True(s.PendingMessages == 0);
                    Assert.True(s.PendingBytes == 0);

                    Assert.True(s.Delivered == total);
                    Assert.True(s.Dropped == 0);

                    s.Unsubscribe();

                    Assert.ThrowsAny <Exception>(() => s.MaxPendingBytes);

                    Assert.ThrowsAny <Exception>(() => s.MaxPendingMessages);

                    Assert.ThrowsAny <Exception>(() => s.PendingMessageLimit);

                    Assert.ThrowsAny <Exception>(() => s.PendingByteLimit);

                    Assert.ThrowsAny <Exception>(() => s.SetPendingLimits(1, 10));
                }
            }
        }