##// END OF EJS Templates
fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.
fixed promise chaining behavior, the error handler doesn't handle result or cancellation handlers exceptions these exceptions are propagated to the next handlers.

File last commit:

r194:d45bdf510514 v2
r196:40d7fed4a09e default
Show More
RunnableComponentTests.cs
195 lines | 5.4 KiB | text/x-csharp | CSharpLexer
/ Implab.Test / RunnableComponentTests.cs
using System;
using System.Reflection;
using System.Threading;
using Implab.Parallels;
using Implab.Components;
#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 {
}
}
class Runnable : RunnableComponent {
public Runnable(bool initialized) : base(initialized) {
}
public Action MockInit {
get;
set;
}
public Func<IPromise> MockStart {
get;
set;
}
public Func<IPromise> MockStop {
get;
set;
}
protected override IPromise OnStart() {
return MockStart != null ? MockStart() : base.OnStart();
}
protected override IPromise OnStop() {
return MockStop != null ? MockStop() : base.OnStart();
}
protected override void OnInitialize() {
if (MockInit != null)
MockInit();
}
}
[TestMethod]
public void NormalFlowTest() {
var comp = new Runnable(false);
Assert.AreEqual(ExecutionState.Created, comp.State);
comp.Init();
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 Runnable(false) {
MockInit = () => {
throw new Exception("BAD");
}
};
ShouldThrow(() => comp.Start());
ShouldThrow(() => comp.Stop());
Assert.AreEqual(ExecutionState.Created, comp.State);
ShouldThrow(comp.Init);
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 Runnable(false);
comp.Dispose();
ShouldThrow(() => comp.Start());
ShouldThrow(() => comp.Stop());
ShouldThrow(comp.Init);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void StartCancelTest() {
var comp = new Runnable(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 Runnable(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 Runnable(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 Runnable(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();
}
}
}