diff options
Diffstat (limited to 'scripts/TestUtil.py')
-rwxr-xr-x | scripts/TestUtil.py | 636 |
1 files changed, 362 insertions, 274 deletions
diff --git a/scripts/TestUtil.py b/scripts/TestUtil.py index 3ba922de2b7..6c56ac930f2 100755 --- a/scripts/TestUtil.py +++ b/scripts/TestUtil.py @@ -10,7 +10,7 @@ import sys, os, re, getopt, time, string, threading, atexit, platform, traceback, subprocess # Global flags and their default values. -protocol = "" # If unset, default to TCP. Valid values are "tcp", "ssl", "ws" or "wss". +protocol = "" # If unset, default to TCP. Valid values are "tcp", "ssl", "ws", "wss" or "bt". compress = False # Set to True to enable bzip2 compression. serialize = False # Set to True to have tests use connection serialization host = None # Will default to loopback. @@ -26,6 +26,9 @@ x86 = False # Binary distribution is 32-bit global armv7l armv7l = False # Binary distribution is armv7l cpp11 = False # Binary distribution is c++11 +global buildMode +buildMode = None + extraArgs = [] clientTraceFilters = [] serverTraceFilters = [] @@ -49,6 +52,21 @@ winrt = False global serverOnly serverOnly = False mx = False +controller = None +configName = None + +queuedTests = [] + +global additionalBinDirectories +additionalBinDirectories = [] + +def addAdditionalBinDirectories(directories): + global additionalBinDirectories + additionalBinDirectories += directories + +def resetAdditionalBinDirectories(): + global additionalBinDirectories + additionalBinDirectories = [] # # Linux distribution @@ -139,31 +157,25 @@ def getCppCompiler(): elif isMINGW(): compiler = "MINGW" else: - config = open(os.path.join(toplevel, "cpp", "config", "Make.rules.mak"), "r") - compiler = re.search("CPP_COMPILER[\t\s]*= ([A-Z0-9]*)", config.read()).group(1) - if compiler != "VC100" and compiler != "VC110" and compiler != "VC120" and compiler != "VC140": - compiler = "" - - if compiler == "": - p = subprocess.Popen("cl", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) - if not p or not p.stdout: - print("Cannot detect C++ compiler") - compiler = VC120 + p = subprocess.Popen("cl", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) + if not p or not p.stdout: + print("Cannot detect C++ compiler") + compiler = VC120 + else: + l = p.stdout.readline().decode("utf-8").strip() + if l.find("Version 16.") != -1: + compiler = "VC100" + elif l.find("Version 17.") != -1: + compiler = "VC110" + elif l.find("Version 18.") != -1: + compiler = "VC120" + elif l.find("Version 19.") != -1: + compiler = "VC140" else: - l = p.stdout.readline().decode("utf-8").strip() - if l.find("Version 16.") != -1: - compiler = "VC100" - elif l.find("Version 17.") != -1: - compiler = "VC110" - elif l.find("Version 18.") != -1: - compiler = "VC120" - elif l.find("Version 19.") != -1: - compiler = "VC140" - else: - # - # Cannot detect C++ compiler use default - # - compiler = "VC120" + # + # Cannot detect C++ compiler use default + # + compiler = "VC140" return compiler def isMINGW(): @@ -377,7 +389,7 @@ except: sys.exit(1) # -# Figure out Ice installation directoty +# Figure out Ice installation directory # iceHome = None # Binary distribution to use (or None to use binaries from source distribution) if os.environ.get("USE_BIN_DIST", "no") == "yes": @@ -393,7 +405,7 @@ if os.environ.get("USE_BIN_DIST", "no") == "yes": if path and len(path) > 0 and os.path.exists(path[0]): iceHome = path[0] -# List of supported cross languages test. +# List of supported cross-language tests. crossTests = [ #"Ice/adapterDeactivation", #"Ice/background", #"Ice/binding", @@ -422,37 +434,39 @@ crossTests = [ #"Ice/adapterDeactivation", def run(tests, root = False): def usage(): print("usage: " + sys.argv[0] + """ - --all Run all sensible permutations of the tests. - --all-cross Run all sensible permutations of cross language tests. - --start=index Start running the tests at the given index. - --loop Run the tests in a loop. - --filter=<regex> Run all the tests that match the given regex. - --rfilter=<regex> Run all the tests that do not match the given regex. - --debug Display debugging information on each test. - --protocol=tcp|ssl|ws|wss Run with the given protocol. - --compress Run the tests with protocol compression. - --host=host Set --Ice.Default.Host=<host>. - --valgrind Run the test with valgrind. - --appverifier Run the test with appverifier under Windows. - --serialize Run with connection serialization. - --continue Keep running when a test fails - --ipv6 Use IPv6 addresses. - --socks Use SOCKS proxy running on localhost. - --no-ipv6 Don't use IPv6 addresses. - --ice-home=<path> Use the binary distribution from the given path. - --x86 Binary distribution is 32-bit. - --x64 Binary distribution is 64-bit. - --c++11 Binary distribution is c++11. - --cross=lang Run cross language test. - --client-home=<dir> Run cross test clients from the given Ice source distribution. - --script Generate a script to run the tests. - --env Print important environment variables. - --service-dir=<dir> Where to locate services for builds without service support. - --compact Ice for .NET uses the Compact Framework. - --winrt Run server with configuration suited for WinRT client. - --server Run only the server. - --mx Enable IceMX when running the tests. - --arg=<property> Append the given argument. + --all Run all sensible permutations of the tests. + --all-cross Run all sensible permutations of cross language tests. + --start=index Start running the tests at the given index. + --loop Run the tests in a loop. + --filter=<regex> Run all the tests that match the given regex. + --rfilter=<regex> Run all the tests that do not match the given regex. + --debug Display debugging information on each test. + --protocol=<prot> Run with the given protocol (tcp|ssl|ws|wss|bt). + --compress Run the tests with protocol compression. + --host=host Set --Ice.Default.Host=<host>. + --valgrind Run the test with valgrind. + --appverifier Run the test with appverifier under Windows. + --serialize Run with connection serialization. + --continue Keep running when a test fails. + --ipv6 Use IPv6 addresses. + --socks Use SOCKS proxy running on localhost. + --no-ipv6 Don't use IPv6 addresses. + --ice-home=<path> Use the binary distribution from the given path. + --mode=debug|release Run the tests with debug or release mode builds (win32 only)." + --x86 Binary distribution is 32-bit. + --x64 Binary distribution is 64-bit. + --c++11 Binary distribution is c++11. + --cross=lang Run cross language test. + --client-home=<dir> Run cross test clients from the given Ice source distribution. + --script Generate a script to run the tests. + --env Print important environment variables. + --service-dir=<dir> Where to locate services for builds without service support. + --compact Ice for .NET uses the Compact Framework. + --winrt Run server with configuration suited for WinRT client. + --server Run only the server. + --mx Enable IceMX when running the tests. + --controller=<host> Use the test controller on the specified host. + --arg=<property> Append the given argument. """) sys.exit(2) @@ -460,9 +474,9 @@ def run(tests, root = False): opts, args = getopt.getopt(sys.argv[1:], "lr:R:", ["start=", "start-after=", "filter=", "rfilter=", "all", "all-cross", "loop", "debug", "protocol=", "compress", "valgrind", "host=", "serialize", "continue", - "ipv6", "no-ipv6", "socks", "ice-home=", "cross=", "client-home=", "x64", "x86", + "ipv6", "no-ipv6", "socks", "ice-home=", "mode=", "cross=", "client-home=", "x64", "x86", "script", "env", "arg=", "service-dir=", "appverifier", "compact", - "winrt", "server", "mx", "c++11"]) + "winrt", "server", "mx", "c++11", "controller=", "configName="]) except getopt.GetoptError: usage() @@ -480,6 +494,8 @@ def run(tests, root = False): winrt = "--winrt" in opts serverOnly = "--server" in opts mx = "--mx" in opts + controller = "--controller" in opts + configName = "--configName" in opts filters = [] for o, a in opts: @@ -516,7 +532,7 @@ def run(tests, root = False): arg += a arg += '"' elif o == "--protocol": - if a not in ( "ws", "wss", "ssl", "tcp"): + if a not in ("bt", "ws", "wss", "ssl", "tcp"): usage() if not root and getDefaultMapping() == "csharp" and (a == "ssl" or a == "wss"): if mono: @@ -525,6 +541,9 @@ def run(tests, root = False): if compact: print("SSL is not supported with the Compact Framework") sys.exit(1) + if a == "bt" and not isLinux(): + print("Bluetooth is only supported on Linux") + sys.exit(1) elif o == "--c++11": global cpp11 cpp11 = True @@ -535,9 +554,9 @@ def run(tests, root = False): global x64 x64 = True if o in ( "--cross", "--protocol", "--host", "--debug", "--compress", "--valgrind", "--serialize", "--ipv6", \ - "--socks", "--ice-home", "--x86", "--x64", "--c++11", "--env", \ + "--socks", "--ice-home", "--mode", "--x86", "--x64", "--c++11", "--env", \ "--service-dir", "--appverifier", "--compact", "--winrt", \ - "--server", "--mx", "--client-home"): + "--server", "--mx", "--client-home", "--controller", "--configName"): arg += " " + o if len(a) > 0: arg += " " + a @@ -545,7 +564,7 @@ def run(tests, root = False): if not root: tests = [ (os.path.join(getDefaultMapping(), "test", x), y) for x, y in tests ] - # Expand all the tests and argument combinations. + # Expand all the test and argument combinations. expanded = [] if all: expanded.append([(test, arg, config) for test,config in tests if "once" in config ]) @@ -703,8 +722,9 @@ def phpSetup(clientConfig = False, iceOptions = None, iceProfile = None): if isWin32(): ext = "php_ice.dll" if not iceHome: - extDir = os.path.abspath(os.path.join(getIceDir("php"), "lib")) - incDir = extDir + extDir = os.path.abspath(os.path.join(getIceDir("php"), "lib", "x64" if x64 else "Win32", + "Debug" if buildMode == "debug" else "Release")) + incDir = os.path.abspath(os.path.join(getIceDir("php"), "lib")) else: extDir = os.path.join(iceHome, "php") incDir = extDir @@ -786,14 +806,16 @@ def getIceBox(): if lang == "cpp": iceBox = "icebox" if isWin32(): - if isDebug(): - iceBox += "d" + if cpp11: + iceBox += "++11" iceBox += ".exe" elif isLinux(): if not x64 and not armv7l: iceBox += "32" if cpp11: iceBox += "++11" + elif isDarwin and cpp11: + iceBox += "++11" iceBox = os.path.join(getCppBinDir(lang), iceBox) elif lang == "java": iceBox = "IceBox.Server" @@ -822,16 +844,10 @@ def getIceStormAdmin(): return getIceExe("icestormadmin") def getIceGridNode(): - exe = "icegridnode" - if isWin32() and isDebug(): - exe += "d" - return getIceExe(exe) + return getIceExe("icegridnode") def getIceGridRegistry(): - exe = "icegridregistry" - if isWin32() and isDebug(): - exe += "d" - return getIceExe(exe) + return getIceExe("icegridregistry") def getGlacier2Router(): return getIceExe("glacier2router") @@ -927,7 +943,7 @@ sslConfigTree["php"] = sslConfigTree["cpp"] sslConfigTree["objective-c"] = sslConfigTree["cpp"] def getDefaultMapping(): - """Try and guess the language mapping out of the current path""" + """Try to guess the language mapping from the current path""" here = os.getcwd().split(os.sep) here.reverse() for i in range(0, len(here)): @@ -961,6 +977,7 @@ class DriverConfig: cpp11 = False serviceDir = None mx = False + controller = None extraArgs = [] def __init__(self, type = None): @@ -979,6 +996,7 @@ class DriverConfig: global serviceDir global compact global mx + global controller global extraArgs self.lang = getDefaultMapping() self.protocol = protocol @@ -997,6 +1015,7 @@ class DriverConfig: self.serviceDir = serviceDir self.compact = compact self.mx = mx + self.controller = controller self.extraArgs = extraArgs def argsToDict(argumentString, results): @@ -1018,7 +1037,7 @@ def argsToDict(argumentString, results): results[current] = None return results -def getCommandLineProperties(exe, config): +def getCommandLineProperties(exe, config, cfgName): # # Command lines are built up from the items in the components @@ -1036,8 +1055,7 @@ def getCommandLineProperties(exe, config): #components.append("--Ice.Trace.Network=3") # - # Now we add additional components dependent on the desired - # configuration. + # Now we add additional components depending on the desired configuration. # if config.protocol == "ssl" or config.protocol == "wss": sslenv = {} @@ -1050,6 +1068,9 @@ def getCommandLineProperties(exe, config): components.append(sslConfigTree[config.lang]["plugin"] % sslenv) components.append(sslConfigTree[config.lang][config.type] % sslenv) + if config.protocol == "bt": + components.append("--Ice.Plugin.IceBT=IceBT:createIceBT") + components.append("--Ice.Default.Protocol=" + config.protocol) if config.compress: @@ -1058,7 +1079,15 @@ def getCommandLineProperties(exe, config): if config.serialize: components.append("--Ice.ThreadPool.Server.Serialize=1") - if config.type == "server" or config.type == "colloc" and config.lang == "python": + # + # TODO + # config.lang == "cpp" required with C++11 mapping, we should be able to ged rid + # of this once AsyncResult is optimized to not required a thread pool thread with + # collocated calls and C++11 mapping. We must also check if it still required for + # python. + # + if (config.type == "server" or config.type == "colloc" and + (config.lang == "python" or config.lang == "cpp")): components.append("--Ice.ThreadPool.Server.Size=1") components.append("--Ice.ThreadPool.Server.SizeMax=3") components.append("--Ice.ThreadPool.Server.SizeWarn=0") @@ -1078,6 +1107,12 @@ def getCommandLineProperties(exe, config): components.append("--IceMX.Metrics.Parent.GroupBy=parent") components.append("--IceMX.Metrics.All.GroupBy=none") + if config.controller: + components.append("--ControllerHost=" + config.controller) + + if cfgName: + components.append("--ConfigName=" + cfgName) + if config.socksProxy: components.append("--Ice.SOCKSProxyHost=127.0.0.1") @@ -1086,8 +1121,9 @@ def getCommandLineProperties(exe, config): if config.host == None: components.append("--Ice.Default.Host=0:0:0:0:0:0:0:1") else: - components.append("--Ice.IPv4=1 --Ice.IPv6=0") - if config.host == None: + if config.protocol != "bt": + components.append("--Ice.IPv4=1 --Ice.IPv6=0") + if config.host == None and config.protocol != "bt": components.append("--Ice.Default.Host=127.0.0.1") if config.host != None and len(config.host) != 0: @@ -1120,7 +1156,7 @@ def getCommandLineProperties(exe, config): output.close() return properties -def getCommandLine(exe, config, options = "", interpreterOptions = ""): +def getCommandLine(exe, config, options = "", interpreterOptions = "", cfgName = None): output = getStringIO() if config.mono and config.lang == "csharp": @@ -1143,7 +1179,6 @@ def getCommandLine(exe, config, options = "", interpreterOptions = ""): output.write("-d64 ") if not config.ipv6: output.write("-Djava.net.preferIPv4Stack=true ") - output.write(getJavaLibraryPath()) if interpreterOptions: output.write(" " + interpreterOptions) output.write(" " + exe + " ") @@ -1176,7 +1211,7 @@ def getCommandLine(exe, config, options = "", interpreterOptions = ""): if exe.find("IceUtil\\") != -1 or exe.find("IceUtil/") != -1: output.write(' ' + options) else: - output.write(getCommandLineProperties(exe, config) + ' ' + options) + output.write(getCommandLineProperties(exe, config, cfgName) + ' ' + options) commandline = output.getvalue() output.close() @@ -1199,9 +1234,11 @@ def directoryToPackage(): raise RuntimeError("cannot find language dir") return ".".join(after) -def getDefaultServerFile(): +def getDefaultServerFile(baseDir = os.getcwd()): lang = getDefaultMapping() - if lang in ["js", "ruby", "php", "cpp", "csharp", "objective-c"]: + if lang in ["cpp", "js", "ruby", "php"]: + return getTestExecutable("server", baseDir) + if lang in ["csharp", "objective-c"]: return "server" if lang == "python": return "Server.py" @@ -1215,6 +1252,8 @@ def getDefaultServerFile(): def getDefaultClientFile(lang = None): if lang is None: lang = getDefaultMapping() + if lang == "cpp": + return getTestExecutable("client") if lang == "ruby": return "Client.rb" if lang == "php": @@ -1234,32 +1273,19 @@ def getDefaultClientFile(lang = None): def getDefaultCollocatedFile(): lang = getDefaultMapping() + if lang == "cpp": + return getTestExecutable("collocated") if lang == "ruby": return "Collocated.rb" if lang == "php": return "Collocated.php" - if lang in ["cpp", "csharp", "objective-c"]: + if lang in ["csharp", "objective-c"]: return "collocated" if lang == "python": return "Collocated.py" if lang == "java": return directoryToPackage() + ".Collocated" -def isDebug(): - # - # Read the build.txt file from the test directory to figure out - # how the IceBox service was built ("debug" vs. "release") and - # decide which icebox executable to use. - # - if os.path.isfile(os.path.join(os.getcwd(), "build.txt")): - return open(os.path.join(os.getcwd(), "build.txt"), "r").read().strip() == "debug" - # - # Try to guess, if icebox release executable exists in the C++ bin dir - # we assume is a release build or bin dist, tests that depends on debug - # or release (C++) need to create the build.txt file. - # - return not os.path.isfile(os.path.join(getCppBinDir("cpp"), "icebox%s" % (".exe" if isWin32() else ""))) - import Expect def _spawn(cmd, env=None, cwd=None, startReader=True, lang=None): @@ -1438,24 +1464,28 @@ def getClientCrossTestDir(base): return os.path.join(clientHome, lang, *after) -def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", +def clientServerTest(cfgName = None, additionalServerOptions = "", additionalClientOptions = "", server = None, client = None, serverenv = None, clientenv = None, interpreterOptions = ""): - if server is None: - server = getDefaultServerFile() - if client is None: - client = getDefaultClientFile() - serverDesc = server - clientDesc = client - lang = getDefaultMapping() testdir = os.getcwd() - # Setup the server. if lang in ["ruby", "php", "js"]: serverdir = getMirrorDir(testdir, "cpp") else: serverdir = testdir + + if server is None: + server = getDefaultServerFile(serverdir) + elif lang in ["ruby", "php", "js"]: + server = getTestExecutable(server, serverdir) + + if client is None: + client = getDefaultClientFile() + + serverDesc = server + clientDesc = client + if lang != "java": server = os.path.join(serverdir, server) @@ -1473,6 +1503,7 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", elif len(cross) == 0: cross.append(lang) + global controller global clientHome for clientLang in cross: clientCfg = DriverConfig("client") @@ -1514,15 +1545,16 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", if appverifier: setAppVerifierSettings([clientExe, serverExe]) - sys.stdout.write("starting " + serverDesc + "... ") - sys.stdout.flush() - serverCfg = DriverConfig("server") - if lang in ["ruby", "php", "js"]: - serverCfg.lang = "cpp" - server = getCommandLine(server, serverCfg, additionalServerOptions, interpreterOptions) - serverProc = spawnServer(server, env = serverenv, lang=serverCfg.lang, mx=serverCfg.mx) - print("ok") - sys.stdout.flush() + if not controller: + sys.stdout.write("starting " + serverDesc + "... ") + sys.stdout.flush() + serverCfg = DriverConfig("server") + if lang in ["ruby", "php", "js"]: + serverCfg.lang = "cpp" + server = getCommandLine(server, serverCfg, additionalServerOptions, interpreterOptions) + serverProc = spawnServer(server, env = serverenv, lang=serverCfg.lang, mx=serverCfg.mx) + print("ok") + sys.stdout.flush() if not serverOnly: if clientLang == lang: @@ -1530,7 +1562,9 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", else: sys.stdout.write("starting %s %s ... " % (clientLang, clientDesc)) sys.stdout.flush() - client = getCommandLine(client, clientCfg, additionalClientOptions, interpreterOptions) + if not controller: + cfgName = None + client = getCommandLine(client, clientCfg, additionalClientOptions, interpreterOptions, cfgName) clientProc = spawnClient(client, env = clientenv, cwd = clientdir, startReader = False, lang=clientCfg.lang) print("ok") @@ -1538,13 +1572,14 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", clientProc.startReader(watchDog) clientProc.waitTestSuccess() - serverProc.waitTestSuccess() + if not controller: + serverProc.waitTestSuccess() if appverifier: appVerifierAfterTestEnd([clientExe, serverExe]) def collocatedTest(additionalOptions = ""): - if serverOnly: + if controller or serverOnly: print("** skipping collocated test") return lang = getDefaultMapping() @@ -1577,21 +1612,25 @@ def collocatedTest(additionalOptions = ""): def clientEchoTest(additionalServerOptions = "", additionalClientOptions = "", server = None, client = None, serverenv = None, clientenv = None): - if server is None: - server = getDefaultServerFile() - if client is None: - client = getDefaultClientFile() - serverDesc = server - clientDesc = client lang = getDefaultMapping() testdir = os.getcwd() # Setup the server. if lang in ["ruby", "php", "js"]: - serverdir = getMappingDir(testdir, "cpp", ["test", "Ice", "echo"]) + serverdir = getMappingDir(testdir, "cpp", ["test", "Ice", "echo"]) else: - serverdir = testdir + serverdir = testdir + + print("serverdir: " + serverdir) + + if server is None: + server = getDefaultServerFile(serverdir) + if client is None: + client = getDefaultClientFile() + serverDesc = server + clientDesc = client + if lang != "java": server = os.path.join(serverdir, server) @@ -1746,6 +1785,10 @@ def createConfig(path, lines, enc=None): def getCppBinDir(lang = None): binDir = os.path.join(getIceDir("cpp"), "bin") + + if isWin32(): + binDir = os.path.join(binDir, "x64" if x64 else "Win32", "Debug" if buildMode == "debug" else "Release") + if isMINGW() and x64: binDir = os.path.join(binDir, "x64") if iceHome: @@ -1795,30 +1838,6 @@ def getCppLibDir(lang = None): return libDir return None -def getJavaLibraryPath(): - if isWin32(): - if iceHome: - return "-Djava.library.path=\"%s\" " % os.path.join(iceHome, "bin\\x64" if x64 else "bin") - else: - return ("-Djava.library.path=\"%s\" " % os.path.join(getIceDir("cpp"), "third-party-packages", - "berkeley.db.java7", "build", "native", "bin", "x64" if x64 else "Win32")) - elif isDarwin(): - if os.path.exists('/usr/local/opt/ice/libexec/lib'): - return "-Djava.library.path=/usr/local/opt/ice/libexec/lib " - else: - return "-Djava.library.path=/usr/local/opt/berkeley-db53/lib " - elif isRhel() or isSles(): - libpath = ("/usr/lib64" if x64 else "/usr/lib") - if "LD_LIBRARY_PATH" in os.environ: - libpath = os.environ["LD_LIBRARY_PATH"] + ":" + libpath - return "-Djava.library.path=%s " % libpath - elif isUbuntu() or isDebian(): - libpath = ("/usr/lib/x86_64-linux-gnu" if x64 else "/usr/lib/i386-linux-gnu") - if "LD_LIBRARY_PATH" in os.environ: - libpath = os.environ["LD_LIBRARY_PATH"] + ":" + libpath - return "-Djava.library.path=%s " % libpath - return '' - def getServiceDir(): global serviceDir if serviceDir is None: @@ -1828,43 +1847,6 @@ def getServiceDir(): serviceDir = "C:\\Program Files\ZeroC\Ice-" + iceVersion + "\\bin" return serviceDir -def getBuildMode(d): - if os.path.isfile(os.path.join(d, "build.txt")): - return open(os.path.join(d, "build.txt"), "r").read().strip() - import glob - executables = glob.glob(os.path.join(d, "*.exe")) - if not executables: - return "release" - p = subprocess.Popen("dumpbin /DEPENDENTS %s" % executables[0], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) - if not p or not p.stdout: - print("unable to get executable information!") - sys.exit(1) - - debug = "MSVCP%sD.dll" - release = "MSVCP%s.dll" - - if isVC100(): - debug = debug % "100" - release = release % "100" - elif isVC110(): - debug = debug % "110" - release = release % "110" - elif isVC120(): - debug = debug % "120" - release = release % "120" - elif isVC140(): - debug = debug % "140" - release = release % "140" - - l = p.stdout.readline() - while l: - l = l.decode("utf-8").strip() - if l.find(debug) != -1: - return "debug" - elif l.find(release) != -1: - return "release" - l = p.stdout.readline() - def getTestEnv(lang, testdir): global compact env = os.environ.copy() @@ -1879,6 +1861,15 @@ def getTestEnv(lang, testdir): # First sanitize the environment. env["CLASSPATH"] = sanitize(os.getenv("CLASSPATH", "")) + for d in additionalBinDirectories: + addLdPath(d, env) + + # + # Add cpp/test/Common output directory to the env + # + if lang == "cpp": + addLdPath(getTestDirectory("testcommon", os.path.join(toplevel, "cpp", "test", "Common")), env) + # Make sure bzip2 can be found by x86 C# builds on x64 platforms if lang == "csharp" and not x64: addPathToEnv("PATH", os.path.join(getCppBinDir("csharp"), "x64"), env) @@ -1895,59 +1886,16 @@ def getTestEnv(lang, testdir): if os.environ.get("USE_BIN_DIST", "no") != "yes": addPathToEnv("NODE_PATH", os.path.join(getIceDir("js", testdir), "src"), env) - # - # DB CLASSPATH, in Windows db.jar come from Ice home or - # from Third Party Home - # - if lang in ["cpp", "java", "csharp", "python", "ruby"]: - if isWin32(): - if iceHome: - addClasspath(os.path.join(getIceDir("java", testdir), "lib", "db.jar"), env) - else: - mode = getBuildMode(os.path.join(getIceDir("cpp"), "bin")) - configuration = "Debug" if mode == "debug" else "Release" - platform = "x64" if x64 else "Win32" - pkgdir = os.path.join(getIceDir("cpp"), "third-party-packages") - pkgsubdir = os.path.join("build", "native", "bin", platform) - - if isMINGW(): - addPathToEnv("PATH", os.path.join(pkgdir, "bzip2.mingw4.7.2", pkgsubdir), env) - else: - platformtoolset = "" - if isVC100(): - platformtoolset = "v100" - elif isVC110(): - platformtoolset = "v110" - elif isVC120(): - platformtoolset = "v120" - elif isVC140(): - platformtoolset = "v140" - # - # For Debug builds we need to add Release binaries to path to be able to use db_xxx tools and - # bzip2 to be able to use protocol compression with .NET - # - if configuration == "Debug": - addPathToEnv("PATH", os.path.join(pkgdir, "berkeley.db.{0}".format(platformtoolset), pkgsubdir, - "Release"), env) - addPathToEnv("PATH", os.path.join(pkgdir, "bzip2.{0}".format(platformtoolset), pkgsubdir, - "Release"), env) - - for package in ["berkeley.db.{0}", "bzip2.{0}", "expat.{0}"]: - addPathToEnv("PATH", os.path.join(pkgdir, package.format(platformtoolset), pkgsubdir, - configuration), env) - - if lang == "java": - addPathToEnv("PATH", os.path.join(pkgdir, "berkeley.db.java7", pkgsubdir), env) - addClasspath(os.path.join(pkgdir, "berkeley.db.java7", "build", "native", "lib", "db.jar"), env) - - elif isDarwin(): - if os.path.exists('/usr/local/opt/ice/libexec/lib'): - addClasspath(os.path.join("/", "usr", "local", "opt", "ice", "libexec", "lib", "db.jar"), env) - else: - addClasspath(os.path.join("/", "usr", "local", "opt", "berkeley-db53", "db.jar"), env) - else: - addClasspath(os.path.join("/", "usr", "share", "java", "db.jar"), env) + if isWin32() and lang in ["cpp", "java", "csharp", "python", "ruby", "php"]: + if not iceHome: + configuration = "Debug" if buildMode == "debug" else "Release" + platform = "x64" if x64 else "Win32" + pkgdir = os.path.join(getIceDir("cpp"), "third-party-packages") + pkgsubdir = os.path.join("build", "native", "bin", platform) + + if isMINGW(): + addPathToEnv("PATH", os.path.join(pkgdir, "bzip2.mingw4.7.2", pkgsubdir), env) # # If Ice is installed on the system, set the CLASSPATH for Java and @@ -1996,8 +1944,9 @@ def getTestEnv(lang, testdir): # if lang == "python": pythonDir = os.path.join(getIceDir("python", testdir), "python") - if isWin32() and x64 and os.path.exists(os.path.join(pythonDir, "x64")): - pythonDir = os.path.join(pythonDir, "x64") + if isWin32(): + addPathToEnv("PYTHONPATH", pythonDir, env) + pythonDir = os.path.join(pythonDir, "Win32" if x86 else "x64", "Debug" if buildMode == "debug" else "Release") addPathToEnv("PYTHONPATH", pythonDir, env) # @@ -2082,38 +2031,40 @@ class WatchDog(threading.Thread): def processCmdLine(): def usage(): print("usage: " + sys.argv[0] + """ - --debug Display debugging information on each test. - --trace=<file> Display tracing. - --protocol=tcp|ssl|ws|wss Run with the given protocol. - --compress Run the tests with protocol compression. - --valgrind Run the tests with valgrind. - --appverifier Run the tests with appverifier. - --host=host Set --Ice.Default.Host=<host>. - --serialize Run with connection serialization. - --ipv6 Use IPv6 addresses. - --socks Use SOCKS proxy running on localhost. - --ice-home=<path> Use the binary distribution from the given path. - --x86 Binary distribution is 32-bit. - --x64 Binary distribution is 64-bit. - --c++11 Binary distribution is c++11. - --env Print important environment variables. - --cross=lang Run cross language test. - --client-home=<dir> Run cross test clients from the given Ice source distribution. - --service-dir=<dir> Where to locate services for builds without service support. - --compact Ice for .NET uses the Compact Framework. - --winrt Run server with configuration suited for WinRT client. - --server Run only the server. - --mx Enable IceMX when running the tests. - --arg=<property> Append the given argument. + --debug Display debugging information on each test. + --trace=<file> Display tracing. + --protocol=<prot> Run with the given protocol (tcp|ssl|ws|wss|bt). + --compress Run the tests with protocol compression. + --valgrind Run the tests with valgrind. + --appverifier Run the tests with appverifier. + --host=host Set --Ice.Default.Host=<host>. + --serialize Run with connection serialization. + --ipv6 Use IPv6 addresses. + --socks Use SOCKS proxy running on localhost. + --ice-home=<path> Use the binary distribution from the given path. + --mode=debug|release Run the tests with debug or release mode builds (win32 only)." + --x86 Binary distribution is 32-bit. + --x64 Binary distribution is 64-bit. + --c++11 Binary distribution is c++11. + --env Print important environment variables. + --cross=lang Run cross language test. + --client-home=<dir> Run cross test clients from the given Ice source distribution. + --service-dir=<dir> Where to locate services for builds without service support. + --compact Ice for .NET uses the Compact Framework. + --winrt Run server with configuration suited for WinRT client. + --server Run only the server. + --mx Enable IceMX when running the tests. + --controller=<host> Use the test controller on the specified host. + --arg=<property> Append the given argument. """) sys.exit(2) try: opts, args = getopt.getopt( sys.argv[1:], "", ["debug", "trace=", "protocol=", "compress", "valgrind", "host=", "serialize", "ipv6", \ - "socks", "ice-home=", "x86", "x64", "cross=", "client-home=", "env", \ + "socks", "ice-home=", "mode=", "x86", "x64", "cross=", "client-home=", "env", \ "service-dir=", "appverifier", "arg=", \ - "compact", "winrt", "server", "mx", "c++11"]) + "compact", "winrt", "server", "mx", "c++11", "controller=", "configName="]) except getopt.GetoptError: usage() @@ -2122,10 +2073,15 @@ def processCmdLine(): global serverOnly global winrt + global buildMode for o, a in opts: if o == "--ice-home": global iceHome iceHome = a + elif o == "--mode": + if a not in ( "debug", "release"): + usage() + buildMode = a elif o == "--cross": global cross cross.append(a) @@ -2185,12 +2141,15 @@ def processCmdLine(): global printenv printenv = True elif o == "--protocol": - if a not in ( "ws", "wss", "ssl", "tcp"): + if a not in ("bt", "ws", "wss", "ssl", "tcp"): usage() # ssl protocol isn't directly supported with mono. if mono and getDefaultMapping() == "csharp" and (a == "ssl" or a == "wss"): print("SSL is not supported with mono") sys.exit(1) + if a == "bt" and not isLinux(): + print("Bluetooth is only supported on Linux") + sys.exit(1) global protocol protocol = a elif o == "--service-dir": @@ -2209,6 +2168,12 @@ def processCmdLine(): elif o == "--mx": global mx mx = True + elif o == "--controller": + global controller + controller = a + elif o == "--configName": + global configName + configName = a if protocol in ["ssl", "wss"] and not serverOnly and getDefaultMapping() == "js": print("SSL is not supported with Node.js") sys.exit(1) @@ -2216,6 +2181,10 @@ def processCmdLine(): if len(args) > 0: usage() + if isWin32() and not buildMode: + print("Error: please define --mode=debug or --mode=release") + sys.exit(1) + if not os.environ.get("TESTCONTROLLER"): if iceHome: sys.stdout.write("*** using Ice installation from " + iceHome + " ") @@ -2367,6 +2336,10 @@ def runTests(start, expanded, num = 0, script = False): print("%s*** test not supported with IceSSL%s" % (prefix, suffix)) continue + if (args.find("bt") != -1) and ("bt" not in config): + print("%s*** test not supported with Bluetooth%s" % (prefix, suffix)) + continue + if (args.find("ws") != -1 or args.find("wss") != -1) and ("nows" in config): print("%s*** test not supported with IceWS%s" % (prefix, suffix)) continue @@ -2418,6 +2391,99 @@ def runTests(start, expanded, num = 0, script = False): global testErrors testErrors.append(message) +class ClientServerTest: + def __init__(self, cfgName, message, additionalServerOptions, additionalClientOptions, + server, client, serverenv, clientenv, interpreterOptions, localOnly): + if cfgName is None: + cfgName = "default" + self.cfgName = cfgName + self.message = message + self.additionalServerOptions = additionalServerOptions + self.additionalClientOptions = additionalClientOptions + self.server = server + self.client = client + self.serverenv = serverenv + self.clientenv = clientenv + self.interpreterOptions = interpreterOptions + self.localOnly = localOnly + + def getConfigName(self): + return self.cfgName + + def getMessage(self): + return self.message + + def isLocalOnly(self): + return self.localOnly + + def getDefaultMessage(self): + return "Running test with regular server." + + def run(self): + clientServerTest(self.cfgName, self.additionalServerOptions, self.additionalClientOptions, self.server, + self.client, self.serverenv, self.clientenv, self.interpreterOptions) + +def queueClientServerTest(configName = None, message = None, additionalServerOptions = "", + additionalClientOptions = "", server = None, client = None, serverenv = None, + clientenv = None, interpreterOptions = "", localOnly = False): + global queuedTests + queuedTests.append(ClientServerTest(configName, message, additionalServerOptions, additionalClientOptions, server, + client, serverenv, clientenv, interpreterOptions, localOnly)) + +class CollocatedTest: + def __init__(self, message = None, additionalOptions = ""): + self.message = message + self.additionalOptions = additionalOptions + + def getMessage(self): + return self.message + + def isLocalOnly(self): + return True + + def getDefaultMessage(self): + return "Running test with collocated server." + + def run(self): + collocatedTest(self.additionalOptions) + +def queueCollocatedTest(message = None, additionalOptions = ""): + global queuedTests + queuedTests.append(CollocatedTest(message, additionalOptions)) + +def runQueuedTests(): + global queuedTests + global serverOnly + global controller + global configName + + if serverOnly: + name = configName + if not name: + name = "default" + + for t in queuedTests: + if isinstance(t, ClientServerTest) and t.getConfigName() == name: + t.run() + return + + print("no queued test found matching configuration name `" + name + "'") + sys.exit(1) + + tests = [] + for t in queuedTests: + if controller and t.isLocalOnly(): + continue + tests.append(t) + + for t in tests: + msg = t.getMessage() + if msg: + print(msg) + elif len(tests) > 1: + print(t.getDefaultMessage()) + t.run() + if "ICE_CONFIG" in os.environ: os.unsetenv("ICE_CONFIG") @@ -2437,3 +2503,25 @@ if os.path.split(frame.f_code.co_filename)[1] == "run.py": if os.path.normpath(d) != os.getcwd(): os.chdir(d) processCmdLine() + +def getTestDirectory(name, baseDir = os.getcwd()): + if isWin32(): + platform = "x64" if x64 else "Win32" + if cpp11: + configuration = "Cpp11-Debug" if buildMode == "debug" else "Cpp11-Release" + else: + configuration = "Debug" if buildMode == "debug" else "Release" + + if isWin32(): + if os.path.isdir(os.path.join(baseDir, "msbuild", name)): + return os.path.join(baseDir, "msbuild", name, platform, configuration) + else: + return os.path.join(baseDir, "msbuild", platform, configuration) + else: + return "." + +def getTestExecutable(name, baseDir = os.getcwd()): + if isWin32(): + return os.path.join(getTestDirectory(name, baseDir), name) + else: + return name |