diff Implab.Test/RunnableComponentTests.cs @ 185:822aab37b107 ref20160224

runnable component, work in progress
author cin
date Mon, 18 Apr 2016 16:41:17 +0300
parents
children 3071220371f8
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Implab.Test/RunnableComponentTests.cs	Mon Apr 18 16:41:17 2016 +0300
@@ -0,0 +1,194 @@
+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;
+
+#else
+
+using Microsoft.VisualStudio.TestTools.UnitTesting;
+
+#endif
+
+namespace Implab.Test {
+    [TestClass]
+    public class RunnableComponentTests {
+
+        static void ShouldThrow(Action action) {
+            try {
+                action();
+                Assert.Fail();
+            } catch(AssertionException) {
+                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.IsInstanceOfType(typeof(OperationCanceledException), comp.LastError);
+
+            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.IsInstanceOfType(typeof(OperationCanceledException), comp.LastError);
+
+            comp.Dispose();
+        }
+
+    }
+}
+