Episodes

You can now create a task that will run an episode of work in the workflow. An episode is simply a pulse of work that the workflow runs.
For example an episode might look like the following

Thread Action
host Run the workflow
host Wait for idle
Workflow Activity 1
Workflow Activity 2 (creates a bookmark)
Workflow Invoke Idle delegate - host sets event
host episode complete


Episodes can end in the following ways as defined by the new EpisodeEndedWith enum

Enum Description
Timeout The episode did not end within the timeout
Aborted The episode aborted due to an unhandled exception
Completed The episode ended when the workflow completed
Idle The episode ended when the workflow became idle

Should Idle end an episode?

Ending an episode on idle is tricky because there are some idle events that you might not want to end a workflow. For example async activities such as the Delay activity will cause the workflow to idle. If you are testing a workflow and you want test what happens after the delay you don't want the idle to end the episode. In other cases you might want to wait the second or third idle or for an idle where there is at least one bookmark.

The Async Episode methods offer overloads that allow you to control how an episode ends.

Option Description
Default An episode ends when completed or aborted
Idle Count An episode ends when the specified idle count occurs
Func<WorkflowApplicationTest, bool> You provide a function that will be invoked when idle is detected allowing you to determine if the episode should end. The function receives the active WorkflowApplicationTest object which has captured all the event arguments and tracking data as well as the last known bookmark count to help you make your decision

Async Methods

Method Description
WorkflowApplicationTest.ResumeBookmarkAsync returns a Task that will resume a bookmark to run an episode of work.
WorkflowApplicationTest.RunAsync returns a Task that will run an episode of work.


Examples

Use the default to run until complete or abort
/// <summary>
/// Verifies that an episode ended with abort
/// </summary>
[TestMethod]
public void EpisodeShouldEndInAbort()
{
    // Arrange
    var host = WorkflowApplicationTest.Create(GetSequenceThatAbortsAfterAsync());

    // Act
    try
    {
        // Run the activity until it aborts, the activity will go idle once 
        // because of the TestAsync activity.
        Assert.AreEqual(EpisodeEndedWith.Aborted, host.RunAsync().Result.EpisodeResult);
    }
    finally
    {
        // Track the tracking records to the test results
        host.Tracking.Trace();
    }
}


Use the idleCount to run until n number of idle events
/// <summary>
/// Verifies that an episode of work ended with an idle event
/// </summary>
[TestMethod]
public void EpisodeShouldRunToIdleAndThenToCompletedAfterResumeBookmark()
{
    // Arrange
    var host =
        WorkflowApplicationTest.Create(
            new Sequence
                {
                    Activities = 
                    {
                        new WriteLine(), new TestBookmark<int> { BookmarkName = "Bookmark1" } 
                    }
                });

    try
    {
        // Act
        // Run the activity to the first idle
        Assert.AreEqual(EpisodeEndedWith.Idle, host.TestActivityAsync(1).Result.EpisodeResult);

        // Resume the bookmark and run the activity to completion
        Assert.AreEqual(EpisodeEndedWith.Completed, host.ResumeBookmarkAsync("Bookmark1").Result.EpisodeResult);
    }
    finally
    {
        host.Tracking.Trace();
    }
}

Use the Func<WorkflowApplicationTes, bool> method to run a workflow until an idle with at least 1 bookmark
/// <summary>
/// Verifies that an episode of work idles, then resumes to completion
/// </summary>
[TestMethod]
public void EpisodeShouldRunToIdleAndThenToCompletedAfterResumeBookmark()
{
    // Arrange
    var host =
        WorkflowApplicationTest.Create(
            new Sequence
                {
                    Activities = 
                    {
                        new WriteLine(), new TestBookmark<int> { BookmarkName = "Bookmark1" } 
                    }
                });

    try
    {
        // Act
        // Run the activity to the first idle
        Assert.AreEqual(EpisodeEndedWith.Idle, host.TestActivityAsync(1).Result.EpisodeResult);

        // Resume the bookmark and run the activity to completion
        Assert.AreEqual(EpisodeEndedWith.Completed, host.ResumeBookmarkAsync("Bookmark1").Result.EpisodeResult);
    }
    finally
    {
        host.Tracking.Trace();
    }
}

Last edited Dec 27, 2010 at 7:34 PM by ronjacobs, version 6

Comments

No comments yet.