diff options
Diffstat (limited to 'util/testrunner/tests/qt_mock_test.py')
-rwxr-xr-x | util/testrunner/tests/qt_mock_test.py | 182 |
1 files changed, 182 insertions, 0 deletions
diff --git a/util/testrunner/tests/qt_mock_test.py b/util/testrunner/tests/qt_mock_test.py new file mode 100755 index 0000000000..a7adb8804a --- /dev/null +++ b/util/testrunner/tests/qt_mock_test.py @@ -0,0 +1,182 @@ +#!/usr/bin/env python3 +# Copyright (C) 2021 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0 + + +# This is an artificial test, mimicking the Qt tests, for example tst_whatever. +# Its purpose is to assist in testing qt-testrunner.py. +# +# Mode A: +# +# If invoked with a test function argument, it runs that test function. +# +# Usage: +# +# $0 always_pass +# $0 always_fail +# $0 always_crash +# $0 fail_then_pass:N # where N is the number of failing runs before passing +# +# Needs environment variable: +# + QT_MOCK_TEST_STATE_FILE :: points to a unique filename, to be written +# for keeping the state of the fail_then_pass:N tests. +# +# Mode B: +# +# If invoked without any argument, it runs the tests listed in the +# variable QT_MOCK_TEST_FAIL_LIST. If variable is empty it just runs +# the always_pass test. It also understands qtestlib's `-o outfile.xml,xml` +# option for writing a mock testlog in a file. Requires environment variables: +# + QT_MOCK_TEST_STATE_FILE :: See above +# + QT_MOCK_TEST_XML_TEMPLATE_FILE :: may point to the template XML file +# located in the same source directory. Without this variable, the +# option `-o outfile.xml,xml` will be ignored. +# + QT_MOCK_TEST_FAIL_LIST :: may contain a comma-separated list of test +# that should run. + + +import sys +import os +import traceback +from tst_testrunner import write_xml_log + + +MY_NAME = os.path.basename(sys.argv[0]) +STATE_FILE = None +XML_TEMPLATE = None +XML_OUTPUT_FILE = None + + +def put_failure(test_name): + with open(STATE_FILE, "a") as f: + f.write(test_name + "\n") +def get_failures(test_name): + n = 0 + try: + with open(STATE_FILE) as f: + for line in f: + if line.strip() == test_name: + n += 1 + except FileNotFoundError: + return 0 + return n + +# Only care about the XML log output file. +def parse_output_argument(a): + global XML_OUTPUT_FILE + if a.endswith(",xml"): + XML_OUTPUT_FILE = a[:-4] + +# Strip qtestlib specific arguments. +# Only care about the "-o ...,xml" argument. +def clean_cmdline(): + args = [] + prev_arg = None + skip_next_arg = True # Skip argv[0] + for a in sys.argv: + if skip_next_arg: + if prev_arg == "-o": + parse_output_argument(a) + prev_arg = None + skip_next_arg = False + continue + if a in ("-o", "-maxwarnings"): + skip_next_arg = True + prev_arg = a + continue + if a in ("-v1", "-v2", "-vs"): + print("VERBOSE RUN") + if "QT_LOGGING_RULES" in os.environ: + print("Environment has QT_LOGGING_RULES:", + os.environ["QT_LOGGING_RULES"]) + continue + args.append(a) + return args + + +def log_test(testcase, result, + testsuite=MY_NAME.rpartition(".")[0]): + print("%-7s: %s::%s()" % (result, testsuite, testcase)) + +# Return the exit code +def run_test(testname): + if testname == "initTestCase": + exit_code = 1 # specifically test that initTestCase fails + elif testname == "always_pass": + exit_code = 0 + elif testname == "always_fail": + exit_code = 1 + elif testname == "always_crash": + exit_code = 130 + elif testname.startswith("fail_then_pass"): + wanted_fails = int(testname.partition(":")[2]) + previous_fails = get_failures(testname) + if previous_fails < wanted_fails: + put_failure(testname) + exit_code = 1 + else: + exit_code = 0 + else: + assert False, "Unknown argument: %s" % testname + + if exit_code == 0: + log_test(testname, "PASS") + elif exit_code == 1: + log_test(testname, "FAIL!") + else: + log_test(testname, "CRASH!") + + return exit_code + +def no_args_run(): + try: + run_list = os.environ["QT_MOCK_TEST_RUN_LIST"].split(",") + except KeyError: + run_list = ["always_pass"] + + total_result = True + fail_list = [] + for test in run_list: + test_exit_code = run_test(test) + if test_exit_code not in (0, 1): + sys.exit(130) # CRASH! + if test_exit_code != 0: + fail_list.append(test) + total_result = total_result and (test_exit_code == 0) + + if XML_TEMPLATE and XML_OUTPUT_FILE: + write_xml_log(XML_OUTPUT_FILE, failure=fail_list) + + if total_result: + sys.exit(0) + else: + sys.exit(1) + + +def main(): + global STATE_FILE + # Will fail if env var is not set. + STATE_FILE = os.environ["QT_MOCK_TEST_STATE_FILE"] + + global XML_TEMPLATE + if "QT_MOCK_TEST_XML_TEMPLATE_FILE" in os.environ: + with open(os.environ["QT_MOCK_TEST_XML_TEMPLATE_FILE"]) as f: + XML_TEMPLATE = f.read() + + args = clean_cmdline() + + if len(args) == 0: + no_args_run() + assert False, "Unreachable!" + else: + sys.exit(run_test(args[0])) + + +# TODO write XPASS test that does exit(1) + +if __name__ == "__main__": + try: + main() + except Exception as e: + traceback.print_exc() + exit(128) # Something went wrong with this script |