示例#1
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);
        }
示例#2
0
        public Test(List <Point3d> expected, List <Point3d> actual, List <string> names, double tolerance)
        {
            ExpectedPoints = expected;
            ActualPoints   = actual;
            Names          = names;
            Tolerance      = tolerance;

            _result     = new List <string>();
            _failedInfo = new List <string>();

            string _failedString;
            bool   _failedCurrent;

            if (ExpectedPoints.Count != ActualPoints.Count || ExpectedPoints.Count != Names.Count)
            {
                throw new ArgumentException("Expected list should match actual and names - check if all three lists have the same number of elements");
            }
            _failed = false;
            for (int i = 0; i < ActualPoints.Count; i++)
            {
                _failedString  = "";
                _failedCurrent = false;
                if (Math.Abs(ExpectedPoints[i].X - ActualPoints[i].X) > Tolerance)
                {
                    _failedString += "Check X coordinate;" + Environment.NewLine;
                    _failedCurrent = true;
                }
                if (Math.Abs(ExpectedPoints[i].Y - ActualPoints[i].Y) > Tolerance)
                {
                    _failedString += "Check Y coordinate;" + Environment.NewLine;
                    _failedCurrent = true;
                }
                if (Math.Abs(ExpectedPoints[i].Z - ActualPoints[i].Z) > Tolerance)
                {
                    _failedString += "Check Z coordinate;" + Environment.NewLine;
                    _failedCurrent = true;
                }
                if (_failedCurrent)
                {
                    Result.Add(Names[i] + ";FAILED");
                    FailedInfo.Add(Names[i]
                                   + Environment.NewLine + "Test Failed: Expected != Actual"
                                   + Environment.NewLine + ExpectedPoints[i] + " != " + ActualPoints[i]
                                   + Environment.NewLine + _failedString);
                    _failed = true;
                }
                else
                {
                    Result.Add(Names[i] + ";OK");
                }
            }
        }
示例#3
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);
        }
        protected override void TaskErrorAction(Exception ex)
        {
            Context.LogSession.Print(LogLevel.Error, CommonConst.PlatformLogSession, "Test Generation failed.");
            TestGenMessage testGenFailMessage = new TestGenMessage(MessageNames.TestGenName, Context.SessionId,
                                                                   CommonConst.PlatformSession, GenerationStatus.Failed)
            {
                Index = Context.MsgIndex
            };

            Context.UplinkMsgProcessor.SendMessage(testGenFailMessage, true);

            // 发送远程运行器生成失败的消息
            RmtGenMessage rmtGenMessage = new RmtGenMessage(MessageNames.UpRmtGenMsgName, Context.SessionId,
                                                            RunnerType.SequenceGroup);

            rmtGenMessage.Params.Add("MsgType", "Failed");
            FailedInfo failedInfo = new FailedInfo(ex, FailedType.TestGenFailed);

            rmtGenMessage.Params.Add("FailedInfo", failedInfo.ToString());
            Context.UplinkMsgProcessor.SendMessage(rmtGenMessage, true);
        }
        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);
            }
        }
