run.py 7.08 KB
Newer Older
1 2
#!/usr/bin/env python

3 4 5 6 7 8 9 10 11 12 13
import os, sys
import argparse
import logging
from run_utils import Err, CMakeCache, log, execute
from run_suite import TestSuite
from run_android import AndroidTestSuite

epilog = '''
NOTE:
Additional options starting with "--gtest_" and "--perf_" will be passed directly to the test executables.
'''
14

15
if __name__ == "__main__":
16

17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
    # log.basicConfig(format='[%(levelname)s] %(message)s', level = log.DEBUG)
    # log.basicConfig(format='[%(levelname)s] %(message)s', level = log.INFO)

    parser = argparse.ArgumentParser(
        description='OpenCV test runner script',
        epilog=epilog,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument("build_path", nargs = "*", default = ["."], help="Path to build directory (should contain CMakeCache.txt, default is current) or to directory with tests (all platform checks will be disabled in this case)")
    parser.add_argument("-t", "--tests", metavar="MODULES", default="", help="Comma-separated list of modules to test (example: -t core,imgproc,java)")
    parser.add_argument("-b", "--blacklist", metavar="MODULES", default="", help="Comma-separated list of modules to exclude from test (example: -b java)")
    parser.add_argument("-a", "--accuracy", action="store_true", default=False, help="Look for accuracy tests instead of performance tests")
    parser.add_argument("--check", action="store_true", default=False, help="Shortcut for '--perf_min_samples=1 --perf_force_samples=1'")
    parser.add_argument("-w", "--cwd", metavar="PATH", default=".", help="Working directory for tests (default is current)")
    parser.add_argument("-l", "--longname", action="store_true", default=False, help="Generate log files with long names")
    parser.add_argument("--list", action="store_true", default=False, help="List available tests (executables)")
    parser.add_argument("--list_short", action="store_true", default=False, help="List available tests (aliases)")
    parser.add_argument("--list_short_main", action="store_true", default=False, help="List available tests (main repository, aliases)")
34
    parser.add_argument("--configuration", metavar="CFG", default=None, help="Force Debug or Release configuration (for Visual Studio and Java tests build)")
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59
    parser.add_argument("-n", "--dry_run", action="store_true", help="Do not run the tests")
    parser.add_argument("-v", "--verbose", action="store_true", default=False, help="Print more debug information")

    # Valgrind
    parser.add_argument("--valgrind", action="store_true", default=False, help="Run C++ tests in valgrind")
    parser.add_argument("--valgrind_supp", metavar="FILE", help="Path to valgrind suppression file (example: --valgrind_supp opencv/platforms/scripts/valgrind.supp)")
    parser.add_argument("--valgrind_opt", metavar="OPT", action="append", default=[], help="Add command line option to valgrind (example: --valgrind_opt=--leak-check=full)")

    # Android
    parser.add_argument("--android", action="store_true", default=False, help="Android: force all tests to run on device")
    parser.add_argument("--android_sdk", metavar="PATH", help="Android: path to SDK to use adb and aapt tools")
    parser.add_argument("--android_test_data_path", metavar="PATH", default="/sdcard/opencv_testdata/", help="Android: path to testdata on device")
    parser.add_argument("--android_env", action='append', help="Android: add environment variable (NAME=VALUE)")
    parser.add_argument("--android_propagate_opencv_env", action="store_true", default=False, help="Android: propagate OPENCV* environment variables")
    parser.add_argument("--serial", metavar="serial number", default="", help="Android: directs command to the USB device or emulator with the given serial number")
    parser.add_argument("--package", metavar="package", default="", help="Android: run jUnit tests for specified package")

    args, other_args = parser.parse_known_args()

    log.setLevel(logging.DEBUG if args.verbose else logging.INFO)

    test_args = [a for a in other_args if a.startswith("--perf_") or a.startswith("--gtest_")]
    bad_args = [a for a in other_args if a not in test_args]
    if len(bad_args) > 0:
        log.error("Error: Bad arguments: %s", bad_args)
60
        exit(1)
61

62
    args.mode = "test" if args.accuracy else "perf"
63

64 65 66 67 68 69 70 71
    android_env = []
    if args.android_env:
        android_env.extend([entry.split("=", 1) for entry in args.android_env])
    if args.android_propagate_opencv_env:
        android_env.extend([entry for entry in os.environ.items() if entry[0].startswith('OPENCV')])
    android_env = dict(android_env)
    if args.android_test_data_path:
        android_env['OPENCV_TEST_DATA_PATH'] = args.android_test_data_path
72

73 74 75 76 77 78 79 80 81
    if args.valgrind:
        try:
            ver = execute(["valgrind", "--version"], silent=True)
            log.debug("Using %s", ver)
        except OSError as e:
            log.error("Failed to run valgrind: %s", e)
            exit(1)

    if len(args.build_path) != 1:
82
        test_args = [a for a in test_args if not a.startswith("--gtest_output=")]
83

84
    if args.check:
85 86 87 88
        if not [a for a in test_args if a.startswith("--perf_min_samples=")] :
            test_args.extend(["--perf_min_samples=1"])
        if not [a for a in test_args if a.startswith("--perf_force_samples=")] :
            test_args.extend(["--perf_force_samples=1"])
89 90
        if not [a for a in test_args if a.startswith("--perf_verify_sanity")] :
            test_args.extend(["--perf_verify_sanity"])
91

92
    ret = 0
93
    logs = []
94 95 96 97
    for path in args.build_path:
        try:
            if not os.path.isdir(path):
                raise Err("Not a directory (should contain CMakeCache.txt ot test executables)")
98
            cache = CMakeCache(args.configuration)
99 100 101 102
            fname = os.path.join(path, "CMakeCache.txt")

            if os.path.isfile(fname):
                log.debug("Reading cmake cache file: %s", fname)
103
                cache.read(path, fname)
104 105 106
            else:
                log.debug("Assuming folder contains tests: %s", path)
                cache.setDummy(path)
107

108 109 110 111 112 113
            if args.android or cache.getOS() == "android":
                log.debug("Creating Android test runner")
                suite = AndroidTestSuite(args, cache, android_env)
            else:
                log.debug("Creating native test runner")
                suite = TestSuite(args, cache)
114

115 116 117 118 119 120 121 122 123 124 125 126 127
            if args.list or args.list_short or args.list_short_main:
                suite.listTests(args.list_short or args.list_short_main, args.list_short_main)
            else:
                log.debug("Running tests in '%s', working dir: '%s'", path, args.cwd)
                def parseTests(s):
                    return [o.strip() for o in s.split(",") if o]
                l, r = suite.runTests(parseTests(args.tests), parseTests(args.blacklist), args.cwd, test_args)
                logs.extend(l)
                if r != 0:
                    ret = r
        except Err as e:
            log.error("ERROR: test path '%s' ==> %s", path, e.msg)
            ret = -1
128

129
    if logs:
130
        log.warning("Collected: %s", ", ".join(logs))
131

132 133 134
    if ret != 0:
        log.error("ERROR: some tests have failed")
    exit(ret)