Ejemplo n.º 1
0
        private void PackageStatusInfo()
        {
            LocalEventQueue <SequenceStatusInfo> statusQueue = _context.StatusQueue;

            while (!_cancellation.IsCancellationRequested)
            {
                // 标记事件处理flag为阻塞中
                Thread.MemoryBarrier();
                Thread.VolatileWrite(ref _eventProcessFlag, 0);

                SequenceStatusInfo statusInfo = statusQueue.WaitUntilMessageCome();
                // 如果为null,StatusQueue已经停止接收,直接跳出
                if (null == statusInfo)
                {
                    return;
                }
                // 标记事件处理flag为处理中
                Thread.MemoryBarrier();
                Thread.VolatileWrite(ref _eventProcessFlag, 1);

                SendSequenceStatusMessage(statusInfo);

                // 标记事件处理flag为处理结束
                Thread.MemoryBarrier();
                Thread.VolatileWrite(ref _eventProcessFlag, 2);
            }

            // 标记事件处理flag为结束状态
            Thread.MemoryBarrier();
            Thread.VolatileWrite(ref _eventProcessFlag, 3);
        }
Ejemplo n.º 2
0
        protected override void FlowTaskAction()
        {
            SendStartMessage();

            // 打印状态日志
            Context.LogSession.Print(LogLevel.Info, Context.SessionId, $"Start run sequence {_sequenceIndex}.");

            Context.State = RuntimeState.Running;

            SessionTaskEntity sessionTaskEntity = Context.SessionTaskEntity;

            try
            {
                sessionTaskEntity.InvokeSetUp();
                RuntimeState setUpState = sessionTaskEntity.GetSequenceTaskState(CommonConst.SetupIndex);
                // 如果SetUp执行失败,则执行TearDown,且配置所有序列为失败状态,并发送所有序列都失败的信息
                if (CoreUtils.IsFailed(setUpState))
                {
                    // 打印状态日志
                    Context.LogSession.Print(LogLevel.Error, Context.SessionId, "Run setup failed.");
                    for (int i = 0; i < sessionTaskEntity.SequenceCount; i++)
                    {
                        SequenceTaskEntity sequenceTaskEntity = sessionTaskEntity.GetSequenceTaskEntity(i);
                        sequenceTaskEntity.State = RuntimeState.Failed;

                        FailedInfo         failedInfo    = new FailedInfo(Context.I18N.GetStr("SetUpFailed"), FailedType.SetUpFailed);
                        CallStack          sequenceStack = ModuleUtils.GetSequenceStack(i, sequenceTaskEntity.RootCoroutineId);
                        SequenceStatusInfo statusInfo    = new SequenceStatusInfo(i, sequenceStack,
                                                                                  StatusReportType.Failed, setUpState, StepResult.NotAvailable, failedInfo)
                        {
                            ExecutionTime  = DateTime.Now,
                            ExecutionTicks = -1,
                            CoroutineId    = sequenceTaskEntity.RootCoroutineId
                        };
                        Context.StatusQueue.Enqueue(statusInfo);
                    }
                }
                else
                {
                    sessionTaskEntity.InvokeSequence(_sequenceIndex);
                }
            }
            finally
            {
                sessionTaskEntity.InvokeTearDown();

                Context.State = RuntimeState.Over;
                this.Next     = null;

                SendOverMessage();

                // 打印状态日志
                Context.LogSession.Print(LogLevel.Info, Context.SessionId, "Run single sequence over.");
            }
        }
Ejemplo n.º 3
0
        protected void RecordRuntimeStatus()
        {
            SequenceStatusInfo statusInfo = new SequenceStatusInfo(SequenceIndex, this.GetStack(), StatusReportType.Record, RuntimeState.Running, Result)
            {
                ExecutionTime = Actuator.ExecutionTime, ExecutionTicks = Actuator.ExecutionTicks, CoroutineId = this.Coroutine.Id
            };

            // 更新watch变量值
            statusInfo.WatchDatas = Context.VariableMapper.GetKeyVariablesValues(StepData);
            Context.StatusQueue.Enqueue(statusInfo);
        }
