#!/usr/bin/env python3 # ===--- Benchmark_QuickCheck.in -----------------------------------------===// # # This source file is part of the Swift.org open source project # # Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors # Licensed under Apache License v2.0 with Runtime Library Exception # # See https://swift.org/LICENSE.txt for license information # See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors # # ===---------------------------------------------------------------------===// import os import subprocess import sys sys.path.append("@PATH_TO_DRIVER_LIBRARY@") import perf_test_driver # noqa (E402 module level import not at top of file) # This is a hacked up XFAIL list. It should really be a json file, but it will # work for now. Add in the exact name of the pass to XFAIL. XFAIL_LIST = [] class QuickCheckResult(perf_test_driver.Result): def __init__(self, name, success): assert isinstance(success, bool) did_fail = not success perf_test_driver.Result.__init__(self, name, did_fail, "", XFAIL_LIST) def print_data(self, max_test_len): fmt = "{:<%d}{:<10}" % (max_test_len + 5) print(fmt.format(self.get_name(), self.get_result())) class QuickCheckBenchmarkDriver(perf_test_driver.BenchmarkDriver): def __init__(self, binary, xfail_list, num_iters, opt_levels): perf_test_driver.BenchmarkDriver.__init__( self, binary, xfail_list, enable_parallel=True, opt_levels=opt_levels ) self.num_iters = num_iters def print_data_header(self, max_test_len): fmt = "{:<%d}{:<10}" % (max_test_len + 5) print(fmt.format("Name", "Result")) # Propagate any data from this class that is needed for individual # tests. The reason this is needed is to avoid issues with attempting to # access a value in a different process. def prepare_input(self, name): return {"num_samples": 1, "num_iters": self.num_iters} def run_test_inner(self, data, num_iters): p = subprocess.Popen( [ data["path"], "--num-samples={}".format(data["num_samples"]), "--num-iters={}".format(num_iters), data["test_name"], ], stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, ) error_out = p.communicate()[1].split("\n") result = p.returncode if result is None: raise RuntimeError("Expected one line of output") if result != 0: raise RuntimeError("Process segfaulted") return error_out def run_test(self, data, num_iters): try: args = [data, num_iters] perf_test_driver.run_with_timeout(self.run_test_inner, args) except Exception as e: sys.stderr.write( "Child Process Failed! (%s,%s). Error: %s\n" % (data["path"], data["test_name"], e) ) sys.stderr.flush() return None return True def process_input(self, data): test_name = "({},{})".format(data["opt"], data["test_name"]) print("Running {}...".format(test_name)) sys.stdout.flush() if self.run_test(data, data["num_iters"]) is None: return QuickCheckResult(test_name, success=False) return QuickCheckResult(test_name, success=True) SWIFT_BIN_DIR = os.path.dirname(os.path.abspath(__file__)) def parse_args(): import argparse parser = argparse.ArgumentParser() parser.add_argument( "--filter", type=str, default=None, help="Filter out any test that does not match the given regex", ) parser.add_argument("--num-iters", type=int, default=2) default_opt_levels = perf_test_driver.BenchmarkDriver_OptLevels parser.add_argument("--opt-level", choices=default_opt_levels) return parser.parse_args() if __name__ == "__main__": args = parse_args() opt_levels = perf_test_driver.BenchmarkDriver_OptLevels if args.opt_level is not None: opt_levels = [args.opt_level] driver = QuickCheckBenchmarkDriver( SWIFT_BIN_DIR, XFAIL_LIST, args.num_iters, opt_levels ) if driver.run(args.filter): sys.exit(0) else: sys.exit(-1)