Merge pull request #20190 from rogday:tf_importer_ref
[platform/upstream/opencv.git] / modules / ts / misc / run_suite.py
1 #!/usr/bin/env python
2 import os
3 import re
4 import sys
5 from run_utils import Err, log, execute, getPlatformVersion, isColorEnabled, TempEnvDir
6 from run_long import LONG_TESTS_DEBUG_VALGRIND, longTestFilter
7
8
9 class TestSuite(object):
10     def __init__(self, options, cache, id):
11         self.options = options
12         self.cache = cache
13         self.nameprefix = "opencv_" + self.options.mode + "_"
14         self.tests = self.cache.gatherTests(self.nameprefix + "*", self.isTest)
15         self.id = id
16
17     def getOS(self):
18         return getPlatformVersion() or self.cache.getOS()
19
20     def getLogName(self, app):
21         return self.getAlias(app) + '_' + str(self.id) + '.xml'
22
23     def listTests(self, short=False, main=False):
24         if len(self.tests) == 0:
25             raise Err("No tests found")
26         for t in self.tests:
27             if short:
28                 t = self.getAlias(t)
29             if not main or self.cache.isMainModule(t):
30                 log.info("%s", t)
31
32     def getAlias(self, fname):
33         return sorted(self.getAliases(fname), key=len)[0]
34
35     def getAliases(self, fname):
36         def getCuts(fname, prefix):
37             # filename w/o extension (opencv_test_core)
38             noext = re.sub(r"\.(exe|apk)$", '', fname)
39             # filename w/o prefix (core.exe)
40             nopref = fname
41             if fname.startswith(prefix):
42                 nopref = fname[len(prefix):]
43             # filename w/o prefix and extension (core)
44             noprefext = noext
45             if noext.startswith(prefix):
46                 noprefext = noext[len(prefix):]
47             return noext, nopref, noprefext
48         # input is full path ('/home/.../bin/opencv_test_core') or 'java'
49         res = [fname]
50         fname = os.path.basename(fname)
51         res.append(fname)  # filename (opencv_test_core.exe)
52         for s in getCuts(fname, self.nameprefix):
53             res.append(s)
54             if self.cache.build_type == "Debug" and "Visual Studio" in self.cache.cmake_generator:
55                 res.append(re.sub(r"d$", '', s))  # MSVC debug config, remove 'd' suffix
56         log.debug("Aliases: %s", set(res))
57         return set(res)
58
59     def getTest(self, name):
60         # return stored test name by provided alias
61         for t in self.tests:
62             if name in self.getAliases(t):
63                 return t
64         raise Err("Can not find test: %s", name)
65
66     def getTestList(self, white, black):
67         res = [t for t in white or self.tests if self.getAlias(t) not in black]
68         if len(res) == 0:
69             raise Err("No tests found")
70         return set(res)
71
72     def isTest(self, fullpath):
73         if fullpath in ['java', 'python2', 'python3']:
74             return self.options.mode == 'test'
75         if not os.path.isfile(fullpath):
76             return False
77         if self.cache.getOS() == "nt" and not fullpath.endswith(".exe"):
78             return False
79         return os.access(fullpath, os.X_OK)
80
81     def wrapCommand(self, module, cmd, env):
82         if self.options.valgrind:
83             res = ['valgrind']
84             supp = self.options.valgrind_supp or []
85             for f in supp:
86                 if os.path.isfile(f):
87                     res.append("--suppressions=%s" % f)
88                 else:
89                     print("WARNING: Valgrind suppression file is missing, SKIP: %s" % f)
90             res.extend(self.options.valgrind_opt)
91             has_gtest_filter = next((True for x in cmd if x.startswith('--gtest_filter=')), False)
92             return res + cmd + ([longTestFilter(LONG_TESTS_DEBUG_VALGRIND, module)] if not has_gtest_filter else [])
93         elif self.options.qemu:
94             import shlex
95             res = shlex.split(self.options.qemu)
96             for (name, value) in [entry for entry in os.environ.items() if entry[0].startswith('OPENCV') and not entry[0] in env]:
97                 res += ['-E', '"{}={}"'.format(name, value)]
98             for (name, value) in env.items():
99                 res += ['-E', '"{}={}"'.format(name, value)]
100             return res + ['--'] + cmd
101         return cmd
102
103     def tryCommand(self, cmd, workingDir):
104         try:
105             if 0 == execute(cmd, cwd=workingDir):
106                 return True
107         except:
108             pass
109         return False
110
111     def runTest(self, module, path, logfile, workingDir, args=[]):
112         args = args[:]
113         exe = os.path.abspath(path)
114         if module == "java":
115             cmd = [self.cache.ant_executable, "-Dopencv.build.type=%s" % self.cache.build_type]
116             if self.options.package:
117                 cmd += ["-Dopencv.test.package=%s" % self.options.package]
118             if self.options.java_test_exclude:
119                 cmd += ["-Dopencv.test.exclude=%s" % self.options.java_test_exclude]
120             cmd += ["buildAndTest"]
121             ret = execute(cmd, cwd=self.cache.java_test_dir)
122             return None, ret
123         elif module in ['python2', 'python3']:
124             executable = os.getenv('OPENCV_PYTHON_BINARY', None)
125             if executable is None or module == 'python{}'.format(sys.version_info[0]):
126                 executable = sys.executable
127             if executable is None:
128                 executable = path
129                 if not self.tryCommand([executable, '--version'], workingDir):
130                     executable = 'python'
131             cmd = [executable, self.cache.opencv_home + '/modules/python/test/test.py', '--repo', self.cache.opencv_home, '-v'] + args
132             module_suffix = '' if 'Visual Studio' not in self.cache.cmake_generator else '/' + self.cache.build_type
133             env = {}
134             env['PYTHONPATH'] = self.cache.opencv_build + '/lib' + module_suffix + os.pathsep + os.getenv('PYTHONPATH', '')
135             if self.cache.getOS() == 'nt':
136                 env['PATH'] = self.cache.opencv_build + '/bin' + module_suffix + os.pathsep + os.getenv('PATH', '')
137             else:
138                 env['LD_LIBRARY_PATH'] = self.cache.opencv_build + '/bin' + os.pathsep + os.getenv('LD_LIBRARY_PATH', '')
139             ret = execute(cmd, cwd=workingDir, env=env)
140             return None, ret
141         else:
142             if isColorEnabled(args):
143                 args.append("--gtest_color=yes")
144             env = {}
145             if not self.options.valgrind and self.options.trace:
146                 env['OPENCV_TRACE'] = '1'
147                 env['OPENCV_TRACE_LOCATION'] = 'OpenCVTrace-{}'.format(self.getLogBaseName(exe))
148                 env['OPENCV_TRACE_SYNC_OPENCL'] = '1'
149             tempDir = TempEnvDir('OPENCV_TEMP_PATH', "__opencv_temp.")
150             tempDir.init()
151             cmd = self.wrapCommand(module, [exe] + args, env)
152             log.warning("Run: %s" % " ".join(cmd))
153             ret = execute(cmd, cwd=workingDir, env=env)
154             try:
155                 if not self.options.valgrind and self.options.trace and int(self.options.trace_dump) >= 0:
156                     import trace_profiler
157                     trace = trace_profiler.Trace(env['OPENCV_TRACE_LOCATION']+'.txt')
158                     trace.process()
159                     trace.dump(max_entries=int(self.options.trace_dump))
160             except:
161                 import traceback
162                 traceback.print_exc()
163                 pass
164             tempDir.clean()
165             hostlogpath = os.path.join(workingDir, logfile)
166             if os.path.isfile(hostlogpath):
167                 return hostlogpath, ret
168             return None, ret
169
170     def runTests(self, tests, black, workingDir, args=[]):
171         args = args[:]
172         logs = []
173         test_list = self.getTestList(tests, black)
174         if len(test_list) != 1:
175             args = [a for a in args if not a.startswith("--gtest_output=")]
176         ret = 0
177         for test in test_list:
178             more_args = []
179             exe = self.getTest(test)
180
181             if exe in ["java", "python2", "python3"]:
182                 logname = None
183             else:
184                 userlog = [a for a in args if a.startswith("--gtest_output=")]
185                 if len(userlog) == 0:
186                     logname = self.getLogName(exe)
187                     more_args.append("--gtest_output=xml:" + logname)
188                 else:
189                     logname = userlog[0][userlog[0].find(":")+1:]
190
191             log.debug("Running the test: %s (%s) ==> %s in %s", exe, args + more_args, logname, workingDir)
192             if self.options.dry_run:
193                 logfile, r = None, 0
194             else:
195                 logfile, r = self.runTest(test, exe, logname, workingDir, args + more_args)
196             log.debug("Test returned: %s ==> %s", r, logfile)
197
198             if r != 0:
199                 ret = r
200             if logfile:
201                 logs.append(os.path.relpath(logfile, workingDir))
202         return logs, ret
203
204
205 if __name__ == "__main__":
206     log.error("This is utility file, please execute run.py script")