Ejemplo n.º 4
0
        private void RecordInvocationError(Exception ex, FailedType failedType)
        {
            FailedInfo         failedInfo = new FailedInfo(ex, failedType);
            SequenceStatusInfo statusInfo = new SequenceStatusInfo(SequenceIndex, this.GetStack(), StatusReportType.Record, RuntimeState.Running, Result, failedInfo)
            {
                ExecutionTime = Actuator.ExecutionTime, ExecutionTicks = Actuator.ExecutionTicks, CoroutineId = this.Coroutine.Id, WatchDatas = Context.VariableMapper.GetKeyVariablesValues(StepData)
            };

            // 一旦失败,需要记录WatchData
            Context.StatusQueue.Enqueue(statusInfo);
            Context.LogSession.Print(LogLevel.Error, Context.SessionId, ex.Message);
        }
Ejemplo n.º 5
0
        public void SetStatusAndSendErrorEvent(StepResult result, FailedInfo failedInfo)
        {
            this.Result = result;
            // 如果发生错误,无论该步骤是否被配置为recordStatus,都需要发送状态信息
            SequenceStatusInfo statusInfo = new SequenceStatusInfo(SequenceIndex, this.GetStack(), StatusReportType.Record, RuntimeState.Running, Result, failedInfo)
            {
                ExecutionTime  = Actuator.ExecutionTime,
                CoroutineId    = Coroutine.Id,
                ExecutionTicks = Actuator.ExecutionTicks
            };

            // 更新watch变量值
            statusInfo.WatchDatas = Context.VariableMapper.GetKeyVariablesValues(StepData);
            Context.StatusQueue.Enqueue(statusInfo);
        }
Ejemplo n.º 6
0
        private void SendSetupFailedEvents(SessionTaskEntity sessionTaskEntity, RuntimeState sequenceState)
        {
            for (int i = 0; i < sessionTaskEntity.SequenceCount; i++)
            {
                SequenceTaskEntity sequenceTaskEntity = sessionTaskEntity.GetSequenceTaskEntity(i);
                sequenceTaskEntity.State = RuntimeState.Failed;

                FailedInfo failedInfo = new FailedInfo(Context.I18N.GetStr("SetUpFailed"),
                                                       FailedType.SetUpFailed);
                CallStack          sequenceStack = ModuleUtils.GetSequenceStack(i, sequenceTaskEntity.RootCoroutineId);
                SequenceStatusInfo statusInfo    = new SequenceStatusInfo(i, sequenceStack,
                                                                          StatusReportType.Failed, sequenceState, StepResult.NotAvailable,
                                                                          failedInfo)
                {
                    ExecutionTime  = DateTime.Now,
                    ExecutionTicks = -1,
                    CoroutineId    = sequenceTaskEntity.RootCoroutineId
                };
                Context.StatusQueue.Enqueue(statusInfo);
            }
        }
