884 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			884 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env python
 | 
						|
 | 
						|
import sys, os, platform, xml, re, tempfile, glob, datetime, getpass, shutil
 | 
						|
from optparse import OptionParser
 | 
						|
from subprocess import Popen, PIPE
 | 
						|
 | 
						|
hostos = os.name # 'nt', 'posix'
 | 
						|
hostmachine = platform.machine() # 'x86', 'AMD64', 'x86_64'
 | 
						|
 | 
						|
SIMD_DETECTION_PROGRAM="""
 | 
						|
#if __SSE5__
 | 
						|
# error SSE5
 | 
						|
#endif
 | 
						|
#if __AVX2__
 | 
						|
# error AVX2
 | 
						|
#endif
 | 
						|
#if __AVX__
 | 
						|
# error AVX
 | 
						|
#endif
 | 
						|
#if __SSE4_2__
 | 
						|
# error SSE4.2
 | 
						|
#endif
 | 
						|
#if __SSE4_1__
 | 
						|
# error SSE4.1
 | 
						|
#endif
 | 
						|
#if __SSSE3__
 | 
						|
# error SSSE3
 | 
						|
#endif
 | 
						|
#if __SSE3__
 | 
						|
# error SSE3
 | 
						|
#endif
 | 
						|
#if __AES__
 | 
						|
# error AES
 | 
						|
#endif
 | 
						|
#if __SSE2__
 | 
						|
# error SSE2
 | 
						|
#endif
 | 
						|
#if __SSE__
 | 
						|
# error SSE
 | 
						|
#endif
 | 
						|
#if __3dNOW__
 | 
						|
# error 3dNOW
 | 
						|
#endif
 | 
						|
#if __MMX__
 | 
						|
# error MMX
 | 
						|
#endif
 | 
						|
#if __ARM_NEON__
 | 
						|
# error NEON
 | 
						|
#endif
 | 
						|
#error NOSIMD
 | 
						|
"""
 | 
						|
 | 
						|
parse_patterns = (
 | 
						|
  {'name': "has_perf_tests",           'default': "OFF",      'pattern': re.compile("^BUILD_PERF_TESTS:BOOL=(ON)$")},
 | 
						|
  {'name': "has_accuracy_tests",       'default': "OFF",      'pattern': re.compile("^BUILD_TESTS:BOOL=(ON)$")},
 | 
						|
  {'name': "cmake_home",               'default': None,       'pattern': re.compile("^CMAKE_HOME_DIRECTORY:INTERNAL=(.+)$")},
 | 
						|
  {'name': "opencv_home",              'default': None,       'pattern': re.compile("^OpenCV_SOURCE_DIR:STATIC=(.+)$")},
 | 
						|
  {'name': "tests_dir",                'default': None,       'pattern': re.compile("^EXECUTABLE_OUTPUT_PATH:PATH=(.+)$")},
 | 
						|
  {'name': "build_type",               'default': "Release",  'pattern': re.compile("^CMAKE_BUILD_TYPE:STRING=(.*)$")},
 | 
						|
  {'name': "svnversion_path",          'default': None,       'pattern': re.compile("^SVNVERSION_PATH:FILEPATH=(.*)$")},
 | 
						|
  {'name': "git_executable",           'default': None,       'pattern': re.compile("^GIT_EXECUTABLE:FILEPATH=(.*)$")},
 | 
						|
  {'name': "cxx_flags",                'default': "",         'pattern': re.compile("^CMAKE_CXX_FLAGS:STRING=(.*)$")},
 | 
						|
  {'name': "cxx_flags_debug",          'default': "",         'pattern': re.compile("^CMAKE_CXX_FLAGS_DEBUG:STRING=(.*)$")},
 | 
						|
  {'name': "cxx_flags_release",        'default': "",         'pattern': re.compile("^CMAKE_CXX_FLAGS_RELEASE:STRING=(.*)$")},
 | 
						|
  {'name': "opencv_cxx_flags",         'default': "",         'pattern': re.compile("^OPENCV_EXTRA_C_FLAGS:INTERNAL=(.*)$")},
 | 
						|
  {'name': "opencv_cxx_flags_debug",   'default': "",         'pattern': re.compile("^OPENCV_EXTRA_C_FLAGS_DEBUG:INTERNAL=(.*)$")},
 | 
						|
  {'name': "opencv_cxx_flags_release", 'default': "",         'pattern': re.compile("^OPENCV_EXTRA_C_FLAGS_RELEASE:INTERNAL=(.*)$")},
 | 
						|
  {'name': "cxx_flags_android",        'default': None,       'pattern': re.compile("^ANDROID_CXX_FLAGS:INTERNAL=(.*)$")},
 | 
						|
  {'name': "ndk_path",                 'default': None,       'pattern': re.compile("^(?:ANDROID_NDK|ANDROID_STANDALONE_TOOLCHAIN)?:PATH=(.*)$")},
 | 
						|
  {'name': "android_abi",              'default': None,       'pattern': re.compile("^ANDROID_ABI:STRING=(.*)$")},
 | 
						|
  {'name': "android_executable",       'default': None,       'pattern': re.compile("^ANDROID_EXECUTABLE:FILEPATH=(.*android.*)$")},
 | 
						|
  {'name': "ant_executable",           'default': None,       'pattern': re.compile("^ANT_EXECUTABLE:FILEPATH=(.*ant.*)$")},
 | 
						|
  {'name': "java_test_binary_dir",     'default': None,       'pattern': re.compile("^opencv_test_java_BINARY_DIR:STATIC=(.*)$")},
 | 
						|
  {'name': "is_x64",                   'default': "OFF",      'pattern': re.compile("^CUDA_64_BIT_DEVICE_CODE:BOOL=(ON)$")},#ugly(
 | 
						|
  {'name': "cmake_generator",          'default': None,       'pattern': re.compile("^CMAKE_GENERATOR:INTERNAL=(.+)$")},
 | 
						|
  {'name': "cxx_compiler",             'default': None,       'pattern': re.compile("^CMAKE_CXX_COMPILER:FILEPATH=(.+)$")},
 | 
						|
  {'name': "cxx_compiler_arg1",        'default': None,       'pattern': re.compile("^CMAKE_CXX_COMPILER_ARG1:[A-Z]+=(.+)$")},
 | 
						|
  {'name': "with_cuda",                'default': "OFF",      'pattern': re.compile("^WITH_CUDA:BOOL=(ON)$")},
 | 
						|
  {'name': "cuda_library",             'default': None,       'pattern': re.compile("^CUDA_CUDA_LIBRARY:FILEPATH=(.+)$")},
 | 
						|
  {'name': "core_dependencies",        'default': None,       'pattern': re.compile("^opencv_core_LIB_DEPENDS:STATIC=(.+)$")},
 | 
						|
)
 | 
						|
 | 
						|
