示例#1
0
        public void WaitForState(Guid operationId, StepStateNames targetState, RollbackState targetRollbackState = RollbackState.NotRollingBack)
        {
            StepStateNames currentState  = StepStateNames.IntentSaved;
            RollbackState  rollbackState = RollbackState.NotRollingBack;
            TimeoutHelper  timeoutHelper = new TimeoutHelper(TimeSpan.FromMinutes(3));

            do
            {
                bool callSucceeded = false;
                TestabilityTrace.TraceSource.WriteInfo(MockClient.TraceType, "{0} waiting for state '{1}'", operationId, targetState);
                ActionStateBase state = null;
                try
                {
                    state         = this.messageProcessor.ProcessGetProgressAsync(operationId, FASConstants.DefaultTestTimeout, CancellationToken.None).GetAwaiter().GetResult();
                    callSucceeded = true;
                }
                catch (OperationCanceledException oce)
                {
                    TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Caught {1}", operationId, oce.ToString());
                }
                catch (TransactionFaultedException tfe)
                {
                    TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Caught {1}", operationId, tfe.ToString());
                }
                catch (FabricTransientException fte)
                {
                    TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Caught {1}", operationId, fte.ToString());
                }

                if (callSucceeded)
                {
                    currentState  = state.StateProgress.Peek();
                    rollbackState = state.RollbackState;
                    TestabilityTrace.TraceSource.WriteInfo(MockClient.TraceType, "{0} current state='{1}', rollbackState='{2}'", operationId, currentState, rollbackState);
                }

                Task.Delay(TimeSpan.FromSeconds(5)).Wait();
            }while ((currentState != targetState || rollbackState != targetRollbackState) &&
                    timeoutHelper.GetRemainingTime() > TimeSpan.Zero);

            if ((currentState != targetState) ||
                (rollbackState != targetRollbackState))
            {
                string error = string.Format(
                    CultureInfo.InvariantCulture,
                    "{0} Did not reach expected situation: current state='{1}', expected state='{2}', current rollbackState='{3}', expected rollbackState='{4}'",
                    operationId,
                    currentState,
                    targetState,
                    rollbackState,
                    targetRollbackState);
                TestabilityTrace.TraceSource.WriteError(TraceType, error);
                ReleaseAssert.Failfast(error);
            }

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} reached expected state '{1}' and rollbackState '{2}'", operationId, targetState, targetRollbackState);
        }
示例#2
0
        public async Task RunAsync(FabricClient fc, FabricTestAction action, ActionStateBase actionState, ServiceInternalFaultInfo serviceInternalFaultInfo, CancellationToken cancellationToken)
        {
            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Inside RunAsync of Engine, entering state machine", actionState.OperationId);
            try
            {
                do
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    RollbackState readRollbackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.OuterLoop).ConfigureAwait(false);

                    // For the non-force case we need to cleanup, so that is why there's no break statement in that case.
                    if (readRollbackState == RollbackState.RollingBackForce)
                    {
                        actionState.StateProgress.Push(StepStateNames.Failed);
                        await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);

                        break;
                    }

                    await this.RunStateMachineAsync(fc, action, actionState, serviceInternalFaultInfo, cancellationToken).ConfigureAwait(false);

                    if (actionState.RollbackState == RollbackState.RollingBackAndWillRetryAction)
                    {
                        actionState.ErrorCausingRollback = 0;
                        int pauseTime = this.random.Next(10, 60);
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Pausing for {1} seconds before retrying", actionState.OperationId, pauseTime);

                        // Clear the rollback state so it will go forward when it resumes.
                        actionState.RollbackState = RollbackState.NotRollingBack;
                        await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);

                        await Task.Delay(TimeSpan.FromSeconds(pauseTime), cancellationToken).ConfigureAwait(false);
                    }
                }while (actionState.StateProgress.Peek() != StepStateNames.CompletedSuccessfully &&
                        actionState.StateProgress.Peek() != StepStateNames.Failed);
            }
            catch (FabricNotPrimaryException notPrimary)
            {
                FaultAnalysisServiceUtility.TraceFabricNotPrimary(actionState.OperationId, notPrimary);
            }
            catch (FabricObjectClosedException objectClosed)
            {
                FaultAnalysisServiceUtility.TraceFabricObjectClosed(actionState.OperationId, objectClosed);
            }
            catch (Exception e)
            {
                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} caught exception - {1}", actionState.OperationId, e);
                throw;
            }

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Exiting state machine", actionState.OperationId);
        }
