using System; using System.Diagnostics; using System.Threading; using UnitTestSharp; namespace TestsForUnitTestSharp { public class TestWorkerTests : TestFixture { /// /// Long enough that a broken worker fails rather than hangs; every healthy case returns immediately. /// private const int Grace = 5000; public void Constructor_Returns_WorkerIsAlreadyMeasuringCpu() { CheckNotNull(new TestWorker().TotalProcessorTime); } public class BeginTests : TestFixture { public void Action_RunsIt() { var worker = new TestWorker(); bool ran = false; worker.Begin(() => ran = true); CheckTrue(worker.WaitForCompletion(Grace)); CheckTrue(ran); } public void Action_RunsItOffTheCallingThread() { var worker = new TestWorker(); int ranOn = Thread.CurrentThread.ManagedThreadId; worker.Begin(() => ranOn = Thread.CurrentThread.ManagedThreadId); worker.WaitForCompletion(Grace); CheckNotEqual(Thread.CurrentThread.ManagedThreadId, ranOn); } public void CalledRepeatedly_ReusesTheSameThread() { var worker = new TestWorker(); int first = 0; int second = 0; worker.Begin(() => first = Thread.CurrentThread.ManagedThreadId); worker.WaitForCompletion(Grace); worker.Begin(() => second = Thread.CurrentThread.ManagedThreadId); worker.WaitForCompletion(Grace); CheckEqual(first, second); } public void AfterAFailure_ClearsThePreviousResult() { var worker = new TestWorker(); worker.Begin(() => { throw new InvalidOperationException("boom"); }); worker.WaitForCompletion(Grace); CheckNotNull(worker.Result); worker.Begin(() => { }); worker.WaitForCompletion(Grace); CheckNull(worker.Result); } } public class WaitForCompletionTests : TestFixture { public void WorkStillRunning_ReturnsFalse() { var worker = new TestWorker(); var release = new ManualResetEventSlim(false); worker.Begin(() => release.Wait()); CheckFalse(worker.WaitForCompletion(1)); release.Set(); worker.WaitForCompletion(Grace); } public void WorkDone_ReturnsTrue() { var worker = new TestWorker(); var release = new ManualResetEventSlim(false); worker.Begin(() => {}); worker.WaitForCompletion(300); Check(worker.WaitForCompletion(1)); release.Set(); worker.WaitForCompletion(Grace); } } public class ResultTests : TestFixture { public void ActionSucceeds_IsNull() { var worker = new TestWorker(); worker.Begin(() => { }); worker.WaitForCompletion(Grace); CheckNull(worker.Result); } public void ActionThrows_IsTheThrownException() { var worker = new TestWorker(); var thrown = new InvalidOperationException("boom"); worker.Begin(() => { throw thrown; }); worker.WaitForCompletion(Grace); CheckEqual(thrown, worker.Result); } } public class AbortTests : TestFixture { public void Abort_WhileRunning_StopsTheWorkAndReportsTheAbort() { var worker = new TestWorker(); var running = new ManualResetEventSlim(false); var neverSet = new ManualResetEventSlim(false); bool reachedTheEnd = false; worker.Begin(() => { running.Set(); neverSet.Wait(); reachedTheEnd = true; }); running.Wait(); worker.Abort(); CheckTrue(worker.WaitForCompletion(Grace)); CheckFalse(reachedTheEnd); CheckEqual(typeof(ThreadAbortException), worker.Result.GetType()); } } public class TotalProcessorTimeTests : TestFixture { public static void BurnCpu() { var elapsed = Stopwatch.StartNew(); double accumulator = 0; while (elapsed.ElapsedMilliseconds < TimedInvokerTests.LongerThanAPoll) { accumulator += Math.Sqrt(accumulator + 1); } } public void ReturnsCpuProcessorTime() { var worker = new TestWorker(); var release = new ManualResetEventSlim(false); worker.Begin(() => BurnCpu()); worker.WaitForCompletion((int)TimedInvokerTests.NoiseFloorMilliseconds); CheckGreater(worker.TotalProcessorTime, TimeSpan.Zero); } } } }