Bug 1519477 - Try to detect networking connectivity problems before running local tests on android; r=bc
authorGeoff Brown <gbrown@mozilla.com>
Wed, 16 Jan 2019 14:59:35 -0700
changeset 511322 4c08e7df7398a16e32d3e42943c960a5fc331a20
parent 511321 6f2303192174baaf9cab167db5f97411bad943bf
child 511323 5f184a902803e881355a3575862f57f35a355b0a
push id10547
push userffxbld-merge
push dateMon, 21 Jan 2019 13:03:58 +0000
treeherdermozilla-beta@24ec1916bffe [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbc
bugs1519477
milestone66.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 1519477 - Try to detect networking connectivity problems before running local tests on android; r=bc
layout/tools/reftest/mach_commands.py
testing/mochitest/mach_commands.py
testing/mozbase/mozrunner/mozrunner/devices/android_device.py
testing/xpcshell/mach_commands.py
--- a/layout/tools/reftest/mach_commands.py
+++ b/layout/tools/reftest/mach_commands.py
@@ -233,12 +233,12 @@ class MachCommands(MachCommandBase):
         kwargs["topsrcdir"] = self.topsrcdir
         process_test_objects(kwargs)
         reftest = self._spawn(ReftestRunner)
         # Unstructured logging must be enabled prior to calling
         # adb which uses an unstructured logger in its constructor.
         reftest.log_manager.enable_unstructured()
         if conditions.is_android(self):
             from mozrunner.devices.android_device import verify_android_device
-            verify_android_device(self, install=True, xre=True, app=kwargs["app"],
-                                  device_serial=kwargs["deviceSerial"])
+            verify_android_device(self, install=True, xre=True, network=True,
+                                  app=kwargs["app"], device_serial=kwargs["deviceSerial"])
             return reftest.run_android_test(**kwargs)
         return reftest.run_desktop_test(**kwargs)
--- a/testing/mochitest/mach_commands.py
+++ b/testing/mochitest/mach_commands.py
@@ -279,17 +279,17 @@ def setup_junit_argument_parser():
 
         with open(path, 'r') as fh:
             imp.load_module('mochitest', fh, path,
                             ('.py', 'r', imp.PY_SOURCE))
 
         import runjunit
 
         from mozrunner.devices.android_device import verify_android_device
-        verify_android_device(build_obj, install=False, xre=True)
+        verify_android_device(build_obj, install=False, xre=True, network=True)
 
     global parser
     parser = runjunit.JunitArgumentParser()
     return parser
 
 
 # condition filters
 
@@ -451,18 +451,18 @@ class MachCommands(MachCommandBase):
             from mozrunner.devices.android_device import grant_runtime_permissions
             from mozrunner.devices.android_device import verify_android_device
             app = kwargs.get('app')
             if not app:
                 app = self.substs["ANDROID_PACKAGE_NAME"]
             device_serial = kwargs.get('deviceSerial')
 
             # verify installation
-            verify_android_device(self, install=True, xre=False, app=app,
-                                  device_serial=device_serial)
+            verify_android_device(self, install=True, xre=False, network=True,
+                                  app=app, device_serial=device_serial)
             grant_runtime_permissions(self, app, device_serial=device_serial)
             run_mochitest = mochitest.run_android_test
         else:
             run_mochitest = mochitest.run_desktop_test
 
         overall = None
         for (flavor, subsuite), tests in sorted(suites.items()):
             fobj = ALL_FLAVORS[flavor]
@@ -563,18 +563,18 @@ class RobocopCommands(MachCommandBase):
 
         from mozrunner.devices.android_device import grant_runtime_permissions, get_adb_path
         from mozrunner.devices.android_device import verify_android_device
         # verify installation
         app = kwargs.get('app')
         if not app:
             app = self.substs["ANDROID_PACKAGE_NAME"]
         device_serial = kwargs.get('deviceSerial')
-        verify_android_device(self, install=True, xre=False, app=app,
-                              device_serial=device_serial)
+        verify_android_device(self, install=True, xre=False, network=True,
+                              app=app, device_serial=device_serial)
         grant_runtime_permissions(self, app, device_serial=device_serial)
 
         if not kwargs['adbPath']:
             kwargs['adbPath'] = get_adb_path(self)
 
         mochitest = self._spawn(MochitestRunner)
         return mochitest.run_robocop_test(self._mach_context, tests, 'robocop', **kwargs)
 
--- a/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
+++ b/testing/mozbase/mozrunner/mozrunner/devices/android_device.py
@@ -7,16 +7,17 @@ from __future__ import absolute_import, 
 import fileinput
 import glob
 import os
 import platform
 import psutil
 import re
 import shutil
 import signal
+import subprocess
 import sys
 import telnetlib
 import time
 import urlparse
 import urllib2
 from distutils.spawn import find_executable
 
 from mozdevice import ADBHost, ADBDevice
@@ -170,28 +171,30 @@ def _maybe_update_host_utils(build_obj):
                 parts = os.path.split(existing_path)
                 backup_dir = '_backup-' + parts[1]
                 backup_path = os.path.join(parts[0], backup_dir)
                 shutil.move(existing_path, backup_path)
                 _install_host_utils(build_obj)
 
 
 def verify_android_device(build_obj, install=False, xre=False, debugger=False,
-                          verbose=False, app=None, device_serial=None):
+                          network=False, verbose=False, app=None, device_serial=None):
     """
        Determine if any Android device is connected via adb.
        If no device is found, prompt to start an emulator.
        If a device is found or an emulator started and 'install' is
        specified, also check whether Firefox is installed on the
        device; if not, prompt to install Firefox.
        If 'xre' is specified, also check with MOZ_HOST_BIN is set
        to a valid xre/host-utils directory; if not, prompt to set
        one up.
        If 'debugger' is specified, also check that JimDB is installed;
        if JimDB is not found, prompt to set up JimDB.
+       If 'network' is specified, also check that the device has basic
+       network connectivity.
        Returns True if the emulator was started or another device was
        already connected.
     """
     device_verified = False
     emulator = AndroidEmulator('*', substs=build_obj.substs, verbose=verbose)
     adb_path = _find_sdk_exe(build_obj.substs, 'adb', False)
     if not adb_path:
         adb_path = 'adb'
