summaryrefslogtreecommitdiffstats
path: root/.github/scripts/tests/junit-postprocess.py
diff options
context:
space:
mode:
authorNikita Kozlovskiy <[email protected]>2023-08-16 14:39:21 +0300
committernkozlovskiy <[email protected]>2023-08-16 16:15:08 +0300
commit193c3861dc3bed68a1d0a394effdda630d0eb551 (patch)
treebe90a52ef8b2b6eae122641e3c6b5d32748afca9 /.github/scripts/tests/junit-postprocess.py
parent8662d99f68311ede697154b9fb02e3fd9e9ad52e (diff)
CI: group tests by test shard name
CI: group tests by test shard name Pull Request resolved: #332
Diffstat (limited to '.github/scripts/tests/junit-postprocess.py')
-rwxr-xr-x.github/scripts/tests/junit-postprocess.py86
1 files changed, 39 insertions, 47 deletions
diff --git a/.github/scripts/tests/junit-postprocess.py b/.github/scripts/tests/junit-postprocess.py
index 150cdfb09e7..df8d07b0f3e 100755
--- a/.github/scripts/tests/junit-postprocess.py
+++ b/.github/scripts/tests/junit-postprocess.py
@@ -1,80 +1,72 @@
#!/usr/bin/env python3
-import os
-import glob
import argparse
+import glob
+import os
+import re
import xml.etree.ElementTree as ET
-from mute_utils import mute_target, update_suite_info, MutedTestCheck
-from junit_utils import add_junit_property
+from mute_utils import MuteTestCheck, mute_target, recalc_suite_info
-def case_iterator(root):
- for case in root.findall("testcase"):
- cls, method = case.attrib["classname"], case.attrib["name"]
- yield case, cls, method
+shard_suffix_re = re.compile(r"-\d+$")
-def attach_filename(testcase, filename):
- shardname = os.path.splitext(filename)[0]
- add_junit_property(testcase, "shard", shardname)
+def update_testname(fn, testcase):
+ shardname = os.path.splitext(os.path.basename(fn))[0]
+ shardname = shard_suffix_re.sub("", shardname)
+ clsname = testcase.get("classname")
+ tstname = testcase.get("name")
+ testcase.set("classname", shardname)
-def postprocess_junit(is_mute_test, folder, no_attach_filename, dry_run):
- for fn in glob.glob(os.path.join(folder, "*.xml")):
- tree = ET.parse(fn)
- root = tree.getroot()
- total_err = total_fail = 0
+ testcase.set("name", f"{clsname}::{tstname}")
+ testcase.set("id", f"{shardname}_{clsname}_{tstname}")
+
+ return f"{shardname}/{clsname}::{tstname}"
- for suite in root.findall("testsuite"):
- fail_cnt = error_cnt = 0
- for case, cls, method in case_iterator(suite):
- if not no_attach_filename:
- attach_filename(case, os.path.basename(fn))
+def postprocess_yunit(fn, mute_check: MuteTestCheck, dry_run):
+ try:
+ tree = ET.parse(fn)
+ except ET.ParseError as e:
+ print(f"Unable to parse {fn}: {e}")
+ return
+
+ root = tree.getroot()
- if is_mute_test(cls, method):
- if mute_target(case):
- print(f"mute {cls}::{method}")
- fail_cnt += 1
- elif mute_target(case, "error"):
- print(f"mute error {cls}::{method}")
- error_cnt += 1
+ for testsuite in root.findall("testsuite"):
+ need_recalc = False
+ for testcase in testsuite.findall("testcase"):
+ new_name = update_testname(fn, testcase)
- if fail_cnt or error_cnt:
- update_suite_info(suite, n_remove_failures=fail_cnt, n_remove_errors=error_cnt,
- n_skipped=fail_cnt + error_cnt)
- total_err += error_cnt
- total_fail += fail_cnt
+ if mute_check(new_name) and mute_target(testcase):
+ print(f"mute {new_name}")
+ need_recalc = True
- if total_fail or total_err:
- update_suite_info(root, n_remove_errors=total_err, n_remove_failures=total_fail,
- n_skipped=total_err + total_fail)
+ if need_recalc:
+ recalc_suite_info(testsuite)
- print(f"{'(dry-run) ' if dry_run else ''}patch {fn}")
+ print(f"{'(dry-run) ' if dry_run else ''}save {fn}")
- if not dry_run:
- tree.write(fn, xml_declaration=True, encoding="UTF-8")
+ if not dry_run:
+ tree.write(fn, xml_declaration=True, encoding="UTF-8")
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--filter-file", required=True)
- parser.add_argument("--no-attach-filename", action="store_true", default=False)
parser.add_argument("--dry-run", action="store_true", default=False)
parser.add_argument("yunit_path")
+
args = parser.parse_args()
if not os.path.isdir(args.yunit_path):
print(f"{args.yunit_path} is not a directory, exit")
raise SystemExit(-1)
- # FIXME: add gtest filter file ?
- is_mute_test = MutedTestCheck(args.filter_file)
-
- if not is_mute_test.has_rules:
- print("nothing to mute")
- return
+ mute_check = MuteTestCheck(args.filter_file)
- postprocess_junit(is_mute_test, args.yunit_path, args.no_attach_filename, args.dry_run)
+ for fn in glob.glob(os.path.join(args.yunit_path, "*.xml")):
+ postprocess_yunit(fn, mute_check, args.dry_run)
if __name__ == "__main__":