summaryrefslogtreecommitdiff
path: root/scripts/Util.py
diff options
context:
space:
mode:
authorJose <jose@zeroc.com>2017-05-19 16:08:24 +0200
committerJose <jose@zeroc.com>2017-05-19 16:08:24 +0200
commit08197ea7b0a7bccc1c88f84d9d6415637c719915 (patch)
treeb057554f925ffbabb86d0c3c4d1511f2e04674e3 /scripts/Util.py
parentFix Whitespaces (diff)
downloadice-08197ea7b0a7bccc1c88f84d9d6415637c719915.tar.bz2
ice-08197ea7b0a7bccc1c88f84d9d6415637c719915.tar.xz
ice-08197ea7b0a7bccc1c88f84d9d6415637c719915.zip
ICE-7486 - Android compat test controller
Diffstat (limited to 'scripts/Util.py')
-rw-r--r--scripts/Util.py202
1 files changed, 199 insertions, 3 deletions
diff --git a/scripts/Util.py b/scripts/Util.py
index 5ba3688450a..6a71bf59745 100644
--- a/scripts/Util.py
+++ b/scripts/Util.py
@@ -492,6 +492,10 @@ class Mapping:
self.uwp = False
self.openssl = False
+ self.device = ""
+ self.avd = ""
+ self.androidemulator = False
+
def __str__(self):
s = []
for o in self.parsedOptions:
@@ -720,10 +724,11 @@ class Mapping:
for f in excludes:
if f.search(self.name + "/" + testId):
return True
-
return False
def loadTestSuites(self, tests, config, filters=[], rfilters=[]):
+ global currentMapping
+ currentMapping = self
for test in tests or [""]:
for root, dirs, files in os.walk(os.path.join(self.getTestsPath(), test.replace('/', os.sep))):
@@ -764,6 +769,7 @@ class Mapping:
testcases = self.computeTestCases(testId, files)
if testcases:
TestSuite(root, testcases)
+ currentMapping = None
def getTestSuites(self, ids=[]):
if not ids:
@@ -1593,9 +1599,10 @@ class Result:
class TestSuite:
def __init__(self, path, testcases=None, options=None, libDirs=None, runOnMainThread=False, chdir=False,
- multihost=True):
+ multihost=True, mapping=None):
+ global currentMapping
self.path = os.path.dirname(path) if os.path.basename(path) == "test.py" else path
- self.mapping = Mapping.getByPath(self.path)
+ self.mapping = currentMapping or Mapping.getByPath(self.path)
self.id = self.mapping.addTestSuite(self)
self.options = options or {}
self.libDirs = libDirs or []
@@ -1924,6 +1931,120 @@ class RemoteProcessController(ProcessController):
if self.adapter:
self.adapter.destroy()
+class AndroidProcessController(RemoteProcessController):
+
+ def __init__(self, current):
+ run("adb kill-server")
+ RemoteProcessController.__init__(self, current,
+ "tcp -h 127.0.0.1 -p 15001" if current.config.androidemulator else None)
+ self.device = current.config.device
+ self.avd = current.config.avd
+ self.androidemulator = current.config.androidemulator
+
+ def __str__(self):
+ return "Android"
+
+ def getControllerIdentity(self, current):
+ return "Android/ProcessController"
+
+ def adb(self):
+ return "adb -s {}".format(self.device) if self.device else "adb"
+
+ def emulator(self):
+ #
+ # We need to use emulator fullpath, otherwise fails to start with
+ # :Qt library not found at ..\emulator\lib64\qt\lib
+ #
+ emu = "emulator.exe" if sys.platform == "win32" else "emulator"
+ for d in os.environ.get("PATH").split(os.pathsep):
+ if os.path.isfile(os.path.join(d, emu)):
+ return os.path.join(d, emu)
+
+ def startEmulator(self, config):
+ #
+ # First check if the AVD image is available
+ #
+ out = run("{} -list-avds".format(self.emulator()))
+ if config.avd not in out:
+ raise RuntimeError("couldn't find AVD `{}'".format(config.avd))
+
+ #
+ # Find and unused port to run android emulator, between 5554 and 5584
+ #
+ port = -1
+ out = run("adb devices -l")
+ for p in range(5554, 5586, 2):
+ if not "emulator-{}".format(p) in out:
+ port = p
+
+ if port == -1:
+ raise RuntimeError("cannot find free port in range 5554-5584, to run android emulator")
+
+ self.device = "emulator-{}".format(port)
+ cmd = "{0} -avd {1} -port {2} -wipe-data".format(self.emulator(), config.avd, port)
+ self.emulator = subprocess.Popen(cmd, shell=True)
+
+ if self.emulator.poll():
+ raise RuntimeError("failed to start Android emulator with AVD {} on port {}".format(config.avd, port))
+
+ self.avd = config.avd
+
+ #
+ # Wait for the device to be ready
+ #
+ t = time.time()
+ while True:
+ try:
+ lines = run("{} shell getprop sys.boot_completed".format(self.adb()))
+ if len(lines) > 0 and lines[0].strip() == "1":
+ break
+ except RuntimeError:
+ pass # expected if device is offline
+ #
+ # If the emulator doesn't complete boot in 60 seconds give up
+ #
+ if (time.time() - t) > 60:
+ raise RuntimeError("couldn't start Android emulator with avd {}".format(config.avd))
+ time.sleep(2)
+ print(" ok")
+
+ def startControllerApp(self, current, ident):
+ if current.config.avd:
+ self.startEmulator(current.config)
+ run("{} install -r test/controller/build/outputs/apk/testController-debug.apk".format(self.adb()))
+ run("{} shell am start -n com.zeroc.testcontroller/.ControllerActivity".format(self.adb()))
+
+ def stopControllerApp(self, ident):
+ try:
+ run("{} shell pm uninstall com.zeroc.testcontroller".format(self.adb()))
+ except:
+ pass
+
+ if self.avd:
+ try:
+ run("{} emu kill".format(self.adb()))
+ except:
+ pass
+
+ try:
+ run("adm kill-server")
+ except:
+ pass
+ #
+ # Wait for the emulator to shutdown
+ #
+ if self.emulator:
+ sys.stdout.write("Wainting for emulator to shutdown..")
+ sys.stdout.flush()
+ while True:
+ if self.emulator.poll() != None:
+ print(" ok")
+ break
+ sys.stdout.write(".")
+ sys.stdout.flush()
+ time.sleep(0.5)
+
+
class iOSSimulatorProcessController(RemoteProcessController):
device = "iOSSimulatorProcessController"
@@ -2439,6 +2560,9 @@ class Driver:
processController = UWPProcessController
elif process and isinstance(process.getMapping(current), JavaScriptMapping) and current.config.browser:
processController = BrowserProcessController
+ elif process and (isinstance(process.getMapping(current), AndroidMapping) or
+ isinstance(process.getMapping(current), AndroidCompatMapping)):
+ processController = AndroidProcessController
else:
processController = LocalProcessController
@@ -2656,6 +2780,74 @@ class JavaCompatMapping(JavaMapping):
"iceboxadmin" : "IceBox.Admin",
}[processType]
+class Android:
+
+ @classmethod
+ def getUnsuportedTests(self, protocol):
+ tests = [
+ "Ice/hash",
+ "Ice/faultTolerance",
+ "Ice/metrics",
+ "Ice/networkProxy",
+ "Ice/throughput",
+ "Ice/plugin",
+ "Ice/properties"]
+ if protocol in ["ssl", "wss"]:
+ tests += [
+ "Ice/binding",
+ "Ice/timeout",
+ "Ice/udp"]
+ return tests
+
+class AndroidMapping(JavaMapping):
+
+ def getTestsPath(self):
+ return os.path.join(self.path, "../java/test/src/main/java/test")
+
+ def filterTestSuite(self, testId, config, filters=[], rfilters=[]):
+ if not testId.startswith("Ice/"):
+ return True
+ return JavaMapping.filterTestSuite(self, testId, config, filters, rfilters)
+
+class AndroidCompatMapping(JavaCompatMapping):
+
+ class Config(Mapping.Config):
+
+ @classmethod
+ def getSupportedArgs(self):
+ return ("", ["device=", "avd=", "androidemulator"])
+
+ @classmethod
+ def usage(self):
+ print("")
+ print("Android Mapping options:")
+ print("--device=<device-id> Id of the emulator or device used to run the tests.")
+ print("--androidemulator Run tests in emulator as opposed to a real device.")
+ print("--avd Start emulator image")
+
+ def __init__(self, options=[]):
+ Mapping.Config.__init__(self, options)
+
+ parseOptions(self, options, { "device" : "device", "avd" : "avd" })
+ self.androidemulator = self.androidemulator or self.avd
+
+ def getSSLProps(self, process, current):
+ props = JavaCompatMapping.getSSLProps(self, process, current)
+ props.update({
+ "IceSSL.KeystoreType" : "BKS",
+ "IceSSL.TruststoreType" : "BKS",
+ "Ice.InitPlugins" : "0",
+ "IceSSL.Keystore": "server.bks" if isinstance(process, Server) else "client.bks"})
+ return props
+
+ def getTestsPath(self):
+ return os.path.join(self.path, "../java-compat/test/src/main/java/test")
+
+ def filterTestSuite(self, testId, config, filters=[], rfilters=[]):
+ if not testId.startswith("Ice/") or testId in Android.getUnsuportedTests(config.protocol):
+ return True
+ return JavaCompatMapping.filterTestSuite(self, testId, config, filters, rfilters)
+
class CSharpMapping(Mapping):
def getTestSuites(self, ids=[]):
@@ -3004,6 +3196,10 @@ for m in filter(lambda x: os.path.isdir(os.path.join(toplevel, x)), os.listdir(
Mapping.add(m, CSharpMapping())
elif m == "objective-c" or re.match("objective-c-*", m):
Mapping.add(m, ObjCMapping())
+ elif m == "android-compat":
+ Mapping.add(m, AndroidCompatMapping())
+ elif m == "android":
+ Mapping.add(m, AndroidMapping())
def runTestsWithPath(path):
runTests([Mapping.getByPath(path)])