2010-06-03 Jb Evain <jbevain@novell.com>
[mcs.git] / nunit24 / NUnitCore / core / SimpleTestRunner.cs
blob94d03754f739b3d2912a2524e41b118cdb30fd8f
1 // ****************************************************************
2 // Copyright 2007, Charlie Poole
3 // This is free software licensed under the NUnit license. You may
4 // obtain a copy of the license at http://nunit.org/?p=license&r=2.4
5 // ****************************************************************
6 using System;
7 using System.IO;
8 using System.Threading;
9 using System.Collections;
10 using System.Collections.Specialized;
11 using NUnit.Core.Filters;
12 using System.Reflection;
14 namespace NUnit.Core
16 /// <summary>
17 /// SimpleTestRunner is the simplest direct-running TestRunner. It
18 /// passes the event listener interface that is provided on to the tests
19 /// to use directly and does nothing to redirect text output. Both
20 /// Run and BeginRun are actually synchronous, although the client
21 /// can usually ignore this. BeginRun + EndRun operates as expected.
22 /// </summary>
23 public class SimpleTestRunner : MarshalByRefObject, TestRunner
25 #region Instance Variables
27 /// <summary>
28 /// Identifier for this runner. Must be unique among all
29 /// active runners in order to locate tests. Default
30 /// value of 0 is adequate in applications with a single
31 /// runner or a non-branching chain of runners.
32 /// </summary>
33 private int runnerID = 0;
35 /// <summary>
36 /// The loaded test suite
37 /// </summary>
38 private Test test;
40 /// <summary>
41 /// The builder we use to load tests, created for each load
42 /// </summary>
43 private TestSuiteBuilder builder;
45 /// <summary>
46 /// Results from the last test run
47 /// </summary>
48 private TestResult testResult;
50 /// <summary>
51 /// The thread on which Run was called. Set to the
52 /// current thread while a run is in process.
53 /// </summary>
54 private Thread runThread;
56 #endregion
58 #region Constructor
59 public SimpleTestRunner() : this( 0 ) { }
61 public SimpleTestRunner( int runnerID )
63 this.runnerID = runnerID;
65 #endregion
67 #region Properties
68 public virtual int ID
70 get { return runnerID; }
73 public IList AssemblyInfo
75 get { return builder.AssemblyInfo; }
78 public ITest Test
80 get { return test == null ? null : new TestNode( test ); }
83 /// <summary>
84 /// Results from the last test run
85 /// </summary>
86 public TestResult TestResult
88 get { return testResult; }
91 public virtual bool Running
93 get { return runThread != null && runThread.IsAlive; }
95 #endregion
97 #region Methods for Loading Tests
98 /// <summary>
99 /// Load a TestPackage
100 /// </summary>
101 /// <param name="package">The package to be loaded</param>
102 /// <returns>True on success, false on failure</returns>
103 public bool Load( TestPackage package )
105 this.builder = new TestSuiteBuilder();
107 this.test = builder.Build( package );
108 if ( test == null ) return false;
110 test.SetRunnerID( this.runnerID, true );
111 return true;
114 /// <summary>
115 /// Unload all tests previously loaded
116 /// </summary>
117 public void Unload()
119 this.test = null; // All for now
121 #endregion
123 #region CountTestCases
124 public int CountTestCases( ITestFilter filter )
126 return test.CountTestCases( filter );
128 #endregion
130 #region Methods for Running Tests
131 public virtual TestResult Run( EventListener listener )
133 return Run( listener, TestFilter.Empty );
136 public virtual TestResult Run( EventListener listener, ITestFilter filter )
140 // Take note of the fact that we are running
141 this.runThread = Thread.CurrentThread;
143 listener.RunStarted( this.Test.TestName.FullName, test.CountTestCases( filter ) );
145 testResult = test.Run( listener, filter );
147 // Signal that we are done
148 listener.RunFinished( testResult );
150 // Return result array
151 return testResult;
153 catch( Exception exception )
155 // Signal that we finished with an exception
156 listener.RunFinished( exception );
157 // Rethrow - should we do this?
158 throw;
160 finally
162 runThread = null;
166 public void BeginRun( EventListener listener )
168 testResult = this.Run( listener );
171 public void BeginRun( EventListener listener, ITestFilter filter )
173 testResult = this.Run( listener, filter );
176 public virtual TestResult EndRun()
178 return TestResult;
181 /// <summary>
182 /// Wait is a NOP for SimpleTestRunner
183 /// </summary>
184 public virtual void Wait()
188 public virtual void CancelRun()
190 if (this.runThread != null)
192 // Cancel Synchronous run only if on another thread
193 if ( runThread == Thread.CurrentThread )
194 throw new InvalidOperationException( "May not CancelRun on same thread that is running the test" );
196 // Make a copy of runThread, which will be set to
197 // null when the thread terminates.
198 Thread cancelThread = this.runThread;
200 // Tell the thread to abort
201 this.runThread.Abort();
203 // Wake up the thread if necessary
204 // Figure out if we need to do an interupt
205 if ( (cancelThread.ThreadState & ThreadState.WaitSleepJoin ) != 0 )
206 cancelThread.Interrupt();
209 #endregion
211 #region InitializeLifetimeService Override
212 public override object InitializeLifetimeService()
214 return null;
216 #endregion