RunnableComponentTests.cs
195 lines
| 5.4 KiB
| text/x-csharp
|
CSharpLexer
/ Implab.Test / RunnableComponentTests.cs
cin
|
r185 | 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; | ||||
cin
|
r188 | using AssertFailedException = NUnit.Framework.AssertionException; | ||
cin
|
r185 | #else | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
#endif | ||||
namespace Implab.Test { | ||||
[TestClass] | ||||
public class RunnableComponentTests { | ||||
static void ShouldThrow(Action action) { | ||||
try { | ||||
action(); | ||||
cin
|
r188 | Assert.Fail(); | ||
} catch (AssertFailedException) { | ||||
cin
|
r185 | 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); | ||||
cin
|
r188 | |||
cin
|
r196 | Assert.IsTrue(comp.LastError is OperationCanceledException); | ||
cin
|
r185 | |||
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)); | ||||
cin
|
r188 | Assert.AreEqual(ExecutionState.Failed, comp.State); | ||
cin
|
r196 | Assert.IsTrue(comp.LastError is OperationCanceledException); | ||
cin
|
r185 | |||
comp.Dispose(); | ||||
} | ||||
} | ||||
} | ||||