public void InstanceStateIsClosedWhenClosed()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark();
                host.TestWorkflowApplication.ResumeUntilBookmark(StateTrigger.T1, 1, StateTrigger.T5);
                host.TestWorkflowApplication.ResumeUntilBookmark(StateTrigger.T5, 1);
                var stateMachineInfo = tracker.StateMachines[0];
                var actual = stateMachineInfo.InstanceState;

                // Assert
                Assert.AreEqual(ActivityInstanceState.Closed, actual);
            }
            catch (Exception exception)
            {
                exception.Trace();
                throw;
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }
        public void CurrentStateWithTwoHostsThrows()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host1 = WorkflowApplicationTest.Create(activity);
            var host2 = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host1.Extensions.Add(tracker);
            host2.Extensions.Add(tracker);

            try
            {
                // Act / Assert
                host1.TestWorkflowApplication.RunUntilBookmark();
                host2.TestWorkflowApplication.RunUntilBookmark();
                host1.TestWorkflowApplication.ResumeUntilBookmark(StateTrigger.T1.ToString(), 1);
                host2.TestWorkflowApplication.ResumeUntilBookmark(StateTrigger.T1.ToString(), 1);

                AssertHelper.Throws<InvalidOperationException>(() => AssertHelper.GetProperty(tracker.CurrentState));
            }
            catch (Exception exception)
            {
                exception.Trace();
                throw;
            }
            finally
            {
                tracker.Trace();
                WorkflowTrace.Information("Host1");
                host1.Tracking.Trace();
                WorkflowTrace.Information("Host2");
                host2.Tracking.Trace();
            }
        }
        public void AttachShouldAttachToApplication()
        {
            var activity = new StateMachineExample();
            Debug.Assert(TestInstanceStore != null, "TestInstanceStore != null");
            var sqlStore = new SqlWorkflowInstanceStore(TestInstanceStore.ConnectionString);

            // Setup the host
            var host = CreateHost(activity, sqlStore);

            // Setup the tracker
            Debug.Assert(host != null, "host != null");

            var tracker = StateTracker.Attach(host.TestWorkflowApplication, sqlStore);

            try
            {
                // Using Microsoft.Activities.Extensions run the workflow until a bookmark named "T1"
                var result = host.TestWorkflowApplication.RunEpisode("T1", TimeSpan.FromSeconds(60));

                Assert.IsInstanceOfType(result, typeof(WorkflowIdleEpisodeResult));
                Assert.IsTrue(host.WaitForUnloadedEvent(Constants.Timeout), "Host did not unload");

                Debug.Assert(result != null, "result != null");
                var instance = StateTracker.LoadInstance(result.InstanceId, TestInstanceStore.ConnectionString);

                Assert.IsNotNull(instance, "Failed to load instance");
                Assert.IsNotNull(tracker);
                Assert.AreEqual(
                    tracker.CurrentState,
                    instance.CurrentState,
                    "State read from database does not match current state from tracker");
            }
            finally
            {
                if (tracker != null)
                {
                    tracker.Trace();
                }

                if (host.Tracking != null)
                {
                    host.Tracking.Trace();
                }
            }
        }
        public void CurrentStateIsState2()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1);

                var actual = tracker.CurrentState;

                // Assert
                Assert.AreEqual(StateMachineExample.State1, actual);
            }
            finally
            {
                tracker.Trace();
                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 StateTrigger[] triggers)
        {
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var sqlWorkflowInstanceStore = new SqlWorkflowInstanceStore(testdb.ConnectionString);
            host.InstanceStore = sqlWorkflowInstanceStore;
            StateTracker.Attach(host.TestWorkflowApplication, sqlWorkflowInstanceStore);

            using (host)
            {
                // Start the workflow and run until it becomes idle with at least one bookmark
                host.TestWorkflowApplication.RunUntilAnyBookmark(Constants.Timeout);

                // Play each of the triggers
                foreach (var trigger in triggers)
                {
                    // Resume the workflow and run until any bookmark
                    host.TestWorkflowApplication.ResumeUntilBookmark(trigger, null, Constants.Timeout);
                }

                host.Unload(Constants.Timeout);
            }

            return host.Id;
        }
        /// <summary>
        /// Creates the workflow application test host
        /// </summary>
        /// <param name="activity">
        /// The activity. 
        /// </param>
        /// <param name="sqlStore">
        /// The sql store. 
        /// </param>
        /// <returns>
        /// A configured host 
        /// </returns>
        private static WorkflowApplicationTest<StateMachineExample> CreateHost(
            StateMachineExample activity, SqlWorkflowInstanceStore sqlStore)
        {
            var host = WorkflowApplicationTest.Create(activity);
            if (sqlStore != null)
            {
                Debug.Assert(host != null, "host != null");
                host.InstanceStore = sqlStore;
            }

            Debug.Assert(host != null, "host != null");
            host.PersistableIdle += args => PersistableIdleAction.Unload;
            return host;
        }
        public void TrackerTracksMoreThanOneInstance()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host1 = WorkflowApplicationTest.Create(activity);
            var host2 = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host1.Extensions.Add(tracker);
            host2.Extensions.Add(tracker);

            try
            {
                // Act / Assert
                host1.TestWorkflowApplication.RunUntilBookmark();
                host2.TestWorkflowApplication.RunUntilBookmark();
                host1.TestWorkflowApplication.ResumeUntilBookmark(StateTrigger.T1.ToString(), 1);
                host2.TestWorkflowApplication.ResumeUntilBookmark(StateTrigger.T1.ToString(), 1);
                Assert.AreEqual(2, tracker.StateMachines.Count);
            }
            catch (Exception exception)
            {
                exception.Trace();
                throw;
            }
            finally
            {
                tracker.Trace();
                WorkflowTrace.Information("Host1");
                host1.Tracking.Trace();
                WorkflowTrace.Information("Host2");
                host2.Tracking.Trace();
            }
        }
        public void ToXmlShouldSerialize()
        {
            const string Expected =
                @"<StateTracker xmlns:i=""http://www.w3.org/2001/XMLSchema-instance"" xmlns=""http://schemas.microsoft.com/2012/07/Microsoft.Activities.Extensions"">
              <StateMachines xmlns:d2p1=""http://schemas.datacontract.org/2004/07/Microsoft.Activities.Extensions.Tracking"">
            <StateMachine>
              <CurrentState>State1</CurrentState>
              <InstanceId>{0}</InstanceId>
              <InstanceState>Executing</InstanceState>
              <MaxHistory>1000</MaxHistory>
              <Name>StateMachine</Name>
              <PossibleTransitions>
            <Transition>T1</Transition>
            <Transition>T2</Transition>
              </PossibleTransitions>
              <PreviousState i:nil=""true"" />
              <StateHistory>
            <State>State1</State>
              </StateHistory>
            </StateMachine>
              </StateMachines>
            </StateTracker>";

            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1);

                var actual = tracker.ToXml();

                // Assert
                Assert.AreEqual(string.Format(Expected, host.Id), actual);
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }
        public void PossibleTransitionsAreTwo()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1);

                var actual = tracker.PossibleTransitions;

                // Assert
                Assert.AreEqual(2, actual.Count);
                Assert.AreEqual(StateTrigger.T1.ToString(), actual.First());
                Assert.AreEqual(StateTrigger.T2.ToString(), actual.Last());
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }
        public void ParseShouldDeserialize()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker1 = new StateTracker();
            StateTracker tracker2 = null;
            host.Extensions.Add(tracker1);

            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1);

                var xml = tracker1.ToXml();
                tracker2 = StateTracker.Parse(xml);

                // Assert
                Assert.AreEqual(tracker1.StateMachines.Count, tracker2.StateMachines.Count);

                for (var i = 0; i < tracker1.StateMachines.Count; i++)
                {
                    AssertEquivalent(tracker1.StateMachines[i], tracker2.StateMachines[i]);
                }
            }
            finally
            {
                tracker1.Trace();
                if (tracker2 != null)
                {
                    tracker2.Trace();
                }

                host.Tracking.Trace();
            }
        }
        public void InstanceStateIsExecutingWhenExecuting()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark();
                var actual = tracker.InstanceState;

                // Assert
                Assert.AreEqual(ActivityInstanceState.Executing, actual);
            }
            catch (Exception exception)
            {
                exception.Trace();
                throw;
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }
        public void InstanceIdIsHostInstanceId()
        {
            // Arrange
            var activity = new StateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1);

                var expected = host.Id;
                var actual = tracker.InstanceId;

                // Assert
                Assert.AreEqual(expected, actual);
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }