Commit eb3955b0 authored by Marc Gravell's avatar Marc Gravell

Migrate: pub/sub test suite

parent c002a00e
//using NUnit.Framework; using NUnit.Framework;
//using System.Threading; using System.Threading;
//using System.Text; using System.Text;
//using System; using System;
//using System.Diagnostics; using System.Diagnostics;
//using System.Threading.Tasks; using System.Threading.Tasks;
//using BookSleeve; using System.Collections.Generic;
//using System.Collections.Generic; using StackExchange.Redis;
//namespace Tests namespace Tests
//{ {
// [TestFixture] [TestFixture]
// public class PubSub // http://redis.io/commands#pubsub public class PubSub // http://redis.io/commands#pubsub
// { {
// [Test] [Test]
// public void TestPublishWithNoSubscribers() public void TestPublishWithNoSubscribers()
// { {
// using (var conn = Config.GetUnsecuredConnection()) using (var muxer = Config.GetUnsecuredConnection())
// { {
// Assert.AreEqual(0, conn.Wait(conn.Publish("channel", "message"))); var conn = muxer.GetSubscriber();
// } Assert.AreEqual(0, conn.Publish("channel", "message"));
// } }
}
// [Test]
// public void TestMassivePublishWithWithoutFlush_Local() [Test]
// { public void TestMassivePublishWithWithoutFlush_Local()
// using (var conn = Config.GetUnsecuredConnection(waitForOpen: true)) {
// { using (var muxer = Config.GetUnsecuredConnection(waitForOpen: true))
// TestMassivePublishWithWithoutFlush(conn, "local"); {
// } var conn = muxer.GetSubscriber();
// } TestMassivePublish(conn, "local");
// [Test] }
// public void TestMassivePublishWithWithoutFlush_Remote() }
// { [Test]
// using (var conn = Config.GetRemoteConnection(waitForOpen: true)) public void TestMassivePublishWithWithoutFlush_Remote()
// { {
// TestMassivePublishWithWithoutFlush(conn, "remote"); using (var muxer = Config.GetRemoteConnection(waitForOpen: true))
// } {
// } var conn = muxer.GetSubscriber();
TestMassivePublish(conn, "remote");
// private void TestMassivePublishWithWithoutFlush(RedisConnection conn, string caption) }
// { }
// const int loop = 100000;
private void TestMassivePublish(ISubscriber conn, string caption)
// GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); {
// GC.WaitForPendingFinalizers(); const int loop = 100000;
// var tasks = new Task[loop]; GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
// var withFlush = Stopwatch.StartNew(); GC.WaitForPendingFinalizers();
// for (int i = 0; i < loop; i++)
// tasks[i] = conn.Publish("foo", "bar"); var tasks = new Task[loop];
// conn.WaitAll(tasks);
// withFlush.Stop(); var withFAF = Stopwatch.StartNew();
for (int i = 0; i < loop; i++)
// GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced); conn.Publish("foo", "bar", CommandFlags.FireAndForget);
// GC.WaitForPendingFinalizers(); withFAF.Stop();
// conn.SuspendFlush(); GC.Collect(GC.MaxGeneration, GCCollectionMode.Forced);
// var withoutFlush = Stopwatch.StartNew(); GC.WaitForPendingFinalizers();
// for (int i = 0; i < loop; i++)
// tasks[i] = conn.Publish("foo", "bar"); var withAsync = Stopwatch.StartNew();
// conn.ResumeFlush(); for (int i = 0; i < loop; i++)
// conn.WaitAll(tasks); tasks[i] = conn.PublishAsync("foo", "bar");
// withoutFlush.Stop(); conn.WaitAll(tasks);
withAsync.Stop();
// Assert.Less(1, 2, "sanity check");
// Assert.Less(withoutFlush.ElapsedMilliseconds, withFlush.ElapsedMilliseconds, caption); Assert.Less(1, 2, "sanity check");
// Console.WriteLine("{2}: {0}ms (eager-flush) vs {1}ms (suspend-flush)", Assert.Less(withFAF.ElapsedMilliseconds, withAsync.ElapsedMilliseconds, caption);
// withFlush.ElapsedMilliseconds, withoutFlush.ElapsedMilliseconds, caption); Console.WriteLine("{2}: {0}ms (F+F) vs {1}ms (async)",
// } withFAF.ElapsedMilliseconds, withAsync.ElapsedMilliseconds, caption);
}
// [Test]
// public void PubSubOrder() [Test]
// { public void PubSubOrder()
// using (var pub = Config.GetRemoteConnection(waitForOpen: true)) {
// using (var sub = pub.GetOpenSubscriberChannel()) using (var muxer = Config.GetRemoteConnection(waitForOpen: true))
// { {
// string channel = "PubSubOrder"; var sub = muxer.GetSubscriber();
// const int count = 500000; string channel = "PubSubOrder";
// object syncLock = new object(); const int count = 500000;
object syncLock = new object();
// List<int> data = new List<int>(count);
// sub.CompletionMode = ResultCompletionMode.PreserveOrder; List<int> data = new List<int>(count);
// sub.Subscribe(channel, (key,val) => { muxer.PreserveAsyncOrder = true;
// bool pulse; sub.SubscribeAsync(channel, (key, val) =>
// lock (data) {
// { bool pulse;
// data.Add(int.Parse(Encoding.UTF8.GetString(val))); lock (data)
// pulse = data.Count == count; {
// if((data.Count % 10) == 99) Console.WriteLine(data.Count); data.Add(int.Parse(Encoding.UTF8.GetString(val)));
// } pulse = data.Count == count;
// if(pulse) if ((data.Count % 10) == 99) Console.WriteLine(data.Count);
// lock(syncLock) }
// Monitor.PulseAll(syncLock); if (pulse)
// }).Wait(); lock (syncLock)
Monitor.PulseAll(syncLock);
// lock (syncLock) }).Wait();
// {
// for (int i = 0; i < count; i++) lock (syncLock)
// { {
// pub.Publish(channel, i.ToString()); for (int i = 0; i < count; i++)
// } {
// if (!Monitor.Wait(syncLock, 10000)) sub.Publish(channel, i.ToString(), CommandFlags.FireAndForget);
// { }
// throw new TimeoutException("Items: " + data.Count); sub.Ping();
// } if (!Monitor.Wait(syncLock, 10000))
// for (int i = 0; i < count; i++) {
// Assert.AreEqual(i, data[i]); throw new TimeoutException("Items: " + data.Count);
// } }
// } for (int i = 0; i < count; i++)
Assert.AreEqual(i, data[i]);
// } }
}
// [Test]
// public void TestPublishWithSubscribers() }
// {
// using (var listenA = Config.GetSubscriberConnection()) [Test]
// using (var listenB = Config.GetSubscriberConnection()) public void TestPublishWithSubscribers()
// using (var conn = Config.GetUnsecuredConnection()) {
// { using (var muxerA = Config.GetUnsecuredConnection())
// var t1 = listenA.Subscribe("channel", delegate { }); using (var muxerB = Config.GetUnsecuredConnection())
// var t2 = listenB.Subscribe("channel", delegate { }); using (var conn = Config.GetUnsecuredConnection())
{
// listenA.Wait(t1); var listenA = muxerA.GetSubscriber();
// Assert.AreEqual(1, listenA.SubscriptionCount, "A subscriptions"); var listenB = muxerB.GetSubscriber();
var t1 = listenA.SubscribeAsync("channel", delegate { });
// listenB.Wait(t2); var t2 = listenB.SubscribeAsync("channel", delegate { });
// Assert.AreEqual(1, listenB.SubscriptionCount, "B subscriptions");
listenA.Wait(t1);
// var pub = conn.Publish("channel", "message"); listenB.Wait(t2);
// Assert.AreEqual(2, conn.Wait(pub), "delivery count");
// } var pub = conn.GetSubscriber().PublishAsync("channel", "message");
// } Assert.AreEqual(2, conn.Wait(pub), "delivery count");
}
// [Test] }
// public void TestMultipleSubscribersGetMessage()
// { [Test]
// using (var listenA = Config.GetSubscriberConnection()) public void TestMultipleSubscribersGetMessage()
// using (var listenB = Config.GetSubscriberConnection()) {
// using (var conn = Config.GetUnsecuredConnection()) using (var muxerA = Config.GetUnsecuredConnection())
// { using (var muxerB = Config.GetUnsecuredConnection())
// conn.Wait(conn.Server.Ping()); using (var conn = Config.GetUnsecuredConnection())
// int gotA = 0, gotB = 0; {
// var tA = listenA.Subscribe("channel", (s, msg) => { if (Encoding.UTF8.GetString(msg) == "message") Interlocked.Increment(ref gotA); }); var listenA = muxerA.GetSubscriber();
// var tB = listenB.Subscribe("channel", (s, msg) => { if (Encoding.UTF8.GetString(msg) == "message") Interlocked.Increment(ref gotB); }); var listenB = muxerB.GetSubscriber();
// listenA.Wait(tA); conn.GetDatabase().Ping();
// listenB.Wait(tB); var pub = conn.GetSubscriber();
// Assert.AreEqual(2, conn.Wait(conn.Publish("channel", "message"))); int gotA = 0, gotB = 0;
// AllowReasonableTimeToPublishAndProcess(); var tA = listenA.SubscribeAsync("channel", (s, msg) => { if (msg == "message") Interlocked.Increment(ref gotA); });
// Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0)); var tB = listenB.SubscribeAsync("channel", (s, msg) => { if (msg == "message") Interlocked.Increment(ref gotB); });
// Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0)); listenA.Wait(tA);
listenB.Wait(tB);
// // and unsubscibe... Assert.AreEqual(2, pub.Publish("channel", "message"));
// tA = listenA.Unsubscribe("channel"); AllowReasonableTimeToPublishAndProcess();
// listenA.Wait(tA); Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0));
// Assert.AreEqual(1, conn.Wait(conn.Publish("channel", "message"))); Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0));
// AllowReasonableTimeToPublishAndProcess();
// Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0)); // and unsubscibe...
// Assert.AreEqual(2, Interlocked.CompareExchange(ref gotB, 0, 0)); tA = listenA.UnsubscribeAsync("channel");
// } listenA.Wait(tA);
// } Assert.AreEqual(1, pub.Publish("channel", "message"));
AllowReasonableTimeToPublishAndProcess();
// [Test] Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0));
// public void Issue38() Assert.AreEqual(2, Interlocked.CompareExchange(ref gotB, 0, 0));
// { // https://code.google.com/p/booksleeve/issues/detail?id=38 }
}
// using (var pub = Config.GetUnsecuredConnection(waitForOpen: true))
// using (var sub = pub.GetOpenSubscriberChannel()) [Test]
// { public void Issue38()
// int count = 0; { // https://code.google.com/p/booksleeve/issues/detail?id=38
// Action<string, byte[]> handler = (channel, payload) => Interlocked.Increment(ref count);
// var a = sub.Subscribe(new string[] { "foo", "bar" }, handler); using (var pub = Config.GetUnsecuredConnection(waitForOpen: true))
// var b = sub.PatternSubscribe(new string[] { "f*o", "b*r" }, handler); {
// sub.WaitAll(a, b); var sub = pub.GetSubscriber();
int count = 0;
// var c = pub.Publish("foo", "foo"); Action<RedisChannel, RedisValue> handler = (channel, payload) => Interlocked.Increment(ref count);
// var d = pub.Publish("f@o", "f@o"); var a0 = sub.SubscribeAsync("foo", handler);
// var e = pub.Publish("bar", "bar"); var a1 = sub.SubscribeAsync("bar", handler);
// var f = pub.Publish("b@r", "b@r"); var b0 = sub.SubscribeAsync("f*o", handler);
var b1 = sub.SubscribeAsync("b*r", handler);
// pub.WaitAll(c, d, e, f); sub.WaitAll(a0, a1, b0, b1);
// long total = c.Result + d.Result + e.Result + f.Result;
var c = sub.PublishAsync("foo", "foo");
// AllowReasonableTimeToPublishAndProcess(); var d = sub.PublishAsync("f@o", "f@o");
var e = sub.PublishAsync("bar", "bar");
// Assert.AreEqual(6, total, "sent"); var f = sub.PublishAsync("b@r", "b@r");
// Assert.AreEqual(6, Interlocked.CompareExchange(ref count, 0, 0), "received");
pub.WaitAll(c, d, e, f);
long total = c.Result + d.Result + e.Result + f.Result;
// }
// } AllowReasonableTimeToPublishAndProcess();
// internal static void AllowReasonableTimeToPublishAndProcess() Assert.AreEqual(6, total, "sent");
// { Assert.AreEqual(6, Interlocked.CompareExchange(ref count, 0, 0), "received");
// Thread.Sleep(50);
// }
}
// [Test] }
// public void TestPartialSubscriberGetMessage()
// { internal static void AllowReasonableTimeToPublishAndProcess()
// using (var listenA = Config.GetSubscriberConnection()) {
// using (var listenB = Config.GetSubscriberConnection()) Thread.Sleep(50);
// using (var conn = Config.GetUnsecuredConnection()) }
// {
// int gotA = 0, gotB = 0; [Test]
// var tA = listenA.Subscribe("channel", (s, msg) => { if (s == "channel" && Encoding.UTF8.GetString(msg) == "message") Interlocked.Increment(ref gotA); }); public void TestPartialSubscriberGetMessage()
// var tB = listenB.PatternSubscribe("chann*", (s, msg) => { if (s == "channel" && Encoding.UTF8.GetString(msg) == "message") Interlocked.Increment(ref gotB); }); {
// listenA.Wait(tA); using (var muxerA = Config.GetUnsecuredConnection())
// listenB.Wait(tB); using (var muxerB = Config.GetUnsecuredConnection())
// Assert.AreEqual(2, conn.Wait(conn.Publish("channel", "message"))); using (var conn = Config.GetUnsecuredConnection())
// AllowReasonableTimeToPublishAndProcess(); {
// Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0)); int gotA = 0, gotB = 0;
// Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0)); var listenA = muxerA.GetSubscriber();
var listenB = muxerB.GetSubscriber();
// // and unsubscibe... var pub = conn.GetSubscriber();
// tB = listenB.PatternUnsubscribe("chann*"); var tA = listenA.SubscribeAsync("channel", (s, msg) => { if (s == "channel" && msg == "message") Interlocked.Increment(ref gotA); });
// listenB.Wait(tB); var tB = listenB.SubscribeAsync("chann*", (s, msg) => { if (s == "channel" && msg == "message") Interlocked.Increment(ref gotB); });
// Assert.AreEqual(1, conn.Wait(conn.Publish("channel", "message"))); listenA.Wait(tA);
// AllowReasonableTimeToPublishAndProcess(); listenB.Wait(tB);
// Assert.AreEqual(2, Interlocked.CompareExchange(ref gotA, 0, 0)); Assert.AreEqual(2, pub.Publish("channel", "message"));
// Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0)); AllowReasonableTimeToPublishAndProcess();
// } Assert.AreEqual(1, Interlocked.CompareExchange(ref gotA, 0, 0));
// } Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0));
// [Test] // and unsubscibe...
// public void TestSubscribeUnsubscribeAndSubscribeAgain() tB = listenB.UnsubscribeAsync("chann*", null);
// { listenB.Wait(tB);
// using (var pub = Config.GetUnsecuredConnection()) Assert.AreEqual(1, pub.Publish("channel", "message"));
// using (var sub = Config.GetSubscriberConnection()) AllowReasonableTimeToPublishAndProcess();
// { Assert.AreEqual(2, Interlocked.CompareExchange(ref gotA, 0, 0));
// int x = 0, y = 0; Assert.AreEqual(1, Interlocked.CompareExchange(ref gotB, 0, 0));
// var t1 = sub.Subscribe("abc", delegate { Interlocked.Increment(ref x); }); }
// var t2 = sub.PatternSubscribe("ab*", delegate { Interlocked.Increment(ref y); }); }
// sub.WaitAll(t1, t2);
// pub.Publish("abc", ""); [Test]
// AllowReasonableTimeToPublishAndProcess(); public void TestSubscribeUnsubscribeAndSubscribeAgain()
// Assert.AreEqual(1, Thread.VolatileRead(ref x)); {
// Assert.AreEqual(1, Thread.VolatileRead(ref y)); using (var pubMuxer = Config.GetUnsecuredConnection())
// t1 = sub.Unsubscribe("abc"); using (var subMuxer = Config.GetUnsecuredConnection())
// t2 = sub.PatternUnsubscribe("ab*"); {
// sub.WaitAll(t1, t2); var pub = pubMuxer.GetSubscriber();
// pub.Publish("abc", ""); var sub = subMuxer.GetSubscriber();
// Assert.AreEqual(1, Thread.VolatileRead(ref x)); int x = 0, y = 0;
// Assert.AreEqual(1, Thread.VolatileRead(ref y)); var t1 = sub.SubscribeAsync("abc", delegate { Interlocked.Increment(ref x); });
// t1 = sub.Subscribe("abc", delegate { Interlocked.Increment(ref x); }); var t2 = sub.SubscribeAsync("ab*", delegate { Interlocked.Increment(ref y); });
// t2 = sub.PatternSubscribe("ab*", delegate { Interlocked.Increment(ref y); }); sub.WaitAll(t1, t2);
// sub.WaitAll(t1, t2); pub.Publish("abc", "");
// pub.Publish("abc", ""); AllowReasonableTimeToPublishAndProcess();
// AllowReasonableTimeToPublishAndProcess(); Assert.AreEqual(1, Thread.VolatileRead(ref x));
// Assert.AreEqual(2, Thread.VolatileRead(ref x)); Assert.AreEqual(1, Thread.VolatileRead(ref y));
// Assert.AreEqual(2, Thread.VolatileRead(ref y)); t1 = sub.UnsubscribeAsync("abc", null);
t2 = sub.UnsubscribeAsync("ab*", null);
// } sub.WaitAll(t1, t2);
// } pub.Publish("abc", "");
// } Assert.AreEqual(1, Thread.VolatileRead(ref x));
//} Assert.AreEqual(1, Thread.VolatileRead(ref y));
t1 = sub.SubscribeAsync("abc", delegate { Interlocked.Increment(ref x); });
t2 = sub.SubscribeAsync("ab*", delegate { Interlocked.Increment(ref y); });
sub.WaitAll(t1, t2);
pub.Publish("abc", "");
AllowReasonableTimeToPublishAndProcess();
Assert.AreEqual(2, Thread.VolatileRead(ref x));
Assert.AreEqual(2, Thread.VolatileRead(ref y));
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment