##// END OF EJS Templates
Слияние
Слияние

File last commit:

r205:8200ab154c8a v2
r232:133ba4444acc merge v2
Show More
PollingComponentTests.cs
230 lines | 6.3 KiB | text/x-csharp | CSharpLexer
/ Implab.Test / PollingComponentTests.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 PollingComponentTests {
static void ShouldThrow(Action action) {
try {
action();
Assert.Fail();
} catch (AssertFailedException) {
throw;
} catch {
}
}
[TestMethod]
public void NormalFlowTest() {
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, 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 ShouldStartTicks() {
var signal = new Signal();
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, true);
comp.MockTick = ct => {
signal.Set();
return Promise.Success;
};
comp.Start().Join(1000);
signal.Wait(1000);
comp.Stop().Join(1000);
}
[TestMethod]
public void StopShouldWaitForTickToComplete() {
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, true);
var signal = new Signal();
var promise = new Promise();
// timer should tick once
comp.MockTick = ct => {
signal.Set();
return promise;
};
// start timer
comp.Start().Join(1000);
signal.Wait(); // wait for tick
// try to stop component
var stopping = comp.Stop();
Assert.AreEqual(ExecutionState.Stopping, comp.State);
ShouldThrow(() => stopping.Join(100));
Assert.AreEqual(ExecutionState.Stopping, comp.State);
// complete operation
promise.Resolve();
// the component should stop normally
stopping.Join(1000);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void ShouldRecoverAfterTickError() {
var ticks = 0;
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, true);
var signal = new Signal(); // will signal when timer fires 10 times
comp.MockTick = ct => {
ticks++;
if (ticks == 10)
signal.Set();
// each time handler dies
throw new Exception("tainted handler");
};
comp.Start();
signal.Wait(1000);
comp.Stop().Join(1000);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void StopCancelHandlerOnStop() {
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, true);
var started = new Signal();
bool cancelled = false;
// timer should tick once
comp.MockTick = ct => {
started.Set();
while(!ct.IsCancellationRequested) {
Thread.Sleep(1);
}
cancelled = true;
throw new OperationCanceledException();
};
// start timer
comp.Start().Join(1000);
started.Wait(); // wait for tick
// try to stop component
comp.Stop().Join(1000);
Assert.AreEqual(true, cancelled);
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void FailTickOnStopShouldBeIgnored() {
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, true);
var started = new Signal();
var finish = new Signal();
// timer should tick once
comp.MockTick = ct => {
started.Set();
finish.Wait();
// component is in stopping state here
throw new Exception("Die, die, die!!!");
};
comp.MockOnError = comp.CallComponentFail;
// start timer
comp.Start().Join(1000);
started.Wait(); // wait for tick
// try to stop component
var stopping = comp.Stop();
// the component is in stopping state but it is waiting for the tick handler to complete
finish.Set(); // signal the tick handler to finish
// tick handler should stop rather soon
stopping.Join(1000);
// validate the component is disposed
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
[TestMethod]
public void FailTickShouldFailComponent() {
var comp = new MockPollingComponent(TimeSpan.FromMilliseconds(1), null, true);
var started = new Signal();
var finish = new Signal();
// timer should tick once
comp.MockTick = ct => {
started.Set();
throw new Exception("Die, die, die!!!");
};
comp.MockOnError = err => {
comp.CallComponentFail(err);
finish.Set();
};
// start timer
comp.Start().Join(1000);
started.Wait(); // wait for tick
finish.Wait();
// try to stop component
ShouldThrow(() => comp.Stop());
Assert.AreEqual(ExecutionState.Failed, comp.State);
Assert.IsNotNull(comp.LastError);
Assert.AreEqual("Die, die, die!!!", comp.LastError.Message);
comp.Dispose();
Assert.AreEqual(ExecutionState.Disposed, comp.State);
}
}
}