Commit a20a2739 authored by Viet Dinh's avatar Viet Dinh

Merge remote-tracking branch 'Itseez/2.4' into fix_bug_5599

parents e9b31a70 33dc4105
...@@ -794,8 +794,42 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray ...@@ -794,8 +794,42 @@ double cv::fisheye::calibrate(InputArrayOfArrays objectPoints, InputArrayOfArray
if (K.needed()) cv::Mat(_K).convertTo(K, K.empty() ? CV_64FC1 : K.type()); if (K.needed()) cv::Mat(_K).convertTo(K, K.empty() ? CV_64FC1 : K.type());
if (D.needed()) cv::Mat(finalParam.k).convertTo(D, D.empty() ? CV_64FC1 : D.type()); if (D.needed()) cv::Mat(finalParam.k).convertTo(D, D.empty() ? CV_64FC1 : D.type());
if (rvecs.needed()) cv::Mat(omc).convertTo(rvecs, rvecs.empty() ? CV_64FC3 : rvecs.type());
if (tvecs.needed()) cv::Mat(Tc).convertTo(tvecs, tvecs.empty() ? CV_64FC3 : tvecs.type()); if (rvecs.needed())
{
if( rvecs.kind() == _InputArray::STD_VECTOR_MAT )
{
rvecs.create((int)objectPoints.total(), 1, CV_64FC3);
for( int i = 0; i < (int)objectPoints.total(); i++ )
{
rvecs.create(3, 1, CV_64F, i, true);
Mat rv = rvecs.getMat(i);
*rv.ptr<Vec3d>(0) = omc[i];
}
}
else
{
cv::Mat(omc).convertTo(rvecs, rvecs.fixedType() ? rvecs.type() : CV_64FC3);
}
}
if (tvecs.needed())
{
if( tvecs.kind() == _InputArray::STD_VECTOR_MAT )
{
tvecs.create((int)objectPoints.total(), 1, CV_64FC3);
for( int i = 0; i < (int)objectPoints.total(); i++ )
{
tvecs.create(3, 1, CV_64F, i, true);
Mat tv = tvecs.getMat(i);
*tv.ptr<Vec3d>(0) = Tc[i];
}
}
else
{
cv::Mat(Tc).convertTo(tvecs, tvecs.fixedType() ? tvecs.type() : CV_64FC3);
}
}
return rms; return rms;
} }
......
#!/usr/bin/env python #!/usr/bin/env python
import sys, os, platform, xml, re, tempfile, glob, datetime, getpass, shutil import os, sys
from optparse import OptionParser import argparse
from subprocess import Popen, PIPE import logging
from run_utils import Err, CMakeCache, log, execute
hostos = os.name # 'nt', 'posix' from run_suite import TestSuite
hostmachine = platform.machine() # 'x86', 'AMD64', 'x86_64' from run_android import AndroidTestSuite
errorCode = 0 epilog = '''
NOTE:
SIMD_DETECTION_PROGRAM=""" Additional options starting with "--gtest_" and "--perf_" will be passed directly to the test executables.
#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__ || __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'])]
if not os.path.isfile(self.aapt[0]):
# it's moved in SDK r22
sdk_dir = os.path.dirname( os.path.dirname(self.adb[0]) )
aapt_fn = ("aapt", "aapt.exe")[hostos == 'nt']
for r, ds, fs in os.walk( os.path.join(sdk_dir, 'build-tools') ):
if aapt_fn in fs:
self.aapt = [ os.path.join(r, aapt_fn) ]
break
else:
self.error = "Can't find '%s' tool!" % aapt_fn
# 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")
lname = "%s_%s_%s_%s%s%s.xml" % (app, self.targetos, self.targetarch, hw, rev, tstamp)
lname = str.replace(lname, '(', '_')
lname = str.replace(lname, ')', '_')
return lname
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 = []):
global errorCode
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()
env = self.options.android_env.copy()
env['OPENCV_TEST_DATA_PATH'] = self.options.test_data_path
if self.options.android_propagate_opencv_env:
for k, v in os.environ.items():
if k.startswith('OPENCV') and not k in env:
env[k] = v
print >> _stderr, "Android environment variables: \n", '\n'.join([' %s=%s' % (k, v) for k, v in env.items()])
commandPrefix = ''.join(['export %s=%s && ' % (k, v) for k, v in env.items()])
Popen(self.adb + ["shell", commandPrefix + "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,
"-Dopencv.build.type="
+ (self.options.configuration if self.options.configuration else self.build_type),
"buildAndTest"]
print >> _stderr, "Run command:", " ".join(cmd)
try:
errorCode = Popen(cmd, stdout=_stdout, stderr=_stderr, cwd = self.java_test_binary_dir + "/.build").wait()
except:
print "Unexpected error:", sys.exc_info()[0]
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:
errorCode = Popen(cmd, stdout=_stdout, stderr=_stderr, cwd = workingDir).wait()
except:
print "Unexpected error:", sys.exc_info()[0]
# 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__": 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("", "--android_env", dest="android_env_array", help="Environment variable for Android run (NAME=VALUE)", action='append')
parser.add_option("", "--android_propagate_opencv_env", dest="android_propagate_opencv_env", help="Propagate OPENCV* environment variables for Android run", action="store_true", default=False)
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) # log.basicConfig(format='[%(levelname)s] %(message)s', level = log.DEBUG)
# log.basicConfig(format='[%(levelname)s] %(message)s', level = log.INFO)
parser = argparse.ArgumentParser(
description='OpenCV test runner script',
epilog=epilog,
formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("build_path", nargs = "*", default = ["."], help="Path to build directory (should contain CMakeCache.txt, default is current) or to directory with tests (all platform checks will be disabled in this case)")
parser.add_argument("-t", "--tests", metavar="MODULES", default="", help="Comma-separated list of modules to test (example: -t core,imgproc,java)")
parser.add_argument("-b", "--blacklist", metavar="MODULES", default="", help="Comma-separated list of modules to exclude from test (example: -b java)")
parser.add_argument("-a", "--accuracy", action="store_true", default=False, help="Look for accuracy tests instead of performance tests")
parser.add_argument("--check", action="store_true", default=False, help="Shortcut for '--perf_min_samples=1 --perf_force_samples=1'")
parser.add_argument("-w", "--cwd", metavar="PATH", default=".", help="Working directory for tests (default is current)")
parser.add_argument("-l", "--longname", action="store_true", default=False, help="Generate log files with long names")
parser.add_argument("--list", action="store_true", default=False, help="List available tests (executables)")
parser.add_argument("--list_short", action="store_true", default=False, help="List available tests (aliases)")
parser.add_argument("--list_short_main", action="store_true", default=False, help="List available tests (main repository, aliases)")
parser.add_argument("--configuration", metavar="CFG", default="", help="Visual Studio: force Debug or Release configuration")
parser.add_argument("-n", "--dry_run", action="store_true", help="Do not run the tests")
parser.add_argument("-v", "--verbose", action="store_true", default=False, help="Print more debug information")
# Valgrind
parser.add_argument("--valgrind", action="store_true", default=False, help="Run C++ tests in valgrind")
parser.add_argument("--valgrind_supp", metavar="FILE", help="Path to valgrind suppression file (example: --valgrind_supp opencv/platforms/scripts/valgrind.supp)")
parser.add_argument("--valgrind_opt", metavar="OPT", action="append", default=[], help="Add command line option to valgrind (example: --valgrind_opt=--leak-check=full)")
# Android
parser.add_argument("--android", action="store_true", default=False, help="Android: force all tests to run on device")
parser.add_argument("--android_sdk", metavar="PATH", help="Android: path to SDK to use adb and aapt tools")
parser.add_argument("--android_test_data_path", metavar="PATH", default="/sdcard/opencv_testdata/", help="Android: path to testdata on device")
parser.add_argument("--android_env", action='append', help="Android: add environment variable (NAME=VALUE)")
parser.add_argument("--android_propagate_opencv_env", action="store_true", default=False, help="Android: propagate OPENCV* environment variables")
parser.add_argument("--serial", metavar="serial number", default="", help="Android: directs command to the USB device or emulator with the given serial number")
parser.add_argument("--package", metavar="package", default="", help="Android: run jUnit tests for specified package")
args, other_args = parser.parse_known_args()
log.setLevel(logging.DEBUG if args.verbose else logging.INFO)
test_args = [a for a in other_args if a.startswith("--perf_") or a.startswith("--gtest_")]
bad_args = [a for a in other_args if a not in test_args]
if len(bad_args) > 0:
log.error("Error: Bad arguments: %s", bad_args)
exit(1)
if options.accuracy: args.mode = "test" if args.accuracy else "perf"
options.mode = "test"
else:
options.mode = "perf"
run_args = getRunArgs(args[1:] or ['.']) android_env = []
if args.android_env:
android_env.extend([entry.split("=", 1) for entry in args.android_env])
if args.android_propagate_opencv_env:
android_env.extend([entry for entry in os.environ.items() if entry[0].startswith('OPENCV')])
android_env = dict(android_env)
if args.android_test_data_path:
android_env['OPENCV_TEST_DATA_PATH'] = args.android_test_data_path
if len(run_args) == 0: if args.valgrind:
print >> sys.stderr, "Usage:", os.path.basename(sys.argv[0]), "[options] [build_path]" try:
ver = execute(["valgrind", "--version"], silent=True)
log.debug("Using %s", ver)
except OSError as e:
log.error("Failed to run valgrind: %s", e)
exit(1) exit(1)
options.android_env = {} if len(args.build_path) != 1:
if options.android_env_array:
for entry in options.android_env_array:
k, v = entry.split("=", 1)
options.android_env[k] = v
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=")] test_args = [a for a in test_args if not a.startswith("--gtest_output=")]
if options.check: if args.check:
if not [a for a in test_args if a.startswith("--perf_min_samples=")] : if not [a for a in test_args if a.startswith("--perf_min_samples=")] :
test_args.extend(["--perf_min_samples=1"]) test_args.extend(["--perf_min_samples=1"])
if not [a for a in test_args if a.startswith("--perf_force_samples=")] : if not [a for a in test_args if a.startswith("--perf_force_samples=")] :
...@@ -902,22 +89,46 @@ if __name__ == "__main__": ...@@ -902,22 +89,46 @@ if __name__ == "__main__":
if not [a for a in test_args if a.startswith("--perf_verify_sanity")] : if not [a for a in test_args if a.startswith("--perf_verify_sanity")] :
test_args.extend(["--perf_verify_sanity"]) test_args.extend(["--perf_verify_sanity"])
ret = 0
logs = [] logs = []
test_list = [] for path in args.build_path:
for path in run_args: try:
suite = TestSuite(options, path) if not os.path.isdir(path):
#print vars(suite),"\n" raise Err("Not a directory (should contain CMakeCache.txt ot test executables)")
if options.list: cache = CMakeCache()
test_list.extend(suite.tests) fname = os.path.join(path, "CMakeCache.txt")
else:
logs.extend(suite.runTests(tests, sys.stdout, sys.stderr, options.cwd, test_args)) if os.path.isfile(fname):
log.debug("Reading cmake cache file: %s", fname)
if options.list: cache.read(path, fname, args.configuration)
print os.linesep.join(test_list) or "No tests found" else:
log.debug("Assuming folder contains tests: %s", path)
cache.setDummy(path)
if args.android or cache.getOS() == "android":
log.debug("Creating Android test runner")
suite = AndroidTestSuite(args, cache, android_env)
else:
log.debug("Creating native test runner")
suite = TestSuite(args, cache)
if args.list or args.list_short or args.list_short_main:
suite.listTests(args.list_short or args.list_short_main, args.list_short_main)
else:
log.debug("Running tests in '%s', working dir: '%s'", path, args.cwd)
def parseTests(s):
return [o.strip() for o in s.split(",") if o]
l, r = suite.runTests(parseTests(args.tests), parseTests(args.blacklist), args.cwd, test_args)
logs.extend(l)
if r != 0:
ret = r
except Err as e:
log.error("ERROR: test path '%s' ==> %s", path, e.msg)
ret = -1
if logs: if logs:
print >> sys.stderr, "Collected: ", " ".join(logs) log.warning("Collected: %s", ", ".join(logs))
if errorCode != 0: if ret != 0:
print "Error code: ", errorCode, (" (0x%x)" % (errorCode & 0xffffffff)) log.error("ERROR: some tests have failed")
exit(errorCode) exit(ret)
#!/usr/bin/env python
import sys
from run_utils import *
from run_suite import TestSuite
def exe(program):
return program + ".exe" if hostos == 'nt' else program
class ApkInfo:
def __init__(self):
self.pkg_name = None
self.pkg_target = None
self.pkg_runner = None
def forcePackage(self, package):
if package:
if package.startswith("."):
self.pkg_target += package
else:
self.pkg_target = package
#==============================================================================
class Tool:
def __init__(self):
self.cmd = []
def run(self, args = [], silent = False):
cmd = self.cmd[:]
cmd.extend(args)
return execute(self.cmd + args, silent)
#==============================================================================
class Adb(Tool):
def __init__(self, sdk_dir):
Tool.__init__(self)
exe_path = os.path.join(sdk_dir, exe("platform-tools/adb"))
if not os.path.isfile(exe_path) or not os.access(exe_path, os.X_OK):
exe_path = None
# fix adb tool location
if not exe_path:
exe_path = getRunningProcessExePathByName("adb")
if not exe_path:
exe_path = "adb"
self.cmd = [exe_path]
self.cpuinfo = ""
def init(self, serial):
# remember current device serial. Needed if another device is connected while this script runs
if not serial:
serial = self.detectSerial()
if serial:
self.cmd.extend(["-s", serial])
# read device cpuinfo
self.cpuinfo = self.run(["shell", "cat /proc/cpuinfo"], silent = True)
if not self.cpuinfo:
raise Err("Can not get cpuinfo from Android device")
def detectSerial(self):
adb_res = self.run(["devices"], silent = True)
# 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:
raise Err("Can not find Android device")
elif len(connected_devices) != 1:
raise Err("Too many (%s) devices are connected. Please specify single device using --serial option:\n\n%s", len(connected_devices), adb_res)
else:
return connected_devices[0].split("\t")[0]
def getOSIdentifier(self):
return "Android" + self.run(["shell", "getprop ro.build.version.release"], silent = True).strip()
def getHardware(self):
hw = re.search(r"^Hardware[ \t]*:[ \t]*(.*?)$", self.cpuinfo, re.MULTILINE)
if hw:
return hw.group(1).strip()
def checkArmHardware(self, expected_abi):
if expected_abi and "armeabi-v7a" in expected_abi:
if "ARMv7" not in self.cpuinfo:
raise Err("Android device does not support ARMv7 commands, but tests are built for armeabi-v7a")
if "NEON" in expected_abi and "neon" not in self.cpuinfo:
raise Err("Android device has no NEON, but tests are built for %s", expected_abi)
#==============================================================================
class Aapt(Tool):
def __init__(self, sdk_dir):
Tool.__init__(self)
aapt_fn = exe("aapt")
aapt = None
for r, ds, fs in os.walk( os.path.join(sdk_dir, 'build-tools') ):
if aapt_fn in fs:
aapt = os.path.join(r, aapt_fn)
break
if not aapt:
raise Err("Can not find aapt tool: %s", aapt_fn)
self.cmd = [aapt]
def dump(self, exe):
res = ApkInfo()
output = self.run(["dump", "xmltree", exe, "AndroidManifest.xml"], silent = True)
if not output:
raise Err("Can not dump manifest from %s", exe)
tags = re.split(r"[ ]+E: ", output)
# get package name
manifest_tag = [t for t in tags if t.startswith("manifest ")]
if not manifest_tag:
raise Err("Can not read package name from: %s", exe)
res.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:
raise Err("Can not find instrumentation detials in: %s", exe)
res.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")
res.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 res.pkg_name or not res.pkg_runner or not res.pkg_target:
raise Err("Can not find instrumentation detials in: %s", exe)
return res
#===================================================================================================
class AndroidTestSuite(TestSuite):
def __init__(self, options, cache, android_env = {}):
TestSuite.__init__(self, options, cache)
sdk_dir = options.android_sdk or os.environ.get("ANDROID_SDK", False) or os.path.dirname(os.path.dirname(self.cache.android_executable))
log.debug("Detecting Android tools in directory: %s", sdk_dir)
self.adb = Adb(sdk_dir)
self.aapt = Aapt(sdk_dir)
self.env = android_env
def isTest(self, fullpath):
if os.path.isfile(fullpath):
if fullpath.endswith(".apk") or os.access(fullpath, os.X_OK):
return True
return False
def getOS(self):
return self.adb.getOSIdentifier()
def getHardware(self):
return [self.adb.getHardware()]
def checkPrerequisites(self):
self.adb.init(self.options.serial)
self.adb.checkArmHardware(self.cache.android_abi)
def runTest(self, path, logfile, workingDir, args = []):
args = args[:]
exe = os.path.abspath(path)
if exe.endswith(".apk"):
info = self.aapt.dump(exe)
if not info:
raise Err("Can not read info from test package: %s", exe)
info.forcePackage(self.options.package)
self.adb.run(["uninstall", info.pkg_name])
output = self.adb.run(["install", exe], silent = True)
if not (output and "Success" in output):
raise Err("Can not install package: %s", exe)
params = ["-e package %s" % info.pkg_target]
ret = self.adb.run(["shell", "am instrument -w %s %s/%s" % (" ".join(params), info.pkg_name, info.pkg_runner)])
return None, ret
else:
device_dir = getpass.getuser().replace(" ","") + "_" + self.options.mode +"/"
if isColorEnabled(args):
args.append("--gtest_color=yes")
tempdir = "/data/local/tmp/"
android_dir = tempdir + device_dir
exename = os.path.basename(exe)
android_exe = android_dir + exename
self.adb.run(["push", exe, android_exe])
self.adb.run(["shell", "chmod 777 " + android_exe])
env_pieces = ["export %s=%s" % (a,b) for a,b in self.env.items()]
pieces = ["cd %s" % android_dir, "./%s %s" % (exename, " ".join(args))]
log.warning("Run: %s" % " && ".join(pieces))
ret = self.adb.run(["shell", " && ".join(env_pieces + pieces)])
# try get log
hostlogpath = os.path.join(workingDir, logfile)
self.adb.run(["pull", android_dir + logfile, hostlogpath])
# cleanup
self.adb.run(["shell", "rm " + android_dir + logfile])
self.adb.run(["shell", "rm " + tempdir + "__opencv_temp.*"], silent = True)
if os.path.isfile(hostlogpath):
return hostlogpath, ret
return None, ret
#===================================================================================================
if __name__ == "__main__":
log.error("This is utility file, please execute run.py script")
#!/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):
# 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)
noext = re.sub(r"\.(exe|apk)$", '', fname)
res.append(noext) # filename w/o extension (opencv_test_core)
nopref = None
if fname.startswith(self.nameprefix):
nopref = fname[len(self.nameprefix):]
res.append(nopref) # filename w/o prefix (core)
if noext.startswith(self.nameprefix):
res.append(noext[len(self.nameprefix):])
if self.options.configuration == "Debug":
res.append(re.sub(r"d$", '', noext)) # MSVC debug config, remove 'd' suffix
if nopref:
res.append(re.sub(r"d$", '', nopref)) # MSVC debug config, remove 'd' suffix
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":
cfg = self.cache.build_type
if self.options.configuration:
cfg = self.options.configuration
cmd = [self.cache.ant_executable, "-Dopencv.build.type=%s" % cfg, "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")
#!/usr/bin/env python
import sys, os, platform, re, tempfile, glob, getpass, logging
from subprocess import check_call, check_output, CalledProcessError, STDOUT
hostos = os.name # 'nt', 'posix'
hostmachine = platform.machine() # 'x86', 'AMD64', 'x86_64'
def initLogger():
l = logging.getLogger("run.py")
l.setLevel(logging.DEBUG)
ch = logging.StreamHandler(sys.stderr)
ch.setFormatter(logging.Formatter("%(message)s"))
l.addHandler(ch)
return l
log = initLogger()
#===================================================================================================
class Err(Exception):
def __init__(self, msg, *args):
self.msg = msg % args
def execute(cmd, silent = False, cwd = "."):
try:
log.debug("Run: %s", cmd)
if silent:
return check_output(cmd, stderr = STDOUT, cwd = cwd).decode("latin-1")
else:
return check_call(cmd, cwd = cwd)
except CalledProcessError as e:
if silent:
log.debug("Process returned: %d", e.returncode)
return e.output.decode("latin-1")
else:
log.error("Process returned: %d", e.returncode)
return e.returncode
def isColorEnabled(args):
usercolor = [a for a in args if a.startswith("--gtest_color=")]
return len(usercolor) == 0 and sys.stdout.isatty() and hostos != "nt"
#===================================================================================================
def getPlatformVersion():
mv = platform.mac_ver()
if mv[0]:
return "Darwin" + mv[0]
else:
wv = platform.win32_ver()
if wv[0]:
return "Windows" + wv[0]
else:
lv = platform.linux_distribution()
if lv[0]:
return lv[0] + lv[1]
return None
def readGitVersion(git, path):
if not path or not git or not os.path.isdir(os.path.join(path, ".git")):
return None
try:
output = execute([git, "-C", path, "rev-parse", "--short", "HEAD"], silent = True)
return output.strip()
except OSError:
log.warning("Git version read failed")
return None
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
"""
def testSIMD(compiler, cxx_flags, compiler_arg = None):
if not compiler:
return None
compiler_output = ""
try:
_, tmpfile = tempfile.mkstemp(suffix=".cpp", text = True)
with open(tmpfile, "w+") as fd:
fd.write(SIMD_DETECTION_PROGRAM)
options = [compiler]
if compiler_arg:
options.append(compiler_arg)
prev_option = None
for opt in " ".join(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)
compiler_output = execute(options, silent = True)
os.remove(tmpfile)
m = re.search("#error\W+(\w+)", compiler_output)
if m:
return m.group(1)
except OSError:
pass
log.debug("SIMD detection failed")
return None
#==============================================================================
parse_patterns = (
{'name': "cmake_home", 'default': None, 'pattern': re.compile(r"^CMAKE_HOME_DIRECTORY:INTERNAL=(.+)$")},
{'name': "opencv_home", 'default': None, 'pattern': re.compile(r"^OpenCV_SOURCE_DIR:STATIC=(.+)$")},
{'name': "opencv_build", 'default': None, 'pattern': re.compile(r"^OpenCV_BINARY_DIR:STATIC=(.+)$")},
{'name': "tests_dir", 'default': None, 'pattern': re.compile(r"^EXECUTABLE_OUTPUT_PATH:PATH=(.+)$")},
{'name': "build_type", 'default': "Release", 'pattern': re.compile(r"^CMAKE_BUILD_TYPE:STRING=(.*)$")},
{'name': "git_executable", 'default': None, 'pattern': re.compile(r"^GIT_EXECUTABLE:FILEPATH=(.*)$")},
{'name': "cxx_flags", 'default': "", 'pattern': re.compile(r"^CMAKE_CXX_FLAGS:STRING=(.*)$")},
{'name': "cxx_flags_debug", 'default': "", 'pattern': re.compile(r"^CMAKE_CXX_FLAGS_DEBUG:STRING=(.*)$")},
{'name': "cxx_flags_release", 'default': "", 'pattern': re.compile(r"^CMAKE_CXX_FLAGS_RELEASE:STRING=(.*)$")},
{'name': "opencv_cxx_flags", 'default': "", 'pattern': re.compile(r"^OPENCV_EXTRA_C_FLAGS:INTERNAL=(.*)$")},
{'name': "cxx_flags_android", 'default': None, 'pattern': re.compile(r"^ANDROID_CXX_FLAGS:INTERNAL=(.*)$")},
{'name': "android_abi", 'default': None, 'pattern': re.compile(r"^ANDROID_ABI:STRING=(.*)$")},
{'name': "android_executable", 'default': None, 'pattern': re.compile(r"^ANDROID_EXECUTABLE:FILEPATH=(.*android.*)$")},
{'name': "ant_executable", 'default': None, 'pattern': re.compile(r"^ANT_EXECUTABLE:FILEPATH=(.*ant.*)$")},
{'name': "java_test_binary_dir", 'default': None, 'pattern': re.compile(r"^opencv_test_java_BINARY_DIR:STATIC=(.*)$")},
{'name': "is_x64", 'default': "OFF", 'pattern': re.compile(r"^CUDA_64_BIT_DEVICE_CODE:BOOL=(ON)$")},#ugly(
{'name': "cmake_generator", 'default': None, 'pattern': re.compile(r"^CMAKE_GENERATOR:INTERNAL=(.+)$")},
{'name': "cxx_compiler", 'default': None, 'pattern': re.compile(r"^CMAKE_CXX_COMPILER:\w*PATH=(.+)$")},
{'name': "cxx_compiler_arg1", 'default': None, 'pattern': re.compile(r"^CMAKE_CXX_COMPILER_ARG1:[A-Z]+=(.+)$")},
{'name': "with_cuda", 'default': "OFF", 'pattern': re.compile(r"^WITH_CUDA:BOOL=(ON)$")},
{'name': "cuda_library", 'default': None, 'pattern': re.compile(r"^CUDA_CUDA_LIBRARY:FILEPATH=(.+)$")},
{'name': "cuda_version", 'default': None, 'pattern': re.compile(r"^CUDA_VERSION:STRING=(.+)$")},
{'name': "core_dependencies", 'default': None, 'pattern': re.compile(r"^opencv_core_LIB_DEPENDS:STATIC=(.+)$")},
)
class CMakeCache:
def __init__(self):
self.setDefaultAttrs()
self.cmake_home_vcver = None
self.opencv_home_vcver = None
self.featuresSIMD = None
self.main_modules = []
def setDummy(self, path):
self.tests_dir = os.path.normpath(path)
def read(self, path, fname, cfg):
rx = re.compile(r'^opencv_(\w+)_SOURCE_DIR:STATIC=(.*)$')
module_paths = {} # name -> path
with open(fname, "rt") as cachefile:
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)
# log.debug("cache value: %s = %s", p["name"], value)
match = rx.search(ll)
if match:
module_paths[match.group(1)] = match.group(2)
if not self.tests_dir:
self.tests_dir = path
else:
rel = os.path.relpath(self.tests_dir, self.opencv_build)
self.tests_dir = os.path.join(path, rel)
self.tests_dir = os.path.normpath(self.tests_dir)
# fix VS test binary path (add Debug or Release)
if "Visual Studio" in self.cmake_generator:
if cfg:
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)
self.cmake_home_vcver = readGitVersion(self.git_executable, self.cmake_home)
if self.opencv_home == self.cmake_home:
self.opencv_home_vcver = self.cmake_home_vcver
else:
self.opencv_home_vcver = readGitVersion(self.git_executable, self.opencv_home)
for module,path in module_paths.items():
rel = os.path.relpath(path, self.opencv_home)
if not ".." in rel:
self.main_modules.append(module)
self.flags = [
self.cxx_flags_android,
self.cxx_flags,
self.cxx_flags_release,
self.opencv_cxx_flags,
self.cxx_flags_release]
self.flags = [f for f in self.flags if f]
self.featuresSIMD = testSIMD(self.cxx_compiler, self.flags, self.cxx_compiler_arg1)
def setDefaultAttrs(self):
for p in parse_patterns:
setattr(self, p["name"], p["default"])
def gatherTests(self, mask, isGood = None):
if self.tests_dir and os.path.isdir(self.tests_dir):
d = os.path.abspath(self.tests_dir)
files = glob.glob(os.path.join(d, mask))
if not self.getOS() == "android" and self.withJava():
files.append("java")
return [f for f in files if isGood(f)]
return []
def isMainModule(self, name):
return name in self.main_modules
def withCuda(self):
return self.cuda_version and self.with_cuda == "ON" and self.cuda_library and not self.cuda_library.endswith("-NOTFOUND")
def withJava(self):
return self.ant_executable and self.java_test_binary_dir
def getGitVersion(self):
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 = ""
return rev
def getTestFullName(self, shortname):
return os.path.join(self.tests_dir, shortname)
def getSIMDFeatures(self):
return self.featuresSIMD
def getOS(self):
if self.android_executable:
return "android"
else:
return hostos
def getArch(self):
arch = "unknown"
if self.getOS() == "android":
if "armeabi-v7a" in self.android_abi:
arch = "armv7a"
elif "armeabi-v6" in self.android_abi:
arch = "armv6"
elif "armeabi" in self.android_abi:
arch = "armv5te"
elif "x86" in self.android_abi:
arch = "x86"
elif "mips" in self.android_abi:
arch = "mips"
else:
arch = "ARM"
elif self.is_x64 and hostmachine in ["AMD64", "x86_64"]:
arch = "x64"
elif hostmachine in ["x86", "AMD64", "x86_64"]:
arch = "x86"
return arch
def getDependencies(self):
if self.core_dependencies:
candidates = ["tbb", "ippicv", "ipp", "pthreads"]
return [a for a in self.core_dependencies.split(";") if a and a in candidates]
return []
#==============================================================================
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 TempEnvDir:
def __init__(self, envname, prefix):
self.envname = envname
self.prefix = prefix
self.saved_name = None
self.new_name = None
def init(self):
self.saved_name = os.environ.get(self.envname)
self.new_name = tempfile.mkdtemp(prefix=self.prefix, dir=self.saved_name or None)
os.environ[self.envname] = self.new_name
def clean(self):
if self.saved_name:
os.environ[self.envname] = self.saved_name
else:
del os.environ[self.envname]
try:
shutil.rmtree(self.new_name)
except:
pass
#===================================================================================================
if __name__ == "__main__":
log.error("This is utility file, please execute run.py script")
{
IPP static init
Memcheck:Cond
fun:ippicvGetCpuFeatures
fun:ippicvStaticInit
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment