~ubuntu-branches/ubuntu/oneiric/monodevelop/oneiric-updates

« back to all changes in this revision

Viewing changes to src/addins/NUnit/Services/ExternalTestRunner.cs

  • Committer: Bazaar Package Importer
  • Author(s): Jo Shields
  • Date: 2009-02-18 08:40:51 UTC
  • mfrom: (1.2.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20090218084051-gh8m6ukvokbwj7cf
Tags: 1.9.2+dfsg-1ubuntu1
* Merge from Debian Experimental (LP: #330519), remaining Ubuntu changes:
  + debian/control:
    - Update for Gnome# 2.24
    - Add libmono-cairo1.0-cil to build-deps to fool pkg-config check

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
using System.Reflection;
32
32
using System.IO;
33
33
using System.Collections;
 
34
using System.Collections.Generic;
34
35
using System.Threading;
 
36
using System.Text;
35
37
 
36
38
using MonoDevelop.Core;
37
39
using MonoDevelop.Core.Execution;
38
40
using NUnit.Core;
 
41
using NUnit.Util;
39
42
using NF = NUnit.Framework;
 
43
using NC = NUnit.Core;
40
44
 
41
 
namespace MonoDevelop.NUnit
 
45
namespace MonoDevelop.NUnit.External
42
46
{
43
 
        [AddinDependency ("MonoDevelop.Projects")]
44
47
        class ExternalTestRunner: RemoteProcessObject
45
48
        {
46
 
                string assemblyName;
47
 
                StringWriter stdout = new StringWriter ();
48
 
                StringWriter stderr = new StringWriter ();
49
 
                
50
 
                public TestResult Run (EventListener listener, IFilter filter, string path, string suiteName)
51
 
                {
52
 
                        TestSuite rootTS = LoadTestSuite (path, suiteName);
53
 
                        if (rootTS == null)
54
 
                                throw new Exception ("Test suite '" + suiteName + "' not found.");
55
 
 
56
 
                        // Force the loading of the NUnit.Framework assembly.
57
 
                        // It's needed since that dll is not located in the test dll directory.
58
 
                        typeof(NF.Assert).ToString ();
59
 
 
60
 
                        TextWriter origStdout = Console.Out;
61
 
                        TextWriter origStderr = Console.Error;
62
 
                        Console.SetOut (stdout);
63
 
                        Console.SetError (stderr);
64
 
                        
65
 
                        string cdir = Environment.CurrentDirectory;
66
 
                        Environment.CurrentDirectory = Path.GetDirectoryName (path);
67
 
                        
68
 
                        try {
69
 
                                return rootTS.Run (listener, filter);
70
 
                        } finally {
71
 
                                Environment.CurrentDirectory = cdir;
72
 
                                Console.SetOut (origStdout);
73
 
                                Console.SetError (origStderr);
74
 
                        }
75
 
                }
76
 
                
77
 
                public string ResetTestConsoleOutput ()
78
 
                {
79
 
                        string s = stdout.ToString ();
80
 
                        stdout = new StringWriter ();
81
 
                        Console.SetOut (stdout);
82
 
                        return s;
83
 
                }
84
 
                        
85
 
                public string ResetTestConsoleError ()
86
 
                {
87
 
                        string s = stderr.ToString ();
88
 
                        stderr = new StringWriter ();
89
 
                        Console.SetError (stderr);
90
 
                        return s;
91
 
                }
92
 
                        
93
 
                TestSuite LoadTestSuite (string path, string fullName)
94
 
                {
95
 
                        ResolveEventHandler reh = new ResolveEventHandler (TryLoad);
96
 
                        AppDomain.CurrentDomain.AssemblyResolve += reh;
97
 
                        assemblyName = path;
98
 
 
99
 
                        try {
100
 
                                if (fullName != "")
101
 
                                        return new TestSuiteBuilder ().Build (path, fullName);
102
 
                                else
103
 
                                        return new TestSuiteBuilder ().Build (path);
104
 
                        } finally {
105
 
                                AppDomain.CurrentDomain.AssemblyResolve -= reh;
106
 
                        }
107
 
                }
108
 
 
109
 
                Assembly TryLoad (object sender, ResolveEventArgs args)
110
 
                {
111
 
                        try {
112
 
                                // NUnit2 uses Assembly.Load on the filename without extension.
113
 
                                // This is done just to allow loading from a full path name.
114
 
                                return Assembly.LoadFrom (assemblyName);
115
 
                        } catch { }
116
 
 
117
 
                        return null;
118
 
                }
119
 
                
120
 
                public TestInfo GetTestInfo (string path)
121
 
                {
122
 
                        // Force the loading of the NUnit.Framework assembly.
123
 
                        // It's needed since that dll is not located in the test dll directory.
124
 
                        typeof(NF.Assert).ToString ();
125
 
 
126
 
                        TestSuite rootTS = LoadTestSuite (path, "");
127
 
                        return BuildTestInfo (rootTS);
128
 
                }
129
 
                
130
 
                TestInfo BuildTestInfo (Test test)
131
 
                {
132
 
                        TestInfo ti = new TestInfo ();
133
 
                        ti.Name = test.Name;
134
 
                        int i = test.FullName.LastIndexOf ('.');
135
 
                        if (i != -1)
136
 
                                ti.PathName = test.FullName.Substring (0,i);
 
49
                NUnitTestRunner runner;
 
50
                
 
51
                public UnitTestResult Run (IRemoteEventListener listener, ITestFilter filter, string path, string suiteName, List<string> supportAssemblies)
 
52
                {
 
53
                        NUnitTestRunner runner = GetRunner (path);
 
54
                        EventListenerWrapper listenerWrapper = listener != null ? new EventListenerWrapper (listener) : null;
 
55
                        
 
56
                        TestResult res = runner.Run (listenerWrapper, filter, path, suiteName, supportAssemblies);
 
57
                        return listenerWrapper.GetLocalTestResult (res);
 
58
                }
 
59
                
 
60
                public NunitTestInfo GetTestInfo (string path, List<string> supportAssemblies)
 
61
                {
 
62
                        NUnitTestRunner runner = GetRunner (path);
 
63
                        return runner.GetTestInfo (path, supportAssemblies);
 
64
                }
 
65
                
 
66
                NUnitTestRunner GetRunner (string assemblyPath)
 
67
                {
 
68
                        TestPackage package = new TestPackage (assemblyPath);
 
69
                        package.Settings ["ShadowCopyFiles"] = false;
 
70
                        DomainManager dm = new DomainManager ();
 
71
                        AppDomain domain = dm.CreateDomain (package);
 
72
                        string asm = Path.Combine (Path.GetDirectoryName (GetType ().Assembly.Location), "NUnitRunner.dll");
 
73
                        runner = (NUnitTestRunner) domain.CreateInstanceFromAndUnwrap (asm, "MonoDevelop.NUnit.External.NUnitTestRunner");
 
74
                        runner.Initialize (typeof(NF.Assert).Assembly.Location, typeof(NC.Test).Assembly.Location);
 
75
                        return runner;
 
76
                }
 
77
        }
 
78
        
 
79
        class EventListenerWrapper: MarshalByRefObject, EventListener
 
80
        {
 
81
                IRemoteEventListener wrapped;
 
82
                StringBuilder consoleOutput;
 
83
                StringBuilder consoleError;
 
84
                
 
85
                public EventListenerWrapper (IRemoteEventListener wrapped)
 
86
                {
 
87
                        this.wrapped = wrapped;
 
88
                }
 
89
                
 
90
                public void RunFinished (Exception exception)
 
91
                {
 
92
                }
 
93
                
 
94
                public void RunFinished (TestResult results)
 
95
                {
 
96
                }
 
97
                
 
98
                public void RunStarted (string name, int testCount)
 
99
                {
 
100
                }
 
101
                
 
102
                public void SuiteFinished (TestSuiteResult result)
 
103
                {
 
104
                        wrapped.SuiteFinished (GetTestName (result.Test.TestName), GetLocalTestResult (result));
 
105
                }
 
106
                
 
107
                public void SuiteStarted (TestName suite)
 
108
                {
 
109
                        wrapped.SuiteStarted (GetTestName (suite));
 
110
                }
 
111
                
 
112
                public void TestFinished (TestCaseResult result)
 
113
                {
 
114
                        wrapped.TestFinished (GetTestName (result.Test.TestName), GetLocalTestResult (result));
 
115
                }
 
116
                
 
117
                public void TestOutput (TestOutput testOutput)
 
118
                {
 
119
                        if (consoleOutput == null)
 
120
                                return;
 
121
                        else if (testOutput.Type == TestOutputType.Out)
 
122
                                consoleOutput.Append (testOutput.Text);
137
123
                        else
138
 
                                ti.PathName = null;
139
 
                                
140
 
                        if (test.Tests != null && test.Tests.Count > 0) {
141
 
                                ti.Tests = new TestInfo [test.Tests.Count];
142
 
                                for (int n=0; n<test.Tests.Count; n++)
143
 
                                        ti.Tests [n] = BuildTestInfo ((Test)test.Tests [n]);
144
 
                        }
145
 
                        return ti;
146
 
                }
147
 
        }
148
 
        
149
 
        [Serializable]
150
 
        class TestInfo
151
 
        {
152
 
                public string Name;
153
 
                public string PathName;
154
 
                public TestInfo[] Tests;
155
 
        }
156
 
        
157
 
        class LocalTestMonitor: MarshalByRefObject, EventListener
158
 
        {
159
 
                TestContext context;
160
 
                UnitTest rootTest;
161
 
                string rootFullName;
162
 
                ExternalTestRunner runner;
163
 
                UnitTest runningTest;
164
 
                bool singleTestRun;
165
 
                Hashtable outputText = new Hashtable ();
166
 
                Hashtable errorText = new Hashtable ();
167
 
                
168
 
                internal UnitTestResult SingleTestResult;
169
 
                
170
 
                public LocalTestMonitor (TestContext context, ExternalTestRunner runner, UnitTest rootTest, string rootFullName, bool singleTestRun)
171
 
                {
172
 
                        this.runner = runner;
173
 
                        this.rootFullName = rootFullName;
174
 
                        this.rootTest = rootTest;
175
 
                        this.context = context;
176
 
                        this.singleTestRun = singleTestRun;
177
 
                }
178
 
                
179
 
                public UnitTest RunningTest {
180
 
                        get { return runningTest; }
181
 
                }
182
 
                
183
 
                void EventListener.RunStarted (Test [] tests)
184
 
                {
185
 
                }
186
 
 
187
 
                void EventListener.RunFinished (TestResult [] results)
188
 
                {
189
 
                }
190
 
 
191
 
                void EventListener.UnhandledException (Exception exception)
192
 
                {
193
 
                }
194
 
 
195
 
                void EventListener.RunFinished (Exception exc)
196
 
                {
197
 
                }
198
 
 
199
 
                void EventListener.TestStarted (TestCase testCase)
200
 
                {
201
 
                        if (singleTestRun)
202
 
                                return;
203
 
                        
204
 
                        UnitTest t = GetLocalTest (testCase);
205
 
                        if (t == null)
206
 
                                return;
207
 
                        
208
 
                        runningTest = t;
209
 
                        context.Monitor.BeginTest (t);
210
 
                        t.Status = TestStatus.Running;
211
 
                }
212
 
                        
213
 
                void EventListener.TestFinished (TestCaseResult result)
214
 
                {
215
 
                        outputText [result] = runner.ResetTestConsoleOutput ();
216
 
                        errorText [result] = runner.ResetTestConsoleError ();
217
 
                        
218
 
                        if (singleTestRun) {
219
 
                                SingleTestResult = GetLocalTestResult (result);
220
 
                                return;
221
 
                        }
222
 
                        
223
 
                        UnitTest t = GetLocalTest ((Test) result.Test);
224
 
                        if (t == null)
225
 
                                return;
226
 
                        
227
 
                        UnitTestResult res = GetLocalTestResult (result);
228
 
                        if (res == null)
229
 
                                return;
230
 
                        
231
 
                        t.RegisterResult (context, res);
232
 
                        context.Monitor.EndTest (t, res);
233
 
                        t.Status = TestStatus.Ready;
234
 
                        runningTest = null;
235
 
                }
236
 
 
237
 
                void EventListener.SuiteStarted (TestSuite suite)
238
 
                {
239
 
                        if (singleTestRun)
240
 
                                return;
241
 
                        
242
 
                        UnitTest t = GetLocalTest (suite);
243
 
                        if (t == null)
244
 
                                return;
245
 
                        
246
 
                        t.Status = TestStatus.Running;
247
 
                        context.Monitor.BeginTest (t);
248
 
                }
249
 
 
250
 
                void EventListener.SuiteFinished (TestSuiteResult result)
251
 
                {
252
 
                        if (singleTestRun)
253
 
                                return;
254
 
                        
255
 
                        UnitTest t = GetLocalTest ((Test) result.Test);
256
 
                        if (t == null)
257
 
                                return;
258
 
                        
259
 
                        UnitTestResult res = GetLocalTestResult (result);
260
 
                        t.RegisterResult (context, res);
261
 
                        t.Status = TestStatus.Ready;
262
 
                        context.Monitor.EndTest (t, res);
263
 
                }
264
 
                
265
 
                public void TestOutput (TestOutput testOutput)
266
 
                {
267
 
                }
268
 
 
269
 
 
270
 
                UnitTest GetLocalTest (Test t)
271
 
                {
272
 
                        if (t == null) return null;
273
 
                        if (t.Parent == null) return rootTest;
274
 
                        
275
 
                        string fn = t.FullName;
276
 
                        string sname = fn.Substring (rootFullName.Length);
277
 
                        if (sname.StartsWith (".")) sname = sname.Substring (1);
278
 
                        UnitTest tt = FindTest (rootTest, sname);
279
 
                        return tt;
280
 
                }
281
 
                
282
 
                UnitTest FindTest (UnitTest t, string testPath)
283
 
                {
284
 
                        if (testPath == "")
285
 
                                return t;
286
 
 
287
 
                        string[] path = testPath.Split ('.');
288
 
                        foreach (string part in path) {
289
 
                                UnitTestGroup group = t as UnitTestGroup;
290
 
                                if (group == null)
291
 
                                        return null;
292
 
                                
293
 
                                t = group.Tests [part];
294
 
                                if (t == null)
295
 
                                        return null;
296
 
                        }
297
 
                        return t;
 
124
                                consoleError.Append (testOutput.Text);
 
125
                }
 
126
                
 
127
                public void TestStarted (TestName testCase)
 
128
                {
 
129
                        wrapped.TestStarted (GetTestName (testCase));
 
130
                        consoleOutput = new StringBuilder ();
 
131
                        consoleError = new StringBuilder ();
 
132
                }
 
133
                
 
134
                public override object InitializeLifetimeService ()
 
135
                {
 
136
                        return null;
 
137
                }
 
138
                
 
139
                public string GetTestName (TestName t)
 
140
                {
 
141
                        if (t == null)
 
142
                                return null;
 
143
                        return t.FullName;
298
144
                }
299
145
                
300
146
                public UnitTestResult GetLocalTestResult (TestResult t)
301
147
                {
302
148
                        UnitTestResult res = new UnitTestResult ();
 
149
                        res.Message = t.Message;
303
150
                        
304
151
                        if (t is TestSuiteResult) {
305
152
                                int s=0, f=0, i=0;
326
173
                                        res.Status = ResultStatus.Success;
327
174
                                        res.TotalSuccess = 1;
328
175
                                }
 
176
                        
 
177
                                if (string.IsNullOrEmpty (res.Message)) {
 
178
                                        if (t.IsFailure)
 
179
                                                res.Message = GettextCatalog.GetString ("Test failed");
 
180
                                        else if (!t.Executed)
 
181
                                                res.Message = GettextCatalog.GetString ("Test ignored");
 
182
                                        else {
 
183
                                                res.Message = GettextCatalog.GetString ("Test successful") + "\n\n";
 
184
                                                res.Message += GettextCatalog.GetString ("Execution time: {0:0.00}ms", t.Time);
 
185
                                        }
 
186
                                }
329
187
                        }
330
 
                        
331
 
                        res.Message = t.Message;
332
188
                        res.StackTrace = t.StackTrace;
333
189
                        res.Time = TimeSpan.FromSeconds (t.Time);
334
 
                        res.ConsoleOutput = (string) outputText [t];
335
 
                        res.ConsoleError = (string) errorText [t];
 
190
                        
 
191
                        if (consoleOutput != null) {
 
192
                                res.ConsoleOutput = consoleOutput.ToString ();
 
193
                                res.ConsoleError = consoleError.ToString ();
 
194
                                consoleOutput = null;
 
195
                                consoleError = null;
 
196
                        }
336
197
                        
337
198
                        return res;
338
 
                }
 
199
                }               
339
200
                
340
201
                void CountResults (TestSuiteResult ts, ref int s, ref int f, ref int i)
341
202
                {
355
216
                                }
356
217
                        }
357
218
                }
 
219
                
 
220
                public void UnhandledException (Exception exception)
 
221
                {
 
222
                }
 
223
        }
 
