From 4f150c451cc185c7cb3ea1f0ac77241b42cb5e49 Mon Sep 17 00:00:00 2001 From: Matt Galbraith Date: Thu, 20 May 2021 14:39:31 -0700 Subject: [PATCH] Workaround for https://github.com/dotnet/arcade/issues/7371. Have azure-pipelines reporter parse XML for failures if ADO fails for any reason, return 0 if we actually passed. --- .../Sdk/tools/azure-pipelines/reporter/run.py | 132 +++++++++++++----- 1 file changed, 98 insertions(+), 34 deletions(-) diff --git a/src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py b/src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py index d596132a795..3788688da87 100644 --- a/src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py +++ b/src/Microsoft.DotNet.Helix/Sdk/tools/azure-pipelines/reporter/run.py @@ -1,10 +1,11 @@ import os +import re import sys import traceback import logging from queue import Queue from threading import Thread, Lock -from typing import Tuple, Optional +from typing import Tuple, Optional, List from test_results_reader import read_results from helpers import batch, get_env @@ -13,6 +14,7 @@ workerFailedLock = Lock() workerFailed = False + class UploadWorker(Thread): def __init__(self, queue, idx, collection_uri, team_project, test_run_id, access_token): super(UploadWorker, self).__init__() @@ -50,7 +52,6 @@ def run(self): self.queue.task_done() - def process_args() -> Tuple[str, str, str, Optional[str]]: if len(sys.argv) < 4 or len(sys.argv) > 5: print("Usage:") @@ -70,52 +71,115 @@ def process_args() -> Tuple[str, str, str, Optional[str]]: return collection_uri, team_project, test_run_id, access_token +# This reporter will be phased out soon, but until then we need to deal with ADO outages and failures from client lib +# Currently only understands XUnit TestResults.xml (should not be around long enough to need more) +# See https://github.com/dotnet/arcade/issues/7371 for details +def check_passed_to_workaround_ado_api_failure(dirs_to_check: List[str]) -> bool: + print("Reporting has failed. Running mitigation for https://github.com/dotnet/arcade/issues/7371") + found_a_result = False + acceptable_xunit_file_names = [ + "testResults.xml", + "test-results.xml", + "test_results.xml", + "TestResults.xUnit.xml" + ] + + failure_count_found = 0 + + for dir_name in dirs_to_check: + print("Searching '{}' for test results files".format(dir_name)) + for root, dirs, files in os.walk(dir_name): + for file_name in files: + if file_name in acceptable_xunit_file_names: + file_path = os.path.join(root, file_name) + print('Found results file {} '.format(file_path)) + found_a_result = True + failure_count_found += get_failure_count(file_path) + + if found_a_result: + if failure_count_found == 0: + print("Reporter script has failed, but we were able to find XUnit test results with no failures.") + return True + else: + print("Reporter script has failed, but we were able to find XUnit test results with failures ({})" + .format(str(failure_count_found))) + else: + print("Tried to mitigate but no results files found.") + return False + + +def get_failure_count(test_results_path: str): + fail_count = 0 + with open(test_results_path, encoding="utf-8") as result_file: + total_regex = re.compile(r'failed="(\d+)"') + for line in result_file: + if '