/// <summary> /// Runs a check to completion, or throws an exception /// </summary> /// <param name="checkRunLaunch">The check run launch (CRL) object</param> /// <returns>The check run artifact (CRA)</returns> public XDocument Run(XDocument checkRunLaunch) { // This identifier is used for the named semaphore that synchronizes for the cross-process, cross-machine check run string uniqueLabelForCheckRunSegment = CheckRunDataHandles.CreateIdFromCrxXDocument(checkRunLaunch); string semaphoreServiceSideUser = Environment.UserName; string semaphoreTimeoutString = DataAccessors.GetCheckRunValue(checkRunLaunch, DataStringConstants.NameAttributeValues.SemaphoreTimeoutMilliseconds); int semaphoreTimeoutMS = 0; try { semaphoreTimeoutMS = int.Parse(semaphoreTimeoutString); } catch (Exception ex) { throw new CheckInfrastructureClientException(string.Format("Parse failed for the configured SemaphoreTimeoutMilliseconds string '{0}'. See InnerException", semaphoreTimeoutString), ex); } // Create semaphore with modification rights for the test user Semaphore checkRunSemaphore = MetaAutomationClientStLibrary.Synchronization.CreateAndGetNamedSemaphore(semaphoreServiceSideUser, uniqueLabelForCheckRunSegment); string startResult = m_MetaAutomationLocal.StartCheckRun(checkRunLaunch.ToString()); if (startResult != MetaAutomationBaseStLibrary.DataStringConstants.StatusString.DefaultServiceSuccessMessage) { throw new CheckInfrastructureClientException(string.Format("StartCheckRun failed with error '{0}'", startResult)); } bool receivedSignal = checkRunSemaphore.WaitOne(semaphoreTimeoutMS); string resultString = null; XDocument resultCRA = null; try { if (receivedSignal) { resultString = m_MetaAutomationLocal.GetCheckRunArtifact(uniqueLabelForCheckRunSegment); resultCRA = DataValidation.Instance.ValidateCheckRunArtifactIntoXDocument(resultString); } else { throw new CheckRunException(string.Format("A semaphore waiting on completion of a sub-check timed out at the configured '{0}' milliseconds.", semaphoreTimeoutMS)); } } catch (CheckInfrastructureClientException) { throw; } catch (Exception ex) { string abortMessage = m_MetaAutomationLocal.GetAbortMessage(uniqueLabelForCheckRunSegment); throw new CheckInfrastructureClientException(string.Format("Check run failed with error '{0}'. The abort message is '{1}'. See InnerException.", resultString, abortMessage), ex); } return(resultCRA); }
public string SetCraXDocument(XDocument xDocCra) { string uniqueLabelForCheckRunSegment = CheckRunDataHandles.CreateIdFromCrxXDocument(xDocCra); string truncatedId = CheckRunDataHandles.StripIdOfMachineNames(uniqueLabelForCheckRunSegment); string craFileName = CraFilePrefix + this.FileNameFromTruncatedId(truncatedId); string fullFileNameAndPath = Path.Combine(this.m_CraDirectory, craFileName); xDocCra.Save(fullFileNameAndPath); return(uniqueLabelForCheckRunSegment); }
public string SetCraXDocument(XDocument xDocCra) { string uniqueLabelForCheckRunSegment = CheckRunDataHandles.CreateIdFromCrxXDocument(xDocCra); string truncatedId = CheckRunDataHandles.StripIdOfMachineNames(uniqueLabelForCheckRunSegment); lock (m_CheckRunArtifactLockObject) { m_CRA_XDocuments.Add(truncatedId, xDocCra); } return(uniqueLabelForCheckRunSegment); }
public string SetCrlXDocument(XDocument crlXDoc) { string uniqueLabelForCheckRunSegment = CheckRunDataHandles.CreateIdFromCrxXDocument(crlXDoc); string truncatedId = CheckRunDataHandles.StripIdOfMachineNames(uniqueLabelForCheckRunSegment); lock (m_CheckRunLaunchLockObject) { m_CRL_XDocuments.Add(truncatedId, crlXDoc); } return(uniqueLabelForCheckRunSegment); }
/// <summary> /// Creates a check run launch for a sub-check call, by modifying the XML for the appropriate target check steps, the /// correct check run data, and the sub-check children of the target sub-check to set up for iteration /// </summary> /// <param name="craOriginalCopy">original copy, for reference</param> /// <param name="originalCurrentSubCheck">original current sub-check, for reference</param> /// <param name="originalCurrentStep">original current check step, for reference</param> /// <returns></returns> public XDocument CreateSubCheckRunLaunch(XDocument craOriginalCopy, XElement originalCurrentSubCheck, XElement originalCurrentStep) { // Transform just like creating a CRL for a check, but with these differences: // 1. For step data, only include step data below the current step // 2. For CheckrunData: // overwrite with name/value pairs from the SubCheck // move into place the only include subcheck that is child of current subject and recursive children // 4. transform to preserve all CheckCustomData XDocument craWorkingCopy = new XDocument(craOriginalCopy); // Fix steps string currentStepXPath = GetRootXPathForElementInCRA(originalCurrentStep); XElement workingCopyStepRootElement = craWorkingCopy.Root.Element(DataStringConstants.ElementNames.CompleteCheckStepInfo); // clean steps from working copy workingCopyStepRootElement.RemoveAll(); // copy the relevant part of the step hierarchy from the original to the working copy foreach (XElement childSteps in originalCurrentStep.Elements()) { workingCopyStepRootElement.Add(childSteps); } // Fix CheckRunData settings for the subcheck call... // use xpath from the original check run artifact (CRA) to select the target subcheck in the working copy Xdoc string currentSubCheckXPath = GetRootXPathForElementInCRA(originalCurrentSubCheck); XElement currentSubCheckWorkingCopy = craWorkingCopy.XPathSelectElement(currentSubCheckXPath); // Get the CheckRunData root in the working copy XElement checkRunDataRootWorkingCopy = craWorkingCopy.Root.Element(DataStringConstants.ElementNames.CheckRunData); // Copy data as needed from the subcheck into the current check of the working copy CRA foreach (XElement dataElement in currentSubCheckWorkingCopy.Elements(DataStringConstants.ElementNames.DataElement)) { this.AddSafeDataElement(checkRunDataRootWorkingCopy, dataElement.Attribute(DataStringConstants.AttributeNames.Name).Value, dataElement.Attribute(DataStringConstants.AttributeNames.Value).Value); } // Remove all SubChecks from the CheckRunData XElement // First, make a list, to not disturb the iterator List <XElement> elementsToRemove = new List <XElement>(); foreach (XElement subCheckWorkingCopyElement in checkRunDataRootWorkingCopy.Elements(DataStringConstants.ElementNames.SubCheckData)) { elementsToRemove.Add(subCheckWorkingCopyElement); } // Second, remove the items foreach (XElement elementToRemove in elementsToRemove) { elementToRemove.Remove(); } // re-add all children of the current target subcheck as children of the CheckRunData XElement, // to create the CRA as it will look to the target subecheck foreach (XElement currentSubCheckChildSubCheck in currentSubCheckWorkingCopy.Elements(DataStringConstants.ElementNames.SubCheckData)) { checkRunDataRootWorkingCopy.Add(currentSubCheckChildSubCheck); } // Do the transform to make CRL from CRA XDocument subCheckLaunchXDocumentResult = new XDocument(); using (XmlWriter xmlWriter = subCheckLaunchXDocumentResult.CreateWriter()) { XslCompiledTransform xslTransform = this.CraToSubCrlTransform; xslTransform.Transform(craWorkingCopy.CreateReader(), xmlWriter); } string id = CheckRunDataHandles.CreateIdFromCrxXDocument(subCheckLaunchXDocumentResult); this.AddSafeDataElement( subCheckLaunchXDocumentResult.Root.Element(DataStringConstants.ElementNames.CheckRunData), DataStringConstants.NameAttributeValues.CheckObjectStorageKey, id); DataValidation.Instance.ValidateCheckRunLaunch(subCheckLaunchXDocumentResult); return(subCheckLaunchXDocumentResult); }
/// <summary> /// Runs a check to completion, or throws an exception /// </summary> /// <param name="checkRunLaunch">The check run launch (CRL) object</param> /// <returns>The check run artifact (CRA)</returns> public XDocument Run(XDocument checkRunLaunch) { // Always set the root CheckRunData/DataElement[@Name='OriginMachine'] to value EnvironmentMachineName, // so it's clear on which machine/OS instance the named semaphore is stored string xPathToOriginMachineDataElement = string.Format( "{0}/{1}[@{2}='{3}']", DataStringConstants.ElementNames.CheckRunData, DataStringConstants.ElementNames.DataElement, DataStringConstants.AttributeNames.Name, DataStringConstants.NameAttributeValues.OriginMachine); // skip the null-checks because they are unnecessary; the schema enforces this XElement originMachineElement = checkRunLaunch.Root.XPathSelectElement(xPathToOriginMachineDataElement); XAttribute originAttribute = originMachineElement.Attribute(DataStringConstants.AttributeNames.Value); originAttribute.Value = Environment.MachineName; // This identifier is used for the named semaphore that synchronizes for the cross-process, cross-machine check run string uniqueLabelForCheckRunSegment = CheckRunDataHandles.CreateIdFromCrxXDocument(checkRunLaunch); string semaphoreServiceSideUser = DataAccessors.GetCheckRunValue(checkRunLaunch, DataStringConstants.NameAttributeValues.ThreadPoolUserName); string semaphoreTimeoutString = DataAccessors.GetCheckRunValue(checkRunLaunch, DataStringConstants.NameAttributeValues.SemaphoreTimeOutMilliseconds); int semaphoreTimeoutMS = 0; try { semaphoreTimeoutMS = int.Parse(semaphoreTimeoutString); } catch (Exception ex) { throw new CheckInfrastructureClientException(string.Format("Parse failed for the configured SemaphoreTimeOutMilliseconds string '{0}'. See InnerException", semaphoreTimeoutString), ex); } // Create semaphore with modification rights for the test user Semaphore checkRunSemaphore = MetaAutomationClientMtLibrary.Synchronization.CreateAndGetNamedSemaphore(semaphoreServiceSideUser, uniqueLabelForCheckRunSegment); string startResult = m_MetaAutomationServiceClient.StartCheckRun(checkRunLaunch.ToString()); if (startResult != MetaAutomationBaseMtLibrary.DataStringConstants.StatusString.DefaultServiceSuccessMessage) { throw new CheckInfrastructureClientException(string.Format("StartCheckRun failed with error '{0}'", startResult)); } bool receivedSignal = checkRunSemaphore.WaitOne(semaphoreTimeoutMS); string resultString = null; XDocument resultCRA = null; try { if (receivedSignal) { resultString = m_MetaAutomationServiceClient.GetCheckRunArtifact(uniqueLabelForCheckRunSegment); resultCRA = DataValidation.Instance.ValidateCheckRunArtifactIntoXDocument(resultString); } else { throw new CheckRunException(string.Format("A semaphore waiting on completion of a sub-check timed out at the configured '{0}' milliseconds.", semaphoreTimeoutMS)); } } catch (CheckInfrastructureClientException) { throw; } catch (Exception ex) { string abortMessage = m_MetaAutomationServiceClient.GetAbortMessage(uniqueLabelForCheckRunSegment); throw new CheckInfrastructureClientException(string.Format("Check run failed with error '{0}'. The abort message is '{1}'. See InnerException.", resultString, abortMessage), ex); } return(resultCRA); }
/// <summary> /// This method is ONLY to be used for launching checks, not sub-checks. /// It creates a CheckRunLaunch object from the passed CheckRunArtifact object, the data members supplied, /// and any custom data. /// All custom data from the passed CheckRunArtifact is removed. /// </summary> /// <param name="lastArtifactForThisCheckMethod"></param> /// <returns></returns> public XDocument CreateCheckRunLaunch(XDocument lastArtifactForThisCheckMethod = null) { XDocument crlXDocumentResult = null; if (m_CrlDataElements == null) { throw new CheckInfrastructureClientException("CreateCheckRunLaunch: the DataMember Dictionary is null."); } if (m_CrlDataElements.Count == 0) { throw new CheckInfrastructureClientException("CreateCheckRunLaunch: the DataMember Dictionary has zero entries."); } if (m_CrlDataElements[DataStringConstants.NameAttributeValues.CheckRunGuid] == null) { throw new CheckInfrastructureClientException(string.Format("CreateCheckRunLaunch: the DataMember Dictionary must have a '{0}' entry.", DataStringConstants.NameAttributeValues.CheckRunGuid)); } try { XElement checkRunDataElement = null; if (lastArtifactForThisCheckMethod == null) { crlXDocumentResult = XDocument.Parse(@"<?xml version='1.0' encoding='utf-8'?><CheckRunLaunch><CheckRunData/><CheckCustomData/><CheckFailData/><CompleteCheckStepInfo/></CheckRunLaunch>"); checkRunDataElement = crlXDocumentResult.Root.Element(DataStringConstants.ElementNames.CheckRunData); foreach (KeyValuePair <string, string> nameValuePair in m_CrlDataElements) { // Add the name/value pairs checkRunDataElement.Add( new XElement(DataStringConstants.ElementNames.DataElement, new XAttribute[] { new XAttribute(DataStringConstants.AttributeNames.Name, nameValuePair.Key), new XAttribute(DataStringConstants.AttributeNames.Value, nameValuePair.Value) })); } } else { // Validate CRA DataValidation.Instance.ValidateCheckRunArtifact(lastArtifactForThisCheckMethod); // Transform CRA to CRL CheckRunTransforms checkRunTransforms = new CheckRunTransforms(); crlXDocumentResult = checkRunTransforms.ConvertCheckRunArtifactToCheckRunLaunch(lastArtifactForThisCheckMethod); // Populate or overwrite with the supplied data, and for DataElement elements that are not specified, give them empty-string values // to prevent spurious data passing from the previous CRA to the current CRL checkRunDataElement = crlXDocumentResult.Root.Element(DataStringConstants.ElementNames.CheckRunData); // Iterate through the DataElement elements in doc order var dataElementIterator = checkRunDataElement.Elements(DataStringConstants.ElementNames.DataElement); foreach (XElement dataElement in dataElementIterator) { XAttribute nameAttribute = dataElement.Attribute(DataStringConstants.AttributeNames.Name); XAttribute valueAttribute = dataElement.Attribute(DataStringConstants.AttributeNames.Value); string name = nameAttribute.Value; if (m_CrlDataElements.ContainsKey(name)) { valueAttribute.Value = m_CrlDataElements[name]; } else if ( (nameAttribute.Value == DataStringConstants.NameAttributeValues.CheckBeginTime) || (nameAttribute.Value == DataStringConstants.NameAttributeValues.CheckEndTime) #if DEBUG || (nameAttribute.Value == DataStringConstants.NameAttributeValues.CheckObjectStorageKey) #endif ) { // Begin and end times are special cases, to be cleaned out here valueAttribute.Value = string.Empty; } } } // Initialize Reserved_SubCheckMap in the CRL, for root check and all subchecks this.SetCheckCounters(checkRunDataElement); #if DEBUG this.DecrementCountDownToFail(crlXDocumentResult); #endif #if DEBUG DataValidation.Instance.ValidateCheckRunLaunch(crlXDocumentResult); #endif if ((this.m_CustomDataElements != null) && (this.m_CustomDataElements.Count > 0)) { XElement customDataElement = crlXDocumentResult.Root.Element(DataStringConstants.ElementNames.CheckCustomData); if (customDataElement == null) { checkRunDataElement.AddAfterSelf(new XElement(DataStringConstants.ElementNames.CheckCustomData)); customDataElement = crlXDocumentResult.Root.Element(DataStringConstants.ElementNames.CheckCustomData); } foreach (KeyValuePair <string, string> nameValuePair in m_CustomDataElements) { XElement existingElementForKey = customDataElement.XPathSelectElement( string.Format("{0}[@{1}]", DataStringConstants.ElementNames.DataElement, nameValuePair.Key)); if (existingElementForKey == null) { // Add the name/value pairs customDataElement.Add( new XElement(DataStringConstants.ElementNames.DataElement, new XAttribute[] { new XAttribute(DataStringConstants.AttributeNames.Name, nameValuePair.Key), new XAttribute(DataStringConstants.AttributeNames.Value, nameValuePair.Value) })); } else { // update the value XAttribute valueAttribute = existingElementForKey.Attribute(DataStringConstants.AttributeNames.Value); if (valueAttribute == null) { existingElementForKey.Add(new XAttribute(DataStringConstants.AttributeNames.Value, nameValuePair.Value)); } else { valueAttribute.Value = nameValuePair.Value; } } } } #if DEBUG string id = CheckRunDataHandles.CreateIdFromCrxXDocument(crlXDocumentResult); this.AddSafeDataElement( crlXDocumentResult.Root.Element(DataStringConstants.ElementNames.CheckRunData), DataStringConstants.NameAttributeValues.CheckObjectStorageKey, id); #endif #if DEBUG DataValidation.Instance.ValidateCheckRunLaunch(crlXDocumentResult); #endif } catch (Exception) { throw; } return(crlXDocumentResult); }