示例#3
0
        public async Task UpdateActionStateInnerAsync(ActionStateBase actionState, bool wasCalledFromCancelApiPath)
        {
            if (!wasCalledFromCancelApiPath)
            {
                // This is from an engine update.  In this case it needs to check to see if the user called the cancel api before writing.  That call inside overwrite the flag, but does not persist
                RollbackState readRollBackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, CancellationToken.None, string.Empty).ConfigureAwait(false);

                if (readRollBackState == RollbackState.RollingBackDueToUserCancel ||
                    readRollBackState == RollbackState.RollingBackForce)
                {
                    actionState.RollbackState = readRollBackState;
                }
            }

            await this.PersistAsync(actionState).ConfigureAwait(false);
        }
示例#4
0
        private static bool MatchesStateFilter(ActionStateBase actionState, TestCommandStateFilter filter)
        {
            if (filter == TestCommandStateFilter.All)
            {
                return(true);
            }

            if (filter == TestCommandStateFilter.Default)
            {
                // future use
                return(true);
            }

            StepStateNames stateName     = actionState.StateProgress.Peek();
            RollbackState  rollbackState = actionState.RollbackState;

            if (filter.HasFlag(TestCommandStateFilter.RollingBack))
            {
                if ((rollbackState == RollbackState.RollingBackAndWillFailAction ||
                     rollbackState == RollbackState.RollingBackForce ||
                     rollbackState == RollbackState.RollingBackDueToUserCancel)
                    &&
                    (stateName != StepStateNames.Failed))
                {
                    return(true);
                }
            }

            if (filter.HasFlag(TestCommandStateFilter.Cancelled))
            {
                // stateName == CompletedSuccessfully is possible if the command was in its last step, and finished the last step successfully
                // before cancellation status was read.  There is no point in "cancelling" since the point is to stop execution.  Since it completed successfully,
                // that has been achieved.  However, the status should be translated here so it is not confusing to user.
                if ((stateName == StepStateNames.Failed || stateName == StepStateNames.CompletedSuccessfully) &&
                    (rollbackState == RollbackState.RollingBackDueToUserCancel))
                {
                    return(true);
                }
            }

            if (filter.HasFlag(TestCommandStateFilter.ForceCancelled))
            {
                // See notes above in Cancelled section, which also applies here.
                if ((stateName == StepStateNames.Failed || stateName == StepStateNames.CompletedSuccessfully) &&
                    (rollbackState == RollbackState.RollingBackForce))
                {
                    return(true);
                }
            }

            switch (stateName)
            {
            case StepStateNames.IntentSaved:
                return(filter.HasFlag(TestCommandStateFilter.Running));

            case StepStateNames.LookingUpState:
                return(filter.HasFlag(TestCommandStateFilter.Running));

            case StepStateNames.PerformingActions:
                return(filter.HasFlag(TestCommandStateFilter.Running));

            case StepStateNames.CompletedSuccessfully:
                return(filter.HasFlag(TestCommandStateFilter.CompletedSuccessfully));

            case StepStateNames.Failed:
                return(filter.HasFlag(TestCommandStateFilter.Failed));

            default:
                return(false);
            }
        }