Ejemplo n.º 7
0
        protected override void FlowTaskAction()
        {
            SendStartMessage();

            // 打印状态日志
            Context.LogSession.Print(LogLevel.Info, Context.SessionId, "Start test project setup.");

            Context.State = RuntimeState.Running;

            SessionTaskEntity sessionTaskEntity = Context.SessionTaskEntity;

            sessionTaskEntity.InvokeSetUp();
            RuntimeState setUpState = sessionTaskEntity.GetSequenceTaskState(CommonConst.SetupIndex);

            // 如果SetUp执行失败,则执行TearDown,且配置所有序列为失败状态,并发送所有序列都失败的信息
            if (CoreUtils.IsFailed(setUpState))
            {
                // 打印状态日志
                Context.LogSession.Print(LogLevel.Error, Context.SessionId, "Run testproject setup failed.");
                for (int i = 0; i < sessionTaskEntity.SequenceCount; i++)
                {
                    sessionTaskEntity.GetSequenceTaskEntity(i).State = RuntimeState.Failed;

                    FailedInfo         failedInfo = new FailedInfo(Context.I18N.GetStr("SetUpFailed"), FailedType.SetUpFailed);
                    SequenceStatusInfo statusInfo = new SequenceStatusInfo(i, ModuleUtils.GetSequenceStack(i, 0),
                                                                           StatusReportType.Failed, setUpState, StepResult.NotAvailable, failedInfo)
                    {
                        ExecutionTime  = DateTime.Now,
                        ExecutionTicks = -1,
                        CoroutineId    = 0
                    };
                    Context.StatusQueue.Enqueue(statusInfo);
                }

                sessionTaskEntity.InvokeTearDown();
                // 打印状态日志
                Context.LogSession.Print(LogLevel.Info, Context.SessionId, "Teardown execution over.");

                return;
            }

            // 打印状态日志
            Context.LogSession.Print(LogLevel.Info, Context.SessionId, "Testproject setup execution over.");

            this._wakeTimer = new Timer(WakeThreadWhenCtrlMessageCome, null, Constants.WakeTimerInterval,
                                        Constants.WakeTimerInterval);
            _blockEvent.WaitOne();

            if (null == Context.CtrlStartMessage)
            {
                Context.LogSession.Print(LogLevel.Error, Context.SessionId,
                                         "Receive CtrlMessage without RunTearDown parameter.");
            }

            // 打印状态日志
            Context.LogSession.Print(LogLevel.Info, Context.SessionId, "Teardown execution start.");

            sessionTaskEntity.InvokeTearDown();

            // 打印状态日志
            Context.LogSession.Print(LogLevel.Info, Context.SessionId, "Teardown execution over.");

            SendOverMessage();

            Context.State = RuntimeState.Over;
            this.Next     = null;
        }
