singrdk/base/Libraries/UnitTest/UnitTest.cs

149 lines
4.5 KiB
C#

///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: UnitTest.cs
//
// Note:
//
using System;
using System.Collections;
using System.Threading;
namespace Microsoft.Singularity.UnitTest
{
public sealed class UnitTest
{
public enum Result
{
Passed = 0,
Failed = 1
}
public delegate void TestDelegate();
internal sealed class TestCommand
{
private string /*!*/ description;
private TestDelegate /*!*/ testDelegate;
internal TestCommand(string /*!*/ description,
TestDelegate /*!*/ testDelegate)
{
this.description = description;
this.testDelegate = testDelegate;
}
internal string Description { get { return description; } }
internal void Execute() { testDelegate(); }
}
private static ArrayList! tests = new ArrayList();
private static object classLock = new object();
private static int runThreadId;
private static volatile int otherThreadExceptions = 0;
private static volatile bool expectAssertionFailure = false;
public static void Add(string /*!*/ description,
TestDelegate /*!*/ test)
{
tests.Add(new TestCommand(description, test));
}
public static void Clear()
{
tests.Clear();
}
public static void ExpectNextAssertionFails()
{
lock (classLock) {
UnitTest.expectAssertionFailure = true;
}
}
public static void ExpectNextAssertionPasses()
{
lock (classLock) {
UnitTest.expectAssertionFailure = false;
}
}
public static Result Run(bool stopOnFailure)
{
runThreadId = GetCurrentThreadId();
int failures = 0;
foreach (TestCommand! tc in tests) {
Result r = Result.Passed;
try {
Console.Write("Running test {0}...", tc.Description);
lock (classLock) {
UnitTest.otherThreadExceptions = 0;
}
tc.Execute();
lock (classLock) {
if (UnitTest.otherThreadExceptions == 0) {
Console.WriteLine("Passed.");
}
else {
Console.WriteLine("Failed.");
r = Result.Failed;
}
}
}
catch (FailedAssertionException fae) {
Console.WriteLine("Failed.");
Console.WriteLine(fae);
r = Result.Failed;
}
catch (Exception e) {
Console.WriteLine("Failed: Unexpected exception caught.");
Console.WriteLine(e);
r = Result.Failed;
}
if (r == Result.Failed) {
failures++;
if (stopOnFailure) {
break;
}
}
}
return (failures == 0) ? Result.Passed : Result.Failed;
}
private static int GetCurrentThreadId()
{
#if SINGULARITY
return Thread.CurrentThread.GetThreadId();
#else
return AppDomain.GetCurrentThreadId();
#endif
}
internal static void Throw(FailedAssertionException /*!*/ e)
{
lock (classLock) {
if (UnitTest.expectAssertionFailure == true) {
UnitTest.expectAssertionFailure = false;
return;
}
int threadId = GetCurrentThreadId();
if (threadId != runThreadId) {
UnitTest.otherThreadExceptions++;
Console.WriteLine("Tester Failure on thread {0}: {1}",
threadId, e);
}
}
throw e;
}
}
}