run.py 9.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. #!/usr/bin/env python
  2. """ Test runner and results collector for OpenCV
  3. This script abstracts execution procedure for OpenCV tests. Target scenario: running automated tests
  4. in a continuous integration system.
  5. See https://github.com/opencv/opencv/wiki/HowToUsePerfTests for more details.
  6. ### Main features
  7. - Collect test executables, distinguish between accuracy and performance, main and contrib test sets
  8. - Pass through common GTest and OpenCV test options and handle some of them internally
  9. - Set up testing environment and handle some OpenCV-specific environment variables
  10. - Test Java and Python bindings
  11. - Test on remote android device
  12. - Support valgrind, qemu wrapping and trace collection
  13. ### Main options
  14. -t MODULES, --tests MODULES - Comma-separated list of modules to test (example: -t core,imgproc,java)
  15. -b MODULES, --blacklist MODULES - Comma-separated list of modules to exclude from test (example: -b java)
  16. -a, --accuracy - Look for accuracy tests instead of performance tests
  17. --check - Shortcut for '--perf_min_samples=1 --perf_force_samples=1'
  18. -w PATH, --cwd PATH - Working directory for tests (default is current)
  19. -n, --dry_run - Do not run anything
  20. -v, --verbose - Print more debug information
  21. ### Example
  22. ./run.py -a -t core --gtest_filter=*CopyTo*
  23. Run: /work/build-opencv/bin/opencv_test_core --gtest_filter=*CopyTo* --gtest_output=xml:core_20221017-195300.xml --gtest_color=yes
  24. CTEST_FULL_OUTPUT
  25. ...
  26. regular test output
  27. ...
  28. [ PASSED ] 113 tests.
  29. Collected: ['core_20221017-195300.xml']
  30. """
  31. import os
  32. import argparse
  33. import logging
  34. import datetime
  35. from run_utils import Err, CMakeCache, log, execute
  36. from run_suite import TestSuite
  37. from run_android import AndroidTestSuite
  38. epilog = '''
  39. NOTE:
  40. Additional options starting with "--gtest_" and "--perf_" will be passed directly to the test executables.
  41. '''
  42. if __name__ == "__main__":
  43. # log.basicConfig(format='[%(levelname)s] %(message)s', level = log.DEBUG)
  44. # log.basicConfig(format='[%(levelname)s] %(message)s', level = log.INFO)
  45. parser = argparse.ArgumentParser(
  46. description='OpenCV test runner script',
  47. epilog=epilog,
  48. formatter_class=argparse.RawDescriptionHelpFormatter)
  49. 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)")
  50. parser.add_argument("-t", "--tests", metavar="MODULES", default="", help="Comma-separated list of modules to test (example: -t core,imgproc,java)")
  51. parser.add_argument("-b", "--blacklist", metavar="MODULES", default="", help="Comma-separated list of modules to exclude from test (example: -b java)")
  52. parser.add_argument("-a", "--accuracy", action="store_true", default=False, help="Look for accuracy tests instead of performance tests")
  53. parser.add_argument("--check", action="store_true", default=False, help="Shortcut for '--perf_min_samples=1 --perf_force_samples=1'")
  54. parser.add_argument("-w", "--cwd", metavar="PATH", default=".", help="Working directory for tests (default is current)")
  55. parser.add_argument("--list", action="store_true", default=False, help="List available tests (executables)")
  56. parser.add_argument("--list_short", action="store_true", default=False, help="List available tests (aliases)")
  57. parser.add_argument("--list_short_main", action="store_true", default=False, help="List available tests (main repository, aliases)")
  58. parser.add_argument("--configuration", metavar="CFG", default=None, help="Force Debug or Release configuration (for Visual Studio and Java tests build)")
  59. parser.add_argument("-n", "--dry_run", action="store_true", help="Do not run the tests")
  60. parser.add_argument("-v", "--verbose", action="store_true", default=False, help="Print more debug information")
  61. # Valgrind
  62. parser.add_argument("--valgrind", action="store_true", default=False, help="Run C++ tests in valgrind")
  63. parser.add_argument("--valgrind_supp", metavar="FILE", action='append', help="Path to valgrind suppression file (example: --valgrind_supp opencv/platforms/scripts/valgrind.supp)")
  64. parser.add_argument("--valgrind_opt", metavar="OPT", action="append", default=[], help="Add command line option to valgrind (example: --valgrind_opt=--leak-check=full)")
  65. # QEMU
  66. parser.add_argument("--qemu", default="", help="Specify qemu binary and base parameters")
  67. # Android
  68. parser.add_argument("--android", action="store_true", default=False, help="Android: force all tests to run on device")
  69. parser.add_argument("--android_sdk", metavar="PATH", help="Android: path to SDK to use adb and aapt tools")
  70. parser.add_argument("--android_test_data_path", metavar="PATH", default="/sdcard/opencv_testdata/", help="Android: path to testdata on device")
  71. parser.add_argument("--android_env", action='append', help="Android: add environment variable (NAME=VALUE)")
  72. parser.add_argument("--android_propagate_opencv_env", action="store_true", default=False, help="Android: propagate OPENCV* environment variables")
  73. parser.add_argument("--serial", metavar="serial number", default="", help="Android: directs command to the USB device or emulator with the given serial number")
  74. parser.add_argument("--package", metavar="package", default="", help="Java: run JUnit tests for specified module or Android package")
  75. parser.add_argument("--java_test_exclude", metavar="java_test_exclude", default="", help="Java: Filter out specific JUnit tests")
  76. parser.add_argument("--trace", action="store_true", default=False, help="Trace: enable OpenCV tracing")
  77. parser.add_argument("--trace_dump", metavar="trace_dump", default=-1, help="Trace: dump highlight calls (specify max entries count, 0 - dump all)")
  78. args, other_args = parser.parse_known_args()
  79. log.setLevel(logging.DEBUG if args.verbose else logging.INFO)
  80. test_args = [a for a in other_args if a.startswith("--perf_") or a.startswith("--test_") or a.startswith("--gtest_")]
  81. bad_args = [a for a in other_args if a not in test_args]
  82. if len(bad_args) > 0:
  83. log.error("Error: Bad arguments: %s", bad_args)
  84. exit(1)
  85. args.mode = "test" if args.accuracy else "perf"
  86. android_env = []
  87. if args.android_env:
  88. android_env.extend([entry.split("=", 1) for entry in args.android_env])
  89. if args.android_propagate_opencv_env:
  90. android_env.extend([entry for entry in os.environ.items() if entry[0].startswith('OPENCV')])
  91. android_env = dict(android_env)
  92. if args.android_test_data_path:
  93. android_env['OPENCV_TEST_DATA_PATH'] = args.android_test_data_path
  94. if args.valgrind:
  95. try:
  96. ver = execute(["valgrind", "--version"], silent=True)
  97. log.debug("Using %s", ver)
  98. except OSError as e:
  99. log.error("Failed to run valgrind: %s", e)
  100. exit(1)
  101. if len(args.build_path) != 1:
  102. test_args = [a for a in test_args if not a.startswith("--gtest_output=")]
  103. if args.check:
  104. if not [a for a in test_args if a.startswith("--perf_min_samples=")]:
  105. test_args.extend(["--perf_min_samples=1"])
  106. if not [a for a in test_args if a.startswith("--perf_force_samples=")]:
  107. test_args.extend(["--perf_force_samples=1"])
  108. if not [a for a in test_args if a.startswith("--perf_verify_sanity")]:
  109. test_args.extend(["--perf_verify_sanity"])
  110. if bool(os.environ.get('BUILD_PRECOMMIT', None)):
  111. test_args.extend(["--skip_unstable=1"])
  112. ret = 0
  113. logs = []
  114. stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
  115. path = args.build_path
  116. try:
  117. if not os.path.isdir(path):
  118. raise Err("Not a directory (should contain CMakeCache.txt to test executables)")
  119. cache = CMakeCache(args.configuration)
  120. fname = os.path.join(path, "CMakeCache.txt")
  121. if os.path.isfile(fname):
  122. log.debug("Reading cmake cache file: %s", fname)
  123. cache.read(path, fname)
  124. else:
  125. log.debug("Assuming folder contains tests: %s", path)
  126. cache.setDummy(path)
  127. if args.android or cache.getOS() == "android":
  128. log.debug("Creating Android test runner")
  129. suite = AndroidTestSuite(args, cache, stamp, android_env)
  130. else:
  131. log.debug("Creating native test runner")
  132. suite = TestSuite(args, cache, stamp)
  133. if args.list or args.list_short or args.list_short_main:
  134. suite.listTests(args.list_short or args.list_short_main, args.list_short_main)
  135. else:
  136. log.debug("Running tests in '%s', working dir: '%s'", path, args.cwd)
  137. def parseTests(s):
  138. return [o.strip() for o in s.split(",") if o]
  139. logs, ret = suite.runTests(parseTests(args.tests), parseTests(args.blacklist), args.cwd, test_args)
  140. except Err as e:
  141. log.error("ERROR: test path '%s' ==> %s", path, e.msg)
  142. ret = -1
  143. if logs:
  144. log.warning("Collected: %s", logs)
  145. if ret != 0:
  146. log.error("ERROR: some tests have failed")
  147. exit(ret)