Commit 2c76086f authored by Marc Gravell's avatar Marc Gravell

Booksleeve test suite: Batches, Performance, Program

parent 5b5d43cc
//using NUnit.Framework; using NUnit.Framework;
//using System; using System;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Linq; using System.Linq;
//using System.Text; using System.Text;
//using System.Threading.Tasks; using System.Threading.Tasks;
//namespace Tests namespace Tests
//{ {
// [TestFixture] [TestFixture]
// public class Batches public class Batches
// { {
// [Test] [Test]
// public void TestBatchNotSent() public void TestBatchNotSent()
// { {
// using (var conn = Config.GetUnsecuredConnection()) using (var muxer = Config.GetUnsecuredConnection())
// { {
// conn.Keys.Remove(0, "batch"); var conn = muxer.GetDatabase(0);
// conn.Strings.Set(0, "batch", "batch-not-sent"); conn.KeyDeleteAsync("batch");
// var tasks = new List<Task>(); conn.StringSetAsync("batch", "batch-not-sent");
// using (var batch = conn.CreateBatch()) var tasks = new List<Task>();
// { var batch = conn.CreateBatch();
// tasks.Add(batch.Keys.Remove(0, "batch"));
// tasks.Add(batch.Sets.Add(0, "batch", "a"));
// tasks.Add(batch.Sets.Add(0, "batch", "b"));
// tasks.Add(batch.Sets.Add(0, "batch", "c"));
// }
// Assert.AreEqual("batch-not-sent", conn.Wait(conn.Strings.GetString(0, "batch")));
// }
// }
// [Test] tasks.Add(batch.KeyDeleteAsync("batch"));
// public void TestBatchSentTogether() tasks.Add(batch.SetAddAsync("batch", "a"));
// { tasks.Add(batch.SetAddAsync("batch", "b"));
// TestBatchSent(true); tasks.Add(batch.SetAddAsync("batch", "c"));
// }
// [Test]
// public void TestBatchSentApart()
// {
// TestBatchSent(false);
// }
// private void TestBatchSent(bool together)
// {
// using (var conn = Config.GetUnsecuredConnection())
// {
// conn.Keys.Remove(0, "batch");
// conn.Strings.Set(0, "batch", "batch-sent");
// var tasks = new List<Task>();
// using (var batch = conn.CreateBatch())
// {
// tasks.Add(batch.Keys.Remove(0, "batch"));
// tasks.Add(batch.Sets.Add(0, "batch", "a"));
// tasks.Add(batch.Sets.Add(0, "batch", "b"));
// tasks.Add(batch.Sets.Add(0, "batch", "c"));
// batch.Send(together);
// }
// var result = conn.Sets.GetAllString(0, "batch");
// tasks.Add(result);
// Task.WhenAll(tasks.ToArray());
// var arr = result.Result; Assert.AreEqual("batch-not-sent", (string)conn.StringGet("batch"));
// Array.Sort(arr); }
// Assert.AreEqual(3, arr.Length); }
// Assert.AreEqual("a", arr[0]);
// Assert.AreEqual("b", arr[1]); [Test]
// Assert.AreEqual("c", arr[2]); public void TestBatchSent()
// } {
// } using (var muxer = Config.GetUnsecuredConnection())
// } {
//} var conn = muxer.GetDatabase(0);
conn.KeyDeleteAsync("batch");
conn.StringSetAsync("batch", "batch-sent");
var tasks = new List<Task>();
var batch = conn.CreateBatch();
tasks.Add(batch.KeyDeleteAsync("batch"));
tasks.Add(batch.SetAddAsync("batch", "a"));
tasks.Add(batch.SetAddAsync("batch", "b"));
tasks.Add(batch.SetAddAsync("batch", "c"));
batch.Execute();
var result = conn.SetMembersAsync("batch");
tasks.Add(result);
Task.WhenAll(tasks.ToArray());
var arr = result.Result;
Array.Sort(arr, (x, y) => string.Compare(x, y));
Assert.AreEqual(3, arr.Length);
Assert.AreEqual("a", (string)arr[0]);
Assert.AreEqual("b", (string)arr[1]);
Assert.AreEqual("c", (string)arr[2]);
}
}
}
}
//using System; using System;
//using System.Diagnostics; using System.Diagnostics;
//using System.Text; using System.Text;
//using System.Threading.Tasks; using System.Threading.Tasks;
//using NUnit.Framework; using NUnit.Framework;
using StackExchange.Redis;
//namespace Tests namespace Tests
//{ {
// [TestFixture] [TestFixture]
// public class Performance public class Performance
// { {
// [Test] [Test]
// public void VerifyPerformanceImprovement() public void VerifyPerformanceImprovement()
// { {
// int asyncTimer, sync, op = 0, asyncFaF, syncFaF; int asyncTimer, sync, op = 0, asyncFaF, syncFaF;
// using (var conn = Config.GetUnsecuredConnection()) using (var muxer= Config.GetUnsecuredConnection())
// { {
// // do these outside the timings, just to ensure the core methods are JITted etc // do these outside the timings, just to ensure the core methods are JITted etc
// for (int db = 0; db < 5; db++ ) for (int db = 0; db < 5; db++)
// conn.Keys.Remove(db, "perftest"); {
muxer.GetDatabase(db).KeyDeleteAsync("perftest");
}
// var timer = Stopwatch.StartNew(); var timer = Stopwatch.StartNew();
// for (int i = 0; i < 100; i++) for (int i = 0; i < 100; i++)
// { {
// // want to test multiplex scenario; test each db, but to make it fair we'll // want to test multiplex scenario; test each db, but to make it fair we'll
// // do in batches of 10 on each // do in batches of 10 on each
// for (int db = 0; db < 5; db++) for (int db = 0; db < 5; db++)
// for (int j = 0; j < 10; j++) {
// conn.Strings.Increment(db, "perftest"); var conn = muxer.GetDatabase(db);
// } for (int j = 0; j < 10; j++)
// asyncFaF = (int)timer.ElapsedMilliseconds; conn.StringIncrementAsync("perftest");
// Task<string>[] final = new Task<string>[5]; }
// for (int db = 0; db < 5; db++) }
// final[db] = conn.Strings.GetString(db, "perftest"); asyncFaF = (int)timer.ElapsedMilliseconds;
// conn.WaitAll(final); Task<RedisValue>[] final = new Task<RedisValue>[5];
// timer.Stop(); for (int db = 0; db < 5; db++)
// asyncTimer = (int)timer.ElapsedMilliseconds; final[db] = muxer.GetDatabase(db).StringGetAsync("perftest");
// Console.WriteLine("async to completion (local): {0}ms", timer.ElapsedMilliseconds); muxer.WaitAll(final);
// for (int db = 0; db < 5; db++) timer.Stop();
// Assert.AreEqual("1000", final[db].Result, "async, db:" + db); asyncTimer = (int)timer.ElapsedMilliseconds;
// } Console.WriteLine("async to completion (local): {0}ms", timer.ElapsedMilliseconds);
// using (var conn = new Redis(Config.LocalHost, 6379)) for (int db = 0; db < 5; db++)
// { Assert.AreEqual(1000, (long)final[db].Result, "async, db:" + db);
// // do these outside the timings, just to ensure the core methods are JITted etc }
// for (int db = 0; db < 5; db++) {
// conn.Db = db;
// conn.Remove("perftest");
// }
// var timer = Stopwatch.StartNew(); using (var conn = new Redis(Config.LocalHost, 6379))
// for (int i = 0; i < 100; i++) {
// { // do these outside the timings, just to ensure the core methods are JITted etc
// // want to test multiplex scenario; test each db, but to make it fair we'll for (int db = 0; db < 5; db++)
// // do in batches of 10 on each {
// for (int db = 0; db < 5; db++) { conn.Db = db;
// conn.Db = db; conn.Remove("perftest");
// op++; }
// for (int j = 0; j < 10; j++) {
// conn.Increment("perftest"); var timer = Stopwatch.StartNew();
// op++; for (int i = 0; i < 100; i++)
// } {
// } // want to test multiplex scenario; test each db, but to make it fair we'll
// } // do in batches of 10 on each
// syncFaF = (int)timer.ElapsedMilliseconds; for (int db = 0; db < 5; db++)
// string[] final = new string[5]; {
// for (int db = 0; db < 5; db++) { conn.Db = db;
// conn.Db = db; op++;
// final[db] = Encoding.ASCII.GetString(conn.Get("perftest")); for (int j = 0; j < 10; j++)
// } {
// timer.Stop(); conn.Increment("perftest");
// sync = (int)timer.ElapsedMilliseconds; op++;
// Console.WriteLine("sync to completion (local): {0}ms", timer.ElapsedMilliseconds); }
// for (int db = 0; db < 5; db++) }
// Assert.AreEqual("1000", final[db], "async, db:" + db); }
// } syncFaF = (int)timer.ElapsedMilliseconds;
// int effectiveAsync = ((10 * asyncTimer) + 3) / 10; string[] final = new string[5];
// int effectiveSync = ((10 * sync) + (op * 3)) / 10; for (int db = 0; db < 5; db++)
// Console.WriteLine("async to completion with assumed 0.3ms LAN latency: " + effectiveAsync); {
// Console.WriteLine("sync to completion with assumed 0.3ms LAN latency: " + effectiveSync); conn.Db = db;
// Console.WriteLine("fire-and-forget: {0}ms sync vs {1}ms async ", syncFaF, asyncFaF); final[db] = Encoding.ASCII.GetString(conn.Get("perftest"));
// Assert.Less(effectiveAsync, effectiveSync, "Everything"); }
// Assert.Less(asyncFaF, syncFaF, "Fire and Forget"); timer.Stop();
// } sync = (int)timer.ElapsedMilliseconds;
// } Console.WriteLine("sync to completion (local): {0}ms", timer.ElapsedMilliseconds);
//} for (int db = 0; db < 5; db++)
Assert.AreEqual("1000", final[db], "async, db:" + db);
}
int effectiveAsync = ((10 * asyncTimer) + 3) / 10;
int effectiveSync = ((10 * sync) + (op * 3)) / 10;
Console.WriteLine("async to completion with assumed 0.3ms LAN latency: " + effectiveAsync);
Console.WriteLine("sync to completion with assumed 0.3ms LAN latency: " + effectiveSync);
Console.WriteLine("fire-and-forget: {0}ms sync vs {1}ms async ", syncFaF, asyncFaF);
Assert.Less(effectiveAsync, effectiveSync, "Everything");
Assert.Less(asyncFaF, syncFaF, "Fire and Forget");
}
}
}
//using System; using System;
//using System.Collections.Generic; using System.Collections.Generic;
//using System.Linq; using System.Linq;
//using System.Text; using System.Text;
//using NUnit.Framework; using NUnit.Framework;
//using System.Reflection; using System.Reflection;
//using System.Threading.Tasks; using System.Threading.Tasks;
//namespace Tests namespace Tests
//{ {
// class Program class Program
// { {
// static void Main() static void Main()
// { {
// try try
// { {
// Main2(); Main2();
// } }
// catch (Exception ex) catch (Exception ex)
// { {
// Console.WriteLine(); Console.WriteLine();
// Console.WriteLine("CRAZY ERRORS: " + ex); Console.WriteLine("CRAZY ERRORS: " + ex);
// } }
// finally finally
// { {
// Console.WriteLine("Press any key to exit"); Console.WriteLine("Press any key to exit");
// Console.ReadKey(); Console.ReadKey();
// } }
// } }
// static void Main2() { static void Main2()
// // why is this here? because some dumbass forgot to install a decent test-runner before going to the airport {
// var epicFail = new List<string>(); // why is this here? because some dumbass forgot to install a decent test-runner before going to the airport
// var testTypes = from type in typeof(Program).Assembly.GetTypes() var epicFail = new List<string>();
// where Attribute.IsDefined(type, typeof(TestFixtureAttribute)) var testTypes = from type in typeof(Program).Assembly.GetTypes()
// && !Attribute.IsDefined(type, typeof(IgnoreAttribute)) where Attribute.IsDefined(type, typeof(TestFixtureAttribute))
// let methods = type.GetMethods() && !Attribute.IsDefined(type, typeof(IgnoreAttribute))
// select new let methods = type.GetMethods()
// { select new
// Type = type, {
// Methods = methods, Type = type,
// ActiveMethods = methods.Where(x => Attribute.IsDefined(x, typeof(ActiveTestAttribute))).ToArray(), Methods = methods,
// Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureSetUpAttribute))), ActiveMethods = methods.Where(x => Attribute.IsDefined(x, typeof(ActiveTestAttribute))).ToArray(),
// TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureTearDownAttribute))) Setup = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureSetUpAttribute))),
// }; TearDown = methods.SingleOrDefault(x => Attribute.IsDefined(x, typeof(TestFixtureTearDownAttribute)))
// int pass = 0, fail = 0; };
int pass = 0, fail = 0;
// bool activeOnly = testTypes.SelectMany(x => x.ActiveMethods).Any(); bool activeOnly = testTypes.SelectMany(x => x.ActiveMethods).Any();
// TaskScheduler.UnobservedTaskException += (sender, args) => TaskScheduler.UnobservedTaskException += (sender, args) =>
// { {
// args.SetObserved(); args.SetObserved();
// //if (args.Exception is AggregateException) //if (args.Exception is AggregateException)
// //{ //{
// // foreach (var ex in ((AggregateException)args.Exception).InnerExceptions) // foreach (var ex in ((AggregateException)args.Exception).InnerExceptions)
// // { // {
// // Console.WriteLine(ex.Message); // Console.WriteLine(ex.Message);
// // } // }
// //} //}
// //else //else
// //{ //{
// // Console.WriteLine(args.Exception.Message); // Console.WriteLine(args.Exception.Message);
// //} //}
// }; };
// foreach (var type in testTypes) foreach (var type in testTypes)
// { {
// var tests = (from method in (activeOnly ? type.ActiveMethods : type.Methods) var tests = (from method in (activeOnly ? type.ActiveMethods : type.Methods)
// where Attribute.IsDefined(method, typeof(TestAttribute)) where Attribute.IsDefined(method, typeof(TestAttribute))
// && !Attribute.IsDefined(method, typeof(IgnoreAttribute)) && !Attribute.IsDefined(method, typeof(IgnoreAttribute))
// select method).ToArray(); select method).ToArray();
// if (tests.Length == 0) continue; if (tests.Length == 0) continue;
// Console.WriteLine(type.Type.FullName); Console.WriteLine(type.Type.FullName);
// object obj; object obj;
// try try
// { {
// obj = Activator.CreateInstance(type.Type); obj = Activator.CreateInstance(type.Type);
// if (obj == null) throw new InvalidOperationException("the world has gone mad"); if (obj == null) throw new InvalidOperationException("the world has gone mad");
// } }
// catch (Exception ex) catch (Exception ex)
// { {
// Console.WriteLine(ex.Message); Console.WriteLine(ex.Message);
// continue; continue;
// } }
// using (obj as IDisposable) using (obj as IDisposable)
// { {
// if (type.Setup != null) if (type.Setup != null)
// { {
// try { type.Setup.Invoke(obj, null); } try
// catch (Exception ex) { type.Setup.Invoke(obj, null); }
// { catch (Exception ex)
// Console.WriteLine("Test fixture startup failed: " + ex.Message); {
// fail++; Console.WriteLine("Test fixture startup failed: " + ex.Message);
// epicFail.Add(type.Setup.DeclaringType.FullName + "." + type.Setup.Name); fail++;
// continue; epicFail.Add(type.Setup.DeclaringType.FullName + "." + type.Setup.Name);
// } continue;
// } }
}
// foreach (var test in tests) foreach (var test in tests)
// { {
// var expectedFail = Attribute.GetCustomAttribute(test, typeof(ExpectedExceptionAttribute)) as ExpectedExceptionAttribute; var expectedFail = Attribute.GetCustomAttribute(test, typeof(ExpectedExceptionAttribute)) as ExpectedExceptionAttribute;
// Console.Write(test.Name + ": "); Console.Write(test.Name + ": ");
// Exception err = null; Exception err = null;
// try try
// { {
// int count = 1; int count = 1;
// if (activeOnly) if (activeOnly)
// { {
// var ata = test.GetCustomAttribute(typeof(ActiveTestAttribute)) as ActiveTestAttribute; var ata = test.GetCustomAttribute(typeof(ActiveTestAttribute)) as ActiveTestAttribute;
// if (ata != null) count = ata.Count; if (ata != null) count = ata.Count;
// } }
// while (count-- > 0) while (count-- > 0)
// { {
// test.Invoke(obj, null); test.Invoke(obj, null);
// } }
// } }
// catch (TargetInvocationException ex) catch (TargetInvocationException ex)
// { {
// err = ex.InnerException; err = ex.InnerException;
// } }
// catch (Exception ex) catch (Exception ex)
// { {
// err = ex; err = ex;
// } }
// if (err is AggregateException && ((AggregateException)err).InnerExceptions.Count == 1) if (err is AggregateException && ((AggregateException)err).InnerExceptions.Count == 1)
// { {
// err = ((AggregateException)err).InnerExceptions[0]; err = ((AggregateException)err).InnerExceptions[0];
// } }
// if (expectedFail != null) if (expectedFail != null)
// { {
// if (err == null) if (err == null)
// { {
// err = new NUnit.Framework.AssertionException("failed to fail"); err = new NUnit.Framework.AssertionException("failed to fail");
// } }
// else else
// { {
// int issues = 0; int issues = 0;
// if (expectedFail.ExpectedException != null && !expectedFail.ExpectedException.IsAssignableFrom(err.GetType())) if (expectedFail.ExpectedException != null && !expectedFail.ExpectedException.IsAssignableFrom(err.GetType()))
// { {
// issues++; issues++;
// } }
// if (expectedFail.ExpectedExceptionName != null && err.GetType().FullName != expectedFail.ExpectedExceptionName) if (expectedFail.ExpectedExceptionName != null && err.GetType().FullName != expectedFail.ExpectedExceptionName)
// { {
// issues++; issues++;
// } }
// if (expectedFail.ExpectedMessage != null && err.Message != expectedFail.ExpectedMessage) if (expectedFail.ExpectedMessage != null && err.Message != expectedFail.ExpectedMessage)
// { {
// issues++; issues++;
// } }
// if (issues == 0) err = null; if (issues == 0) err = null;
// else else
// { {
// err = new InvalidOperationException("Failed in a different way", err); err = new InvalidOperationException("Failed in a different way", err);
// } }
// } }
// } }
// if (err == null) if (err == null)
// { {
// Console.WriteLine("pass"); Console.WriteLine("pass");
// pass++; pass++;
// } }
// else else
// { {
// Console.WriteLine(err.Message); Console.WriteLine(err.Message);
// fail++; fail++;
// epicFail.Add(test.DeclaringType.FullName + "." + test.Name); epicFail.Add(test.DeclaringType.FullName + "." + test.Name);
// } }
// } }
// if (type.TearDown != null) if (type.TearDown != null)
// { {
// try { type.TearDown.Invoke(obj, null); } try
// catch (Exception ex) { type.TearDown.Invoke(obj, null); }
// { catch (Exception ex)
// Console.WriteLine("Test fixture teardown failed: " + ex.Message); {
// fail++; Console.WriteLine("Test fixture teardown failed: " + ex.Message);
// epicFail.Add(type.TearDown.DeclaringType.FullName + "." + type.TearDown.Name); fail++;
// } epicFail.Add(type.TearDown.DeclaringType.FullName + "." + type.TearDown.Name);
// } }
// } }
// } }
// Console.WriteLine("Passed: {0}; Failed: {1}", pass, fail); }
// foreach (var msg in epicFail) Console.WriteLine(msg); Console.WriteLine("Passed: {0}; Failed: {1}", pass, fail);
//#if DEBUG foreach (var msg in epicFail) Console.WriteLine(msg);
// Console.WriteLine(); #if DEBUG
// Console.WriteLine("Callbacks: {0:###,###,##0} sync, {1:###,###,##0} async", Console.WriteLine();
// BookSleeve.RedisConnectionBase.AllSyncCallbacks, BookSleeve.RedisConnectionBase.AllAsyncCallbacks); Console.WriteLine("Callbacks: {0:###,###,##0} sync, {1:###,###,##0} async",
//#endif BookSleeve.RedisConnectionBase.AllSyncCallbacks, BookSleeve.RedisConnectionBase.AllAsyncCallbacks);
#endif
// } }
// } }
//} }
//[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)] [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
//public sealed class ActiveTestAttribute : Attribute { public sealed class ActiveTestAttribute : Attribute
// private readonly int count; {
// public int Count { get { return count; } } private readonly int count;
// public ActiveTestAttribute() : this(1) { } public int Count { get { return count; } }
// public ActiveTestAttribute(int count) { this.count = count; } public ActiveTestAttribute() : this(1) { }
//} public ActiveTestAttribute(int count) { this.count = count; }
\ No newline at end of file }
\ No newline at end of file
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