public void Start_ActionOrchestratorStopping_Throws() { //Arrange var ctsFromTest = new CancellationTokenSource(TimeSpan.FromSeconds(1)); var initialExecution = true; var action = Get.CustomBuilderFor.MockAnarchyAction .ThatIsSchedulable() .ThatExecutesTask(async ctFromOrchestrator => { // the goal of this is to block the action execution on the first call, // this will lead to an active task in _executionInstances that will need cancelling if (initialExecution) { initialExecution = false; await Block.UntilCancelled(ctsFromTest.Token); } }) .Build(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); #pragma warning disable 4014 // explicitly not awaiting here as we need to set separate tasks running that are blocked to trigger test state sut.TriggerOnce(TimeSpan.FromMinutes(1000)); // block the stop action to ensure we have a token that is cancelled but not replaced sut.Stop(); #pragma warning restore 4014 //Act var exception = Assert.Catch(() => sut.Start()); ctsFromTest.Cancel(); //Assert exception.Should().BeOfType <ActionStoppingException>(); }
public async Task StopKillsUnscheduledExecutions() { //Arrange var cts = new CancellationTokenSource(); var ctFromTest = cts.Token; CancellationToken linkedCancellationToken; var action = Get.CustomBuilderFor.MockAnarchyAction .ThatIsSchedulable() .ThatExecutesTask(async ctFromOrchestrator => { linkedCancellationToken = CancellationTokenSource.CreateLinkedTokenSource(ctFromOrchestrator, ctFromTest).Token; await Block.UntilCancelled(linkedCancellationToken); }) .Build(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.TriggerOnce(null); //Act #pragma warning disable CS4014 // Intentionally not awaiting Stop as we want to check the task triggered sut.Stop(); #pragma warning restore CS4014 // We instead wait until our test state is triggered before asserting await Wait.Until(() => linkedCancellationToken.IsCancellationRequested, 1); var stopCancelledTheTask = !ctFromTest.IsCancellationRequested; cts.Cancel(); //Assert Assert.That(stopCancelledTheTask); }
public async Task TriggerOnceSetsIsActiveFalseAfterActionExecutionThrows(int?durationSecs) { //Arrange var triggered = false; var action = Get.CustomBuilderFor.MockAnarchyAction .ThatIsSchedulable() .ThatExecutesTask(ct => { triggered = true; throw new Exception("this shouldn't affect things"); }) .Build(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); var duration = durationSecs.HasValue ? TimeSpan.FromSeconds(durationSecs.Value) : (TimeSpan?)null; //Act sut.TriggerOnce(duration); await Wait.Until(() => triggered, 1); await Wait.Until(() => sut.IsActive == false, 1); //Assert sut.IsActive.Should().BeFalse(); }
public void ForTargetPatternThrowsIfNotValidRegex(string targetPattern) { //Arrange var action = Substitute.For <ICauseAnarchy>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); Action forTargetPattern = () => sut.ForTargetPattern(targetPattern); //Act/Assert forTargetPattern.Should().Throw <InvalidTargetPatternException>(); }
public void Start_SchedulableAndScheduleNotSet_DoesNotSetIsActive() { //Arrange var action = Substitute.For <ICauseScheduledAnarchy>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act Assert.Catch(() => sut.Start()); //Assert sut.IsActive.Should().BeFalse(); }
public void UpdateActionValid_EmptyObjectPayload_DoesNotAlterAction(string payload) { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); //Act sut.UpdateAction(payload); //Assert sut.AnarchyAction.Should().BeEquivalentTo(originalAction); }
public async Task StopSetsIsActive() { //Arrange var action = Substitute.For <ICauseAnarchy>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act await sut.Stop(); //Assert sut.IsActive.Should().BeFalse(); }
public void UpdateActionInvalid_MissingOrNonJsonPayload_DoesNotAlterAction(string payload) { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); //Act Assert.Catch(() => sut.UpdateAction(payload)); //Assert sut.AnarchyAction.Should().Be(originalAction); }
public void UpdateActionInvalid_NullForValueTypePayload_Throws() { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); const string payload = "{ 'ThisIsAnIntegerProperty': null }"; //Act var exception = Assert.Catch(() => sut.UpdateAction(payload)); //Assert exception.Should().BeOfType <InvalidActionPayloadException>(); }
public void UpdateActionInvalid_MissingOrNonJsonPayload_Throws(string payload) { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); //Act var exception = Assert.Catch(() => sut.UpdateAction(payload)); //Assert exception.Should().BeOfType <InvalidActionPayloadException>(); }
public void ForTargetPatternSetsTargetPatternIfNotWhitespace() { //Arrange var action = Substitute.For <ICauseAnarchy>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); var targetPattern = ".*"; //Act sut.ForTargetPattern(targetPattern); //Assert sut.TargetPattern.Should().Be(targetPattern); }
public void UpdateActionValid_SinglePublicPropertyPayload_SetsProperty() { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); const string payload = "{ \"ThisIsAPublicProperty\":\"Bob\" }"; //Act sut.UpdateAction(payload); //Assert ((FakeAnarchyAction)sut.AnarchyAction).ThisIsAPublicProperty.Should().Be("Bob"); }
public void UpdateActionValid_ReadonlyPropertyPayload_DoesNotAlterAction() { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); const string payload = "{ 'Name':'ShouldNotBeSet' }"; //Act sut.UpdateAction(payload); //Assert sut.AnarchyAction.Should().BeEquivalentTo(originalAction); }
public void TriggerOnceCallsActionExecuteAsync(int?durationSecs) { //Arrange var action = (ICauseScheduledAnarchy)Get.CustomBuilderFor.MockAnarchyAction.ThatIsSchedulable().Build(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); var duration = durationSecs.HasValue ? TimeSpan.FromSeconds(durationSecs.Value) : (TimeSpan?)null; //Act sut.TriggerOnce(duration); //Assert action.Received(1).ExecuteAsync(duration, Arg.Any <CancellationToken>()); }
public void AssociateScheduleCannotSetScheduleForUnscheduledAction() { //Arrange var action = Substitute.For <ICauseAnarchy>(); var schedule = new Schedule(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var orchestrator = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act Action sutCall = () => orchestrator.AssociateSchedule(schedule); //Assert sutCall.Should().Throw <UnschedulableActionException>(); }
public void UpdateActionValid_SinglePublicPropertyPayload_DoesNotAlterOtherProperties() { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); const string payload = "{ \"ThisIsAPublicProperty\":\"Bob\" }"; //Act sut.UpdateAction(payload); //Assert sut.AnarchyAction.Should().BeEquivalentTo(originalAction, e => e.Excluding(b => b.ThisIsAPublicProperty)); }
public void AssociateScheduleSetsScheduleCorrectly() { //Arrange var action = Substitute.For <ICauseAnarchy, ICauseScheduledAnarchy>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var schedule = new Schedule(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act sut.AssociateSchedule(schedule); //Assert sut.ExecutionSchedule.Should().BeSameAs(schedule); }
public void Start_SchedulableAndScheduleNotSet_Throws() { //Arrange var action = Substitute.For <ICauseScheduledAnarchy>(); var scheduler = Substitute.For <IScheduler>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory .CreatesSpecifiedScheduler(scheduler) .Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act Action sutCall = () => sut.Start(); //Assert sutCall.Should().Throw <ScheduleMissingException>(); }
public void Start_SchedulableAndScheduleNotSet_DoesNotCallStartSchedule() { //Arrange var action = Substitute.For <ICauseScheduledAnarchy>(); var scheduler = Substitute.For <IScheduler>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory .CreatesSpecifiedScheduler(scheduler) .Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act Assert.Catch(() => sut.Start()); //Assert scheduler.DidNotReceive().StartSchedule(); }
public void Start_NotSchedulable_Throws() { //Arrange var action = Substitute.For <ICauseAnarchy>(); var scheduler = Substitute.For <IScheduler>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory .CreatesSpecifiedScheduler(scheduler) .Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); //Act var exception = Assert.Catch(() => sut.Start()); //Assert exception.Should().BeOfType <UnschedulableActionException>(); }
public async Task HandleRequestHandlesIfTargetPatternMatches() { //Arrange var action = Substitute.For <ICauseAnarchy>(); var context = Get.CustomBuilderFor.MockHttpContext.WithPath("/bob").Build(); var next = Substitute.For <RequestDelegate>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.ForTargetPattern("/bob$"); //Act await sut.HandleRequest(context, next); //Assert await action.Received(1).HandleRequestAsync(context, next, Arg.Any <CancellationToken>());; }
public async Task HandleRequestRejectsAllUrlsIfTargetPatternIsNull(string url) { //Arrange var action = Substitute.For <ICauseAnarchy>(); var context = Get.CustomBuilderFor.MockHttpContext.WithPath(url).Build(); var next = Substitute.For <RequestDelegate>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.ForTargetPattern(null); //Act await sut.HandleRequest(context, next); //Assert await action.DidNotReceive().HandleRequestAsync(context, next, Arg.Any <CancellationToken>());; }
public void Start_SchedulableAndScheduleIsSet_CallsStartSchedule() { //Arrange var action = Substitute.For <ICauseScheduledAnarchy>(); var scheduler = Substitute.For <IScheduler>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory .CreatesSpecifiedScheduler(scheduler) .Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.AssociateSchedule(new Schedule()); //Act sut.Start(); //Assert scheduler.Received(1).StartSchedule(); }
public void UpdateActionValid_MultiplePublicPropertiesPayload_SetsProperties() { //Arrange var originalAction = new FakeAnarchyAction(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); const string payload = "{ \"ThisIsAPublicProperty\":\"Bob\", \"ThisIsAPublicDictionaryProperty\":{\"ThisIsAKey\":\"ThisIsAValue\"} }"; //Act sut.UpdateAction(payload); //Assert var alteredAction = (FakeAnarchyAction)sut.AnarchyAction; alteredAction.ThisIsAPublicProperty.Should().Be("Bob"); alteredAction.ThisIsAPublicDictionaryProperty.Should().BeEquivalentTo(new Dictionary <string, string> { { "ThisIsAKey", "ThisIsAValue" } }); }
public void UpdateActionValid_MultiplePublicPropertiesPayload_DoesNotAlterOtherProperties() { //Arrange var originalAction = new FakeAnarchyAction { ThisIsAnIntegerProperty = 43 }; var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <FakeAnarchyAction>(originalAction, schedulerFactory); const string payload = "{ \"ThisIsAPublicProperty\":\"Bob\", \"ThisIsAPublicDictionaryProperty\":{\"ThisIsAKey\":\"ThisIsAValue\"} }"; //Act sut.UpdateAction(payload); //Assert var alteredAction = (FakeAnarchyAction)sut.AnarchyAction; alteredAction.Should().BeEquivalentTo(originalAction, e => e .Excluding(b => b.ThisIsAPublicProperty) .Excluding(b => b.ThisIsAPublicDictionaryProperty)); }
public void Start_ScheduleRunning_Throws() { //Arrange var action = Substitute.For <ICauseScheduledAnarchy>(); var scheduler = Substitute.For <IScheduler>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory .CreatesSpecifiedScheduler(scheduler) .Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.AssociateSchedule(new Schedule()); sut.Start(); scheduler.Running.Returns(true); //Act Action sutCall = () => sut.Start(); //Assert sutCall.Should().Throw <ScheduleRunningException>(); }
public void Start_ScheduleRunning_DoesNotCallStartSchedule() { //Arrange var action = Substitute.For <ICauseScheduledAnarchy>(); var scheduler = Substitute.For <IScheduler>(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory .CreatesSpecifiedScheduler(scheduler) .Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.AssociateSchedule(new Schedule()); sut.Start(); scheduler.Running.Returns(true); scheduler.ClearReceivedCalls(); //Act Assert.Catch(() => sut.Start()); //Assert scheduler.DidNotReceive().StartSchedule(); }
public void TriggerOnceSetsIsActive(int?durationSecs) { //Arrange var cts = new CancellationTokenSource(); var action = Get.CustomBuilderFor.MockAnarchyAction .ThatIsSchedulable() .ThatExecutesTask(async ct => await Block.UntilCancelled(cts.Token)) .Build(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); var duration = durationSecs.HasValue ? TimeSpan.FromSeconds(durationSecs.Value) : (TimeSpan?)null; //Act sut.TriggerOnce(duration); var runningIsActiveState = sut.IsActive; cts.Cancel(); //Assert runningIsActiveState.Should().BeTrue(); }
public void HandleRequestErrorsWhenActionOrchestratorIsStopping() { //Arrange var ctsFromTest = new CancellationTokenSource(TimeSpan.FromSeconds(1)); var next = Substitute.For <RequestDelegate>(); var initialExecution = true; var action = Get.CustomBuilderFor.MockAnarchyAction .ThatHandlesRequestWithTask(async ctFromOrchestrator => { // the goal of this is to block the action execution on the first call, // this will lead to an active task in _executionInstances that will need cancelling if (initialExecution) { initialExecution = false; await Block.UntilCancelled(ctsFromTest.Token); } }) .Build(); var context = Get.CustomBuilderFor.MockHttpContext.WithPath("/bob").Build(); var schedulerFactory = Get.CustomBuilderFor.MockSchedulerFactory.Build(); var sut = new ActionOrchestrator <ICauseAnarchy>(action, schedulerFactory); sut.ForTargetPattern(".*"); #pragma warning disable 4014 // explicitly not awaiting here as we need to set separate tasks running that are blocked to trigger test state sut.HandleRequest(context, next); sut.Stop(); #pragma warning restore 4014 //Act var exception = Assert.CatchAsync(async() => await sut.HandleRequest(context, next)); ctsFromTest.Cancel(); //Assert exception.Should().BeOfType <ActionStoppingException>(); }