using System; using System.Collections.Generic; using System.IO; using System.Linq; using Cosmos.Build.Common; namespace Cosmos.TestRunner.Core { public partial class Engine { private static readonly string WorkingDirectoryBase = Path.Combine( Path.GetDirectoryName(typeof(Engine).Assembly.Location), "WorkingDirectory"); // configuration: in process eases debugging, but means certain errors (like stack overflow) kill the test runner. protected bool DebugIL2CPU => mConfiguration.DebugIL2CPU; protected string KernelPkg => mConfiguration.KernelPkg; protected TraceAssemblies TraceAssembliesLevel => mConfiguration.TraceAssembliesLevel; protected bool EnableStackCorruptionChecks => mConfiguration.EnableStackCorruptionChecks; protected StackCorruptionDetectionLevel StackCorruptionDetectionLevel => mConfiguration.StackCorruptionDetectionLevel; protected bool RunWithGDB => mConfiguration.RunWithGDB; protected bool StartBochsDebugGui => mConfiguration.StartBochsDebugGUI; public IEnumerable KernelsToRun => mConfiguration.KernelTypesToRun; private IEngineConfiguration mConfiguration; private TestResultOutputHandler mTestResultOutputHandler; public OutputHandlerBasic OutputHandler { get; private set; } public Engine(IEngineConfiguration aEngineConfiguration) { mConfiguration = aEngineConfiguration; mTestResultOutputHandler = new TestResultOutputHandler(); } public ITestResult Execute() { if (!RunTargets.Any()) { throw new InvalidOperationException("No run targets were specified!"); } var xTestResult = new TestResult(); OutputHandler.ExecutionStart(); foreach (var xConfig in GetRunConfigurations()) { OutputHandler.RunConfigurationStart(xConfig); foreach (var xKernelType in KernelsToRun) { var xKernelName = xKernelType.Assembly.GetName().Name; var xKernelTestResult = new KernelTestResult(xKernelName, xConfig); var xWorkingDirectory = Path.Combine(WorkingDirectoryBase, xKernelName); if (Directory.Exists(xWorkingDirectory)) { Directory.Delete(xWorkingDirectory, true); } Directory.CreateDirectory(xWorkingDirectory); try { xKernelTestResult.Result = ExecuteKernel( xKernelType.Assembly.Location, xWorkingDirectory, xConfig, xKernelTestResult); } catch (Exception e) { OutputHandler.UnhandledException(e); } xKernelTestResult.TestLog = mTestResultOutputHandler.TestLog; xTestResult.AddKernelTestResult(xKernelTestResult); if (!xKernelTestResult.Result) { OutputHandler.LogMessage(xKernelTestResult.TestLog); break; } } OutputHandler.RunConfigurationEnd(xConfig); } OutputHandler.ExecutionEnd(); var xPassedTestsCount = xTestResult.KernelTestResults.Count(r => r.Result); var xFailedTestsCount = xTestResult.KernelTestResults.Count(r => !r.Result); OutputHandler.LogMessage($"Done executing: {xPassedTestsCount} test(s) passed, {xFailedTestsCount} test(s) failed."); return xTestResult; } public void SetOutputHandler(OutputHandlerBasic outputHandler) => OutputHandler = new MultiplexingOutputHandler(outputHandler, mTestResultOutputHandler); private IEnumerable GetRunConfigurations() { foreach (var xTarget in RunTargets) { yield return new RunConfiguration(isElf: true, runTarget: xTarget); //yield return new RunConfiguration(isElf: false, runTarget: xTarget); } } } }