@@ -300,16 +303,38 @@ def verify_android_device(build_obj, ins
                     break
         if err:
             _log_info("Host utilities not found: %s" % err)
             response = raw_input(
                 "Download and setup your host utilities? (Y/n) ").strip()
             if response.lower().startswith('y') or response == '':
                 _install_host_utils(build_obj)
 
+    if device_verified and network:
+        # Optionally check the network: If on a device that does not look like
+        # an emulator, verify that the device IP address can be obtained
+        # and check that this host can ping the device.
+        serial = device_serial or os.environ.get('DEVICE_SERIAL')
+        if not serial or ('emulator' not in serial):
+            device = _get_device(build_obj.substs, serial)
+            try:
+                addr = device.get_ip_address()
+                if not addr:
+                    _log_warning("unable to get Android device's IP address!")
+                    _log_warning("tests may fail without network connectivity to the device!")
+                else:
+                    _log_info("Android device's IP address: %s" % addr)
+                    response = subprocess.check_output(["ping", "-c", "1", addr])
+                    _log_debug(response)
+            except Exception as e:
+                _log_warning("unable to verify network connection to device: %s" % str(e))
+                _log_warning("tests may fail without network connectivity to the device!")
+        else:
+            _log_debug("network check skipped on emulator")
+
     if debugger:
         # Optionally set up JimDB. See https://wiki.mozilla.org/Mobile/Fennec/Android/GDB.
         build_platform = _get_device_platform(build_obj.substs)
         jimdb_path = os.path.join(EMULATOR_HOME_DIR, 'jimdb-%s' % build_platform)
         jimdb_utils_path = os.path.join(jimdb_path, 'utils')
         gdb_path = os.path.join(jimdb_path, 'bin', 'gdb')
         err = None
         if not os.path.isdir(jimdb_path):
--- a/testing/xpcshell/mach_commands.py
+++ b/testing/xpcshell/mach_commands.py
@@ -243,17 +243,17 @@ class MachCommands(MachCommandBase):
                 "XPCShellTests", params, log_defaults, fmt_defaults)
 
         if not params['threadCount']:
             params['threadCount'] = int((cpu_count() * 3) / 2)
 
         if conditions.is_android(self):
             from mozrunner.devices.android_device import verify_android_device, get_adb_path
             device_serial = params.get('deviceSerial')
-            verify_android_device(self, device_serial=device_serial)
+            verify_android_device(self, network=True, device_serial=device_serial)
             if not params['adbPath']:
                 params['adbPath'] = get_adb_path(self)
             xpcshell = self._spawn(AndroidXPCShellRunner)
         else:
             xpcshell = self._spawn(XPCShellRunner)
         xpcshell.cwd = self._mach_context.cwd
 
         try: