Bug 1280126 - Use tooltool hostutils for Android automated tests; r=kmoir
authorGeoff Brown <gbrown@mozilla.com>
Mon, 20 Jun 2016 11:39:40 -0600
changeset 302104 5ac935a39dc2
parent 302103 4a25006fb0ea
child 302105 9a6b2786a581
push id78594
push usergbrown@mozilla.com
push dateMon, 20 Jun 2016 17:39:52 +0000
treeherdermozilla-inbound@5ac935a39dc2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskmoir
bugs1280126
milestone50.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1280126 - Use tooltool hostutils for Android automated tests; r=kmoir
testing/mozharness/configs/android/androidarm_4_3.py
testing/mozharness/configs/android/androidx86.py
testing/mozharness/scripts/android_emulator_unittest.py
testing/mozharness/scripts/androidx86_emulator_unittest.py
--- a/testing/mozharness/configs/android/androidarm_4_3.py
+++ b/testing/mozharness/configs/android/androidarm_4_3.py
@@ -1,13 +1,13 @@
 import os
 
 config = {
     "buildbot_json_path": "buildprops.json",
-    "host_utils_url": "http://talos-remote.pvt.build.mozilla.org/tegra/tegra-host-utils.Linux.1109310.2.zip",
+    "hostutils_manifest_path": "testing/config/tooltool-manifests/linux64/hostutils.manifest",
     "robocop_package_name": "org.mozilla.roboexample.test",
     "tooltool_manifest_path": "testing/config/tooltool-manifests/androidarm_4_3/releng.manifest",
     "tooltool_cache": "/builds/tooltool_cache",
     "avds_dir": "/home/cltbld/.android",
     "emulator_manifest": """
         [
         {
         "size": 140097024,
--- a/testing/mozharness/configs/android/androidx86.py
+++ b/testing/mozharness/configs/android/androidx86.py
@@ -1,13 +1,13 @@
 import os
 
 config = {
     "buildbot_json_path": "buildprops.json",
-    "host_utils_url": "http://talos-remote.pvt.build.mozilla.org/tegra/tegra-host-utils.Linux.1109310.2.zip",
+    "hostutils_manifest_path": "testing/config/tooltool-manifests/linux64/hostutils.manifest",
     "robocop_package_name": "org.mozilla.roboexample.test",
     "device_ip": "127.0.0.1",
     "tooltool_manifest_path": "testing/config/tooltool-manifests/androidx86/releng.manifest",
     "tooltool_cache": "/builds/tooltool_cache",
     "avds_dir": "/home/cltbld/.android",
     "emulator_manifest": """
         [
         {
--- a/testing/mozharness/scripts/android_emulator_unittest.py
+++ b/testing/mozharness/scripts/android_emulator_unittest.py
@@ -2,16 +2,17 @@
 # ***** BEGIN LICENSE BLOCK *****
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 # ***** END LICENSE BLOCK *****
 
 import copy
 import datetime
+import glob
 import os
 import sys
 import signal
 import socket
 import subprocess
 import telnetlib
 import time
 import tempfile
@@ -27,23 +28,16 @@ from mozharness.base.vcs.vcsbase import 
 from mozharness.mozilla.blob_upload import BlobUploadMixin, blobupload_config_options
 from mozharness.mozilla.mozbase import MozbaseMixin
 from mozharness.mozilla.testing.testbase import TestingMixin, testing_config_options
 from mozharness.mozilla.testing.unittest import EmulatorMixin
 
 
 class AndroidEmulatorTest(BlobUploadMixin, TestingMixin, EmulatorMixin, VCSMixin, BaseScript, MozbaseMixin):
     config_options = [[
-        ["--host-utils-url"],
-        {"action": "store",
-         "dest": "xre_url",
-         "default": None,
-         "help": "URL to the host utils zip",
-         }
-    ], [
         ["--test-suite"],
         {"action": "store",
          "dest": "test_suite",
          }
     ], [
         ["--adb-path"],
         {"action": "store",
          "dest": "adb_path",
@@ -99,22 +93,22 @@ class AndroidEmulatorTest(BlobUploadMixi
         c = self.config
         abs_dirs = self.query_abs_dirs()
         self.adb_path = self.query_exe('adb')
         self.installer_url = c.get('installer_url')
         self.installer_path = c.get('installer_path')
         self.test_url = c.get('test_url')
         self.test_manifest = c.get('test_manifest')
         self.robocop_path = os.path.join(abs_dirs['abs_work_dir'], "robocop.apk")
-        self.host_utils_url = c.get('host_utils_url')
         self.minidump_stackwalk_path = c.get("minidump_stackwalk_path")
         self.emulator = c.get('emulator')
         self.test_suite_definitions = c['test_suite_definitions']
         self.test_suite = c.get('test_suite')
         self.sdk_level = None
+        self.xre_path = None
         assert self.test_suite in self.test_suite_definitions
 
     def _query_tests_dir(self):
         dirs = self.query_abs_dirs()
         suite_category = self.test_suite_definitions[self.test_suite]["category"]
         try:
             test_dir = self.config["suite_definitions"][suite_category]["testsdir"]
         except:
@@ -403,17 +397,17 @@ class AndroidEmulatorTest(BlobUploadMixi
         self._run_with_timeout(30, [self.adb_path, 'kill-server'])
         self._run_with_timeout(30, [self.adb_path, 'start-server'])
 
     def _screenshot(self, prefix):
         """
            Save a screenshot of the entire screen to the blob upload directory.
         """
         dirs = self.query_abs_dirs()
-        utility = os.path.join(dirs['abs_xre_dir'], "bin", "screentopng")
+        utility = os.path.join(self.xre_path, "screentopng")
         if not os.path.exists(utility):
             self.warning("Unable to take screenshot: %s does not exist" % utility)
             return
         try:
             tmpfd, filename = tempfile.mkstemp(prefix=prefix, suffix='.png',
                 dir=dirs['abs_blob_upload_dir'])
             os.close(tmpfd)
             self.info("Taking screenshot with %s; saving to %s" % (utility, filename))
@@ -457,18 +451,18 @@ class AndroidEmulatorTest(BlobUploadMixi
         raw_log_file = os.path.join(dirs['abs_blob_upload_dir'],
                                     '%s_raw.log' % self.test_suite)
 
         error_summary_file = os.path.join(dirs['abs_blob_upload_dir'],
                                           '%s_errorsummary.log' % self.test_suite)
         str_format_values = {
             'app': self._query_package_name(),
             'remote_webserver': c['remote_webserver'],
-            'xre_path': os.path.join(dirs['abs_xre_dir'], 'xre'),
-            'utility_path':  os.path.join(dirs['abs_xre_dir'], 'bin'),
+            'xre_path': self.xre_path,
+            'utility_path': self.xre_path,
             'http_port': self.emulator['http_port'],
             'ssl_port': self.emulator['ssl_port'],
             'certs_path': os.path.join(dirs['abs_work_dir'], 'tests/certs'),
             # TestingMixin._download_and_extract_symbols() will set
             # self.symbols_path when downloading/extracting.
             'symbols_path': self.symbols_path,
             'modules_dir': dirs['abs_modules_dir'],
             'installer_path': self.installer_path,
@@ -495,32 +489,31 @@ class AndroidEmulatorTest(BlobUploadMixi
         cmd.extend(try_options)
         cmd.extend(self.query_tests_args(
             self.config["suite_definitions"][suite_category].get("tests"),
             self.test_suite_definitions[self.test_suite].get("tests"),
             try_tests))
 
         return cmd
 
-    def _tooltool_fetch(self, url):
+    def _tooltool_fetch(self, url, dir):
         c = self.config
-        dirs = self.query_abs_dirs()
 
         manifest_path = self.download_file(
             url,
             file_name='releng.manifest',
-            parent_dir=dirs['abs_avds_dir']
+            parent_dir=dir
         )
 
         if not os.path.exists(manifest_path):
-            self.fatal("Could not retrieve manifest needed to retrieve avds "
+            self.fatal("Could not retrieve manifest needed to retrieve "
                        "artifacts from %s" % manifest_path)
 
         self.tooltool_fetch(manifest_path,
-                            output_dir=dirs['abs_avds_dir'],
+                            output_dir=dir,
                             cache=c.get("tooltool_cache", None))
 
     ##########################################
     ### Actions for AndroidEmulatorTest ###
     ##########################################
     def setup_avds(self):
         '''
         If tooltool cache mechanism is enabled, the cached version is used by
@@ -535,23 +528,23 @@ class AndroidEmulatorTest(BlobUploadMixi
         # check whether the unpacked content already present match the
         # contents of the tar ball
         self.rmtree(dirs['abs_avds_dir'])
         self.mkdir_p(dirs['abs_avds_dir'])
         if not self.buildbot_config:
             # XXX until we figure out how to determine the repo_path, revision
             url = 'https://hg.mozilla.org/%s/raw-file/%s/%s' % (
                 "try", "default", c["tooltool_manifest_path"])
-            self._tooltool_fetch(url)
+            self._tooltool_fetch(url, dirs['abs_avds_dir'])
         elif self.buildbot_config and 'properties' in self.buildbot_config:
             url = 'https://hg.mozilla.org/%s/raw-file/%s/%s' % (
                 self.buildbot_config['properties']['repo_path'],
                 self.buildbot_config['properties']['revision'],
                 c["tooltool_manifest_path"])
-            self._tooltool_fetch(url)
+            self._tooltool_fetch(url, dirs['abs_avds_dir'])
         else:
             self.fatal("properties in self.buildbot_config are required to "
                        "retrieve tooltool manifest to be used for avds setup")
 
         avd_home_dir = self.abs_dirs['abs_avds_dir']
         if avd_home_dir != "/home/cltbld/.android":
             # Modify the downloaded avds to point to the right directory.
             cmd = [
@@ -629,17 +622,29 @@ class AndroidEmulatorTest(BlobUploadMixi
         """
         suite_category = self.test_suite_definitions[self.test_suite]['category']
         super(AndroidEmulatorTest, self).download_and_extract(suite_categories=[suite_category])
         dirs = self.query_abs_dirs()
         if self.test_suite.startswith('robocop'):
             robocop_url = self.installer_url[:self.installer_url.rfind('/')] + '/robocop.apk'
             self.info("Downloading robocop...")
             self.download_file(robocop_url, 'robocop.apk', dirs['abs_work_dir'], error_level=FATAL)
-        self.download_unzip(self.host_utils_url, dirs['abs_xre_dir'])
+        self.rmtree(dirs['abs_xre_dir'])
+        self.mkdir_p(dirs['abs_xre_dir'])
+        if self.config["hostutils_manifest_path"]:
+            url = 'https://hg.mozilla.org/%s/raw-file/%s/%s' % (
+                "try", "default", self.config["hostutils_manifest_path"])
+            self._tooltool_fetch(url, dirs['abs_xre_dir'])
+            for p in glob.glob(os.path.join(dirs['abs_xre_dir'], 'host-utils-*')):
+                if os.path.isdir(p) and os.path.isfile(os.path.join(p, 'xpcshell')):
+                    self.xre_path = p
+            if not self.xre_path:
+                self.fatal("xre path not found in %s" % dirs['abs_xre_dir'])
+        else:
+            self.fatal("configure hostutils_manifest_path!")
 
     def install(self):
         """
         Install APKs on the emulator
         """
         assert self.installer_path is not None, \
             "Either add installer_path to the config or use --installer-path."
 
--- a/testing/mozharness/scripts/androidx86_emulator_unittest.py
+++ b/testing/mozharness/scripts/androidx86_emulator_unittest.py
@@ -1,16 +1,17 @@
 #!/usr/bin/env python
 # ***** BEGIN LICENSE BLOCK *****
 # This Source Code Form is subject to the terms of the Mozilla Public
 # License, v. 2.0. If a copy of the MPL was not distributed with this file,
 # You can obtain one at http://mozilla.org/MPL/2.0/.
 # ***** END LICENSE BLOCK *****
 
 import copy
+import glob
 import os
 import sys
 import signal
 import socket
 import subprocess
 import telnetlib
 import time
 import tempfile
@@ -34,23 +35,16 @@ class AndroidEmulatorTest(BlobUploadMixi
     config_options = [[
         ["--robocop-url"],
         {"action": "store",
          "dest": "robocop_url",
          "default": None,
          "help": "URL to the robocop apk",
          }
     ], [
-        ["--host-utils-url"],
-        {"action": "store",
-         "dest": "xre_url",
-         "default": None,
-         "help": "URL to the host utils zip",
-         }
-    ], [
         ["--test-suite"],
         {"action": "append",
          "dest": "test_suites",
          }
     ], [
         ["--adb-path"],
         {"action": "store",
          "dest": "adb_path",
@@ -105,23 +99,23 @@ class AndroidEmulatorTest(BlobUploadMixi
         abs_dirs = self.query_abs_dirs()
         self.adb_path = self.query_exe('adb')
         self.installer_url = c.get('installer_url')
         self.installer_path = c.get('installer_path')
         self.test_url = c.get('test_url')
         self.test_manifest = c.get('test_manifest')
         self.robocop_url = c.get('robocop_url')
         self.robocop_path = os.path.join(abs_dirs['abs_work_dir'], "robocop.apk")
-        self.host_utils_url = c.get('host_utils_url')
         self.minidump_stackwalk_path = c.get("minidump_stackwalk_path")
         self.emulators = c.get('emulators')
         self.test_suite_definitions = c['test_suite_definitions']
         self.test_suites = c.get('test_suites')
         for suite in self.test_suites:
             assert suite in self.test_suite_definitions
+        self.xre_path = None
 
     def _query_tests_dir(self, suite_name):
         dirs = self.query_abs_dirs()
         suite_category = self.test_suite_definitions[suite_name]["category"]
         try:
             test_dir = self.config["suite_definitions"][suite_category]["testsdir"]
         except:
             test_dir = suite_category
@@ -425,18 +419,18 @@ class AndroidEmulatorTest(BlobUploadMixi
 
         raw_log_file = os.path.join(dirs['abs_blob_upload_dir'],
                                     '%s_raw.log' % suite_name)
         error_summary_file = os.path.join(dirs['abs_blob_upload_dir'],
                                           '%s_errorsummary.log' % suite_name)
         str_format_values = {
             'app': self._query_package_name(),
             'remote_webserver': c['remote_webserver'],
-            'xre_path': os.path.join(dirs['abs_xre_dir'], 'xre'),
-            'utility_path':  os.path.join(dirs['abs_xre_dir'], 'bin'),
+            'xre_path': self.xre_path,
+            'utility_path': self.xre_path,
             'http_port': emulator['http_port'],
             'ssl_port': emulator['ssl_port'],
             'certs_path': os.path.join(dirs['abs_work_dir'], 'tests/certs'),
             # TestingMixin._download_and_extract_symbols() will set
             # self.symbols_path when downloading/extracting.
             'symbols_path': self.symbols_path,
             'modules_dir': dirs['abs_modules_dir'],
             'installer_path': self.installer_path,
@@ -504,32 +498,31 @@ class AndroidEmulatorTest(BlobUploadMixi
         return {
             "process": subprocess.Popen(cmd, cwd=cwd, stdout=tmp_stdout, stderr=tmp_stdout, env=env),
             "tmp_file": tmp_file,
             "tmp_stdout": tmp_stdout,
             "suite_name": suite_name,
             "emulator_index": emulator_index
         }
 
-    def _tooltool_fetch(self, url):
+    def _tooltool_fetch(self, url, dir):
         c = self.config
-        dirs = self.query_abs_dirs()
 
         manifest_path = self.download_file(
             url,
             file_name='releng.manifest',
-            parent_dir=dirs['abs_avds_dir']
+            parent_dir=dir
         )
 
         if not os.path.exists(manifest_path):
-            self.fatal("Could not retrieve manifest needed to retrieve avds "
+            self.fatal("Could not retrieve manifest needed to retrieve "
                        "artifacts from %s" % manifest_path)
 
         self.tooltool_fetch(manifest_path,
-                            output_dir=dirs['abs_avds_dir'],
+                            output_dir=dir,
                             cache=c.get("tooltool_cache", None))
 
     ##########################################
     ### Actions for AndroidEmulatorTest ###
     ##########################################
     def setup_avds(self):
         '''
         If tooltool cache mechanism is enabled, the cached version is used by
@@ -544,23 +537,23 @@ class AndroidEmulatorTest(BlobUploadMixi
         # check whether the unpacked content already present match the
         # contents of the tar ball
         self.rmtree(dirs['abs_avds_dir'])
         self.mkdir_p(dirs['abs_avds_dir'])
         if not self.buildbot_config:
             # XXX until we figure out how to determine the repo_path, revision
             url = 'https://hg.mozilla.org/%s/raw-file/%s/%s' % (
                 "try", "default", c["tooltool_manifest_path"])
-            self._tooltool_fetch(url)
+            self._tooltool_fetch(url, dirs['abs_avds_dir'])
         elif self.buildbot_config and 'properties' in self.buildbot_config:
             url = 'https://hg.mozilla.org/%s/raw-file/%s/%s' % (
                 self.buildbot_config['properties']['repo_path'],
                 self.buildbot_config['properties']['revision'],
                 c["tooltool_manifest_path"])
-            self._tooltool_fetch(url)
+            self._tooltool_fetch(url, dirs['abs_avds_dir'])
         else:
             self.fatal("properties in self.buildbot_config are required to "
                        "retrieve tooltool manifest to be used for avds setup")
 
         avd_home_dir = self.abs_dirs['abs_avds_dir']
         if avd_home_dir != "/home/cltbld/.android":
             # Modify the downloaded avds to point to the right directory.
             cmd = [
@@ -681,17 +674,29 @@ class AndroidEmulatorTest(BlobUploadMixi
         super(AndroidEmulatorTest, self).download_and_extract(suite_categories=suite_categories)
         dirs = self.query_abs_dirs()
 
         for suite_name in self.test_suites:
             if suite_name.startswith('robocop'):
                 self._download_robocop_apk()
                 break
 
-        self.download_unzip(self.host_utils_url, dirs['abs_xre_dir'])
+        self.rmtree(dirs['abs_xre_dir'])
+        self.mkdir_p(dirs['abs_xre_dir'])
+        if self.config["hostutils_manifest_path"]:
+            url = 'https://hg.mozilla.org/%s/raw-file/%s/%s' % (
+                "try", "default", self.config["hostutils_manifest_path"])
+            self._tooltool_fetch(url, dirs['abs_xre_dir'])
+            for p in glob.glob(os.path.join(dirs['abs_xre_dir'], 'host-utils-*')):
+                if os.path.isdir(p) and os.path.isfile(os.path.join(p, 'xpcshell')):
+                    self.xre_path = p
+            if not self.xre_path:
+                self.fatal("xre path not found in %s" % dirs['abs_xre_dir'])
+        else:
+            self.fatal("configure hostutils_manifest_path!")
 
     def install(self):
         assert self.installer_path is not None, \
             "Either add installer_path to the config or use --installer-path."
 
         emulator_index = 0
         for suite_name in self.test_suites:
             emulator = self.emulators[emulator_index]