def query_yes_no(stdout, question, default="yes"):
 | 
						|
    valid = {"yes":True, "y":True, "ye":True, "no":False, "n":False}
 | 
						|
    if default == None:
 | 
						|
        prompt = " [y/n] "
 | 
						|
    elif default == "yes":
 | 
						|
        prompt = " [Y/n] "
 | 
						|
    elif default == "no":
 | 
						|
        prompt = " [y/N] "
 | 
						|
    else:
 | 
						|
        raise ValueError("invalid default answer: '%s'" % default)
 | 
						|
 | 
						|
    while True:
 | 
						|
        stdout.write(os.linesep + question + prompt)
 | 
						|
        choice = raw_input().lower()
 | 
						|
        if default is not None and choice == '':
 | 
						|
            return valid[default]
 | 
						|
        elif choice in valid:
 | 
						|
            return valid[choice]
 | 
						|
        else:
 | 
						|
            stdout.write("Please respond with 'yes' or 'no' "\
 | 
						|
                             "(or 'y' or 'n').\n")
 | 
						|
 | 
						|
def getRunningProcessExePathByName_win32(name):
 | 
						|
    from ctypes import windll, POINTER, pointer, Structure, sizeof
 | 
						|
    from ctypes import c_long , c_int , c_uint , c_char , c_ubyte , c_char_p , c_void_p
 | 
						|
 | 
						|
    class PROCESSENTRY32(Structure):
 | 
						|
        _fields_ = [ ( 'dwSize' , c_uint ) ,
 | 
						|
                    ( 'cntUsage' , c_uint) ,
 | 
						|
                    ( 'th32ProcessID' , c_uint) ,
 | 
						|
                    ( 'th32DefaultHeapID' , c_uint) ,
 | 
						|
                    ( 'th32ModuleID' , c_uint) ,
 | 
						|
                    ( 'cntThreads' , c_uint) ,
 | 
						|
                    ( 'th32ParentProcessID' , c_uint) ,
 | 
						|
                    ( 'pcPriClassBase' , c_long) ,
 | 
						|
                    ( 'dwFlags' , c_uint) ,
 | 
						|
                    ( 'szExeFile' , c_char * 260 ) ,
 | 
						|
                    ( 'th32MemoryBase' , c_long) ,
 | 
						|
                    ( 'th32AccessKey' , c_long ) ]
 | 
						|
 | 
						|
    class MODULEENTRY32(Structure):
 | 
						|
        _fields_ = [ ( 'dwSize' , c_long ) ,
 | 
						|
                    ( 'th32ModuleID' , c_long ),
 | 
						|
                    ( 'th32ProcessID' , c_long ),
 | 
						|
                    ( 'GlblcntUsage' , c_long ),
 | 
						|
                    ( 'ProccntUsage' , c_long ) ,
 | 
						|
                    ( 'modBaseAddr' , c_long ) ,
 | 
						|
                    ( 'modBaseSize' , c_long ) ,
 | 
						|
                    ( 'hModule' , c_void_p ) ,
 | 
						|
                    ( 'szModule' , c_char * 256 ),
 | 
						|
                    ( 'szExePath' , c_char * 260 ) ]
 | 
						|
 | 
						|
    TH32CS_SNAPPROCESS = 2
 | 
						|
    TH32CS_SNAPMODULE = 0x00000008
 | 
						|
 | 
						|
    ## CreateToolhelp32Snapshot
 | 
						|
    CreateToolhelp32Snapshot= windll.kernel32.CreateToolhelp32Snapshot
 | 
						|
    CreateToolhelp32Snapshot.reltype = c_long
 | 
						|
    CreateToolhelp32Snapshot.argtypes = [ c_int , c_int ]
 | 
						|
    ## Process32First
 | 
						|
    Process32First = windll.kernel32.Process32First
 | 
						|
    Process32First.argtypes = [ c_void_p , POINTER( PROCESSENTRY32 ) ]
 | 
						|
    Process32First.rettype = c_int
 | 
						|
    ## Process32Next
 | 
						|
    Process32Next = windll.kernel32.Process32Next
 | 
						|
    Process32Next.argtypes = [ c_void_p , POINTER(PROCESSENTRY32) ]
 | 
						|
    Process32Next.rettype = c_int
 | 
						|
    ## CloseHandle
 | 
						|
    CloseHandle = windll.kernel32.CloseHandle
 | 
						|
    CloseHandle.argtypes = [ c_void_p ]
 | 
						|
    CloseHandle.rettype = c_int
 | 
						|
    ## Module32First
 | 
						|
    Module32First = windll.kernel32.Module32First
 | 
						|
    Module32First.argtypes = [ c_void_p , POINTER(MODULEENTRY32) ]
 | 
						|
    Module32First.rettype = c_int
 | 
						|
 | 
						|
    hProcessSnap = c_void_p(0)
 | 
						|
    hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 )
 | 
						|
 | 
						|
    pe32 = PROCESSENTRY32()
 | 
						|
    pe32.dwSize = sizeof( PROCESSENTRY32 )
 | 
						|
    ret = Process32First( hProcessSnap , pointer( pe32 ) )
 | 
						|
    path = None
 | 
						|
 | 
						|
    while ret :
 | 
						|
        if name + ".exe" == pe32.szExeFile:
 | 
						|
            hModuleSnap = c_void_p(0)
 | 
						|
            me32 = MODULEENTRY32()
 | 
						|
            me32.dwSize = sizeof( MODULEENTRY32 )
 | 
						|
            hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pe32.th32ProcessID )
 | 
						|
 | 
						|
            ret = Module32First( hModuleSnap, pointer(me32) )
 | 
						|
            path = me32.szExePath
 | 
						|
            CloseHandle( hModuleSnap )
 | 
						|
            if path:
 | 
						|
                break
 | 
						|
        ret = Process32Next( hProcessSnap, pointer(pe32) )
 | 
						|
    CloseHandle( hProcessSnap )
 | 
						|
    return path
 | 
						|
 | 
						|
