Example #1
0
        private static void WaitForRunnerToFinish(CancellableJobRunner runner)
        {
            int timeout = System.Diagnostics.Debugger.IsAttached ? 20000 : 3000;

            try
            {
                runner.TestingWaitHandle?.WaitOne(timeout);
            }
            catch (ObjectDisposedException)
            {
                // If the runner has finished then the token source will have been disposed
            }
        }
Example #2
0
        public void NoOperations_NoProgressHandler_NoErrors()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true, logThreadId: true);

            testLogger.WriteLine("[Test] Executing test");

            // Act
            var testSubject = CancellableJobRunner.Start("my job", new Action[] { },
                                                         null /* should be ok to pass null here */,
                                                         testLogger);

            WaitForRunnerToFinish(testSubject, testLogger);

            // Assert
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Finished);
        }
Example #3
0
        public void NoOperations_NoProgressHandler_NoErrors()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true);

            TestContext.WriteLine($"Test executing on thread {Thread.CurrentThread.ManagedThreadId}");

            // Act
            var testSubject = CancellableJobRunner.Start("my job", new Action[] { },
                                                         null /* should be ok to pass null here */,
                                                         testLogger);

            WaitForRunnerToFinish(testSubject);

            // Assert
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Finished);
        }
Example #4
0
        public void AllOperationsExecuted()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true, logThreadId: true);

            testLogger.WriteLine("[Test] Executing test");

            var progressRecorder = new ProgressNotificationRecorder(testLogger);

            bool op1Executed = false, op2Executed = false;
            int  operationThreadId = -1;

            CancellableJobRunner testSubject = null;

            Action op1 = () =>
            {
                testLogger.WriteLine("[Test] Executing op1");
                testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Running);

                op1Executed       = true;
                operationThreadId = Thread.CurrentThread.ManagedThreadId;
            };

            Action op2 = () => op2Executed = true;

            // Act
            testSubject = CancellableJobRunner.Start("my job", new[] { op1, op2 }, progressRecorder, testLogger);
            WaitForRunnerToFinish(testSubject, testLogger);

            // Assert
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Finished);

            op1Executed.Should().BeTrue();
            op2Executed.Should().BeTrue();

            operationThreadId.Should().NotBe(Thread.CurrentThread.ManagedThreadId);

            progressRecorder.Notifications.Count.Should().Be(4);
            CheckExpectedNotification(progressRecorder.Notifications[0], CancellableJobRunner.RunnerState.Running, 0, 2);
            CheckExpectedNotification(progressRecorder.Notifications[1], CancellableJobRunner.RunnerState.Running, 1, 2);
            CheckExpectedNotification(progressRecorder.Notifications[2], CancellableJobRunner.RunnerState.Running, 2, 2);
            CheckExpectedNotification(progressRecorder.Notifications[3], CancellableJobRunner.RunnerState.Finished, 2, 2);
        }
Example #5
0
        public void CancelAfterFirstOperation()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true, logThreadId: true);

            testLogger.WriteLine("[Test] Executing test");
            var progressRecorder = new ProgressNotificationRecorder(testLogger);

            bool op1Executed = false, op2Executed = false;
            CancellableJobRunner testSubject = null;

            Action op1 = () =>
            {
                testLogger.WriteLine("[Test] Executing op1");
                op1Executed = true;

                testSubject.Cancel();
            };

            Action op2 = () =>
            {
                testLogger.WriteLine("[Test] Executing op2");
                op2Executed = true;
            };

            // Act
            testSubject = CancellableJobRunner.Start("my job", new[] { op1, op2 }, progressRecorder, testLogger);


            WaitForRunnerToFinish(testSubject, testLogger);
            // Pause for any final progress steps to be reported before checking the progressRecorder below
            Thread.Sleep(200);

            // Other checks
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Cancelled);
            op1Executed.Should().BeTrue();
            op2Executed.Should().BeFalse();

            progressRecorder.Notifications.Count.Should().Be(2);
            CheckExpectedNotification(progressRecorder.Notifications[0], CancellableJobRunner.RunnerState.Running, 0, 2);
            CheckExpectedNotification(progressRecorder.Notifications[1], CancellableJobRunner.RunnerState.Cancelled, 0, 2);
        }
