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

Deprecate xunit reporter #7931

Merged
merged 3 commits into from
Sep 30, 2021
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
3 changes: 0 additions & 3 deletions eng/common/templates/steps/send-to-helix.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ parameters:
IncludeDotNetCli: false # optional -- true will download a version of the .NET CLI onto the Helix machine as a correlation payload; requires DotNetCliPackageType and DotNetCliVersion
DotNetCliPackageType: '' # optional -- either 'sdk', 'runtime' or 'aspnetcore-runtime'; determines whether the sdk or runtime will be sent to Helix; see https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
DotNetCliVersion: '' # optional -- version of the CLI to send to Helix; based on this: https://raw.githubusercontent.com/dotnet/core/main/release-notes/releases-index.json
EnableXUnitReporter: false # optional -- true enables XUnit result reporting to Mission Control
WaitForWorkItemCompletion: true # optional -- true will make the task wait until work items have been completed and fail the build if work items fail. False is "fire and forget."
IsExternal: false # [DEPRECATED] -- doesn't do anything, jobs are external if HelixAccessToken is empty and Creator is set
HelixBaseUri: 'https://helix.dot.net/' # optional -- sets the Helix API base URI (allows targeting int)
Expand Down Expand Up @@ -54,7 +53,6 @@ steps:
IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }}
WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
HelixBaseUri: ${{ parameters.HelixBaseUri }}
Creator: ${{ parameters.Creator }}
Expand Down Expand Up @@ -85,7 +83,6 @@ steps:
IncludeDotNetCli: ${{ parameters.IncludeDotNetCli }}
DotNetCliPackageType: ${{ parameters.DotNetCliPackageType }}
DotNetCliVersion: ${{ parameters.DotNetCliVersion }}
EnableXUnitReporter: ${{ parameters.EnableXUnitReporter }}
WaitForWorkItemCompletion: ${{ parameters.WaitForWorkItemCompletion }}
HelixBaseUri: ${{ parameters.HelixBaseUri }}
Creator: ${{ parameters.Creator }}
Expand Down
1 change: 0 additions & 1 deletion src/Microsoft.DotNet.Helix/Sdk/Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ Given a local folder `$(TestFolder)` containing `runtests.cmd`, this will run `r
test-results.xml
test_results.xml
-->
<EnableXUnitReporter>false</EnableXUnitReporter>
<!-- Instruct the sdk to wait for test result ingestion by MC, and fail if there are any failed work items or tests. -->
<FailOnMissionControlTestFailure>false</FailOnMissionControlTestFailure>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project>
<PropertyGroup>
<EnableXUnitReporter Condition=" '$(EnableXUnitReporter)' != 'true' ">false</EnableXUnitReporter>
</PropertyGroup>

<Project>
<PropertyGroup Condition=" '$(HelixTestConfigurationFilePath)' == '' ">
<HelixTestConfigurationFilePath Condition=" '$(RepositoryEngineeringDir)' != '' ">$(RepositoryEngineeringDir)/test-configuration.json</HelixTestConfigurationFilePath>
</PropertyGroup>
Expand All @@ -23,18 +19,6 @@

<Import Project="$(_HelixMonoQueueTargets)" Condition="'$(_HelixMonoQueueTargets)' != ''"/>

<Target Name="AddXUnitReporter" Condition="$(EnableXUnitReporter)" BeforeTargets="CoreTest">
<ItemGroup>
<HelixCorrelationPayload Include="$(MSBuildThisFileDirectory)xunit-reporter"/>
</ItemGroup>
<PropertyGroup>
<HelixPostCommands Condition="$(IsPosixShell)">$(HelixPostCommands);$HELIX_PYTHONPATH -B $HELIX_CORRELATION_PAYLOAD/xunit-reporter.py</HelixPostCommands>
<HelixPostCommands Condition="!$(IsPosixShell)">$(HelixPostCommands);%HELIX_PYTHONPATH% -B %HELIX_CORRELATION_PAYLOAD%\xunit-reporter.py</HelixPostCommands>

<MaxRetryCount Condition="'$(MaxRetryCount)' == ''">0</MaxRetryCount>
</PropertyGroup>
</Target>

<ItemGroup>
<HelixProperties Condition="'$(HelixConfiguration)' != ''" Include="configuration" Value="$(HelixConfiguration)" />
<HelixProperties Condition="'$(HelixArchitecture)' != ''" Include="architecture" Value="$(HelixArchitecture)" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ There are some required configuration properties that need to be set for XHarnes
<HelixType>test/product/</HelixType>
<HelixBaseUri>https://helix.int-dot.net</HelixBaseUri>
<Creator>$(BUILD_SOURCEVERSIONAUTHOR)</Creator>
<EnableXUnitReporter>true</EnableXUnitReporter>
<EnableAzurePipelinesReporter>true</EnableAzurePipelinesReporter>
</PropertyGroup>

Expand Down
122 changes: 4 additions & 118 deletions src/Microsoft.DotNet.Helix/Sdk/tools/xunit-reporter/xunit-reporter.py
Original file line number Diff line number Diff line change
@@ -1,124 +1,10 @@
#!/usr/bin/env python

import re
import os
import urllib
import helix.azure_storage
import helix.event
import helix.settings
import helix.logs

log = helix.logs.get_logger()

acceptableXUnitFileNames = [
"testResults.xml",
"test-results.xml",
"test_results.xml",
"TestResults.xUnit.xml"
]

class HelixHelper:
def __init__(self, settings):
self.settings = settings
self.event_client = helix.event.create_from_uri(settings.event_uri)
self.upload_client = helix.azure_storage.get_upload_client(settings)

def error(self, error_type, message, log_uri=None):
self.event_client.error(self.settings, error_type, message, log_uri)

def xunit_event(self, results_uri, test_count, file_name):
self.event_client.send(
{
'Type': 'XUnitTestResult',
'WorkItemId': self.settings.workitem_id,
'WorkItemFriendlyName': self.settings.workitem_friendly_name,
'CorrelationId': self.settings.correlation_id,
'ResultsXmlUri': results_uri,
'TestCount': test_count,
}
)

def file_event(self, results_uri, file_name):
self.event_client.send(
{
'Type': 'File',
'Uri': results_uri,
'FileName': file_name,
'WorkItemId': self.settings.workitem_id,
'WorkItemFriendlyName': self.settings.workitem_friendly_name,
'CorrelationId': self.settings.correlation_id,
}
)

def upload_file_to_storage(self, file_path):
""" Copy file specified to azure storage account using Helix infrastructure
:param file_path: Path to file to be copied to Azure storage
:type file_path:string
"""
try:
return self.upload_client.upload(file_path, os.path.basename(file_path))
except ValueError:
self.error("FailedUpload", "Failed to upload "+file_path+"after retry")

def findXUnitResults(search_dir):
for root, dirs, files in os.walk(search_dir):
for file_name in files:
if file_name in acceptableXUnitFileNames:
return os.path.join(root, file_name)
return None

def main():
settings = helix.settings.settings_from_env()

if settings.output_uri is None or settings.event_uri is None:
log.error("Unable to report xunit results: output_uri and/or event_uri are not set.")
return 1

helper = HelixHelper(settings)
working_dir = settings.workitem_working_dir
upload_dir = settings.workitem_upload_dir
need_to_upload_results = True

results_path = findXUnitResults(working_dir)

if results_path is None:
log.info("Didn't find test results in working directory, trying upload folder")
results_path = findXUnitResults(upload_dir)
need_to_upload_results = False

if results_path is None:
log.error("Unable to report xunit results: no test results xml file found.")
return 2

log.info("Uploading results from {}".format(results_path))

with open(results_path, encoding="utf-8") as result_file:
test_count = 0
total_regex = re.compile(r'total="(\d+)"')
for line in result_file:
if '<assembly ' in line:
match = total_regex.search(line)
if match is not None:
test_count = int(match.groups()[0])
break

log.info("Sending XUnit test result events")
if need_to_upload_results:
result_url = helper.upload_file_to_storage(results_path)
helper.file_event(result_url, os.path.basename(results_path))
else:
# Will be uploaded, but we still need to send events.
# This prevents duplicate uploads and errors from them in logs
result_url = '{container}/{file}{sas}'.format(
container=settings.output_uri,
file=os.path.basename(results_path),
sas=settings.output_read_token)

helper.xunit_event(result_url, test_count, os.path.basename(results_path))

return 0


if __name__ == '__main__':
import sys
sys.exit(main())
settings = helix.settings.settings_from_env()
event_client = helix.event.create_from_uri(settings.event_uri)
event_client.warning(settings, "Obsolete", "xunit-reporter.py is deprecated, please remove 'EnableXUnitReporter' from your build and use 'EnableAzurePipelinesReporter' instead.")
print("This reporter is deprecated")
2 changes: 0 additions & 2 deletions tests/XHarness.Tests.Common.props
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,13 @@
<HelixType>test/product/</HelixType>
<TestRunNamePrefix>$(AGENT_JOBNAME)</TestRunNamePrefix>
<IncludeXHarnessCli>true</IncludeXHarnessCli>
<EnableXUnitReporter>true</EnableXUnitReporter>
<EnableAzurePipelinesReporter>true</EnableAzurePipelinesReporter>
<HelixBaseUri>https://helix.dot.net</HelixBaseUri>
<EnableXHarnessTelemetry>true</EnableXHarnessTelemetry>
</PropertyGroup>

<!-- For non-ci local runs -->
<PropertyGroup Condition=" '$(AGENT_JOBNAME)' == '' ">
<EnableXUnitReporter>false</EnableXUnitReporter>
<EnableAzurePipelinesReporter>false</EnableAzurePipelinesReporter>
</PropertyGroup>

Expand Down