AsyncTests.cs
301 lines
| 9.0 KiB
| text/x-csharp
|
CSharpLexer
/ Implab.Test / AsyncTests.cs
|
|
r4 | using System; | ||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
| using System.Reflection; | ||||
| using System.Threading; | ||||
|
|
r11 | using Implab.Parallels; | ||
|
|
r4 | |||
|
|
r15 | namespace Implab.Test { | ||
| [TestClass] | ||||
| public class AsyncTests { | ||||
| [TestMethod] | ||||
| public void ResolveTest() { | ||||
| int res = -1; | ||||
| var p = new Promise<int>(); | ||||
| p.Then(x => res = x); | ||||
| p.Resolve(100); | ||||
|
|
r4 | |||
|
|
r15 | Assert.AreEqual(res, 100); | ||
| } | ||||
|
|
r0 | |||
|
|
r4 | [TestMethod] | ||
|
|
r15 | public void RejectTest() { | ||
| int res = -1; | ||||
| Exception err = null; | ||||
|
|
r4 | |||
|
|
r15 | var p = new Promise<int>(); | ||
| p.Then(x => res = x, e => err = e); | ||||
| p.Reject(new ApplicationException("error")); | ||||
|
|
r4 | |||
|
|
r15 | Assert.AreEqual(res, -1); | ||
| Assert.AreEqual(err.Message, "error"); | ||||
|
|
r4 | |||
|
|
r15 | } | ||
|
|
r0 | |||
|
|
r4 | [TestMethod] | ||
|
|
r15 | public void JoinSuccessTest() { | ||
| var p = new Promise<int>(); | ||||
| p.Resolve(100); | ||||
| Assert.AreEqual(p.Join(), 100); | ||||
| } | ||||
|
|
r0 | |||
|
|
r4 | [TestMethod] | ||
|
|
r15 | public void JoinFailTest() { | ||
| var p = new Promise<int>(); | ||||
| p.Reject(new ApplicationException("failed")); | ||||
|
|
r4 | |||
|
|
r15 | try { | ||
| p.Join(); | ||||
| throw new ApplicationException("WRONG!"); | ||||
| } catch (TargetInvocationException err) { | ||||
| Assert.AreEqual(err.InnerException.Message, "failed"); | ||||
| } catch { | ||||
| Assert.Fail("Got wrong excaption"); | ||||
| } | ||||
| } | ||||
|
|
r0 | |||
|
|
r4 | [TestMethod] | ||
|
|
r15 | public void MapTest() { | ||
| var p = new Promise<int>(); | ||||
|
|
r4 | |||
|
|
r15 | var p2 = p.Map(x => x.ToString()); | ||
| p.Resolve(100); | ||||
|
|
r4 | |||
|
|
r15 | Assert.AreEqual(p2.Join(), "100"); | ||
| } | ||||
|
|
r0 | |||
|
|
r4 | [TestMethod] | ||
|
|
r11 | public void FixErrorTest() { | ||
| var p = new Promise<int>(); | ||||
| var p2 = p.Error(e => 101); | ||||
| p.Reject(new Exception()); | ||||
| Assert.AreEqual(p2.Join(), 101); | ||||
| } | ||||
| [TestMethod] | ||||
|
|
r15 | public void ChainTest() { | ||
| var p1 = new Promise<int>(); | ||||
|
|
r4 | |||
|
|
r15 | var p3 = p1.Chain(x => { | ||
| var p2 = new Promise<string>(); | ||||
| p2.Resolve(x.ToString()); | ||||
| return p2; | ||||
| }); | ||||
|
|
r4 | |||
|
|
r15 | p1.Resolve(100); | ||
|
|
r4 | |||
|
|
r15 | Assert.AreEqual(p3.Join(), "100"); | ||
| } | ||||
|
|
r0 | |||
|
|
r4 | [TestMethod] | ||
|
|
r15 | public void PoolTest() { | ||
| var pid = Thread.CurrentThread.ManagedThreadId; | ||||
| var p = AsyncPool.Invoke(() => Thread.CurrentThread.ManagedThreadId); | ||||
|
|
r4 | |||
|
|
r15 | Assert.AreNotEqual(pid, p.Join()); | ||
| } | ||||
|
|
r10 | |||
| [TestMethod] | ||||
|
|
r13 | public void WorkerPoolSizeTest() { | ||
|
|
r15 | var pool = new WorkerPool(5, 10); | ||
|
|
r13 | |||
| Assert.AreEqual(5, pool.ThreadCount); | ||||
|
|
r15 | pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | ||
| pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | ||||
| pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | ||||
|
|
r13 | |||
| Assert.AreEqual(5, pool.ThreadCount); | ||||
| for (int i = 0; i < 100; i++) | ||||
|
|
r15 | pool.Invoke(() => { Thread.Sleep(1000000); return 10; }); | ||
| Thread.Sleep(100); | ||||
|
|
r13 | Assert.AreEqual(10, pool.ThreadCount); | ||
|
|
r15 | |||
| pool.Dispose(); | ||||
|
|
r13 | } | ||
| [TestMethod] | ||||
| public void WorkerPoolCorrectTest() { | ||||
|
|
r15 | var pool = new WorkerPool(); | ||
| int iterations = 1000; | ||||
| int pending = iterations; | ||||
| var stop = new ManualResetEvent(false); | ||||
|
|
r13 | |||
| var count = 0; | ||||
|
|
r15 | for (int i = 0; i < iterations; i++) { | ||
|
|
r13 | pool | ||
| .Invoke(() => 1) | ||||
|
|
r15 | .Then(x => Interlocked.Add(ref count, x)) | ||
| .Then(x => Math.Log10(x)) | ||||
| .Anyway(() => { | ||||
| Interlocked.Decrement(ref pending); | ||||
| if (pending == 0) | ||||
| stop.Set(); | ||||
| }); | ||||
| } | ||||
| stop.WaitOne(); | ||||
|
|
r13 | |||
|
|
r15 | Assert.AreEqual(iterations, count); | ||
| Console.WriteLine("Max threads: {0}", pool.MaxRunningThreads); | ||||
| pool.Dispose(); | ||||
| } | ||||
| [TestMethod] | ||||
| public void WorkerPoolDisposeTest() { | ||||
| var pool = new WorkerPool(5, 20); | ||||
| Assert.AreEqual(5, pool.ThreadCount); | ||||
| pool.Dispose(); | ||||
| Thread.Sleep(100); | ||||
| Assert.AreEqual(0, pool.ThreadCount); | ||||
| pool.Dispose(); | ||||
|
|
r13 | } | ||
| [TestMethod] | ||||
|
|
r14 | public void MTQueueTest() { | ||
| var queue = new MTQueue<int>(); | ||||
| int res; | ||||
| queue.Enqueue(10); | ||||
| Assert.IsTrue(queue.TryDequeue(out res)); | ||||
| Assert.AreEqual(10, res); | ||||
| Assert.IsFalse(queue.TryDequeue(out res)); | ||||
| for (int i = 0; i < 1000; i++) | ||||
| queue.Enqueue(i); | ||||
| for (int i = 0; i < 1000; i++) { | ||||
| queue.TryDequeue(out res); | ||||
| Assert.AreEqual(i, res); | ||||
| } | ||||
| int writers = 0; | ||||
| int readers = 0; | ||||
| var stop = new ManualResetEvent(false); | ||||
| int total = 0; | ||||
| int itemsPerWriter = 1000; | ||||
| int writersCount = 3; | ||||
| for (int i = 0; i < writersCount; i++) { | ||||
| Interlocked.Increment(ref writers); | ||||
| var wn = i; | ||||
| AsyncPool | ||||
| .InvokeNewThread(() => { | ||||
| for (int ii = 0; ii < itemsPerWriter; ii++) { | ||||
| queue.Enqueue(1); | ||||
| } | ||||
| return 1; | ||||
| }) | ||||
|
|
r15 | .Anyway(() => Interlocked.Decrement(ref writers)); | ||
|
|
r14 | } | ||
|
|
r15 | |||
|
|
r14 | for (int i = 0; i < 10; i++) { | ||
| Interlocked.Increment(ref readers); | ||||
| var wn = i; | ||||
| AsyncPool | ||||
| .InvokeNewThread(() => { | ||||
| int t; | ||||
| do { | ||||
| while (queue.TryDequeue(out t)) | ||||
| Interlocked.Add(ref total, t); | ||||
| } while (writers > 0); | ||||
| return 1; | ||||
| }) | ||||
|
|
r15 | .Anyway(() => { | ||
|
|
r14 | Interlocked.Decrement(ref readers); | ||
| if (readers == 0) | ||||
| stop.Set(); | ||||
| }); | ||||
| } | ||||
| stop.WaitOne(); | ||||
| Assert.AreEqual(itemsPerWriter * writersCount, total); | ||||
| } | ||||
| [TestMethod] | ||||
|
|
r15 | public void ParallelMapTest() { | ||
| int count = 100000; | ||||
| double[] args = new double[count]; | ||||
| var rand = new Random(); | ||||
| for (int i = 0; i < count; i++) | ||||
| args[i] = rand.NextDouble(); | ||||
| var t = Environment.TickCount; | ||||
| var res = args.ParallelMap(x => Math.Sin(x*x), 4).Join(); | ||||
| Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t); | ||||
| t = Environment.TickCount; | ||||
| for (int i = 0; i < count; i++) | ||||
| Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]); | ||||
| Console.WriteLine("Verified in {0} ms", Environment.TickCount - t); | ||||
| } | ||||
| [TestMethod] | ||||
| public void ParallelForEachTest() { | ||||
| int count = 100000; | ||||
| int[] args = new int[count]; | ||||
| var rand = new Random(); | ||||
| for (int i = 0; i < count; i++) | ||||
| args[i] = (int)(rand.NextDouble() * 100); | ||||
| int result = 0; | ||||
| var t = Environment.TickCount; | ||||
| args.ParallelForEach(x => Interlocked.Add(ref result, x), 4).Join(); | ||||
| Console.WriteLine("Iteration complete in {0} ms, result: {1}", Environment.TickCount - t, result); | ||||
| int result2 = 0; | ||||
| t = Environment.TickCount; | ||||
| for (int i = 0; i < count; i++) | ||||
| result2 += args[i]; | ||||
| Assert.AreEqual(result2, result); | ||||
| Console.WriteLine("Verified in {0} ms", Environment.TickCount - t); | ||||
| } | ||||
| [TestMethod] | ||||
|
|
r10 | public void ComplexCase1Test() { | ||
| var flags = new bool[3]; | ||||
| // op1 (aync 200ms) => op2 (async 200ms) => op3 (sync map) | ||||
| var p = PromiseHelper | ||||
| .Sleep(200, "Alan") | ||||
| .Cancelled(() => flags[0] = true) | ||||
| .Chain(x => | ||||
| PromiseHelper | ||||
| .Sleep(200, "Hi, " + x) | ||||
|
|
r15 | .Map(y => y) | ||
|
|
r10 | .Cancelled(() => flags[1] = true) | ||
| ) | ||||
| .Cancelled(() => flags[2] = true); | ||||
| Thread.Sleep(300); | ||||
| p.Cancel(); | ||||
| try { | ||||
| Assert.AreEqual(p.Join(), "Hi, Alan"); | ||||
| Assert.Fail("Shouldn't get here"); | ||||
|
|
r15 | } catch (OperationCanceledException) { | ||
|
|
r10 | } | ||
| Assert.IsFalse(flags[0]); | ||||
| Assert.IsTrue(flags[1]); | ||||
| Assert.IsTrue(flags[2]); | ||||
| } | ||||
|
|
r15 | } | ||
|
|
r4 | } | ||
