/// <summary> /// Run a single test case. /// Returns the result of the test case, containing the action trace /// </summary> /// <param name="testNr">test case number</param> /// <returns>test result</returns> internal TestResult RunTestCase(int testNr) { Sequence <Action> testCase = Sequence <Action> .EmptySequence; Action /*?*/ o = null; // Requirements metrics Bag <Pair <string, string> > executedRequirements = Bag <Pair <string, string> > .EmptyBag; while ((this.stepsCnt <= 0) || testCase.Count < stepsCnt || (!model.IsInAcceptingState && (maxStepsCnt <= 0 || testCase.Count < maxStepsCnt))) { if (o != null || (IsAsync && !observations.IsEmpty)) { #region there is an implementation action o to be checked if (o == null) { o = observations.Dequeue(); } testCase = testCase.AddLast(o); //record the action in the testCase string failureReason = ""; if (model.IsActionEnabled(o, out failureReason)) //check conformance to the model { model.DoAction(o); o = null; //consume the action } else { return(new TestResult(testNr, Verdict.Failure, failureReason, testCase, executedRequirements)); // Requirements metrics: ", executedRequirements" } #endregion } else { //use only cleanup actions when in cleanup phase Set <Symbol> actionSymbols = (((stepsCnt <= 0) || testCase.Count < stepsCnt) ? this.testerActionSymbols : this.cleanupActionSymbols); //select a tester action that is enabled in the current model state Action testerAction = model.SelectAction(actionSymbols); //if a tester action could be chosen if (testerAction != null) { #region execute the tester action //get the timespan within which calling impl with testerAction must return TimeSpan t = (!internalActionSymbols.Contains(testerAction.Symbol) ? this.testerActionTimeout(model.CurrentState, testerAction) : new TimeSpan()); //do the action in the model model.DoAction(testerAction); // Requirements metrics string actionName = testerAction.Name; foreach (string methodName in LibraryModelProgram.AllModeledRequirements.Keys) { // The methods names don't contain "_Start" // when testerAction.Name == actionName_Start, remove the "_Start" // in order to check it in AllModeledRequirements.Keys if (actionName.Contains("_Start")) { actionName = actionName.Replace("_Start", ""); } // I use 'Contains' to get all the enabled actions as well if (methodName.Contains(actionName)) { foreach (Pair <string, string> req in LibraryModelProgram.AllModeledRequirements[methodName]) { executedRequirements = executedRequirements.Add(req); } } } //record the action in the testCase testCase = testCase.AddLast(testerAction); //call the implementation if the symbol is shared if (!internalActionSymbols.Contains(testerAction.Symbol)) { try { DateTime startAction = DateTime.Now; // Performance metrics o = DoAction(testerAction, t); //if return value is non-null it will be checked next time around // Requirements metrics CalcPerformance(testerAction, startAction); } catch (ConformanceTesterException e) { return(new TestResult(testNr, Verdict.Failure, e.Message, testCase, executedRequirements)); //conformance failure // Requirements : ", executedRequirements" } } #endregion } else { //otherwise, try to get an implementation action if (IsAsync) { //get the Wait action from the model Action w = model.SelectAction(waitActionSet); int obsTimeout = (w == null ? 0 : (int)w[0]); if (w != null) { testCase = testCase.AddLast(w); model.DoAction(w); } if (!observations.TryDequeue(new TimeSpan(0, 0, 0, 0, obsTimeout), out o)) { //if there are no tester actions and no observables but the //model is in accepting state, the test succeeds if (model.IsInAcceptingState) { return(new TestResult(testNr, Verdict.Success, "", testCase, executedRequirements));// Requirements metrics: ", executedRequirements" } else { o = timeoutAction; } } } else { //if there are no tester actions and no observables but the //model is in accepting state, the test succeeds if (model.IsInAcceptingState) { return(new TestResult(testNr, Verdict.Success, "", testCase, executedRequirements));// Requirements metrics: ", executedRequirements" } else { return(new TestResult(testNr, Verdict.Failure, "Run stopped in a non-accepting state", testCase, executedRequirements));// Requirements metrics: ", executedRequirements" } } } } } if (model.IsInAcceptingState) { return(new TestResult(testNr, Verdict.Success, "", testCase, executedRequirements));// Requirements metrics: ", executedRequirements" } else { return(new TestResult(testNr, Verdict.Failure, "Test run did not finish in accepting state", testCase, executedRequirements));// Requirements metrics: ", executedRequirements" } }