Bug 1274408: Remove B2G runners from Marionette Python Harness r?maja_zf draft
authorDavid Burns <dburns@mozilla.com>
Tue, 24 May 2016 22:54:13 +0100
changeset 370534 9e4fcd6481ec1ab2240cdae0959ea281ebdd3498
parent 370533 0ad7fbdb608345fb15fb89f0f813b58ac419de4f
child 521773 5ae23250ffd62a1e10e2d0e64b753f8351adf4fc
push id19087
push userdburns@mozilla.com
push dateTue, 24 May 2016 22:03:13 +0000
reviewersmaja_zf
bugs1274408
milestone49.0a1
Bug 1274408: Remove B2G runners from Marionette Python Harness r?maja_zf All tests were migrated over to MarionetteJS support before we stopped work on B2G. This is now not used and am removing. MozReview-Commit-ID: CEBty565UAu
testing/marionette/harness/marionette/__init__.py
testing/marionette/harness/marionette/runner/__init__.py
testing/marionette/harness/marionette/runner/base.py
testing/marionette/harness/marionette/runner/mixins/__init__.py
testing/marionette/harness/marionette/runner/mixins/b2g.py
--- a/testing/marionette/harness/marionette/__init__.py
+++ b/testing/marionette/harness/marionette/__init__.py
@@ -10,18 +10,16 @@ from .marionette_test import (
     MarionetteJSTestCase,
     MarionetteTestCase,
     skip,
     skip_if_desktop,
     SkipTest,
     skip_unless_protocol,
 )
 from .runner import (
-    B2GTestCaseMixin,
-    B2GTestResultMixin,
     BaseMarionetteArguments,
     BaseMarionetteTestRunner,
     BrowserMobProxyTestCaseMixin,
     EnduranceArguments,
     EnduranceTestCaseMixin,
     HTMLReportingArguments,
     HTMLReportingTestResultMixin,
     HTMLReportingTestRunnerMixin,
--- a/testing/marionette/harness/marionette/runner/__init__.py
+++ b/testing/marionette/harness/marionette/runner/__init__.py
@@ -1,28 +1,25 @@
 # 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/.
 
 from .base import (
-    B2GTestResultMixin,
     BaseMarionetteArguments,
     BaseMarionetteTestRunner,
     Marionette,
     MarionetteTest,
     MarionetteTestResult,
     MarionetteTextTestRunner,
     TestManifest,
     TestResult,
     TestResultCollection,
 )
 
 from .mixins import (
-    B2GTestCaseMixin,
-    B2GTestResultMixin,
     EnduranceArguments,
     EnduranceTestCaseMixin,
     HTMLReportingArguments,
     HTMLReportingTestResultMixin,
     HTMLReportingTestRunnerMixin,
     MemoryEnduranceTestCaseMixin,
     BrowserMobProxyTestCaseMixin,
     BrowserMobProxyArguments,
--- a/testing/marionette/harness/marionette/runner/base.py
+++ b/testing/marionette/harness/marionette/runner/base.py
@@ -16,17 +16,16 @@ import traceback
 import unittest
 import warnings
 import mozprofile
 
 
 from manifestparser import TestManifest
 from manifestparser.filters import tags
 from marionette_driver.marionette import Marionette
-from mixins.b2g import B2GTestResultMixin, get_b2g_pid, get_dm
 from mozlog import get_default_logger
 from moztest.adapters.unit import StructuredTestRunner, StructuredTestResult
 from moztest.results import TestResultCollection, TestResult, relevant_line
 import mozversion
 
 import httpd
 
 
@@ -62,23 +61,16 @@ class MarionetteTestResult(StructuredTes
     resultClass = MarionetteTest
 
     def __init__(self, *args, **kwargs):
         self.marionette = kwargs.pop('marionette')
         TestResultCollection.__init__(self, 'MarionetteTest')
         self.passed = 0
         self.testsRun = 0
         self.result_modifiers = [] # used by mixins to modify the result
-        pid = kwargs.pop('b2g_pid')
-        if pid:
-            if B2GTestResultMixin not in self.__class__.__bases__:
-                bases = [b for b in self.__class__.__bases__]
-                bases.append(B2GTestResultMixin)
-                self.__class__.__bases__ = tuple(bases)
-            B2GTestResultMixin.__init__(self, b2g_pid=pid)
         StructuredTestResult.__init__(self, *args, **kwargs)
 
     @property
     def skipped(self):
         return [t for t in self if t.result == 'SKIPPED']
 
     @skipped.setter
     def skipped(self, value):
@@ -222,43 +214,28 @@ class MarionetteTestResult(StructuredTes
 
 class MarionetteTextTestRunner(StructuredTestRunner):
 
     resultclass = MarionetteTestResult
 
     def __init__(self, **kwargs):
         self.marionette = kwargs.pop('marionette')
         self.capabilities = kwargs.pop('capabilities')
-        self.pre_run_functions = []
-        self.b2g_pid = None
-
-        if self.capabilities["device"] != "desktop" and self.capabilities["browserName"] == "B2G":
-            def b2g_pre_run():
-                dm_type = os.environ.get('DM_TRANS', 'adb')
-                if dm_type == 'adb':
-                    self.b2g_pid = get_b2g_pid(get_dm(self.marionette))
-            self.pre_run_functions.append(b2g_pre_run)
 
         StructuredTestRunner.__init__(self, **kwargs)
 
-
     def _makeResult(self):
         return self.resultclass(self.stream,
                                 self.descriptions,
                                 self.verbosity,
                                 marionette=self.marionette,
-                                b2g_pid=self.b2g_pid,
                                 logger=self.logger,
                                 result_callbacks=self.result_callbacks)
 
     def run(self, test):
-        "Run the given test case or test suite."
-        for pre_run_func in self.pre_run_functions:
-            pre_run_func()
-
         result = super(MarionetteTextTestRunner, self).run(test)
         result.printLogs(test)
         return result
 
 
 class BaseMarionetteArguments(ArgumentParser):
     socket_timeout_default = 360.0
 
@@ -314,19 +291,16 @@ class BaseMarionetteArguments(ArgumentPa
                         help="addon to install; repeat for multiple addons.")
         self.add_argument('--repeat',
                         type=int,
                         default=0,
                         help='number of times to repeat the test(s)')
         self.add_argument('--testvars',
                         action='append',
                         help='path to a json file with any test data required')
-        self.add_argument('--tree',
-                        default='b2g',
-                        help='the tree that the revision parameter refers to')
         self.add_argument('--symbols-path',
                         help='absolute path to directory containing breakpad symbols, or the url of a zip file containing symbols')
         self.add_argument('--timeout',
                         type=int,
                         help='if a --timeout value is given, it will set the default page load timeout, search timeout and script timeout to the given value. If not passed in, it will use the default values of 30000ms for page load, 0ms for search timeout and 10000ms for script timeout')
         self.add_argument('--startup-timeout',
                         type=int,
                         default=60,
@@ -476,17 +450,17 @@ class BaseMarionetteArguments(ArgumentPa
 class BaseMarionetteTestRunner(object):
 
     textrunnerclass = MarionetteTextTestRunner
     driverclass = Marionette
 
     def __init__(self, address=None,
                  app=None, app_args=None, binary=None, profile=None,
                  logger=None, logdir=None,
-                 repeat=0, testvars=None, tree=None,
+                 repeat=0, testvars=None,
                  symbols_path=None, timeout=None,
                  shuffle=False, shuffle_seed=random.randint(0, sys.maxint),
                  sdcard=None, this_chunk=1, total_chunks=1, sources=None,
                  server_root=None, gecko_log=None, result_callbacks=None,
                  prefs=None, test_tags=None,
                  socket_timeout=BaseMarionetteArguments.socket_timeout_default,
                  startup_timeout=None, addons=None, workspace=None,
                  verbose=0, e10s=True, **kwargs):
@@ -497,17 +471,16 @@ class BaseMarionetteTestRunner(object):
         self.profile = profile
         self.addons = addons
         self.logger = logger
         self.httpd = None
         self.marionette = None
         self.logdir = logdir
         self.repeat = repeat
         self.test_kwargs = kwargs
-        self.tree = tree
         self.symbols_path = symbols_path
         self.timeout = timeout
         self.socket_timeout = socket_timeout
         self._device = None
         self._capabilities = None
         self._appinfo = None
         self._appName = None
         self.shuffle = shuffle
@@ -800,25 +773,16 @@ setReq.onerror = function() {
                 self.start_httpd(need_external_ip)
                 self.marionette.baseurl = self.httpd.get_url()
                 self.logger.info("running httpd on %s" % self.marionette.baseurl)
             else:
                 self.marionette.baseurl = self.server_root
                 self.logger.info("using remote content from %s" % self.marionette.baseurl)
 
         device_info = None
-        if self.capabilities['device'] != 'desktop' and self.capabilities['browserName'] == 'B2G':
-            dm = get_dm(self.marionette)
-            device_info = dm.getInfo()
-            # Add Android version (SDK level) to mozinfo so that manifest entries
-            # can be conditional on android_version.
-            androidVersion = dm.shellCheckOutput(['getprop', 'ro.build.version.sdk'])
-            self.logger.info(
-                "Android sdk version '%s'; will use this to filter manifests" % androidVersion)
-            mozinfo.info['android_version'] = androidVersion
 
         for test in tests:
             self.add_test(test)
 
         # ensure we have only tests files with names starting with 'test_'
         invalid_tests = \
             [t['filepath'] for t in self.tests
              if not os.path.basename(t['filepath']).startswith('test_')]
@@ -925,17 +889,16 @@ setReq.onerror = function() {
             for root, dirs, files in os.walk(filepath):
                 for filename in files:
                     if (filename.startswith('test_') and
                         (filename.endswith('.py') or filename.endswith('.js'))):
                         filepath = os.path.join(root, filename)
                         self.add_test(filepath)
             return
 
-        testarg_b2g = mozinfo.info.get('appname') == 'b2g'
 
         file_ext = os.path.splitext(os.path.split(filepath)[-1])[1]
 
         if file_ext == '.ini':
             manifest = TestManifest()
             manifest.read(filepath)
 
             filters = []
@@ -963,21 +926,16 @@ setReq.onerror = function() {
                     target_tests.append(test)
 
             for i in target_tests:
                 if not os.path.exists(i["path"]):
                     raise IOError("test file: %s does not exist" % i["path"])
 
                 file_ext = os.path.splitext(os.path.split(i['path'])[-1])[-1]
                 test_container = None
-                if i.get('test_container') and testarg_b2g:
-                    if i.get('test_container') == "true":
-                        test_container = True
-                    elif i.get('test_container') == "false":
-                        test_container = False
 
                 self.add_test(i["path"], i["expected"], test_container)
             return
 
         self.tests.append({'filepath': filepath, 'expected': expected, 'test_container': test_container})
 
     def run_test(self, filepath, expected, test_container):
 
--- a/testing/marionette/harness/marionette/runner/mixins/__init__.py
+++ b/testing/marionette/harness/marionette/runner/mixins/__init__.py
@@ -9,14 +9,13 @@ from .endurance import (
 )
 
 from .reporting import (
     HTMLReportingArguments,
     HTMLReportingTestResultMixin,
     HTMLReportingTestRunnerMixin,
 )
 
-from .b2g import B2GTestCaseMixin, B2GTestResultMixin
 from .browsermob import (
     BrowserMobProxyTestCaseMixin,
     BrowserMobProxyArguments,
     BrowserMobTestCase,
 )
deleted file mode 100644
--- a/testing/marionette/harness/marionette/runner/mixins/b2g.py
+++ /dev/null
@@ -1,125 +0,0 @@
-# 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/.
-
-import mozdevice
-import os
-import re
-
-
-def get_dm(marionette=None, **kwargs):
-    dm_type = os.environ.get('DM_TRANS', 'adb')
-    if marionette and hasattr(marionette.runner, 'device'):
-        return marionette.runner.app_ctx.dm
-    else:
-        if dm_type == 'adb':
-            return mozdevice.DeviceManagerADB(deviceSerial=marionette.device_serial,
-                                              serverHost=marionette.adb_host,
-                                              serverPort=marionette.adb_port,
-                                              **kwargs)
-        elif dm_type == 'sut':
-            host = os.environ.get('TEST_DEVICE')
-            if not host:
-                raise Exception('Must specify host with SUT!')
-            return mozdevice.DeviceManagerSUT(host=host)
-        else:
-            raise Exception('Unknown device manager type: %s' % dm_type)
-
-
-def get_b2g_pid(dm):
-    b2g_output = dm.shellCheckOutput(['b2g-ps']).split('\n')
-    first_line = b2g_output[0].split()
-    app_index = first_line.index('APPLICATION')
-    pid_index = first_line.index('PID')
-    for line in b2g_output:
-        split_line = line.split()
-        if split_line[app_index] == 'b2g':
-            return split_line[pid_index]
-
-
-class B2GTestCaseMixin(object):
-
-    # TODO: add methods like 'restart b2g'
-    def __init__(self, *args, **kwargs):
-        self._device_manager = None
-
-    def get_device_manager(self, *args, **kwargs):
-        capabilities = self.marionette.session and \
-            self.marionette.session_capabilities or {}
-        if not self._device_manager and \
-                capabilities.get('device') != 'desktop':
-            self._device_manager = get_dm(self.marionette, **kwargs)
-        return self._device_manager
-
-    @property
-    def device_manager(self):
-        return self.get_device_manager()
-
-
-class B2GTestResultMixin(object):
-
-    def __init__(self, *args, **kwargs):
-        self.result_modifiers.append(self.b2g_output_modifier)
-        self.b2g_pid = kwargs.pop('b2g_pid')
-        self.logcat_stdout = kwargs.pop('logcat_stdout')
-
-    def _diagnose_socket(self):
-        # This function will check if b2g is running and report any recent errors. This is
-        # used in automation since a plain timeout error doesn't tell you
-        # much information about what actually is going on
-
-        extra_output = None
-        dm_type = os.environ.get('DM_TRANS', 'adb')
-        if dm_type == 'adb':
-            device_manager = get_dm(self.marionette)
-            pid = get_b2g_pid(device_manager)
-            if pid:
-                # find recent errors
-                message = ""
-                error_re = re.compile(r"""[\s\S]*(exception|error)[\s\S]*""",
-                                      flags=re.IGNORECASE)
-                logcat = device_manager.getLogcat()
-                # Due to Bug 1050211
-                if len(logcat) == 1:
-                    logcat = logcat[0].splitlines()
-                latest = []
-                iters = len(logcat) - 1
-                # reading from the latest line
-                while len(latest) < 5 and iters >= 0:
-                    line = logcat[iters]
-                    error_log_line = error_re.match(line)
-                    if error_log_line is not None:
-                        latest.append(line)
-                    iters -= 1
-                message += "\nMost recent errors/exceptions are:\n"
-                for line in reversed(latest):
-                    message += "%s" % line
-                b2g_status = ""
-                if pid != self.b2g_pid:
-                    b2g_status = "The B2G process has restarted after crashing during  the tests so "
-                else:
-                    b2g_status = "B2G is still running but "
-                extra_output = ("%s\n%sMarionette can't respond due to either a Gecko, Gaia or Marionette error. "
-                                "Above, the 5 most recent errors are listed. "
-                                "Check logcat for all errors if these errors are not the cause "
-                                "of the failure." % (message, b2g_status))
-            else:
-                extra_output = "B2G process has died"
-        return extra_output
-
-    def b2g_output_modifier(self, test, result_expected, result_actual, output, context):
-        # output is the actual string output from the test, so we have to do string comparison
-        if "IOError" in output or "Broken pipe" in output or "Connection timed out" in output:
-            extra_output = self._diagnose_socket()
-            if extra_output:
-                self.logger.error(extra_output)
-                output += extra_output
-
-        if self.logcat_stdout:
-            dm = get_dm(self.marionette)
-            for next_line in dm.getLogcat():
-                self.logger.info(next_line)
-            self.logger.info("--------- end logcat")
-            dm.shellCheckOutput(['/system/bin/logcat', '-c'])
-
-        return result_expected, result_actual, output, context