diff options
Diffstat (limited to 'scripts/TestUtil.py')
-rwxr-xr-x | scripts/TestUtil.py | 710 |
1 files changed, 414 insertions, 296 deletions
diff --git a/scripts/TestUtil.py b/scripts/TestUtil.py index e766ca80622..45e0230f6b8 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,10 @@ x86 = False # Binary distribution is 32-bit global armv7l armv7l = False # Binary distribution is armv7l cpp11 = False # Binary distribution is c++11 +static = False # Static build +global buildMode +buildMode = None + extraArgs = [] clientTraceFilters = [] serverTraceFilters = [] @@ -49,6 +53,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 +158,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(): @@ -199,13 +212,24 @@ def getIceSoVersion(): majorVersion = int(intVersion / 10000) minorVersion = int(intVersion / 100) - 100 * majorVersion patchVersion = intVersion % 100 - if patchVersion > 50: - if patchVersion >= 52: - return '%db%d' % (majorVersion * 10 + minorVersion, patchVersion - 50) - else: - return '%db' % (majorVersion * 10 + minorVersion) - else: + if patchVersion <= 50: return '%d' % (majorVersion * 10 + minorVersion) + elif patchVersion <= 70: + return '%da%d' % (majorVersion * 10 + minorVersion, patchVersion - 51) + else: + return '%db%d' % (majorVersion * 10 + minorVersion, patchVersion - 71) + +def getIceJsonVersion(): + r = re.search(r"([0-9]+)\.([0-9]+)(\.[0-9]+|[ab][0-9]+)", iceVersion) + major = int(r.group(1)) + minor = int(r.group(2)) + v = ("%d.%d" % (major, minor)).strip() + if r.group(3).startswith("a"): + return v + ".0-" + r.group(3).replace("a", "alpha").strip() + elif r.group(3).startswith("b"): + return v + ".0-" + r.group(3).replace("b", "beta").strip() + else: + return ("%s%s" % (v, r.group(3))).strip() def getJdkVersion(): process = subprocess.Popen("java -version", stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True) @@ -370,17 +394,18 @@ else: iceVersion = None try: if isWin32(): - config = open(os.path.join(toplevel, "config", "Make.common.rules.mak"), "r") + config = open(os.path.join(toplevel, "config", "Ice.props"), "r") + iceVersion = re.search("<IceVersion>[\t\s]*([0-9]+\.[0-9]+(\.[0-9]+|[ab][0-9]*))</IceVersion>", config.read()).group(1) else: - config = open(os.path.join(toplevel, "config", "Make.common.rules"), "r") - iceVersion = re.search("VERSION[\t\s]*= ([0-9]+\.[0-9]+(\.[0-9]+|b[0-9]*))", config.read()).group(1) + config = open(os.path.join(toplevel, "config", "Make.rules"), "r") + iceVersion = re.search("version[\t\s]*= ([0-9]+\.[0-9]+(\.[0-9]+|[ab][0-9]*))", config.read()).group(1) config.close() except: print("error: couldn't figure Ice version") 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": @@ -396,7 +421,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", @@ -425,37 +450,40 @@ 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. + --static Binary distribution is static. + --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) @@ -463,9 +491,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", "static", "controller=", "configName="]) except getopt.GetoptError: usage() @@ -483,6 +511,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: @@ -519,7 +549,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: @@ -528,9 +558,15 @@ 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 + elif o == "--static": + global static + static = True elif o == "--x86": global x86 x86 = True @@ -538,9 +574,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", "--static", "--env", \ "--service-dir", "--appverifier", "--compact", "--winrt", \ - "--server", "--mx", "--client-home"): + "--server", "--mx", "--client-home", "--controller", "--configName"): arg += " " + o if len(a) > 0: arg += " " + a @@ -548,7 +584,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 ]) @@ -706,8 +742,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 @@ -789,14 +826,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" @@ -806,17 +845,10 @@ def getIceBox(): return iceBox def getIceBoxAdmin(): - # - # Get and return the path of the IceBoxAdmin executable - # - lang = getDefaultMapping() - if lang == "java": - iceBoxAdmin = "IceBox.Admin" + if getDefaultMapping() == "java": + return "IceBox.Admin" else: return getIceExe("iceboxadmin") - iceBoxAdmin = "iceboxadmin" - - return iceBoxAdmin def getIceGridAdmin(): return getIceExe("icegridadmin") @@ -825,16 +857,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") @@ -920,11 +946,14 @@ if isWin32(): sslConfigTree["python"] = sslConfigTree["cpp"] sslConfigTree["ruby"] = sslConfigTree["cpp"] -sslConfigTree["php"] = sslConfigTree["cpp"] +sslConfigTree["php"] = sslConfigTree["cpp"].copy() sslConfigTree["objective-c"] = sslConfigTree["cpp"] +if isUbuntu(): + sslConfigTree["php"]["client"] += " --IceSSL.InitOpenSSL=0" + 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)): @@ -956,8 +985,10 @@ class DriverConfig: x64 = False x86 = False cpp11 = False + static = False serviceDir = None mx = False + controller = None extraArgs = [] def __init__(self, type = None): @@ -973,9 +1004,11 @@ class DriverConfig: global x64 global x86 global cpp11 + global static global serviceDir global compact global mx + global controller global extraArgs self.lang = getDefaultMapping() self.protocol = protocol @@ -991,9 +1024,11 @@ class DriverConfig: self.x64 = x64 self.x86 = x86 self.cpp11 = cpp11 + self.static = static self.serviceDir = serviceDir self.compact = compact self.mx = mx + self.controller = controller self.extraArgs = extraArgs def argsToDict(argumentString, results): @@ -1015,7 +1050,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 @@ -1034,8 +1069,7 @@ def getCommandLineProperties(exe, config): #components.append("--Ice.Trace.Protocol=1") # - # 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 = {} @@ -1048,6 +1082,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: @@ -1056,7 +1093,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") @@ -1076,6 +1121,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") @@ -1084,8 +1135,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: @@ -1118,7 +1170,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": @@ -1141,7 +1193,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 + " ") @@ -1174,7 +1225,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() @@ -1197,9 +1248,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", "objective-c", "js", "ruby", "php"]: + return getTestExecutable("server", baseDir) + if lang in ["csharp"]: return "server" if lang == "python": return "Server.py" @@ -1213,11 +1266,13 @@ def getDefaultServerFile(): def getDefaultClientFile(lang = None): if lang is None: lang = getDefaultMapping() + if lang in ["cpp", "objective-c"]: + return getTestExecutable("client") if lang == "ruby": return "Client.rb" if lang == "php": return "Client.php" - if lang in ["cpp", "csharp", "objective-c"]: + if lang in ["csharp"]: return "client" if lang == "python": return "Client.py" @@ -1232,32 +1287,19 @@ def getDefaultClientFile(lang = None): def getDefaultCollocatedFile(): lang = getDefaultMapping() + if lang in ["cpp", "objective-c"]: + 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"]: 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): @@ -1436,24 +1478,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 = os.path.basename(server) + clientDesc = os.path.basename(client) + if lang != "java": server = os.path.join(serverdir, server) @@ -1471,6 +1517,7 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", elif len(cross) == 0: cross.append(lang) + global controller global clientHome for clientLang in cross: clientCfg = DriverConfig("client") @@ -1481,6 +1528,7 @@ def clientServerTest(additionalServerOptions = "", additionalClientOptions = "", clientCfg.lang = clientLang client = getDefaultClientFile(clientLang) + clientDesc = client if clientHome: clientdir = getMirrorDir(getClientCrossTestDir(testdir), clientLang) else: @@ -1512,15 +1560,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: @@ -1528,7 +1577,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") @@ -1536,13 +1587,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() @@ -1575,21 +1627,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) @@ -1744,6 +1800,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: @@ -1793,30 +1853,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: @@ -1826,43 +1862,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() @@ -1872,11 +1871,20 @@ def getTestEnv(lang, testdir): # iceJARs = ["ice", "glacier2", "freeze", "icebox", "icestorm", "icegrid", "icepatch2", "icediscovery", "icelocatordiscovery"] - jarSuffix = "-" + iceVersion + ".jar" + jarSuffix = "-" + getIceJsonVersion() + ".jar" # 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) @@ -1893,59 +1901,15 @@ 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", "js"]: - 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" + 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) - # - # 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 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 @@ -1970,7 +1934,7 @@ def getTestEnv(lang, testdir): elif isAIX(): addLdPath(getCppLibDir(lang), env) elif lang in ["python", "ruby", "php", "js", "objective-c"]: - # C++ binaries use rpath $ORIGIN or similar to find the Ice libraries + # C++ binaries use rpath $ORIGIN or similar to find the Ice libraries addLdPath(getCppLibDir(lang), env) if lang == "java": @@ -1997,8 +1961,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) # @@ -2083,38 +2048,41 @@ 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. + --static Binary distribution is static. + --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", "static", "controller=", "configName="]) except getopt.GetoptError: usage() @@ -2123,10 +2091,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) @@ -2149,6 +2122,9 @@ def processCmdLine(): elif o == "--c++11": global cpp11 cpp11 = True + elif o == "--static": + global static + static = True elif o == "--compress": global compress compress = True @@ -2186,12 +2162,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": @@ -2210,6 +2189,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) @@ -2217,6 +2202,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 + " ") @@ -2333,6 +2322,10 @@ def runTests(start, expanded, num = 0, script = False): print("%s*** test not supported with C++11%s" % (prefix, suffix)) continue + if static and "nostatic" in config: + print("%s*** test not supported with static%s" % (prefix, suffix)) + continue + if x86 and iceHome and "nomultiarch" in config: print("%s*** test not supported with x86 in multiarch%s" % (prefix, suffix)) continue @@ -2368,6 +2361,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 @@ -2419,6 +2416,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") @@ -2438,3 +2528,31 @@ 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(): + buildDir = "msbuild" + 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" + else: + buildDir = "build" + if isDarwin(): + platform = "osx" + elif isUbuntu() or isDebian(): + platform = "x86_64-linux-gnu" if x64 else "i386-linux-gnu" + elif isAIX(): + platform = "ppc64" if x64 else "ppc" + else: + platform = "x64" if x64 else "x86" + configuration = ("cpp11-" if cpp11 else "") + ("static" if static else "shared") + + if os.path.isdir(os.path.join(baseDir, buildDir, name)): + return os.path.join(baseDir, buildDir, name, platform, configuration) + else: + return os.path.join(baseDir, buildDir, platform, configuration) + +def getTestExecutable(name, baseDir = os.getcwd()): + return os.path.join(getTestDirectory(name, baseDir), name) |