annotate Implab.Test/RunnableComponentTests.cs @ 198:b305c678923a

fixed error handling for chained actions
author koff
date Mon, 10 Oct 2016 03:14:00 +0300
parents 40d7fed4a09e
children 4d9830a9bbb8
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
185
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
1 using System;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
2 using System.Reflection;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
3 using System.Threading;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
4 using Implab.Parallels;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
5 using Implab.Components;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
6
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
7 #if MONO
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
8
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
9 using NUnit.Framework;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
10 using TestClassAttribute = NUnit.Framework.TestFixtureAttribute;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
11 using TestMethodAttribute = NUnit.Framework.TestAttribute;
188
3071220371f8 Updated VS project
cin
parents: 185
diff changeset
12 using AssertFailedException = NUnit.Framework.AssertionException;
185
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
13 #else
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
14
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
15 using Microsoft.VisualStudio.TestTools.UnitTesting;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
16
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
17 #endif
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
18
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
19 namespace Implab.Test {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
20 [TestClass]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
21 public class RunnableComponentTests {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
22
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
23 static void ShouldThrow(Action action) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
24 try {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
25 action();
188
3071220371f8 Updated VS project
cin
parents: 185
diff changeset
26 Assert.Fail();
3071220371f8 Updated VS project
cin
parents: 185
diff changeset
27 } catch (AssertFailedException) {
185
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
28 throw;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
29 } catch {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
30 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
31 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
32
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
33 class Runnable : RunnableComponent {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
34 public Runnable(bool initialized) : base(initialized) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
35 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
36
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
37 public Action MockInit {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
38 get;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
39 set;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
40 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
41
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
42 public Func<IPromise> MockStart {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
43 get;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
44 set;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
45 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
46
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
47 public Func<IPromise> MockStop {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
48 get;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
49 set;
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
50 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
51
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
52 protected override IPromise OnStart() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
53 return MockStart != null ? MockStart() : base.OnStart();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
54 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
55
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
56 protected override IPromise OnStop() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
57 return MockStop != null ? MockStop() : base.OnStart();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
58 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
59
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
60 protected override void OnInitialize() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
61 if (MockInit != null)
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
62 MockInit();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
63 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
64 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
65
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
66 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
67 public void NormalFlowTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
68 var comp = new Runnable(false);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
69
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
70 Assert.AreEqual(ExecutionState.Created, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
71
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
72 comp.Init();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
73
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
74 Assert.AreEqual(ExecutionState.Ready, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
75
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
76 comp.Start().Join(1000);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
77
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
78 Assert.AreEqual(ExecutionState.Running, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
79
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
80 comp.Stop().Join(1000);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
81
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
82 Assert.AreEqual(ExecutionState.Disposed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
83
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
84 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
85
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
86 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
87 public void InitFailTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
88 var comp = new Runnable(false) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
89 MockInit = () => {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
90 throw new Exception("BAD");
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
91 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
92 };
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
93
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
94 ShouldThrow(() => comp.Start());
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
95 ShouldThrow(() => comp.Stop());
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
96 Assert.AreEqual(ExecutionState.Created, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
97
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
98 ShouldThrow(comp.Init);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
99
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
100 Assert.AreEqual(ExecutionState.Failed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
101
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
102 ShouldThrow(() => comp.Start());
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
103 ShouldThrow(() => comp.Stop());
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
104 Assert.AreEqual(ExecutionState.Failed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
105
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
106 comp.Dispose();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
107 Assert.AreEqual(ExecutionState.Disposed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
108 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
109
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
110 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
111 public void DisposedTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
112
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
113 var comp = new Runnable(false);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
114 comp.Dispose();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
115
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
116 ShouldThrow(() => comp.Start());
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
117 ShouldThrow(() => comp.Stop());
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
118 ShouldThrow(comp.Init);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
119
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
120 Assert.AreEqual(ExecutionState.Disposed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
121 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
122
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
123 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
124 public void StartCancelTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
125 var comp = new Runnable(true) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
126 MockStart = () => PromiseHelper.Sleep(100000, 0)
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
127 };
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
128
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
129 var p = comp.Start();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
130 Assert.AreEqual(ExecutionState.Starting, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
131 p.Cancel();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
132 ShouldThrow(() => p.Join(1000));
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
133 Assert.AreEqual(ExecutionState.Failed, comp.State);
188
3071220371f8 Updated VS project
cin
parents: 185
diff changeset
134
196
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 188
diff changeset
135 Assert.IsTrue(comp.LastError is OperationCanceledException);
185
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
136
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
137 comp.Dispose();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
138 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
139
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
140 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
141 public void StartStopTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
142 var stop = new Signal();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
143 var comp = new Runnable(true) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
144 MockStart = () => PromiseHelper.Sleep(100000, 0),
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
145 MockStop = () => AsyncPool.RunThread(stop.Wait)
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
146 };
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
147
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
148 var p1 = comp.Start();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
149 var p2 = comp.Stop();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
150 // should enter stopping state
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
151
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
152 ShouldThrow(p1.Join);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
153 Assert.IsTrue(p1.IsCancelled);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
154 Assert.AreEqual(ExecutionState.Stopping, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
155
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
156 stop.Set();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
157 p2.Join(1000);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
158 Assert.AreEqual(ExecutionState.Disposed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
159 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
160
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
161 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
162 public void StartStopFailTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
163 var comp = new Runnable(true) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
164 MockStart = () => PromiseHelper.Sleep(100000, 0).Then(null,null,x => { throw new Exception("I'm dead"); })
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
165 };
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
166
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
167 comp.Start();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
168 var p = comp.Stop();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
169 // if Start fails to cancel, should fail to stop
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
170 ShouldThrow(() => p.Join(1000));
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
171 Assert.AreEqual(ExecutionState.Failed, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
172 Assert.IsNotNull(comp.LastError);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
173 Assert.AreEqual("I'm dead", comp.LastError.Message);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
174 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
175
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
176 [TestMethod]
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
177 public void StopCancelTest() {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
178 var comp = new Runnable(true) {
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
179 MockStop = () => PromiseHelper.Sleep(100000, 0)
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
180 };
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
181
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
182 comp.Start();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
183 var p = comp.Stop();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
184 Assert.AreEqual(ExecutionState.Stopping, comp.State);
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
185 p.Cancel();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
186 ShouldThrow(() => p.Join(1000));
188
3071220371f8 Updated VS project
cin
parents: 185
diff changeset
187 Assert.AreEqual(ExecutionState.Failed, comp.State);
196
40d7fed4a09e fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
cin
parents: 188
diff changeset
188 Assert.IsTrue(comp.LastError is OperationCanceledException);
185
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
189
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
190 comp.Dispose();
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
191 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
192
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
193 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
194 }
822aab37b107 runnable component, work in progress
cin
parents:
diff changeset
195