// *********************************************************************** // Copyright (c) 2007 Charlie Poole // // Permission is hereby granted, free of charge, to any person obtaining // a copy of this software and associated documentation files (the // "Software"), to deal in the Software without restriction, including // without limitation the rights to use, copy, modify, merge, publish, // distribute, sublicense, and/or sell copies of the Software, and to // permit persons to whom the Software is furnished to do so, subject to // the following conditions: // // The above copyright notice and this permission notice shall be // included in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // *********************************************************************** using System; using System.Linq; using System.Text.RegularExpressions; using NUnitLite; #if SSHARP using Crestron.SimplSharpPro.CrestronThread; using Crestron.SimplSharp; using NUnit.Framework.Interfaces; using SSCore.Diagnostics; #endif namespace NUnitLite.Tests { public static class NUnitLite { // The main program executes the tests. Output may be routed to // various locations, depending on the sub class of TextUI // that is created and any arument passed. // // Examples: // // Sending output to the console works on desktop Windows and Windows CE. // // new ConsoleUI().Execute( args ); // // Debug output works on all platforms. // // new DebugUI().Execute( args ); // // Sending output to a file works on all platforms, but care must be taken // to write to an accessible location on some platforms. // // string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.Personal); // string path = System.IO.Path.Combine( myDocs, "TestResult.txt" ); // System.IO.TextWriter writer = new System.IO.StreamWriter(output); // new TextUI( writer ).Execute( args ); // writer.Close(); #if SSHARP private static ConsoleRun _cr; private static DateTime _timeLastTestFinished = DateTime.MaxValue; private static Thread _watchdogThread; private static ManualResetEvent _watchdogEvent = new ManualResetEvent (false); private const int WatchdogTimeout = 10000; private static bool _runCompleted; private static object WatchdogThread (object state) { while (!_watchdogEvent.Wait (WatchdogTimeout) && !_runCompleted) { if (!Debugger.IsAttached && _cr.AreTestsRunning && DateTime.Now - _timeLastTestFinished > TimeSpan.FromMilliseconds (WatchdogTimeout)) CrestronEnvironment.AllowOtherAppsToRun (); } return null; } static NUnitLite () { _cr = new ConsoleRun (null); _cr.OnTestCompleted += TestCompletedCallback; _cr.OnRunCompleted += _cr_OnRunCompleted; CrestronEnvironment.ProgramStatusEventHandler += CrestronEnvironment_ProgramStatusEventHandler; } static void CrestronEnvironment_ProgramStatusEventHandler (eProgramStatusEventType programEventType) { if (programEventType != eProgramStatusEventType.Stopping) return; _cr_OnRunCompleted (_cr, -1); } static void _cr_OnRunCompleted (object sender, int result) { if (_watchdogThread == null) return; _runCompleted = true; _watchdogEvent.Set (); if (_watchdogThread.Join(WatchdogTimeout)) _watchdogThread.Abort (); _watchdogThread = null; } public static void NUnitLiteSSharpTestsMain (string commandLine) { const string re = @"\G(""((""""|[^""])+)""|(\S+)) *"; var ms = Regex.Matches (commandLine, re); string[] args = ms.Cast ().Select (m => Regex.Replace (m.Groups[2].Success ? m.Groups[2].Value : m.Groups[4].Value, @"""""", @"""")).ToArray (); DoTest (args); } static void DoTest (string[] args) { #else static void Main (string[] args) { #endif //if (Environment.OSVersion.Platform == PlatformID.WinCE) //{ // string path = System.IO.Path.Combine(NUnit.Env.DocumentFolder, "TestResult.txt"); // System.IO.TextWriter writer = new System.IO.StreamWriter(path); // new TextUI(writer).Execute(args); // writer.Close(); // // new TcpUI("ppp_peer", 9000).Execute(args); //} //else //{ // new TcpUI("ferrari", 9000).Execute(args); #if SSHARP if (args.Length == 0) args = new [] {"-status"}; var arg0 = args[0].ToLowerInvariant (); if (arg0 == "-abort") _cr.StopTests (true); else if (arg0 == "-stop" || arg0 == "-cancel") _cr.StopTests (false); else if (arg0 == "-status" || arg0 == "-s") { if (_cr.AreTestsRunning) if (String.IsNullOrEmpty (_cr.CurrentTest)) CrestronConsole.ConsoleCommandResponse ("No test running, previous test was '{0}'.", _cr.PreviousTest); else if (_cr.CurrentTests != null && !_cr.CurrentTests.IsEmpty) { var cts = _cr.CurrentTests.Where (ct => !ct.Value.IsSuite && !ct.Value.HasChildren).ToArray (); if (cts.Length > 1) { CrestronConsole.ConsoleCommandResponse ("Current running tests are:"); foreach (var curTest in cts.OrderBy (ct => ct.Value.Timestamp)) CrestronConsole.ConsoleCommandResponse ("\r\n {0} : {1}", curTest.Key, curTest.Value.Timestamp.ToString ("HH:mm:ss.fff")); } else if (cts.Length == 1) CrestronConsole.ConsoleCommandResponse ("Current running test is '{0}' [{1:HH:mm:ss.fff}]", cts[0].Key, cts[0].Value.Timestamp); else CrestronConsole.ConsoleCommandResponse ("No test running, previous test was '{0}'.", _cr.PreviousTest); } else CrestronConsole.ConsoleCommandResponse ("Current running test is '{0}'.", _cr.CurrentTest); else CrestronConsole.ConsoleCommandResponse ("Inactive."); } else if (arg0 == "--debug" || arg0 == "-d") { if (args.Length != 2) CrestronConsole.ConsoleCommandResponse ("Trace mode is {0}", Trace.Mode); else { var debugMode = args[1].ToLowerInvariant (); switch (debugMode) { case "d": case "debug": case "debugger": Trace.Mode = OutputMode.Debugger; break; case "c": case "con": case "console": Trace.Mode = OutputMode.Console; break; case "n": case"none": Trace.Mode = OutputMode.None; break; case "cd": case "cod": case "cind": case "consoleifnotdebugging": Trace.Mode = OutputMode.ConsoleIfNotDebugging; break; default: CrestronConsole.ConsoleCommandResponse ("Invalid trace mode. Must be: Debugger, Console, ConsoleIfNotDebugging, None"); break; } } } else { if (_cr.AreTestsRunning) { CrestronConsole.ConsoleCommandResponse ("Tests are running. Current test is '{0}'. Cancel before running additonal tests.", _cr.CurrentTest); return; } if (!args.Any(a => a.StartsWith("-explore"))) { _cr_OnRunCompleted (_cr, -1); _timeLastTestFinished = DateTime.Now; _watchdogEvent.Reset (); _runCompleted = false; _watchdogThread = new Thread (WatchdogThread, null, Thread.eThreadStartOptions.CreateSuspended); _watchdogThread.Priority = Thread.eThreadPriority.HighPriority; _watchdogThread.Start (); } try { _cr.Execute (args, true); } catch (Exception ex) { CrestronConsole.ConsoleCommandResponse ("ConsoleRunner Exception: '{0}' at:\r\n{1}", ex.Message, ex.StackTrace); } } #else new TextUI ().Execute (args); #endif //} } #if SSHARP private static void TestCompletedCallback (object sender, ITestResult result) { _timeLastTestFinished = DateTime.Now; CrestronEnvironment.AllowOtherAppsToRun (); } #endif } }