##// END OF EJS Templates
Added ResetState to RunnableComponent to reset in case of failure...
Added ResetState to RunnableComponent to reset in case of failure Added StateChanged event to IRunnable Renamed Promise.SUCCESS -> Promise.Success Added Promise.FromException Renamed Bundle -> PromiseAll in PromiseExtensions

File last commit:

r205:8200ab154c8a v2
r205:8200ab154c8a v2
Show More
RunnableComponentTests.cs
230 lines | 6.5 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, error) => {
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, error) => {
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;
Exception lastError = null;
comp.MockDispose = (disposing, error) => {
disposed = true;
lastError = error;
};
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();
}
}
}