4
|
1 using System;
|
|
2 using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
3 using System.Reflection;
|
|
4 using System.Threading;
|
11
|
5 using Implab.Parallels;
|
4
|
6
|
15
|
7 namespace Implab.Test {
|
|
8 [TestClass]
|
|
9 public class AsyncTests {
|
|
10 [TestMethod]
|
|
11 public void ResolveTest() {
|
|
12 int res = -1;
|
|
13 var p = new Promise<int>();
|
|
14 p.Then(x => res = x);
|
|
15 p.Resolve(100);
|
4
|
16
|
15
|
17 Assert.AreEqual(res, 100);
|
|
18 }
|
0
|
19
|
4
|
20 [TestMethod]
|
15
|
21 public void RejectTest() {
|
|
22 int res = -1;
|
|
23 Exception err = null;
|
4
|
24
|
15
|
25 var p = new Promise<int>();
|
|
26 p.Then(x => res = x, e => err = e);
|
|
27 p.Reject(new ApplicationException("error"));
|
4
|
28
|
15
|
29 Assert.AreEqual(res, -1);
|
|
30 Assert.AreEqual(err.Message, "error");
|
4
|
31
|
15
|
32 }
|
0
|
33
|
4
|
34 [TestMethod]
|
15
|
35 public void JoinSuccessTest() {
|
|
36 var p = new Promise<int>();
|
|
37 p.Resolve(100);
|
|
38 Assert.AreEqual(p.Join(), 100);
|
|
39 }
|
0
|
40
|
4
|
41 [TestMethod]
|
15
|
42 public void JoinFailTest() {
|
|
43 var p = new Promise<int>();
|
|
44 p.Reject(new ApplicationException("failed"));
|
4
|
45
|
15
|
46 try {
|
|
47 p.Join();
|
|
48 throw new ApplicationException("WRONG!");
|
|
49 } catch (TargetInvocationException err) {
|
|
50 Assert.AreEqual(err.InnerException.Message, "failed");
|
|
51 } catch {
|
|
52 Assert.Fail("Got wrong excaption");
|
|
53 }
|
|
54 }
|
0
|
55
|
4
|
56 [TestMethod]
|
15
|
57 public void MapTest() {
|
|
58 var p = new Promise<int>();
|
4
|
59
|
15
|
60 var p2 = p.Map(x => x.ToString());
|
|
61 p.Resolve(100);
|
4
|
62
|
15
|
63 Assert.AreEqual(p2.Join(), "100");
|
|
64 }
|
0
|
65
|
4
|
66 [TestMethod]
|
11
|
67 public void FixErrorTest() {
|
|
68 var p = new Promise<int>();
|
|
69
|
|
70 var p2 = p.Error(e => 101);
|
|
71
|
|
72 p.Reject(new Exception());
|
|
73
|
|
74 Assert.AreEqual(p2.Join(), 101);
|
|
75 }
|
|
76
|
|
77 [TestMethod]
|
15
|
78 public void ChainTest() {
|
|
79 var p1 = new Promise<int>();
|
4
|
80
|
15
|
81 var p3 = p1.Chain(x => {
|
|
82 var p2 = new Promise<string>();
|
|
83 p2.Resolve(x.ToString());
|
|
84 return p2;
|
|
85 });
|
4
|
86
|
15
|
87 p1.Resolve(100);
|
4
|
88
|
15
|
89 Assert.AreEqual(p3.Join(), "100");
|
|
90 }
|
0
|
91
|
4
|
92 [TestMethod]
|
15
|
93 public void PoolTest() {
|
|
94 var pid = Thread.CurrentThread.ManagedThreadId;
|
|
95 var p = AsyncPool.Invoke(() => Thread.CurrentThread.ManagedThreadId);
|
4
|
96
|
15
|
97 Assert.AreNotEqual(pid, p.Join());
|
|
98 }
|
10
|
99
|
|
100 [TestMethod]
|
13
|
101 public void WorkerPoolSizeTest() {
|
15
|
102 var pool = new WorkerPool(5, 10);
|
13
|
103
|
|
104 Assert.AreEqual(5, pool.ThreadCount);
|
|
105
|
15
|
106 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
|
|
107 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
|
|
108 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
|
13
|
109
|
|
110 Assert.AreEqual(5, pool.ThreadCount);
|
|
111
|
|
112 for (int i = 0; i < 100; i++)
|
15
|
113 pool.Invoke(() => { Thread.Sleep(1000000); return 10; });
|
|
114 Thread.Sleep(100);
|
13
|
115 Assert.AreEqual(10, pool.ThreadCount);
|
15
|
116
|
|
117 pool.Dispose();
|
13
|
118 }
|
|
119
|
|
120 [TestMethod]
|
|
121 public void WorkerPoolCorrectTest() {
|
15
|
122 var pool = new WorkerPool();
|
|
123
|
|
124 int iterations = 1000;
|
|
125 int pending = iterations;
|
|
126 var stop = new ManualResetEvent(false);
|
13
|
127
|
|
128 var count = 0;
|
15
|
129 for (int i = 0; i < iterations; i++) {
|
13
|
130 pool
|
|
131 .Invoke(() => 1)
|
15
|
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();
|
13
|
142
|
15
|
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();
|
13
|
157 }
|
|
158
|
|
159 [TestMethod]
|
14
|
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 })
|
15
|
195 .Anyway(() => Interlocked.Decrement(ref writers));
|
14
|
196 }
|
15
|
197
|
14
|
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 })
|
15
|
210 .Anyway(() => {
|
14
|
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]
|
15
|
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]
|
16
|
245 public void ChainedMapTest() {
|
|
246
|
|
247 using (var pool = new WorkerPool(1,10)) {
|
|
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]
|
15
|
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]
|
10
|
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)
|
15
|
315 .Map(y => y)
|
10
|
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");
|
15
|
324 } catch (OperationCanceledException) {
|
10
|
325 }
|
|
326
|
|
327 Assert.IsFalse(flags[0]);
|
|
328 Assert.IsTrue(flags[1]);
|
|
329 Assert.IsTrue(flags[2]);
|
|
330 }
|
15
|
331 }
|
4
|
332 }
|
|
333
|