public void canceled_transition_reverts_back_to_original_state() { var factory = new StateMachineTaskFactory <State>(); var cancellationTokenSource = new CancellationTokenSource(); factory.RegisterTransition(State.Starting, State.Started, (ct, o) => TaskUtil.FromResult(true)); factory.RegisterTransition(State.Stopping, State.Stopped, (ct, o) => TaskUtil.Delay(TimeSpan.FromSeconds(3), cancellationTokenSource.Token)); factory.StateChanged += (s, e) => { if (e.NewState == State.Stopping) { // cancel the stop cancellationTokenSource.Cancel(); } }; var startedTask = factory.TransitionTo(State.Started); var stoppedTask = factory.TransitionTo(State.Stopped, cancellationTokenSource.Token); startedTask.Wait(TimeSpan.FromSeconds(3)); try { stoppedTask.Wait(TimeSpan.FromSeconds(3)); Assert.True(false, "Failed to throw exception."); } catch (AggregateException ex) { Assert.Equal(1, ex.InnerExceptions.Count); Assert.IsType <OperationCanceledException>(ex.InnerExceptions[0]); Assert.Equal(State.Started, factory.State); } }
public void transition_to_returns_same_task_if_called_multiple_times_whilst_initial_task_is_still_in_progress() { var factory = new StateMachineTaskFactory <State>(); factory.RegisterTransition(State.Starting, State.Started, (ct, o) => TaskUtil.Delay(TimeSpan.FromMilliseconds(250))); var initialTask = factory.TransitionTo(State.Started); Assert.Equal(initialTask, factory.TransitionTo(State.Started)); Assert.Equal(initialTask, factory.TransitionTo(State.Started)); Assert.Equal(initialTask, factory.TransitionTo(State.Started)); Assert.True(initialTask.Wait(TimeSpan.FromSeconds(3))); }
public void transition_to_ensures_previous_transition_is_first_completed_before_starting_subsequent_transition() { var factory = new StateMachineTaskFactory <State>(); factory.RegisterTransition(State.Starting, State.Started, (ct, o) => TaskUtil.Delay(TimeSpan.FromMilliseconds(10))); factory.RegisterTransition(State.Stopping, State.Stopped, (ct, o) => TaskUtil.Delay(TimeSpan.FromMilliseconds(10))); var startedAt = DateTime.MinValue; var stoppedAt = DateTime.MinValue; var startedTask = factory.TransitionTo(State.Started).ContinueWith(x => startedAt = DateTime.UtcNow, TaskContinuationOptions.ExecuteSynchronously); var stoppedTask = factory.TransitionTo(State.Stopped).ContinueWith(x => stoppedAt = DateTime.UtcNow, TaskContinuationOptions.ExecuteSynchronously); Assert.True(Task.WaitAll(new Task[] { startedTask, stoppedTask }, TimeSpan.FromSeconds(3)), "Timed out waiting for tasks to complete."); Assert.True(stoppedAt > startedAt, "stoppedAt is " + stoppedAt.Millisecond + " and startedAt is " + startedAt.Millisecond + ", difference is " + (stoppedAt - startedAt).ToString()); }
public void state_gets_the_current_state() { var factory = new StateMachineTaskFactory <State>(State.Stopped); factory.RegisterTransition(State.Starting, State.Started, (ct, o) => TaskUtil.Delay(TimeSpan.FromMilliseconds(100))); factory.RegisterTransition(State.Stopping, State.Stopped, (ct, o) => TaskUtil.Delay(TimeSpan.FromMilliseconds(100))); var task = factory.TransitionTo(State.Started); Assert.Equal(State.Starting, factory.State); task.Wait(TimeSpan.FromSeconds(3)); Assert.Equal(State.Started, factory.State); task = factory.TransitionTo(State.Stopped); Assert.Equal(State.Stopping, factory.State); task.Wait(TimeSpan.FromSeconds(3)); Assert.Equal(State.Stopped, factory.State); }
public void transition_to_can_be_canceled() { var factory = new StateMachineTaskFactory <State>(); var cancellationTokenSource = new CancellationTokenSource(); factory.RegisterTransition(State.Starting, State.Started, (ct, o) => TaskUtil.FromResult(true)); factory.RegisterTransition(State.Stopping, State.Stopped, (ct, o) => TaskUtil.Delay(TimeSpan.FromMilliseconds(150))); var startedTask = factory.TransitionTo(State.Started, cancellationTokenSource.Token); startedTask.ContinueWith(x => cancellationTokenSource.Cancel()); var stoppedTask = factory.TransitionTo(State.Stopped, cancellationTokenSource.Token); startedTask.Wait(TimeSpan.FromSeconds(3)); try { stoppedTask.Wait(TimeSpan.FromSeconds(3)); Assert.True(false, "Failed to throw exception."); } catch (AggregateException ex) { Assert.Equal(1, ex.InnerExceptions.Count); Assert.IsType <OperationCanceledException>(ex.InnerExceptions[0]); } }