示例#5
0
        private async Task CleanupStepAsync(
            FabricClient fabricClient,
            FabricTestAction action,
            ActionStateBase actionState,
            CancellationToken cancellationToken,
            ServiceInternalFaultInfo serviceInternalFaultInfo)
        {
            StepStateNames state = actionState.StateProgress.Peek();

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Cleaning up state={0}, name={1}, key={2}", state, actionState.ActionType, actionState.OperationId);

            StepBase actionUnit = null;

            actionUnit = action.GetStep(fabricClient, actionState, state, cancellationToken);

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Cleaning up {1}", actionState.OperationId, actionUnit.StepName);

            try
            {
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    RollbackState readRollbackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.InnerCleanupLoop).ConfigureAwait(false);

                    if (readRollbackState == RollbackState.RollingBackDueToUserCancel)
                    {
                        // Do nothing, already rolling back
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Inner cleanup loop read RollingBackDueToUserCancel", actionState.OperationId);
                    }
                    else if (readRollbackState == RollbackState.RollingBackForce)
                    {
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Inner cleanup loop read RollingBackForce", actionState.OperationId);
                        break;
                    }

                    try
                    {
                        await actionUnit.CleanupAsync(cancellationToken).ConfigureAwait(false);

                        actionState.StateProgress.Pop();
                        break;
                    }
                    catch (Exception cleanupException)
                    {
                        TestabilityTrace.TraceSource.WriteWarning(
                            TraceType,
                            "{0} - Cleanup of action type={1}, failed with {2}, retrying",
                            actionState.OperationId,
                            actionState.ActionType,
                            cleanupException);
                    }

                    await Task.Delay(TimeSpan.FromSeconds(this.commandStepRetryBackoffInSeconds), cancellationToken).ConfigureAwait(false);
                }
            }
            catch (Exception e)
            {
                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - CleanupStepAsync, error: {1}", actionState.OperationId, e.ToString());
                throw;
            }
        }
示例#6
0
        private async Task RunStepAsync(
            FabricClient fabricClient,
            FabricTestAction action,
            ActionStateBase actionState,
            CancellationToken cancellationToken,
            ServiceInternalFaultInfo serviceInternalFaultInfo)
        {
            StepStateNames state = actionState.StateProgress.Peek();

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "Running state={0}, name={1}, key={2}", state, actionState.ActionType, actionState.OperationId);

            StepBase actionUnit = null;

            actionUnit = action.GetStep(fabricClient, actionState, state, cancellationToken);

            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - Running {1}", actionState.OperationId, actionUnit.StepName);
            try
            {
                while (true)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    RollbackState readRollbackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.InnerForwardLoop).ConfigureAwait(false);

                    TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - readRollbackState={1}", actionState.OperationId, readRollbackState);

                    // If RetryStepWithoutRollingbackOnFailure == true, then don't allow graceful user cancel
                    if (!actionState.RetryStepWithoutRollingBackOnFailure && (readRollbackState == RollbackState.RollingBackDueToUserCancel))
                    {
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - read RollingBackDueToUserCancel breaking from Run loop inside RunStepAsync()", actionState.OperationId);
                        break;
                    }

                    // RollingBackForce always stops execution
                    if (readRollbackState == RollbackState.RollingBackForce)
                    {
                        break;
                    }

                    Exception runException = null;
                    try
                    {
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0}, {1} - calling Step.Run()", actionState.OperationId, actionState.ActionType);
                        ActionStateBase newContext = await actionUnit.RunAsync(cancellationToken, serviceInternalFaultInfo).ConfigureAwait(false);

                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0}, {1} - calling break after run", actionState.OperationId, actionState.ActionType);
                        break;
                    }
                    catch (Exception runExceptionTemp)
                    {
                        runException = runExceptionTemp;
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0}, {1} - runException {2}", actionState.OperationId, actionState.ActionType, runException);
                        if (actionState.RetryStepWithoutRollingBackOnFailure)
                        {
                            // trace and loop.  Should have /backoff/?
                            TestabilityTrace.TraceSource.WriteWarning(
                                TraceType,
                                "{0}, {1} has RetryStepWithoutRollingbackOnFailure set to true, retrying step name='{2}'.  Caught exception: {3}",
                                actionState.OperationId,
                                actionState.ActionType,
                                actionUnit.StepName,
                                runException);

                            this.ProcessRetryStepExceptions(actionState.OperationId, runException);
                        }
                        else
                        {
                            throw;
                        }
                    }

                    if (runException != null)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(this.commandStepRetryBackoffInSeconds), cancellationToken).ConfigureAwait(false);
                    }
                }
            }
            catch (Exception e)
            {
                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - RunState, error: {1}", actionState.OperationId, e.ToString());
                throw;
            }
        }
