run_suite.py 7.81 KB
Newer Older
wester committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
#!/usr/bin/env python

import datetime
from run_utils import *

class TestSuite(object):
    def __init__(self, options, cache):
        self.options = options
        self.cache = cache
        self.nameprefix = "opencv_" + self.options.mode + "_"
        self.tests = self.cache.gatherTests(self.nameprefix + "*", self.isTest)

    def getOS(self):
        return getPlatformVersion() or self.cache.getOS()

    def getHardware(self):
        res = []
        if self.cache.getArch() in ["x86", "x64"] and self.cache.withCuda():
            res.append("CUDA")
        return res

a  
Kai Westerkamp committed
22
    def getLogName(self, app, timestamp):
wester committed
23 24 25 26 27 28 29 30 31 32 33 34 35
        app = self.getAlias(app)
        rev = self.cache.getGitVersion()
        if isinstance(timestamp, datetime.datetime):
            timestamp = timestamp.strftime("%Y%m%d-%H%M%S")
        if self.options.longname:
            small_pieces = [self.getOS(), self.cache.getArch()] + self.cache.getDependencies() + self.getHardware() + [self.cache.getSIMDFeatures()]
            big_pieces = [app, str(rev), timestamp, "_".join([p for p in small_pieces if p])]
            l = "__".join(big_pieces)
        else:
            pieces = [app, self.cache.getOS(), self.cache.getArch()] + self.getHardware() + [rev, timestamp]
            lname = "_".join([p for p in pieces if p])
            lname = re.sub(r'[\(\)\[\]\s,]', '_', lname)
            l = re.sub(r'_+', '_', lname)
a  
Kai Westerkamp committed
36
        return l + ".xml"
wester committed
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87

    def listTests(self, short = False, main = False):
        if len(self.tests) == 0:
            raise Err("No tests found")
        for t in self.tests:
            if short:
                t = self.getAlias(t)
            if not main or self.cache.isMainModule(t):
                log.info("%s", t)

    def getAlias(self, fname):
        return sorted(self.getAliases(fname), key = len)[0]

    def getAliases(self, fname):
        def getCuts(fname, prefix):
            # filename w/o extension (opencv_test_core)
            noext = re.sub(r"\.(exe|apk)$", '', fname)
            # filename w/o prefix (core.exe)
            nopref = fname
            if fname.startswith(prefix):
                nopref = fname[len(prefix):]
            # filename w/o prefix and extension (core)
            noprefext = noext
            if noext.startswith(prefix):
                noprefext = noext[len(prefix):]
            return noext, nopref, noprefext
        # input is full path ('/home/.../bin/opencv_test_core') or 'java'
        res = [fname]
        fname = os.path.basename(fname)
        res.append(fname) # filename (opencv_test_core.exe)
        for s in getCuts(fname, self.nameprefix):
            res.append(s)
            if self.cache.build_type == "Debug" and "Visual Studio" in self.cache.cmake_generator:
                res.append(re.sub(r"d$", '', s)) # MSVC debug config, remove 'd' suffix
        log.debug("Aliases: %s", set(res))
        return set(res)

    def getTest(self, name):
        # return stored test name by provided alias
        for t in self.tests:
            if name in self.getAliases(t):
                return t
        raise Err("Can not find test: %s", name)

    def getTestList(self, white, black):
        res = [t for t in white or self.tests if self.getAlias(t) not in black]
        if len(res) == 0:
            raise Err("No tests found")
        return set(res)

    def isTest(self, fullpath):
wester committed
88 89
        if fullpath in ['java', 'python', 'python2', 'python3']:
            return self.options.mode == 'test'
wester committed
90 91 92 93 94 95 96 97 98
        if not os.path.isfile(fullpath):
            return False
        if self.cache.getOS() == "nt" and not fullpath.endswith(".exe"):
            return False
        return os.access(fullpath, os.X_OK)

    def wrapInValgrind(self, cmd = []):
        if self.options.valgrind:
            res = ['valgrind']
a  
Kai Westerkamp committed
99 100
            if self.options.valgrind_supp:
                res.append("--suppressions=%s" % self.options.valgrind_supp)
wester committed
101
            res.extend(self.options.valgrind_opt)
