Bug 1368195 - Make it possible to test e10s state in MnH; r?maja_zf draft
authorAndreas Tolfsen <ato@mozilla.com>
Thu, 08 Jun 2017 13:03:54 +0100
changeset 590945 d5d496d81fa34b5cf326a908b7f8ab642217dd77
parent 590944 217570d12e8b0352863428fdba22507761d7ed20
child 632376 4f4a809a88c0df6c3c2a9b2d99249e2a27890548
push id62905
push userbmo:ato@mozilla.com
push dateThu, 08 Jun 2017 12:05:06 +0000
reviewersmaja_zf
bugs1368195
milestone55.0a1
Bug 1368195 - Make it possible to test e10s state in MnH; r?maja_zf The previous commit removed BaseMarionetteTestRunner.appinfo which a Marionette harness test relied upon to verify that the harness threw an assertion when the Firefox instance did not match the desired e10s configuration. To circumvent this problem, this patch introducs a _e10s_from_browser state that is populated when querying the browser about its e10s state. We can use this in the same manner as appinfo by modifying the property before running the test. MozReview-Commit-ID: H8vPAjzJMeA
testing/marionette/harness/marionette_harness/runner/base.py
testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py
--- a/testing/marionette/harness/marionette_harness/runner/base.py
+++ b/testing/marionette/harness/marionette_harness/runner/base.py
@@ -548,22 +548,27 @@ class BaseMarionetteTestRunner(object):
         self.test_tags = test_tags
         self.startup_timeout = startup_timeout
         self.workspace = workspace
         # If no workspace is set, default location for gecko.log is .
         # and default location for profile is TMP
         self.workspace_path = workspace or os.getcwd()
         self.verbose = verbose
         self.headless = headless
+
+        # self.e10s stores the desired configuration, whereas
+        # self._e10s_from_browser is the cached value from querying e10s
+        # in self.is_e10s
         self.e10s = e10s
+        self._e10s_from_browser = None
         if self.e10s:
             self.prefs.update({
                 'browser.tabs.remote.autostart': True,
                 'browser.tabs.remote.force-enable': True,
-                'extensions.e10sBlocksEnabling': False
+                'extensions.e10sBlocksEnabling': False,
             })
 
         def gather_debug(test, status):
             # No screenshots and page source for skipped tests
             if status == "SKIP":
                 return
 
             rv = {}
@@ -796,16 +801,31 @@ class BaseMarionetteTestRunner(object):
         for test in self.manifest_skipped_tests:
             name = os.path.basename(test['path'])
             self.logger.test_start(name)
             self.logger.test_end(name,
                                  'SKIP',
                                  message=test['disabled'])
             self.todo += 1
 
+    @property
+    def is_e10s(self):
+        """Query the browser on whether E10s (Electrolysis) is enabled."""
+        if self._e10s_from_browser is not None:
+            return self._e10s_from_browser
+
+        if self.marionette is None or self.marionette.session is None:
+            raise Exception("No Marionette session to query e10s state")
+
+        with self.marionette.using_context("chrome"):
+            self._e10s_from_browser = self.marionette.execute_script(
+                "return Services.appinfo.browserTabsRemoteAutostart")
+
+        return self.is_e10s
+
     def run_tests(self, tests):
         start_time = time.time()
         self._initialize_test_run(tests)
 
         if self.marionette is None:
             self.marionette = self.driverclass(**self._build_kwargs())
             self.logger.info("Profile path is %s" % self.marionette.profile_path)
 
@@ -824,27 +844,26 @@ class BaseMarionetteTestRunner(object):
         device_info = None
         if self.marionette.instance and self.emulator:
             try:
                 device_info = self.marionette.instance.runner.device.dm.getInfo()
             except Exception:
                 self.logger.warning('Could not get device info', exc_info=True)
 
         self.marionette.start_session()
-        with self.marionette.using_context("chrome"):
-            appinfo_e10s = self.marionette.execute_script(
-                "return Services.appinfo.browserTabsRemoteAutostart")
+
         self.marionette.delete_session()
 
-        self.logger.info("e10s is {}".format("enabled" if appinfo_e10s else "disabled"))
-        if self.e10s != appinfo_e10s:
-            message_e10s = ("BaseMarionetteTestRunner configuration (self.e10s) does "
-                            "not match browser appinfo")
+        self.logger.info("e10s is {}".format("enabled" if self.is_e10s else "disabled"))
+        print "self.is_e10s=%s" % self.is_e10s
+        print "self.e10s=%s" % self.e10s
+        if self.e10s != self.is_e10s:
             self.cleanup()
-            raise AssertionError(message_e10s)
+            raise AssertionError("BaseMarionetteTestRunner configuration (self.e10s) "
+                "does not match browser appinfo (self.is_e10s)")
 
         tests_by_group = defaultdict(list)
         for test in self.tests:
             tests_by_group[test['group']].append(test['filepath'])
 
         self.logger.suite_start(tests_by_group,
                                 version_info=self.version_info,
                                 device_info=device_info)
--- a/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py
+++ b/testing/marionette/harness/marionette_harness/tests/harness_unit/test_marionette_runner.py
@@ -1,17 +1,18 @@
 # 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 manifestparser
 import pytest
 
-from mock import Mock, patch, mock_open, sentinel, DEFAULT
+from mock import MagicMock, Mock, patch, mock_open, sentinel, DEFAULT
 
+from marionette_driver.marionette import Marionette
 from marionette_harness.runtests import MarionetteTestRunner
 
 
 @pytest.fixture
 def runner(mach_parsed_kwargs):
     """
     MarionetteTestRunner instance initialized with default options.
     """
@@ -25,17 +26,17 @@ def mock_runner(runner, mock_marionette,
     self.marionette and other properties,
     to enable testing runner.run_tests().
     """
     runner.driverclass = mock_marionette
     for attr in ['run_test_set', '_capabilities']:
         setattr(runner, attr, Mock())
     runner._appName = 'fake_app'
     # simulate that browser runs with e10s by default
-    runner._appinfo = {'browserTabsRemoteAutostart': True}
+    runner._e10s_from_browser = True
     monkeypatch.setattr('marionette_harness.runner.base.mozversion', Mock())
     return runner
 
 
 @pytest.fixture
 def build_kwargs_using(mach_parsed_kwargs):
     '''Helper function for test_build_kwargs_* functions'''
     def kwarg_builder(new_items, return_socket=False):
@@ -427,17 +428,18 @@ def test_e10s_option_sets_prefs(mach_par
         'extensions.e10sBlocksEnabling': False
     }
     for k,v in e10s_prefs.iteritems():
         if k == 'extensions.e10sBlocksEnabling' and not e10s:
             continue
         assert runner.prefs.get(k, False) == (v and e10s)
 
 def test_e10s_option_clash_raises(mock_runner):
-    mock_runner.e10s = False
+    mock_runner._e10s_from_browser = False
+
     with pytest.raises(AssertionError) as e:
         mock_runner.run_tests([u'test_fake_thing.py'])
         assert "configuration (self.e10s) does not match browser appinfo" in e.value.message
 
 if __name__ == '__main__':
     import sys
     sys.exit(pytest.main(
         ['--log-tbpl=-', __file__]))