Example #6
0
        public void NoOperations_NoErrors()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true, logThreadId: true);

            testLogger.WriteLine("[Test] Executing test");
            var progressRecorder = new ProgressNotificationRecorder(testLogger);

            // Act
            var testSubject = CancellableJobRunner.Start("my job", new Action[] { }, progressRecorder, testLogger);

            WaitForRunnerToFinish(testSubject, testLogger);

            // Assert
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Finished);

            progressRecorder.Notifications.Count.Should().Be(2);
            CheckExpectedNotification(progressRecorder.Notifications[0], CancellableJobRunner.RunnerState.Running, 0, 0);
            CheckExpectedNotification(progressRecorder.Notifications[1], CancellableJobRunner.RunnerState.Finished, 0, 0);
        }
Example #7
0
        public void CancelAfterFirstOperation()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true);

            TestContext.WriteLine($"Test executing on thread {Thread.CurrentThread.ManagedThreadId}");
            var progressRecorder = new ProgressNotificationRecorder();

            bool op1Executed = false, op2Executed = false;
            CancellableJobRunner testSubject = null;

            Action op1 = () =>
            {
                TestContext.WriteLine($"Executing op1 on thread {Thread.CurrentThread.ManagedThreadId}");
                op1Executed = true;

                testSubject.Cancel();
            };

            Action op2 = () =>
            {
                TestContext.WriteLine($"Executing op2 on thread {Thread.CurrentThread.ManagedThreadId}");
                op2Executed = true;
            };

            // Act
            testSubject = CancellableJobRunner.Start("my job", new[] { op1, op2 }, progressRecorder, testLogger);


            WaitForRunnerToFinish(testSubject);

            // Other checks
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Cancelled);
            op1Executed.Should().BeTrue();
            op2Executed.Should().BeFalse();

            progressRecorder.Notifications.Count.Should().Be(2);
            CheckExpectedNotification(progressRecorder.Notifications[0], CancellableJobRunner.RunnerState.Running, 0, 2);
            CheckExpectedNotification(progressRecorder.Notifications[1], CancellableJobRunner.RunnerState.Cancelled, 0, 2);
        }
Example #8
0
        public void ExceptionInOperationPreventsSubsequentOperations()
        {
            // Arrange
            var testLogger = new TestLogger(logToConsole: true, logThreadId: true);

            testLogger.WriteLine("[Test] Executing test");
            var progressRecorder = new ProgressNotificationRecorder(testLogger);

            bool op1Executed = false, op2Executed = false;

            Action op1 = () =>
            {
                testLogger.WriteLine("[Test] Executing op1");
                op1Executed = true;
                throw new InvalidOperationException("XXX YYY");
            };

            Action op2 = () =>
            {
                testLogger.WriteLine("[Test] Executing op2");
                op2Executed = true;
            };

            // Act
            var testSubject = CancellableJobRunner.Start("my job", new[] { op1, op2 }, progressRecorder, testLogger);

            WaitForRunnerToFinish(testSubject, testLogger);

            // Other checks
            testSubject.State.Should().Be(CancellableJobRunner.RunnerState.Faulted);
            testLogger.AssertPartialOutputStringExists("XXX YYY");

            op1Executed.Should().BeTrue();
            op2Executed.Should().BeFalse();

            progressRecorder.Notifications.Count.Should().Be(2);
            CheckExpectedNotification(progressRecorder.Notifications[0], CancellableJobRunner.RunnerState.Running, 0, 2);
            CheckExpectedNotification(progressRecorder.Notifications[1], CancellableJobRunner.RunnerState.Faulted, 0, 2);
        }
Example #9
0
        private static void WaitForRunnerToFinish(CancellableJobRunner runner, ILogger logger)
        {
            int  timeout   = System.Diagnostics.Debugger.IsAttached ? 20000 : 3000;
            bool signalled = false;

            try
            {
                signalled = runner.TestingWaitHandle?.WaitOne(timeout) ?? false;
                if (signalled)
                {
                    logger.WriteLine("[Test] In WaitForRunnerToFinish. Event was signalled.");
                }
                else
                {
                    logger.WriteLine("[Test] In WaitForRunnerToFinish: Event was not signalled.");
                }
            }
            catch (ObjectDisposedException)
            {
                // If the runner has finished then the token source will have been disposed
                logger.WriteLine("[Test] In WaitForRunnerToFinish: Caught ObjectDisposedException.");
            }
        }