diff options
author | Egor Tensin <Egor.Tensin@gmail.com> | 2021-04-13 17:32:05 +0300 |
---|---|---|
committer | Egor Tensin <Egor.Tensin@gmail.com> | 2021-04-13 17:32:05 +0300 |
commit | 795dd9e87e44d1c49f160cd003cdde4113ee8247 (patch) | |
tree | 8235133e9007abdb53ed7380f201058c24269031 /tools/ctest-driver.py | |
parent | README: fix badge links (diff) | |
download | cmake-common-795dd9e87e44d1c49f160cd003cdde4113ee8247.tar.gz cmake-common-795dd9e87e44d1c49f160cd003cdde4113ee8247.zip |
tools: drop the .py extension
Diffstat (limited to 'tools/ctest-driver.py')
-rwxr-xr-x | tools/ctest-driver.py | 166 |
1 files changed, 0 insertions, 166 deletions
diff --git a/tools/ctest-driver.py b/tools/ctest-driver.py deleted file mode 100755 index 414e20c..0000000 --- a/tools/ctest-driver.py +++ /dev/null @@ -1,166 +0,0 @@ -#!/usr/bin/env python3 - -# Copyright (c) 2021 Egor Tensin <Egor.Tensin@gmail.com> -# This file is part of the "cmake-common" project. -# For details, see https://github.com/egor-tensin/cmake-common. -# Distributed under the MIT License. - -'''Wrap your actual test driver to use with CTest - -CTest suffers from at least two issues, in particular with regard to its -PASS_REGULAR_EXPRESSION feature: - -1. The regular expression syntax used by CMake is deficient. -2. The exit code of a test is ignored if one of the regexes matches. - -This script tries to fix them. -''' - -import argparse -import os -import re -import subprocess -import sys - - -SCRIPT_NAME = os.path.basename(__file__) - - -def dump(msg, **kwargs): - print(f'{SCRIPT_NAME}: {msg}', **kwargs) - - -def err(msg): - dump(msg, file=sys.stderr) - - -def read_file(path): - with open(path, mode='r') as fd: - return fd.read() - - -def run(cmd_line): - try: - result = subprocess.run(cmd_line, check=True, universal_newlines=True, - stderr=subprocess.STDOUT, - stdout=subprocess.PIPE) - assert result.returncode == 0 - return result.stdout - except subprocess.CalledProcessError as e: - sys.stdout.write(e.output) - sys.exit(e.returncode) - - -def run_new_window(cmd_line): - try: - result = subprocess.run(cmd_line, check=True, - creationflags=subprocess.CREATE_NEW_CONSOLE) - assert result.returncode == 0 - return None - except subprocess.CalledProcessError as e: - sys.exit(e.returncode) - - -def match(s, regex): - return re.search(regex, s, flags=re.MULTILINE) - - -def match_any(s, regexes): - return any([match(s, regex) for regex in regexes]) - - -def match_all(s, regexes): - return all([match(s, regex) for regex in regexes]) - - -def match_pass_regexes(output, regexes): - if not regexes: - return - if not match_all(output, regexes): - err("Couldn't match test program's output against all of the"\ - " regular expressions:") - for regex in regexes: - err(f'\t{regex}') - sys.exit(1) - - -def match_fail_regexes(output, regexes): - if not regexes: - return - if match_any(output, regexes): - err("Matched test program's output against some of the regular"\ - " expressions:") - for regex in regexes: - err(f'\t{regex}') - sys.exit(1) - - -def run_actual_test_driver(args): - cmd_line = [args.exe_path] + args.exe_args - run_func = run - if args.new_window: - run_func = run_new_window - output = run_func(cmd_line) - if args.new_window and (args.pass_regexes or args.fail_regexes): - err("Cannot launch child process in a new window and capture its output") - if output is not None: - sys.stdout.write(output) - match_pass_regexes(output, args.pass_regexes) - match_fail_regexes(output, args.fail_regexes) - - -def grep_file(args): - contents = read_file(args.path) - match_pass_regexes(contents, args.pass_regexes) - match_fail_regexes(contents, args.fail_regexes) - - -def parse_args(argv=None): - if argv is None: - argv = sys.argv[1:] - - parser = argparse.ArgumentParser( - description=__doc__, - formatter_class=argparse.RawDescriptionHelpFormatter) - - subparsers = parser.add_subparsers(dest='command') - - parser_run = subparsers.add_parser('run', help='run an executable and check its output') - parser_run.add_argument('-p', '--pass-regex', nargs='*', - dest='pass_regexes', metavar='REGEX', - help='pass if all of these regexes match') - parser_run.add_argument('-f', '--fail-regex', nargs='*', - dest='fail_regexes', metavar='REGEX', - help='fail if any of these regexes matches') - parser_run.add_argument('-n', '--new-window', action='store_true', - help='launch child process in a new console window') - parser_run.add_argument('exe_path', metavar='PATH', - help='path to the test executable') - # nargs='*' here would discard additional '--'s. - parser_run.add_argument('exe_args', metavar='ARG', nargs=argparse.REMAINDER, - help='test executable arguments') - parser_run.set_defaults(func=run_actual_test_driver) - - parser_grep = subparsers.add_parser('grep', help='check file contents for matching patterns') - parser_grep.add_argument('-p', '--pass-regex', nargs='*', - dest='pass_regexes', metavar='REGEX', - help='pass if all of these regexes match') - parser_grep.add_argument('-f', '--fail-regex', nargs='*', - dest='fail_regexes', metavar='REGEX', - help='fail if any of these regexes matches') - parser_grep.add_argument('path', metavar='PATH', help='text file path') - parser_grep.set_defaults(func=grep_file) - - args = parser.parse_args(argv) - if args.command is None: - parser.error('please specify a subcommand to run') - return args - - -def main(argv=None): - args = parse_args(argv) - args.func(args) - - -if __name__ == '__main__': - main() |