diff options
Diffstat (limited to 'tests/auto/testlib/selftests/generate_expected_output.py')
-rwxr-xr-x | tests/auto/testlib/selftests/generate_expected_output.py | 128 |
1 files changed, 80 insertions, 48 deletions
diff --git a/tests/auto/testlib/selftests/generate_expected_output.py b/tests/auto/testlib/selftests/generate_expected_output.py index 70813ab9fe..350d20fa27 100755 --- a/tests/auto/testlib/selftests/generate_expected_output.py +++ b/tests/auto/testlib/selftests/generate_expected_output.py @@ -1,31 +1,6 @@ #!/usr/bin/env python3 -############################################################################# -## -## Copyright (C) 2020 The Qt Company Ltd. -## Contact: https://www.qt.io/licensing/ -## -## This file is part of the release tools of the Qt Toolkit. -## -## $QT_BEGIN_LICENSE:GPL-EXCEPT$ -## Commercial License Usage -## Licensees holding valid commercial Qt licenses may use this file in -## accordance with the commercial license agreement provided with the -## Software or, alternatively, in accordance with the terms contained in -## a written agreement between you and The Qt Company. For licensing terms -## and conditions see https://www.qt.io/terms-conditions. For further -## information use the contact form at https://www.qt.io/contact-us. -## -## GNU General Public License Usage -## Alternatively, this file may be used under the terms of the GNU -## General Public License version 3 as published by the Free Software -## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT -## included in the packaging of this file. Please review the following -## information to ensure the GNU General Public License requirements will -## be met: https://www.gnu.org/licenses/gpl-3.0.html. -## -## $QT_END_LICENSE$ -## -############################################################################# +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 from argparse import ArgumentParser, RawTextHelpFormatter import os @@ -49,22 +24,24 @@ the saved copies of the output. """ -DEFAULT_FORMATS = ['xml', 'txt', 'junitxml', 'lightxml', 'teamcity', 'tap'] +DEFAULT_FORMATS = ['xml', 'txt', 'junitxml', 'lightxml', 'teamcity', 'tap', 'csv'] TESTS = ['assert', 'badxml', 'benchlibcallgrind', 'benchlibcounting', 'benchlibeventcounter', 'benchliboptions', 'benchlibtickcounter', 'benchlibwalltime', 'blacklisted', 'cmptest', 'commandlinedata', 'counting', 'crashes', 'datatable', 'datetime', 'deleteLater', - 'deleteLater_noApp', 'differentexec', 'exceptionthrow', 'expectfail', - 'failcleanup', 'faildatatype', 'failfetchtype', 'failinit', - 'failinitdata', 'fetchbogus', 'findtestdata', 'float', 'globaldata', - 'longstring', 'maxwarnings', 'multiexec', 'pairdiagnostics', 'pass', + 'deleteLater_noApp', 'differentexec', 'eventloop', 'exceptionthrow', + 'expectfail', "extendedcompare", 'failcleanup', 'failcleanuptestcase', + 'faildatatype', 'failfetchtype', 'failinit', 'failinitdata', + 'fetchbogus', 'findtestdata', 'float', 'globaldata', 'longstring', + 'maxwarnings', 'mouse', 'multiexec', 'pairdiagnostics', 'pass', 'printdatatags', 'printdatatagswithglobaltags', 'qexecstringlist', - 'signaldumper', 'silent', 'singleskip', 'skip', 'skipcleanup', - 'skipinit', 'skipinitdata', 'sleep', 'strcmp', 'subtest', 'testlib', - 'tuplediagnostics', 'verbose1', 'verbose2', 'verifyexceptionthrown', - 'warnings', 'watchdog', 'xunit', 'keyboard'] + 'signaldumper', 'silent', 'silent_fatal', 'singleskip', 'skip', + 'skipblacklisted', 'skipcleanup', 'skipcleanuptestcase', 'skipinit', + 'skipinitdata', 'sleep', 'strcmp', 'subtest', 'testlib', 'tuplediagnostics', + 'verbose1', 'verbose2', 'verifyexceptionthrown', 'warnings', 'watchdog', + 'junit', 'keyboard'] class Fail (Exception): pass @@ -99,8 +76,12 @@ class Cleaner (object): def _read_qt_version(qtbase_dir): cmake_conf_file = os.path.join(qtbase_dir, '.cmake.conf') with open(cmake_conf_file) as f: - qtver = f.readline().strip() - return qtver.split('"')[1] # set(QT_REPO_MODULE_VERSION "6.1.0") + for line in f: + # set(QT_REPO_MODULE_VERSION "6.1.0") + if 'set(QT_REPO_MODULE_VERSION' in line: + return line.strip().split('"')[1] + + raise RuntimeError("Someone broke .cmake.conf formatting again") @staticmethod def __getPatterns(patterns = ( @@ -116,6 +97,7 @@ class Cleaner (object): (r'(Config: Using QtTest library).*', r'\1'), # txt (r'( *<QtBuild)>[^<]+</QtBuild>', r'\1/>'), # xml, lightxml (r'(<property name="QtBuild" value=")[^"]+"', r'\1"'), # junitxml + (r'(<testsuite .*? hostname=")[^"]+(".*>)', r'\1@HOSTNAME@\2'), # junit # Line numbers in source files: (r'(ASSERT: ("|").*("|") in file .*, line) \d+', r'\1 0'), # lightxml (r'(Loc: \[[^[\]()]+)\(\d+\)', r'\1(0)'), # txt @@ -193,18 +175,20 @@ class Scanner (object): def __init__(self): pass - def subdirs(self, given, skip_benchlib=False): + def subdirs(self, given, skip_callgrind=False): if given: for d in given: if not os.path.isdir(d): print('No such directory:', d, '- skipped') + elif skip_callgrind and d == 'benchlibcallgrind': + pass # Skip this test, as requeted. elif d in TESTS: yield d else: print(f'Directory {d} is not in the list of tests') else: tests = TESTS - if skip_benchlib: + if skip_callgrind: tests.remove('benchlibcallgrind') missing = 0 for d in tests: @@ -218,11 +202,11 @@ class Scanner (object): del re -# Keep in sync with tst_selftests.cpp's processEnvironment(): +# Keep in sync with tst_selftests.cpp's testEnvironment(): def baseEnv(platname=None, - keep=('PATH', 'QT_QPA_PLATFORM'), + keep=('PATH', 'QT_QPA_PLATFORM', 'QTEST_THROW_ON_FAIL', 'QTEST_THROW_ON_SKIP', 'ASAN_OPTIONS'), posix=('HOME', 'USER', 'QEMU_SET_ENV', 'QEMU_LD_PREFIX'), - nonapple=('DISPLAY', 'XAUTHLOCALHOSTNAME'), # and XDG_* + nonapple=('DISPLAY', 'XAUTHORITY', 'XAUTHLOCALHOSTNAME'), # and XDG_* # Don't actually know how to test for QNX, so this is ignored: qnx=('GRAPHICS_ROOT', 'TZ'), # Probably not actually relevant @@ -269,9 +253,9 @@ def testEnv(testname, "watchdog": { "QTEST_FUNCTION_TIMEOUT": "100" }, }, # Must match tst_Selftests::runSubTest_data(): - crashers = ("assert", "blacklisted", "crashes", "crashedterminate", + crashers = ("assert", "crashes", "crashedterminate", "exceptionthrow", "faildatatype", "failfetchtype", - "fetchbogus", "silent", "watchdog")): + "fetchbogus", "silent_fatal", "watchdog")): """Determine the environment in which to run a test.""" data = baseEnv() if testname in crashers: @@ -280,6 +264,43 @@ def testEnv(testname, data.update(extraEnv[testname]) return data +def shouldIgnoreTest(testname, format): + """Test whether to exclude a test/format combination. + + See TestLogger::shouldIgnoreTest() in tst_selftests.cpp; it starts + with various exclusions for opt-in tests, platform dependencies + and tool availability; we ignore those, as we need the test data + to be present when those exclusions aren't in effect. + + In the remainder, exclude what it always excludes. + """ + if format != 'txt': + if testname in ("differentexec", + "multiexec", + "qexecstringlist", + "benchliboptions", + "printdatatags", + "printdatatagswithglobaltags", + "silent", + "silent_fatal", + "crashes", + "benchlibcallgrind", + "float", + "sleep"): + return True + + if testname == "badxml" and not format.endswith('xml'): + return True + + # Skip benchlib* for teamcity, and everything else for csv: + if format == ('teamcity' if testname.startswith('benchlib') else 'csv'): + return True + + if testname == "junit" and format != "junitxml": + return True + + return False + def generateTestData(test_path, expected_path, clean, formats): """Run one test and save its cleaned results. @@ -299,6 +320,8 @@ def generateTestData(test_path, expected_path, clean, formats): env = testEnv(testname) for format in formats: + if shouldIgnoreTest(testname, format): + continue print(f' running {testname}/{format}') cmd = [path, f'-{format}'] expected_file = f'expected_{testname}.{format}' @@ -312,8 +335,8 @@ def main(argv): argument_parser = ArgumentParser(description=USAGE, formatter_class=RawTextHelpFormatter) argument_parser.add_argument('--formats', '-f', help='Comma-separated list of formats') - argument_parser.add_argument('--skip-benchlib', '-s', action='store_true', - help='Skip the expensive benchlib callgrind test') + argument_parser.add_argument('--skip-callgrind', '-s', action='store_true', + help='Skip the (no longer expensive) benchlib callgrind test') argument_parser.add_argument('subtests', help='subtests to regenerate', nargs='*', type=str) @@ -323,7 +346,16 @@ def main(argv): cleaner = Cleaner() src_dir = cleaner.sourceDir - tests = tuple(Scanner().subdirs(options.subtests, options.skip_benchlib)) + if not options.skip_callgrind: + # Skip it, even if not requested, when valgrind isn't available: + try: + probe = subprocess.Popen(['valgrind', '--version'], stdout=subprocess.PIPE, + env=testEnv('benchlibcallgrind'), universal_newlines=True) + except FileNotFoundError: + options.skip_callgrind = True + print("Failed to find valgrind, skipping benchlibcallgrind test") + + tests = tuple(Scanner().subdirs(options.subtests, options.skip_callgrind)) print("Generating", len(tests), "test results for", cleaner.version, "in:", src_dir) for path in tests: generateTestData(path, src_dir, cleaner.clean, formats) |