comparison Implab.Test/AsyncTests.cs @ 18:0c924dff5498

Слияние с promises
author cin
date Fri, 08 Nov 2013 01:27:04 +0400
parents 7cd4a843b4e4
children e3935fdf59a2
comparison
equal deleted inserted replaced
6:dfa21d507bc5 18:0c924dff5498
1 using System; 1 using System;
2 using Microsoft.VisualStudio.TestTools.UnitTesting; 2 using Microsoft.VisualStudio.TestTools.UnitTesting;
3 using Implab;
4 using System.Reflection; 3 using System.Reflection;
5 using System.Threading; 4 using System.Threading;
6 5 using Implab.Parallels;
7 namespace Implab.Tests 6
8 { 7 namespace Implab.Test {
9 [TestClass] 8 [TestClass]
10 public class AsyncTests 9 public class AsyncTests {
11 { 10 [TestMethod]
12 [TestMethod] 11 public void ResolveTest() {
13 public void ResolveTest () 12 int res = -1;
14 { 13 var p = new Promise<int>();
15 int res = -1; 14 p.Then(x => res = x);
16 var p = new Promise<int> (); 15 p.Resolve(100);
17 p.Then (x => res = x); 16
18 p.Resolve (100); 17 Assert.AreEqual(res, 100);
19 18 }
20 Assert.AreEqual (res, 100); 19
21 } 20 [TestMethod]
22 21 public void RejectTest() {
23 [TestMethod] 22 int res = -1;
24 public void RejectTest () 23 Exception err = null;
25 { 24
26 int res = -1; 25 var p = new Promise<int>();
27 Exception err = null; 26 p.Then(x => res = x, e => err = e);
28 27 p.Reject(new ApplicationException("error"));
29 var p = new Promise<int> (); 28
30 p.Then (x => res = x, e => err = e); 29 Assert.AreEqual(res, -1);
31 p.Reject (new ApplicationException ("error")); 30 Assert.AreEqual(err.Message, "error");
32 31
33 Assert.AreEqual (res, -1); 32 }
34 Assert.AreEqual (err.Message, "error"); 33
35 34 [TestMethod]
36 } 35 public void JoinSuccessTest() {
37 36 var p = new Promise<int>();
38 [TestMethod] 37 p.Resolve(100);
39 public void JoinSuccessTest () 38 Assert.AreEqual(p.Join(), 100);
40 { 39 }
41 var p = new Promise<int> (); 40
42 p.Resolve (100); 41 [TestMethod]
43 Assert.AreEqual (p.Join (), 100); 42 public void JoinFailTest() {
44 } 43 var p = new Promise<int>();
45 44 p.Reject(new ApplicationException("failed"));
46 [TestMethod] 45
47 public void JoinFailTest () 46 try {
48 { 47 p.Join();
49 var p = new Promise<int> (); 48 throw new ApplicationException("WRONG!");
50 p.Reject (new ApplicationException ("failed")); 49 } catch (TargetInvocationException err) {
51 50 Assert.AreEqual(err.InnerException.Message, "failed");
52 try { 51 } catch {
53 p.Join (); 52 Assert.Fail("Got wrong excaption");
54 throw new ApplicationException ("WRONG!"); 53 }
55 } catch (TargetInvocationException err) { 54 }
56 Assert.AreEqual (err.InnerException.Message, "failed"); 55
57 } catch { 56 [TestMethod]
58 Assert.Fail ("Got wrong excaption"); 57 public void MapTest() {
59 } 58 var p = new Promise<int>();
60 } 59
61 60 var p2 = p.Map(x => x.ToString());
62 [TestMethod] 61 p.Resolve(100);
63 public void MapTest () 62
64 { 63 Assert.AreEqual(p2.Join(), "100");
65 var p = new Promise<int> (); 64 }
66 65
67 var p2 = p.Map (x => x.ToString ()); 66 [TestMethod]
68 p.Resolve (100); 67 public void FixErrorTest() {
69 68 var p = new Promise<int>();
70 Assert.AreEqual (p2.Join (), "100"); 69
71 } 70 var p2 = p.Error(e => 101);
72 71
73 [TestMethod] 72 p.Reject(new Exception());
74 public void ChainTest () 73
75 { 74 Assert.AreEqual(p2.Join(), 101);
76 var p1 = new Promise<int> (); 75 }
77 76
78 var p3 = p1.Chain (x => { 77 [TestMethod]
79 var p2 = new Promise<string> (); 78 public void ChainTest() {
80 p2.Resolve (x.ToString ()); 79 var p1 = new Promise<int>();
81 return p2; 80
82 }); 81 var p3 = p1.Chain(x => {
83 82 var p2 = new Promise<string>();
84 p1.Resolve (100); 83 p2.Resolve(x.ToString());
85 84 return p2;
86 Assert.AreEqual (p3.Join (), "100"); 85 });
87 } 86
88 87 p1.Resolve(100);
89 [TestMethod] 88
90 public void PoolTest () 89 Assert.AreEqual(p3.Join(), "100");
91 { 90 }
92 var pid = Thread.CurrentThread.ManagedThreadId; 91
93 var p = AsyncPool.Invoke (() => { 92 [TestMethod]
94 return Thread.CurrentThread.ManagedThreadId; 93 public void PoolTest() {
95 }); 94 var pid = Thread.CurrentThread.ManagedThreadId;
96 95 var p = AsyncPool.Invoke(() => Thread.CurrentThread.ManagedThreadId);
97 Assert.AreNotEqual (pid, p.Join ()); 96
98 } 97 Assert.AreNotEqual(pid, p.Join());
99 } 98 }
99
100 [TestMethod]
101 public void WorkerPoolSizeTest() {
102 var pool = new WorkerPool(5, 10, 0);
103
104 Assert.AreEqual(5, pool.ThreadCount);
105
106 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
107 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
108 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
109
110 Assert.AreEqual(5, pool.ThreadCount);
111
112 for (int i = 0; i < 100; i++)
113 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
114 Thread.Sleep(100);
115 Assert.AreEqual(10, pool.ThreadCount);
116
117 pool.Dispose();
118 }
119
120 [TestMethod]
121 public void WorkerPoolCorrectTest() {
122 var pool = new WorkerPool(0,1000,100);
123
124 int iterations = 1000;
125 int pending = iterations;
126 var stop = new ManualResetEvent(false);
127
128 var count = 0;
129 for (int i = 0; i < iterations; i++) {
130 pool
131 .Invoke(() => 1)
132 .Then(x => Interlocked.Add(ref count, x))
133 .Then(x => Math.Log10(x))
134 .Anyway(() => {
135 Interlocked.Decrement(ref pending);
136 if (pending == 0)
137 stop.Set();
138 });
139 }
140
141 stop.WaitOne();
142
143 Assert.AreEqual(iterations, count);
144 Console.WriteLine("Max threads: {0}", pool.MaxRunningThreads);
145 pool.Dispose();
146
147 }
148
149 [TestMethod]
150 public void WorkerPoolDisposeTest() {
151 var pool = new WorkerPool(5, 20);
152 Assert.AreEqual(5, pool.ThreadCount);
153 pool.Dispose();
154 Thread.Sleep(100);
155 Assert.AreEqual(0, pool.ThreadCount);
156 pool.Dispose();
157 }
158
159 [TestMethod]
160 public void MTQueueTest() {
161 var queue = new MTQueue<int>();
162 int res;
163
164 queue.Enqueue(10);
165 Assert.IsTrue(queue.TryDequeue(out res));
166 Assert.AreEqual(10, res);
167 Assert.IsFalse(queue.TryDequeue(out res));
168
169 for (int i = 0; i < 1000; i++)
170 queue.Enqueue(i);
171
172 for (int i = 0; i < 1000; i++) {
173 queue.TryDequeue(out res);
174 Assert.AreEqual(i, res);
175 }
176
177 int writers = 0;
178 int readers = 0;
179 var stop = new ManualResetEvent(false);
180 int total = 0;
181
182 int itemsPerWriter = 1000;
183 int writersCount = 3;
184
185 for (int i = 0; i < writersCount; i++) {
186 Interlocked.Increment(ref writers);
187 var wn = i;
188 AsyncPool
189 .InvokeNewThread(() => {
190 for (int ii = 0; ii < itemsPerWriter; ii++) {
191 queue.Enqueue(1);
192 }
193 return 1;
194 })
195 .Anyway(() => Interlocked.Decrement(ref writers));
196 }
197
198 for (int i = 0; i < 10; i++) {
199 Interlocked.Increment(ref readers);
200 var wn = i;
201 AsyncPool
202 .InvokeNewThread(() => {
203 int t;
204 do {
205 while (queue.TryDequeue(out t))
206 Interlocked.Add(ref total, t);
207 } while (writers > 0);
208 return 1;
209 })
210 .Anyway(() => {
211 Interlocked.Decrement(ref readers);
212 if (readers == 0)
213 stop.Set();
214 });
215 }
216
217 stop.WaitOne();
218
219 Assert.AreEqual(itemsPerWriter * writersCount, total);
220 }
221
222 [TestMethod]
223 public void ParallelMapTest() {
224
225 int count = 100000;
226
227 double[] args = new double[count];
228 var rand = new Random();
229
230 for (int i = 0; i < count; i++)
231 args[i] = rand.NextDouble();
232
233 var t = Environment.TickCount;
234 var res = args.ParallelMap(x => Math.Sin(x*x), 4).Join();
235
236 Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t);
237
238 t = Environment.TickCount;
239 for (int i = 0; i < count; i++)
240 Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]);
241 Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
242 }
243
244 [TestMethod]
245 public void ChainedMapTest() {
246
247 using (var pool = new WorkerPool(8,100,0)) {
248 int count = 10000;
249
250 double[] args = new double[count];
251 var rand = new Random();
252
253 for (int i = 0; i < count; i++)
254 args[i] = rand.NextDouble();
255
256 var t = Environment.TickCount;
257 var res = args
258 .ChainedMap(
259 x => pool.Invoke(
260 () => Math.Sin(x * x)
261 ),
262 4
263 )
264 .Join();
265
266 Console.WriteLine("Map complete in {0} ms", Environment.TickCount - t);
267
268 t = Environment.TickCount;
269 for (int i = 0; i < count; i++)
270 Assert.AreEqual(Math.Sin(args[i] * args[i]), res[i]);
271 Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
272 Console.WriteLine("Max workers: {0}", pool.MaxRunningThreads);
273 }
274 }
275
276 [TestMethod]
277 public void ParallelForEachTest() {
278
279 int count = 100000;
280
281 int[] args = new int[count];
282 var rand = new Random();
283
284 for (int i = 0; i < count; i++)
285 args[i] = (int)(rand.NextDouble() * 100);
286
287 int result = 0;
288
289 var t = Environment.TickCount;
290 args.ParallelForEach(x => Interlocked.Add(ref result, x), 4).Join();
291
292 Console.WriteLine("Iteration complete in {0} ms, result: {1}", Environment.TickCount - t, result);
293
294 int result2 = 0;
295
296 t = Environment.TickCount;
297 for (int i = 0; i < count; i++)
298 result2 += args[i];
299 Assert.AreEqual(result2, result);
300 Console.WriteLine("Verified in {0} ms", Environment.TickCount - t);
301 }
302
303 [TestMethod]
304 public void ComplexCase1Test() {
305 var flags = new bool[3];
306
307 // op1 (aync 200ms) => op2 (async 200ms) => op3 (sync map)
308
309 var p = PromiseHelper
310 .Sleep(200, "Alan")
311 .Cancelled(() => flags[0] = true)
312 .Chain(x =>
313 PromiseHelper
314 .Sleep(200, "Hi, " + x)
315 .Map(y => y)
316 .Cancelled(() => flags[1] = true)
317 )
318 .Cancelled(() => flags[2] = true);
319 Thread.Sleep(300);
320 p.Cancel();
321 try {
322 Assert.AreEqual(p.Join(), "Hi, Alan");
323 Assert.Fail("Shouldn't get here");
324 } catch (OperationCanceledException) {
325 }
326
327 Assert.IsFalse(flags[0]);
328 Assert.IsTrue(flags[1]);
329 Assert.IsTrue(flags[2]);
330 }
331 }
100 } 332 }
101 333