diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs index 6fe81836fc..730c9531d2 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs @@ -282,72 +282,75 @@ public void TestResultHandler(object sender, ObjectModel.Logging.TestResultEvent /// public void TestRunCompleteHandler(object sender, TestRunCompleteEventArgs e) { - if (this.testRun != null) - { - XmlPersistence helper = new XmlPersistence(); - XmlTestStoreParameters parameters = XmlTestStoreParameters.GetParameters(); - XmlElement rootElement = helper.CreateRootElement("TestRun"); + // Create test run + // If abort occurs there is no call to TestResultHandler which results in testRun not created. + // This happens when some test aborts in the first batch of execution. + if (this.testRun == null) + CreateTestRun(); - // Save runId/username/creation time etc. - this.testRun.Finished = DateTime.UtcNow; - helper.SaveSingleFields(rootElement, this.testRun, parameters); + XmlPersistence helper = new XmlPersistence(); + XmlTestStoreParameters parameters = XmlTestStoreParameters.GetParameters(); + XmlElement rootElement = helper.CreateRootElement("TestRun"); - // Save test settings - helper.SaveObject(this.testRun.RunConfiguration, rootElement, "TestSettings", parameters); + // Save runId/username/creation time etc. + this.testRun.Finished = DateTime.UtcNow; + helper.SaveSingleFields(rootElement, this.testRun, parameters); - // Save test results - helper.SaveIEnumerable(this.results.Values, rootElement, "Results", ".", null, parameters); + // Save test settings + helper.SaveObject(this.testRun.RunConfiguration, rootElement, "TestSettings", parameters); - // Save test definitions - helper.SaveIEnumerable(this.testElements.Values, rootElement, "TestDefinitions", ".", null, parameters); + // Save test results + helper.SaveIEnumerable(this.results.Values, rootElement, "Results", ".", null, parameters); - // Save test entries - helper.SaveIEnumerable(this.entries.Values, rootElement, "TestEntries", ".", "TestEntry", parameters); + // Save test definitions + helper.SaveIEnumerable(this.testElements.Values, rootElement, "TestDefinitions", ".", null, parameters); - // Save default categories - List categories = new List(); - categories.Add(TestListCategory.UncategorizedResults); - categories.Add(TestListCategory.AllResults); - helper.SaveList(categories, rootElement, "TestLists", ".", "TestList", parameters); + // Save test entries + helper.SaveIEnumerable(this.entries.Values, rootElement, "TestEntries", ".", "TestEntry", parameters); - // Save summary - if (this.testRunOutcome == TrxLoggerObjectModel.TestOutcome.Passed) - { - this.testRunOutcome = TrxLoggerObjectModel.TestOutcome.Completed; - } + // Save default categories + List categories = new List(); + categories.Add(TestListCategory.UncategorizedResults); + categories.Add(TestListCategory.AllResults); + helper.SaveList(categories, rootElement, "TestLists", ".", "TestList", parameters); - List errorMessages = new List(); - List collectorEntries = Converter.ToCollectionEntries(e.AttachmentSets, this.testRun, this.testResultsDirPath); - IList resultFiles = Converter.ToResultFiles(e.AttachmentSets, this.testRun, this.testResultsDirPath, errorMessages); + // Save summary + if (this.testRunOutcome == TrxLoggerObjectModel.TestOutcome.Passed) + { + this.testRunOutcome = TrxLoggerObjectModel.TestOutcome.Completed; + } - if (errorMessages.Count > 0) + List errorMessages = new List(); + List collectorEntries = Converter.ToCollectionEntries(e.AttachmentSets, this.testRun, this.testResultsDirPath); + IList resultFiles = Converter.ToResultFiles(e.AttachmentSets, this.testRun, this.testResultsDirPath, errorMessages); + + if (errorMessages.Count > 0) + { + // Got some errors while attaching files, report them and set the outcome of testrun to be Error... + this.testRunOutcome = TrxLoggerObjectModel.TestOutcome.Error; + foreach (string msg in errorMessages) { - // Got some errors while attaching files, report them and set the outcome of testrun to be Error... - this.testRunOutcome = TrxLoggerObjectModel.TestOutcome.Error; - foreach (string msg in errorMessages) - { - RunInfo runMessage = new RunInfo(msg, null, Environment.MachineName, TrxLoggerObjectModel.TestOutcome.Error); - this.runLevelErrorsAndWarnings.Add(runMessage); - } + RunInfo runMessage = new RunInfo(msg, null, Environment.MachineName, TrxLoggerObjectModel.TestOutcome.Error); + this.runLevelErrorsAndWarnings.Add(runMessage); } - - TestRunSummary runSummary = new TestRunSummary( - this.totalTests, - this.passTests + this.failTests, - this.passTests, - this.failTests, - this.testRunOutcome, - this.runLevelErrorsAndWarnings, - this.runLevelStdOut.ToString(), - resultFiles, - collectorEntries); - - helper.SaveObject(runSummary, rootElement, "ResultSummary", parameters); - - //Save results to Trx file - this.DeriveTrxFilePath(); - this.PopulateTrxFile(this.trxFilePath, rootElement); } + + TestRunSummary runSummary = new TestRunSummary( + this.totalTests, + this.passTests + this.failTests, + this.passTests, + this.failTests, + this.testRunOutcome, + this.runLevelErrorsAndWarnings, + this.runLevelStdOut.ToString(), + resultFiles, + collectorEntries); + + helper.SaveObject(runSummary, rootElement, "ResultSummary", parameters); + + //Save results to Trx file + this.DeriveTrxFilePath(); + this.PopulateTrxFile(this.trxFilePath, rootElement); } /// @@ -675,4 +678,4 @@ private TestEntry GetTestEntry(Guid executionId) #endregion } -} \ No newline at end of file +} diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs index aedac00a5f..217352bdd2 100644 --- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs +++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Utility/Converter.cs @@ -461,15 +461,26 @@ private static CollectorDataEntry ToCollectorEntry(ObjectModel.AttachmentSet att // copy the source file to the target location string targetFileName = FileHelper.GetNextIterationFileName(targetDirectory, Path.GetFileName(sourceFile), false); - CopyFile(sourceFile, targetFileName); - // Add the target file name to the collector files list. - // (Trx viewer automatically adds In\ to the collected file. - string fileName = Path.Combine(Environment.MachineName, Path.GetFileName(targetFileName)); - Uri sourceFileUri = new Uri(fileName, UriKind.Relative); - TrxObjectModel.UriDataAttachment dataAttachment = new TrxObjectModel.UriDataAttachment(uriDataAttachment.Description, sourceFileUri); + try + { + CopyFile(sourceFile, targetFileName); + + // Add the target file name to the collector files list. + // (Trx viewer automatically adds In\ to the collected file. + string fileName = Path.Combine(Environment.MachineName, Path.GetFileName(targetFileName)); + Uri sourceFileUri = new Uri(fileName, UriKind.Relative); + TrxObjectModel.UriDataAttachment dataAttachment = new TrxObjectModel.UriDataAttachment(uriDataAttachment.Description, sourceFileUri); - uriDataAttachments.Add(dataAttachment); + uriDataAttachments.Add(dataAttachment); + } + catch(Exception ex) + { + if (ObjectModel.EqtTrace.IsErrorEnabled) + { + ObjectModel.EqtTrace.Error("Trxlogger: ToCollectorEntry: " + ex); + } + } } return new CollectorDataEntry( @@ -509,15 +520,25 @@ private static IList ToResultFiles(ObjectModel.AttachmentSet attachmentS string sourceFile = uriDataAttachment.Uri.LocalPath; Debug.Assert(Path.IsPathRooted(sourceFile), "Source file is not rooted"); - // copy the source file to the target location string targetFileName = FileHelper.GetNextIterationFileName(testResultDirectory, Path.GetFileName(sourceFile), false); - CopyFile(sourceFile, targetFileName); - // Add the target file name to the result files list. - // (Trx viewer automatically adds In\ to the result file. - string fileName = Path.Combine(Environment.MachineName, Path.GetFileName(targetFileName)); - resultFiles.Add(fileName); + try + { + CopyFile(sourceFile, targetFileName); + + // Add the target file name to the result files list. + // (Trx viewer automatically adds In\ to the result file. + string fileName = Path.Combine(Environment.MachineName, Path.GetFileName(targetFileName)); + resultFiles.Add(fileName); + } + catch(Exception ex) + { + if (ObjectModel.EqtTrace.IsErrorEnabled) + { + ObjectModel.EqtTrace.Error("Trxlogger: ToResultFiles: " + ex); + } + } } return resultFiles; diff --git a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs index 8ad0b14d98..865ee466e8 100644 --- a/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs +++ b/test/Microsoft.TestPlatform.Extensions.TrxLogger.UnitTests/TrxLoggerTests.cs @@ -515,6 +515,18 @@ public void TestResultHandlerShouldAddSingleTestEntryForOrderedTest() Assert.AreEqual(this.testableTrxLogger.TestEntryCount, 1, "TestResultHandler is adding multiple test entries for ordered test."); } + [TestMethod] + public void TestRunCompleteHandlerShouldReportFailedOutcomeIfTestRunIsAborted() + { + string message = "The information to test"; + TestRunMessageEventArgs trme = new TestRunMessageEventArgs(TestMessageLevel.Error, message); + this.testableTrxLogger.TestMessageHandler(new object(), trme); + + this.testableTrxLogger.TestRunCompleteHandler(new object(), new TestRunCompleteEventArgs(null, false, true, null, null, TimeSpan.Zero)); + + Assert.AreEqual(this.testableTrxLogger.TestResultOutcome, TrxLoggerObjectModel.TestOutcome.Failed); + } + [TestMethod] public void OutcomeOfRunWillBeFailIfAnyTestsFails() {