Ejemplo n.º 8
0
        private void SendSequenceStatusMessage(SequenceStatusInfo statusInfo)
        {
            StatusMessage statusMessage = null;

            switch (statusInfo.ReportType)
            {
            case StatusReportType.Start:
                statusMessage = new StatusMessage(MessageNames.ReportStatusName, _context.State, _context.SessionId)
                {
                    Time = statusInfo.Time, Index = _context.MsgIndex
                };
                statusMessage.InterestedSequence.Add(statusInfo.Sequence);
                statusMessage.Stacks.Add(statusInfo.Stack);
                statusMessage.SequenceStates.Add(RuntimeState.Running);
                statusMessage.Results.Add(statusInfo.Result);
                statusMessage.ExecutionTimes.Add(statusInfo.ExecutionTime);
                statusMessage.ExecutionTicks.Add(statusInfo.ExecutionTicks);
                statusMessage.Coroutines.Add(statusInfo.CoroutineId);
                _transceiver.SendMessage(statusMessage);
                break;

            case StatusReportType.Record:
                statusMessage = new StatusMessage(MessageNames.ReportStatusName, _context.State, _context.SessionId)
                {
                    Time = statusInfo.Time, Index = _context.MsgIndex
                };
                statusMessage.InterestedSequence.Add(statusInfo.Sequence);
                statusMessage.Stacks.Add(statusInfo.Stack);
                statusMessage.SequenceStates.Add(RuntimeState.Running);
                statusMessage.Results.Add(statusInfo.Result);
                statusMessage.WatchData = statusInfo.WatchDatas;
                statusMessage.ExecutionTimes.Add(statusInfo.ExecutionTime);
                statusMessage.ExecutionTicks.Add(statusInfo.ExecutionTicks);
                statusMessage.Coroutines.Add(statusInfo.CoroutineId);
                if (statusInfo.FailedInfo != null)
                {
                    statusMessage.FailedInfo.Add(statusInfo.Sequence, statusInfo.FailedInfo.ToString());
                }
                _transceiver.SendMessage(statusMessage);
                break;

            case StatusReportType.DebugHitted:
                DebugMessage debugMessage = new DebugMessage(MessageNames.BreakPointHitName, _context.SessionId,
                                                             statusInfo.Stack, false)
                {
                    Time  = statusInfo.Time,
                    Index = _context.MsgIndex
                };
                // TODO add watch datas
                _transceiver.SendMessage(debugMessage);
                break;

            case StatusReportType.Failed:
                statusMessage = new StatusMessage(MessageNames.ReportStatusName, _context.State, _context.SessionId)
                {
                    Time = statusInfo.Time, Index = _context.MsgIndex
                };
                statusMessage.InterestedSequence.Add(statusInfo.Sequence);
                statusMessage.Stacks.Add(statusInfo.Stack);
                statusMessage.SequenceStates.Add(RuntimeState.Failed);
                statusMessage.Results.Add(statusInfo.Result);
                statusMessage.WatchData = statusInfo.WatchDatas;
                statusMessage.ExecutionTimes.Add(statusInfo.ExecutionTime);
                statusMessage.ExecutionTicks.Add(statusInfo.ExecutionTicks);
                statusMessage.Coroutines.Add(statusInfo.CoroutineId);
                if (statusInfo.FailedInfo != null)
                {
                    statusMessage.FailedInfo.Add(statusInfo.Sequence, statusInfo.FailedInfo.ToString());
                }
                _transceiver.SendMessage(statusMessage);
                break;

            case StatusReportType.Over:
                statusMessage = new StatusMessage(MessageNames.ReportStatusName, _context.State, _context.SessionId)
                {
                    Time = statusInfo.Time, Index = _context.MsgIndex
                };
                statusMessage.InterestedSequence.Add(statusInfo.Sequence);
                statusMessage.Stacks.Add(statusInfo.Stack);
                statusMessage.SequenceStates.Add(RuntimeState.Success);
                statusMessage.Results.Add(statusInfo.Result);
                statusMessage.WatchData = statusInfo.WatchDatas;
                statusMessage.ExecutionTimes.Add(statusInfo.ExecutionTime);
                statusMessage.ExecutionTicks.Add(statusInfo.ExecutionTicks);
                statusMessage.Coroutines.Add(statusInfo.CoroutineId);
                _transceiver.SendMessage(statusMessage);
                break;

            case StatusReportType.Error:
                statusMessage = new StatusMessage(MessageNames.ReportStatusName, _context.State, _context.SessionId)
                {
                    Time = statusInfo.Time, Index = _context.MsgIndex
                };
                statusMessage.InterestedSequence.Add(statusInfo.Sequence);
                statusMessage.Stacks.Add(statusInfo.Stack);
                statusMessage.SequenceStates.Add(RuntimeState.Error);
                statusMessage.Results.Add(statusInfo.Result);
                statusMessage.WatchData = statusInfo.WatchDatas;
                statusMessage.ExecutionTimes.Add(statusInfo.ExecutionTime);
                statusMessage.ExecutionTicks.Add(statusInfo.ExecutionTicks);
                statusMessage.Coroutines.Add(statusInfo.CoroutineId);
                if (statusInfo.FailedInfo != null)
                {
                    statusMessage.FailedInfo.Add(statusInfo.Sequence, statusInfo.FailedInfo.ToString());
                    statusMessage.ExceptionInfo = null;
                }
                _transceiver.SendMessage(statusMessage);
                break;

            default:
                throw new NotImplementedException();
            }
        }
