/// <summary> /// invokes the sub check /// </summary> /// <param name="oneBasedIndex">1-based index into the check run object</param> /// <param name="currentStep">current step</param> public void CallSubCheck(int oneBasedIndex, XElement currentStep) { int subCheckCount = this.SubCheckCount; if (oneBasedIndex > SubCheckCount) { throw new CheckInfrastructureClientException(string.Format("CallSubCheck invoked with 1-based index='{0}', but the total number of subChecks is '{1}'. This might be due to a mismatch between the XML driving the check and the check method call of a sub-check.", oneBasedIndex, subCheckCount)); } CheckRunTransforms checkRunTransforms = new CheckRunTransforms(); XDocument subCheckCrl = checkRunTransforms.CreateSubCheckRunLaunch(this.m_BaseElementForSection.Document, this.GetSubCheck(oneBasedIndex), currentStep); XDocument artifactFromSubCheck = null; if (this.m_RunSubCheckDelegate != null) { artifactFromSubCheck = this.m_RunSubCheckDelegate(subCheckCrl); } else { throw new CheckInfrastructureClientException("The subcheck delegate is not set, so cannot be invoked for subcheck."); } XElement rootOfSubsteps = artifactFromSubCheck.Root.Element(DataStringConstants.ElementNames.CompleteCheckStepInfo); // remove child steps from current step as needed XElement rootStepFromSubCheck = rootOfSubsteps.Elements(DataStringConstants.ElementNames.CheckStepInformation).First <XElement>(); if (rootStepFromSubCheck != null) { string subCheckRootStepName = rootStepFromSubCheck.Attribute(DataStringConstants.AttributeNames.Name).Value; XElement tempCurrentStep = ChildSteps.CleanStepsOnSearchForCorrectChildStep(currentStep, subCheckRootStepName); if (tempCurrentStep == null) { ChildSteps.AddChildStep(currentStep, rootStepFromSubCheck); } else { ChildSteps.ReplaceChildStep(tempCurrentStep, rootStepFromSubCheck); } } // Copy over the subcheck exception informaiton, and throw if needed XElement checkFailDataFromSubCheck = artifactFromSubCheck.Root.Element(DataStringConstants.ElementNames.CheckFailData); if (checkFailDataFromSubCheck.HasElements) { XElement failDataRoot = currentStep.Document.Root.Element(DataStringConstants.ElementNames.CheckFailData); XElement subCheckRoot = new XElement(DataStringConstants.ElementNames.DataElement, new XAttribute(DataStringConstants.AttributeNames.Name, CheckConstants.AttributeValues.SubCheckExceptions)); failDataRoot.Add(subCheckRoot); // the subcheck failed, so insert the element before CompleteCheckStepInfo = CheckConstants.Strings.CheckStepRootInfo. // At this time, this is the only failure info in the current process context foreach (XElement el in checkFailDataFromSubCheck.Elements()) { subCheckRoot.Add(el); } throw new CheckFailException("The subcheck failed, so rethrowing here to fail the check."); } }
/// <summary> /// Moves the step recorder currency to the new location on the XML hiearchy /// that traces the hierarchical steps for execution record of this check, and creates a new /// XElement for this if needed. /// </summary> /// <param name="stepName"></param> /// <param name="msTimeLimit">out parameter of timeout read from XML, or default of 30000ms</param> /// <returns>debug fail is required before step begin</returns> public bool BeginStep(string stepName, out uint msTimeLimit) { msTimeLimit = DataStringConstants.NumericConstants.DefaultTimeoutMilliseconds; bool debugFailRequired = false; // Check for a pre-existing step that maps to this one. If there isn't an existing step with the correct name, // then create one. lock (m_lockObjectForStepRecords) { bool correctStepFound = false; if ((m_currentStep != null) && (m_currentStep.Attribute(DataStringConstants.AttributeNames.Name) != null) && (m_currentStep.Attribute(DataStringConstants.AttributeNames.Name).Value == stepName)) { // easy case: the current step is the correct step. correctStepFound = true; } else { XElement tempStep = ChildSteps.CleanStepsOnSearchForCorrectChildStep(m_currentStep, stepName); if (tempStep != null) { m_currentStep = tempStep; correctStepFound = true; } } // if available, read the timeout from the step if (correctStepFound) { XAttribute timeLimitAttribute = m_currentStep.Attribute(DataStringConstants.AttributeNames.TimeLimit); if (timeLimitAttribute != null) { // XML scheme requires int here, so will fit msTimeLimit = uint.Parse(timeLimitAttribute.Value); } } // if the step wasn't found, add it if (!correctStepFound) { // Add the correct step m_currentStep = ChildSteps.AddChildStep(m_currentStep, stepName); // set time limit in ms SetTimeLimitAttribute(m_currentStep, msTimeLimit); } } #if DEBUG XAttribute countDownToFailAttribute = m_currentStep.Attribute(DataStringConstants.AttributeNames.CountDownToFail); XAttribute failCheckStepAttribute = m_currentStep.Attribute(DataStringConstants.AttributeNames.FailCheckStep); if (((countDownToFailAttribute != null) && (countDownToFailAttribute.Value == "0")) || ((failCheckStepAttribute != null) && (failCheckStepAttribute.Value == "true"))) { debugFailRequired = true; } #endif return(debugFailRequired); }