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(); } } }
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(); } } } }
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); } } } }
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); } }
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); } } }); }
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); } } }); }
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); } }); }
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); } }); }
// 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."); } } }
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(); } } } } }
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(); } } } }
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)); } } } } }
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)); } } }