##// 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 using System;
2 using System;
3 using Implab.Automaton;
3 using Implab.Automaton;
4 using Implab.Xml;
4 using Implab.Xml;
@@ -7,11 +7,10 using Implab.Formats;
7 using Implab.Formats.Json;
7 using Implab.Formats.Json;
8 using System.IO;
8 using System.IO;
9
9
10 namespace Implab.Format.Test {
10 namespace Implab.Test {
11 [TestFixture]
12 public class JsonTests {
11 public class JsonTests {
13
12
14 [Test]
13 [Fact]
15 public void TestScannerValidTokens() {
14 public void TestScannerValidTokens() {
16 using (var scanner = JsonStringScanner.Create(@"9123, -123, 0, 0.1, -0.2, -0.1e3, 1.3E-3, ""some \t\n\u0020 text"", literal []{}:")) {
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 JsonTokenType tokenType;
43 JsonTokenType tokenType;
45 for (var i = 0; i < expexted.Length; i++) {
44 for (var i = 0; i < expexted.Length; i++) {
46
45
47 Assert.IsTrue(scanner.ReadToken(out value, out tokenType));
46 Assert.True(scanner.ReadToken(out value, out tokenType));
48 Assert.AreEqual(expexted[i].Item1, tokenType);
47 Assert.Equal(expexted[i].Item1, tokenType);
49 Assert.AreEqual(expexted[i].Item2, value);
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 public void TestScannerBadTokens() {
56 public void TestScannerBadTokens() {
58 var bad = new[] {
57 var bad = new[] {
59 " 1",
58 " 1",
@@ -81,7 +80,7 namespace Implab.Format.Test {
81 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value);
80 Console.WriteLine("'{0}' is read as {1}", json, value is String ? String.Format("'{0}'", value) : value);
82 continue;
81 continue;
83 }
82 }
84 Assert.Fail("Token '{0}' shouldn't pass", json);
83 Assert.True(false, $"Token '{json}' shouldn't pass");
85 } catch (ParserException e) {
84 } catch (ParserException e) {
86 Console.WriteLine(e.Message);
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 public void JsonXmlReaderSimpleTest() {
92 public void JsonXmlReaderSimpleTest() {
94 var json = "\"some text\"";
93 var json = "\"some text\"";
95 //Console.WriteLine($"JSON: {json}");
94 //Console.WriteLine($"JSON: {json}");
@@ -104,56 +103,35 namespace Implab.Format.Test {
104 Assert.IsFalse(xmlReader.Read());
103 Assert.IsFalse(xmlReader.Read());
105 }*/
104 }*/
106
105
107 //DumpJsonParse("\"text value\"");
106 DumpJsonParse("\"text value\"");
108 //DumpJsonParse("null");
107 DumpJsonParse("null");
109 //DumpJsonParse("true");
108 DumpJsonParse("true");
110 //DumpJsonParse("{}");
109 DumpJsonParse("{}");
111 //DumpJsonParse("[]");
110 DumpJsonParse("[]");
112 DumpJsonParse("{\"one\":1, \"two\":2}");
111 DumpJsonParse("{\"one\":1, \"two\":2}");
113 DumpJsonParse("[1,\"\",2,3]");
112 DumpJsonParse("[1,\"\",2,3]");
114 DumpJsonParse("[{\"info\": [7,8,9]}]");
113 DumpJsonParse("[{\"info\": [7,8,9]}]");
115 DumpJsonFlatParse("[1,2,\"\",[3,4],{\"info\": [5,6]},{\"num\": [7,8,null]}, null,[null]]");
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 void AssertRead(XmlReader reader, XmlNodeType expected) {
117 void AssertRead(XmlReader reader, XmlNodeType expected) {
145 Assert.IsTrue(reader.Read());
118 Assert.True(reader.Read());
146 Console.WriteLine($"{new string(' ', reader.Depth * 2)}{reader}");
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 void DumpJsonParse(string json) {
123 void DumpJsonParse(string json) {
151 Console.WriteLine($"JSON: {json}");
124 Console.WriteLine($"JSON: {json}");
152 Console.WriteLine("XML");
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 using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "json" })) {
131 using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "json" })) {
154 while (xmlReader.Read())
132 xmlWriter.WriteNode(xmlReader, false);
155 Console.WriteLine($"{new string(' ', xmlReader.Depth * 2)}{xmlReader}");
156 }
133 }
134 Console.WriteLine();
157 }
135 }
158
136
159 void DumpJsonFlatParse(string json) {
137 void DumpJsonFlatParse(string json) {
@@ -167,6 +145,7 namespace Implab.Format.Test {
167 using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "", FlattenArrays = true })) {
145 using (var xmlReader = new JsonXmlReader(JsonReader.ParseString(json), new JsonXmlReaderOptions { NamespaceUri = "JsonXmlReaderSimpleTest", NodesPrefix = "", FlattenArrays = true })) {
168 xmlWriter.WriteNode(xmlReader, false);
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 protected async override Task StopInternalAsync(CancellationToken ct) {
23 protected async override Task StopInternalAsync(CancellationToken ct) {
24 await base.StopInternalAsync(ct);
24 if (StopWorker != null)
25 if (StopWorker != null)
25 await StopWorker.Invoke(ct);
26 await StopWorker.Invoke(ct);
26 }
27 }
27
28
28 protected async override Task StartInternalAsync(CancellationToken ct) {
29 protected async override Task StartInternalAsync(CancellationToken ct) {
30 await base.StartInternalAsync(ct);
29 if (StartWorker != null)
31 if (StartWorker != null)
30 await StartWorker.Invoke(ct);
32 await StartWorker.Invoke(ct);
31 }
33 }
@@ -8,7 +8,7 namespace Implab.Test {
8
8
9 public class RunnableComponentTests {
9 public class RunnableComponentTests {
10 [Fact]
10 [Fact]
11 public async Task Test1() {
11 public async Task SimpleStartStop() {
12
12
13 using (var m = new MockPollComponent(true)) {
13 using (var m = new MockPollComponent(true)) {
14 m.StartWorker = async (ct) => await Task.Yield();
14 m.StartWorker = async (ct) => await Task.Yield();
@@ -17,11 +17,245 namespace Implab.Test {
17 Assert.Equal(ExecutionState.Ready, m.State);
17 Assert.Equal(ExecutionState.Ready, m.State);
18 Assert.NotNull(m.Completion);
18 Assert.NotNull(m.Completion);
19
19
20 m.Start(CancellationToken.None);
20 m.Start();
21 await m.Completion;
21 await m.Completion;
22 Assert.Equal(ExecutionState.Running, m.State);
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 m.Stop(CancellationToken.None);
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 await m.Completion;
259 await m.Completion;
26 Assert.Equal(ExecutionState.Stopped, m.State);
260 Assert.Equal(ExecutionState.Stopped, m.State);
27 }
261 }
@@ -1,4 +1,5
1 using System;
1 using System;
2 using System.Threading;
2
3
3 namespace Implab.Components {
4 namespace Implab.Components {
4 /// <summary>
5 /// <summary>
@@ -23,6 +24,7 namespace Implab.Components {
23 /// </para>
24 /// </para>
24 /// </remarks>
25 /// </remarks>
25 void Initialize();
26 void Initialize();
27 void Initialize(CancellationToken ct);
26 }
28 }
27 }
29 }
28
30
@@ -19,6 +19,7 namespace Implab.Components {
19 /// This operation is cancellable and it's expected to move to
19 /// This operation is cancellable and it's expected to move to
20 /// the failed state or just ignore the cancellation request,
20 /// the failed state or just ignore the cancellation request,
21 /// </remarks>
21 /// </remarks>
22 void Start();
22 void Start(CancellationToken ct);
23 void Start(CancellationToken ct);
23
24
24 /// <summary>
25 /// <summary>
@@ -31,6 +32,7 namespace Implab.Components {
31 /// will be requested to cancel. The stop operatin will be
32 /// will be requested to cancel. The stop operatin will be
32 /// performed only if the component in the running state.
33 /// performed only if the component in the running state.
33 /// </remarks>
34 /// </remarks>
35 void Stop();
34 void Stop(CancellationToken ct);
36 void Stop(CancellationToken ct);
35
37
36 /// <summary>
38 /// <summary>
@@ -49,6 +49,7 namespace Implab.Components {
49 m_cancellation.Cancel();
49 m_cancellation.Cancel();
50 try {
50 try {
51 // await for pending poll
51 // await for pending poll
52 if (m_poll != null)
52 await m_poll;
53 await m_poll;
53 } catch (OperationCanceledException) {
54 } catch (OperationCanceledException) {
54 // OK
55 // OK
@@ -171,9 +171,13 namespace Implab.Components {
171 }
171 }
172
172
173 public void Initialize() {
173 public void Initialize() {
174 Initialize(CancellationToken.None);
175 }
176
177 public void Initialize(CancellationToken ct) {
174 var cookie = new object();
178 var cookie = new object();
175 if (MoveInitialize(cookie))
179 if (MoveInitialize(cookie))
176 Safe.NoWait(ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie));
180 Safe.NoWait(ScheduleTask(InitializeInternalAsync, ct, cookie));
177 else
181 else
178 throw new InvalidOperationException();
182 throw new InvalidOperationException();
179 }
183 }
@@ -191,6 +195,10 namespace Implab.Components {
191 return Task.CompletedTask;
195 return Task.CompletedTask;
192 }
196 }
193
197
198 public void Start() {
199 Start(CancellationToken.None);
200 }
201
194 public void Start(CancellationToken ct) {
202 public void Start(CancellationToken ct) {
195 var cookie = new object();
203 var cookie = new object();
196 if (MoveStart(cookie))
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 public void Stop(CancellationToken ct) {
235 public void Stop(CancellationToken ct) {
224 var cookie = new object();
236 var cookie = new object();
225 if (MoveStop(cookie))
237 if (MoveStop(cookie))
@@ -230,7 +242,12 namespace Implab.Components {
230
242
231 async Task StopAsync(CancellationToken ct) {
243 async Task StopAsync(CancellationToken ct) {
232 m_current.Cancel();
244 m_current.Cancel();
245
246 try {
233 await Completion;
247 await Completion;
248 } catch(OperationCanceledException) {
249 // OK
250 }
234
251
235 ct.ThrowIfCancellationRequested();
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 lock (m_lock) {
323 lock (m_lock) {
307 if (m_cookie != cookie)
324 if (m_cookie != cookie)
308 return;
325 return false;
309 LastError = err;
326 LastError = err;
310 State = ExecutionState.Failed;
327 State = ExecutionState.Failed;
328 return true;
311 }
329 }
312 }
330 }
313
331
@@ -8,8 +8,8
8 and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc.
8 and SharedLock, Trace helpers on top of System.Diagnostics, ObjectPool etc.
9 </Description>
9 </Description>
10 <Copyright>2012-2018 Sergey Smirnov</Copyright>
10 <Copyright>2012-2018 Sergey Smirnov</Copyright>
11 <Version>3.0.6</Version>
11 <Version>3.0.8</Version>
12 <PackageLicenseUrl>https://opensource.org/licenses/BSD-2-Clause</PackageLicenseUrl>
12 <PackageLicenseUrl>https://hg.implab.org/pub/ImplabNet/file/tip/Implab/license.txt</PackageLicenseUrl>
13 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
13 <PackageProjectUrl>https://implab.org</PackageProjectUrl>
14 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
14 <RepositoryUrl>https://hg.implab.org/pub/ImplabNet/</RepositoryUrl>
15 <RepositoryType>mercurial</RepositoryType>
15 <RepositoryType>mercurial</RepositoryType>
1 NO CONTENT: file was removed
NO CONTENT: file was removed
1 NO CONTENT: file was removed
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