Ejemplo n.º 9
0
        public void Invoke(bool forceInvoke = false)
        {
            FailedInfo       failedInfo      = null;
            StepResult       lastStepResult  = StepResult.NotAvailable;
            StatusReportType finalReportType = StatusReportType.Failed;

            try
            {
                this.State = RuntimeState.Running;
                SequenceStatusInfo startStatusInfo = new SequenceStatusInfo(Index, _stepEntityRoot.GetStack(),
                                                                            StatusReportType.Start, RuntimeState.Running, StepResult.NotAvailable)
                {
                    ExecutionTime  = DateTime.Now,
                    ExecutionTicks = -1,
                    CoroutineId    = RootCoroutineId
                };
                _context.StatusQueue.Enqueue(startStatusInfo);

                StepTaskEntityBase stepEntity = _stepEntityRoot;
                do
                {
                    stepEntity.Invoke(forceInvoke);
                } while (null != (stepEntity = stepEntity.NextStep));
                SetResultState(out lastStepResult, out finalReportType, out failedInfo);
            }
            catch (TaskFailedException ex)
            {
                // 停止失败的step的计时
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                currentStep?.EndTiming();
                FillFinalExceptionReportInfo(ex, out finalReportType, out lastStepResult, out failedInfo);
                // 如果抛出TargetInvokcationException到当前位置则说明内部没有发送错误事件
                if (null != currentStep && currentStep.Result == StepResult.NotAvailable)
                {
                    currentStep.SetStatusAndSendErrorEvent(lastStepResult, failedInfo);
                }
            }
            catch (TestflowAssertException ex)
            {
                // 停止失败的step的计时
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                currentStep?.EndTiming();
                FillFinalExceptionReportInfo(ex, out finalReportType, out lastStepResult, out failedInfo);
                // 如果抛出TargetInvokcationException到当前位置则说明内部没有发送错误事件
                if (null != currentStep && currentStep.Result == StepResult.NotAvailable)
                {
                    currentStep.SetStatusAndSendErrorEvent(lastStepResult, failedInfo);
                }
            }
            catch (ThreadAbortException ex)
            {
                // 停止失败的step的计时
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                currentStep?.EndTiming();
                FillFinalExceptionReportInfo(ex, out finalReportType, out lastStepResult, out failedInfo);
                // Abort异常不会在内部处理,需要在外部强制抛出
                currentStep?.SetStatusAndSendErrorEvent(lastStepResult, failedInfo);
            }
            catch (TargetInvocationException ex)
            {
                // 停止失败的step的计时
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                currentStep?.EndTiming();
                FillFinalExceptionReportInfo(ex.InnerException, out finalReportType, out lastStepResult, out failedInfo);
                // 如果抛出TargetInvokcationException到当前位置则说明内部没有发送错误事件
                if (null != currentStep && currentStep.Result == StepResult.NotAvailable)
                {
                    currentStep.SetStatusAndSendErrorEvent(lastStepResult, failedInfo);
                }
            }
            catch (TestflowLoopBreakException ex)
            {
                // 停止失败的step的计时
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                currentStep?.EndTiming();
                // 如果包含内部异常,则说明发生了运行时错误,记录错误信息。
                if (null != ex.InnerException)
                {
                    FillFinalExceptionReportInfo(ex.InnerException, out finalReportType, out lastStepResult,
                                                 out failedInfo);
                    // 如果抛出TargetInvokcationException到当前位置则说明内部没有发送错误事件
                    if (null != currentStep && currentStep.BreakIfFailed)
                    {
                        currentStep.SetStatusAndSendErrorEvent(lastStepResult, failedInfo);
                    }
                }
                // 只是流程控制,记录结果信息后退出
                else
                {
                    SetResultState(out lastStepResult, out finalReportType, out failedInfo);
                }
            }
            catch (Exception ex)
            {
                // 停止失败的step的计时
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                currentStep?.EndTiming();
                FillFinalExceptionReportInfo(ex, out finalReportType, out lastStepResult, out failedInfo);
                // 如果抛出Exception到当前位置则说明内部没有发送错误事件
                if (null != currentStep && currentStep.BreakIfFailed)
                {
                    currentStep.SetStatusAndSendErrorEvent(lastStepResult, failedInfo);
                }
            }
            finally
            {
                StepTaskEntityBase currentStep = StepTaskEntityBase.GetCurrentStep(Index, RootCoroutineId);
                // 发送结束事件,包括所有的ReturnData信息
                SequenceStatusInfo overStatusInfo = new SequenceStatusInfo(Index, currentStep.GetStack(),
                                                                           finalReportType, this.State, StepResult.Over, failedInfo)
                {
                    ExecutionTime  = DateTime.Now,
                    CoroutineId    = RootCoroutineId,
                    ExecutionTicks = 0
                };
                overStatusInfo.WatchDatas = _context.VariableMapper.GetReturnDataValues(_sequence);
                this._context.StatusQueue.Enqueue(overStatusInfo);

                _context.VariableMapper.ClearSequenceVariables(_sequence);
                this._stepEntityRoot = null;
                // 将失败步骤职责链以后的step标记为null
                currentStep.NextStep = null;
            }
        }