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