def getRunningProcessExePathByName_posix(name):
 | 
						|
    pids= [pid for pid in os.listdir('/proc') if pid.isdigit()]
 | 
						|
    for pid in pids:
 | 
						|
        try:
 | 
						|
            path = os.readlink(os.path.join('/proc', pid, 'exe'))
 | 
						|
            if path and path.endswith(name):
 | 
						|
                return path
 | 
						|
        except:
 | 
						|
            pass
 | 
						|
 | 
						|
def getRunningProcessExePathByName(name):
 | 
						|
    try:
 | 
						|
        if hostos == "nt":
 | 
						|
            return getRunningProcessExePathByName_win32(name)
 | 
						|
        elif hostos == "posix":
 | 
						|
            return getRunningProcessExePathByName_posix(name)
 | 
						|
        else:
 | 
						|
            return None
 | 
						|
    except:
 | 
						|
        return None
 | 
						|
 | 
						|
class TestSuite(object):
 | 
						|
    def __init__(self, options, path = None):
 | 
						|
        self.options = options
 | 
						|
        self.path = path
 | 
						|
        self.error = None
 | 
						|
        self.setUp = None
 | 
						|
        self.tearDown = None
 | 
						|
        self.adb = None
 | 
						|
        self.targetos = None
 | 
						|
        self.nameprefix = "opencv_" + self.options.mode + "_"
 | 
						|
        for p in parse_patterns:
 | 
						|
            setattr(self, p["name"], p["default"])
 | 
						|
 | 
						|
        if self.path:
 | 
						|
            cachefile = open(os.path.join(self.path, "CMakeCache.txt"), "rt")
 | 
						|
            try:
 | 
						|
                for l in cachefile.readlines():
 | 
						|
                    ll = l.strip()
 | 
						|
                    if not ll or ll.startswith("#"):
 | 
						|
                        continue
 | 
						|
                    for p in parse_patterns:
 | 
						|
                        match = p["pattern"].match(ll)
 | 
						|
                        if match:
 | 
						|
                            value = match.groups()[0]
 | 
						|
                            if value and not value.endswith("-NOTFOUND"):
 | 
						|
                                setattr(self, p["name"], value)
 | 
						|
            except:
 | 
						|
                pass
 | 
						|
            cachefile.close()
 | 
						|
 | 
						|
            # detect target platform
 | 
						|
            if self.android_executable or self.android_abi or self.ndk_path:
 | 
						|
                self.targetos = "android"
 | 
						|
            else:
 | 
						|
                self.targetos = hostos
 | 
						|
 | 
						|
            self.initialize()
 | 
						|
 | 
						|
    def initialize(self):
 | 
						|
        # fix empty tests dir
 | 
						|
        if not self.tests_dir:
 | 
						|
            self.tests_dir = self.path
 | 
						|
        self.tests_dir = os.path.normpath(self.tests_dir)
 | 
						|
 | 
						|
        # compute path to adb
 | 
						|
        if self.android_executable:
 | 
						|
            self.adb = os.path.join(os.path.dirname(os.path.dirname(self.android_executable)), ("platform-tools/adb","platform-tools/adb.exe")[hostos == 'nt'])
 | 
						|
            if not os.path.isfile(self.adb) or not os.access(self.adb, os.X_OK):
 | 
						|
                self.adb = None
 | 
						|
        else:
 | 
						|
            self.adb = None
 | 
						|
 | 
						|
        if self.targetos == "android":
 | 
						|
            # fix adb tool location
 | 
						|
            if not self.adb:
 | 
						|
                self.adb = getRunningProcessExePathByName("adb")
 | 
						|
            if not self.adb:
 | 
						|
                self.adb = "adb"
 | 
						|
            if self.options.adb_serial:
 | 
						|
                self.adb = [self.adb, "-s", self.options.adb_serial]
 | 
						|
            else:
 | 
						|
                self.adb = [self.adb]
 | 
						|
            try:
 | 
						|
                output = Popen(self.adb + ["shell", "ls"], stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
            except OSError:
 | 
						|
                self.adb = []
 | 
						|
            # remember current device serial. Needed if another device is connected while this script runs
 | 
						|
            if self.adb and not self.options.adb_serial:
 | 
						|
                adb_res = self.runAdb("devices")
 | 
						|
                if not adb_res:
 | 
						|
                    self.error = "Could not run adb command: %s (for %s)" % (self.error, self.path)
 | 
						|
                    self.adb = []
 | 
						|
                else:
 | 
						|
                    # assume here that device name may consists of any characters except newline
 | 
						|
                    connected_devices = re.findall(r"^[^\n]+[ \t]+device\r?$", adb_res, re.MULTILINE)
 | 
						|
                    if not connected_devices:
 | 
						|
                        self.error = "Android device not found"
 | 
						|
                        self.adb = []
 | 
						|
                    elif len(connected_devices) != 1:
 | 
						|
                        self.error = "Too many (%s) devices are connected. Please specify single device using --serial option:\n\n" % (len(connected_devices)) + adb_res
 | 
						|
                        self.adb = []
 | 
						|
                    else:
 | 
						|
                        self.options.adb_serial = connected_devices[0].split("\t")[0]
 | 
						|
                        self.adb = self.adb + ["-s", self.options.adb_serial]
 | 
						|
            if self.adb:
 | 
						|
                # construct name for aapt tool
 | 
						|
                self.aapt = [os.path.join(os.path.dirname(self.adb[0]), ("aapt","aapt.exe")[hostos == 'nt'])]
 | 
						|
 | 
						|
        # fix has_perf_tests param
 | 
						|
        self.has_perf_tests = self.has_perf_tests == "ON"
 | 
						|
        self.has_accuracy_tests = self.has_accuracy_tests == "ON"
 | 
						|
        # fix is_x64 flag
 | 
						|
        self.is_x64 = self.is_x64 == "ON"
 | 
						|
        if not self.is_x64 and ("X64" in "%s %s %s" % (self.cxx_flags, self.cxx_flags_release, self.cxx_flags_debug) or "Win64" in self.cmake_generator):
 | 
						|
            self.is_x64 = True
 | 
						|
 | 
						|
        # fix test path
 | 
						|
        if "Visual Studio" in self.cmake_generator:
 | 
						|
            if self.options.configuration:
 | 
						|
                self.tests_dir = os.path.join(self.tests_dir, self.options.configuration)
 | 
						|
            else:
 | 
						|
                self.tests_dir = os.path.join(self.tests_dir, self.build_type)
 | 
						|
        elif not self.is_x64 and self.cxx_compiler:
 | 
						|
            #one more attempt to detect x64 compiler
 | 
						|
            try:
 | 
						|
                compiler = [self.cxx_compiler]
 | 
						|
                if self.cxx_compiler_arg1:
 | 
						|
                    compiler.append(self.cxx_compiler_arg1)
 | 
						|
                output = Popen(compiler + ["-v"], stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
                if not output[0] and "x86_64" in output[1]:
 | 
						|
                    self.is_x64 = True
 | 
						|
            except OSError:
 | 
						|
                pass
 | 
						|
 | 
						|
        # detect target arch
 | 
						|
        if self.targetos == "android":
 | 
						|
            if "armeabi-v7a" in self.android_abi:
 | 
						|
                self.targetarch = "armv7a"
 | 
						|
            elif "armeabi-v6" in self.android_abi:
 | 
						|
                self.targetarch = "armv6"
 | 
						|
            elif "armeabi" in self.android_abi:
 | 
						|
                self.targetarch = "armv5te"
 | 
						|
            elif "x86" in self.android_abi:
 | 
						|
                self.targetarch = "x86"
 | 
						|
            elif "mips" in self.android_abi:
 | 
						|
                self.targetarch = "mips"
 | 
						|
            else:
 | 
						|
                self.targetarch = "ARM"
 | 
						|
        elif self.is_x64 and hostmachine in ["AMD64", "x86_64"]:
 | 
						|
            self.targetarch = "x64"
 | 
						|
        elif hostmachine in ["x86", "AMD64", "x86_64"]:
 | 
						|
            self.targetarch = "x86"
 | 
						|
        else:
 | 
						|
            self.targetarch = "unknown"
 | 
						|
 | 
						|
        # fix CUDA attributes
 | 
						|
        self.with_cuda = self.with_cuda == "ON"
 | 
						|
        if self.cuda_library and self.cuda_library.endswith("-NOTFOUND"):
 | 
						|
            self.cuda_library = None
 | 
						|
        self.has_cuda = self.with_cuda and self.cuda_library and self.targetarch in ["x86", "x64"]
 | 
						|
 | 
						|
        self.hardware = None
 | 
						|
 | 
						|
        self.cmake_home_vcver = self.getVCVersion(self.cmake_home)
 | 
						|
        if self.opencv_home == self.cmake_home:
 | 
						|
            self.opencv_home_vcver = self.cmake_home_vcver
 | 
						|
        else:
 | 
						|
            self.opencv_home_vcver = self.getVCVersion(self.opencv_home)
 | 
						|
 | 
						|
        self.tests = self.getAvailableTestApps()
 | 
						|
 | 
						|
    def getVCVersion(self, root_path):
 | 
						|
        if not root_path:
 | 
						|
            return None
 | 
						|
        if os.path.isdir(os.path.join(root_path, ".svn")):
 | 
						|
            return self.getSvnVersion(root_path)
 | 
						|
        elif os.path.isdir(os.path.join(root_path, ".git")):
 | 
						|
            return self.getGitHash(root_path)
 | 
						|
        return None
 | 
						|
 | 
						|
    def getGitHash(self, path):
 | 
						|
        if not path or not self.git_executable:
 | 
						|
            return None
 | 
						|
        try:
 | 
						|
            output = Popen([self.git_executable, "rev-parse", "--short", "HEAD"], stdout=PIPE, stderr=PIPE, cwd = path).communicate()
 | 
						|
            if not output[1]:
 | 
						|
                return output[0].strip()
 | 
						|
            else:
 | 
						|
                return None
 | 
						|
        except OSError:
 | 
						|
            return None
 | 
						|
 | 
						|
    def getSvnVersion(self, path):
 | 
						|
        if not path:
 | 
						|
            val = None
 | 
						|
        elif not self.svnversion_path and hostos == 'nt':
 | 
						|
            val = self.tryGetSvnVersionWithTortoise(path)
 | 
						|
        else:
 | 
						|
            svnversion = self.svnversion_path
 | 
						|
            if not svnversion:
 | 
						|
                svnversion = "svnversion"
 | 
						|
            try:
 | 
						|
                output = Popen([svnversion, "-n", path], stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
                if not output[1]:
 | 
						|
                    val = output[0]
 | 
						|
                else:
 | 
						|
                    val = None
 | 
						|
            except OSError:
 | 
						|
                val = None
 | 
						|
        if val:
 | 
						|
            val = val.replace(" ", "_")
 | 
						|
        return val
 | 
						|
 | 
						|
    def tryGetSvnVersionWithTortoise(self, path):
 | 
						|
        try:
 | 
						|
            wcrev = "SubWCRev.exe"
 | 
						|
            dir = tempfile.mkdtemp()
 | 
						|
            #print dir
 | 
						|
            tmpfilename = os.path.join(dir, "svn.tmp")
 | 
						|
            tmpfilename2 = os.path.join(dir, "svn_out.tmp")
 | 
						|
            tmpfile = open(tmpfilename, "w")
 | 
						|
            tmpfile.write("$WCRANGE$$WCMODS?M:$")
 | 
						|
            tmpfile.close();
 | 
						|
            output = Popen([wcrev, path, tmpfilename, tmpfilename2, "-f"], stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
            if "is not a working copy" in output[0]:
 | 
						|
                version = "exported"
 | 
						|
            else:
 | 
						|
                tmpfile = open(tmpfilename2, "r")
 | 
						|
                version = tmpfile.read()
 | 
						|
                tmpfile.close()
 | 
						|
            return version
 | 
						|
        except:
 | 
						|
            return None
 | 
						|
        finally:
 | 
						|
            if dir:
 | 
						|
                shutil.rmtree(dir)
 | 
						|
 | 
						|
    def isTest(self, fullpath):
 | 
						|
        if not os.path.isfile(fullpath):
 | 
						|
            return False
 | 
						|
        if self.targetos == "nt" and not fullpath.endswith(".exe"):
 | 
						|
            return False
 | 
						|
        if hostos == self.targetos:
 | 
						|
            return os.access(fullpath, os.X_OK)
 | 
						|
        if self.targetos == "android" and fullpath.endswith(".apk"):
 | 
						|
            return True
 | 
						|
        return True
 | 
						|
 | 
						|
    def getAvailableTestApps(self):
 | 
						|
        if self.tests_dir and os.path.isdir(self.tests_dir):
 | 
						|
            files = glob.glob(os.path.join(self.tests_dir, self.nameprefix + "*"))
 | 
						|
            files = [f for f in files if self.isTest(f)]
 | 
						|
            if self.ant_executable and self.java_test_binary_dir:
 | 
						|
                files.append("java")
 | 
						|
            return files
 | 
						|
        return []
 | 
						|
 | 
						|
    def getLogName(self, app, timestamp):
 | 
						|
        app = os.path.basename(app)
 | 
						|
        if app.endswith(".exe"):
 | 
						|
            if app.endswith("d.exe"):
 | 
						|
                app = app[:-5]
 | 
						|
            else:
 | 
						|
                app = app[:-4]
 | 
						|
        if app.startswith(self.nameprefix):
 | 
						|
            app = app[len(self.nameprefix):]
 | 
						|
 | 
						|
        if self.cmake_home_vcver:
 | 
						|
            if self.cmake_home_vcver == self.opencv_home_vcver:
 | 
						|
                rev = self.cmake_home_vcver
 | 
						|
            elif self.opencv_home_vcver:
 | 
						|
                rev = self.cmake_home_vcver + "-" + self.opencv_home_vcver
 | 
						|
            else:
 | 
						|
                rev = self.cmake_home_vcver
 | 
						|
        else:
 | 
						|
            rev = None
 | 
						|
        if rev:
 | 
						|
            rev = rev.replace(":","to")
 | 
						|
        else:
 | 
						|
            rev = ""
 | 
						|
 | 
						|
        if self.options.useLongNames:
 | 
						|
            if not rev:
 | 
						|
                rev = "unknown"
 | 
						|
            tstamp = timestamp.strftime("%Y%m%d-%H%M%S")
 | 
						|
 | 
						|
            features = []
 | 
						|
            #OS
 | 
						|
            _os = ""
 | 
						|
            if self.targetos == "android":
 | 
						|
                _os = "Android" + self.runAdb("shell", "getprop ro.build.version.release").strip()
 | 
						|
            else:
 | 
						|
                mv = platform.mac_ver()
 | 
						|
                if mv[0]:
 | 
						|
                    _os = "Darwin" + mv[0]
 | 
						|
                else:
 | 
						|
                    wv = platform.win32_ver()
 | 
						|
                    if wv[0]:
 | 
						|
                        _os = "Windows" + wv[0]
 | 
						|
                    else:
 | 
						|
                        lv = platform.linux_distribution()
 | 
						|
                        if lv[0]:
 | 
						|
                            _os = lv[0] + lv[1]
 | 
						|
                        else:
 | 
						|
                            _os = self.targetos
 | 
						|
            features.append(_os)
 | 
						|
 | 
						|
            #HW(x86, x64, ARMv7a)
 | 
						|
            if self.targetarch:
 | 
						|
                features.append(self.targetarch)
 | 
						|
 | 
						|
            #TBB
 | 
						|
            if ";tbb;" in self.core_dependencies:
 | 
						|
                features.append("TBB")
 | 
						|
 | 
						|
            #CUDA
 | 
						|
            if self.has_cuda:
 | 
						|
                #TODO: determine compute capability
 | 
						|
                features.append("CUDA")
 | 
						|
 | 
						|
            #SIMD
 | 
						|
            compiler_output = ""
 | 
						|
            try:
 | 
						|
                tmpfile = tempfile.mkstemp(suffix=".cpp", text = True)
 | 
						|
                fd = os.fdopen(tmpfile[0], "w+b")
 | 
						|
                fd.write(SIMD_DETECTION_PROGRAM)
 | 
						|
                fd.close();
 | 
						|
                options = [self.cxx_compiler]
 | 
						|
                if self.cxx_compiler_arg1:
 | 
						|
                    options.append(self.cxx_compiler_arg1)
 | 
						|
                cxx_flags = self.cxx_flags + " " + self.cxx_flags_release + " " + self.opencv_cxx_flags + " " + self.opencv_cxx_flags_release
 | 
						|
                if self.targetos == "android" and self.cxx_flags_android:
 | 
						|
                    cxx_flags = self.cxx_flags_android + " " + cxx_flags
 | 
						|
 | 
						|
                prev_option = None
 | 
						|
                for opt in cxx_flags.split(" "):
 | 
						|
                    if opt.count('\"') % 2 == 1:
 | 
						|
                        if prev_option is None:
 | 
						|
                             prev_option = opt
 | 
						|
                        else:
 | 
						|
                             options.append(prev_option + " " + opt)
 | 
						|
                             prev_option = None
 | 
						|
                    elif prev_option is None:
 | 
						|
                        options.append(opt)
 | 
						|
                    else:
 | 
						|
                        prev_option = prev_option + " " + opt
 | 
						|
                options.append(tmpfile[1])
 | 
						|
                output = Popen(options, stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
                compiler_output = output[1]
 | 
						|
                os.remove(tmpfile[1])
 | 
						|
            except OSError:
 | 
						|
                pass
 | 
						|
            if compiler_output:
 | 
						|
                m = re.search("#error\W+(\w+)", compiler_output)
 | 
						|
                if m:
 | 
						|
                    features.append(m.group(1))
 | 
						|
 | 
						|
            #fin
 | 
						|
            return "%s__%s__%s__%s.xml" % (app, rev, tstamp, "_".join(features))
 | 
						|
        else:
 | 
						|
            if rev:
 | 
						|
                rev = rev + "_"
 | 
						|
            if self.hardware:
 | 
						|
                hw = str(self.hardware).replace(" ", "_") + "_"
 | 
						|
            elif self.has_cuda:
 | 
						|
                hw = "CUDA_"
 | 
						|
            else:
 | 
						|
                hw = ""
 | 
						|
            tstamp = timestamp.strftime("%Y%m%d-%H%M%S")
 | 
						|
            return "%s_%s_%s_%s%s%s.xml" % (app, self.targetos, self.targetarch, hw, rev, tstamp)
 | 
						|
 | 
						|
    def getTest(self, name):
 | 
						|
        # full path
 | 
						|
        if self.isTest(name):
 | 
						|
            return name
 | 
						|
 | 
						|
        # name only
 | 
						|
        fullname = os.path.join(self.tests_dir, name)
 | 
						|
        if self.isTest(fullname):
 | 
						|
            return fullname
 | 
						|
 | 
						|
        # name without extension
 | 
						|
        fullname += ".exe"
 | 
						|
        if self.isTest(fullname):
 | 
						|
            return fullname
 | 
						|
        if self.targetos == "android":
 | 
						|
            fullname += ".apk"
 | 
						|
            if self.isTest(fullname):
 | 
						|
                return fullname
 | 
						|
 | 
						|
        # short name for OpenCV tests
 | 
						|
        for t in self.tests:
 | 
						|
            if t == name:
 | 
						|
                return t
 | 
						|
            fname = os.path.basename(t)
 | 
						|
            if fname == name:
 | 
						|
                return t
 | 
						|
            if fname.endswith(".exe") or (self.targetos == "android" and fname.endswith(".apk")):
 | 
						|
                fname = fname[:-4]
 | 
						|
            if fname == name:
 | 
						|
                return t
 | 
						|
            if self.options.configuration == "Debug" and fname == name + 'd':
 | 
						|
                return t
 | 
						|
            if fname.startswith(self.nameprefix):
 | 
						|
                fname = fname[len(self.nameprefix):]
 | 
						|
            if fname == name:
 | 
						|
                return t
 | 
						|
            if self.options.configuration == "Debug" and fname == name + 'd':
 | 
						|
                return t
 | 
						|
        return None
 | 
						|
 | 
						|
    def runAdb(self, *args):
 | 
						|
        cmd = self.adb[:]
 | 
						|
        cmd.extend(args)
 | 
						|
        try:
 | 
						|
            output = Popen(cmd, stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
            if not output[1]:
 | 
						|
                return output[0]
 | 
						|
            self.error = output[1]
 | 
						|
        except OSError:
 | 
						|
            pass
 | 
						|
        return None
 | 
						|
 | 
						|
    def isRunnable(self):
 | 
						|
        if self.error:
 | 
						|
            return False
 | 
						|
        if self.targetarch == "x64" and hostmachine == "x86":
 | 
						|
            self.error = "Target architecture is incompatible with current platform (at %s)" % self.path
 | 
						|
            return False
 | 
						|
        if self.targetos == "android":
 | 
						|
            if not self.adb:
 | 
						|
                self.error = "Could not find adb executable (for %s)" % self.path
 | 
						|
                return False
 | 
						|
            if "armeabi-v7a" in self.android_abi:
 | 
						|
                adb_res = self.runAdb("shell", "cat /proc/cpuinfo")
 | 
						|
                if not adb_res:
 | 
						|
                    self.error = "Could not get info about Android platform: %s (for %s)" % (self.error, self.path)
 | 
						|
                    return False
 | 
						|
                if "ARMv7" not in adb_res:
 | 
						|
                    self.error = "Android device does not support ARMv7 commands, but tests are built for armeabi-v7a (for %s)" % self.path
 | 
						|
                    return False
 | 
						|
                if "NEON" in self.android_abi and "neon" not in adb_res:
 | 
						|
                    self.error = "Android device has no NEON, but tests are built for %s (for %s)" % (self.android_abi, self.path)
 | 
						|
                    return False
 | 
						|
                hw = re.search(r"^Hardware[ \t]*:[ \t]*(.*?)$", adb_res, re.MULTILINE)
 | 
						|
                if hw:
 | 
						|
                    self.hardware = hw.groups()[0].strip()
 | 
						|
        return True
 | 
						|
 | 
						|
    def runTest(self, path, workingDir, _stdout, _stderr, args = []):
 | 
						|
        if self.error:
 | 
						|
            return
 | 
						|
        args = args[:]
 | 
						|
        timestamp = datetime.datetime.now()
 | 
						|
        logfile = self.getLogName(path, timestamp)
 | 
						|
        exe = os.path.abspath(path)
 | 
						|
 | 
						|
        userlog = [a for a in args if a.startswith("--gtest_output=")]
 | 
						|
        if len(userlog) == 0:
 | 
						|
            args.append("--gtest_output=xml:" + logfile)
 | 
						|
        else:
 | 
						|
            logfile = userlog[0][userlog[0].find(":")+1:]
 | 
						|
 | 
						|
        if self.targetos == "android" and exe.endswith(".apk"):
 | 
						|
            print "Run java tests:", exe
 | 
						|
            try:
 | 
						|
                # get package info
 | 
						|
                output = Popen(self.aapt + ["dump", "xmltree", exe, "AndroidManifest.xml"], stdout=PIPE, stderr=_stderr).communicate()
 | 
						|
                if not output[0]:
 | 
						|
                    print >> _stderr, "fail to dump manifest from", exe
 | 
						|
                    return
 | 
						|
                tags = re.split(r"[ ]+E: ", output[0])
 | 
						|
                # get package name
 | 
						|
                manifest_tag = [t for t in tags if t.startswith("manifest ")]
 | 
						|
                if not manifest_tag:
 | 
						|
                    print >> _stderr, "fail to read package name from", exe
 | 
						|
                    return
 | 
						|
                pkg_name =  re.search(r"^[ ]+A: package=\"(?P<pkg>.*?)\" \(Raw: \"(?P=pkg)\"\)\r?$", manifest_tag[0], flags=re.MULTILINE).group("pkg")
 | 
						|
                # get test instrumentation info
 | 
						|
                instrumentation_tag = [t for t in tags if t.startswith("instrumentation ")]
 | 
						|
                if not instrumentation_tag:
 | 
						|
                    print >> _stderr, "can not find instrumentation detials in", exe
 | 
						|
                    return
 | 
						|
                pkg_runner = re.search(r"^[ ]+A: android:name\(0x[0-9a-f]{8}\)=\"(?P<runner>.*?)\" \(Raw: \"(?P=runner)\"\)\r?$", instrumentation_tag[0], flags=re.MULTILINE).group("runner")
 | 
						|
                pkg_target =  re.search(r"^[ ]+A: android:targetPackage\(0x[0-9a-f]{8}\)=\"(?P<pkg>.*?)\" \(Raw: \"(?P=pkg)\"\)\r?$", instrumentation_tag[0], flags=re.MULTILINE).group("pkg")
 | 
						|
                if not pkg_name or not pkg_runner or not pkg_target:
 | 
						|
                    print >> _stderr, "can not find instrumentation detials in", exe
 | 
						|
                    return
 | 
						|
                if self.options.junit_package:
 | 
						|
                    if self.options.junit_package.startswith("."):
 | 
						|
                        pkg_target += self.options.junit_package
 | 
						|
                    else:
 | 
						|
                        pkg_target = self.options.junit_package
 | 
						|
                # uninstall previously installed package
 | 
						|
                print >> _stderr, "Uninstalling old", pkg_name, "from device..."
 | 
						|
                Popen(self.adb + ["uninstall", pkg_name], stdout=PIPE, stderr=_stderr).communicate()
 | 
						|
                print >> _stderr, "Installing new", exe, "to device...",
 | 
						|
                output = Popen(self.adb + ["install", exe], stdout=PIPE, stderr=PIPE).communicate()
 | 
						|
                if output[0] and output[0].strip().endswith("Success"):
 | 
						|
                    print >> _stderr, "Success"
 | 
						|
                else:
 | 
						|
                    print >> _stderr, "Failure"
 | 
						|
                    print >> _stderr, "Failed to install", exe, "to device"
 | 
						|
                    return
 | 
						|
                print >> _stderr, "Running jUnit tests for ", pkg_target
 | 
						|
                if self.setUp:
 | 
						|
                    self.setUp()
 | 
						|
                Popen(self.adb + ["shell", "am instrument -w -e package " + pkg_target + " " + pkg_name + "/" + pkg_runner], stdout=_stdout, stderr=_stderr).wait()
 | 
						|
                if self.tearDown:
 | 
						|
                    self.tearDown()
 | 
						|
            except OSError:
 | 
						|
                pass
 | 
						|
            return
 | 
						|
        elif self.targetos == "android":
 | 
						|
            hostlogpath = ""
 | 
						|
            usercolor = [a for a in args if a.startswith("--gtest_color=")]
 | 
						|
            if len(usercolor) == 0 and _stdout.isatty() and hostos != "nt":
 | 
						|
                args.append("--gtest_color=yes")
 | 
						|
            try:
 | 
						|
                tempdir = "/data/local/tmp/"
 | 
						|
                andoidcwd = tempdir + getpass.getuser().replace(" ","") + "_" + self.options.mode +"/"
 | 
						|
                exename = os.path.basename(exe)
 | 
						|
                androidexe = andoidcwd + exename
 | 
						|
                # upload
 | 
						|
                _stderr.write("Uploading... ")
 | 
						|
                output = Popen(self.adb + ["push", exe, androidexe], stdout=_stdout, stderr=_stderr).wait()
 | 
						|
                if output != 0:
 | 
						|
                    print >> _stderr, "adb finishes unexpectedly with error code", output
 | 
						|
                    return
 | 
						|
                # chmod
 | 
						|
                output = Popen(self.adb + ["shell", "chmod 777 " + androidexe], stdout=_stdout, stderr=_stderr).wait()
 | 
						|
                if output != 0:
 | 
						|
                    print >> _stderr, "adb finishes unexpectedly with error code", output
 | 
						|
                    return
 | 
						|
                # run
 | 
						|
                if self.options.help:
 | 
						|
                    command = exename + " --help"
 | 
						|
                else:
 | 
						|
                    command = exename + " " + " ".join(args)
 | 
						|
                print >> _stderr, "Run command:", command
 | 
						|
                if self.setUp:
 | 
						|
                    self.setUp()
 | 
						|
                Popen(self.adb + ["shell", "export OPENCV_TEST_DATA_PATH=" + self.options.test_data_path + "&& cd " + andoidcwd + "&& ./" + command], stdout=_stdout, stderr=_stderr).wait()
 | 
						|
                if self.tearDown:
 | 
						|
                    self.tearDown()
 | 
						|
                # try get log
 | 
						|
                if not self.options.help:
 | 
						|
                    #_stderr.write("Pull log...  ")
 | 
						|
                    hostlogpath = os.path.join(workingDir, logfile)
 | 
						|
                    output = Popen(self.adb + ["pull", andoidcwd + logfile, hostlogpath], stdout=_stdout, stderr=PIPE).wait()
 | 
						|
                    if output != 0:
 | 
						|
                        print >> _stderr, "adb finishes unexpectedly with error code", output
 | 
						|
                        return
 | 
						|
                    #rm log
 | 
						|
                    Popen(self.adb + ["shell", "rm " + andoidcwd + logfile], stdout=PIPE, stderr=PIPE).wait()
 | 
						|
 | 
						|
                # clean temporary files
 | 
						|
                Popen(self.adb + ["shell", "rm " + tempdir + "__opencv_temp.*"], stdout=PIPE, stderr=PIPE).wait()
 | 
						|
            except OSError:
 | 
						|
                pass
 | 
						|
            if os.path.isfile(hostlogpath):
 | 
						|
                return hostlogpath
 | 
						|
            return None
 | 
						|
        elif path == "java":
 | 
						|
            cmd = [self.ant_executable, "-DjavaLibraryPath=" + self.tests_dir, "buildAndTest"]
 | 
						|
 | 
						|
            print >> _stderr, "Run command:", " ".join(cmd)
 | 
						|
            try:
 | 
						|
                Popen(cmd, stdout=_stdout, stderr=_stderr, cwd = self.java_test_binary_dir + "/.build").wait()
 | 
						|
            except OSError:
 | 
						|
                pass
 | 
						|
 | 
						|
            return None
 | 
						|
        else:
 | 
						|
            cmd = [exe]
 | 
						|
            if self.options.help:
 | 
						|
                cmd.append("--help")
 | 
						|
            else:
 | 
						|
                cmd.extend(args)
 | 
						|
 | 
						|
            orig_temp_path = os.environ.get('OPENCV_TEMP_PATH')
 | 
						|
            temp_path = tempfile.mkdtemp(prefix="__opencv_temp.", dir=orig_temp_path or None)
 | 
						|
            os.environ['OPENCV_TEMP_PATH'] = temp_path
 | 
						|
 | 
						|
            print >> _stderr, "Run command:", " ".join(cmd)
 | 
						|
            try:
 | 
						|
                Popen(cmd, stdout=_stdout, stderr=_stderr, cwd = workingDir).wait()
 | 
						|
            except OSError:
 | 
						|
                pass
 | 
						|
 | 
						|
            # clean temporary files
 | 
						|
            if orig_temp_path:
 | 
						|
                os.environ['OPENCV_TEMP_PATH'] = orig_temp_path
 | 
						|
            else:
 | 
						|
                del os.environ['OPENCV_TEMP_PATH']
 | 
						|
 | 
						|
            try:
 | 
						|
                shutil.rmtree(temp_path)
 | 
						|
                pass
 | 
						|
            except:
 | 
						|
                pass
 | 
						|
 | 
						|
            logpath = os.path.join(workingDir, logfile)
 | 
						|
            if os.path.isfile(logpath):
 | 
						|
                return logpath
 | 
						|
            return None
 | 
						|
 | 
						|
    def runTests(self, tests, _stdout, _stderr, workingDir, args = []):
 | 
						|
        if not self.isRunnable():
 | 
						|
            print >> _stderr, "Error:", self.error
 | 
						|
        if self.error:
 | 
						|
            return []
 | 
						|
        if self.adb and self.targetos == "android":
 | 
						|
            print "adb command:", " ".join(self.adb)
 | 
						|
        if not tests:
 | 
						|
            tests = self.tests
 | 
						|
        logs = []
 | 
						|
        for test in tests:
 | 
						|
            t = self.getTest(test)
 | 
						|
            if t:
 | 
						|
                logfile = self.runTest(t, workingDir, _stdout, _stderr, args)
 | 
						|
                if logfile:
 | 
						|
                    logs.append(os.path.relpath(logfile, "."))
 | 
						|
            else:
 | 
						|
                print >> _stderr, "Error: Test \"%s\" is not found in %s" % (test, self.tests_dir)
 | 
						|
        return logs
 | 
						|
 | 
						|
def getRunArgs(args):
 | 
						|
    run_args = []
 | 
						|
    for path in args:
 | 
						|
        path = os.path.abspath(path)
 | 
						|
        while (True):
 | 
						|
            if os.path.isdir(path) and os.path.isfile(os.path.join(path, "CMakeCache.txt")):
 | 
						|
                run_args.append(path)
 | 
						|
                break
 | 
						|
            npath = os.path.dirname(path)
 | 
						|
            if npath == path:
 | 
						|
                break
 | 
						|
            path = npath
 | 
						|
    return run_args
 | 
						|
 | 
						|
if __name__ == "__main__":
 | 
						|
    test_args = [a for a in sys.argv if a.startswith("--perf_") or a.startswith("--gtest_")]
 | 
						|
    argv =      [a for a in sys.argv if not(a.startswith("--perf_") or a.startswith("--gtest_"))]
 | 
						|
 | 
						|
    parser = OptionParser()
 | 
						|
    parser.add_option("-t", "--tests", dest="tests", help="comma-separated list of modules to test", metavar="SUITS", default="")
 | 
						|
    parser.add_option("-w", "--cwd", dest="cwd", help="working directory for tests", metavar="PATH", default=".")
 | 
						|
    parser.add_option("-a", "--accuracy", dest="accuracy", help="look for accuracy tests instead of performance tests", action="store_true", default=False)
 | 
						|
    parser.add_option("-l", "--longname", dest="useLongNames", action="store_true", help="generate log files with long names", default=False)
 | 
						|
    parser.add_option("", "--android_test_data_path", dest="test_data_path", help="OPENCV_TEST_DATA_PATH for Android run", metavar="PATH", default="/sdcard/opencv_testdata/")
 | 
						|
    parser.add_option("", "--configuration", dest="configuration", help="force Debug or Release configuration", metavar="CFG", default="")
 | 
						|
    parser.add_option("", "--serial", dest="adb_serial", help="Android: directs command to the USB device or emulator with the given serial number", metavar="serial number", default="")
 | 
						|
    parser.add_option("", "--package", dest="junit_package", help="Android: run jUnit tests for specified package", metavar="package", default="")
 | 
						|
    parser.add_option("", "--help-tests", dest="help", help="Show help for test executable", action="store_true", default=False)
 | 
						|
    parser.add_option("", "--check", dest="check", help="Shortcut for '--perf_min_samples=1 --perf_force_samples=1'", action="store_true", default=False)
 | 
						|
    parser.add_option("", "--list", dest="list", help="List available tests", action="store_true", default=False)
 | 
						|
 | 
						|
    (options, args) = parser.parse_args(argv)
 | 
						|
 | 
						|
    if options.accuracy:
 | 
						|
        options.mode = "test"
 | 
						|
    else:
 | 
						|
        options.mode = "perf"
 | 
						|
 | 
						|
    run_args = getRunArgs(args[1:] or ['.'])
 | 
						|
 | 
						|
    if len(run_args) == 0:
 | 
						|
        print >> sys.stderr, "Usage:", os.path.basename(sys.argv[0]), "[options] [build_path]"
 | 
						|
        exit(1)
 | 
						|
 | 
						|
    tests = [s.strip() for s in options.tests.split(",") if s]
 | 
						|
 | 
						|
    if len(tests) != 1 or len(run_args) != 1:
 | 
						|
        # remove --gtest_output from params
 | 
						|
        test_args = [a for a in test_args if not a.startswith("--gtest_output=")]
 | 
						|
 | 
						|
    if options.check:
 | 
						|
        if not [a for a in test_args if a.startswith("--perf_min_samples=")] :
 | 
						|
            test_args.extend(["--perf_min_samples=1"])
 | 
						|
        if not [a for a in test_args if a.startswith("--perf_force_samples=")] :
 | 
						|
            test_args.extend(["--perf_force_samples=1"])
 | 
						|
        if not [a for a in test_args if a.startswith("--perf_verify_sanity")] :
 | 
						|
            test_args.extend(["--perf_verify_sanity"])
 | 
						|
 | 
						|
    logs = []
 | 
						|
    test_list = []
 | 
						|
    for path in run_args:
 | 
						|
        suite = TestSuite(options, path)
 | 
						|
        #print vars(suite),"\n"
 | 
						|
        if options.list:
 | 
						|
            test_list.extend(suite.tests)
 | 
						|
        else:
 | 
						|
            logs.extend(suite.runTests(tests, sys.stdout, sys.stderr, options.cwd, test_args))
 | 
						|
 | 
						|
    if options.list:
 | 
						|
        print os.linesep.join(test_list) or "No tests found"
 | 
						|
 | 
						|
    if logs:
 | 
						|
        print >> sys.stderr, "Collected:  ", " ".join(logs)
 |