OSDN Git Service

e27ef07351560ce199d613bb374cdf8fd81bea7c
[applistation/AppliStation.git] / test-na-get-lib / NaGetTaskSet2Test.cs
1 using System;
2 using System.Collections.Generic;
3 using System.Threading;
4 using NUnit.Framework;
5 using NaGet.SubCommands.SubTask;
6 using NaGet.Tasks;
7
8 using NaGet.SubCommands;
9
10 namespace test_na_get_lib
11 {
12         [TestFixture]
13         public class NaGetTaskSet2Test
14         {
15                 [Test]
16                 public void SubTasks()
17                 {
18                         IList<string> subTaskMsgs = new string[]{"0", "1", "2"};
19                         IList<NaGetSubTask> subTasks = new NaGetSubTask[] {
20                                 new FunctionalSubTask(null, null),
21                                 new FunctionalSubTask(null, null),
22                                 new FunctionalSubTask(null, null),
23                         };
24                         ATaskSetForTest task = new ATaskSetForTest(subTaskMsgs, subTasks);
25                         
26                         Assert.AreEqual(subTaskMsgs, task.TaskSetNames);
27                 }
28                 
29                 [Test]
30                 public void NotifyGoToNextSubTask()
31                 {
32                         ATaskSetForTest task = null;
33                         IList<NaGetSubTask> subTasks = null;
34                         
35                         IList<string> subTaskMsgs = new string[]{"0", "1", "2"};
36                         int blockCount = 0;
37                         Action<object>[] funcs = new Action<object>[] {
38                                 delegate (object arg) {
39                                         blockCount ++;
40                                         Assert.AreEqual(0, task.CurrentTaskSetIndex);
41                                         Assert.IsTrue(task.Running);
42                                         Assert.IsTrue(subTasks[0].Running);
43                                         Assert.IsFalse(subTasks[1].Running);
44                                 },
45                                 delegate (object arg) {
46                                         blockCount ++;
47                                         Assert.IsTrue(task.Running);
48                                         Assert.IsTrue(subTasks[0].Done);
49                                         Assert.IsTrue(subTasks[1].Running);
50                                         Assert.IsFalse(subTasks[2].Running);
51                                 },
52                                 delegate (object arg) {
53                                         blockCount ++;
54                                         Assert.IsTrue(task.Running);
55                                         Assert.IsTrue(subTasks[1].Done);
56                                         Assert.IsTrue(subTasks[2].Running);
57                                 }
58                         };
59                         subTasks = new NaGetSubTask[] {
60                                 new FunctionalSubTask(funcs[0], null),
61                                 new FunctionalSubTask(funcs[1], null),
62                                 new FunctionalSubTask(funcs[2], null),
63                         };
64                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
65                         blockCount = 0;
66                         task.Run();
67                         Assert.IsTrue(task.Done);
68                         Assert.IsTrue(subTasks[0].Done);
69                         Assert.IsTrue(subTasks[1].Done);
70                         Assert.IsTrue(subTasks[2].Done);
71                         Assert.AreEqual(3, blockCount);
72                 }
73                 
74                 [Test]
75                 public void NotifyGoToSubTask()
76                 {
77                         ATaskSetForTest task = null;
78                         IList<NaGetSubTask> subTasks = null;
79                         
80                         IList<string> subTaskMsgs = new string[]{"0", "1"};
81                         List<int> blockPass = new List<int>();
82                         Action<object>[] funcs = new Action<object>[] {
83                                 delegate (object arg) {
84                                         blockPass.Add(0);
85                                         Assert.AreEqual(0, task.CurrentTaskSetIndex);
86                                         Assert.IsTrue(task.Running);
87                                         Assert.IsTrue(subTasks[0].Running);
88                                         Assert.IsFalse(subTasks[1].Running);
89                                 },
90                                 delegate (object arg) {
91                                         blockPass.Add(1);
92                                         Assert.IsTrue(task.Running);
93                                         Assert.IsTrue(subTasks[0].Done);
94                                         Assert.IsTrue(subTasks[1].Running);
95                                         
96                                         if (blockPass.Count < 6) {
97                                                 throw new JumpTaskException(0);
98                                         }
99                                 }
100                         };
101                         subTasks = new NaGetSubTask[] {
102                                 new FunctionalSubTask(funcs[0], null),
103                                 new FunctionalSubTask(funcs[1], null),
104                         };
105                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
106                         blockPass.Clear();
107                         task.Run();
108                         Assert.IsTrue(task.Done);
109                         Assert.AreEqual(new int[]{0, 1, 0, 1, 0, 1}, blockPass.ToArray());
110                 }
111                 
112                 [Test]
113                 public void TaskEventRaised()
114                 {
115                         ATaskSetForTest task = null;
116                         IList<string> subTaskMsgs = new string[]{"0", "1"};
117                         IList<NaGetSubTask> subTasks = null;
118                         List<TaskEventArgs> taskEventList = new List<TaskEventArgs>();
119                         List<TaskEventArgs> subtaskEventList = new List<TaskEventArgs>();
120                         
121                         Action<ASubTaskForEventTest> subTaskBody = delegate(ASubTaskForEventTest subTask) {
122                                 subTask.RaiseTaskSetEventExt(TaskEventType.STARTED,     "S", -1);
123                                 subTask.RaiseTaskSetEventExt(TaskEventType.INFO,                "I", 0);
124                                 subTask.RaiseTaskSetEventExt(TaskEventType.PING,                "P", 50);
125                                 subTask.RaiseTaskSetEventExt(TaskEventType.WARNING,     "W", 75);
126                                 subTask.RaiseTaskSetEventExt(TaskEventType.COMPLETED,"C", 100);
127                         };
128                         subTasks = new NaGetSubTask[] {
129                                 new ASubTaskForEventTest(subTaskBody),
130                                 new ASubTaskForEventTest(subTaskBody),
131                         };
132                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
133                         
134                         EventHandler<TaskEventArgs> taskEventHandler = delegate(object sender, TaskEventArgs e) {
135                                 Assert.AreEqual(task, sender);
136                                 taskEventList.Add(e);
137                         };
138                         EventHandler<TaskEventArgs> subtaskEventHandler = delegate(object sender, TaskEventArgs e) {
139                                 Assert.AreEqual(subTasks[task.CurrentTaskSetIndex], sender);
140                                 subtaskEventList.Add(e);
141                         };
142                         
143                         // イベントをフックしているときの動作確認
144                         
145                         task.TaskEventRaised += taskEventHandler;
146                         task.SubTaskEventRaised += subtaskEventHandler;
147                         
148                         taskEventList.Clear();
149                         subtaskEventList.Clear();
150                         task.Run();
151                         Assert.IsTrue(task.Done);
152                         
153                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.STARTED,                   "", 0),                 taskEventList[0]);
154                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.STARTED_SUBTASK,   "0", 0),                taskEventList[1]);
155                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 0),               taskEventList[2]);
156                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 25),              taskEventList[3]);
157                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 37.5f),   taskEventList[4]);
158                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 50),              taskEventList[5]);
159                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.COMPLETED_SUBTASK,"0", 50),                taskEventList[6]);
160                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.STARTED_SUBTASK,   "1", 50),               taskEventList[7]);
161                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 50),              taskEventList[8]);
162                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 75),              taskEventList[9]);
163                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 87.5f),   taskEventList[10]);
164                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,                              null, 100),     taskEventList[11]);
165                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.COMPLETED_SUBTASK,"1", 100),               taskEventList[12]);
166                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.COMPLETED,         "", 100),               taskEventList[13]);
167                         Assert.AreEqual(14, taskEventList.Count);
168                         
169                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.STARTED,   "S", -1),       subtaskEventList[0]);
170                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.INFO,              "I", 0),        subtaskEventList[1]);
171                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,              "P", 50),       subtaskEventList[2]);
172                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.WARNING,   "W", 75),       subtaskEventList[3]);
173                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.COMPLETED,"C", 100),       subtaskEventList[4]);
174                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.STARTED,   "S", -1),       subtaskEventList[5]);
175                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.INFO,              "I", 0),        subtaskEventList[6]);
176                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.PING,              "P", 50),       subtaskEventList[7]);
177                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.WARNING,   "W", 75),       subtaskEventList[8]);
178                         AreSameTaskEventArgs(new TaskEventArgs(TaskEventType.COMPLETED,"C", 100),       subtaskEventList[9]);
179                         Assert.AreEqual(10, subtaskEventList.Count);
180                         
181                         // イベントをフックしていないときの動作確認
182                         
183                         task.TaskEventRaised -= taskEventHandler;
184                         task.SubTaskEventRaised -= subtaskEventHandler;
185                         
186                         taskEventList.Clear();
187                         subtaskEventList.Clear();
188                         task.Run();
189                         Assert.IsTrue(task.Done);
190                 }
191                 
192                 [Test]
193                 public void Cancel()
194                 {
195                         ATaskSetForTest task = null;
196                         IList<string> subTaskMsgs = new string[]{"0"};
197                         IList<NaGetSubTask> subTasks = null;
198                         
199                         Action<ASubTaskForEventTest> subTaskBody = delegate(ASubTaskForEventTest subTask) {
200                                 subTask.RaiseTaskSetEventExt(TaskEventType.STARTED,     "S", 0);
201                                 Thread.Sleep(50);
202                                 subTask.RaiseTaskSetEventExt(TaskEventType.COMPLETED,"C", 100);
203                         };
204                         bool? cancelRetVal = null;
205                         ParameterizedThreadStart cancelThread = new ParameterizedThreadStart(
206                                 delegate (object param) {
207                                         Thread.Sleep((int) param);
208                                         cancelRetVal = task.Cancel();
209                                 }
210                         );
211                         
212                         // キャンセル無効なときはキャンセル処理は行われない。
213                         
214                         subTasks = new NaGetSubTask[] { new ASubTaskForEventTest(subTaskBody) };
215                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
216                         task._Cancelable = false;
217                         cancelRetVal = null;
218                         (new Thread(cancelThread)).Start((object) 10);
219                         task.Run();
220                         Assert.AreEqual(false, cancelRetVal);
221                         Assert.IsTrue(task.Done);
222                         Assert.IsFalse(task.Cancelable);
223                         
224                         // すでに終了しているものにはキャンセルはできない
225                         Assert.IsFalse(task.Cancel());
226                         
227                         // キャンセル有効なときでキャンセルするとき
228                         subTasks = new NaGetSubTask[] { new ASubTaskForEventTest(subTaskBody) };
229                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
230                         task._Cancelable = true;
231                         cancelRetVal = null;
232                         (new Thread(cancelThread)).Start((object) 10);
233                         task.Run();
234                         Assert.AreEqual(true, cancelRetVal);
235                         Assert.IsTrue(task.Cancelled);
236                         Assert.IsFalse(task.Cancelable);
237                         
238                         // すでにキャンセルしているものにはキャンセルはできない
239                         Assert.IsFalse(task.Cancel());
240                         
241                         // キャンセルトリガの挙動確認
242                         bool cancelBlockPassed = false;
243                         subTasks = new NaGetSubTask[] { new ASubTaskForEventTest(subTaskBody) };
244                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
245                         task._Cancelable = true;
246                         task.OnCancelCalled += delegate(object arg) {
247                                 Assert.IsFalse(task.Cancelled);
248                                 Assert.IsTrue(task.Running);
249                                 Assert.IsFalse(task.Cancelable);
250                                 Assert.IsFalse(task.Cancel());
251                                 
252                                 ASubTaskForEventTest subTask = ((ASubTaskForEventTest) subTasks[0]);
253                                 Assert.IsFalse(subTask.Cancelled);
254                                 Assert.IsTrue(subTask.Running);
255                                 Assert.IsFalse(subTask.Cancelable);
256                                 Assert.IsFalse(subTask.Cancel());
257                                 
258                                 cancelBlockPassed = true;
259                         };
260                         ((ASubTaskForEventTest) subTasks[0])._Cancelable = true;
261                         cancelRetVal = null;
262                         (new Thread(cancelThread)).Start((object) 10);
263                         task.Run();
264                         Assert.AreEqual(true, cancelRetVal);
265                         Assert.IsTrue(task.Cancelled);
266                         Assert.IsFalse(task.Cancelable);
267                         Assert.IsTrue(((ASubTaskForEventTest) subTasks[0]).Cancelled);
268                         Assert.IsFalse(((ASubTaskForEventTest) subTasks[0]).Cancelable);
269                         Assert.IsTrue(cancelBlockPassed);
270                 }
271                 
272                 [Test]
273                 public void RaiseTaskSetQueryEvent()
274                 {
275                         IList<string> subTaskMsgs = new string[]{"0"};
276                         ATaskSetForTest task = null;
277                         Action<object> subTaskBody = null;
278                         IList<NaGetSubTask> subTasks = null;
279                         bool blockPassed = false;
280                         
281                         subTaskBody = delegate (object arg) {
282                                 NaGetTaskQueryResult ret;
283                                 ret = task.RaiseTaskSetQueryEventExt("#1", NaGetTaskQueryResult.CONTINUE);
284                                 Assert.AreEqual(NaGetTaskQueryResult.CANCELED_AUTOMATICALLY, ret);
285                                 
286                                 blockPassed = true;
287                         };
288                         subTasks = new NaGetSubTask[] {
289                                 new FunctionalSubTask(subTaskBody, null),
290                         };
291                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
292                         task.Run();
293                         Assert.IsTrue(task.Done);
294                         Assert.IsTrue(blockPassed);
295                         
296                         
297                         subTaskBody = delegate (object arg) {
298                                 NaGetTaskQueryResult ret;
299                                 ret = task.RaiseTaskSetQueryEventExt("#1", NaGetTaskQueryResult.CONTINUE);
300                                 Assert.AreEqual(NaGetTaskQueryResult.CONTINUE, ret);
301                                 ret = task.RaiseTaskSetQueryEventExt("#2", (NaGetTaskQueryResult.RETRY | NaGetTaskQueryResult.CANCEL));
302                                 Assert.AreEqual(NaGetTaskQueryResult.RETRY, ret);
303                                 
304                                 blockPassed = true;
305                         };
306                         subTasks = new NaGetSubTask[] {
307                                 new FunctionalSubTask(subTaskBody, null),
308                         };
309                         task = new ATaskSetForTest(subTaskMsgs, subTasks);
310                         task.TaskQueryRaised += delegate (object sender, NaGetTaskQueryArgs e) {
311                                 if (e.Message == "#1") {
312                                         Assert.AreEqual(NaGetTaskQueryResult.CONTINUE, e.SelectionFlag);
313                                         return NaGetTaskQueryResult.CONTINUE;
314                                 } else {
315                                         Assert.AreEqual((NaGetTaskQueryResult.RETRY | NaGetTaskQueryResult.CANCEL), e.SelectionFlag);
316                                         return NaGetTaskQueryResult.RETRY;
317                                 }
318                         };
319                         task.Run();
320                         Assert.IsTrue(task.Done);
321                         Assert.IsTrue(blockPassed);
322                 }
323                 
324                 private void AreSameTaskEventArgs(TaskEventArgs expected, TaskEventArgs actual)
325                 {
326                         string expectedLabel= string.Format("[type={0}, message=\"{1}\", percent={2}%]", expected.Type, expected.TaskMessage, expected.ProgressPercent);
327                         string actualLabel      = string.Format("[type={0}, message=\"{1}\", percent={2}%]", actual.Type, actual.TaskMessage, actual.ProgressPercent);
328                         string failtureMsg = string.Format("Expected: {0}\tBut was: {1}", expectedLabel, actualLabel);
329                         
330                         Assert.AreEqual(expected.Type, actual.Type, failtureMsg);
331                         Assert.AreEqual(expected.TaskMessage, actual.TaskMessage, failtureMsg);
332                         Assert.AreEqual(expected.ProgressPercent, actual.ProgressPercent, failtureMsg);
333                 }
334                 
335                 #region テスト用派生クラス
336                 
337                 private class JumpTaskException : Exception
338                 {
339                         public int subTaskId = -1;
340                         
341                         /// <summary>
342                         /// コンストラクタ
343                         /// </summary>
344                         /// <param name="id">ジャンプ先のサブタスクID</param>
345                         public JumpTaskException(int id)
346                         {
347                                 subTaskId = id;
348                         }
349                 }
350                 
351                 private class ATaskSetForTest : NaGetTaskSet2
352                 {
353                         public event Action<object> OnCancelCalled;
354                         
355                         public ATaskSetForTest(IList<string> subTaskMsgs, IList<NaGetSubTask> subTasks)
356                         {
357                                 initSubTask();
358                                 Assert.IsTrue(subTaskMsgs.Count == subTasks.Count);
359                                 
360                                 for (int i = 0; i < subTaskMsgs.Count; i++) {
361                                         registSubTask(subTaskMsgs[i], subTasks[i]);
362                                 }
363                                 
364                                 this.onCancelCalled += new Action<object>(delegate (object arg) {
365                                                                                 if (OnCancelCalled != null) {
366                                                                                                                                 OnCancelCalled(arg);
367                                                                                                                         }
368                                                                           });
369                         }
370                         
371                         public override void Run()
372                         {
373                                 NotifyStarted();
374                                 RaiseTaskSetEvent(TaskEventType.STARTED, string.Empty);
375                                 try {
376                                         while (hasMoreSubTask) {
377                                                 try {
378                                                         RaiseTaskSetEvent(TaskEventType.STARTED_SUBTASK, currentSubTaskName);
379                                                         currentSubTask.Run();
380                                                         RaiseTaskSetEvent(TaskEventType.COMPLETED_SUBTASK, currentSubTaskName);
381                                                         
382                                                         NotifyGoToNextSubTask();
383                                                 } catch (JumpTaskException ex) {
384                                                         NotifyGoToSubTask(ex.subTaskId);
385                                                 }
386                                         }
387                                 } finally {
388                                         if (cancelCalled) {
389                                                 NotifyCancelled();
390                                                 RaiseTaskSetEvent(TaskEventType.CANCELED, string.Empty);
391                                         } else {
392                                                 NotifyCompleted();
393                                                 RaiseTaskSetEvent(TaskEventType.COMPLETED, string.Empty);
394                                         }
395                                 }
396                         }
397                         
398                         private bool cancelable = false;
399                         
400                         public override bool Cancelable {
401                                 get { return cancelable && !cancelCalled && !isCancelled; }
402                         }
403                         
404                         public virtual bool _Cancelable {
405                                 set { cancelable = value; }
406                         }
407                         
408                         public NaGetTaskQueryResult RaiseTaskSetQueryEventExt(string message, NaGetTaskQueryResult selection)
409                         {
410                                 return RaiseTaskSetQueryEvent(message, selection);
411                         }
412                 }
413                 
414                 private class ASubTaskForEventTest : NaGetSubTask
415                 {
416                         private Action<ASubTaskForEventTest> func = null;
417                         
418                         public ASubTaskForEventTest(Action<ASubTaskForEventTest> func)
419                         {
420                                 this.func = func;
421                         }
422                         
423                         public void RaiseTaskSetEventExt(TaskEventType type, string message, float percent)
424                         {
425                                 RaiseTaskSetEvent(type, message, percent);
426                         }
427                         
428                         public override void Run()
429                         {
430                                 NotifyStarted();
431                                 try {
432                                         this.func(this);
433                                 } finally {
434                                         if (cancelCalled) {
435                                                 NotifyCancelled();
436                                         } else {
437                                                 NotifyCompleted();
438                                         }
439                                 }
440                         }
441                         
442                         private bool cancelable = false;
443                         
444                         public override bool Cancelable {
445                                 get { return cancelable && !cancelCalled && !Cancelled; }
446                         }
447                         
448                         public virtual bool _Cancelable {
449                                 set { cancelable = value; }
450                         }
451                         
452                         private bool cancelCalled = true;
453                         
454                         public override bool Cancel()
455                         {
456                                 if (Cancelable) {
457                                         cancelCalled = true;
458                                         return true;
459                                 } else {
460                                         return base.Cancel();
461                                 }
462                         }
463                 }
464                 
465                 #endregion
466                 
467         }
468 }