示例#7
0
        private async Task RunStateMachineAsync(
            FabricClient fabricClient,
            FabricTestAction action,
            ActionStateBase actionState,
            ServiceInternalFaultInfo serviceInternalFaultInfo,
            CancellationToken cancellationToken)
        {
            if (actionState.StateProgress == null || actionState.StateProgress.Count == 0)
            {
                ReleaseAssert.AssertIf(actionState.StateProgress == null || actionState.StateProgress.Count == 0, "ActionProgress should not be null or empty");
            }

            Exception actionError = null;

            if (actionState.RollbackState == RollbackState.NotRollingBack ||
                (actionState.RollbackState != RollbackState.RollingBackForce && actionState.RetryStepWithoutRollingBackOnFailure))
            {
                // TODO: should also include Error
                while (actionState.StateProgress.Peek() != StepStateNames.CompletedSuccessfully)
                {
                    cancellationToken.ThrowIfCancellationRequested();

                    RollbackState readRollbackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.ForwardLoop).ConfigureAwait(false);

                    if ((readRollbackState == RollbackState.RollingBackForce) ||
                        ((readRollbackState == RollbackState.RollingBackDueToUserCancel) && !actionState.RetryStepWithoutRollingBackOnFailure))
                    {
                        break;
                    }

                    try
                    {
                        await this.RunStepAsync(fabricClient, action, actionState, cancellationToken, serviceInternalFaultInfo).ConfigureAwait(false);

                        ActionTest.PerformInternalServiceFaultIfRequested(actionState.OperationId, serviceInternalFaultInfo, actionState, cancellationToken);
                        if (actionState.StateProgress.Peek() == StepStateNames.CompletedSuccessfully)
                        {
                            TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - completed successfully, clearing ErrorCausingRollback", actionState.OperationId);
                            actionState.ErrorCausingRollback = 0;
                        }

                        actionState.TimeStopped = DateTime.UtcNow;
                        await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);
                    }
                    catch (RetrySameStepException)
                    {
                        // Retry the command in the same step - do not rollback or go forward, and do not call ActionStore.UpdateActionStateAsync().
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - threw RetrySameStepException, retrying state {1} ", actionState.StateProgress.Peek());
                    }
                    catch (FabricNotPrimaryException)
                    {
                        throw;
                    }
                    catch (FabricObjectClosedException)
                    {
                        throw;
                    }
                    catch (Exception e)
                    {
                        TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - RunStateMachineAsync caught: {1}", actionState.OperationId, e.ToString());
                        readRollbackState = this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.ForwardLoopExceptionBlock).GetAwaiter().GetResult();

                        // 1st line: if this is a force rollback (RollingBackForce), just exit
                        // 2nd line: if !RetryStepWithoutRollingBackOnFailure and there was a graceful cancel then exit this block and proceed to the rollback code block below.
                        // If RetryStepWithoutRollingBackOnFailure is true, which it is only for the node steps today,  then first call HandleRollback to translate the exception.
                        if ((readRollbackState == RollbackState.RollingBackForce) ||
                            ((readRollbackState == RollbackState.RollingBackDueToUserCancel) && !actionState.RetryStepWithoutRollingBackOnFailure))
                        {
                            break;
                        }
                        else
                        {
                            bool isRetryable = this.HandleRollback(actionState.OperationId, e);
                            if (isRetryable)
                            {
                                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - observed retryable exception, will retry action.  Exception: {1}", actionState.OperationId, e.ToString());
                                actionState.RollbackState = RollbackState.RollingBackAndWillRetryAction;
                            }
                            else
                            {
                                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - observed non-retryable exception.  Exception: {1}", actionState.OperationId, e.ToString());
                                actionState.RollbackState = RollbackState.RollingBackAndWillFailAction;
                            }
                        }

                        actionError = e;
                        break;
                    }
                }
            }

            if (actionState.RollbackState == RollbackState.RollingBackAndWillRetryAction ||
                actionState.RollbackState == RollbackState.RollingBackAndWillFailAction ||
                (actionState.RollbackState == RollbackState.RollingBackDueToUserCancel && (actionState.StateProgress.Peek() != StepStateNames.CompletedSuccessfully)))
            {
                TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Rollingback type={1}", actionState.OperationId, actionState.ActionType);
                if (!this.isTestMode && actionState.StateProgress.Peek() == StepStateNames.CompletedSuccessfully)
                {
                    string error = string.Format(CultureInfo.InvariantCulture, "{0} - state should not be CompletedSuccessfully", actionState.OperationId);
                    TestabilityTrace.TraceSource.WriteError(TraceType, error);
                    ReleaseAssert.Failfast(error);
                }

                // If actionError is not null it means we are currently running a resumed rollback.  In that case the ErrorCausingRollback must have
                // already been set.
                if (actionError != null)
                {
                    actionState.ErrorCausingRollback = TranslateRollbackError(actionError.HResult);
                    TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Translated ErrorCausingRollback ={1}", actionState.OperationId, actionState.ErrorCausingRollback);
                }

                if (this.isTestMode && actionState.StateProgress.Peek() == StepStateNames.CompletedSuccessfully)
                {
                    // In test mode it's intentionally possible to fault an action after it's completed its work, but before the state name has been updated.
                    actionState.StateProgress.Pop();
                }

                await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);

                try
                {
                    while (actionState.StateProgress.Peek() != StepStateNames.IntentSaved &&
                           actionState.StateProgress.Peek() != StepStateNames.Failed)
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        RollbackState readRollbackState = await this.CheckUserCancellationAndUpdateIfNeededAsync(actionState, cancellationToken, FASConstants.OuterCleanupLoop).ConfigureAwait(false);

                        if (readRollbackState == RollbackState.RollingBackDueToUserCancel)
                        {
                            // Do nothing, already rolling back - debug only
                            TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Read RollingBackDueToUserCancel in outer rollback loop", actionState.OperationId);
                        }
                        else if (readRollbackState == RollbackState.RollingBackForce)
                        {
                            TestabilityTrace.TraceSource.WriteWarning(TraceType, "{0} - Read RollingBackForce in outer rollback loop", actionState.OperationId);
                            break;
                        }

                        StepStateNames currentStateName = actionState.StateProgress.Peek();
                        TestabilityTrace.TraceSource.WriteInfo(TraceType, "{0} - DEBUG - Rollback path loop, current state {1}", actionState.OperationId, actionState.StateProgress.Peek());

                        try
                        {
                            await this.CleanupStepAsync(fabricClient, action, actionState, cancellationToken, serviceInternalFaultInfo).ConfigureAwait(false);

                            await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);
                        }
                        catch (FabricNotPrimaryException)
                        {
                            throw;
                        }
                        catch (FabricObjectClosedException)
                        {
                            throw;
                        }
                        catch (Exception e)
                        {
                            ReleaseAssert.Failfast("Unexpected exception, RunStateAsync for cleanup should have handled {0}", e);
                        }
                    }

                    // If this is true rollback is finished.  If it is retryable set the state to LookingUpState
                    if (actionState.StateProgress.Peek() == StepStateNames.IntentSaved)
                    {
                        if (actionState.RollbackState == RollbackState.RollingBackAndWillRetryAction)
                        {
                            actionState.StateProgress.Push(StepStateNames.LookingUpState);
                            actionState.ClearInfo();
                        }
                        else if (actionState.RollbackState == RollbackState.RollingBackAndWillFailAction)
                        {
                            actionState.StateProgress.Push(StepStateNames.Failed);

                            actionState.RollbackState = RollbackState.NotRollingBack;
                            actionState.TimeStopped   = DateTime.UtcNow;
                        }
                        else if (actionState.RollbackState == RollbackState.RollingBackDueToUserCancel)
                        {
                            actionState.StateProgress.Push(StepStateNames.Failed);

                            actionState.TimeStopped = DateTime.UtcNow;
                        }
                        else if (actionState.RollbackState == RollbackState.RollingBackForce)
                        {
                            actionState.StateProgress.Push(StepStateNames.Failed);

                            actionState.TimeStopped = DateTime.UtcNow;
                        }
                        else
                        {
                            string error = string.Format(CultureInfo.InvariantCulture, "{0} - RollbackState == NotRollingBack not expected", actionState.OperationId);
                            ReleaseAssert.Failfast(error);
                        }
                    }
                    else if (actionState.RollbackState == RollbackState.RollingBackForce)
                    {
                        actionState.StateProgress.Push(StepStateNames.Failed);
                        actionState.TimeStopped = DateTime.UtcNow;
                    }
                }
                catch (OperationCanceledException)
                {
                    // This means the cancellation token is set, not that an api call observed an E_ABORT
                    throw;
                }
                catch (FabricNotPrimaryException)
                {
                    throw;
                }
                catch (FabricObjectClosedException)
                {
                    throw;
                }
                catch (Exception e)
                {
                    ReleaseAssert.Failfast("Unexpected exception, RunStateAsync for cleanup should have handled {0}", e);
                }

                TestabilityTrace.TraceSource.WriteInfo(
                    TraceType,
                    "{0} - Action failed, type='{1}', will retry={2}, RollbackState={3}",
                    actionState.OperationId,
                    actionState.ActionType,
                    actionState.RollbackState == RollbackState.RollingBackAndWillRetryAction ? "true" : "false",
                    actionState.RollbackState);

                await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);
            }
            else if (actionState.StateProgress.Peek() == StepStateNames.CompletedSuccessfully)
            {
                // user cancelled, but action/command completed anyways before cancellation was checked.
                TestabilityTrace.TraceSource.WriteInfo(TraceType, "DEBUG {0} - Action type '{1}' completed successfully, not updating again ", actionState.OperationId, actionState.ActionType);
            }
            else if ((actionState.StateProgress.Peek() == StepStateNames.IntentSaved) &&
                     (actionState.RollbackState == RollbackState.RollingBackDueToUserCancel))
            {
                actionState.StateProgress.Push(StepStateNames.Failed);
                actionState.TimeStopped = DateTime.UtcNow;

                await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);
            }
            else if (actionState.RollbackState == RollbackState.RollingBackForce)
            {
                // Note: unlike the case above this does not have a state of IntentSaved as a requirement since a force rollback is an abort and does run the steps in reverse.
                // It is possible for the StateProgress to be CompletedSuccessfully here, since we want to exit as quickly as possible.  In that case, the block 2 blocks above handles it -
                // we do nothing extra, and the command finishes executing.  If the user calls an api for information on this command, we translate the state to ForceCancelled if state is a terminal state
                // and RollbackState is RollingBackForce.  See ActionStore.MatchesStateFilter().
                actionState.TimeStopped = DateTime.UtcNow;
                TestabilityTrace.TraceSource.WriteWarning(TraceType, "Bottom of Engine.RunAsync() - state is={0}, rollbackState={1}", actionState.StateProgress.Peek().ToString(), actionState.RollbackState.ToString());
                actionState.StateProgress.Push(StepStateNames.Failed);
                await this.actionStore.UpdateActionStateAsync(actionState).ConfigureAwait(false);
            }
            else
            {
                string unexpectedError = string.Format(CultureInfo.InvariantCulture, "Unexpected case reached, state is={0}, rollbackState={1}", actionState.StateProgress.Peek().ToString(), actionState.RollbackState.ToString());
                TestabilityTrace.TraceSource.WriteError(TraceType, "{0}", unexpectedError);
                ReleaseAssert.Failfast(unexpectedError);
            }
        }
