view Implab.Test/CancelationTests.cs @ 212:a01d9df88d74 v2

Added class Trace<T> to manage channels for individual classes, if SomeClass uses Trace<SomeClass> it sould be marked with TraceSourceAttribute
author cin
date Tue, 04 Apr 2017 12:04:05 +0300
parents eb793fbbe4ea
children cbe10ac0731e
line wrap: on
line source

using System;
using Implab.Parallels;

#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 CancelationTests {

        [TestMethod]
        public void PromiseCancelTest() {
            var p = new Promise();
            bool requested = false;
            var reason = new Exception("Test");

            // request cancelation
            p.Cancel(reason);

            Assert.IsTrue(p.IsCancellationRequested);
            Assert.AreSame(reason, p.CancellationReason);
            Assert.IsFalse(p.IsCancelled);

            p.CancellationRequested(r => {
                Assert.AreSame(reason, r);
                requested = true;
            });

            Assert.IsTrue(requested);

            // cancel the promise
            Assert.IsTrue(p.CancelOperationIfRequested());
            Assert.IsTrue(p.IsCancelled);
            Assert.AreSame(reason, p.Error);
        }

        [TestMethod]
        public void CancelActionBeforeStartTask() {
            bool run = false;
            var task = new ActionTask(() => {
                run = true;
            }, null, null, true);

            // request cancelation
            task.Cancel();
            Assert.IsTrue(task.IsCancelled);
            task.Resolve();
            Assert.IsFalse(run);
        }

        [TestMethod]
        public void CancelActionAfterTaskStarted() {
            var finish = new Signal();
            var started = new Signal();

            var task = new ActionTask(() => {
                started.Set();
                finish.Wait();
            }, null, null, true);

            AsyncPool.RunThread(() => {
                task.Resolve();
            });

            started.Wait(1000);

            task.Cancel();
            Assert.IsTrue(task.IsCancellationRequested);
            Assert.IsFalse(task.IsCancelled);
            Assert.IsFalse(task.IsResolved);

            finish.Set();
            task.Join(1000);

        }

        [TestMethod]
        public void CancelTaskChainFromBottom() {
            var started = new Signal();
            var check1 = new Signal();
            var requested = false;
            var p1 = AsyncPool.RunThread(token => {
                token.CancellationRequested(reason => requested = true);
                started.Set();
                check1.Wait();
                token.CancelOperationIfRequested();
            });

            started.Wait();

            var p2 = p1.Then(() => {
            });

            Assert.IsFalse(p1.IsResolved);
            Assert.IsFalse(p2.IsResolved);

            p2.Cancel();

            Assert.IsFalse(p2.IsCancelled);
            Assert.IsFalse(p1.IsCancelled);
            Assert.IsTrue(requested);

            check1.Set();

            try {
                p2.Join(1000);
                Assert.Fail("The chain isn't cancelled");
            } catch(OperationCanceledException){
            }

            Assert.IsTrue(p1.IsCancelled);
            Assert.IsTrue(p2.IsCancelled);
        }



        [TestMethod]
        public void CancellableAsyncTask() {
            var finish = new Signal();
            var started = new Signal();

            var p = AsyncPool.RunThread(token => {
                token.CancellationRequested(r => finish.Set());
                started.Set();
                finish.Wait();
                Assert.IsTrue(token.CancelOperationIfRequested());
            });

            started.Wait(1000);
            Assert.IsFalse(p.IsResolved);
            p.Cancel();
            try {
                p.Join(1000);
            } catch (OperationCanceledException) {
            }
        }
    }
}