public void StateMachineWillIdleWithT1OrT2() { // Arrange WorkflowTestTrace.Arrange(); var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var stateTracker = StateTracker.Attach(host.TestWorkflowApplication); try { // Act WorkflowTestTrace.Act(); host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1); // Assert WorkflowTestTrace.Assert(); Assert.IsTrue(stateTracker.PossibleTransitions.Any(s => s == "T1")); } finally { WorkflowTestTrace.Finally(); host.Tracking.Trace(); } }
/// <summary> /// The create instance and persist. /// </summary> /// <param name="testdb"> /// The test database. /// </param> /// <returns> /// The <see cref="WorkflowApplicationTest"/>. /// </returns> private static WorkflowApplicationTest<StateMachineExample> CreateInstanceAndPersist( SqlWorkflowInstanceStoreTest testdb) { WorkflowTestTrace.Arrange(); var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var instanceStore = SqlWorkflowInstanceStoreManager.CreateInstanceStore( testdb.DatabaseName, testdb.ConnectionString, true); host.InstanceStore = instanceStore; host.PersistableIdle += args => PersistableIdleAction.Unload; var stateTracker = StateTracker.Attach(host.TestWorkflowApplication, instanceStore); // Act host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1); Assert.IsTrue(host.WaitForUnloadedEvent()); return host; }
public void TrackerShouldReportPreviousState() { var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var tracker = new StateMachineStateTracker(activity); Debug.Assert(host != null, "host != null"); Debug.Assert(host.Extensions != null, "host.Extensions != null"); host.Extensions.Add(tracker); try { // Using Microsoft.Activities.Extensions run the workflow until a bookmark named "T1" Assert.IsInstanceOfType( host.TestWorkflowApplication.RunEpisode("T1", Constants.Timeout), typeof(WorkflowIdleEpisodeResult)); WorkflowTrace.Information("First Idle"); tracker.Trace(); Debug.Assert(tracker.TrackedStateMachines != null, "tracker.TrackedStateMachines != null"); Assert.AreEqual(1, tracker.TrackedStateMachines.Count); var stateTrackerInfo = tracker.TrackedStateMachines.Values.ElementAt(0); Debug.Assert(stateTrackerInfo != null, "stateTrackerInfo != null"); Assert.AreEqual(null, stateTrackerInfo.PreviousState); Assert.AreEqual(null, tracker.PreviousState); Assert.AreEqual(tracker.PreviousState, stateTrackerInfo.PreviousState); Debug.Assert(stateTrackerInfo.Transitions != null, "stateTrackerInfo.Transitions != null"); Assert.AreEqual(2, stateTrackerInfo.Transitions.Count); Assert.AreEqual("T1, T2", stateTrackerInfo.PossibleTransitions); // Run until bookmark "T3" Assert.IsInstanceOfType( host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"), typeof(WorkflowIdleEpisodeResult)); WorkflowTrace.Information("Second Idle"); tracker.Trace(); // Use the tracker operations that are forwarded to the current state Debug.Assert(tracker.TrackedStateMachines != null, "tracker.TrackedStateMachines != null"); Assert.AreEqual(1, tracker.TrackedStateMachines.Count); Assert.AreEqual("State1", tracker.PreviousState); Debug.Assert(tracker.Transitions != null, "tracker.Transitions != null"); Assert.AreEqual(2, tracker.Transitions.Count); Assert.AreEqual("T3, T5", tracker.PossibleTransitions); // Resume bookmark T5 and run until complete Assert.IsInstanceOfType( host.TestWorkflowApplication.ResumeEpisodeBookmark("T5", null), typeof(WorkflowCompletedEpisodeResult)); Assert.AreEqual(1, tracker.TrackedStateMachines.Count); } finally { tracker.Trace(); Debug.Assert(host.Tracking != null, "host.Tracking != null"); host.Tracking.Trace(); } }
public void TrackerShouldConvertToAndFromXml() { var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var tracker1 = new StateMachineStateTracker(activity); Debug.Assert(host != null, "host != null"); Debug.Assert(host.Extensions != null, "host.Extensions != null"); host.Extensions.Add(tracker1); try { host.TestWorkflowApplication.RunEpisode("T1", Constants.Timeout); host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"); var xml = tracker1.ToXml(); WorkflowTrace.Information("*** Tracker1***"); WorkflowTrace.Information(xml); WorkflowTrace.Information(Environment.NewLine); var tracker2 = StateMachineStateTracker.Parse(activity, xml); WorkflowTrace.Information("*** Tracker2***"); WorkflowTrace.Information(tracker2.ToXml()); WorkflowTrace.Information(Environment.NewLine); Assert.AreEqual(tracker1.CurrentState, tracker2.CurrentState); Assert.AreEqual(tracker1.CurrentStateMachine, tracker2.CurrentStateMachine); Assert.AreEqual(tracker1.InstanceId, tracker2.InstanceId); Assert.AreEqual(tracker1.PossibleTransitions, tracker2.PossibleTransitions); Assert.AreEqual(tracker1.PreviousState, tracker2.PreviousState); Assert.AreEqual(tracker1.PreviousStateMachine, tracker2.PreviousStateMachine); Assert.AreEqual(tracker1.RootActivity, tracker2.RootActivity); AssertHelper.AreEqual(tracker1.StateHistory, tracker2.StateHistory); AssertHelper.AreEqual(tracker1.Transitions, tracker2.Transitions); } finally { host.Tracking.Trace(); } }
public void TrackerAccumulatesHistoryAcrossLoad() { using (var testdb = new SqlWorkflowInstanceStoreTest()) { // Arrange var triggers = new[] { ExampleTrigger.T1 }; var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); Guid id; StateMachineStateTracker.Attach(host.TestWorkflowApplication, testdb.CreateInstanceStore()); // Act using (host) { try { // Start the workflow and run until it becomes idle with at least one bookmark host.TestWorkflowApplication.RunEpisode(AnyBookmark, Constants.Timeout); // Play each of the triggers foreach (var trigger in triggers) { // Resume the workflow and run until any bookmark host.TestWorkflowApplication.ResumeEpisodeBookmark( trigger.ToString(), Constants.Timeout, AnyBookmark); } host.Persist(Constants.Timeout); host.Unload(Constants.Timeout); id = host.Id; } finally { host.Tracking.Trace(); } } var tracker = StateMachineStateTracker.LoadInstance(id, activity, testdb.ConnectionString); var host2 = WorkflowApplicationTest.Create(activity); StateMachineStateTracker.Attach(host2.TestWorkflowApplication, testdb.InstanceStore, tracker: tracker); host2.Load(id, Constants.Timeout); using (host2) { try { // Resume the workflow and run until any bookmark host2.TestWorkflowApplication.ResumeEpisodeBookmark( ExampleTrigger.T3.ToString(), Constants.Timeout, AnyBookmark); } finally { host.Tracking.Trace(); } } // Assert Assert.IsNotNull(tracker); Assert.AreEqual(3, tracker.StateHistory.Count); } }
public void HistoryIsCircularBuffer() { // Arrange const int MaxHistory = 3; var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); var tracker = new StateMachineStateTracker(activity, MaxHistory); host.Extensions.Add(tracker); try { // Start the workflow - run to State1 with bookmark "T1" host.TestWorkflowApplication.RunEpisode("T1", Constants.Timeout); // History // State1 CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State1" }); // Run until State2 with bookmark "T3" host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"); // History // State1 // State2 CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State1", "State2" }); // Run until State1 with bookmark "T1" host.TestWorkflowApplication.ResumeEpisodeBookmark("T3", null, "T1"); // History // State1 // State2 // State1 CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State1", "State2", "State1" }); // Run until State2 with bookmark "T3" host.TestWorkflowApplication.ResumeEpisodeBookmark("T1", null, "T3"); // History // State1 <- Dropped from buffer // State2 // State1 // State2 Assert.AreEqual(MaxHistory, tracker.StateHistory.Count()); CollectionAssert.AreEqual(tracker.StateHistory.ToList(), new[] { "State2", "State1", "State2" }); } finally { tracker.Trace(); Debug.Assert(host.Tracking != null, "host.Tracking != null"); host.Tracking.Trace(); } }
/// <summary> /// Runs the sample state machine through a number of triggers and leaves a persisted instance /// </summary> /// <param name="testdb"> The test database </param> /// <param name="triggers"> The triggers </param> /// <returns> The workflow instance ID </returns> private Guid RunSampleStateMachine(SqlWorkflowInstanceStoreTest testdb, params ExampleTrigger[] triggers) { var activity = new StateMachineExample(); var host = WorkflowApplicationTest.Create(activity); Debug.Assert(host != null, "host != null"); Debug.Assert(testdb != null, "TestInstanceStore != null"); StateMachineStateTracker.Attach( host.TestWorkflowApplication, new SqlWorkflowInstanceStore(testdb.ConnectionString)); using (host) { try { // Start the workflow and run until it becomes idle with at least one bookmark Assert.IsInstanceOfType( host.TestWorkflowApplication.RunEpisode(AnyBookmark, Constants.Timeout), typeof(WorkflowIdleEpisodeResult)); // Play each of the triggers Debug.Assert(triggers != null, "triggers != null"); foreach (var trigger in triggers) { // Resume the workflow and run until any bookmark host.TestWorkflowApplication.ResumeEpisodeBookmark( trigger.ToString(), Constants.Timeout, AnyBookmark); } host.Persist(Constants.Timeout); host.Unload(Constants.Timeout); } finally { Debug.Assert(host.Tracking != null, "host.Tracking != null"); host.Tracking.Trace(); } } return host.Id; }