4 from run_utils import *
5 from run_long import LONG_TESTS_DEBUG_VALGRIND, longTestFilter
7 timestamp = datetime.datetime.now()
9 class TestSuite(object):
10 def __init__(self, options, cache):
11 self.options = options
13 self.nameprefix = "opencv_" + self.options.mode + "_"
14 self.tests = self.cache.gatherTests(self.nameprefix + "*", self.isTest)
17 return getPlatformVersion() or self.cache.getOS()
19 def getHardware(self):
21 if self.cache.getArch() in ["x86", "x64"] and self.cache.withCuda():
25 def getLogBaseName(self, app):
27 app = self.getAlias(app)
28 rev = self.cache.getGitVersion()
29 if isinstance(timestamp, datetime.datetime):
30 timestamp = timestamp.strftime("%Y%m%d-%H%M%S")
31 if self.options.longname:
32 small_pieces = [self.getOS(), self.cache.getArch()] + self.cache.getDependencies() + self.getHardware() + [self.cache.getSIMDFeatures()]
33 big_pieces = [app, str(rev), timestamp, "_".join([p for p in small_pieces if p])]
34 l = "__".join(big_pieces)
36 pieces = [app, self.cache.getOS(), self.cache.getArch()] + self.getHardware() + [rev, timestamp]
37 lname = "_".join([p for p in pieces if p])
38 lname = re.sub(r'[\(\)\[\]\s,]', '_', lname)
39 l = re.sub(r'_+', '_', lname)
42 def getLogName(self, app):
43 return self.getLogBaseName(app) + '.xml'
45 def listTests(self, short = False, main = False):
46 if len(self.tests) == 0:
47 raise Err("No tests found")
51 if not main or self.cache.isMainModule(t):
54 def getAlias(self, fname):
55 return sorted(self.getAliases(fname), key = len)[0]
57 def getAliases(self, fname):
58 def getCuts(fname, prefix):
59 # filename w/o extension (opencv_test_core)
60 noext = re.sub(r"\.(exe|apk)$", '', fname)
61 # filename w/o prefix (core.exe)
63 if fname.startswith(prefix):
64 nopref = fname[len(prefix):]
65 # filename w/o prefix and extension (core)
67 if noext.startswith(prefix):
68 noprefext = noext[len(prefix):]
69 return noext, nopref, noprefext
70 # input is full path ('/home/.../bin/opencv_test_core') or 'java'
72 fname = os.path.basename(fname)
73 res.append(fname) # filename (opencv_test_core.exe)
74 for s in getCuts(fname, self.nameprefix):
76 if self.cache.build_type == "Debug" and "Visual Studio" in self.cache.cmake_generator:
77 res.append(re.sub(r"d$", '', s)) # MSVC debug config, remove 'd' suffix
78 log.debug("Aliases: %s", set(res))
81 def getTest(self, name):
82 # return stored test name by provided alias
84 if name in self.getAliases(t):
86 raise Err("Can not find test: %s", name)
88 def getTestList(self, white, black):
89 res = [t for t in white or self.tests if self.getAlias(t) not in black]
91 raise Err("No tests found")
94 def isTest(self, fullpath):
95 if fullpath in ['java', 'python2', 'python3']:
96 return self.options.mode == 'test'
97 if not os.path.isfile(fullpath):
99 if self.cache.getOS() == "nt" and not fullpath.endswith(".exe"):
101 return os.access(fullpath, os.X_OK)
103 def wrapInValgrind(self, cmd = []):
104 if self.options.valgrind:
106 supp = self.options.valgrind_supp or []
108 if os.path.isfile(f):
109 res.append("--suppressions=%s" % f)
111 print("WARNING: Valgrind suppression file is missing, SKIP: %s" % f)
112 res.extend(self.options.valgrind_opt)
113 has_gtest_filter = next((True for x in cmd if x.startswith('--gtest_filter=')), False)
114 return res + cmd + ([longTestFilter(LONG_TESTS_DEBUG_VALGRIND)] if not has_gtest_filter else [])
117 def tryCommand(self, cmd):
119 if 0 == execute(cmd, cwd = workingDir):
125 def runTest(self, path, logfile, workingDir, args = []):
127 exe = os.path.abspath(path)
129 cmd = [self.cache.ant_executable, "-Dopencv.build.type=%s" % self.cache.build_type, "buildAndTest"]
130 ret = execute(cmd, cwd = self.cache.java_test_binary_dir + "/.build")
132 elif path in ['python2', 'python3']:
133 executable = os.getenv('OPENCV_PYTHON_BINARY', None)
134 if executable is None:
136 if not self.tryCommand([executable, '--version']):
137 executable = 'python'
138 cmd = [executable, self.cache.opencv_home + '/modules/python/test/test.py', '--repo', self.cache.opencv_home, '-v'] + args
139 module_suffix = '' if not 'Visual Studio' in self.cache.cmake_generator else '/' + self.cache.build_type
141 env['PYTHONPATH'] = self.cache.opencv_build + '/lib' + module_suffix + os.pathsep + os.getenv('PYTHONPATH', '')
142 if self.cache.getOS() == 'nt':
143 env['PATH'] = self.cache.opencv_build + '/bin' + module_suffix + os.pathsep + os.getenv('PATH', '')
145 env['LD_LIBRARY_PATH'] = self.cache.opencv_build + '/bin' + os.pathsep + os.getenv('LD_LIBRARY_PATH', '')
146 ret = execute(cmd, cwd = workingDir, env = env)
149 if isColorEnabled(args):
150 args.append("--gtest_color=yes")
151 cmd = self.wrapInValgrind([exe] + args)
153 if not self.options.valgrind and self.options.trace:
154 env['OPENCV_TRACE'] = '1'
155 env['OPENCV_TRACE_LOCATION'] = 'OpenCVTrace-{}'.format(self.getLogBaseName(exe))
156 env['OPENCV_TRACE_SYNC_OPENCL'] = '1'
157 tempDir = TempEnvDir('OPENCV_TEMP_PATH', "__opencv_temp.")
159 log.warning("Run: %s" % " ".join(cmd))
160 ret = execute(cmd, cwd = workingDir, env=env)
162 if not self.options.valgrind and self.options.trace and int(self.options.trace_dump) >= 0:
163 import trace_profiler
164 trace = trace_profiler.Trace(env['OPENCV_TRACE_LOCATION']+'.txt')
166 trace.dump(max_entries=int(self.options.trace_dump))
169 traceback.print_exc()
172 hostlogpath = os.path.join(workingDir, logfile)
173 if os.path.isfile(hostlogpath):
174 return hostlogpath, ret
177 def checkPrerequisites(self):
178 if self.cache.getArch() == "x64" and hostmachine == "x86":
179 raise Err("Target architecture is incompatible with current platform")
181 def runTests(self, tests, black, workingDir, args = []):
182 self.checkPrerequisites()
185 test_list = self.getTestList(tests, black)
186 if len(test_list) != 1:
187 args = [a for a in args if not a.startswith("--gtest_output=")]
189 for test in test_list:
191 exe = self.getTest(test)
193 if exe in ["java", "python2", "python3"]:
196 userlog = [a for a in args if a.startswith("--gtest_output=")]
197 if len(userlog) == 0:
198 logname = self.getLogName(exe)
199 more_args.append("--gtest_output=xml:" + logname)
201 logname = userlog[0][userlog[0].find(":")+1:]
203 log.debug("Running the test: %s (%s) ==> %s in %s", exe, args + more_args, logname, workingDir)
204 if self.options.dry_run:
207 logfile, r = self.runTest(exe, logname, workingDir, args + more_args)
208 log.debug("Test returned: %s ==> %s", r, logfile)
213 logs.append(os.path.relpath(logfile, workingDir))
216 #===================================================================================================
218 if __name__ == "__main__":
219 log.error("This is utility file, please execute run.py script")