public void Execute(XmlNode testConfig, Context context) { var configuration = new BizUnitXmlCompareConfiguration(testConfig, context); string foundFilePath = GetFoundFilePath(context, configuration); try { StringBuilder diff; bool comparisonResult = Compare(out diff, configuration.GoalFilePath, foundFilePath, configuration.StringsToSearchAndReplace, configuration.ElementsToExclude, configuration.AttributesToExclude, configuration.IgnoreChildOrder, configuration.IgnoreComments); if (!comparisonResult) { context.LogInfo(string.Format(CultureInfo.CurrentCulture, "This is the diff result: {0}", diff)); throw new ApplicationException(string.Format(CultureInfo.CurrentCulture, "Xml comparison failed between {0} and {1}. This is the diff result: {2}", foundFilePath, configuration.GoalFilePath, diff)); } context.LogInfo("Files are identical."); } finally { if (!string.IsNullOrEmpty(foundFilePath) && configuration.DeleteFile) { File.Delete(foundFilePath); context.LogInfo(string.Format(CultureInfo.CurrentCulture, "Found file ({0}) deleted.", foundFilePath)); } } }
/// <summary> /// TestStepBase.Execute() implementation /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { context.LogInfo("About to wait for {0} milli seconds...", _timeOut.ToString()); Thread.Sleep(_timeOut); context.LogInfo("A delay of {0} milli second has successfully completed.", _timeOut.ToString()); }
/// <summary> /// Execute() /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { context.LogInfo("Using database connection string: {0}", ConnectionString); string sqlQueryToExecute = SQLQuery.GetFormattedSqlQuery(context); // Sleep for delay seconds... if (0 < DelayBeforeCheck) { context.LogInfo("Sleeping for: {0} seconds", DelayBeforeCheck); System.Threading.Thread.Sleep(DelayBeforeCheck*1000); } context.LogInfo("Executing database query: {0}", sqlQueryToExecute); DataSet ds = FillDataSet(ConnectionString, sqlQueryToExecute); if (NumberOfRowsExpected != ds.Tables[0].Rows.Count) { throw new ApplicationException(string.Format("Number of rows expected to be returned by the query does not match the value specified in the teststep. Number of rows the NnumberOfRowsExpected were: {0}, actual: {1}", NumberOfRowsExpected, ds.Tables[0].Rows.Count)); } context.LogInfo("NumberOfRowsExpected: {0}, actual number returned: {1}", NumberOfRowsExpected, ds.Tables[0].Rows.Count); if (0 == NumberOfRowsExpected) { return; } if (0 < DbRowsToValidate.Count) { int rowCount = 0; foreach (var dbRowToValidate in DbRowsToValidate) { context.LogInfo("Validating row number: {0}", rowCount); var resultRow = ds.Tables[0].Rows[rowCount]; ; var cells = dbRowToValidate.Cells; foreach (DbCellToValidate cell in cells) { object dbData = resultRow[cell.ColumnName]; var dbDataStringValue = string.Empty; if (0 == ValidateData(dbData, cell.ExpectedValue, ref dbDataStringValue)) { context.LogInfo("Validation succeeded for field: {0}. Expected value: {1}", cell.ColumnName, dbDataStringValue); } else { throw new Exception(String.Format("Validation failed for field: {0}. Expected value: {1}, actual value: {2}", cell.ColumnName, cell.ExpectedValue, dbDataStringValue)); } } rowCount++; } } }
/// <summary> /// Helper method to read a message from an MQ Series queue /// </summary> /// /// <param name="queueManagerName">The name of the MQ Series queue manager</param> /// <param name="queueName">The name of the MQ Series queue to read from</param> /// <param name="waitDelay">The time to wait for the message to be read from the queue</param> /// <param name="context">The BizUnit context object which holds state and is passed between test steps</param> /// <param name="msgID">[out] the MQ Series message ID</param> /// <returns>String containing the data from the MQ series message</returns> static public string ReadMessage(string queueManagerName, string queueName, int waitDelay, Context context, out byte[] msgID) { MQQueueManager queueManager = null; MQQueue receiveQueue = null; string message = null; try { context.LogInfo("Opening queue manager: \"{0}\"", queueManagerName); queueManager = new MQQueueManager(queueManagerName); context.LogInfo("Opening queue: \"{0}\"", queueName); receiveQueue = queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_FAIL_IF_QUIESCING); MQMessage mqMsg = new MQMessage(); MQGetMessageOptions mqMsgOpts = new MQGetMessageOptions(); mqMsgOpts.WaitInterval = waitDelay*1000; mqMsgOpts.Options = MQC.MQGMO_WAIT; context.LogInfo("Reading message from queue '{0}'.", queueName); receiveQueue.Get(mqMsg,mqMsgOpts); if(mqMsg.Format.CompareTo(MQC.MQFMT_STRING)==0) { mqMsg.Seek(0); message = System.Text.UTF8Encoding.UTF8.GetString(mqMsg.ReadBytes(mqMsg.MessageLength)); msgID = mqMsg.MessageId; } else { throw new NotSupportedException(string.Format("Unsupported message format: '{0}' read from queue: {1}.", mqMsg.Format, queueName)); } } finally { if (receiveQueue != null) { receiveQueue.Close(); } if (queueManager != null) { queueManager.Close(); } } return message; }
internal static string GetFoundFilePath(Context context, BizUnitCompareConfiguration configuration) { VerifyParameters(context, configuration); context.LogInfo(string.Format(CultureInfo.CurrentCulture, "Waiting for file (in: {0}) for {1} seconds.", configuration.SearchDirectory, configuration.Timeout/1000)); DateTime endTime = DateTime.Now.AddMilliseconds(configuration.Timeout).AddMilliseconds(1); bool fileFound = false; string foundFilePath = string.Empty; do { string[] files = Directory.GetFiles(configuration.SearchDirectory, configuration.Filter, SearchOption.TopDirectoryOnly); if (files.Length > 0) { try { string fileData; using (FileStream testFileStream = File.Open(files[0], FileMode.Open, FileAccess.Read, FileShare.Read)) { using (var testFileStreamReader = new StreamReader(testFileStream)) { fileData = testFileStreamReader.ReadToEnd(); } // it might be tempting to try to load the found file into an XmlDocument here, // but the user might have configured replacements which will turn an invalid document into a valid XML. } context.LogInfo(string.Format(CultureInfo.CurrentCulture, "File found: {0}", files[0])); context.LogInfo(fileData); foundFilePath = files[0]; fileFound = true; } catch (IOException) { context.LogWarning("Error while opening found file ({0}) for reading. Will retry continously until timeout expires.", files[0]); } } Thread.Sleep(100); } while (DateTime.Now < endTime && !fileFound); if (!fileFound) { throw new FileNotFoundException(string.Format(CultureInfo.CurrentCulture, "No files found in {0} within the given timeout ({1})", configuration.SearchDirectory, configuration.Timeout)); } return foundFilePath; }
/// <summary> /// TestStepBase.Execute() implementation /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { context.LogInfo("About to create the directory: {0}", DirectoryName); System.IO.Directory.CreateDirectory(DirectoryName); }
public void Execute(XmlNode testConfig, Context context) { var configuration = new BizUnitFlatfileCompareConfiguration(testConfig, context); string foundFilePath = BizUnitCompare.GetFoundFilePath(context, configuration); using (MemoryStream cleanedFoundData = FlatfileCleaner.RemoveExclusions(foundFilePath, configuration.Exclusions)) { using (MemoryStream cleanedGoalData = FlatfileCleaner.RemoveExclusions(configuration.GoalFilePath, configuration.Exclusions)) { // just to be sure. cleanedFoundData.Seek(0, SeekOrigin.Begin); cleanedGoalData.Seek(0, SeekOrigin.Begin); if (cleanedFoundData.Length != cleanedGoalData.Length) { throw new ApplicationException(string.Format(CultureInfo.CurrentCulture, "Flatfile comparison failed (different length) between {0} and {1}.", foundFilePath, configuration.GoalFilePath)); } try { do { int foundByte = cleanedFoundData.ReadByte(); int goalByte = cleanedGoalData.ReadByte(); if (foundByte != goalByte) { throw new ApplicationException(string.Format(CultureInfo.CurrentCulture, "Flatfile comparison failed at offset {2} between {0} and {1}.", foundFilePath, configuration.GoalFilePath, cleanedFoundData.Position - 1)); } } while (!(cleanedFoundData.Position >= cleanedFoundData.Length)); context.LogInfo("Files are identical."); } finally { if (!string.IsNullOrEmpty(foundFilePath) && configuration.DeleteFile) { File.Delete(foundFilePath); context.LogInfo(string.Format(CultureInfo.CurrentCulture, "Found file ({0}) deleted.", foundFilePath)); } } } } }
public override Stream Load(Context context) { var doc = new XmlDocument(); context.LogInfo("Loading file: {0}", FilePath); doc.Load(FilePath); if (null != UpdateXml) { foreach (var xpath in UpdateXml) { context.LogInfo("Selecting node in document, description: {0}, XPath: {1}", xpath.Description, xpath.XPath); XPathNavigator xpn = doc.CreateNavigator(); XPathNavigator node = xpn.SelectSingleNode(xpath.XPath); if (null == node) { context.LogError("XPath expression failed to find node"); throw new ApplicationException(String.Format("Node not found: {0}", xpath.Description)); } if (!string.IsNullOrEmpty(xpath.ContextKey)) { context.LogInfo("Updating XmlNode with value from context key: {0}", xpath.ContextKey); node.SetValue(context.GetValue(xpath.ContextKey)); } else { context.LogInfo("Updating XmlNode with value: {0}", xpath.Value); node.SetValue(xpath.Value); } } } MemoryStream ms = new MemoryStream(); doc.Save(ms); ms.Seek(0, SeekOrigin.Begin); return ms; }
/// <summary> /// Execute() implementation /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { FileStream dstFs = null; Stream srcFs = null; try { context.LogInfo("FileCreateStep about to copy the data from File: {0} to the File: {1}", _sourcePath, _creationPath); srcFs = DataSource.Load(context); dstFs = File.Create(_creationPath); var buff = new byte[BuffSize]; int read = srcFs.Read(buff, 0, BuffSize); while (read > 0) { dstFs.Write(buff, 0, read); read = srcFs.Read(buff, 0, BuffSize); } context.Add(FileCreationPathContextKey, _creationPath, true); } finally { if (null != srcFs) { srcFs.Close(); } if (null != dstFs) { dstFs.Close(); } } }
/// <summary> /// Helper method to write a message to an MQ Series queue /// </summary> /// /// <param name="queueManagerName">The name of the MQ Series queue manager</param> /// <param name="queueName">The name of the MQ Series queue to read from</param> /// <param name="message">The MQ Series queue</param> /// <param name="correlId">The correlation ID to be set on the new message</param> /// <param name="context">The BizUnit context object which holds state and is passed between test steps</param> static public void WriteMessage(string queueManagerName, string queueName, string message, byte[] correlId, Context context) { MQQueueManager queueManager = null; MQQueue sendQueue = null; MQMessage mqMessage; MQPutMessageOptions mqPutMsgOpts; try { context.LogInfo("Opening queue manager: \"{0}\"", queueManagerName); queueManager = new MQQueueManager(queueManagerName); context.LogInfo("Opening queue: '{0}'.", queueName); sendQueue = queueManager.AccessQueue(queueName, MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING ); mqMessage = new MQMessage(); byte[] data = ConvertToBytes(message); mqMessage.Write(data); mqMessage.Format = MQC.MQFMT_STRING; mqPutMsgOpts = new MQPutMessageOptions(); context.LogInfo("Writing {0} byte message to queue '{1}'.", data.Length, queueName); if (correlId != null) { mqMessage.CorrelationId = correlId; } sendQueue.Put( mqMessage, mqPutMsgOpts ); } finally { if (sendQueue != null) { sendQueue.Close(); } if (queueManager != null) { queueManager.Close(); } } }
/// <summary> /// TestStepBase.Execute() implementation /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { Thread.Sleep(Timeout); // Get the list of files in the directory string [] filelist = Directory.GetFiles( DirectoryPath, SearchPattern ); if ( filelist.Length == 0) { // Expecting more than one file throw new ApplicationException( String.Format( "Directory contains no files matching the pattern!" ) ); } // For each file in the file list foreach (string filePath in filelist) { context.LogInfo("FileReadMultipleStep validating file: {0}", filePath); Stream fileData = StreamHelper.LoadFileToStream(filePath, Timeout); context.LogData("File: " + filePath, fileData); fileData.Seek(0, SeekOrigin.Begin); // Check it against the validate steps to see if it matches one of them foreach(var subStep in _subSteps) { try { // Try the validation and catch the exception fileData = subStep.Execute(fileData, context); } catch (Exception ex) { context.LogException(ex); throw; } } if(DeleteFiles) { File.Delete(filePath); } } }
private void ValidateXPathExpressions(XmlDocument doc, Context context) { foreach (XPathDefinition validation in _xPathValidations) { var xpathExp = validation.XPath; var expectedValue = validation.Value; if (null != validation.Description) { context.LogInfo("XPath: {0}", validation.Description); } context.LogInfo("Evaluting XPath {0} equals \"{1}\"", xpathExp, expectedValue); XPathNavigator xpn = doc.CreateNavigator(); object result = xpn.Evaluate(xpathExp); string actualValue = null; if (result.GetType().Name == "XPathSelectionIterator") { var xpi = result as XPathNodeIterator; xpi.MoveNext(); // BUGBUG! actualValue = xpi.Current.ToString(); } else { actualValue = result.ToString(); } if (!string.IsNullOrEmpty(validation.ContextKey)) { context.Add(validation.ContextKey, actualValue); } if (!string.IsNullOrEmpty(expectedValue)) { if (0 != expectedValue.CompareTo(actualValue)) { context.LogError("XPath evaluation failed. Expected:<{0}>. Actual:<{1}>.", expectedValue, actualValue); throw new ApplicationException( string.Format("XmlValidationStep failed, compare {0} != {1}, xpath query used: {2}", expectedValue, actualValue, xpathExp)); } context.LogInfo("XPath evaluation succeeded. Expected:<{0}>. Actual:<{1}>.", expectedValue, actualValue); } } }
/// <summary> /// Helper method to compare two Xml documents from streams /// </summary> /// <param name="s1">Stream containing the 1st Xml document</param> /// <param name="s2">Stream containing the 2nd Xml document</param> /// <param name="context">The BizUnit context object which holds state and is passed between test steps</param> public static void CompareXmlDocs(Stream s1, Stream s2, Context context) { XmlDocument doc = new XmlDocument(); doc.Load(new XmlTextReader(s1)); XmlElement root = doc.DocumentElement; string data1 = root.OuterXml; doc = new XmlDocument(); doc.Load(new XmlTextReader(s2)); root = doc.DocumentElement; string data2 = root.OuterXml; context.LogInfo("About to compare the following Xml documents:\r\nDocument1: {0},\r\nDocument2: {1}", data1, data2); CompareStreams( LoadMemoryStream(data1), LoadMemoryStream(data2) ); }
/// <summary> /// ITestStep.Execute() implementation /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { if (DelayBeforeCheck > 0) { context.LogInfo("Waiting for {0} seconds before checking the event log.", DelayBeforeCheck); System.Threading.Thread.Sleep(DelayBeforeCheck * 1000); } EventLogEntryType entryType = (EventLogEntryType)Enum.Parse(typeof(EventLogEntryType), Type, true); DateTime cutOffTime = context.TestCaseStart; // Note: event log time is always truncated, so the cut off time also need sto be! cutOffTime = cutOffTime.Subtract(new TimeSpan(0, 0, 0, 0, context.TestCaseStart.Millisecond + 1)); bool found = false; using (EventLog log = new EventLog(EventLog, Machine)) { EventLogEntryCollection entries = log.Entries; context.LogInfo("Scanning {0} event log entries from log: '{1}' on machine: '{2}', cutOffTime: '{3}'.", entries.Count, EventLog, Machine, cutOffTime.ToString("HH:mm:ss.fff dd/MM/yyyy")); for (int i = entries.Count - 1; i >= 0; i--) { EventLogEntry entry = entries[i]; if (0 > (DateTime.Compare(entry.TimeGenerated, cutOffTime))) { context.LogInfo("Scanning of event log stopped, event.TimeGenerated: {0}, cutOffTime: {1}", entry.TimeGenerated.ToString("HH:mm:ss.fff dd/MM/yyyy"), cutOffTime.ToString("HH:mm:ss.fff dd/MM/yyyy")); found = false; break; } context.LogInfo("Checking entry, Source: {0}, EntryType: {1}, EventId: {2}", entry.Source, entry.EntryType, entry.InstanceId); // Note: EventId is optional... if (((entry.Source == Source) && (entry.EntryType == entryType)) && (((EventId > 0) && (entry.InstanceId == EventId)) || (EventId == 0))) { foreach (string validationRegex in _validationRegExs) { string matchPattern = validationRegex; Match match = Regex.Match(entry.Message, matchPattern); if (match.Success) { found = true; context.LogInfo("Successfully matched event log entry generated at '{0}'.", entry.TimeGenerated); context.LogData("Event log entry.", entry.Message); break; } found = false; } } if (found) { break; } } } // Check that its ok if (!FailIfFound && !found) { throw new ApplicationException("Failed to find expected event log entry."); } if (FailIfFound && found) { throw new ApplicationException("Found event log entry which should not be present."); } }
/// <summary> /// ITestStep.Execute() implementation /// </summary> /// <param name='context'>The context for the test, this holds state that is passed beteen tests</param> public override void Execute(Context context) { File.Move( _sourcePath, _destinationPath ) ; context.LogInfo( "FileMoveStep has moved file: \"{0}\" to \"{1}\"", _sourcePath, _destinationPath ) ; }