##// END OF EJS Templates
Added IInitializable.Initialize() overload...
cin -
r262:f1696cdc3d7a v3.0.8 v3
parent child
Show More
@@ -1,4 +1,4
1 using NUnit.Framework;
1 using Xunit;
2 2 using System;
3 3 using Implab.Automaton;
4 4 using Implab.Xml;
@@ -7,11 +7,10 using Implab.Formats;
7 7 using Implab.Formats.Json;
8 8 using System.IO;
9 9
10 namespace Implab.Format.Test {
11 [TestFixture]
10 namespace Implab.Test {
12 11 public class JsonTests {
13 12
14 [Test]
13 [Fact]
15 14 public void TestScannerValidTokens() {
16 15 using (var scanner = JsonStringScanner.Create(@"9123, -123, 0, 0.1, -0.2, -0.1e3, 1.3E-3, ""some \t\n\u0020 text"", literal []{}:")) {
17 16
@@ -44,16 +43,16 namespace Implab.Format.Test {
44 43 JsonTokenType tokenType;
45 44 for (var i = 0; i < expexted.Length; i++) {
46 45
47 Assert.IsTrue(scanner.ReadToken(out value, out tokenType));
48 Assert.AreEqual(expexted[i].Item1, tokenType);
49 Assert.AreEqual(expexted[i].Item2, value);
46 Assert.True(scanner.ReadToken(out value, out tokenType));
47 Assert.Equal(expexted[i].Item1, tokenType);
48 Assert.Equal(expexted[i].Item2, value);
50 49 }
51 50
52 Assert.IsFalse(scanner.ReadToken(out value, out tokenType));
51 Assert.False(scanner.ReadToken(out value, out tokenType));
53 52 }
54 53 }
55 54
56 [Test]
55 [Fact]
57 56 public void TestScannerBadTokens() {
58 57 var bad = new[] {
59 58 " 1",
@@ -81,7 +80,7 namespace Implab.Format.Test {
81 80 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value);
82 81 continue;
83 82 }
84 Assert.Fail("Token '{0}' shouldn't pass", json);
83 Assert.True(false, $"Token '{json}' shouldn't pass");
85 84 } catch (ParserException e) {
86 85 Console.WriteLine(e.Message);
87 86 }
@@ -89,7 +88,7 namespace Implab.Format.Test {
89 88 }
90 89 }
91 90
92 [Test]
91 [Fact]
93 92 public void JsonXmlReaderSimpleTest() {
94 93 var json = "\"some text\"";
95 94 //Console.WriteLine($"JSON: {json}");
@@ -104,56 +103,35 namespace Implab.Format.Test {
104 103 Assert.IsFalse(xmlReader.Read());
105 104 }*/
106 105
107 //DumpJsonParse("\"text value\"");
108 //DumpJsonParse("null");
109 //DumpJsonParse("true");
110 //DumpJsonParse("{}");
111 //DumpJsonParse("[]");
106 DumpJsonParse("\"text value\"");
107 DumpJsonParse("null");
108 DumpJsonParse("true");
109 DumpJsonParse("{}");
110 DumpJsonParse("[]");
112 111 DumpJsonParse("{\"one\":1, \"two\":2}");
113 112 DumpJsonParse("[1,\"\",2,3]");
114 113 DumpJsonParse("[{\"info\": [7,8,9]}]");
115 114 DumpJsonFlatParse("[1,2,\"\",[3,4],{\"info\": [5,6]},{\"num\": [7,8,null]}, null,[null]]");
116 115 }
117 116
118 [Test]
119 public void JsonBenchmark() {
120 var t = Environment.TickCount;
121 using (var reader = new JsonXmlReader(JsonReader.Create("e:\\citylots.json"), new JsonXmlReaderOptions { NamespaceUri = "XmlReaderSimpleTest", RootName = "data" })) {
122 while (reader.Read()) {
123 }
124 }
125 Console.WriteLine($"JsonXmlReader: {Environment.TickCount - t} ms");
126
127 t = Environment.TickCount;
128 using(var reader = JsonReader.Create("e:\\citylots.json")) {
129 while(reader.Read()) {
130 }
131 }
132
133 Console.WriteLine($"JsonReader: {Environment.TickCount - t} ms");
134
135 t = Environment.TickCount;
136 using (var reader = XmlReader.Create("file:///e:\\citylots.xml")) {
137 while (reader.Read()) {
138 }
139 }
140
141 Console.WriteLine($"XmlReader: {Environment.TickCount - t} ms");
142 }
143
144 117 void AssertRead(XmlReader reader, XmlNodeType expected) {
145 Assert.IsTrue(reader.Read());
118 Assert.True(reader.Read());
146 119 Console.WriteLine($"{new string(' ', reader.Depth * 2)}{reader}");
147 Assert.AreEqual(expected, reader.NodeType);
120 Assert.Equal(expected, reader.NodeType);
148 121 }
149 122
150 123 void DumpJsonParse(string json) {
151 124 Console.WriteLine($"JSON: {json}");
152 125 Console.WriteLine("XML");
126 using (var xmlWriter = XmlWriter.Create(Console.Out, new XmlWriterSettings {
127 Indent = true,
128 CloseOutput = false,
129 ConformanceLevel = ConformanceLevel.Document
130 }))
153 131 using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "json" })) {
154 while (xmlReader.Read())
155 Console.WriteLine($"{new string(' ', xmlReader.Depth * 2)}{xmlReader}");
132 xmlWriter.WriteNode(xmlReader, false);
156 133 }
134 Console.WriteLine();
157 135 }
158 136
159 137 void DumpJsonFlatParse(string json) {
@@ -167,6 +145,7 namespace Implab.Format.Test {
167 145 using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "", FlattenArrays = true })) {
168 146 xmlWriter.WriteNode(xmlReader, false);
169 147 }
148 Console.WriteLine();
170 149 }
171 150 }
172 151 }
@@ -21,11 +21,13 namespace Implab.Test {
21 21 }
22 22
23 23 protected async override Task StopInternalAsync(CancellationToken ct) {
24 await base.StopInternalAsync(ct);
24 25 if (StopWorker != null)
25 26 await StopWorker.Invoke(ct);
26 27 }
27 28
28 29 protected async override Task StartInternalAsync(CancellationToken ct) {
30 await base.StartInternalAsync(ct);
29 31 if (StartWorker != null)
30 32 await StartWorker.Invoke(ct);
31 33 }
@@ -8,7 +8,7 namespace Implab.Test {
8 8
9 9 public class RunnableComponentTests {
10 10 [Fact]
11 public async Task Test1() {
11 public async Task SimpleStartStop() {
12 12
13 13 using (var m = new MockPollComponent(true)) {
14 14 m.StartWorker = async (ct) => await Task.Yield();
@@ -17,11 +17,245 namespace Implab.Test {
17 17 Assert.Equal(ExecutionState.Ready, m.State);
18 18 Assert.NotNull(m.Completion);
19 19
20 m.Start(CancellationToken.None);
20 m.Start();
21 21 await m.Completion;
22 22 Assert.Equal(ExecutionState.Running, m.State);
23 23
24 m.Stop();
25 await m.Completion;
26 Assert.Equal(ExecutionState.Stopped, m.State);
27 }
28 }
29
30 [Fact]
31 public async Task SyncStart() {
32 using (var m = new MockPollComponent(true)) {
33 m.Start();
34 Assert.Equal(ExecutionState.Running, m.State);
35 await m.Completion;
36 }
37 }
38
39 [Fact]
40 public async Task AsyncStarting() {
41 using (var m = new MockPollComponent(true)) {
42 var signal = Safe.CreateTask();
43
44 m.StartWorker = async (ct) => await signal;
45 m.Start();
46
47 Assert.Equal(ExecutionState.Starting, m.State);
48 Assert.False(m.Completion.IsCompleted);
49
50 signal.Start();
51
52 await m.Completion;
53
54 Assert.Equal(ExecutionState.Running, m.State);
55 }
56 }
57
58 [Fact]
59 public async Task FailWhileStarting() {
60 using (var m = new MockPollComponent(true)) {
61 const string failMessage = "Fail me";
62 var signal = new Task(() => {
63 throw new Exception(failMessage);
64 });
65
66 m.StartWorker = async (ct) => await signal;
67 m.Start();
68
69 Assert.Equal(ExecutionState.Starting, m.State);
70 Assert.False(m.Completion.IsCompleted);
71
72 signal.Start();
73 try {
74 await m.Completion;
75 Assert.True(false);
76 } catch (Exception e) {
77 Assert.Equal(failMessage, e.Message);
78 }
79
80 Assert.Equal(ExecutionState.Failed, m.State);
81 }
82 }
83
84 [Fact]
85 public async Task SyncStop() {
86 using (var m = new MockPollComponent(true)) {
87 m.Start();
88 Assert.Equal(ExecutionState.Running, m.State);
89 m.Stop();
90 Assert.Equal(ExecutionState.Stopped, m.State);
91 await m.Completion;
92 }
93 }
94
95 [Fact]
96 public async Task AsyncStopping() {
97 using (var m = new MockPollComponent(true)) {
98 var signal = Safe.CreateTask();
99
100 m.StopWorker = async (ct) => await signal;
101
102 // Start
103 m.Start();
104 Assert.Equal(ExecutionState.Running, m.State);
105
106 // Stop
107 m.Stop();
108 Assert.Equal(ExecutionState.Stopping, m.State);
109 Assert.False(m.Completion.IsCompleted);
110 signal.Start();
111
112 await m.Completion;
113
114 Assert.Equal(ExecutionState.Stopped, m.State);
115 }
116 }
117
118 [Fact]
119 public async Task FailWhileStopping() {
120 using (var m = new MockPollComponent(true)) {
121 const string failMessage = "Fail me";
122 var signal = new Task(() => {
123 throw new Exception(failMessage);
124 });
125
126 m.StopWorker = async (ct) => await signal;
127
128 // Start
129 m.Start();
130 Assert.Equal(ExecutionState.Running, m.State);
131
132 // Stop
133 m.Stop();
134 Assert.Equal(ExecutionState.Stopping, m.State);
135 Assert.False(m.Completion.IsCompleted);
136
137 signal.Start();
138 try {
139 await m.Completion;
140 Assert.True(false);
141 } catch (Exception e) {
142 Assert.Equal(failMessage, e.Message);
143 }
144
145 Assert.Equal(ExecutionState.Failed, m.State);
146 }
147 }
148
149 [Fact]
150 public async Task ThrowOnInvalidTrasition() {
151 using (var m = new MockPollComponent(false)) {
152 var started = Safe.CreateTask();
153 var stopped = Safe.CreateTask();
154
155 m.StartWorker = async (ct) => await started;
156 m.StopWorker = async (ct) => await stopped;
157
158 Assert.Throws<InvalidOperationException>(() => m.Start());
159
160 // Initialize
161 m.Initialize();
162 await m.Completion;
163
164 // Start
165 m.Start();
166 Assert.Equal(ExecutionState.Starting, m.State);
167
168 // Check invalid transitions
169 Assert.Throws<InvalidOperationException>(() => m.Start());
170
171 // Component can be stopped before started
172 // m.Stop(CancellationToken.None);
173
174 // Running
175 started.Start();
176 await m.Completion;
177 Assert.Equal(ExecutionState.Running, m.State);
178
179
180 Assert.Throws<InvalidOperationException>(() => m.Start());
181
182 // Stop
183 m.Stop();
184
185 // Check invalid transitions
186 Assert.Throws<InvalidOperationException>(() => m.Start());
187 Assert.Throws<InvalidOperationException>(() => m.Stop());
188
189 // Stopped
190 stopped.Start();
191 await m.Completion;
192 Assert.Equal(ExecutionState.Stopped, m.State);
193
194 // Check invalid transitions
195 Assert.Throws<InvalidOperationException>(() => m.Start());
196 Assert.Throws<InvalidOperationException>(() => m.Stop());
197 }
198 }
199
200 [Fact]
201 public async Task CancelStart() {
202 using (var m = new MockPollComponent(true)) {
203 m.StartWorker = (ct) => Safe.CreateTask(ct);
204
205 m.Start();
206 var start = m.Completion;
207
208 Assert.Equal(ExecutionState.Starting, m.State);
209 m.Stop();
210 await m.Completion;
211 Assert.Equal(ExecutionState.Stopped, m.State);
212 Assert.True(start.IsCompleted);
213 Assert.True(start.IsCanceled);
214 }
215 }
216
217 [Fact]
218 public async Task AwaitWorker() {
219 using (var m = new MockPollComponent(true)) {
220 var worker = Safe.CreateTask();
221
222 m.PollWorker = (ct) => worker;
223
224 m.Start(CancellationToken.None);
225 await m.Completion;
226
227 Assert.Equal(ExecutionState.Running, m.State);
228
24 229 m.Stop(CancellationToken.None);
230 Assert.Equal(ExecutionState.Stopping, m.State);
231 worker.Start();
232 await m.Completion;
233 Assert.Equal(ExecutionState.Stopped, m.State);
234 }
235 }
236
237 [Fact]
238 public async Task CancelWorker() {
239 using (var m = new MockPollComponent(true)) {
240 var worker = Safe.CreateTask();
241
242 var started = Safe.CreateTask();
243
244 m.PollWorker = async (ct) => {
245 started.Start();
246 await worker;
247 ct.ThrowIfCancellationRequested();
248 };
249
250 m.Start(CancellationToken.None);
251 await m.Completion;
252 await started; // await for the poll worker to start
253
254 Assert.Equal(ExecutionState.Running, m.State);
255
256 m.Stop(CancellationToken.None);
257 Assert.Equal(ExecutionState.Stopping, m.State);
258 worker.Start();
25 259 await m.Completion;
26 260 Assert.Equal(ExecutionState.Stopped, m.State);
27 261 }
@@ -1,4 +1,5
1 1 using System;
2 using System.Threading;
2 3
3 4 namespace Implab.Components {
4 5 /// <summary>
@@ -23,6 +24,7 namespace Implab.Components {
23 24 /// </para>
24 25 /// </remarks>
25 26 void Initialize();
27 void Initialize(CancellationToken ct);
26 28 }
27 29 }
28 30
@@ -19,6 +19,7 namespace Implab.Components {
19 19 /// This operation is cancellable and it's expected to move to
20 20 /// the failed state or just ignore the cancellation request,
21 21 /// </remarks>
22 void Start();
22 23 void Start(CancellationToken ct);
23 24
24 25 /// <summary>
@@ -31,6 +32,7 namespace Implab.Components {
31 32 /// will be requested to cancel. The stop operatin will be
32 33 /// performed only if the component in the running state.
33 34 /// </remarks>
35 void Stop();
34 36 void Stop(CancellationToken ct);
35 37
36 38 /// <summary>
@@ -49,6 +49,7 namespace Implab.Components {
49 49 m_cancellation.Cancel();
50 50 try {
51 51 // await for pending poll
52 if (m_poll != null)
52 53 await m_poll;
53 54 } catch (OperationCanceledException) {
54 55 // OK
@@ -171,9 +171,13 namespace Implab.Components {
171 171 }
172 172
173 173 public void Initialize() {
174 Initialize(CancellationToken.None);
175 }
176
177 public void Initialize(CancellationToken ct) {
174 178 var cookie = new object();
175 179 if (MoveInitialize(cookie))
176 Safe.NoWait(ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie));
180 Safe.NoWait(ScheduleTask(InitializeInternalAsync, ct, cookie));
177 181 else
178 182 throw new InvalidOperationException();
179 183 }
@@ -191,6 +195,10 namespace Implab.Components {
191 195 return Task.CompletedTask;
192 196 }
193 197
198 public void Start() {
199 Start(CancellationToken.None);
200 }
201
194 202 public void Start(CancellationToken ct) {
195 203 var cookie = new object();
196 204 if (MoveStart(cookie))
@@ -220,6 +228,10 namespace Implab.Components {
220 228
221 229 }
222 230
231 public void Stop() {
232 Stop(CancellationToken.None);
233 }
234
223 235 public void Stop(CancellationToken ct) {
224 236 var cookie = new object();
225 237 if (MoveStop(cookie))
@@ -230,7 +242,12 namespace Implab.Components {
230 242
231 243 async Task StopAsync(CancellationToken ct) {
232 244 m_current.Cancel();
245
246 try {
233 247 await Completion;
248 } catch(OperationCanceledException) {
249 // OK
250 }
234 251
235 252 ct.ThrowIfCancellationRequested();
236 253
@@ -302,12 +319,13 namespace Implab.Components {
302 319 }
303 320 }
304 321
305 void MoveFailed(Exception err, object cookie) {
322 bool MoveFailed(Exception err, object cookie) {
306 323 lock (m_lock) {
307 324 if (m_cookie != cookie)
308 return;
325 return false;
309 326 LastError = err;
310 327 State = ExecutionState.Failed;
328 return true;
311 329 }
312 330 }
313 331
@@ -8,8 +8,8
8 8 and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc.
9 9 </Description>
10 10 <Copyright>2012-2018 Sergey Smirnov</Copyright>
11 <Version>3.0.6</Version>
12 <PackageLicenseUrl>https://opensource.org/licenses/BSD-2-Clause</PackageLicenseUrl>
11 <Version>3.0.8</Version>
12 <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl>
13 13 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
14 14 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
15 15 <RepositoryType>mercurial</RepositoryType>
1 NO CONTENT: file was removed
1 NO CONTENT: file was removed
General Comments 3
Under Review
author

Auto status change to "Under Review"

Approved
author

ok, latest stable version should be in default

You need to be logged in to leave comments. Login now