summaryrefslogtreecommitdiff
path: root/scripts/TestUtil.py
diff options
context:
space:
mode:
authorMatthew Newhook <matthew@zeroc.com>2008-08-04 19:18:45 -0230
committerMatthew Newhook <matthew@zeroc.com>2008-08-04 19:18:45 -0230
commitd9c568300c2aed6ab736026ea116b3f1a72fbe43 (patch)
tree27191ba2b0d1ef43256561da01462b98c7bd696d /scripts/TestUtil.py
parentMerge branch 'R3_3_branch' of ssh://cvs.zeroc.com/home/git/ice into R3_3_branch (diff)
downloadice-d9c568300c2aed6ab736026ea116b3f1a72fbe43.tar.bz2
ice-d9c568300c2aed6ab736026ea116b3f1a72fbe43.tar.xz
ice-d9c568300c2aed6ab736026ea116b3f1a72fbe43.zip
Numerous cleanups to the test suite and expect scripts.
Conflicts: cpp/test/Glacier2/staticFiltering/run.py
Diffstat (limited to 'scripts/TestUtil.py')
-rwxr-xr-xscripts/TestUtil.py1180
1 files changed, 1180 insertions, 0 deletions
diff --git a/scripts/TestUtil.py b/scripts/TestUtil.py
new file mode 100755
index 00000000000..b8b1fda0f0b
--- /dev/null
+++ b/scripts/TestUtil.py
@@ -0,0 +1,1180 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2008 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+import sys, os, re, errno, getopt, time, StringIO, string, copy
+from threading import Thread
+
+# Global flags and their default values.
+protocol = "" # If unset, default to TCP. Valid values are "tcp" or "ssl".
+compress = False # Set to True to enable bzip2 compression.
+serialize = False # Set to True to have tests use connection serialization
+host = "127.0.0.1" # Default to loopback.
+debug = False # Set to True to enable test suite debugging.
+mono = False # Set to True when not on Windows
+keepGoing = False # Set to True to have the tests continue on failure.
+ipv6 = False # Default to use IPv4 only
+iceHome = None # Binary distribution to use (None to use binaries from source distribution)
+x64 = False # Binary distribution is 64-bit
+javaCmd = "java" # Default java loader
+valgrind = False # Set to True to use valgrind for C++ executables.
+tracefile = None
+cross = []
+
+def isCygwin():
+ # The substring on sys.platform is required because some cygwin
+ # versions return variations like "cygwin_nt-4.01".
+ return sys.platform[:6] == "cygwin"
+
+def isWin32():
+ return sys.platform == "win32" or isCygwin()
+
+def isVista():
+ return isWin32() and sys.getwindowsversion()[0] == 6
+
+def isWin9x():
+ if isWin32():
+ return not (os.environ.has_key("OS") and os.environ["OS"] == "Windows_NT")
+ else:
+ return 0
+
+def isSolaris():
+ return sys.platform == "sunos5"
+
+def isSparc():
+ p = os.popen("uname -m")
+ l = p.readline().strip()
+ p.close()
+ if l == "sun4u":
+ return True
+ else:
+ return False
+
+def isHpUx():
+ return sys.platform == "hp-ux11"
+
+def isAIX():
+ return sys.platform in ['aix4', 'aix5']
+
+def isDarwin():
+ return sys.platform == "darwin"
+
+def isLinux():
+ return sys.platform.startswith("linux")
+
+#
+# The PHP interpreter is called "php5" on some platforms (e.g., SLES).
+#
+phpCmd = "php"
+for path in string.split(os.environ["PATH"], os.pathsep):
+ #
+ # Stop if we find "php" in the PATH first.
+ #
+ if os.path.exists(os.path.join(path, "php")):
+ break
+ elif os.path.exists(os.path.join(path, "php5")):
+ phpCmd = "php5"
+ break
+
+#
+# This is set by the choice of init method. If not set, before it is
+# used, it indicates a bug and things should terminate.
+#
+defaultMapping = None
+
+testErrors = []
+
+toplevel = None
+
+path = [ ".", "..", "../..", "../../..", "../../../..", "../../../../.." ]
+head = os.path.dirname(sys.argv[0])
+if len(head) > 0:
+ path = [os.path.join(head, p) for p in path]
+path = [os.path.abspath(p) for p in path if os.path.exists(os.path.join(p, "scripts", "TestUtil.py")) ]
+if len(path) == 0:
+ raise "can't find toplevel directory!"
+toplevel = path[0]
+
+def sanitize(cp):
+ np = ""
+ for p in cp.split(os.pathsep):
+ if p == "classes":
+ continue
+ if len(np) > 0:
+ np = np + os.pathsep
+ np = np + p
+ return np
+
+def configurePaths():
+ if iceHome:
+ print "*** using Ice installation from " + iceHome,
+ if x64:
+ print "(64bit)",
+ print
+
+ # First sanitize the environment.
+ os.environ["CLASSPATH"] = sanitize(os.getenv("CLASSPATH", ""))
+
+ #
+ # If Ice is installed from RPMs, just set the CLASSPATH for Java.
+ #
+ if iceHome == "/usr":
+ javaDir = os.path.join("/", "usr", "share", "java")
+ addClasspath(os.path.join(javaDir, "Ice.jar"))
+ return # That's it, we're done!
+
+ if isWin32():
+ libDir = getCppBinDir()
+ else:
+ libDir = os.path.join(getIceDir("cpp"), "lib")
+ if iceHome and x64:
+ if isHpUx():
+ libDir = os.path.join(libDir, "pa20_64")
+ elif isSolaris():
+ if isSparc():
+ libDir = os.path.join(libDir, "sparcv9")
+ else:
+ libDir = os.path.join(libDir, "amd64")
+ else:
+ libDir = libDir + "64"
+ addLdPath(libDir)
+
+ javaDir = os.path.join(getIceDir("java"), "lib")
+ addClasspath(os.path.join(javaDir, "Ice.jar"))
+ addClasspath(os.path.join(javaDir))
+
+ #
+ # On Windows, C# assemblies are found thanks to the .exe.config files.
+ #
+ if not isWin32():
+ os.environ["MONO_PATH"] = os.path.join(getIceDir("cs"), "bin") + os.pathsep + os.getenv("MONO_PATH", "")
+
+ #
+ # On Windows x64, set PYTHONPATH to python/x64.
+ #
+ pythonDir = os.path.join(getIceDir("py"), "python")
+ if isWin32() and x64:
+ os.environ["PYTHONPATH"] = os.path.join(pythonDir, "x64") + os.pathsep + os.getenv("PYTHONPATH", "")
+ else:
+ os.environ["PYTHONPATH"] = pythonDir + os.pathsep + os.getenv("PYTHONPATH", "")
+
+ rubyDir = os.path.join(getIceDir("rb"), "ruby")
+ os.environ["RUBYLIB"] = rubyDir + os.pathsep + os.getenv("RUBYLIB", "")
+
+def addLdPath(libpath, env = None):
+ if env is None:
+ env = os.environ
+ if isWin32():
+ env["PATH"] = libpath + os.pathsep + env.get("PATH", "")
+ elif isHpUx():
+ env["SHLIB_PATH"] = libpath + os.pathsep + env.get("SHLIB_PATH", "")
+ env["LD_LIBRARY_PATH"] = libpath + os.pathsep + env.get("LD_LIBRARY_PATH", "")
+ elif isDarwin():
+ env["DYLD_LIBRARY_PATH"] = libpath + os.pathsep + env.get("DYLD_LIBRARY_PATH", "")
+ elif isAIX():
+ env["LIBPATH"] = libpath + os.pathsep + env.get("LIBPATH", "")
+ else:
+ env["LD_LIBRARY_PATH"] = libpath + os.pathsep + env.get("LD_LIBRARY_PATH", "")
+ env["LD_LIBRARY_PATH_64"] = libpath + os.pathsep + env.get("LD_LIBRARY_PATH_64", "")
+ return env
+
+def addClasspath(dir, env = None):
+ if env is None:
+ env = os.environ
+ env["CLASSPATH"] = dir + os.pathsep + env.get("CLASSPATH", "")
+ return env
+
+# List of supported cross languages test.
+crossTests = [
+ "Ice/adapterDeactivation",
+ "Ice/background",
+ "Ice/binding",
+ "Ice/checksum",
+ #"Ice/custom",
+ "Ice/exceptions",
+ "Ice/facets",
+ "Ice/hold",
+ "Ice/inheritance",
+ "Ice/location",
+ "Ice/objects",
+ "Ice/operations",
+ "Ice/proxy",
+ "Ice/retry",
+ #"Ice/servantLocator",
+ "Ice/timeout",
+ "Ice/slicing/exceptions",
+ "Ice/slicing/objects",
+ ]
+
+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 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.
+ --serialize Run with connection serialization.
+ --continue Keep running when a test fails
+ --ipv6 Use IPv6 addresses.
+ --ice-home=<path> Use the binary distribution from the given path.
+ --x64 Binary distribution is 64-bit.
+ --cross=lang Run cross language test.
+ --script Generate a script to run the tests.
+ """
+ sys.exit(2)
+
+ try:
+ 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", "ice-home=", "cross=", "x64", "script"])
+ except getopt.GetoptError:
+ usage()
+
+ if args:
+ usage()
+
+ start = 0
+ loop = False
+ all = False
+ allCross = False
+ arg = ""
+ script = False
+
+ filters = []
+ for o, a in opts:
+ if o == "--continue":
+ global keepGoing
+ keepGoing = True
+ elif o in ("-l", "--loop"):
+ loop = True
+ elif o in ("-r", "-R", "--filter", '--rfilter'):
+ testFilter = re.compile(a)
+ if o in ("--rfilter", "-R"):
+ filters.append((testFilter, True))
+ else:
+ filters.append((testFilter, False))
+ elif o == "--cross":
+ global cross
+ if not a in ["cpp", "java", "cs", "py", "rb" ]:
+ print "cross must be one of cpp, java, cs, py or rb"
+ sys.exit(1)
+ cross.append(a)
+ elif o == "--all" :
+ all = True
+ elif o == "--all-cross" :
+ allCross = True
+ elif o in '--start':
+ start = int(a)
+ elif o == "--script":
+ script = True
+ elif o == "--protocol":
+ if a not in ( "ssl", "tcp"):
+ usage()
+ if mono and getDefaultMapping() == "cs" and a == "ssl":
+ print "SSL is not supported with mono"
+ sys.exit(1)
+
+ if o in ( "--cross", "--protocol", "--host", "--debug", "--compress", "--valgrind", "--serialize", "--ipv6", \
+ "--ice-home", "--x64"):
+ arg += " " + o
+ if len(a) > 0:
+ arg += " " + a
+
+ if not root:
+ tests = [ (os.path.join(getDefaultMapping(), "test", x), y) for x, y in tests ]
+
+ # Expand all the tests and argument combinations.
+ expanded = []
+ if all:
+ expanded.append([(test, arg, config) for test,config in tests if "once" in config ])
+
+ a = '--protocol=tcp %s' % arg
+ expanded.append([ (test, a, config) for test,config in tests if "core" in config])
+
+ a = '--protocol=ssl %s' % arg
+ expanded.append([ (test, a, config) for test,config in tests if "core" in config])
+
+ a = '--protocol=tcp --compress %s' % arg
+ expanded.append([ (test, a, config) for test,config in tests if "core" in config])
+
+ a = "--ipv6 --protocol=tcp %s" % arg
+ expanded.append([ (test, a, config) for test,config in tests if "core" in config])
+
+ a = "--ipv6 --protocol=ssl %s" % arg
+ expanded.append([ (test, a, config) for test,config in tests if "core" in config])
+
+ a = "--protocol=tcp %s" % arg
+ expanded.append([ (test, a, config) for test,config in tests if "service" in config])
+
+ a = "--protocol=ssl --ipv6 %s" % arg
+ expanded.append([ (test, a, config) for test,config in tests if "service" in config])
+
+ a = "--protocol=tcp --serialize %s" % arg
+ expanded.append([ (test, a, config) for test,config in tests if "stress" in config])
+ elif not allCross:
+ expanded.append([ (test, arg, config) for test,config in tests])
+
+ if allCross:
+ if len(cross) == 0:
+ cross = ["cpp", "java", "cs" ]
+ if root:
+ allLang = ["cpp", "java", "cs" ]
+ else:
+ allLang = [ getDefaultMapping() ]
+ for lang in allLang:
+ # This is all other languages than the current mapping.
+ crossLang = [ l for l in cross if lang != l ]
+ # This is all eligible cross tests for the current mapping.
+ # Now expand out the tests. We run only tcp for most cross tests.
+ for c in crossLang:
+ a = "--cross=%s --protocol=tcp" % c
+ expanded.append([ ( "%s/test/%s" % (lang, test), a, []) for test in crossTests if not (test == "Ice/background" and (lang == "cs" or c == "cs"))])
+
+ # Add ssl & compress for the operations test.
+ if mono and c == "cs": # Don't add the ssl tests for mono.
+ continue
+ a = "--cross=%s --protocol=ssl --compress" % c
+ expanded.append([("%s/test/Ice/operations" % lang, a, [])])
+
+ # Apply filters after expanding.
+ if len(filters) > 0:
+ for testFilter, removeFilter in filters:
+ nexpanded = []
+ for tests in expanded:
+ if removeFilter:
+ nexpanded.append([ (x, a, y) for x,a,y in tests if not testFilter.search(x) ])
+ else:
+ nexpanded.append([ (x, a, y) for x,a,y in tests if testFilter.search(x) ])
+ expanded = nexpanded
+
+ if loop:
+ num = 1
+ while 1:
+ runTests(start, expanded, num, script = script)
+ num += 1
+ else:
+ runTests(start, expanded, script = script)
+
+ global testErrors
+ if len(testErrors) > 0:
+ print "The following errors occurred:"
+ for x in testErrors:
+ print x
+
+if not isWin32():
+ mono = True
+
+def getIceDir(subdir = None):
+ #
+ # If ICE_HOME is set we're running the test against a binary distribution. Otherwise,
+ # we're running the test against a source distribution.
+ #
+ global iceHome
+ if iceHome:
+ return iceHome
+ elif subdir:
+ return os.path.join(toplevel, subdir)
+ else:
+ return toplevel
+
+def writePhpIni(src, dst):
+ extDir = None
+ ext = None
+
+ #
+ # TODO
+ #
+ # When we no longer support PHP 5.1.x, we can use the following PHP
+ # command-line options:
+ #
+ # -d extension_dir=...
+ # -d extension=[php_ice.dll|IcePHP.so]
+ #
+ if isWin32():
+ ext = "php_ice.dll"
+ extDir = os.path.abspath(os.path.join(getIceDir("php"), "bin"))
+ else:
+ ext = "IcePHP.so"
+ if not iceHome:
+ extDir = os.path.abspath(os.path.join(toplevel, "php", "lib"))
+ else:
+ #
+ # If ICE_HOME points to the installation directory of a source build, the
+ # PHP extension will be located in $ICE_HOME/lib or $ICE_HOME/lib64.
+ # For an RPM installation, PHP is already configured to load the extension.
+ # We could also execute "php -m" and check if the output includes "ice".
+ #
+ if x64:
+ extDir = os.path.join(iceHome, "lib64")
+ else:
+ extDir = os.path.join(iceHome, "lib")
+
+ if not os.path.exists(os.path.join(extDir, ext)):
+ if iceHome == "/usr":
+ extDir = None # Assume PHP is already configured to load the extension.
+ else:
+ print "unable to find IcePHP extension!"
+ sys.exit(1)
+
+ ini = open(src, "r").readlines()
+ for i in range(0, len(ini)):
+ ini[i] = ini[i].replace("ICE_HOME", os.path.join(toplevel))
+ tmpini = open(dst, "w")
+ tmpini.writelines(ini)
+ if extDir:
+ tmpini.write("extension_dir=%s\n" % extDir)
+ tmpini.write("extension=%s\n" % ext)
+ tmpini.close()
+
+def getIceSoVersion():
+
+ config = open(os.path.join(toplevel, "cpp", "include", "IceUtil", "Config.h"), "r")
+ intVersion = int(re.search("ICE_INT_VERSION ([0-9]*)", config.read()).group(1))
+ majorVersion = intVersion / 10000
+ minorVersion = 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:
+ return '%d' % (majorVersion * 10 + minorVersion)
+
+def getIceSSLVersion():
+ javaPipeIn, javaPipeOut = os.popen4("java IceSSL.Util")
+ if not javaPipeIn or not javaPipeOut:
+ print "unable to get IceSSL version!"
+ sys.exit(1)
+ version = javaPipeOut.readline()
+ if not version:
+ print "unable to get IceSSL version!"
+ sys.exit(1)
+ javaPipeIn.close()
+ javaPipeOut.close()
+ return version.strip()
+
+def getJdkVersion():
+ javaPipeIn, javaPipeOut = os.popen4("java -version")
+ if not javaPipeIn or not javaPipeOut:
+ print "unable to get Java version!"
+ sys.exit(1)
+ version = javaPipeOut.readline()
+ if not version:
+ print "unable to get Java version!"
+ sys.exit(1)
+ javaPipeIn.close()
+ javaPipeOut.close()
+ return version
+
+def getIceBox():
+ #
+ # Get and return the path of the IceBox executable
+ #
+ lang = getDefaultMapping()
+ if lang == "cpp":
+ iceBox = ""
+ if isWin32():
+ #
+ # 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.
+ #
+ build = open(os.path.join(os.getcwd(), "build.txt"), "r")
+ type = build.read().strip()
+ if type == "debug":
+ iceBox = os.path.join(getCppBinDir(), "iceboxd.exe")
+ elif type == "release":
+ iceBox = os.path.join(getCppBinDir(), "icebox.exe")
+ else:
+ iceBox = os.path.join(getCppBinDir(), "icebox")
+
+ if not os.path.exists(iceBox):
+ print "couldn't find icebox executable to run the test"
+ sys.exit(0)
+ elif lang == "java":
+ iceBox = "IceBox.Server"
+ elif lang == "cs":
+ iceBox = os.path.join(getIceDir("cs"), "bin", "iceboxnet")
+
+ if iceBox == "":
+ print "couldn't find icebox executable to run the test"
+ sys.exit(0)
+
+ return iceBox
+
+class InvalidSelectorString(Exception):
+ def __init__(self, value):
+ self.value = value
+ def __str__(self):
+ return repr(self.value)
+
+sslConfigTree = {
+ "cpp" : {
+ "plugin" : " --Ice.Plugin.IceSSL=IceSSL:createIceSSL --Ice.Default.Protocol=ssl " +
+ "--IceSSL.DefaultDir=%(certsdir)s --IceSSL.CertAuthFile=cacert.pem",
+ "client" : " --IceSSL.CertFile=c_rsa1024_pub.pem --IceSSL.KeyFile=c_rsa1024_priv.pem",
+ "server" : " --IceSSL.CertFile=s_rsa1024_pub.pem --IceSSL.KeyFile=s_rsa1024_priv.pem",
+ "colloc" : " --IceSSL.CertFile=c_rsa1024_pub.pem --IceSSL.KeyFile=c_rsa1024_priv.pem"
+ },
+ "java" : {
+ "plugin" : " --Ice.Plugin.IceSSL=IceSSL.PluginFactory --Ice.Default.Protocol=ssl " +
+ "--IceSSL.DefaultDir=%(certsdir)s --IceSSL.Truststore=certs.jks --IceSSL.Password=password",
+ "client" : " --IceSSL.Keystore=client.jks",
+ "server" : " --IceSSL.Keystore=server.jks",
+ "colloc" : " --IceSSL.Keystore=client.jks"
+ },
+ "cs" : {
+ "plugin" : " --Ice.Plugin.IceSSL=IceSSL:IceSSL.PluginFactory --Ice.Default.Protocol=ssl" +
+ " --IceSSL.Password=password --IceSSL.DefaultDir=%(certsdir)s",
+ "client" : " --IceSSL.CertFile=c_rsa1024.pfx --IceSSL.CheckCertName=0",
+ "server" : " --IceSSL.CertFile=s_rsa1024.pfx --IceSSL.ImportCert.CurrentUser.Root=cacert.pem",
+ "colloc" : " --IceSSL.CertFile=c_rsa1024.pfx --IceSSL.ImportCert.CurrentUser.Root=cacert.pem --IceSSL.CheckCertName=0"
+ },
+ }
+sslConfigTree["py"] = sslConfigTree["cpp"]
+sslConfigTree["rb"] = sslConfigTree["cpp"]
+sslConfigTree["php"] = sslConfigTree["cpp"]
+
+def getDefaultMapping():
+ """Try and guess the language mapping out of the current path"""
+
+ here = os.getcwd()
+ while len(here) > 0:
+ current = os.path.basename(here)
+ here = os.path.dirname(here)
+ if current in ["cpp", "cs", "java", "php", "py", "rb", "tmp"]:
+ return current
+ else:
+ raise "cannot determine mapping"
+
+def getTestEnv():
+ env = {}
+ env["certsdir"] = os.path.abspath(os.path.join(toplevel, "certs"))
+ return env
+
+class DriverConfig:
+ lang = None
+ protocol = None
+ compress = 0
+ serialize = 0
+ host = None
+ mono = False
+ valgrind = False
+ type = None
+ overrides = None
+ ipv6 = False
+ x64 = False
+
+ def __init__(self, type = None):
+ global protocol
+ global compress
+ global serialize
+ global host
+ global mono
+ global valgrind
+ global ipv6
+ global x64
+ self.lang = getDefaultMapping()
+ self.protocol = protocol
+ self.compress = compress
+ self.serialize = serialize
+ self.host = host
+ self.mono = mono
+ self.valgrind = valgrind
+ self.type = type
+ self.ipv6 = ipv6
+ self.x64 = x64
+
+def argsToDict(argumentString, results):
+ """Converts an argument string to dictionary"""
+ args = argumentString.strip()
+ while len(args) > 0:
+ end = args.find(" --")
+ if end == -1:
+ current = args.strip()
+ args = ""
+ else:
+ current = args[:end].strip()
+ args = args[end:].strip()
+
+ value = current.find("=")
+ if value != -1:
+ results[current[:value]] = current[value+1:]
+ else:
+ results[current] = None
+ return results
+
+def getCommandLine(exe, config, env=None):
+
+ if not env:
+ env = getTestEnv()
+
+ #
+ # Command lines are built up from the items in the components
+ # sequence, which is initialized with command line options common to
+ # all test drivers.
+ #
+ components = ["--Ice.NullHandleAbort=1", "--Ice.Warn.Connections=1"]
+
+ #
+ # Turn on network tracing.
+ #
+ # components.append("--Ice.Trace.Network=3")
+
+ #
+ # Now we add additional components dependent on the desired
+ # configuration.
+ #
+ if config.protocol == "ssl":
+ components.append(sslConfigTree[config.lang]["plugin"] % env)
+ components.append(sslConfigTree[config.lang][config.type] % env)
+
+ if config.compress:
+ components.append("--Ice.Override.Compress=1")
+
+ if config.serialize:
+ components.append("--Ice.ThreadPool.Server.Serialize=1")
+
+ if config.type == "server" or config.type == "colloc" and config.lang == "py":
+ components.append("--Ice.ThreadPool.Server.Size=1 --Ice.ThreadPool.Server.SizeMax=3 --Ice.ThreadPool.Server.SizeWarn=0")
+
+ if config.type == "server":
+ components.append("--Ice.PrintAdapterReady=1 --Ice.ServerIdleTime=30")
+
+ if config.ipv6:
+ components.append("--Ice.Default.Host=0:0:0:0:0:0:0:1 --Ice.IPv6=1")
+ elif config.host != None and len(config.host) != 0:
+ components.append("--Ice.Default.Host=%s" % config.host)
+
+ #
+ # Not very many tests actually require an option override, so not to worried
+ # about optimal here.
+ #
+ if config.overrides != None and len(config.overrides) > 0:
+ propTable = {}
+ for c in components:
+ argsToDict(c, propTable)
+
+ argsToDict(config.overrides, propTable)
+ components = []
+ for k, v in propTable.iteritems():
+ if v != None:
+ components.append("%s=%s" % (k, v))
+ else:
+ components.append("%s" % k)
+
+ output = StringIO.StringIO()
+ if config.mono and config.lang == "cs":
+ print >>output, "mono", "--debug %s.exe" % exe,
+ elif config.lang == "rb" and config.type == "client":
+ print >>output, "ruby", exe,
+ elif config.lang == "java":
+ print >>output, "%s -ea" % javaCmd,
+ if isSolaris() and config.x64:
+ print >>output, "-d64",
+ if not config.ipv6:
+ print >>output, "-Djava.net.preferIPv4Stack=true",
+ print >>output, exe,
+ elif config.lang == "py":
+ print >>output, "python", exe,
+ elif config.lang == "php" and config.type == "client":
+ print >>output, phpCmd, "-c tmp.ini -f", exe, " -- ",
+ elif config.lang == "cpp" and config.valgrind:
+ # --child-silent-after-fork=yes is required for the IceGrid/activator test where the node
+ # forks a process with execv failing (invalid exe name).
+ print >>output, "valgrind -q --child-silent-after-fork=yes --leak-check=full ",
+ print >>output, "--suppressions=" + os.path.join(toplevel, "config", "valgrind.sup"), exe,
+ else:
+ print >>output, exe,
+
+ for c in components:
+ print >>output, c,
+ commandline = output.getvalue()
+ output.close()
+
+ return commandline
+
+def getDefaultServerFile():
+ lang = getDefaultMapping()
+ if lang in ["rb", "php", "cpp", "cs"]:
+ return "server"
+ if lang == "py":
+ return "Server.py"
+ if lang == "java":
+ return "Server"
+
+def getDefaultClientFile(lang = None):
+ if lang is None:
+ lang = getDefaultMapping()
+ if lang == "rb":
+ return "Client.rb"
+ if lang == "php":
+ return "Client.php"
+ if lang in ["cpp", "cs"]:
+ return "client"
+ if lang == "py":
+ return "Client.py"
+ if lang == "java":
+ return "Client"
+
+def getDefaultCollocatedFile():
+ lang = getDefaultMapping()
+ if lang == "rb":
+ return "Collocated.rb"
+ if lang == "php":
+ return "Collocated.php"
+ if lang in ["cpp", "cs"]:
+ return "collocated"
+ if lang == "py":
+ return "Collocated.py"
+ if lang == "java":
+ return "Collocated"
+
+def isDebug():
+ return debug
+
+import Expect
+def spawn(cmd, env = None, cwd = None):
+ if debug:
+ print "(%s)" % cmd,
+ return Expect.Expect(cmd, env = env, logfile=tracefile, cwd = cwd)
+
+def spawnClient(cmd, env = None, cwd = None, echo = True):
+ client = spawn(cmd, env, cwd)
+ if echo:
+ client.trace()
+ return client
+
+def spawnServer(cmd, env = None, cwd = None, count = 1, adapter = None, echo = True):
+ server = spawn(cmd, env, cwd)
+ if adapter:
+ server.expect("%s ready\n" % adapter)
+ else:
+ while count > 0:
+ server.expect("[^\n]+ ready\n")
+ count = count -1
+ if echo:
+ server.trace([re.compile("[^\n]+ ready")])
+ return server
+
+def getMirrorDir(base, mapping):
+ """Get the mirror directory for the current test in the given mapping."""
+ lang = getDefaultMapping()
+ after = []
+ before = base
+ while len(before) > 0:
+ current = os.path.basename(before)
+ before = os.path.dirname(before)
+ if current == lang:
+ break
+ after.insert(0, current)
+ else:
+ raise "cannot find language dir"
+ return os.path.join(before, mapping, *after)
+
+
+def clientServerTest(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 ["rb", "php"]:
+ serverdir = getMirrorDir(testdir, "cpp")
+ else:
+ serverdir = testdir
+ if lang != "java":
+ server = os.path.join(serverdir, server)
+
+ if serverenv is None:
+ serverenv = copy.deepcopy(os.environ)
+ if lang == "cpp":
+ addLdPath(os.path.join(serverdir), serverenv)
+ elif lang == "java":
+ addClasspath(os.path.join(serverdir, "classes"), serverenv)
+
+ global cross
+ if len(cross) == 0:
+ cross.append(lang)
+
+ for clientLang in cross:
+ clientCfg = DriverConfig("client")
+ if clientLang != lang:
+ if clientDesc != getDefaultClientFile():
+ print "** skipping cross test"
+ return
+
+ clientCfg.lang = clientLang
+ client = getDefaultClientFile(clientLang)
+ clientdir = getMirrorDir(testdir, clientLang)
+ print clientdir
+ if not os.path.exists(clientdir):
+ print "** no matching test for %s" % clientLang
+ return
+ else:
+ clientdir = testdir
+
+ if clientLang != "java":
+ client = os.path.join(clientdir, client)
+
+ if clientenv is None:
+ clientenv = copy.deepcopy(os.environ)
+ if clientLang == "cpp":
+ addLdPath(os.path.join(clientdir), clientenv)
+ elif clientLang == "java":
+ addClasspath(os.path.join(clientdir, "classes"), clientenv)
+
+ print "starting " + serverDesc + "...",
+ serverCfg = DriverConfig("server")
+ if lang in ["rb", "php"]:
+ serverCfg.lang = "cpp"
+ server = getCommandLine(server, serverCfg) + " " + additionalServerOptions
+ serverProc = spawnServer(server, env = serverenv)
+ print "ok"
+
+ if lang == "php":
+ writePhpIni("php.ini", "tmp.ini")
+
+ if clientLang == lang:
+ print "starting %s..." % clientDesc,
+ else:
+ print "starting %s %s ..." % (clientLang, clientDesc),
+ client = getCommandLine(client, clientCfg) + " " + additionalClientOptions
+ clientProc = spawnClient(client, env = clientenv)
+ print "ok"
+
+ clientProc.waitTestSuccess()
+ serverProc.waitTestSuccess()
+
+def collocatedTest(additionalOptions = ""):
+ lang = getDefaultMapping()
+ if len(cross) > 1 or cross[0] != lang:
+ print "** skipping cross test"
+ return
+ testdir = os.getcwd()
+
+ collocated = getDefaultCollocatedFile()
+ if lang != "java":
+ collocated = os.path.join(testdir, collocated)
+ if lang == "cpp":
+ env = copy.deepcopy(os.environ)
+ addLdPath(os.path.join(testdir), env)
+ else:
+ env = None
+ else:
+ env = copy.deepcopy(os.environ)
+ addClasspath(os.path.join(testdir, "classes"), env)
+
+ print "starting collocated...",
+ collocated = getCommandLine(collocated, DriverConfig("colloc")) + ' ' + additionalOptions
+ collocatedProc = spawnClient(collocated, env = env)
+ print "ok"
+ collocatedProc.waitTestSuccess()
+
+def cleanDbDir(path):
+ for filename in [ os.path.join(path, f) for f in os.listdir(path) if f != ".gitignore" and f != "DB_CONFIG" ]:
+ os.remove(filename)
+
+def startClient(exe, args = "", config=None, env=None, echo = True):
+ if config == None:
+ config = DriverConfig("client")
+ cmd = getCommandLine(exe, config, env) + ' ' + args
+ if config.lang == "php":
+ writePhpIni("php.ini", "tmp.ini")
+
+ return spawnClient(cmd, echo = echo)
+
+def startServer(exe, args = "", config=None, env=None, adapter = None, count = 1, echo = False):
+ if config == None:
+ config = DriverConfig("server")
+ cmd = getCommandLine(exe, config, env) + ' ' + args
+ return spawnServer(cmd, adapter = adapter, count = count, echo = echo)
+
+def startColloc(exe, args, config=None, env=None):
+ if config == None:
+ config = DriverConfig("colloc")
+ cmd = getCommandLine(exe, config, env) + ' ' + args
+ return spawnClient(cmd)
+
+def simpleTest(exe, options = ""):
+ print "starting client...",
+ command = exe + ' ' + options
+ client = spawnClient(command)
+ print "ok"
+ client.waitTestSuccess()
+
+def getCppBinDir():
+ binDir = os.path.join(getIceDir("cpp"), "bin")
+ if iceHome and x64:
+ if isHpUx():
+ binDir = os.path.join(binDir, "pa20_64")
+ elif isSolaris():
+ if isSparc():
+ binDir = os.path.join(binDir, "sparcv9")
+ else:
+ binDir = os.path.join(binDir, "amd64")
+ elif isWin32():
+ binDir = os.path.join(binDir, "x64")
+ return binDir
+
+def getTestName():
+ lang = getDefaultMapping()
+ here = os.getcwd().split(os.sep)
+ here.reverse()
+ for i in range(0, len(here)):
+ if here[i] == lang:
+ break
+ else:
+ raise "cannot find language dir"
+ here = here[:i-1]
+ here.reverse()
+ # The crossTests list is in UNIX format.
+ return os.path.join(*here).replace(os.sep, '/')
+
+def processCmdLine():
+ def usage():
+ print "usage: " + sys.argv[0] + """
+ --debug Display debugging information on each test.
+ --trace=<file> Display tracing.
+ --protocol=tcp|ssl Run with the given protocol.
+ --compress Run the tests with protocol compression.
+ --valgrind Run the tests with valgrind.
+ --host=host Set --Ice.Default.Host=<host>.
+ --serialize Run with connection serialization.
+ --ipv6 Use IPv6 addresses.
+ --ice-home=<path> Use the binary distribution from the given path.
+ --x64 Binary distribution is 64-bit.
+ --cross=lang Run cross language test.
+ """
+ sys.exit(2)
+
+ try:
+ opts, args = getopt.getopt(
+ sys.argv[1:], "", ["debug", "trace=", "protocol=", "compress", "valgrind", "host=", "serialize", "ipv6", \
+ "ice-home=", "x64", "cross="])
+ except getopt.GetoptError:
+ usage()
+
+ if args:
+ usage()
+
+ for o, a in opts:
+ if o == "--ice-home":
+ global iceHome
+ iceHome = a
+ elif o == "--cross":
+ global cross
+ #testName = getTestName()
+ #if testName == "Ice/custom":
+ #if getTestName() not in crossTests:
+ cross.append(a)
+ if not a in ["cpp", "java", "cs", "py", "rb" ]:
+ print "cross must be one of cpp, java, cs, py or rb"
+ sys.exit(1)
+ if getTestName() not in crossTests:
+ print "*** This test does not support cross language testing"
+ sys.exit(0)
+ # Temporary.
+ lang = getDefaultMapping()
+ if getTestName() == "Ice/background" and (lang == "cs" or cross == "cs"):
+ print "*** This test does not support cross language testing"
+ sys.exit(0)
+
+ elif o == "--x64":
+ global x64
+ x64 = True
+ elif o == "--compress":
+ global compress
+ compress = True
+ elif o == "--serialize":
+ global serialize
+ serialize = True
+ elif o == "--host":
+ global host
+ host = a
+ elif o == "--valgrind":
+ global valgrind
+ valgrind = True
+ elif o == "--ipv6":
+ global ipv6
+ ipv6 = True
+ if o == "--trace":
+ global tracefile
+ if a == "stdout":
+ tracefile = sys.stdout
+ else:
+ tracefile = open(a, "w")
+ elif o == "--debug":
+ global debug
+ debug = True
+ elif o == "--protocol":
+ if a not in ( "ssl", "tcp"):
+ usage()
+ # ssl protocol isn't directly supported with mono.
+ if mono and getDefaultMapping() == "cs" and a == "ssl":
+ print "SSL is not supported with mono"
+ sys.exit(1)
+ global protocol
+ protocol = a
+
+ if len(args) > 0:
+ usage()
+
+ # Only use binary distribution from ICE_HOME environment variable if USE_BIN_DIST=yes
+ if not iceHome and os.environ.get("USE_BIN_DIST", "no") == "yes":
+ if os.environ.get("ICE_HOME", "") != "":
+ iceHome = os.environ["ICE_HOME"]
+ elif isLinux():
+ iceHome = "/usr"
+
+ if not x64:
+ x64 = isWin32() and os.environ.get("XTARGET") == "x64" or os.environ.get("LP64") == "yes"
+
+ configurePaths()
+
+def runTests(start, expanded, num = 0, script = False):
+ total = 0
+ for tests in expanded:
+ for i, args, config in tests:
+ total = total + 1
+ #
+ # The configs argument is a list containing one or more test configurations.
+ #
+ index = 0
+ for tests in expanded:
+ for i, args, config in tests:
+ index = index + 1
+ if index < start:
+ continue
+ i = os.path.normpath(i)
+ dir = os.path.join(toplevel, i)
+
+ print
+ if num > 0:
+ print "[" + str(num) + "]",
+ if script:
+ prefix = "echo \""
+ suffix = "\""
+ else:
+ prefix = ""
+ suffix = ""
+
+ print "%s*** running tests %d/%d in %s%s" % (prefix, index, total, dir, suffix)
+ print "%s*** configuration:" % prefix,
+ if len(args.strip()) == 0:
+ print "Default",
+ else:
+ print args.strip(),
+ print suffix
+
+ if args.find("cross") != -1:
+ test = os.path.join(*i.split(os.sep)[2:])
+ # The crossTests list is in UNIX format.
+ test = test.replace(os.sep, '/')
+ if not test in crossTests:
+ print "%s*** test does not support cross testing%s" % (prefix, suffix)
+ continue
+
+ #
+ # Skip tests not supported with IPv6 if necessary
+ #
+ if args.find("ipv6") != -1 and "noipv6" in config:
+ print "%s*** test not supported with IPv6%s" % (prefix, suffix)
+ continue
+
+ if isVista() and "novista" in config:
+ print "%s*** test not supported under Vista%s" % (prefix, suffix)
+ continue
+
+ if not isWin32() and "win32only" in config:
+ print "%s*** test only supported under Win32%s" % (prefix, suffix)
+ continue
+
+ # If this is mono and we're running ssl protocol tests
+ # then skip. This occurs when using --all.
+ if mono and ("nomono" in config or (i.find(os.path.join("cs","test")) != -1 and args.find("ssl") != -1)):
+ print "%s*** test not supported with mono%s" % (prefix, suffix)
+ continue
+
+ # If this is java and we're running ipv6 under windows then skip.
+ if isWin32() and i.find(os.path.join("java","test")) != -1 and args.find("ipv6") != -1:
+ print "%s*** test not supported under windows%s" % (prefix, suffix)
+ continue
+
+ # Skip tests not supported by valgrind
+ if args.find("valgrind") != -1 and ("novalgrind" in config or args.find("ssl") != -1):
+ print "%s*** test not supported with valgrind%s" % (prefix, suffix)
+ continue
+
+ if script:
+ print "echo \"*** test started: `date`\""
+ print "cd %s" % dir
+ else:
+ print "*** test started:", time.strftime("%x %X")
+ sys.stdout.flush()
+
+ os.chdir(dir)
+
+ global keepGoing
+ if script:
+ print "if ! python %s %s; then" % (os.path.join(dir, "run.py"), args)
+ print " echo 'test in %s failed'" % os.path.abspath(dir)
+ if not keepGoing:
+ print " exit 1"
+ print "fi"
+ else:
+ status = os.system("python " + os.path.join(dir, "run.py " + args))
+
+ if status:
+ if(num > 0):
+ print "[" + str(num) + "]",
+ message = "test in " + os.path.abspath(dir) + " failed with exit status", status,
+ print message
+ if not keepGoing:
+ sys.exit(status)
+ else:
+ print " ** Error logged and will be displayed again when suite is completed **"
+ global testErrors
+ testErrors.append(message)
+
+
+if os.environ.has_key("ICE_CONFIG"):
+ os.unsetenv("ICE_CONFIG")
+
+import inspect
+frame = inspect.currentframe()
+# Move to the top-most frame in the callback.
+while frame.f_back is not None:
+ frame = frame.f_back
+if os.path.split(frame.f_code.co_filename)[1] == "run.py":
+ # If we're not in the test directory, chdir to the correct
+ # location.
+ if not os.path.isabs(sys.argv[0]):
+ d = os.path.join(os.getcwd(), sys.argv[0])
+ else:
+ d = sys.argv[0]
+ d = os.path.split(d)[0]
+ if os.path.normpath(d) != os.getcwd():
+ os.chdir(d)
+ processCmdLine()