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;
|
|
12
|
|
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();
|
|
26 Assert.Fail();
|
|
27 } catch(AssertionException) {
|
|
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);
|
|
134 Assert.IsInstanceOfType(typeof(OperationCanceledException), comp.LastError);
|
|
135
|
|
136 comp.Dispose();
|
|
137 }
|
|
138
|
|
139 [TestMethod]
|
|
140 public void StartStopTest() {
|
|
141 var stop = new Signal();
|
|
142 var comp = new Runnable(true) {
|
|
143 MockStart = () => PromiseHelper.Sleep(100000, 0),
|
|
144 MockStop = () => AsyncPool.RunThread(stop.Wait)
|
|
145 };
|
|
146
|
|
147 var p1 = comp.Start();
|
|
148 var p2 = comp.Stop();
|
|
149 // should enter stopping state
|
|
150
|
|
151 ShouldThrow(p1.Join);
|
|
152 Assert.IsTrue(p1.IsCancelled);
|
|
153 Assert.AreEqual(ExecutionState.Stopping, comp.State);
|
|
154
|
|
155 stop.Set();
|
|
156 p2.Join(1000);
|
|
157 Assert.AreEqual(ExecutionState.Disposed, comp.State);
|
|
158 }
|
|
159
|
|
160 [TestMethod]
|
|
161 public void StartStopFailTest() {
|
|
162 var comp = new Runnable(true) {
|
|
163 MockStart = () => PromiseHelper.Sleep(100000, 0).Then(null,null,x => { throw new Exception("I'm dead"); })
|
|
164 };
|
|
165
|
|
166 comp.Start();
|
|
167 var p = comp.Stop();
|
|
168 // if Start fails to cancel, should fail to stop
|
|
169 ShouldThrow(() => p.Join(1000));
|
|
170 Assert.AreEqual(ExecutionState.Failed, comp.State);
|
|
171 Assert.IsNotNull(comp.LastError);
|
|
172 Assert.AreEqual("I'm dead", comp.LastError.Message);
|
|
173 }
|
|
174
|
|
175 [TestMethod]
|
|
176 public void StopCancelTest() {
|
|
177 var comp = new Runnable(true) {
|
|
178 MockStop = () => PromiseHelper.Sleep(100000, 0)
|
|
179 };
|
|
180
|
|
181 comp.Start();
|
|
182 var p = comp.Stop();
|
|
183 Assert.AreEqual(ExecutionState.Stopping, comp.State);
|
|
184 p.Cancel();
|
|
185 ShouldThrow(() => p.Join(1000));
|
|
186 Assert.AreEqual(ExecutionState.Failed, comp.State);
|
|
187 Assert.IsInstanceOfType(typeof(OperationCanceledException), comp.LastError);
|
|
188
|
|
189 comp.Dispose();
|
|
190 }
|
|
191
|
|
192 }
|
|
193 }
|
|
194
|