run_suite.py 6.39 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 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 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 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
#!/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

    def getLogName(self, app, timestamp):
        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)
        return l + ".xml"

    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):
        if fullpath == "java":
            return True
        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']
            if self.options.valgrind_supp:
                res.append("--suppressions=%s" % self.options.valgrind_supp)
            res.extend(self.options.valgrind_opt)
            return res + cmd
        return cmd

    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
        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))
            ret = execute(cmd, cwd = workingDir)
            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)
        date = datetime.datetime.now()
        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)

            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:]

            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")