Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write props of tests into trx #14905

Merged
merged 2 commits into from
Jan 20, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ private FeatureFlag() { }
// Disable not sharing .NET Framework testhosts. Which will return behavior to sharing testhosts when they are running .NET Framework dlls, and are not disabling appdomains or running in parallel.
public const string VSTEST_DISABLE_SHARING_NETFRAMEWORK_TESTHOST = nameof(VSTEST_DISABLE_SHARING_NETFRAMEWORK_TESTHOST);

// Disable outputting Traits into TRX file in the Properties node.
public const string VSTEST_DISABLE_TRX_WRITE_PROPERTIES = nameof(VSTEST_DISABLE_TRX_WRITE_PROPERTIES);

[Obsolete("Only use this in tests.")]
internal static void Reset()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Runtime.CompilerServices;

[assembly: InternalsVisibleTo("Microsoft.TestPlatform.TestHostRuntimeProvider, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("Microsoft.VisualStudio.TestPlatform.Extensions.Trx.TestLogger, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("vstest.console, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("vstest.console.arm64, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
[assembly: InternalsVisibleTo("Microsoft.TestPlatform.CoreUtilities.UnitTests, PublicKey=002400000480000094000000060200000024000052534131000400000100010007d1fa57c4aed9f0a32e84aa0faefd0de9e8fd6aec8f87fb03766c834c99921eb23be79ad9d5dcc1dd9ad236132102900b723cf980957fc4e177108fc607774f29e8320e92ea05ece4e821c0a5efe8f1645c4c0c93c1ab99285d622caa652c1dfad63d745d6f2de5f17e5eaf0fc4963d261c8a12436518206dc093344d5ad293")]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@

<ItemGroup>
<Compile Include="$(RepoRoot)src\Microsoft.TestPlatform.TestHostProvider\Properties\TestExtensionTypesAttribute.cs" Link="Properties\TestExtensionTypesAttribute.cs" />
<Compile Include="..\..\shared\NullableAttributes.cs" Link="NullableAttributes.cs" />
</ItemGroup>

<ItemGroup>
Expand All @@ -49,11 +48,6 @@
</ItemGroup>

<ItemGroup>
<Compile Update="NullableHelpers.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>NullableHelpers.tt</DependentUpon>
</Compile>
<Compile Update="Resources\TrxResource.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
Expand Down Expand Up @@ -81,13 +75,6 @@
<AdditionalFiles Include="PublicAPI/$(TargetFramework)/PublicAPI.Unshipped.txt" />
</ItemGroup>

<ItemGroup>
<None Update="NullableHelpers.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>NullableHelpers.cs</LastGenOutput>
</None>
</ItemGroup>

<ItemGroup>
<Service Include="{508349b6-6b84-4df5-91f0-309beebad82d}" />
</ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;

using Microsoft.TestPlatform.Extensions.TrxLogger.XML;
using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger;

namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel;

/// <summary>
/// Stores a string which categorizes the Test
/// </summary>
internal sealed class Property : IXmlTestStore
{
[StoreXmlSimpleField(Location = "@Key", DefaultValue = "")]
private readonly string _key = string.Empty;
[StoreXmlSimpleField(Location = "@Value", DefaultValue = "")]
private readonly string _value = string.Empty;

/// <summary>
/// Create a new item with the property set
/// </summary>
public Property(string key, string value)
{
// Treat null as empty.

_key = StripIllegalChars(key);
_value = StripIllegalChars(value);
}

/// <summary>
/// Gets the property for this Trait
/// </summary>
public string Trait
{
get
{
return _key;
}
}

private static string StripIllegalChars(string property)
{
string ret = property.Trim();
ret = ret.Replace("&", string.Empty);
ret = ret.Replace("|", string.Empty);
ret = ret.Replace("!", string.Empty);
ret = ret.Replace(",", string.Empty);
return ret;
}

/// <summary>
/// Compare the values of the items
/// </summary>
/// <param name="other">Value being compared to.</param>
/// <returns>True if the values are the same and false otherwise.</returns>
public override bool Equals(object? other)
{
if (other is not Property otherItem)
{
return false;
}

TPDebug.Assert(_key != null, "property is null");
return string.Equals(_key, otherItem._key, StringComparison.OrdinalIgnoreCase);
}

/// <summary>
/// Convert the property name to a hashcode
/// </summary>
/// <returns>Hashcode of the property.</returns>
public override int GetHashCode()
{
TPDebug.Assert(_key != null, "property is null");
return _key.ToUpperInvariant().GetHashCode();
}

/// <summary>
/// Convert the property name to a string
/// </summary>
/// <returns>The property.</returns>
public override string ToString()
{
TPDebug.Assert(_key != null, "property is null");
return _key;
}

/// <summary>
/// Saves the class under the XmlElement.
/// </summary>
/// <param name="element"> XmlElement element </param>
/// <param name="parameters"> XmlTestStoreParameters parameters</param>
public void Save(System.Xml.XmlElement element, XmlTestStoreParameters? parameters)
{
new XmlPersistence().SaveSingleFields(element, this, parameters);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System.Text;

using Microsoft.TestPlatform.Extensions.TrxLogger.Utility;
using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger;

namespace Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel;

/// <summary>
/// A collection of strings which categorize the test.
/// </summary>
internal sealed class PropertyCollection : EqtBaseCollection<Property>
{
/// <summary>
/// Creates an empty PropertyCollection.
/// </summary>
public PropertyCollection()
{
}

/// <summary>
/// Adds the property.
/// </summary>
/// <param name="key">Key to be added.</param>
/// <param name="value">Value to be added.</param>
public void Add(string key, string value)
{
Add(new Property(key, value));
}

/// <summary>
/// Adds the property.
/// </summary>
/// <param name="item">Property to be added.</param>
public override void Add(Property item)
{
EqtAssert.ParameterNotNull(item, nameof(item));

// Don't add empty items.
if (!item.Trait.IsNullOrEmpty())
{
base.Add(item);
}
}

/// <summary>
/// Convert the PropertyCollection to a string.
/// each item is surrounded by a comma (,)
/// </summary>
/// <returns></returns>
public override string ToString()
{
StringBuilder returnString = new();
if (Count > 0)
{
returnString.Append(',');
foreach (Property item in this)
{
returnString.Append(item.Trait);
returnString.Append(',');
}
}

return returnString.ToString();
}

/// <summary>
/// Convert the PropertyCollection to an array of strings.
/// </summary>
/// <returns>Array of strings containing the test categories.</returns>
public string[] ToArray()
{
string[] result = new string[Count];

int i = 0;
foreach (Property item in this)
{
result[i++] = item.Trait;
}

return result;
}

/// <summary>
/// Compare the collection items
/// </summary>
/// <param name="obj">other collection</param>
/// <returns>true if the collections contain the same items</returns>
public override bool Equals(object? obj)
{
bool result = false;

if (obj is not PropertyCollection other)
{
// Other object is not a TraitItemCollection.
result = false;
}
else if (ReferenceEquals(this, other))
{
// The other object is the same object as this one.
result = true;
}
else if (Count != other.Count)
{
// The count of categories in the other object does not
// match this one, so they are not equal.
result = false;
}
else
{
// Check each item and return on the first mismatch.
foreach (Property item in this)
{
if (!other.Contains(item))
{
result = false;
break;
}
}
}

return result;
}

/// <summary>
/// Return the hash code of this collection
/// </summary>
/// <returns>The hashcode.</returns>
public override int GetHashCode()
{
return base.GetHashCode();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ internal abstract class TestElement : ITestElement, IXmlTestStore
protected TestExecId _executionId;
protected TestExecId _parentExecutionId;
protected TestCategoryItemCollection _testCategories;
protected PropertyCollection _properties;
protected WorkItemCollection _workItems;
protected TestListCategoryId _catId;

Expand All @@ -46,6 +47,7 @@ public TestElement(Guid id, string name, string adapter)
_executionId = TestExecId.Empty;
_parentExecutionId = TestExecId.Empty;
_testCategories = new TestCategoryItemCollection();
_properties = new PropertyCollection();
_workItems = new WorkItemCollection();
_isRunnable = true;
_catId = TestListCategoryId.Uncategorized;
Expand Down Expand Up @@ -185,6 +187,21 @@ public WorkItemCollection WorkItems
}
}


/// <summary>
/// Gets or sets the test traits.
/// </summary>
public PropertyCollection Traits
{
get { return _properties; }

set
{
EqtAssert.ParameterNotNull(value, "value");
_properties = value;
}
}

/// <summary>
/// Gets the adapter name.
/// </summary>
Expand Down Expand Up @@ -245,6 +262,7 @@ public virtual void Save(System.Xml.XmlElement element, XmlTestStoreParameters?
h.SaveSimpleField(element, "@priority", _priority, DefaultPriority);
h.SaveSimpleField(element, "Owners/Owner/@name", _owner, string.Empty);
h.SaveObject(_testCategories, element, "TestCategory", parameters);
h.SaveObject(_properties, element, "Properties", parameters);

if (_executionId != null)
h.SaveGuid(element, "Execution/@id", _executionId.Id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger;
using Microsoft.VisualStudio.TestPlatform.ObjectModel;
using Microsoft.VisualStudio.TestPlatform.Utilities.Helpers.Interfaces;
using Microsoft.VisualStudio.TestPlatform.Utilities;

using TrxLoggerResources = Microsoft.VisualStudio.TestPlatform.Extensions.TrxLogger.Resources.TrxResource;
using TrxObjectModel = Microsoft.TestPlatform.Extensions.TrxLogger.ObjectModel;
Expand Down Expand Up @@ -76,6 +77,14 @@ public static ITestElement ToTestElement(
testElement.WorkItems.Add(workItem);
}

if (!FeatureFlag.Instance.IsSet(nameof(FeatureFlag.VSTEST_DISABLE_TRX_WRITE_PROPERTIES)))
{
foreach (var trait in rockSteadyTestCase.Traits.Where(t => t.Name is not "Owner" and not "Priority"))
{
testElement.Traits.Add(new Property(trait.Name, trait.Value));
}
}

return testElement;
}

Expand Down