a  
Kai Westerkamp committed
102
            return res + cmd
wester committed
103 104
        return cmd

wester committed
105 106 107 108 109 110 111 112
    def tryCommand(self, cmd):
        try:
            if 0 == execute(cmd, cwd = workingDir):
                return True
        except:
            pass
        return False

wester committed
113 114 115 116 117 118 119
    def runTest(self, path, logfile, workingDir, args = []):
        args = args[:]
        exe = os.path.abspath(path)
        if path == "java":
            cmd = [self.cache.ant_executable, "-Dopencv.build.type=%s" % self.cache.build_type, "buildAndTest"]
            ret = execute(cmd, cwd = self.cache.java_test_binary_dir + "/.build")
            return None, ret
wester committed
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
        elif path in ['python', 'python2', 'python3']:
            executable = os.getenv('OPENCV_PYTHON_BINARY', None)
            if executable is None:
                executable = path
                if not self.tryCommand([executable, '--version']):
                    executable = 'python'
            cmd = [executable, self.cache.opencv_home + '/modules/python/test/test.py', '--repo', self.cache.opencv_home, '-v'] + args
            module_suffix = '' if not 'Visual Studio' in self.cache.cmake_generator else '/' + self.cache.build_type
            env = {}
            env['PYTHONPATH'] = self.cache.opencv_build + '/lib' + module_suffix + os.pathsep + os.getenv('PYTHONPATH', '')
            if self.cache.getOS() == 'nt':
                env['PATH'] = self.cache.opencv_build + '/bin' + module_suffix + os.pathsep + os.getenv('PATH', '')
            else:
                env['LD_LIBRARY_PATH'] = self.cache.opencv_build + '/bin' + os.pathsep + os.getenv('LD_LIBRARY_PATH', '')
            ret = execute(cmd, cwd = workingDir, env = env)
            return None, ret
wester committed
136 137 138 139 140 141 142
        else:
            if isColorEnabled(args):
                args.append("--gtest_color=yes")
            cmd = self.wrapInValgrind([exe] + args)
            tempDir = TempEnvDir('OPENCV_TEMP_PATH', "__opencv_temp.")
            tempDir.init()
            log.warning("Run: %s" % " ".join(cmd))
a  
Kai Westerkamp committed
143
            ret = execute(cmd, cwd = workingDir)
wester committed
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
            tempDir.clean()
            hostlogpath = os.path.join(workingDir, logfile)
            if os.path.isfile(hostlogpath):
                return hostlogpath, ret
            return None, ret

    def checkPrerequisites(self):
        if self.cache.getArch() == "x64" and hostmachine == "x86":
            raise Err("Target architecture is incompatible with current platform")

    def runTests(self, tests, black, workingDir, args = []):
        self.checkPrerequisites()
        args = args[:]
        logs = []
        test_list = self.getTestList(tests, black)
a  
Kai Westerkamp committed
159
        date = datetime.datetime.now()
wester committed
160 161 162 163 164 165 166
        if len(test_list) != 1:
            args = [a for a in args if not a.startswith("--gtest_output=")]
        ret = 0
        for test in test_list:
            more_args = []
            exe = self.getTest(test)

wester committed
167 168
            if exe in ["java", "python", "python2", "python3"]:
                logname = None
wester committed
169
            else:
wester committed
170 171 172 173 174 175
                userlog = [a for a in args if a.startswith("--gtest_output=")]
                if len(userlog) == 0:
                    logname = self.getLogName(exe, date)
                    more_args.append("--gtest_output=xml:" + logname)
                else:
                    logname = userlog[0][userlog[0].find(":")+1:]
wester committed
176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193

            log.debug("Running the test: %s (%s) ==> %s in %s", exe, args + more_args, logname, workingDir)
            if self.options.dry_run:
                logfile, r = None, 0
            else:
                logfile, r = self.runTest(exe, logname, workingDir, args + more_args)
            log.debug("Test returned: %s ==> %s", r, logfile)

            if r != 0:
                ret = r
            if logfile:
                logs.append(os.path.relpath(logfile, workingDir))
        return logs, ret

#===================================================================================================

if __name__ == "__main__":
    log.error("This is utility file, please execute run.py script")