More work on #140. Now tests are ran. Next step is logging to xml.

This commit is contained in:
Matthijs ter Woord 2015-06-21 13:57:46 +02:00
parent 0cbba4c0d0
commit 89d62cc55a
11 changed files with 226 additions and 57 deletions

View file

@ -51,6 +51,9 @@
<Compile Include="Engine.Run.cs"> <Compile Include="Engine.Run.cs">
<DependentUpon>Engine.cs</DependentUpon> <DependentUpon>Engine.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="OutputHandlerBase.cs" />
<Compile Include="OutputHandlerConsole.cs" />
<Compile Include="OutputHandlerText.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>

View file

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.IO; using System.IO;
using System.Threading;
using Cosmos.Build.Common; using Cosmos.Build.Common;
using Cosmos.Debug.Common; using Cosmos.Debug.Common;
using Cosmos.Debug.VSDebugEngine.Host; using Cosmos.Debug.VSDebugEngine.Host;
@ -9,6 +10,8 @@ namespace Cosmos.TestRunner.Core
{ {
partial class Engine partial class Engine
{ {
private const int AllowedSecondsInKernel = 10;
private void RunIsoInBochs(string iso) private void RunIsoInBochs(string iso)
{ {
var xBochsConfig = Path.Combine(mBaseWorkingDirectory, "Kernel.bochsrc"); var xBochsConfig = Path.Combine(mBaseWorkingDirectory, "Kernel.bochsrc");
@ -20,28 +23,53 @@ namespace Cosmos.TestRunner.Core
var xDebugConnector = new DebugConnectorPipeServer("Cosmos\\Serial"); var xDebugConnector = new DebugConnectorPipeServer("Cosmos\\Serial");
xDebugConnector.CmdChannel += ChannelPacketReceived; xDebugConnector.CmdChannel = ChannelPacketReceived;
xDebugConnector.CmdStarted += () => xDebugConnector.CmdStarted = () =>
{ {
DoLog("DC: Started"); OutputHandler.LogMessage("DC: Started");
xDebugConnector.SendCmd(Vs2Ds.BatchEnd); xDebugConnector.SendCmd(Vs2Ds.BatchEnd);
}; };
xDebugConnector.CmdText += s => DoLog("Text from kernel: " + s); xDebugConnector.Error = e =>
xDebugConnector.CmdMessageBox += s => DoLog("MessageBox from kernel: " + s); {
OutputHandler.LogMessage("DC Error: " + e.ToString());
mBochsRunning = false;
};
xDebugConnector.CmdText += s => OutputHandler.LogMessage("Text from kernel: " + s);
xDebugConnector.CmdMessageBox = s => OutputHandler.LogMessage("MessageBox from kernel: " + s);
var xBochs = new Bochs(xParams, false, new FileInfo(xBochsConfig)); var xBochs = new Bochs(xParams, false, new FileInfo(xBochsConfig));
xBochs.OnShutDown = (a, b) =>
{
};
mBochsRunning = true;
xBochs.Start(); xBochs.Start();
try try
{ {
var xStartTime = DateTime.Now;
Console.WriteLine("Bochs started"); Console.WriteLine("Bochs started");
Console.ReadLine(); while (mBochsRunning)
{
Thread.Sleep(50);
if (Math.Abs(DateTime.Now.Subtract(xStartTime).TotalSeconds) > AllowedSecondsInKernel)
{
OutputHandler.SetKernelTestResult(false, "Timeout exceeded");
break;
} }
catch }
Console.WriteLine("Stopping bochs now");
}
finally
{ {
xBochs.Stop(); xBochs.Stop();
xDebugConnector.Dispose();
} }
} }
private bool mBochsRunning = true;
private void ChannelPacketReceived(byte arg1, byte arg2, byte[] arg3) private void ChannelPacketReceived(byte arg1, byte arg2, byte[] arg3)
{ {
Console.WriteLine("ChannelPacket received. Channel = {0}, command = {1}", arg1, arg2); Console.WriteLine("ChannelPacket received. Channel = {0}, command = {1}", arg1, arg2);

View file

@ -32,8 +32,8 @@ namespace Cosmos.TestRunner.Core
var xProcess = new Process(); var xProcess = new Process();
xProcess.StartInfo = xStartInfo; xProcess.StartInfo = xStartInfo;
xProcess.OutputDataReceived += (sender, e) => DoLog(e.Data); xProcess.OutputDataReceived += (sender, e) => OutputHandler.LogMessage(e.Data);
xProcess.ErrorDataReceived += (sender, e) => DoLog(e.Data); xProcess.ErrorDataReceived += (sender, e) => OutputHandler.LogError(e.Data);
xProcess.Start(); xProcess.Start();
xProcess.BeginErrorReadLine(); xProcess.BeginErrorReadLine();
xProcess.BeginOutputReadLine(); xProcess.BeginOutputReadLine();
@ -46,9 +46,6 @@ namespace Cosmos.TestRunner.Core
private void RunIL2CPU(string kernelFileName, string outputFile) private void RunIL2CPU(string kernelFileName, string outputFile)
{ {
DoLog("Running IL2CPU");
mLogLevel++;
RunProcess(typeof(Program).Assembly.Location, RunProcess(typeof(Program).Assembly.Location,
mBaseWorkingDirectory, mBaseWorkingDirectory,
new[] new[]
@ -72,16 +69,13 @@ namespace Cosmos.TestRunner.Core
private void RunNasm(string inputFile, string outputFile, bool isElf) private void RunNasm(string inputFile, string outputFile, bool isElf)
{ {
DoLog("Running Nasm");
mLogLevel++;
var xNasmTask = new NAsmTask(); var xNasmTask = new NAsmTask();
xNasmTask.InputFile = inputFile; xNasmTask.InputFile = inputFile;
xNasmTask.OutputFile = outputFile; xNasmTask.OutputFile = outputFile;
xNasmTask.IsELF = isElf; xNasmTask.IsELF = isElf;
xNasmTask.ExePath = Path.Combine(GetCosmosUserkitFolder(), "build", "tools", "nasm", "nasm.exe"); xNasmTask.ExePath = Path.Combine(GetCosmosUserkitFolder(), "build", "tools", "nasm", "nasm.exe");
xNasmTask.LogMessage = DoLog; xNasmTask.LogMessage = OutputHandler.LogMessage;
xNasmTask.LogError = DoLog; xNasmTask.LogError = OutputHandler.LogError;
if (!xNasmTask.Execute()) if (!xNasmTask.Execute())
{ {
throw new Exception("Error running nasm!"); throw new Exception("Error running nasm!");
@ -90,9 +84,6 @@ namespace Cosmos.TestRunner.Core
private void RunLd(string inputFile, string outputFile) private void RunLd(string inputFile, string outputFile)
{ {
DoLog("Running Ld");
mLogLevel++;
RunProcess(Path.Combine(GetCosmosUserkitFolder(), "build", "tools", "cygwin", "ld.exe"), RunProcess(Path.Combine(GetCosmosUserkitFolder(), "build", "tools", "cygwin", "ld.exe"),
mBaseWorkingDirectory, mBaseWorkingDirectory,
new[] new[]
@ -121,7 +112,6 @@ namespace Cosmos.TestRunner.Core
private void MakeIso(string objectFile, string isoFile) private void MakeIso(string objectFile, string isoFile)
{ {
DoLog("Build ISO");
IsoMaker.Generate(objectFile, isoFile); IsoMaker.Generate(objectFile, isoFile);
if (!File.Exists(isoFile)) if (!File.Exists(isoFile))
{ {

View file

@ -16,31 +16,58 @@ namespace Cosmos.TestRunner.Core
private bool mIsELF = true; private bool mIsELF = true;
private void ExecuteKernel(string assemblyFileName) private void ExecuteKernel(string assemblyFileName)
{ {
OutputHandler.ExecuteKernelStart(assemblyFileName);
try
{
var xAssemblyFile = Path.Combine(mBaseWorkingDirectory, "Kernel.asm"); var xAssemblyFile = Path.Combine(mBaseWorkingDirectory, "Kernel.asm");
var xObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.obj"); var xObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.obj");
var xTempObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.o"); var xTempObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.o");
var xIsoFile = Path.Combine(mBaseWorkingDirectory, "Kernel.iso"); var xIsoFile = Path.Combine(mBaseWorkingDirectory, "Kernel.iso");
mLogLevel = 1; RunTask("IL2CPU", () => RunIL2CPU(assemblyFileName, xAssemblyFile));
DoLog(string.Format("Testing '{0}'", assemblyFileName)); RunTask("Nasm", () => RunNasm(xAssemblyFile, xObjectFile, mIsELF));
mLogLevel = 2;
RunIL2CPU(assemblyFileName, xAssemblyFile);
mLogLevel = 2;
RunNasm(xAssemblyFile, xObjectFile, mIsELF);
if (mIsELF) if (mIsELF)
{ {
File.Move(xObjectFile, xTempObjectFile); File.Move(xObjectFile, xTempObjectFile);
mLogLevel = 2; RunTask("Ld", () => RunLd(xTempObjectFile, xObjectFile));
RunLd(xTempObjectFile, xObjectFile);
} }
mLogLevel = 2; RunTask("MakeISO", () => MakeIso(xObjectFile, xIsoFile));
MakeIso(xObjectFile, xIsoFile); RunTask("IL2CPU", () => RunIsoInBochs(xIsoFile));
mLogLevel = 2; }
RunIsoInBochs(xIsoFile); catch (Exception e)
{
OutputHandler.UnhandledException(e);
}
finally
{
OutputHandler.ExecuteKernelEnd(assemblyFileName);
}
} }
private void RunTask(string taskName, Action action)
{
if (action == null)
{
throw new ArgumentNullException("action");
}
OutputHandler.TaskStart(taskName);
try
{
action();
}
catch (Exception e)
{
OutputHandler.UnhandledException(e);
}
finally
{
OutputHandler.TaskEnd(taskName);
}
}
} }
} }

View file

@ -1,4 +1,5 @@
using System; using System;
using System.CodeDom;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
@ -21,8 +22,15 @@ namespace Cosmos.TestRunner.Core
private string mBaseWorkingDirectory; private string mBaseWorkingDirectory;
public OutputHandlerBase OutputHandler;
public void Execute() public void Execute()
{ {
if (OutputHandler == null)
{
throw new InvalidOperationException("No OutputHandler set!");
}
mBaseWorkingDirectory = Path.Combine(Path.GetDirectoryName(typeof(Engine).Assembly.Location), "WorkingDirectory"); mBaseWorkingDirectory = Path.Combine(Path.GetDirectoryName(typeof(Engine).Assembly.Location), "WorkingDirectory");
if (Directory.Exists(mBaseWorkingDirectory)) if (Directory.Exists(mBaseWorkingDirectory))
{ {
@ -30,23 +38,26 @@ namespace Cosmos.TestRunner.Core
} }
Directory.CreateDirectory(mBaseWorkingDirectory); Directory.CreateDirectory(mBaseWorkingDirectory);
DoLog("Start executing"); OutputHandler.ExecutionStart();
try
{
// todo: test with multiple configurations (for example, ELF and BIN format, with or without stack corruption detection, etc) // todo: test with multiple configurations (for example, ELF and BIN format, with or without stack corruption detection, etc)
foreach (var xAssemblyFile in mKernelsToRun) foreach (var xAssemblyFile in mKernelsToRun)
{ {
ExecuteKernel(xAssemblyFile); ExecuteKernel(xAssemblyFile);
} }
}
// todo: now report summary catch (Exception E)
throw new NotImplementedException(); {
OutputHandler.UnhandledException(E);
}
finally
{
OutputHandler.ExecutionEnd();
} }
private int mLogLevel = 0; // todo: now report summary
private void DoLog(string message) //DoLog("NotImplemented, summary?");
{
Console.Write(new String(' ', mLogLevel * 2));
Console.WriteLine(message);
} }
} }
} }

View file

@ -0,0 +1,18 @@
using System;
namespace Cosmos.TestRunner.Core
{
public abstract class OutputHandlerBase
{
public abstract void ExecuteKernelStart(string assemblyName);
public abstract void ExecuteKernelEnd(string assemblyName);
public abstract void LogMessage(string message);
public abstract void LogError(string message);
public abstract void ExecutionStart();
public abstract void ExecutionEnd();
public abstract void UnhandledException(Exception exception);
public abstract void TaskStart(string taskName);
public abstract void TaskEnd(string taskName);
public abstract void SetKernelTestResult(bool succeeded, string message);
}
}

View file

@ -0,0 +1,84 @@
using System;
using System.Diagnostics;
namespace Cosmos.TestRunner.Core
{
public class OutputHandlerConsole: OutputHandlerBase
{
private readonly Stopwatch mCurrentTaskStopwatch=new Stopwatch();
private readonly Stopwatch mCurrentKernelStopwatch = new Stopwatch();
private readonly Stopwatch mExecutionStopwatch = new Stopwatch();
public override void TaskStart(string taskName)
{
Log("Running task '" + taskName + "'");
mCurrentTaskStopwatch.Reset();
mCurrentTaskStopwatch.Start();
mLogLevel = 2;
}
public override void TaskEnd(string taskName)
{
mCurrentTaskStopwatch.Stop();
mLogLevel = 1;
Log("Done running task '" + taskName + "'. Took " + mCurrentTaskStopwatch.Elapsed);
}
public override void UnhandledException(Exception exception)
{
Log("Unhandled exception: "+ exception.ToString());
}
public override void ExecutionEnd()
{
mLogLevel = 0;
Log("Done executing");
Log("Took " + mExecutionStopwatch.Elapsed);
}
public override void ExecutionStart()
{
mLogLevel = 0;
Log("Start executing");
mExecutionStopwatch.Reset();
mExecutionStopwatch.Start();
mLogLevel = 1;
}
public override void LogError(string message)
{
Log("Error: " + message);
}
public override void LogMessage(string message)
{
Log(message);
}
public override void ExecuteKernelEnd(string assemblyName)
{
mCurrentKernelStopwatch.Stop();
Log("Done running kernel. Took " + mCurrentKernelStopwatch.Elapsed);
}
public override void ExecuteKernelStart(string assemblyName)
{
Log("Starting kernel '" + assemblyName + "'");
mCurrentKernelStopwatch.Reset();
mCurrentKernelStopwatch.Start();
}
private int mLogLevel;
private void Log(string message)
{
Console.Write(DateTime.Now.ToString("hh:mm:ss.ffffff "));
Console.Write(new String(' ', mLogLevel * 2));
Console.WriteLine(message);
}
public override void SetKernelTestResult(bool succeeded, string message)
{
Log(string.Format("Success = {0}, Message = '{1}'", succeeded, message));
}
}
}

View file

@ -0,0 +1,7 @@
namespace Cosmos.TestRunner.Core
{
public class OutputHandlerText
{
//OutputHandlerBase
}
}

View file

@ -14,6 +14,7 @@ namespace Cosmos.TestRunner.Console
{ {
var xEngine = new Engine(); var xEngine = new Engine();
xEngine.AddKernel(typeof(Kernel).Assembly.Location); xEngine.AddKernel(typeof(Kernel).Assembly.Location);
xEngine.OutputHandler = new OutputHandlerConsole();
xEngine.Execute(); xEngine.Execute();
} }
} }

View file

@ -41,7 +41,7 @@ namespace Cosmos.Debug.VSDebugEngine.Host
"ata3: enabled=0\n" + "ata3: enabled=0\n" +
"pci: enabled=1, chipset=i440fx\n" + "pci: enabled=1, chipset=i440fx\n" +
"vga: extension=vbe, update_freq=5, realtime=1\n" + "vga: extension=vbe, update_freq=5, realtime=1\n" +
"cpu: count=1, ips=4000000, model=corei5_lynnfield_750, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0\n" + "cpu: count=1, ips=4000000, model=bx_generic, reset_on_triple_fault=1, cpuid_limit_winnt=0, ignore_bad_msrs=1, mwait_is_nop=0\n" +
"print_timestamps: enabled=0\n" + "print_timestamps: enabled=0\n" +
"port_e9_hack: enabled=0\n" + "port_e9_hack: enabled=0\n" +
"private_colormap: enabled=0\n" + "private_colormap: enabled=0\n" +

View file

@ -6,7 +6,7 @@ using System.Text;
namespace Cosmos.HAL { namespace Cosmos.HAL {
public class ConsoleKeyInfoEx public class ConsoleKeyInfoEx
{ {
// once Github issue #137 is fixed, replace this class with ConsoleKeyInfo struct. // todo: once Github issue #137 is fixed, replace this class with ConsoleKeyInfo struct.
public char KeyChar public char KeyChar
{ {