示例#6
0
        // 处理事件和消息。完成的工作有:
        // 更新SequenceStateHandle的状态、生成RuntimeStatusData并持久化、序列执行结束后生成SequenceResultData并持久化
        #region 事件消息处理

        public void AbortEventProcess(AbortEventInfo eventInfo)
        {
            // 如果序列已经结束或者当前序列为teardown序列,则不接收abort状态更新
            if (ModuleUtils.IsOver(this.State) || this.SequenceIndex == CommonConst.TeardownIndex)
            {
                return;
            }
            if (eventInfo.IsRequest)
            {
                RefreshCommonStatus(eventInfo, RuntimeState.AbortRequested, StepResult.NotAvailable);
            }
            else
            {
                RefreshCommonStatus(eventInfo, RuntimeState.Abort, StepResult.Abort);
                RefreshExecutionStatus(null, 0);
                FailedInfo failedInfo = new FailedInfo(_stateManageContext.GlobalInfo.I18N.GetStr("UserAbort"), FailedType.Abort);
                UpdateSequenceTestResult(failedInfo, null);
                _eventDispatcher.RaiseEvent(Constants.SequenceOver, eventInfo.Session, _sequenceTestResult);

                WriteRuntimeStatusData(StepResult.Abort, string.Empty, new FailedInfo(eventInfo.FailInfo));
            }
        }
        public override void TaskAbortAction()
        {
            TestGenMessage testGenMessage = new TestGenMessage(MessageNames.TestGenName, Context.SessionId,
                                                               CommonConst.PlatformLogSession, GenerationStatus.Failed)
            {
                Index = Context.MsgIndex
            };

            Context.UplinkMsgProcessor.SendMessage(testGenMessage, true);

            // 发送远程运行器生成失败的消息
            RmtGenMessage rmtGenMessage = new RmtGenMessage(MessageNames.UpRmtGenMsgName, Context.SessionId,
                                                            RunnerType.SequenceGroup);

            rmtGenMessage.Params.Add("MsgType", "Failed");
            FailedInfo failedInfo = new FailedInfo(Context.I18N.GetStr("OperationAborted"), FailedType.Abort);

            rmtGenMessage.Params.Add("FailedInfo", failedInfo.ToString());
            Context.UplinkMsgProcessor.SendMessage(rmtGenMessage, true);

            base.TaskAbortAction();
        }
        private bool HandleControlMessage(ControlMessage message)
        {
            int    session = message.Id;
            string name    = message.Name;

            switch (name)
            {
            case MessageNames.CtrlAbort:
                bool           abortSuccess   = bool.Parse(message.Params["AbortSuccess"]);
                AbortEventInfo abortEventInfo = new AbortEventInfo(session, false, abortSuccess);
                // 如果不包含,说明取消成功
                if (!abortSuccess && message.Params.ContainsKey("Message"))
                {
                    abortEventInfo.FailInfo = message.Params["Message"];
                }
                else
                {
                    abortEventInfo.FailInfo = FailedInfo.GetFailedStr(_globalInfo.I18N.GetStr("UserAbort"),
                                                                      FailedType.Abort);
                }
                _globalInfo.EventQueue.Enqueue(abortEventInfo);
                _testsMaintainer.FreeHost(session);
                // 如果所有的都已经结束,则修改状态机状态
                if (0 == _testsMaintainer.TestContainers.Count)
                {
                    _globalInfo.StateMachine.State = RuntimeState.Abort;
                }
                // 同步释放,每个Session的停止都是同步执行的。
                _abortBlocker?.Free(Constants.AbortState);
                break;

            default:
                throw new InvalidOperationException();
            }
            return(true);
        }
示例#9
0
 public SequenceStatusInfo(int sequence, CallStack stack, StatusReportType type, RuntimeState sequenceState, StepResult result, FailedInfo failedInfo = null)
 {
     this.SequenceState = sequenceState;
     this.Sequence      = sequence;
     this.Stack         = stack;
     this.ReportType    = type;
     this.FailedInfo    = failedInfo;
     this.Time          = DateTime.Now;
     this.Result        = result;
 }
示例#10
0
        private void ProcessQueuedItems(object ignored)
        {
            while (true)
            {
                JobMessage job;
                lock (_jobs)
                {
                    if (_jobs.Count == 0)
                    {
                        _delegateQueuedOrRunning = false;
                        break;
                    }

                    job = _jobs.Dequeue();
                }

                JobUtilExtensions.RunSync(async() =>
                {
                    try
                    {
                        var properies = new Dictionary <string, object>
                        {
                            [JobConstant.LOGGER_SCOPE_JOBID_KEY]    = job.Id,
                            [JobConstant.LOGGER_SCOPE_JOBLOGID_KEY] = job.LogId,
                            [JobConstant.LOGGER_SCOPE_JOBAREA_KEY]  = JobConstant.LOGGER_SCOPE_JOBAREA_VALUE
                        };
                        using (_logger.BeginScope(properies))
                        {
                            var result       = await _sender.Execute(job);
                            job.CallBackCode = result.Code;
                            if (result.Code == JobConstant.HTTP_FAIL_CODE)
                            {
                                _logger.LogError($"执行失败. Id:{job.Id}, Msg: {result.Msg}");
                                job.Reason = result.Msg;
                            }
                            else
                            {
                                job.Reason = result.Content;
                            }
                        }
                        await _sender.CallBack(new List <JobMessage>()
                        {
                            job
                        });
                    }
                    catch (Exception ex)
                    {
                        var failedInfo = new FailedInfo()
                        {
                            ServiceProvider = _serviceProvider,
                            Exception       = ex,
                            Job             = job,
                            Message         = $"执行异常. Id:{job.Id}"
                        };

                        _options?.FailedCallback?.Invoke(failedInfo);
                        _logger.LogError(ex, failedInfo.Message);
                    }
                });
            }
        }
        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;
        }
示例#12
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;
            }
        }