##// END OF EJS Templates
Bound promise to CancellationToken...
Bound promise to CancellationToken Added new states to ExecutionSate enum. Added Safe.Guard() method to handle cleanup of the result of the promise

File last commit:

r208:7d07503621fe v2
r209:a867536c68fc v2
Show More
RunnableComponentTests.cs
228 lines | 6.4 KiB | text/x-csharp | CSharpLexer
/ Implab.Test / RunnableComponentTests.cs
using System;
using System.Reflection;
using System.Threading;
using Implab.Parallels;
using Implab.Components;
using Implab.Test.Mock;
#if MONO
using NUnit.Framework;
using TestClassAttribute = NUnit.Framework.TestFixtureAttribute;
using TestMethodAttribute = NUnit.Framework.TestAttribute;
using AssertFailedException = NUnit.Framework.AssertionException;
#else
using Microsoft.VisualStudio.TestTools.UnitTesting;
#endif
namespace Implab.Test {
[TestClass]
public class RunnableComponentTests {
static void ShouldThrow(Action action) {
try {
action();
Assert.Fail();
} catch (AssertFailedException) {
throw;
} catch {
}
}
[TestMethod]
public void NormalFlowTest() {
var comp = new MockRunnableComponent(false);
Assert.AreEqual(ExecutionState.Created, comp.State);
comp.Initialize();
Assert.AreEqual(ExecutionState.Ready, comp.State);
comp.Start().Join(1000);
Assert.AreEqual(ExecutionState.Running, comp.State);
comp.Stop().Join(1000);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void InitFailTest() {
var comp = new MockRunnableComponent(false) {
MockInit = () => {
throw new Exception("BAD");
}
};
ShouldThrow(() => comp.Start());
ShouldThrow(() => comp.Stop());
Assert.AreEqual(ExecutionState.Created, comp.State);
ShouldThrow(comp.Initialize);
Assert.AreEqual(ExecutionState.Failed, comp.State);
ShouldThrow(() => comp.Start());
ShouldThrow(() => comp.Stop());
Assert.AreEqual(ExecutionState.Failed, comp.State);
comp.Dispose();
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void DisposedTest() {
var comp = new MockRunnableComponent(false);
comp.Dispose();
ShouldThrow(() => comp.Start());
ShouldThrow(() => comp.Stop());
ShouldThrow(comp.Initialize);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void ShouldCallDisposeOnStop() {
var comp = new MockRunnableComponent(true);
bool disposed = false;
comp.MockDispose = (disposing) => {
disposed = true;
};
comp.Start().Join(1000);
comp.Stop().Join(1000);
ShouldThrow(() => comp.Start());
ShouldThrow(() => comp.Stop());
ShouldThrow(comp.Initialize);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
Assert.IsTrue(disposed);
}
[TestMethod]
public void ShouldNotCallDisposeOnStop() {
var comp = new MockRunnableComponent(true, true);
bool disposed = false;
comp.MockDispose = (disposing) => {
disposed = true;
};
comp.Start().Join(1000);
comp.Stop().Join(1000);
Assert.AreEqual(ExecutionState.Ready, comp.State);
Assert.IsFalse(disposed);
}
[TestMethod]
public void SelfDisposeOnStop() {
var comp = new MockRunnableComponent(true, true);
bool disposed = false;
comp.MockDispose = (disposing) => {
disposed = true;
};
comp.Start().Join(1000);
comp.Stop().Join(1000);
Assert.AreEqual(ExecutionState.Ready, comp.State);
Assert.IsFalse(disposed);
comp.MockStop = () => {
comp.Dispose();
return Promise.Success;
};
comp.Start().Join(1000);
comp.Stop().Join(1000);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
Assert.IsTrue(disposed);
}
[TestMethod]
public void StartCancelTest() {
var comp = new MockRunnableComponent(true) {
MockStart = () => PromiseHelper.Sleep(100000, 0)
};
var p = comp.Start();
Assert.AreEqual(ExecutionState.Starting, comp.State);
p.Cancel();
ShouldThrow(() => p.Join(1000));
Assert.AreEqual(ExecutionState.Failed, comp.State);
Assert.IsTrue(comp.LastError is OperationCanceledException);
comp.Dispose();
}
[TestMethod]
public void StartStopTest() {
var stop = new Signal();
var comp = new MockRunnableComponent(true) {
MockStart = () => PromiseHelper.Sleep(100000, 0),
MockStop = () => AsyncPool.RunThread(stop.Wait)
};
var p1 = comp.Start();
var p2 = comp.Stop();
// should enter stopping state
ShouldThrow(p1.Join);
Assert.IsTrue(p1.IsCancelled);
Assert.AreEqual(ExecutionState.Stopping, comp.State);
stop.Set();
p2.Join(1000);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void StartStopFailTest() {
var comp = new MockRunnableComponent(true) {
MockStart = () => PromiseHelper.Sleep(100000, 0).Then(null,null,x => { throw new Exception("I'm dead"); })
};
comp.Start();
var p = comp.Stop();
// if Start fails to cancel, should fail to stop
ShouldThrow(() => p.Join(1000));
Assert.AreEqual(ExecutionState.Failed, comp.State);
Assert.IsNotNull(comp.LastError);
Assert.AreEqual("I'm dead", comp.LastError.Message);
}
[TestMethod]
public void StopCancelTest() {
var comp = new MockRunnableComponent(true) {
MockStop = () => PromiseHelper.Sleep(100000, 0)
};
comp.Start();
var p = comp.Stop();
Assert.AreEqual(ExecutionState.Stopping, comp.State);
p.Cancel();
ShouldThrow(() => p.Join(1000));
Assert.AreEqual(ExecutionState.Failed, comp.State);
Assert.IsTrue(comp.LastError is OperationCanceledException);
comp.Dispose();
}
}
}