Files
TheRock/debug-tools/rocgdb/source/gdb/testsuite/analyze-racy-logs.py
T
derek.holloway 7502bf64a4
CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
Flatten subprojects into a single base monorepo
2026-09-02 16:34:47 -07:00

181 lines
6.6 KiB
Python
Executable File

#!/usr/bin/env python3
# Copyright (C) 2016-2024 Free Software Foundation, Inc.
#
# This file is part of GDB.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# This program is used to analyze the test results (i.e., *.sum files)
# generated by GDB's testsuite, and print the testcases that are found
# to be racy.
#
# Racy testcases are considered as being testcases which can
# intermittently FAIL (or PASS) when run two or more times
# consecutively, i.e., tests whose results are not deterministic.
#
# This program is invoked when the user runs "make check" and
# specifies the RACY_ITER environment variable.
import re
import sys
# The (global) dictionary that stores the associations between a *.sum
# file and its results. The data inside it will be stored as:
#
# files_and_tests = { 'file1.sum' : { 'PASS' : { 'test1', 'test2' ... },
# 'FAIL' : { 'test5', 'test6' ... },
# ...
# },
# { 'file2.sum' : { 'PASS' : { 'test1', 'test3' ... },
# ...
# }
# }
files_and_tests: dict[str, dict[str, set[str]]] = dict()
# The relatioships between various states of the same tests that
# should be ignored. For example, if the same test PASSes on a
# testcase run but KFAILs on another, this test should be considered
# racy because a known-failure is... known.
ignore_relations = {"PASS": "KFAIL"}
# We are interested in lines that start with '.?(PASS|FAIL)'. In
# other words, we don't process errors (maybe we should).
sum_matcher = re.compile("^(.?(PASS|FAIL)): (.*)$")
def parse_sum_line(line: str, dic: dict[str, set[str]]):
"""Parse a single LINE from a sumfile, and store the results in the
dictionary referenced by DIC."""
global sum_matcher
line = line.rstrip()
m = re.match(sum_matcher, line)
if m:
result = m.group(1)
test_name = m.group(3)
# Remove tail parentheses. These are likely to be '(timeout)'
# and other extra information that will only confuse us.
test_name = re.sub(r"(\s+)?\(.*$", "", test_name)
if result not in dic.keys():
dic[result] = set()
if test_name in dic[result]:
# If the line is already present in the dictionary, then
# we include a unique identifier in the end of it, in the
# form or '<<N>>' (where N is a number >= 2). This is
# useful because the GDB testsuite is full of non-unique
# test messages; however, if you process the racy summary
# file you will also need to perform this same operation
# in order to identify the racy test.
i = 2
while True:
nname = test_name + " <<" + str(i) + ">>"
if nname not in dic[result]:
break
i += 1
test_name = nname
dic[result].add(test_name)
def read_sum_files(files: list[str]):
"""Read the sumfiles (passed as a list in the FILES variable), and
process each one, filling the FILES_AND_TESTS global dictionary with
information about them."""
global files_and_tests
for x in files:
with open(x, "r") as f:
files_and_tests[x] = dict()
for line in f.readlines():
parse_sum_line(line, files_and_tests[x])
def identify_racy_tests():
"""Identify and print the racy tests. This function basically works
on sets, and the idea behind it is simple. It takes all the sets that
refer to the same result (for example, all the sets that contain PASS
tests), and compare them. If a test is present in all PASS sets, then
it is not racy. Otherwise, it is.
This function does that for all sets (PASS, FAIL, KPASS, KFAIL, etc.),
and then print a sorted list (without duplicates) of all the tests
that were found to be racy."""
global files_and_tests
# First, construct two dictionaries that will hold one set of
# testcases for each state (PASS, FAIL, etc.).
#
# Each set in NONRACY_TESTS will contain only the non-racy
# testcases for that state. A non-racy testcase is a testcase
# that has the same state in all test runs.
#
# Each set in ALL_TESTS will contain all tests, racy or not, for
# that state.
nonracy_tests: dict[str, set[str]] = dict()
all_tests: dict[str, set[str]] = dict()
for f in files_and_tests:
for state in files_and_tests[f]:
try:
nonracy_tests[state] &= files_and_tests[f][state].copy()
except KeyError:
nonracy_tests[state] = files_and_tests[f][state].copy()
try:
all_tests[state] |= files_and_tests[f][state].copy()
except KeyError:
all_tests[state] = files_and_tests[f][state].copy()
# Now, we eliminate the tests that are present in states that need
# to be ignored. For example, tests both in the PASS and KFAIL
# states should not be considered racy.
ignored_tests: set[str] = set()
for s1, s2 in ignore_relations.items():
try:
ignored_tests |= all_tests[s1] & all_tests[s2]
except:
continue
racy_tests: set[str] = set()
for f in files_and_tests:
for state in files_and_tests[f]:
racy_tests |= files_and_tests[f][state] - nonracy_tests[state]
racy_tests = racy_tests - ignored_tests
# Print the header.
print("\t\t=== gdb racy tests ===\n")
# Print each test.
for line in sorted(racy_tests):
print(line)
# Print the summary.
print("\n")
print("\t\t=== gdb Summary ===\n")
print("# of racy tests:\t\t%d" % len(racy_tests))
if __name__ == "__main__":
if len(sys.argv) < 3:
# It only makes sense to invoke this program if you pass two
# or more files to be analyzed.
sys.exit("Usage: %s [FILE] [FILE] ..." % sys.argv[0])
read_sum_files(sys.argv[1:])
identify_racy_tests()
exit(0)