[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Api / NUnitTestAssemblyRunner.cs
1 // ***********************************************************************
2 // Copyright (c) 2012-2014 Charlie Poole
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
11 //
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
14 //
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 // ***********************************************************************
23 #define PORTABLE
24 #define TIZEN
25 #define NUNIT_FRAMEWORK
26 #define NUNITLITE
27 #define NET_4_5
28 #define PARALLEL
29 using System;
30 using System.Collections;
31 using System.IO;
32 using System.Reflection;
33 using System.Threading;
34 using NUnit.Common;
35 using NUnit.Framework.Interfaces;
36 using NUnit.Framework.Internal;
37 using NUnit.Framework.TUnit;
38 using NUnit.Framework.Internal.Execution;
39 using System.Collections.Generic;
40
41 #if !SILVERLIGHT && !NETCF && !PORTABLE
42 using System.Diagnostics;
43 //using System.Windows.Forms;
44 #endif
45
46 namespace NUnit.Framework.Api
47 {
48     /// <summary>
49     /// Implementation of ITestAssemblyRunner
50     /// </summary>
51     public class NUnitTestAssemblyRunner : ITestAssemblyRunner
52     {
53         private static Logger log = InternalTrace.GetLogger("DefaultTestAssemblyRunner");
54
55         private ITestAssemblyBuilder _builder;
56         private ManualResetEvent _runComplete = new ManualResetEvent(false);
57
58         private ITestListener _listener;
59 #if TIZEN
60         private Dictionary<string, ITest> TestcaseIDDic;
61 #endif
62
63 #if !SILVERLIGHT && !NETCF && !PORTABLE
64         // Saved Console.Out and Console.Error
65         private TextWriter _savedOut;
66         private TextWriter _savedErr;
67 #endif
68
69 #if PARALLEL
70         // Event Pump
71         private EventPump _pump;
72 #endif
73
74         #region Constructors
75
76         /// <summary>
77         /// Initializes a new instance of the <see cref="NUnitTestAssemblyRunner"/> class.
78         /// </summary>
79         /// <param name="builder">The builder.</param>
80         public NUnitTestAssemblyRunner(ITestAssemblyBuilder builder)
81         {
82             _builder = builder;
83 #if TIZEN
84             TestcaseIDDic = new Dictionary<string, ITest>();
85 #endif
86         }
87
88         #endregion
89
90         #region Properties
91
92 #if PARALLEL
93         /// <summary>
94         /// Gets the default level of parallel execution (worker threads)
95         /// </summary>
96         public static int DefaultLevelOfParallelism
97         {
98 #if NETCF
99             get { return 2; }
100 #else
101             get { return Math.Max(Environment.ProcessorCount, 2); }
102 #endif
103         }
104 #endif
105
106         /// <summary>
107         /// The tree of tests that was loaded by the builder
108         /// </summary>
109         public ITest LoadedTest { get; private set; }
110
111         /// <summary>
112         /// The test result, if a run has completed
113         /// </summary>
114         public ITestResult Result
115         {
116             get { return TopLevelWorkItem == null ? null : TopLevelWorkItem.Result; }
117         }
118
119         /// <summary>
120         /// Indicates whether a test is loaded
121         /// </summary>
122         public bool IsTestLoaded
123         {
124             get { return LoadedTest != null; }
125         }
126
127         /// <summary>
128         /// Indicates whether a test is running
129         /// </summary>
130         public bool IsTestRunning
131         {
132             get { return TopLevelWorkItem != null && TopLevelWorkItem.State == WorkItemState.Running; }
133         }
134
135         /// <summary>
136         /// Indicates whether a test run is complete
137         /// </summary>
138         public bool IsTestComplete
139         {
140             get { return TopLevelWorkItem != null && TopLevelWorkItem.State == WorkItemState.Complete; }
141         }
142
143         /// <summary>
144         /// Our settings, specified when loading the assembly
145         /// </summary>
146         private IDictionary<string, object> Settings { get; set; }
147
148         /// <summary>
149         /// The top level WorkItem created for the assembly as a whole
150         /// </summary>
151         private WorkItem TopLevelWorkItem { get; set; }
152
153         /// <summary>
154         /// The TestExecutionContext for the top level WorkItem
155         /// </summary>
156         private TestExecutionContext Context { get; set; }
157
158         #endregion
159
160         #region Public Methods
161
162         /// <summary>
163         /// Loads the tests found in an Assembly
164         /// </summary>
165         /// <param name="assemblyName">File name of the assembly to load</param>
166         /// <param name="settings">Dictionary of option settings for loading the assembly</param>
167         /// <returns>True if the load was successful</returns>
168         public ITest Load(string assemblyName, IDictionary<string, object> settings)
169         {
170             Settings = settings;
171
172             if (settings.ContainsKey(PackageSettings.RandomSeed))
173                 Randomizer.InitialSeed = (int)settings[PackageSettings.RandomSeed];
174
175             return LoadedTest = _builder.Build(assemblyName, settings);
176
177         }
178
179         /// <summary>
180         /// Loads the tests found in an Assembly
181         /// </summary>
182         /// <param name="assembly">The assembly to load</param>
183         /// <param name="settings">Dictionary of option settings for loading the assembly</param>
184         /// <returns>True if the load was successful</returns>
185         public ITest Load(Assembly assembly, IDictionary<string, object> settings)
186         {
187             Settings = settings;
188
189             if (settings.ContainsKey(PackageSettings.RandomSeed))
190                 Randomizer.InitialSeed = (int)settings[PackageSettings.RandomSeed];
191
192             LoadedTest = _builder.Build(assembly, settings);
193             MakeTestcaseIDDic(LoadedTest);
194             return LoadedTest;
195         }
196
197 #if TIZEN
198         ///// <summary>
199         /// Make Testcase ID Dictionary
200         public void MakeTestcaseIDDic(ITest testsuite)
201         {
202             foreach (ITest testmethod in testsuite.Tests)
203             {
204                 if (testmethod.IsSuite)
205                 {
206                     MakeTestcaseIDDic(testmethod);
207                 }
208                 else
209                 {
210                     TestcaseIDDic.Add(testmethod.FullName, testmethod);
211                 }
212             }
213         }
214
215         ///// <summary>
216         /// Get Testcase ID List
217         /// </summary>
218         /// <returns>Return Dictionary of TestcaseID</returns>
219         public Dictionary<string, ITest> GetTestcaseIDList()
220         {
221             return TestcaseIDDic;
222         }
223 #endif
224
225         /// <summary>
226         /// Count Test Cases using a filter
227         /// </summary>
228         /// <param name="filter">The filter to apply</param>
229         /// <returns>The number of test cases found</returns>
230         public int CountTestCases(ITestFilter filter)
231         {
232             if (LoadedTest == null)
233                 throw new InvalidOperationException("The CountTestCases method was called but no test has been loaded");
234
235             return CountTestCases(LoadedTest, filter);
236         }
237
238         /// <summary>
239         /// Run selected tests and return a test result. The test is run synchronously,
240         /// and the listener interface is notified as it progresses.
241         /// </summary>
242         /// <param name="listener">Interface to receive EventListener notifications.</param>
243         /// <param name="filter">A test filter used to select tests to be run</param>
244         /// <returns></returns>
245         public ITestResult Run(ITestListener listener, ITestFilter filter)
246         {
247             _listener = listener;
248             RunAsync(listener, filter);
249
250             return Result;
251         }
252
253         /// <summary>
254         /// Run selected tests asynchronously, notifying the listener interface as it progresses.
255         /// </summary>
256         /// <param name="listener">Interface to receive EventListener notifications.</param>
257         /// <param name="filter">A test filter used to select tests to be run</param>
258         /// <remarks>
259         /// RunAsync is a template method, calling various abstract and
260         /// virtual methods to be overridden by derived classes.
261         /// </remarks>
262         public void RunAsync(ITestListener listener, ITestFilter filter)
263         {
264             log.Info("Running tests");
265             if (LoadedTest == null)
266                 throw new InvalidOperationException("The Run method was called but no test has been loaded");
267
268             _runComplete.Reset();
269
270             CreateTestExecutionContext(listener);
271
272             TopLevelWorkItem = WorkItem.CreateWorkItem(LoadedTest, filter);
273             TopLevelWorkItem.InitializeContext(Context);
274             TopLevelWorkItem.Completed += OnRunCompleted;
275
276 #if TIZEN
277             TSettings tsetting = TSettings.GetInstance();
278             if (tsetting.IsSlaveMode && !tsetting.IsManual)
279             {
280                 tsetting.NextStepRequest();
281
282                 if (tsetting.Testcase_ID.Equals("0") || TSettings.IsLastTC == true)
283                 {
284                     return;
285                 }
286             }
287 #endif
288
289             StartRun(listener);
290             WaitForCompletion(Timeout.Infinite);
291         }
292
293         /// <summary>
294         /// Wait for the ongoing run to complete.
295         /// </summary>
296         /// <param name="timeout">Time to wait in milliseconds</param>
297         /// <returns>True if the run completed, otherwise false</returns>
298         public bool WaitForCompletion(int timeout)
299         {
300 #if !SILVERLIGHT && !PORTABLE
301             return _runComplete.WaitOne(timeout, false);
302 #else
303             return _runComplete.WaitOne(timeout);
304 #endif
305         }
306
307         /// <summary>
308         /// Signal any test run that is in process to stop. Return without error if no test is running.
309         /// </summary>
310         /// <param name="force">If true, kill any tests that are currently running</param>
311         public void StopRun(bool force)
312         {
313             if (IsTestRunning)
314             {
315                 Context.ExecutionStatus = force
316                     ? TestExecutionStatus.AbortRequested
317                     : TestExecutionStatus.StopRequested;
318
319                 Context.Dispatcher.CancelRun(force);
320             }
321         }
322
323         #endregion
324
325         #region Helper Methods
326
327         /// <summary>
328         /// Initiate the test run.
329         /// </summary>
330         private void StartRun(ITestListener listener)
331         {
332 #if !SILVERLIGHT && !NETCF && !PORTABLE
333             // Save Console.Out and Error for later restoration
334             _savedOut = Console.Out;
335             _savedErr = Console.Error;
336
337             Console.SetOut(new TextCapture(Console.Out));
338             Console.SetError(new EventListenerTextWriter("Error", Console.Error));
339 #endif
340
341 #if PARALLEL
342             // Queue and pump events, unless settings have SynchronousEvents == false
343             if (!Settings.ContainsKey(PackageSettings.SynchronousEvents) || !(bool)Settings[PackageSettings.SynchronousEvents])
344             {
345                 QueuingEventListener queue = new QueuingEventListener();
346                 Context.Listener = queue;
347
348                 _pump = new EventPump(listener, queue.Events);
349                 _pump.Start();
350             }
351 #endif
352
353 #if !NETCF
354             if (!System.Diagnostics.Debugger.IsAttached &&
355                 Settings.ContainsKey(PackageSettings.DebugTests) &&
356                 (bool)Settings[PackageSettings.DebugTests])
357                 System.Diagnostics.Debugger.Launch();
358
359 #if !SILVERLIGHT && !PORTABLE
360             if (Settings.ContainsKey(PackageSettings.PauseBeforeRun) &&
361                 (bool)Settings[PackageSettings.PauseBeforeRun])
362                 PauseBeforeRun();
363
364 #endif
365 #endif
366
367             Context.Dispatcher.Dispatch(TopLevelWorkItem);
368         }
369
370         /// <summary>
371         /// Create the initial TestExecutionContext used to run tests
372         /// </summary>
373         /// <param name="listener">The ITestListener specified in the RunAsync call</param>
374         private void CreateTestExecutionContext(ITestListener listener)
375         {
376             Context = new TestExecutionContext();
377
378             // Apply package settings to the context
379             if (Settings.ContainsKey(PackageSettings.DefaultTimeout))
380                 Context.TestCaseTimeout = (int)Settings[PackageSettings.DefaultTimeout];
381             if (Settings.ContainsKey(PackageSettings.StopOnError))
382                 Context.StopOnError = (bool)Settings[PackageSettings.StopOnError];
383
384             if (Settings.ContainsKey(PackageSettings.WorkDirectory))
385                 Context.WorkDirectory = (string)Settings[PackageSettings.WorkDirectory];
386             else
387                 Context.WorkDirectory = Env.DefaultWorkDirectory;
388
389             // Apply attributes to the context
390
391             // Set the listener - overriding runners may replace this
392             Context.Listener = listener;
393
394 #if PARALLEL
395             int levelOfParallelism = GetLevelOfParallelism();
396
397             if (levelOfParallelism > 0)
398                 Context.Dispatcher = new ParallelWorkItemDispatcher(levelOfParallelism);
399             else
400                 Context.Dispatcher = new SimpleWorkItemDispatcher();
401 #else
402             Context.Dispatcher = new SimpleWorkItemDispatcher();
403 #endif
404         }
405
406         /// <summary>
407         /// Handle the the Completed event for the top level work item
408         /// </summary>
409         private void OnRunCompleted(object sender, EventArgs e)
410         {
411 #if PARALLEL
412             if (_pump != null)
413                 _pump.Dispose();
414 #endif
415
416 #if !SILVERLIGHT && !NETCF && !PORTABLE
417             Console.SetOut(_savedOut);
418             Console.SetError(_savedErr);
419 #endif
420 #if TIZEN
421             #region tronghieu.d - testkit-stub
422             TSettings tsetting = TSettings.GetInstance();
423             if (tsetting.IsSlaveMode && !tsetting.IsManual)
424             {
425                 //tsetting.NextStepRequest();
426
427                 if (tsetting.Testcase_ID != "0" && TSettings.IsLastTC != true)
428                 {
429                     StartRun(_listener);
430                     return;
431                 }
432             }
433             #endregion
434 #endif
435
436             _runComplete.Set();
437         }
438
439         private int CountTestCases(ITest test, ITestFilter filter)
440         {
441             if (!test.IsSuite)
442                 return 1;
443
444             int count = 0;
445             foreach (ITest child in test.Tests)
446                 if (filter.Pass(child))
447                     count += CountTestCases(child, filter);
448
449             return count;
450         }
451
452 #if PARALLEL
453         private int GetLevelOfParallelism()
454         {
455             return Settings.ContainsKey(PackageSettings.NumberOfTestWorkers)
456                 ? (int)Settings[PackageSettings.NumberOfTestWorkers]
457                 : (LoadedTest.Properties.ContainsKey(PropertyNames.LevelOfParallelism)
458                    ? (int)LoadedTest.Properties.Get(PropertyNames.LevelOfParallelism)
459                    : NUnitTestAssemblyRunner.DefaultLevelOfParallelism);
460         }
461 #endif
462
463 #if !SILVERLIGHT && !NETCF && !PORTABLE
464         private static void PauseBeforeRun()
465         {
466             var process = Process.GetCurrentProcess();
467             string attachMessage = string.Format("Attach debugger to Process {0}.exe with Id {1} if desired.", process.ProcessName, process.Id);
468             //MessageBox.Show(attachMessage, process.ProcessName, MessageBoxButtons.OK, MessageBoxIcon.Information);
469         }
470 #endif
471
472         #endregion
473     }
474 }