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">
<DependentUpon>Engine.cs</DependentUpon>
</Compile>
<Compile Include="OutputHandlerBase.cs" />
<Compile Include="OutputHandlerConsole.cs" />
<Compile Include="OutputHandlerText.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>

View file

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

View file

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

View file

@ -16,31 +16,58 @@ namespace Cosmos.TestRunner.Core
private bool mIsELF = true;
private void ExecuteKernel(string assemblyFileName)
{
var xAssemblyFile = Path.Combine(mBaseWorkingDirectory, "Kernel.asm");
var xObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.obj");
var xTempObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.o");
var xIsoFile = Path.Combine(mBaseWorkingDirectory, "Kernel.iso");
mLogLevel = 1;
DoLog(string.Format("Testing '{0}'", assemblyFileName));
mLogLevel = 2;
RunIL2CPU(assemblyFileName, xAssemblyFile);
mLogLevel = 2;
RunNasm(xAssemblyFile, xObjectFile, mIsELF);
if (mIsELF)
OutputHandler.ExecuteKernelStart(assemblyFileName);
try
{
File.Move(xObjectFile, xTempObjectFile);
mLogLevel = 2;
RunLd(xTempObjectFile, xObjectFile);
var xAssemblyFile = Path.Combine(mBaseWorkingDirectory, "Kernel.asm");
var xObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.obj");
var xTempObjectFile = Path.Combine(mBaseWorkingDirectory, "Kernel.o");
var xIsoFile = Path.Combine(mBaseWorkingDirectory, "Kernel.iso");
RunTask("IL2CPU", () => RunIL2CPU(assemblyFileName, xAssemblyFile));
RunTask("Nasm", () => RunNasm(xAssemblyFile, xObjectFile, mIsELF));
if (mIsELF)
{
File.Move(xObjectFile, xTempObjectFile);
RunTask("Ld", () => RunLd(xTempObjectFile, xObjectFile));
}
RunTask("MakeISO", () => MakeIso(xObjectFile, xIsoFile));
RunTask("IL2CPU", () => RunIsoInBochs(xIsoFile));
}
catch (Exception e)
{
OutputHandler.UnhandledException(e);
}
finally
{
OutputHandler.ExecuteKernelEnd(assemblyFileName);
}
mLogLevel = 2;
MakeIso(xObjectFile, xIsoFile);
mLogLevel = 2;
RunIsoInBochs(xIsoFile);
}
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.CodeDom;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -21,8 +22,15 @@ namespace Cosmos.TestRunner.Core
private string mBaseWorkingDirectory;
public OutputHandlerBase OutputHandler;
public void Execute()
{
if (OutputHandler == null)
{
throw new InvalidOperationException("No OutputHandler set!");
}
mBaseWorkingDirectory = Path.Combine(Path.GetDirectoryName(typeof(Engine).Assembly.Location), "WorkingDirectory");
if (Directory.Exists(mBaseWorkingDirectory))
{
@ -30,23 +38,26 @@ namespace Cosmos.TestRunner.Core
}
Directory.CreateDirectory(mBaseWorkingDirectory);
DoLog("Start executing");
// todo: test with multiple configurations (for example, ELF and BIN format, with or without stack corruption detection, etc)
foreach (var xAssemblyFile in mKernelsToRun)
OutputHandler.ExecutionStart();
try
{
ExecuteKernel(xAssemblyFile);
// todo: test with multiple configurations (for example, ELF and BIN format, with or without stack corruption detection, etc)
foreach (var xAssemblyFile in mKernelsToRun)
{
ExecuteKernel(xAssemblyFile);
}
}
catch (Exception E)
{
OutputHandler.UnhandledException(E);
}
finally
{
OutputHandler.ExecutionEnd();
}
// todo: now report summary
throw new NotImplementedException();
}
private int mLogLevel = 0;
private void DoLog(string message)
{
Console.Write(new String(' ', mLogLevel * 2));
Console.WriteLine(message);
//DoLog("NotImplemented, summary?");
}
}
}

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();
xEngine.AddKernel(typeof(Kernel).Assembly.Location);
xEngine.OutputHandler = new OutputHandlerConsole();
xEngine.Execute();
}
}

View file

@ -41,7 +41,7 @@ namespace Cosmos.Debug.VSDebugEngine.Host
"ata3: enabled=0\n" +
"pci: enabled=1, chipset=i440fx\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" +
"port_e9_hack: enabled=0\n" +
"private_colormap: enabled=0\n" +

View file

@ -6,7 +6,7 @@ using System.Text;
namespace Cosmos.HAL {
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
{
@ -124,4 +124,4 @@ namespace Cosmos.HAL {
protected set;
}
}
}
}