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 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();
            }
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="StateTrackerPersistence"/> class.
        /// </summary>
        /// <param name="tracker">
        /// The tracker. 
        /// </param>
        public StateTrackerPersistence(StateTracker tracker)
        {
            Contract.Requires(tracker != null);
            if (tracker == null)
            {
                throw new ArgumentNullException("tracker");
            }

            this.tracker = tracker;
        }
        /// <summary>
        /// Initializes a new instance of the <see cref="StateTrackerPersistence"/> class.
        /// </summary>
        /// <param name="tracker">
        /// The tracker. 
        /// </param>
        /// <param name="instanceStore">
        /// The instance Store. 
        /// </param>
        public StateTrackerPersistence(StateTracker tracker, SqlWorkflowInstanceStore instanceStore)
            : this(tracker)
        {
            Contract.Requires(instanceStore != null);
            if (instanceStore == null)
            {
                throw new ArgumentNullException("instanceStore");
            }

            Promote(instanceStore);
        }
        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>
 ///   Initializes a new instance of the <see cref="WorkflowInstance" /> class.
 /// </summary>
 /// <param name="model"> The view. </param>
 /// <param name="stateTracker"> The StateTracker (optional) </param>
 public WorkflowInstance(WorkflowModel model, StateTracker stateTracker = null)
 {
     this.model = model;
     this.StateTracker = stateTracker ?? new StateTracker();
 }
        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();
            }
        }
        /// <summary>
        /// Attaches a StateTracker to a WorkflowServiceHost
        /// </summary>
        /// <param name="workflowServiceHost">
        /// The host 
        /// </param>
        /// <param name="sqlWorkflowInstanceStore">
        /// The instance store 
        /// </param>
        /// <param name="maxHistory">
        /// The maximum history 
        /// </param>
        /// <returns>
        /// The Microsoft.Activities.Extensions.Tracking.StateTracker. 
        /// </returns>
        public static StateTracker Attach(
            WorkflowServiceHost workflowServiceHost, 
            SqlWorkflowInstanceStore sqlWorkflowInstanceStore, 
            int maxHistory = StateMachineInfo.DefaultMaxHistory)
        {
            Contract.Requires(workflowServiceHost != null);
            if (workflowServiceHost == null)
            {
                throw new ArgumentNullException("workflowServiceHost");
            }

            var stateTracker = new StateTracker(maxHistory);
            workflowServiceHost.WorkflowExtensions.Add(stateTracker);

            if (sqlWorkflowInstanceStore != null)
            {
                if (sqlWorkflowInstanceStore.IsReadOnly())
                {
                    throw new InvalidOperationException("Instance store is read only - cannot promote properties");
                }

                StateTrackerPersistence.Promote(sqlWorkflowInstanceStore);
                var persistence = new StateTrackerPersistence(stateTracker);
                workflowServiceHost.WorkflowExtensions.Add(persistence);
            }

            return stateTracker;
        }
        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 NestedStateMachineIsTracked()
        {
            var activity = new NestedStateMachineExample();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);

            try
            {
                host.TestWorkflowApplication.RunUntilBookmark(StateTrigger.T1, Constants.Timeout);

                // Run until bookmark "NT1" from nested state machine
                host.TestWorkflowApplication.ResumeUntilBookmark("T1", null, "NT1");

                Assert.AreEqual(2, tracker.StateMachines.Count);
            }
            finally
            {
                tracker.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();
            }
        }
        public void InstanceStateIsFaultedWhenFaulted()
        {
            // Arrange
            var activity = StateTrackerTest.CreateStateMachineThatFaults();
            var host = WorkflowApplicationTest.Create(activity);
            var tracker = new StateTracker();
            host.Extensions.Add(tracker);
            try
            {
                // Act
                AssertHelper.Throws<InvalidOperationException>(() => host.TestWorkflowApplication.RunUntilBookmark());
                var stateMachineInfo = tracker.StateMachines[0];
                var actual = stateMachineInfo.InstanceState;

                // Assert
                Assert.AreEqual(ActivityInstanceState.Faulted, actual);
            }
            catch (Exception exception)
            {
                exception.Trace();
                throw;
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }
        public void StateHistoryEnforcesMaxHistory()
        {
            // Arrange
            const int ExpectedHistory = 10;
            var activity = CreateLargeStateMachine(20);
            var host = WorkflowInvokerTest.Create(activity);
            var tracker = new StateTracker(maxHistory: ExpectedHistory);
            host.Extensions.Add(tracker);
            try
            {
                // Act
                host.TestActivity();

                var actual = tracker.StateHistory;

                // Assert
                Assert.AreEqual(ExpectedHistory, actual.Count());
                Assert.AreEqual("State11", actual.First());
                Assert.AreEqual("State20", actual.Last());
            }
            finally
            {
                tracker.Trace();
                host.Tracking.Trace();
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="StateTrackerSurrogated"/> class.
 /// </summary>
 /// <param name="stateTracker">
 /// The state tracker.
 /// </param>
 public StateTrackerSurrogated(StateTracker stateTracker)
 {
     this.StateMachines = new StateMachineList(stateTracker.StateMachines);
 }