[NUI] Rebase develnui (DevelNUI only patches --> master) (#3910)
[platform/core/csapi/tizenfx.git] / test / Tizen.NUI.Devel.Tests.Ubuntu / nunit.framework / Internal / TestExecutionContext.cs
1 // ***********************************************************************
2 // Copyright (c) 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.Generic;
31 using System.Globalization;
32 using System.Diagnostics;
33 using System.IO;
34 using System.Threading;
35 using NUnit.Framework.Constraints;
36 using NUnit.Framework.Interfaces;
37 using NUnit.Framework.Internal.Execution;
38
39 #if !SILVERLIGHT && !NETCF && !PORTABLE
40 using System.Runtime.Remoting.Messaging;
41 using System.Security.Principal;
42 using NUnit.Compatibility;
43 #endif
44
45 namespace NUnit.Framework.Internal
46 {
47     /// <summary>
48     /// Helper class used to save and restore certain static or
49     /// singleton settings in the environment that affect tests
50     /// or which might be changed by the user tests.
51     ///
52     /// An internal class is used to hold settings and a stack
53     /// of these objects is pushed and popped as Save and Restore
54     /// are called.
55     /// </summary>
56     public class TestExecutionContext
57 #if !SILVERLIGHT && !NETCF && !PORTABLE
58         : LongLivedMarshalByRefObject, ILogicalThreadAffinative
59 #endif
60     {
61         // NOTE: Be very careful when modifying this class. It uses
62         // conditional compilation extensively and you must give
63         // thought to whether any new features will be supported
64         // on each platform. In particular, instance fields,
65         // properties, initialization and restoration must all
66         // use the same conditions for each feature.
67
68         #region Instance Fields
69
70         /// <summary>
71         /// Link to a prior saved context
72         /// </summary>
73         private TestExecutionContext _priorContext;
74
75         /// <summary>
76         /// Indicates that a stop has been requested
77         /// </summary>
78         private TestExecutionStatus _executionStatus;
79
80         /// <summary>
81         /// The event listener currently receiving notifications
82         /// </summary>
83         private ITestListener _listener = TestListener.NULL;
84
85         /// <summary>
86         /// The number of assertions for the current test
87         /// </summary>
88         private int _assertCount;
89
90         private Randomizer _randomGenerator;
91
92         /// <summary>
93         /// The current culture
94         /// </summary>
95         private CultureInfo _currentCulture;
96
97         /// <summary>
98         /// The current UI culture
99         /// </summary>
100         private CultureInfo _currentUICulture;
101
102         /// <summary>
103         /// The current test result
104         /// </summary>
105         private TestResult _currentResult;
106
107 #if !NETCF && !SILVERLIGHT && !PORTABLE
108         /// <summary>
109         /// The current Principal.
110         /// </summary>
111         private IPrincipal _currentPrincipal;
112 #endif
113
114         #endregion
115
116         #region Constructors
117
118         /// <summary>
119         /// Initializes a new instance of the <see cref="TestExecutionContext"/> class.
120         /// </summary>
121         public TestExecutionContext()
122         {
123             _priorContext = null;
124             TestCaseTimeout = 0;
125             UpstreamActions = new List<ITestAction>();
126
127             _currentCulture = CultureInfo.CurrentCulture;
128             _currentUICulture = CultureInfo.CurrentUICulture;
129
130 #if !NETCF && !SILVERLIGHT && !PORTABLE
131             _currentPrincipal = Thread.CurrentPrincipal;
132 #endif
133
134             CurrentValueFormatter = (val) => MsgUtils.DefaultValueFormatter(val);
135             IsSingleThreaded = false;
136         }
137
138         /// <summary>
139         /// Initializes a new instance of the <see cref="TestExecutionContext"/> class.
140         /// </summary>
141         /// <param name="other">An existing instance of TestExecutionContext.</param>
142         public TestExecutionContext(TestExecutionContext other)
143         {
144             _priorContext = other;
145
146             CurrentTest = other.CurrentTest;
147             CurrentResult = other.CurrentResult;
148             TestObject = other.TestObject;
149             WorkDirectory = other.WorkDirectory;
150             _listener = other._listener;
151             StopOnError = other.StopOnError;
152             TestCaseTimeout = other.TestCaseTimeout;
153             UpstreamActions = new List<ITestAction>(other.UpstreamActions);
154
155             _currentCulture = other.CurrentCulture;
156             _currentUICulture = other.CurrentUICulture;
157
158 #if !NETCF && !SILVERLIGHT && !PORTABLE
159             _currentPrincipal = other.CurrentPrincipal;
160 #endif
161
162             CurrentValueFormatter = other.CurrentValueFormatter;
163
164             Dispatcher = other.Dispatcher;
165             ParallelScope = other.ParallelScope;
166             IsSingleThreaded = other.IsSingleThreaded;
167         }
168
169         #endregion
170
171         #region Static Singleton Instance
172
173         // NOTE: We use different implementations for various platforms
174
175         // If a user creates a thread then the current context
176         // will be null. This also happens when the compiler
177         // automatically creates threads for async methods.
178         // We create a new context, which is automatically
179         // populated with values taken from the current thread.
180
181 #if SILVERLIGHT || PORTABLE
182         // In the Silverlight and portable builds, we use a ThreadStatic
183         // field to hold the current TestExecutionContext.
184
185         [ThreadStatic]
186         private static TestExecutionContext _currentContext;
187
188         /// <summary>
189         /// Gets and sets the current context.
190         /// </summary>
191         public static TestExecutionContext CurrentContext
192         {
193             get
194             {
195                if (_currentContext == null)
196                     _currentContext = new TestExecutionContext();
197
198                 return _currentContext;
199             }
200             private set
201             {
202                 _currentContext = value;
203             }
204         }
205 #elif NETCF
206         // In the compact framework build, we use a LocalStoreDataSlot
207
208         private static LocalDataStoreSlot contextSlot = Thread.AllocateDataSlot();
209         
210         /// <summary>
211         /// Gets and sets the current context.
212         /// </summary>
213         public static TestExecutionContext CurrentContext
214         {
215             get
216             {
217                 var current = GetTestExecutionContext();
218                 if (current == null)
219                 {
220                     current = new TestExecutionContext();
221                     Thread.SetData(contextSlot, current);
222                 }
223
224                 return current;
225             }
226             private set
227             {
228                 Thread.SetData(contextSlot, value);
229             }
230         }
231
232         /// <summary>
233         /// Get the current context or return null if none is found.
234         /// </summary>
235         public static TestExecutionContext GetTestExecutionContext()
236         {
237             return (TestExecutionContext)Thread.GetData(contextSlot);
238         }
239 #else
240         // In all other builds, we use the CallContext
241
242         private static readonly string CONTEXT_KEY = "NUnit.Framework.TestContext";
243
244         /// <summary>
245         /// Gets and sets the current context.
246         /// </summary>
247         public static TestExecutionContext CurrentContext
248         {
249             get
250             {
251                 var context = GetTestExecutionContext();
252                 if (context == null) // This can happen on Mono
253                 {
254                     context = new TestExecutionContext();
255                     CallContext.SetData(CONTEXT_KEY, context);
256                 }
257
258                 return context;
259             }
260             private set
261             {
262                 if (value == null)
263                     CallContext.FreeNamedDataSlot(CONTEXT_KEY);
264                 else
265                     CallContext.SetData(CONTEXT_KEY, value);
266             }
267         }
268
269         /// <summary>
270         /// Get the current context or return null if none is found.
271         /// </summary>
272         public static TestExecutionContext GetTestExecutionContext()
273         {
274             return CallContext.GetData(CONTEXT_KEY) as TestExecutionContext;
275         }
276 #endif
277
278         /// <summary>
279         /// Clear the current context. This is provided to
280         /// prevent "leakage" of the CallContext containing
281         /// the current context back to any runners.
282         /// </summary>
283         public static void ClearCurrentContext()
284         {
285             CurrentContext = null;
286         }
287
288         #endregion
289
290         #region Properties
291
292         /// <summary>
293         /// Gets or sets the current test
294         /// </summary>
295         public Test CurrentTest { get; set; }
296
297         /// <summary>
298         /// The time the current test started execution
299         /// </summary>
300         public DateTime StartTime { get; set; }
301
302         /// <summary>
303         /// The time the current test started in Ticks
304         /// </summary>
305         public long StartTicks { get; set; }
306
307         /// <summary>
308         /// Gets or sets the current test result
309         /// </summary>
310         public TestResult CurrentResult
311         {
312             get { return _currentResult; }
313             set
314             {
315                 _currentResult = value;
316                 if (value != null)
317                     OutWriter = value.OutWriter;
318             }
319         }
320
321         /// <summary>
322         /// Gets a TextWriter that will send output to the current test result.
323         /// </summary>
324         public TextWriter OutWriter { get; private set; }
325
326         /// <summary>
327         /// The current test object - that is the user fixture
328         /// object on which tests are being executed.
329         /// </summary>
330         public object TestObject { get; set; }
331
332         /// <summary>
333         /// Get or set the working directory
334         /// </summary>
335         public string WorkDirectory { get; set; }
336
337         /// <summary>
338         /// Get or set indicator that run should stop on the first error
339         /// </summary>
340         public bool StopOnError { get; set; }
341
342         /// <summary>
343         /// Gets an enum indicating whether a stop has been requested.
344         /// </summary>
345         public TestExecutionStatus ExecutionStatus
346         {
347             get
348             {
349                 // ExecutionStatus may have been set to StopRequested or AbortRequested
350                 // in a prior context. If so, reflect the same setting in this context.
351                 if (_executionStatus == TestExecutionStatus.Running && _priorContext != null)
352                     _executionStatus = _priorContext.ExecutionStatus;
353
354                 return _executionStatus;
355             }
356             set
357             {
358                 _executionStatus = value;
359
360                 // Push the same setting up to all prior contexts
361                 if (_priorContext != null)
362                     _priorContext.ExecutionStatus = value;
363             }
364         }
365
366         /// <summary>
367         /// The current test event listener
368         /// </summary>
369         internal ITestListener Listener
370         {
371             get { return _listener; }
372             set { _listener = value; }
373         }
374
375         /// <summary>
376         /// The current WorkItemDispatcher. Made public for 
377         /// use by nunitlite.tests
378         /// </summary>
379         public IWorkItemDispatcher Dispatcher { get; set; }
380
381         /// <summary>
382         /// The ParallelScope to be used by tests running in this context.
383         /// For builds with out the parallel feature, it has no effect.
384         /// </summary>
385         public ParallelScope ParallelScope { get; set; }
386
387         /// <summary>
388         /// The unique name of the worker that spawned the context.
389         /// For builds with out the parallel feature, it is null.
390         /// </summary>
391         public string WorkerId {get; internal set;}
392
393         /// <summary>
394         /// Gets the RandomGenerator specific to this Test
395         /// </summary>
396         public Randomizer RandomGenerator
397         {
398             get
399             {
400                 if (_randomGenerator == null)
401                     _randomGenerator = new Randomizer(CurrentTest.Seed);
402                 return _randomGenerator;
403             }
404         }
405
406         /// <summary>
407         /// Gets the assert count.
408         /// </summary>
409         /// <value>The assert count.</value>
410         internal int AssertCount
411         {
412             get { return _assertCount; }
413         }
414
415         /// <summary>
416         /// Gets or sets the test case timeout value
417         /// </summary>
418         public int TestCaseTimeout { get; set; }
419
420         /// <summary>
421         /// Gets a list of ITestActions set by upstream tests
422         /// </summary>
423         public List<ITestAction> UpstreamActions { get; private set; }
424
425         // TODO: Put in checks on all of these settings
426         // with side effects so we only change them
427         // if the value is different
428
429         /// <summary>
430         /// Saves or restores the CurrentCulture
431         /// </summary>
432         public CultureInfo CurrentCulture
433         {
434             get { return _currentCulture; }
435             set
436             {
437                 _currentCulture = value;
438 #if !NETCF && !PORTABLE
439                 Thread.CurrentThread.CurrentCulture = _currentCulture;
440 #endif
441             }
442         }
443
444         /// <summary>
445         /// Saves or restores the CurrentUICulture
446         /// </summary>
447         public CultureInfo CurrentUICulture
448         {
449             get { return _currentUICulture; }
450             set
451             {
452                 _currentUICulture = value;
453 #if !NETCF && !PORTABLE
454                 Thread.CurrentThread.CurrentUICulture = _currentUICulture;
455 #endif
456             }
457         }
458
459 #if !NETCF && !SILVERLIGHT && !PORTABLE
460         /// <summary>
461         /// Gets or sets the current <see cref="IPrincipal"/> for the Thread.
462         /// </summary>
463         public IPrincipal CurrentPrincipal
464         {
465             get { return _currentPrincipal; }
466             set
467             {
468                 _currentPrincipal = value;
469                 Thread.CurrentPrincipal = _currentPrincipal;
470             }
471         }
472 #endif
473
474         /// <summary>
475         /// The current head of the ValueFormatter chain, copied from MsgUtils.ValueFormatter
476         /// </summary>
477         public ValueFormatter CurrentValueFormatter { get; private set; }
478
479         /// <summary>
480         /// If true, all tests must run on the same thread. No new thread may be spawned.
481         /// </summary>
482         public bool IsSingleThreaded { get; set; }
483
484         #endregion
485
486         #region Instance Methods
487
488         /// <summary>
489         /// Record any changes in the environment made by
490         /// the test code in the execution context so it
491         /// will be passed on to lower level tests.
492         /// </summary>
493         public void UpdateContextFromEnvironment()
494         {
495             _currentCulture = CultureInfo.CurrentCulture;
496             _currentUICulture = CultureInfo.CurrentUICulture;
497
498 #if !NETCF && !SILVERLIGHT && !PORTABLE
499             _currentPrincipal = Thread.CurrentPrincipal;
500 #endif
501         }
502
503         /// <summary>
504         /// Set up the execution environment to match a context.
505         /// Note that we may be running on the same thread where the
506         /// context was initially created or on a different thread.
507         /// </summary>
508         public void EstablishExecutionEnvironment()
509         {
510 #if !NETCF && !PORTABLE
511             Thread.CurrentThread.CurrentCulture = _currentCulture;
512             Thread.CurrentThread.CurrentUICulture = _currentUICulture;
513 #endif
514
515 #if !NETCF && !SILVERLIGHT && !PORTABLE
516             Thread.CurrentPrincipal = _currentPrincipal;
517 #endif
518
519             CurrentContext = this;
520         }
521
522         /// <summary>
523         /// Increments the assert count by one.
524         /// </summary>
525         public void IncrementAssertCount()
526         {
527             Interlocked.Increment(ref _assertCount);
528         }
529
530         /// <summary>
531         /// Increments the assert count by a specified amount.
532         /// </summary>
533         public void IncrementAssertCount(int count)
534         {
535             // TODO: Temporary implementation
536             while (count-- > 0)
537                 Interlocked.Increment(ref _assertCount);
538         }
539
540         /// <summary>
541         /// Adds a new ValueFormatterFactory to the chain of formatters
542         /// </summary>
543         /// <param name="formatterFactory">The new factory</param>
544         public void AddFormatter(ValueFormatterFactory formatterFactory)
545         {
546             CurrentValueFormatter = formatterFactory(CurrentValueFormatter);
547         }
548
549         #endregion
550
551         #region InitializeLifetimeService
552
553 #if !SILVERLIGHT && !NETCF && !PORTABLE
554         /// <summary>
555         /// Obtain lifetime service object
556         /// </summary>
557         /// <returns></returns>
558         public override object InitializeLifetimeService()
559         {
560             return null;
561         }
562 #endif
563
564         #endregion
565     }
566 }