4 from run_utils import Err, log, execute, getPlatformVersion, isColorEnabled, TempEnvDir
5 from run_long import LONG_TESTS_DEBUG_VALGRIND, longTestFilter
8 class TestSuite(object):
9 def __init__(self, options, cache, id):
10 self.options = options
12 self.nameprefix = "opencv_" + self.options.mode + "_"
13 self.tests = self.cache.gatherTests(self.nameprefix + "*", self.isTest)
17 return getPlatformVersion() or self.cache.getOS()
19 def getLogName(self, app):
20 return self.getAlias(app) + '_' + str(self.id) + '.xml'
22 def listTests(self, short=False, main=False):
23 if len(self.tests) == 0:
24 raise Err("No tests found")
28 if not main or self.cache.isMainModule(t):
31 def getAlias(self, fname):
32 return sorted(self.getAliases(fname), key=len)[0]
34 def getAliases(self, fname):
35 def getCuts(fname, prefix):
36 # filename w/o extension (opencv_test_core)
37 noext = re.sub(r"\.(exe|apk)$", '', fname)
38 # filename w/o prefix (core.exe)
40 if fname.startswith(prefix):
41 nopref = fname[len(prefix):]
42 # filename w/o prefix and extension (core)
44 if noext.startswith(prefix):
45 noprefext = noext[len(prefix):]
46 return noext, nopref, noprefext
47 # input is full path ('/home/.../bin/opencv_test_core') or 'java'
49 fname = os.path.basename(fname)
50 res.append(fname) # filename (opencv_test_core.exe)
51 for s in getCuts(fname, self.nameprefix):
53 if self.cache.build_type == "Debug" and "Visual Studio" in self.cache.cmake_generator:
54 res.append(re.sub(r"d$", '', s)) # MSVC debug config, remove 'd' suffix
55 log.debug("Aliases: %s", set(res))
58 def getTest(self, name):
59 # return stored test name by provided alias
61 if name in self.getAliases(t):
63 raise Err("Can not find test: %s", name)
65 def getTestList(self, white, black):
66 res = [t for t in white or self.tests if self.getAlias(t) not in black]
68 raise Err("No tests found")
71 def isTest(self, fullpath):
72 if fullpath in ['java', 'python2', 'python3']:
73 return self.options.mode == 'test'
74 if not os.path.isfile(fullpath):
76 if self.cache.getOS() == "nt" and not fullpath.endswith(".exe"):
78 return os.access(fullpath, os.X_OK)
80 def wrapCommand(self, cmd, env):
81 if self.options.valgrind:
83 supp = self.options.valgrind_supp or []
86 res.append("--suppressions=%s" % f)
88 print("WARNING: Valgrind suppression file is missing, SKIP: %s" % f)
89 res.extend(self.options.valgrind_opt)
90 has_gtest_filter = next((True for x in cmd if x.startswith('--gtest_filter=')), False)
91 return res + cmd + ([longTestFilter(LONG_TESTS_DEBUG_VALGRIND)] if not has_gtest_filter else [])
92 elif self.options.qemu:
94 res = shlex.split(self.options.qemu)
95 for (name, value) in [entry for entry in os.environ.items() if entry[0].startswith('OPENCV') and not entry[0] in env]:
96 res += ['-E', '"{}={}"'.format(name, value)]
97 for (name, value) in env.items():
98 res += ['-E', '"{}={}"'.format(name, value)]
99 return res + ['--'] + cmd
102 def tryCommand(self, cmd, workingDir):
104 if 0 == execute(cmd, cwd=workingDir):
110 def runTest(self, path, logfile, workingDir, args=[]):
112 exe = os.path.abspath(path)
114 cmd = [self.cache.ant_executable, "-Dopencv.build.type=%s" % self.cache.build_type, "buildAndTest"]
115 ret = execute(cmd, cwd=self.cache.java_test_dir)
117 elif path in ['python2', 'python3']:
118 executable = os.getenv('OPENCV_PYTHON_BINARY', None)
119 if executable is None:
121 if not self.tryCommand([executable, '--version'], workingDir):
122 executable = 'python'
123 cmd = [executable, self.cache.opencv_home + '/modules/python/test/test.py', '--repo', self.cache.opencv_home, '-v'] + args
124 module_suffix = '' if 'Visual Studio' not in self.cache.cmake_generator else '/' + self.cache.build_type
126 env['PYTHONPATH'] = self.cache.opencv_build + '/lib' + module_suffix + os.pathsep + os.getenv('PYTHONPATH', '')
127 if self.cache.getOS() == 'nt':
128 env['PATH'] = self.cache.opencv_build + '/bin' + module_suffix + os.pathsep + os.getenv('PATH', '')
130 env['LD_LIBRARY_PATH'] = self.cache.opencv_build + '/bin' + os.pathsep + os.getenv('LD_LIBRARY_PATH', '')
131 ret = execute(cmd, cwd=workingDir, env=env)
134 if isColorEnabled(args):
135 args.append("--gtest_color=yes")
137 if not self.options.valgrind and self.options.trace:
138 env['OPENCV_TRACE'] = '1'
139 env['OPENCV_TRACE_LOCATION'] = 'OpenCVTrace-{}'.format(self.getLogBaseName(exe))
140 env['OPENCV_TRACE_SYNC_OPENCL'] = '1'
141 tempDir = TempEnvDir('OPENCV_TEMP_PATH', "__opencv_temp.")
143 cmd = self.wrapCommand([exe] + args, env)
144 log.warning("Run: %s" % " ".join(cmd))
145 ret = execute(cmd, cwd=workingDir, env=env)
147 if not self.options.valgrind and self.options.trace and int(self.options.trace_dump) >= 0:
148 import trace_profiler
149 trace = trace_profiler.Trace(env['OPENCV_TRACE_LOCATION']+'.txt')
151 trace.dump(max_entries=int(self.options.trace_dump))
154 traceback.print_exc()
157 hostlogpath = os.path.join(workingDir, logfile)
158 if os.path.isfile(hostlogpath):
159 return hostlogpath, ret
162 def runTests(self, tests, black, workingDir, args=[]):
165 test_list = self.getTestList(tests, black)
166 if len(test_list) != 1:
167 args = [a for a in args if not a.startswith("--gtest_output=")]
169 for test in test_list:
171 exe = self.getTest(test)
173 if exe in ["java", "python2", "python3"]:
176 userlog = [a for a in args if a.startswith("--gtest_output=")]
177 if len(userlog) == 0:
178 logname = self.getLogName(exe)
179 more_args.append("--gtest_output=xml:" + logname)
181 logname = userlog[0][userlog[0].find(":")+1:]
183 log.debug("Running the test: %s (%s) ==> %s in %s", exe, args + more_args, logname, workingDir)
184 if self.options.dry_run:
187 logfile, r = self.runTest(exe, logname, workingDir, args + more_args)
188 log.debug("Test returned: %s ==> %s", r, logfile)
193 logs.append(os.path.relpath(logfile, workingDir))
197 if __name__ == "__main__":
198 log.error("This is utility file, please execute run.py script")