diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IDataAttachment.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IDataAttachment.cs
index 735dc0048c..cae4bcd6c8 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IDataAttachment.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IDataAttachment.cs
@@ -6,7 +6,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// Interface used to define a data attachment.
///
- public interface IDataAttachment
+ internal interface IDataAttachment
{
///
/// Gets the description for the attachment.
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestAggregation.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestAggregation.cs
new file mode 100644
index 0000000000..8a5b372067
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestAggregation.cs
@@ -0,0 +1,13 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System;
+ using System.Collections.Generic;
+
+ internal interface ITestAggregation : ITestElement
+ {
+ Dictionary TestLinks { get; }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs
new file mode 100644
index 0000000000..92d7db22f4
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestElement.cs
@@ -0,0 +1,21 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ internal interface ITestElement
+ {
+ TestId Id { get; }
+ string Name { get; set; }
+ string Owner { get; set; }
+ string Storage { get; set; }
+ string Adapter { get; }
+ int Priority { get; set; }
+ bool IsRunnable { get; }
+ TestExecId ExecutionId { get; set; }
+ TestExecId ParentExecutionId { get; set; }
+ TestListCategoryId CategoryId { get; set; }
+ TestCategoryItemCollection TestCategories { get; }
+ TestType TestType { get; }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestResult.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestResult.cs
new file mode 100644
index 0000000000..6835dc5fc1
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestResult.cs
@@ -0,0 +1,28 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+
+ using System;
+
+ internal interface ITestResult
+ {
+ TestResultId Id { get; }
+ string ResultType { get; set; }
+ string StdOut { get; set; }
+ string StdErr { get; set; }
+ string DebugTrace { get; set; }
+ string TestResultsDirectory { get; }
+ string RelativeTestResultsDirectory { get; }
+ string ErrorMessage { get; set; }
+ string ErrorStackTrace { get; set; }
+ string ComputerName { get; }
+ string[] TextMessages { get; set; }
+ int DataRowInfo { get; set; }
+ DateTime StartTime { get; set; }
+ DateTime EndTime { get; set; }
+ TimeSpan Duration { get; set; }
+ TestOutcome Outcome { get; set; }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestResultAggregation.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestResultAggregation.cs
new file mode 100644
index 0000000000..7ee85e3e4c
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/ITestResultAggregation.cs
@@ -0,0 +1,12 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System.Collections.Generic;
+
+ internal interface ITestResultAggregation : ITestResult
+ {
+ List InnerResults { get; }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStore.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStore.cs
index bfaf94d069..cb020b977d 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStore.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStore.cs
@@ -9,7 +9,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
/// Implementing this interface indicates a custom persistence logic is provided.
/// The attribute based persistence is ignored in such a case.
///
- public interface IXmlTestStore
+ internal interface IXmlTestStore
{
///
/// Saves the class under the XmlElement.
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStoreCustom.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStoreCustom.cs
index ca5bcec137..7ff25b9fc0 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStoreCustom.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/IXmlTestStoreCustom.cs
@@ -8,7 +8,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.XML
///
/// Implementing this interface allows you to customize XmlStore persistence.
///
- public interface IXmlTestStoreCustom
+ internal interface IXmlTestStoreCustom
{
///
/// Gets the name of the tag to use to persist this object.
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/XmlTestStoreParameters.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/XmlTestStoreParameters.cs
index 11e8f37567..aa086638b4 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/XmlTestStoreParameters.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/Interfaces/XmlTestStoreParameters.cs
@@ -15,7 +15,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
/// saved when 'MyClass.SaveDetails' parameter is set to 'true'.
///
[SuppressMessage("StyleCop.CSharp.DocumentationRules", "SA1650:ElementDocumentationMustBeSpelledCorrectly", Justification = "Reviewed. Suppression is OK here.")]
- public sealed class XmlTestStoreParameters : Dictionary
+ internal sealed class XmlTestStoreParameters : Dictionary
{
private XmlTestStoreParameters()
{
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/OrderedTestElement.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/OrderedTestElement.cs
new file mode 100644
index 0000000000..907b14bc6d
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/OrderedTestElement.cs
@@ -0,0 +1,35 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
+
+ ///
+ /// Ordered test element.
+ ///
+ internal class OrderedTestElement : TestElementAggregation, IXmlTestStoreCustom
+ {
+ public OrderedTestElement(Guid id, string name, string adapter) : base(id, name, adapter) { }
+
+ string IXmlTestStoreCustom.ElementName
+ {
+ get { return Constants.OrderedTestElementName; }
+ }
+
+ string IXmlTestStoreCustom.NamespaceUri
+ {
+ get { return null; }
+ }
+
+ ///
+ /// Gets the test type.
+ ///
+ public override TestType TestType
+ {
+ get { return Constants.OrderedTestType; }
+ }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestCategoryItems.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestCategoryItems.cs
index 9ebc88feaf..14ffe14426 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestCategoryItems.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestCategoryItems.cs
@@ -14,7 +14,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// Stores a string which categorizes the Test
///
- public sealed class TestCategoryItem : IXmlTestStore
+ internal sealed class TestCategoryItem : IXmlTestStore
{
#region Fields
[StoreXmlSimpleField(Location = "@TestCategory", DefaultValue = "")]
@@ -123,7 +123,7 @@ public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameter
///
/// A collection of strings which categorize the test.
///
- public sealed class TestCategoryItemCollection : EqtBaseCollection
+ internal sealed class TestCategoryItemCollection : EqtBaseCollection
{
#region Constructors
///
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs
new file mode 100644
index 0000000000..9562822962
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElement.cs
@@ -0,0 +1,252 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System;
+ using System.Diagnostics;
+ using System.Globalization;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
+ using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource;
+
+ ///
+ /// Test element.
+ ///
+ internal abstract class TestElement : ITestElement, IXmlTestStore
+ {
+ ///
+ /// Default priority for a test method that does not specify a priority
+ ///
+ protected const int DefaultPriority = int.MaxValue;
+
+ protected TestId id;
+ protected string name;
+ protected string owner;
+ protected string storage;
+ protected string adapter;
+ protected int priority;
+ protected bool isRunnable;
+ protected TestExecId executionId;
+ protected TestExecId parentExecutionId;
+ protected TestCategoryItemCollection testCategories;
+ protected TestListCategoryId catId;
+
+ public TestElement(Guid id, string name, string adapter)
+ {
+ Debug.Assert(!string.IsNullOrEmpty(name), "name is null");
+ Debug.Assert(!string.IsNullOrEmpty(adapter), "adapter is null");
+
+ this.Initialize();
+
+ this.id = new TestId(id);
+ this.name = name;
+ this.adapter = adapter;
+ }
+
+
+ ///
+ /// Gets the id.
+ ///
+ public TestId Id
+ {
+ get { return this.id; }
+ }
+
+ ///
+ /// Gets or sets the name.
+ ///
+ public string Name
+ {
+ get { return this.name; }
+
+ set
+ {
+ EqtAssert.ParameterNotNull(value, "Name");
+ this.name = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the owner.
+ ///
+ public string Owner
+ {
+ get { return this.owner; }
+
+ set
+ {
+ EqtAssert.ParameterNotNull(value, "Owner");
+ this.owner = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the priority.
+ ///
+ public int Priority
+ {
+ get { return this.priority; }
+ set { this.priority = value; }
+ }
+
+ ///
+ /// Gets or sets the storage.
+ ///
+ public string Storage
+ {
+ get { return this.storage; }
+
+ set
+ {
+ EqtAssert.StringNotNullOrEmpty(value, "Storage");
+ this.storage = value.ToLowerInvariant();
+ }
+ }
+
+ ///
+ /// Gets or sets the execution id.
+ ///
+ public TestExecId ExecutionId
+ {
+ get { return this.executionId; }
+ set { this.executionId = value; }
+ }
+
+ ///
+ /// Gets or sets the parent execution id.
+ ///
+ public TestExecId ParentExecutionId
+ {
+ get { return this.parentExecutionId; }
+ set { this.parentExecutionId = value; }
+ }
+
+ ///
+ /// Gets the isRunnable value.
+ ///
+ public bool IsRunnable
+ {
+ get { return this.isRunnable; }
+ }
+
+ ///
+ /// Gets or sets the category id.
+ ///
+ ///
+ /// Instead of setting to null use TestListCategoryId.Uncategorized
+ ///
+ public TestListCategoryId CategoryId
+ {
+ get { return this.catId; }
+
+ set
+ {
+ EqtAssert.ParameterNotNull(value, "CategoryId");
+ this.catId = value;
+ }
+ }
+
+ ///
+ /// Gets or sets the test categories.
+ ///
+ public TestCategoryItemCollection TestCategories
+ {
+ get { return this.testCategories; }
+
+ set
+ {
+ EqtAssert.ParameterNotNull(value, "value");
+ this.testCategories = value;
+ }
+ }
+
+ ///
+ /// Gets the adapter name.
+ ///
+ public string Adapter
+ {
+ get { return adapter; }
+ }
+
+ ///
+ /// Gets the test type.
+ ///
+ public abstract TestType TestType { get; }
+
+ ///
+ /// Override for ToString.
+ ///
+ /// String representation of test element.
+ public override string ToString()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "'{0}' {1}",
+ this.name != null ? this.name : TrxLoggerResources.Common_NullInMessages,
+ this.id != null ? this.id.ToString() : TrxLoggerResources.Common_NullInMessages);
+ }
+
+ ///
+ /// Override for Equals.
+ ///
+ ///
+ /// The object to compare.
+ ///
+ ///
+ /// The .
+ ///
+ public override bool Equals(object other)
+ {
+ TestElement otherTest = other as TestElement;
+ return (otherTest == null) ?
+ false :
+ this.id.Equals(otherTest.id);
+ }
+
+ ///
+ /// Override for GetHashCode
+ ///
+ ///
+ /// The .
+ ///
+ public override int GetHashCode()
+ {
+ return this.id.GetHashCode();
+ }
+
+ public virtual void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
+ {
+ XmlPersistence h = new XmlPersistence();
+
+ h.SaveSimpleField(element, "@name", this.name, null);
+ h.SaveSimpleField(element, "@storage", this.storage, string.Empty);
+ h.SaveSimpleField(element, "@priority", this.priority, DefaultPriority);
+ h.SaveSimpleField(element, "Owners/Owner/@name", this.owner, string.Empty);
+ h.SaveObject(this.testCategories, element, "TestCategory", parameters);
+
+ if (this.executionId != null)
+ h.SaveGuid(element, "Execution/@id", this.executionId.Id);
+ if (this.parentExecutionId != null)
+ h.SaveGuid(element, "Execution/@parentId", this.parentExecutionId.Id);
+
+ XmlTestStoreParameters testIdParameters = XmlTestStoreParameters.GetParameters();
+ testIdParameters[TestId.IdLocationKey] = "@id";
+ h.SaveObject(this.id, element, testIdParameters);
+ }
+
+ private void Initialize()
+ {
+ this.id = TestId.Empty;
+ this.name = string.Empty;
+ this.owner = string.Empty;
+ this.priority = DefaultPriority;
+ this.storage = string.Empty;
+ this.executionId = TestExecId.Empty;
+ this.parentExecutionId = TestExecId.Empty;
+ this.testCategories = new TestCategoryItemCollection();
+ this.isRunnable = true;
+ this.catId = TestListCategoryId.Uncategorized;
+ }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElementAggregation.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElementAggregation.cs
new file mode 100644
index 0000000000..d814acaee6
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestElementAggregation.cs
@@ -0,0 +1,38 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
+
+ ///
+ /// Test aggregation element.
+ ///
+ internal abstract class TestElementAggregation : TestElement, ITestAggregation
+ {
+ protected Dictionary testLinks = new Dictionary();
+
+ public TestElementAggregation(Guid id, string name, string adapter) : base(id, name, adapter) { }
+
+ ///
+ /// Test links.
+ ///
+ public Dictionary TestLinks
+ {
+ get { return testLinks; }
+ }
+
+ public override void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
+ {
+ base.Save(element, parameters);
+
+ XmlPersistence h = new XmlPersistence();
+ if (testLinks.Count > 0)
+ {
+ h.SaveIEnumerable(testLinks.Values, element, "TestLinks", ".", "TestLink", parameters);
+ }
+ }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestEntry.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestEntry.cs
index 7b6b8d791d..294f50ad58 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestEntry.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestEntry.cs
@@ -3,9 +3,10 @@
namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
{
+ using System;
+ using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
-
using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
///
@@ -16,8 +17,10 @@ internal sealed class TestEntry : IXmlTestStore
#region Fields
private TestId testId;
- private TestExecId execId;
+ private Guid executionId;
+ private Guid parentExecutionId;
private TestListCategoryId categoryId;
+ private List testEntries;
#endregion
@@ -46,17 +49,41 @@ public TestEntry(TestId testId, TestListCategoryId catId)
///
/// Gets or sets the exec id.
///
- public TestExecId ExecId
+ public Guid ExecutionId
{
- get
+ get { return this.executionId; }
+
+ set
{
- return this.execId;
+ Debug.Assert(value != null, "ExecId is null");
+ this.executionId = value;
}
+ }
+
+ ///
+ /// Gets or sets the parent exec id.
+ ///
+ public Guid ParentExecutionId
+ {
+ get { return this.parentExecutionId; }
set
{
Debug.Assert(value != null, "ExecId is null");
- this.execId = value;
+ this.parentExecutionId = value;
+ }
+ }
+
+ public List TestEntries
+ {
+ get
+ {
+ if (this.testEntries == null)
+ {
+ this.testEntries = new List();
+ }
+
+ return this.testEntries;
}
}
@@ -83,10 +110,10 @@ public override bool Equals(object obj)
return false;
}
- Debug.Assert(this.execId != null, "this.execId is null");
- Debug.Assert(e.execId != null, "e.execId is null");
+ Debug.Assert(this.executionId != null, "this.executionId is null");
+ Debug.Assert(e.executionId != null, "e.executionId is null");
- if (!this.execId.Equals(e.execId))
+ if (!this.executionId.Equals(e.executionId))
{
return false;
}
@@ -104,7 +131,7 @@ public override bool Equals(object obj)
///
public override int GetHashCode()
{
- return this.execId.GetHashCode();
+ return this.executionId.GetHashCode();
}
#endregion
@@ -126,8 +153,12 @@ public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameter
helper.SaveSingleFields(element, this, parameters);
helper.SaveObject(this.testId, element, null);
- helper.SaveGuid(element, "@executionId", this.execId.Id);
+ helper.SaveGuid(element, "@executionId", this.executionId);
+ if (parentExecutionId != null)
+ helper.SaveGuid(element, "@parentExecutionId", this.parentExecutionId);
helper.SaveGuid(element, "@testListId", this.categoryId.Id);
+ if (this.TestEntries.Count > 0)
+ helper.SaveIEnumerable(TestEntries, element, "TestEntries", ".", "TestEntry", parameters);
}
#endregion
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestExecId.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestExecId.cs
index a960834e99..dcf48aa29b 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestExecId.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestExecId.cs
@@ -10,7 +10,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
/// Class identifying test execution id.
/// Execution ID is assigned to test at run creation time and is guaranteed to be unique within that run.
///
- public sealed class TestExecId
+ internal sealed class TestExecId
{
private static TestExecId emptyId = new TestExecId(Guid.Empty);
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestId.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestId.cs
index a871790b2f..6bfada65f3 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestId.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestId.cs
@@ -15,7 +15,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// Class that uniquely identifies a test.
///
- public sealed class TestId : IEquatable, IComparable, IComparable, IXmlTestStore
+ internal sealed class TestId : IEquatable, IComparable, IComparable, IXmlTestStore
{
#region Constants
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestLink.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestLink.cs
new file mode 100644
index 0000000000..b770e30d20
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestLink.cs
@@ -0,0 +1,115 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System;
+ using System.Diagnostics;
+ using System.Globalization;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
+
+ ///
+ /// Test link.
+ ///
+ internal sealed class TestLink : IXmlTestStore
+ {
+ private Guid id;
+ private string name = string.Empty;
+ private string storage = string.Empty;
+
+ public TestLink(Guid id, string name, string storage)
+ {
+ if (id == Guid.Empty)
+ {
+ throw new ArgumentException("ID cant be empty");
+ }
+
+ EqtAssert.StringNotNullOrEmpty(name, "name");
+ EqtAssert.ParameterNotNull(storage, "storage");
+
+ this.id = id;
+ this.name = name;
+ this.storage = storage;
+ }
+
+ ///
+ /// Gets the id.
+ ///
+ public Guid Id
+ {
+ get { return this.id; }
+ }
+
+ ///
+ /// Gets the name.
+ ///
+ public string Name
+ {
+ get { return this.name; }
+ }
+
+ ///
+ /// Gets the storage.
+ ///
+ public string Storage
+ {
+ get { return this.storage; }
+ }
+
+ ///
+ /// Whether this Link is equal to other Link. Compares by Id.
+ ///
+ public override bool Equals(object other)
+ {
+ TestLink link = other as TestLink;
+ return (link == null) ?
+ false :
+ this.id.Equals(link.id);
+ }
+
+ ///
+ /// Whether this Link is exactly the same as other Link. Compares all fields.
+ ///
+ public bool IsSame(TestLink other)
+ {
+ if (other == null)
+ return false;
+
+ return this.id.Equals(other.id) &&
+ this.name.Equals(other.name) &&
+ this.storage.Equals(other.storage);
+ }
+
+ ///
+ /// Override for GetHashCode.
+ ///
+ ///
+ public override int GetHashCode()
+ {
+ return this.id.GetHashCode();
+ }
+
+ ///
+ /// Override for ToString.
+ ///
+ ///
+ public override string ToString()
+ {
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "Link to '{0}' {1} '{2}'.",
+ this.name != null ? this.name : "(null)",
+ this.id.ToString("B"),
+ this.storage != null ? this.storage : "(null)");
+ }
+
+ public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
+ {
+ XmlPersistence h = new XmlPersistence();
+ h.SaveGuid(element, "@id", this.Id);
+ h.SaveSimpleField(element, "@name", this.name, null);
+ h.SaveSimpleField(element, "@storage", this.storage, string.Empty);
+ }
+ }
+}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategory.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategory.cs
index df9eaf7406..22c88e0021 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategory.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategory.cs
@@ -13,7 +13,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// The test list category.
///
- public class TestListCategory : IXmlTestStore
+ internal class TestListCategory : IXmlTestStore
{
#region Fields
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategoryId.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategoryId.cs
index cfad2cc563..d50fd06cf8 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategoryId.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestListCategoryId.cs
@@ -9,7 +9,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// Class to categorize the tests.
///
- public sealed class TestListCategoryId
+ internal sealed class TestListCategoryId
{
private static TestListCategoryId emptyId = new TestListCategoryId(Guid.Empty);
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestOutcome.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestOutcome.cs
index b302628dc2..97b336b316 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestOutcome.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestOutcome.cs
@@ -13,7 +13,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
/// NOTE: the order is important and is used for computing outcome for aggregations.
/// More important outcomes come first. See TestOutcomeHelper.GetAggregationOutcome.
///
- public enum TestOutcome
+ internal enum TestOutcome
{
///
/// There was a system error while we were trying to execute a test.
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs
index e34dbabc8d..517fecafb8 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResult.cs
@@ -4,21 +4,27 @@
namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
{
using System;
+ using System.Collections;
+ using System.Collections.Generic;
using System.Diagnostics;
+ using System.Globalization;
+ using System.IO;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
+ using Microsoft.VisualStudio.TestPlatform.ObjectModel;
+ using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource;
///
/// Class to uniquely identify test results
///
- public sealed class TestResultId : IXmlTestStore
+ internal sealed class TestResultId : IXmlTestStore
{
#region Fields
- private Guid runId;
-
- // id of test within run
- private TestExecId executionId;
- private TestId testId;
+ private Guid runId;
+ private Guid executionId;
+ private Guid parentExecutionId;
+ private Guid testId;
#endregion
@@ -39,10 +45,11 @@ public sealed class TestResultId : IXmlTestStore
///
/// The test id.
///
- public TestResultId(Guid runId, TestExecId executionId, TestId testId)
+ public TestResultId(Guid runId, Guid executionId, Guid parentExecutionId, Guid testId)
{
this.runId = runId;
this.executionId = executionId;
+ this.parentExecutionId = parentExecutionId;
this.testId = testId;
}
@@ -53,11 +60,27 @@ public TestResultId(Guid runId, TestExecId executionId, TestId testId)
///
/// Gets the execution id.
///
- public TestExecId ExecutionId
+ public Guid ExecutionId
{
get { return this.executionId; }
}
+ ///
+ /// Gets the parent execution id.
+ ///
+ public Guid ParentExecutionId
+ {
+ get { return this.parentExecutionId; }
+ }
+
+ ///
+ /// Gets the test id.
+ ///
+ public Guid TestId
+ {
+ get { return this.testId; }
+ }
+
#endregion
#region Overrides
@@ -101,7 +124,7 @@ public override int GetHashCode()
///
public override string ToString()
{
- return this.executionId.Id.ToString("B");
+ return this.executionId.ToString("B");
}
#endregion
@@ -121,11 +144,11 @@ public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameter
XmlPersistence helper = new XmlPersistence();
if (this.executionId != null)
- {
- helper.SaveGuid(element, "@executionId", this.executionId.Id);
- }
+ helper.SaveGuid(element, "@executionId", this.executionId);
+ if (this.parentExecutionId != null)
+ helper.SaveGuid(element, "@parentExecutionId", this.parentExecutionId);
- helper.SaveObject(this.testId, element, null);
+ helper.SaveGuid(element, "@testId", this.testId);
}
#endregion
@@ -190,4 +213,416 @@ public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameter
#endregion
}
+
+ ///
+ /// Class for test result.
+ ///
+ internal class TestResult : ITestResult, IXmlTestStore
+ {
+ #region Fields
+
+ private TestResultId id;
+ private string resultName;
+ private string computerInfo;
+ private string stdOut;
+ private string stdErr;
+ private string debugTrace;
+ private string resultType;
+ private int dataRowInfo;
+ private TimeSpan duration;
+ private DateTime startTime;
+ private DateTime endTime;
+ private TestType testType;
+ private TestOutcome outcome;
+ private TestRun testRun;
+ private TestResultErrorInfo errorInfo;
+ private TestListCategoryId categoryId;
+ private ArrayList textMessages;
+
+ ///
+ /// Directory containing the test result files, relative to the root test results directory
+ ///
+ private string relativeTestResultsDirectory;
+
+ ///
+ /// Paths to test result files, relative to the test results folder, sorted in increasing order
+ ///
+ private SortedList resultFiles = new SortedList(StringComparer.OrdinalIgnoreCase);
+
+ ///
+ /// Information provided by data collectors for the test case
+ ///
+ private List collectorDataEntries = new List();
+
+ #endregion
+
+ #region Constructor
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ ///
+ /// The computer name.
+ ///
+ ///
+ /// The run id.
+ ///
+ ///
+ /// The test.
+ ///
+ ///
+ /// The outcome.
+ ///
+ public TestResult(
+ Guid runId,
+ Guid testId,
+ Guid executionId,
+ Guid parentExecutionId,
+ string resultName,
+ string computerName,
+ TestOutcome outcome,
+ TestType testType,
+ TestListCategoryId testCategoryId)
+ {
+ Debug.Assert(computerName != null, "computername is null");
+ Debug.Assert(!Guid.Empty.Equals(executionId), "ExecutionId is empty");
+ Debug.Assert(!Guid.Empty.Equals(testId), "TestId is empty");
+
+ this.Initialize();
+
+ this.id = new TestResultId(runId, executionId, parentExecutionId, testId);
+ this.resultName = resultName;
+ this.testType = testType;
+ this.computerInfo = computerName;
+ this.outcome = outcome;
+ this.categoryId = testCategoryId;
+ this.relativeTestResultsDirectory = TestRunDirectories.GetRelativeTestResultsDirectory(executionId);
+ }
+
+ #endregion
+
+ #region properties
+
+ ///
+ /// Gets or sets the end time.
+ ///
+ public DateTime EndTime
+ {
+ get { return this.endTime; }
+ set { this.endTime = value; }
+ }
+
+ ///
+ /// Gets or sets the start time.
+ ///
+ public DateTime StartTime
+ {
+ get { return this.startTime; }
+ set { this.startTime = value; }
+ }
+
+ ///
+ /// Gets or sets the duration.
+ ///
+ public TimeSpan Duration
+ {
+ get { return this.duration; }
+
+ set
+ {
+ // On some hardware the Stopwatch.Elapsed can return a negative number. This tends
+ // to happen when the duration of the test is very short and it is hardware dependent
+ // (seems to happen most on virtual machines or machines with AMD processors). To prevent
+ // reporting a negative duration, use TimeSpan.Zero when the elapsed time is less than zero.
+ EqtTrace.WarningIf(value < TimeSpan.Zero, "TestResult.Duration: The duration is being set to {0}. Since the duration is negative the duration will be updated to zero.", value);
+ this.duration = value > TimeSpan.Zero ? value : TimeSpan.Zero;
+ }
+ }
+
+ ///
+ /// Gets the computer name.
+ ///
+ public string ComputerName
+ {
+ get { return this.computerInfo; }
+ }
+
+ ///
+ /// Gets or sets the outcome.
+ ///
+ public TestOutcome Outcome
+ {
+ get { return this.outcome; }
+ set { this.outcome = value; }
+ }
+
+
+ ///
+ /// Gets or sets the id.
+ ///
+ public TestResultId Id
+ {
+ get { return this.id; }
+ internal set { this.id = value; }
+ }
+
+ ///
+ /// Gets or sets the error message.
+ ///
+ public string ErrorMessage
+ {
+ get { return (this.errorInfo == null) ? string.Empty : this.errorInfo.Message; }
+ set { this.errorInfo = new TestResultErrorInfo(value); }
+ }
+
+ ///
+ /// Gets or sets the error stack trace.
+ ///
+ public string ErrorStackTrace
+ {
+ get { return (this.errorInfo == null) ? string.Empty : this.errorInfo.StackTrace; }
+
+ set
+ {
+ Debug.Assert(this.errorInfo != null, "errorInfo is null");
+ this.errorInfo.StackTrace = value;
+ }
+ }
+
+ ///
+ /// Gets the text messages.
+ ///
+ ///
+ /// Additional information messages from TestTextResultMessage, e.g. generated by TestOutcome.WriteLine.
+ /// Avoid using this property in the following way: for (int i=0; i<prop.Length; i++) { ... prop[i] ...}
+ ///
+ public string[] TextMessages
+ {
+ get { return (string[])this.textMessages.ToArray(typeof(string)); }
+
+ set
+ {
+ if (value != null)
+ this.textMessages = new ArrayList(value);
+ else
+ this.textMessages.Clear();
+ }
+ }
+
+ ///
+ /// Gets or sets the standard out.
+ ///
+ public string StdOut
+ {
+ get { return this.stdOut ?? string.Empty; }
+ set { this.stdOut = value; }
+ }
+
+ ///
+ /// Gets or sets the standard err.
+ ///
+ public string StdErr
+ {
+ get { return this.stdErr ?? string.Empty; }
+ set { this.stdErr = value; }
+ }
+
+ ///
+ /// Gets or sets the debug trace.
+ ///
+ public string DebugTrace
+ {
+ get { return this.debugTrace ?? string.Empty; }
+ set { this.debugTrace = value; }
+ }
+
+ ///
+ /// Gets the path to the test results directory
+ ///
+ public string TestResultsDirectory
+ {
+ get
+ {
+ if (this.testRun == null)
+ {
+ Debug.Fail("'m_testRun' is null");
+ throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, TrxLoggerResources.Common_MissingRunInResult));
+ }
+
+ return this.testRun.GetResultFilesDirectory(this);
+ }
+ }
+
+ ///
+ /// Gets the directory containing the test result files, relative to the root results directory
+ ///
+ public string RelativeTestResultsDirectory
+ {
+ get { return this.relativeTestResultsDirectory; }
+ }
+
+ ///
+ /// Gets or sets the data row info.
+ ///
+ public int DataRowInfo
+ {
+ get { return this.dataRowInfo; }
+ set { this.dataRowInfo = value; }
+ }
+
+ ///
+ /// Gets or sets the result type.
+ ///
+ public string ResultType
+ {
+ get { return this.resultType; }
+ set { this.resultType = value; }
+ }
+
+ #endregion
+
+ #region Overrides
+ public override bool Equals(object obj)
+ {
+ TestResult trm = obj as TestResult;
+ if (trm == null)
+ {
+ return false;
+ }
+ Debug.Assert(this.id != null, "id is null");
+ Debug.Assert(trm.id != null, "test result message id is null");
+ return this.id.Equals(trm.id);
+ }
+
+ public override int GetHashCode()
+ {
+ Debug.Assert(this.id != null, "id is null");
+ return this.id.GetHashCode();
+ }
+
+ #endregion
+
+ ///
+ /// Helper function to add a text message info to the test result
+ ///
+ /// Message to be added
+ public void AddTextMessage(string text)
+ {
+ EqtAssert.ParameterNotNull(text, "text");
+ this.textMessages.Add(text);
+ }
+
+ ///
+ /// Sets the test run the test was executed in
+ ///
+ /// The test run the test was executed in
+ internal virtual void SetTestRun(TestRun testRun)
+ {
+ Debug.Assert(testRun != null, "'testRun' is null");
+ this.testRun = testRun;
+ }
+
+ ///
+ /// Adds result files to the collection
+ ///
+ /// Paths to the result files
+ internal void AddResultFiles(IEnumerable resultFileList)
+ {
+ Debug.Assert(resultFileList != null, "'resultFileList' is null");
+
+ string testResultsDirectory = this.TestResultsDirectory;
+ foreach (string resultFile in resultFileList)
+ {
+ Debug.Assert(!string.IsNullOrEmpty(resultFile), "'resultFile' is null or empty");
+ Debug.Assert(resultFile.Trim() == resultFile, "'resultFile' has whitespace at the ends");
+
+ this.resultFiles[FileHelper.MakePathRelative(resultFile, testResultsDirectory)] = null;
+ }
+ }
+
+ ///
+ /// Adds collector data entries to the collection
+ ///
+ /// The collector data entry to add
+ internal void AddCollectorDataEntries(IEnumerable collectorDataEntryList)
+ {
+ Debug.Assert(collectorDataEntryList != null, "'collectorDataEntryList' is null");
+
+ string testResultsDirectory = this.TestResultsDirectory;
+ foreach (CollectorDataEntry collectorDataEntry in collectorDataEntryList)
+ {
+ Debug.Assert(collectorDataEntry != null, "'collectorDataEntry' is null");
+ Debug.Assert(!this.collectorDataEntries.Contains(collectorDataEntry), "The collector data entry already exists in the collection");
+#if DEBUG
+ // Verify that any URI data attachments in the entry have relative paths
+ foreach (IDataAttachment attachment in collectorDataEntry.Attachments)
+ {
+ UriDataAttachment uriDataAttachment = attachment as UriDataAttachment;
+ if (uriDataAttachment != null)
+ {
+ Debug.Assert(uriDataAttachment.Uri.IsAbsoluteUri, "'collectorDataEntry' contains a URI data attachment with a relative URI");
+ }
+ }
+#endif
+
+ this.collectorDataEntries.Add(collectorDataEntry.Clone(testResultsDirectory, false));
+ }
+ }
+
+
+ #region IXmlTestStore Members
+
+ ///
+ /// Saves the class under the XmlElement..
+ ///
+ ///
+ /// The parent xml.
+ ///
+ ///
+ /// The parameter
+ ///
+ public virtual void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
+ {
+ XmlPersistence helper = new XmlPersistence();
+
+ helper.SaveObject(this.id, element, ".", parameters);
+ helper.SaveSimpleField(element, "@testName", this.resultName, string.Empty);
+ helper.SaveSimpleField(element, "@computerName", this.computerInfo, string.Empty);
+ helper.SaveSimpleField(element, "@duration", this.duration, default(TimeSpan));
+ helper.SaveSimpleField(element, "@startTime", this.startTime, default(DateTime));
+ helper.SaveSimpleField(element, "@endTime", this.endTime, default(DateTime));
+ helper.SaveGuid(element, "@testType", this.testType.Id);
+
+ if (this.stdOut != null)
+ this.stdOut = this.stdOut.Trim();
+
+ if (this.stdErr != null)
+ this.stdErr = this.stdErr.Trim();
+
+ helper.SaveSimpleField(element, "@outcome", this.outcome, default(TestOutcome));
+ helper.SaveSimpleField(element, "Output/StdOut", this.stdOut, string.Empty);
+ helper.SaveSimpleField(element, "Output/StdErr", this.stdErr, string.Empty);
+ helper.SaveSimpleField(element, "Output/DebugTrace", this.debugTrace, string.Empty);
+ helper.SaveObject(this.errorInfo, element, "Output/ErrorInfo", parameters);
+ helper.SaveGuid(element, "@testListId", this.categoryId.Id);
+ helper.SaveIEnumerable(this.textMessages, element, "Output/TextMessages", ".", "Message", parameters);
+ helper.SaveSimpleField(element, "@relativeResultsDirectory", this.relativeTestResultsDirectory, null);
+ helper.SaveIEnumerable(this.resultFiles.Keys, element, "ResultFiles", "@path", "ResultFile", parameters);
+ helper.SaveIEnumerable(this.collectorDataEntries, element, "CollectorDataEntries", ".", "Collector", parameters);
+
+ if (this.dataRowInfo >= 0)
+ helper.SaveSimpleField(element, "@dataRowInfo", this.dataRowInfo, -1);
+
+ if (!string.IsNullOrEmpty(this.resultType))
+ helper.SaveSimpleField(element, "@resultType", this.resultType, string.Empty);
+ }
+
+ #endregion
+
+ private void Initialize()
+ {
+ this.textMessages = new ArrayList();
+ this.dataRowInfo = -1;
+ }
+ }
}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs
new file mode 100644
index 0000000000..1561fa287e
--- /dev/null
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestResultAggregation.cs
@@ -0,0 +1,52 @@
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// Licensed under the MIT license. See LICENSE file in the project root for full license information.
+
+namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
+{
+ using System;
+ using System.Collections.Generic;
+ using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
+
+ ///
+ /// Test result aggregation.
+ ///
+ internal class TestResultAggregation : TestResult, ITestResultAggregation
+ {
+ protected List innerResults;
+
+ public TestResultAggregation(
+ Guid runId,
+ Guid testId,
+ Guid executionId,
+ Guid parentExecutionId,
+ string resultName,
+ string computerName,
+ TestOutcome outcome,
+ TestType testType,
+ TestListCategoryId testCategoryId) : base(runId, testId, executionId, parentExecutionId, resultName, computerName, outcome, testType, testCategoryId) { }
+
+ ///
+ /// Gets the inner results.
+ ///
+ public List InnerResults
+ {
+ get
+ {
+ if (innerResults == null)
+ {
+ innerResults = new List();
+ }
+ return innerResults;
+ }
+ }
+
+ public override void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
+ {
+ base.Save(element, parameters);
+
+ XmlPersistence helper = new XmlPersistence();
+ if (this.InnerResults.Count > 0)
+ helper.SaveIEnumerable(this.InnerResults, element, "InnerResults", ".", null, parameters);
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs
index d2d2500e7b..a40949ef3f 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestRun.cs
@@ -17,7 +17,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// Class having information about a test run.
///
- public sealed class TestRun
+ internal sealed class TestRun
{
#region Fields
@@ -159,7 +159,7 @@ internal Guid Id
///
/// Result directory.
///
- internal string GetResultFilesDirectory(UnitTestResult result)
+ internal string GetResultFilesDirectory(TestResult result)
{
EqtAssert.ParameterNotNull(result, "result");
return Path.Combine(this.GetResultsDirectory(), result.RelativeTestResultsDirectory);
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestType.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestType.cs
index a7d6611009..2ca37de652 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestType.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/TestType.cs
@@ -10,7 +10,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
///
/// Class identifying test type.
///
- public sealed class TestType : IXmlTestStore
+ internal sealed class TestType : IXmlTestStore
{
[StoreXmlSimpleField(".")]
private Guid typeId;
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestElement.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestElement.cs
index 6e6c3105eb..b50a9ef1e1 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestElement.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestElement.cs
@@ -5,106 +5,33 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
{
using System;
using System.Diagnostics;
- using System.Globalization;
-
using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
- using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource;
-
///
- /// Class for all tests
+ /// Unit test element.
///
- internal class UnitTestElement : IXmlTestStore, IXmlTestStoreCustom
+ internal class UnitTestElement : TestElement, IXmlTestStoreCustom
{
- #region Constants
- ///
- /// Default priority for a test method that does not specify a priority
- ///
- internal const int DefaultPriority = int.MaxValue;
-
- ///
- /// Timeout value indicating a not-set timeout
- ///
- internal const int NotSetTimeout = 0;
-
- private static readonly Guid TestTypeGuid = new Guid("13CDC9D9-DDB5-4fa4-A97D-D965CCFC6D4B");
- private static readonly TestType TestTypeInstance = new TestType(TestTypeGuid);
-
- #endregion
-
- #region Fields
-
- private TestId id;
-
- private string name;
-
- private string owner;
-
- private int priority;
-
- private TestCategoryItemCollection testCategories;
-
- private TestExecId executionId;
-
- private string storage;
-
private string codeBase;
-
- // partial or fully qualified name of the adapter used to execute the test
- private string executorUriOfAdapter;
-
private TestMethod testMethod;
- private bool isRunnable;
-
- private TestListCategoryId catId;
-
- #endregion
-
- #region Constructors
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The id.
- ///
- ///
- /// The name.
- ///
- ///
- /// The adapter type name.
- ///
- ///
- /// The test method.
- ///
public UnitTestElement(
Guid id,
string name,
- string executorUriOfAdapter,
- TestMethod testMethod)
+ string adapter,
+ TestMethod testMethod) : base(id, name, adapter)
{
- Debug.Assert(!string.IsNullOrEmpty(name), "name is null");
- Debug.Assert(!string.IsNullOrEmpty(executorUriOfAdapter), "executorUriOfAdapter is null");
+ Debug.Assert(!string.IsNullOrEmpty(adapter), "adapter is null");
Debug.Assert(testMethod != null, "testMethod is null");
+ Debug.Assert(testMethod != null && testMethod.ClassName != null, "className is null");
- this.Initialize();
-
- this.id = new TestId(id);
- this.name = name;
- this.executorUriOfAdapter = executorUriOfAdapter;
this.testMethod = testMethod;
- Debug.Assert(this.testMethod.ClassName != null, "className is null");
}
- #endregion
-
- #region IXmlTestStoreCustom
-
string IXmlTestStoreCustom.ElementName
{
- get { return "UnitTest"; }
+ get { return Constants.UnitTestElementName; }
}
string IXmlTestStoreCustom.NamespaceUri
@@ -112,207 +39,28 @@ string IXmlTestStoreCustom.NamespaceUri
get { return null; }
}
- #endregion
-
- ///
- /// Gets or sets the category id.
- ///
- ///
- /// Instead of setting to null use TestListCategoryId.Uncategorized
- ///
- public TestListCategoryId CategoryId
- {
- get
- {
- return this.catId;
- }
-
- set
- {
- EqtAssert.ParameterNotNull(value, "CategoryId");
- this.catId = value;
- }
- }
-
- ///
- /// Gets the id.
- ///
- public TestId Id
- {
- get { return this.id; }
- }
-
- ///
- /// Gets or sets the execution id.
- ///
- public TestExecId ExecutionId
- {
- get { return this.executionId; }
- set { this.executionId = value; }
- }
-
- ///
- /// Gets or sets the name.
- ///
- public string Name
- {
- get
- {
- return this.name;
- }
-
- set
- {
- EqtAssert.ParameterNotNull(value, "Name");
-
- this.name = value;
- }
- }
-
- ///
- /// Gets or sets the storage.
- ///
- public string Storage
- {
- get
- {
- return this.storage;
- }
-
- set
- {
- EqtAssert.StringNotNullOrEmpty(value, "Storage");
- this.storage = value.ToLowerInvariant();
- }
- }
-
- ///
- /// Gets or sets the priority.
- ///
- public int Priority
- {
- get
- {
- return this.priority;
- }
-
- set
- {
- this.priority = value;
- }
- }
-
- ///
- /// Gets or sets the owner.
- ///
- public string Owner
- {
- get
- {
- return this.owner;
- }
-
- set
- {
- EqtAssert.ParameterNotNull(value, "Owner");
- this.owner = value;
- }
- }
-
///
/// Gets the test type.
///
- public TestType TestType
+ public override TestType TestType
{
- get { return TestTypeInstance; }
+ get { return Constants.UnitTestType; }
}
///
- /// Gets or sets the test categories.
+ /// Gets or sets the storage.
///
- public TestCategoryItemCollection TestCategories
+ public string CodeBase
{
- get
- {
- return this.testCategories;
- }
+ get { return this.codeBase; }
set
{
- EqtAssert.ParameterNotNull(value, "value");
- this.testCategories = value;
- }
- }
-
- ///
- /// The assign code base.
- ///
- ///
- /// The code base.
- ///
- public void AssignCodeBase(string cb)
- {
- EqtAssert.StringNotNullOrEmpty(cb, "codeBase");
- this.codeBase = cb;
- }
-
- public bool IsRunnable
- {
- get { return this.isRunnable; }
- }
-
- #region Overrides
-
- ///
- /// Override for Tostring.
- ///
- ///
- /// The .
- ///
- public override string ToString()
- {
- return string.Format(
- CultureInfo.InvariantCulture,
- "'{0}' {1}",
- this.name != null ? this.name : TrxLoggerResources.Common_NullInMessages,
- this.id != null ? this.id.ToString() : TrxLoggerResources.Common_NullInMessages);
- }
-
- ///
- /// Override for Equals.
- ///
- ///
- /// The object to compare.
- ///
- ///
- /// The .
- ///
- public override bool Equals(object other)
- {
- UnitTestElement otherTest = other as UnitTestElement;
- if (otherTest == null)
- {
- return false;
+ EqtAssert.StringNotNullOrEmpty(value, "CodeBase");
+ this.codeBase = value;
}
-
- return this.id.Equals(otherTest.id);
}
- ///
- /// Override for GetHashCode
- ///
- ///
- /// The .
- ///
- public override int GetHashCode()
- {
- return this.id.GetHashCode();
- }
-
- #endregion
-
- #region IXmlTestStore Members
-
///
/// Saves the class under the XmlElement..
///
@@ -322,47 +70,14 @@ public override int GetHashCode()
///
/// The parameter
///
- public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
+ public override void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
{
+ base.Save(element, parameters);
XmlPersistence h = new XmlPersistence();
- h.SaveSimpleField(element, "@name", this.name, null);
- h.SaveSimpleField(element, "@storage", this.storage, string.Empty);
- h.SaveSimpleField(element, "@priority", this.priority, DefaultPriority);
- h.SaveSimpleField(element, "Owners/Owner/@name", this.owner, string.Empty);
- h.SaveObject(this.testCategories, element, "TestCategory", parameters);
-
- // Save the test ID. We exclude "test" from the default locations used by TestId, since this is already a test
- // element. Ideally, we would let TestId save the IDs to the default locations, but the previous behavior of
- // TestElement was to store the test ID at @testId, and since we can't change this, TestId supports custom
- // locations for the IDs. See TestId.GetLocations for more info.
- XmlTestStoreParameters testIdParameters = XmlTestStoreParameters.GetParameters();
- testIdParameters[TestId.IdLocationKey] = "@id";
- h.SaveObject(this.id, element, testIdParameters);
-
- if (this.executionId != null)
- {
- h.SaveGuid(element, "Execution/@id", this.executionId.Id);
- }
-
h.SaveSimpleField(element, "TestMethod/@codeBase", this.codeBase, string.Empty);
- h.SaveSimpleField(element, "TestMethod/@executorUriOfAdapter", this.executorUriOfAdapter, string.Empty);
+ h.SaveSimpleField(element, "TestMethod/@adapterTypeName", this.adapter, string.Empty);
h.SaveObject(this.testMethod, element, "TestMethod", parameters);
}
-
- #endregion //IXmlTestStore
-
- private void Initialize()
- {
- this.id = TestId.Empty;
- this.name = string.Empty;
- this.owner = string.Empty;
- this.priority = DefaultPriority;
- this.executionId = TestExecId.Empty;
- this.testCategories = new TestCategoryItemCollection();
- this.storage = string.Empty;
- this.isRunnable = true;
- this.catId = TestListCategoryId.Uncategorized;
- }
}
}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs
index 4c7027370d..66c815765e 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UnitTestResult.cs
@@ -4,455 +4,21 @@
namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
{
using System;
- using System.Collections;
- using System.Collections.Generic;
- using System.Diagnostics;
- using System.Globalization;
- using System.IO;
-
- using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
- using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
- using Microsoft.VisualStudio.TestPlatform.ObjectModel;
-
- using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource;
///
/// Class for unit test result.
///
- internal class UnitTestResult: IXmlTestStore
+ internal class UnitTestResult: TestResultAggregation
{
- #region Fields
- // id of test within run
- private TestResultId id;
-
- // name of test within run
- private string testName;
-
- private string computerInfo;
-
- private TimeSpan duration;
-
- private DateTime startTime;
-
- private DateTime endTime;
-
- // type of test (Guid)
- private TestType testType;
-
- ///
- /// The outcome of the test result
- ///
- private TestOutcome outcome;
-
- ///
- /// The test run in which the test was executed
- ///
- private TestRun testRun;
-
- private string stdOut;
-
- private string stdErr;
-
- private string debugTrace;
-
- private TestResultErrorInfo errorInfo;
-
- private TestListCategoryId categoryId;
-
- private ArrayList textMessages;
-
- ///
- /// Directory containing the test result files, relative to the root test results directory
- ///
- private string relativeTestResultsDirectory;
-
- ///
- /// Paths to test result files, relative to the test results folder, sorted in increasing order
- ///
- private SortedList resultFiles = new SortedList(StringComparer.OrdinalIgnoreCase);
-
- ///
- /// Information provided by data collectors for the test case
- ///
- private List collectorDataEntries = new List();
-
- #endregion
-
- #region Constructor
-
- ///
- /// Initializes a new instance of the class.
- ///
- ///
- /// The computer name.
- ///
- ///
- /// The run id.
- ///
- ///
- /// The test.
- ///
- ///
- /// The outcome.
- ///
- public UnitTestResult(string computerName, Guid runId, UnitTestElement test, TestOutcome outcome)
- {
- Debug.Assert(computerName != null, "computername is null");
- Debug.Assert(test != null, "test is null");
- Debug.Assert(!Guid.Empty.Equals(test.ExecutionId.Id), "ExecutionId is empty");
- Debug.Assert(!Guid.Empty.Equals(test.Id.Id), "Id is empty");
-
- this.Initialize();
-
- this.id = new TestResultId(runId, test.ExecutionId, test.Id);
- this.testName = test.Name;
- this.testType = test.TestType;
- this.computerInfo = computerName;
-
- this.outcome = outcome;
- this.categoryId = test.CategoryId;
- this.relativeTestResultsDirectory = TestRunDirectories.GetRelativeTestResultsDirectory(test.ExecutionId.Id);
- }
-
- #endregion
-
- #region properties
-
- ///
- /// Gets or sets the end time.
- ///
- public DateTime EndTime
- {
- get { return this.endTime; }
- set { this.endTime = value; }
- }
-
- ///
- /// Gets or sets the start time.
- ///
- public DateTime StartTime
- {
- get { return this.startTime; }
- set { this.startTime = value; }
- }
-
- ///
- /// Gets or sets the duration.
- ///
- public TimeSpan Duration
- {
- get
- {
- return this.duration;
- }
-
- set
- {
- // On some hardware the Stopwatch.Elapsed can return a negative number. This tends
- // to happen when the duration of the test is very short and it is hardware dependent
- // (seems to happen most on virtual machines or machines with AMD processors). To prevent
- // reporting a negative duration, use TimeSpan.Zero when the elapsed time is less than zero.
- EqtTrace.WarningIf(value < TimeSpan.Zero, "TestResult.Duration: The duration is being set to {0}. Since the duration is negative the duration will be updated to zero.", value);
- this.duration = value > TimeSpan.Zero ? value : TimeSpan.Zero;
- }
- }
-
- ///
- /// Gets the computer name.
- ///
- public string ComputerName
- {
- get { return this.computerInfo; }
- }
-
- ///
- /// Gets or sets the outcome.
- ///
- public TestOutcome Outcome
- {
- get { return this.outcome; }
- set { this.outcome = value; }
- }
-
-
- ///
- /// Gets or sets the id.
- ///
- public TestResultId Id
- {
- get { return this.id; }
- internal set { this.id = value; }
- }
-
- ///
- /// Gets or sets the error message.
- ///
- public string ErrorMessage
- {
- get
- {
- if (this.errorInfo == null)
- {
- return string.Empty;
- }
-
- return this.errorInfo.Message;
- }
-
- set
- {
- this.errorInfo = new TestResultErrorInfo(value);
- }
- }
-
- ///
- /// Gets or sets the error stack trace.
- ///
- public string ErrorStackTrace
- {
- get
- {
- if (this.errorInfo == null)
- {
- return string.Empty;
- }
-
- return this.errorInfo.StackTrace;
- }
-
- set
- {
- Debug.Assert(this.errorInfo != null, "errorInfo is null");
- this.errorInfo.StackTrace = value;
- }
- }
-
- ///
- /// Gets the text messages.
- ///
- ///
- /// Additional information messages from TestTextResultMessage, e.g. generated by TestOutcome.WriteLine.
- /// Avoid using this property in the following way: for (int i=0; i<prop.Length; i++) { ... prop[i] ...}
- ///
- public string[] TextMessages
- {
- get
- {
- return (string[])this.textMessages.ToArray(typeof(string));
- }
-
- internal set
- {
- if (value != null)
- {
- this.textMessages = new ArrayList(value);
- }
- else
- {
- this.textMessages.Clear();
- }
- }
- }
-
- ///
- /// Gets or sets the standard out.
- ///
- public string StdOut
- {
- get { return this.stdOut ?? string.Empty; }
- set { this.stdOut = value; }
- }
-
- ///
- /// Gets or sets the standard err.
- ///
- public string StdErr
- {
- get { return this.stdErr ?? string.Empty; }
- set { this.stdErr = value; }
- }
-
- ///
- /// Gets or sets the debug trace.
- ///
- public string DebugTrace
- {
- get { return this.debugTrace ?? string.Empty; }
- set { this.debugTrace = value; }
- }
-
- ///
- /// Gets the path to the test results directory
- ///
- public string TestResultsDirectory
- {
- get
- {
- if (this.testRun == null)
- {
- Debug.Fail("'m_testRun' is null");
- throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, TrxLoggerResources.Common_MissingRunInResult));
- }
-
- return this.testRun.GetResultFilesDirectory(this);
- }
- }
-
- ///
- /// Gets the directory containing the test result files, relative to the root results directory
- ///
- internal string RelativeTestResultsDirectory
- {
- get
- {
- return this.relativeTestResultsDirectory;
- }
- }
-
- #endregion
-
- #region Overrides
- public override bool Equals(object obj)
- {
- UnitTestResult trm = obj as UnitTestResult;
- if (trm == null)
- {
- return false;
- }
- Debug.Assert(this.id != null, "id is null");
- Debug.Assert(trm.id != null, "test result message id is null");
- return this.id.Equals(trm.id);
- }
-
- public override int GetHashCode()
- {
- Debug.Assert(this.id != null, "id is null");
- return this.id.GetHashCode();
- }
-
- #endregion
-
- ///
- /// Helper function to add a text message info to the test result
- ///
- /// Message to be added
- public void AddTextMessage(string text)
- {
- EqtAssert.ParameterNotNull(text, "text");
- this.textMessages.Add(text);
- }
-
- ///
- /// Sets the test run the test was executed in
- ///
- /// The test run the test was executed in
- internal virtual void SetTestRun(TestRun testRun)
- {
- Debug.Assert(testRun != null, "'testRun' is null");
- this.testRun = testRun;
- }
-
- ///
- /// Adds result files to the collection
- ///
- /// Paths to the result files
- internal void AddResultFiles(IEnumerable resultFileList)
- {
- Debug.Assert(resultFileList != null, "'resultFileList' is null");
-
- string testResultsDirectory = this.TestResultsDirectory;
- foreach (string resultFile in resultFileList)
- {
- Debug.Assert(!string.IsNullOrEmpty(resultFile), "'resultFile' is null or empty");
- Debug.Assert(resultFile.Trim() == resultFile, "'resultFile' has whitespace at the ends");
- Debug.Assert(Path.IsPathRooted(resultFile), "'resultFile' is a relative path");
-
- this.resultFiles[FileHelper.MakePathRelative(resultFile, testResultsDirectory)] = null;
- }
- }
-
- ///
- /// Adds collector data entries to the collection
- ///
- /// The collector data entry to add
- internal void AddCollectorDataEntries(IEnumerable collectorDataEntryList)
- {
- Debug.Assert(collectorDataEntryList != null, "'collectorDataEntryList' is null");
-
- string testResultsDirectory = this.TestResultsDirectory;
- foreach (CollectorDataEntry collectorDataEntry in collectorDataEntryList)
- {
- Debug.Assert(collectorDataEntry != null, "'collectorDataEntry' is null");
- Debug.Assert(!this.collectorDataEntries.Contains(collectorDataEntry), "The collector data entry already exists in the collection");
-#if DEBUG
- // Verify that any URI data attachments in the entry have relative paths
- foreach (IDataAttachment attachment in collectorDataEntry.Attachments)
- {
- UriDataAttachment uriDataAttachment = attachment as UriDataAttachment;
- if (uriDataAttachment != null)
- {
- Debug.Assert(uriDataAttachment.Uri.IsAbsoluteUri, "'collectorDataEntry' contains a URI data attachment with a relative URI");
- }
- }
-#endif
-
- this.collectorDataEntries.Add(collectorDataEntry.Clone(testResultsDirectory, false));
- }
- }
-
-
- #region IXmlTestStore Members
-
- ///
- /// Saves the class under the XmlElement..
- ///
- ///
- /// The parent xml.
- ///
- ///
- /// The parameter
- ///
- public void Save(System.Xml.XmlElement element, XmlTestStoreParameters parameters)
- {
- XmlPersistence helper = new XmlPersistence();
-
- helper.SaveObject(this.id, element, ".", parameters);
- helper.SaveSimpleField(element, "@testName", this.testName, string.Empty);
- helper.SaveSimpleField(element, "@computerName", this.computerInfo, string.Empty);
- helper.SaveSimpleField(element, "@duration", this.duration, default(TimeSpan));
- helper.SaveSimpleField(element, "@startTime", this.startTime, default(DateTime));
- helper.SaveSimpleField(element, "@endTime", this.endTime, default(DateTime));
- helper.SaveGuid(element, "@testType", this.testType.Id);
-
- if (this.stdOut != null)
- {
- this.stdOut = this.stdOut.Trim();
- }
-
- if (this.stdErr != null)
- {
- this.stdErr = this.stdErr.Trim();
- }
-
- helper.SaveSimpleField(element, "@outcome", this.outcome, default(TestOutcome));
- helper.SaveSimpleField(element, "Output/StdOut", this.stdOut, string.Empty);
- helper.SaveSimpleField(element, "Output/StdErr", this.stdErr, string.Empty);
- helper.SaveSimpleField(element, "Output/DebugTrace", this.debugTrace, string.Empty);
- helper.SaveObject(this.errorInfo, element, "Output/ErrorInfo", parameters);
-
- helper.SaveGuid(element, "@testListId", this.categoryId.Id);
-
- helper.SaveIEnumerable(this.textMessages, element, "Output/TextMessages", ".", "Message", parameters);
- helper.SaveSimpleField(element, "@relativeResultsDirectory", this.relativeTestResultsDirectory, null);
- helper.SaveIEnumerable(this.resultFiles.Keys, element, "ResultFiles", "@path", "ResultFile", parameters);
- helper.SaveIEnumerable(this.collectorDataEntries, element, "CollectorDataEntries", ".", "Collector", parameters);
- }
-
- #endregion
-
- private void Initialize()
- {
- this.textMessages = new ArrayList();
- }
+ public UnitTestResult(
+ Guid runId,
+ Guid testId,
+ Guid executionId,
+ Guid parentExecutionId,
+ string resultName,
+ string computerName,
+ TestOutcome outcome,
+ TestType testType,
+ TestListCategoryId testCategoryId) : base(runId, testId, executionId, parentExecutionId, resultName, computerName, outcome, testType, testCategoryId) { }
}
}
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs
index efe86e3862..918a0839a2 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/ObjectModel/UriDataAttachment.cs
@@ -15,7 +15,7 @@ namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel
/// Class that provides a basic implementation of IUriAttachment, which can be used by plugin
/// writers to send any resource accessible by a URI as an attachment.
///
- public class UriDataAttachment : IDataAttachment, IXmlTestStore
+ internal class UriDataAttachment : IDataAttachment, IXmlTestStore
{
#region Private fields
diff --git a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs
index 0470951b77..7c96abb56f 100644
--- a/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs
+++ b/src/Microsoft.TestPlatform.Extensions.TrxLogger/TrxLogger.cs
@@ -4,6 +4,7 @@
namespace Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger
{
using System;
+ using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
@@ -11,50 +12,24 @@ namespace Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger
using System.IO;
using System.Text;
using System.Xml;
-
using Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel;
using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.ObjectModel.Client;
using Microsoft.VisualStudio.TestPlatform.Utilities;
-
using ObjectModel.Logging;
-
+ using TrxLoggerConstants = Microsoft.TestPlatform.Extensions.TrxLogger.Utility.Constants;
using TrxLoggerObjectModel = Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel;
using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource;
///
/// Logger for Generating TRX
///
- [FriendlyName(TrxLogger.FriendlyName)]
- [ExtensionUri(TrxLogger.ExtensionUri)]
+ [FriendlyName(TrxLoggerConstants.FriendlyName)]
+ [ExtensionUri(TrxLoggerConstants.ExtensionUri)]
internal class TrxLogger : ITestLoggerWithParameters
{
- #region Constants
-
- ///
- /// Uri used to uniquely identify the TRX logger.
- ///
- public const string ExtensionUri = "logger://Microsoft/TestPlatform/TrxLogger/v1";
-
- ///
- /// Alternate user friendly string to uniquely identify the console logger.
- ///
- public const string FriendlyName = "Trx";
-
- ///
- /// Prefix of the data collector
- ///
- public const string DataCollectorUriPrefix = "dataCollector://";
-
- ///
- /// Log file parameter key
- ///
- public const string LogFileNameKey = "LogFileName";
-
- #endregion
-
#region Fields
///
@@ -63,9 +38,13 @@ internal class TrxLogger : ITestLoggerWithParameters
private string trxFilePath;
private TrxLoggerObjectModel.TestRun testRun;
- private List results;
- private List testElements;
- private List entries;
+ private ConcurrentDictionary results;
+ private ConcurrentDictionary testElements;
+ private ConcurrentDictionary entries;
+
+ // Caching results and inner test entries for constant time lookup for inner parents.
+ private ConcurrentDictionary innerResults;
+ private ConcurrentDictionary innerTestEntries;
///
/// Specifies the run level "out" messages
@@ -206,7 +185,7 @@ internal TrxLoggerObjectModel.TestOutcome TestResultOutcome
///
/// Event args
///
- internal void TestMessageHandler(object sender, TestRunMessageEventArgs e)
+ public void TestMessageHandler(object sender, TestRunMessageEventArgs e)
{
ValidateArg.NotNull
[TestMethod]
- public void GetQToolsTestElementFromTestCaseShouldNotFailWhenThereIsNoTestCategoreis()
+ public void ToTestElementShouldNotFailWhenThereIsNoTestCategoreis()
{
ObjectModel.TestCase testCase = CreateTestCase("TestCase1");
ObjectModel.TestResult result = new ObjectModel.TestResult(testCase);
- TrxLoggerObjectModel.UnitTestElement unitTestElement = Converter.GetQToolsTestElementFromTestCase(result);
+ var unitTestElement = Converter.ToTestElement(testCase.Id, Guid.Empty, Guid.Empty, testCase.DisplayName, TrxLoggerConstants.UnitTestType, testCase);
object[] expected = Enumerable.Empty