示例#8
0
 public RollbackStatus(RollbackState state, string failReason = "")
 {
     State = state;
     FailReason = failReason;
 }
示例#9
0
 public RollbackStatus(RollbackState state, string failReason = "")
 {
     State      = state;
     FailReason = failReason;
 }
示例#10
0
        public ServiceInternalFaultInfo(StepStateNames targetStepStateName, ServiceInternalFaultType faultType, RollbackState rollbackState, string location, StepStateNames targetCancelStepStateName)
        {
            // The step in which to do the internal fault (other than user cancel)
            this.TargetStepStateName = targetStepStateName;

            // What type of intentional internal fault to do
            this.FaultType = faultType;

            // The type of user cancel to inject.  See ActionTest.PerformTestUserCancelIfRequested().
            this.RollbackType = rollbackState;

            // The engine location in which to perform the user cancel.  Note, not the same as the step to do it in, which is in TargetCancelStepStateName.
            this.Location = location;

            // The step in which to do user cancellation
            this.TargetCancelStepStateName = targetCancelStepStateName;

            this.CountForThrowThreeTimesFault = 3;
        }
示例#11
0
 public ServiceInternalFaultInfo(StepStateNames targetStepStateName, ServiceInternalFaultType faultType, RollbackState rollbackState, string location)
     : this(targetStepStateName, faultType, rollbackState, location, StepStateNames.None)
 {
 }
        // Translate the current "state" into the state the user sees when calling a query or progress api, from a combination of StateStateNames and RollbackState.
        internal static TestCommandProgressState ConvertState(ActionStateBase action, string callerTraceType)
        {
            StepStateNames state         = action.StateProgress.Peek();
            RollbackState  rollbackState = action.RollbackState;

            TestabilityTrace.TraceSource.WriteInfo(callerTraceType, "ConvertState - state is={0}, rollbackState={1}", state.ToString(), rollbackState.ToString());
            if (state == StepStateNames.CompletedSuccessfully)
            {
                // It's possible to reach CompletedSuccessfully even though the cancel api was called because when
                // a command is running it only checks cancel status in between steps.  Since from the user's point of view cancel means
                // "stop executing", and this has been achieved in this situation, it's ok to return Cancelled or ForceCancelled in the cases below.
                // This will also make the return value match what they expect.
                if (rollbackState == RollbackState.RollingBackForce)
                {
                    return(TestCommandProgressState.ForceCancelled);
                }

                if (rollbackState == RollbackState.RollingBackDueToUserCancel)
                {
                    return(TestCommandProgressState.Cancelled);
                }

                return(TestCommandProgressState.Completed);
            }

            if ((rollbackState == RollbackState.RollingBackAndWillFailAction ||
                 rollbackState == RollbackState.RollingBackForce ||
                 rollbackState == RollbackState.RollingBackDueToUserCancel)
                &&
                state != StepStateNames.Failed)
            {
                return(TestCommandProgressState.RollingBack);
            }

            if (state == StepStateNames.Failed)
            {
                if (rollbackState == RollbackState.RollingBackForce)
                {
                    return(TestCommandProgressState.ForceCancelled);
                }

                if (rollbackState == RollbackState.RollingBackDueToUserCancel)
                {
                    return(TestCommandProgressState.Cancelled);
                }
            }

            switch (state)
            {
            case StepStateNames.IntentSaved:
                return(TestCommandProgressState.Running);

            case StepStateNames.LookingUpState:
                return(TestCommandProgressState.Running);

            case StepStateNames.PerformingActions:
                return(TestCommandProgressState.Running);

            case StepStateNames.CompletedSuccessfully:
                return(TestCommandProgressState.Completed);

            case StepStateNames.Failed:
                return(TestCommandProgressState.Faulted);

            default:
                return(TestCommandProgressState.Invalid);
            }
        }