224
        
 
225
        interface IRemoteEventListener
 
226
        {
 
227
                void TestStarted (string testCase);
 
228
                void TestFinished (string test, UnitTestResult result);
 
229
                void SuiteStarted (string suite);
 
230
                void SuiteFinished (string suite, UnitTestResult result);
 
231
        }
 
232
        
 
233
        class LocalTestMonitor: MarshalByRefObject, IRemoteEventListener
 
234
        {
 
235
                TestContext context;
 
236
                UnitTest rootTest;
 
237
                string rootFullName;
 
238
                UnitTest runningTest;
 
239
                bool singleTestRun;
 
240
                UnitTestResult singleTestResult;
 
241
                
 
242
                public LocalTestMonitor (TestContext context, ExternalTestRunner runner, UnitTest rootTest, string rootFullName, bool singleTestRun)
 
243
                {
 
244
                        this.rootFullName = rootFullName;
 
245
                        this.rootTest = rootTest;
 
246
                        this.context = context;
 
247
                        this.singleTestRun = singleTestRun;
 
248
                }
 
249
                
 
250
                public UnitTest RunningTest {
 
251
                        get { return runningTest; }
 
252
                }
 
253
                
 
254
                internal UnitTestResult SingleTestResult {
 
255
                        get {
 
256
                                if (singleTestResult == null)
 
257
                                        singleTestResult = new UnitTestResult ();
 
258
                                return singleTestResult;
 
259
                        }
 
260
                        set {
 
261
                                singleTestResult = value;
 
262
                        }
 
263
                }
 
264
                
 
265
                void IRemoteEventListener.TestStarted (string testCase)
 
266
                {
 
267
                        if (singleTestRun)
 
268
                                return;
 
269
                        
 
270
                        UnitTest t = GetLocalTest (testCase);
 
271
                        if (t == null)
 
272
                                return;
 
273
                        
 
274
                        runningTest = t;
 
275
                        context.Monitor.BeginTest (t);
 
276
                        t.Status = TestStatus.Running;
 
277
                }
 
278
                        
 
279
                void IRemoteEventListener.TestFinished (string test, UnitTestResult result)
 
280
                {
 
281
                        if (singleTestRun) {
 
282
                                SingleTestResult = result;
 
283
                                return;
 
284
                        }
 
285
                        
 
286
                        UnitTest t = GetLocalTest (test);
 
287
                        if (t == null)
 
288
                                return;
 
289
                        
 
290
                        t.RegisterResult (context, result);
 
291
                        context.Monitor.EndTest (t, result);
 
292
                        t.Status = TestStatus.Ready;
 
293
                        runningTest = null;
 
294
                }
 
295
 
 
296
                void IRemoteEventListener.SuiteStarted (string suite)
 
297
                {
 
298
                        if (singleTestRun)
 
299
                                return;
 
300
                        
 
301
                        UnitTest t = GetLocalTest (suite);
 
302
                        if (t == null)
 
303
                                return;
 
304
                        
 
305
                        t.Status = TestStatus.Running;
 
306
                        context.Monitor.BeginTest (t);
 
307
                }
 
308
 
 
309
                void IRemoteEventListener.SuiteFinished (string suite, UnitTestResult result)
 
310
                {
 
311
                        if (singleTestRun)
 
312
                                return;
 
313
                        
 
314
                        UnitTest t = GetLocalTest (suite);
 
315
                        if (t == null)
 
316
                                return;
 
317
                        
 
318
                        t.RegisterResult (context, result);
 
319
                        t.Status = TestStatus.Ready;
 
320
                        context.Monitor.EndTest (t, result);
 
321
                }
 
322
                
 
323
                UnitTest GetLocalTest (string sname)
 
324
                {
 
325
                        if (sname == null) return null;
 
326
                        if (sname == "<root>") return rootTest;
 
327
                        
 
328
                        if (sname.StartsWith (rootFullName)) {
 
329
                                sname = sname.Substring (rootFullName.Length);
 
330
                        }
 
331
                        if (sname.StartsWith (".")) sname = sname.Substring (1);
 
332
                        UnitTest tt = FindTest (rootTest, sname);
 
333
                        return tt;
 
334
                }
 
335
                
 
336
                UnitTest FindTest (UnitTest t, string testPath)
 
337
                {
 
338
                        if (testPath == "")
 
339
                                return t;
 
340
 
 
341
                        UnitTestGroup group = t as UnitTestGroup;
 
342
                        if (group == null)
 
343
                                return null;
 
344
 
 
345
                        UnitTest returnTest = group.Tests [testPath];
 
346
                        if (returnTest != null)
 
347
                                return returnTest;
 
348
 
 
349
                        string[] paths = testPath.Split (new char[] {'.'}, 2);
 
350
                        if (paths.Length == 2) {
 
351
                                string nextPathSection = paths[0];
 
352
                                string nextTestCandidate = paths[1];
 
353
 
 
354
                                UnitTest childTest = group.Tests [nextPathSection];
 
355
                                if (childTest != null)
 
356
                                        return FindTest (childTest, nextTestCandidate);
 
357
                        }
 
358
                        return null;
 
359
                }
358
360
        }       
359
361
}
360
362