Merge mozilla-central to inbound. a=merge
authorCoroiu Cristina <ccoroiu@mozilla.com>
Thu, 18 Jan 2018 10:54:04 +0200
changeset 454115 cdfc5335df1578bea4c58533913b9ba41421634c
parent 454114 7d9ba3d649624ea9ab78fed37c2d5686135ea640 (current diff)
parent 454074 f095d500e45453ae318c26097dc2258bdf48d084 (diff)
child 454116 7bc2219779f7bec698834234797b09fd16db1051
push id1648
push usermtabara@mozilla.com
push dateThu, 01 Mar 2018 12:45:47 +0000
treeherdermozilla-release@cbb9688c2eeb [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmerge
milestone59.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
Merge mozilla-central to inbound. a=merge
--- a/testing/marionette/client/marionette_driver/geckoinstance.py
+++ b/testing/marionette/client/marionette_driver/geckoinstance.py
@@ -11,18 +11,16 @@ import traceback
 from copy import deepcopy
 
 import mozversion
 
 from mozdevice import DMError
 from mozprofile import Profile
 from mozrunner import Runner, FennecEmulatorRunner
 
-import errors
-
 
 class GeckoInstance(object):
     required_prefs = {
         # Increase the APZ content response timeout in tests to 1 minute.
         # This is to accommodate the fact that test environments tends to be slower
         # than production environments (with the b2g emulator being the slowest of them
         # all), resulting in the production timeout value sometimes being exceeded
         # and causing false-positive test failures. See bug 1176798, bug 1177018,
@@ -121,34 +119,37 @@ class GeckoInstance(object):
         self.runner_class = Runner
         self.app_args = app_args or []
         self.runner = None
         self.symbols_path = symbols_path
         self.binary = bin
 
         self.marionette_host = host
         self.marionette_port = port
+        # Alternative to default temporary directory
+        self.workspace = workspace
         self.addons = addons
+        # Check if it is a Profile object or a path to profile
+        self.profile = None
+        if isinstance(profile, Profile):
+            self.profile = profile
+        else:
+            self.profile_path = profile
         self.prefs = prefs
         self.required_prefs = deepcopy(self.required_prefs)
         if prefs:
             self.required_prefs.update(prefs)
 
         self._gecko_log_option = gecko_log
         self._gecko_log = None
         self.verbose = verbose
         self.headless = headless
-
         # keep track of errors to decide whether instance is unresponsive
         self.unresponsive_count = 0
 
-        # Alternative to default temporary directory
-        self.workspace = workspace
-        self.profile = profile
-
     @property
     def gecko_log(self):
         if self._gecko_log:
             return self._gecko_log
 
         path = self._gecko_log_option
         if path != "-":
             if path is None:
@@ -159,97 +160,52 @@ class GeckoInstance(object):
 
             path = os.path.realpath(path)
             if os.access(path, os.F_OK):
                 os.remove(path)
 
         self._gecko_log = path
         return self._gecko_log
 
-    @property
-    def profile(self):
-        return self._profile
-
-    @profile.setter
-    def profile(self, value):
-        self._update_profile(value)
-
-    def _update_profile(self, profile=None, profile_name=None):
-        """Check if the profile has to be created, or replaced
-
-        :param profile: A Profile instance to be used.
-        :param name: Profile name to be used in the path.
-        """
-        if self.runner and self.runner.is_running():
-            raise errors.MarionetteException("The used profile can only be updated "
-                                             "when the instance is not running")
-
-        if isinstance(profile, Profile):
-            # Only replace the profile if it is not the current one
-            if hasattr(self, "_profile") and profile is self._profile:
-                return
-
-        else:
-            profile_args = self.profile_args
-            profile_path = profile
-
-            # If a path to a profile is given then clone it
-            if isinstance(profile_path, basestring):
-                profile_args["path_from"] = profile_path
-                profile_args["path_to"] = tempfile.mkdtemp(
-                    suffix=".{}".format(profile_name or os.path.basename(profile_path)),
-                    dir=self.workspace)
-                # The target must not exist yet
-                os.rmdir(profile_args["path_to"])
-
-                profile = Profile.clone(**profile_args)
-
-            # Otherwise create a new profile
-            else:
-                profile_args["profile"] = tempfile.mkdtemp(
-                    suffix=".{}".format(profile_name or "mozrunner"),
-                    dir=self.workspace)
-                profile = Profile(**profile_args)
-                profile.create_new = True
-
-        if hasattr(self, "_profile") and self._profile:
-            self._profile.cleanup()
-        self._profile = profile
-
-    def switch_profile(self, profile_name=None, clone_from=None):
-        if isinstance(clone_from, Profile):
-            clone_from = clone_from.profile
-
-        self._update_profile(clone_from, profile_name=profile_name)
-
-    @property
-    def profile_args(self):
-        args = {"preferences": deepcopy(self.required_prefs)}
-        args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port
-
+    def _update_profile(self):
+        profile_args = {"preferences": deepcopy(self.required_prefs)}
+        profile_args["preferences"]["marionette.defaultPrefs.port"] = self.marionette_port
         if self.prefs:
-            args["preferences"].update(self.prefs)
-
+            profile_args["preferences"].update(self.prefs)
         if self.verbose:
             level = "TRACE" if self.verbose >= 2 else "DEBUG"
-            args["preferences"]["marionette.logging"] = level
-
+            profile_args["preferences"]["marionette.logging"] = level
         if "-jsdebugger" in self.app_args:
-            args["preferences"].update({
+            profile_args["preferences"].update({
                 "devtools.browsertoolbox.panel": "jsdebugger",
                 "devtools.debugger.remote-enabled": True,
                 "devtools.chrome.enabled": True,
                 "devtools.debugger.prompt-connection": False,
                 "marionette.debugging.clicktostart": True,
             })
+        if self.addons:
+            profile_args["addons"] = self.addons
 
-        if self.addons:
-            args["addons"] = self.addons
-
-        return args
+        if hasattr(self, "profile_path") and self.profile is None:
+            if not self.profile_path:
+                if self.workspace:
+                    profile_args["profile"] = tempfile.mkdtemp(
+                        suffix=".mozrunner-{:.0f}".format(time.time()),
+                        dir=self.workspace)
+                self.profile = Profile(**profile_args)
+            else:
+                profile_args["path_from"] = self.profile_path
+                profile_name = "{}-{:.0f}".format(
+                    os.path.basename(self.profile_path),
+                    time.time()
+                )
+                if self.workspace:
+                    profile_args["path_to"] = os.path.join(self.workspace,
+                                                           profile_name)
+                self.profile = Profile.clone(**profile_args)
 
     @classmethod
     def create(cls, app=None, *args, **kwargs):
         try:
             if not app and kwargs["bin"] is not None:
                 app_id = mozversion.get_version(binary=kwargs["bin"])["application_id"]
                 app = app_ids[app_id]
 
@@ -257,17 +213,17 @@ class GeckoInstance(object):
         except (IOError, KeyError):
             exc, val, tb = sys.exc_info()
             msg = 'Application "{0}" unknown (should be one of {1})'
             raise NotImplementedError, msg.format(app, apps.keys()), tb
 
         return instance_class(*args, **kwargs)
 
     def start(self):
-        self._update_profile(self.profile)
+        self._update_profile()
         self.runner = self.runner_class(**self._get_runner_args())
         self.runner.start()
 
     def _get_runner_args(self):
         process_args = {
             "processOutputLine": [NullOutput()],
         }
 
@@ -318,22 +274,22 @@ class GeckoInstance(object):
 
     def restart(self, prefs=None, clean=True):
         """
         Close then start the managed Gecko process.
 
         :param prefs: Dictionary of preference names and values.
         :param clean: If True, reset the profile before starting.
         """
+        self.close(clean=clean)
+
         if prefs:
             self.prefs = prefs
         else:
             self.prefs = None
-
-        self.close(clean=clean)
         self.start()
 
 
 class FennecInstance(GeckoInstance):
     fennec_prefs = {
         # Enable output of dump()
         "browser.dom.window.dump.enabled": True,
 
@@ -386,17 +342,17 @@ class FennecInstance(GeckoInstance):
         if self._package_name is None:
             self._package_name = "org.mozilla.fennec"
             user = os.getenv("USER")
             if user:
                 self._package_name += "_" + user
         return self._package_name
 
     def start(self):
-        self._update_profile(self.profile)
+        self._update_profile()
         self.runner = self.runner_class(**self._get_runner_args())
         try:
             if self.connect_to_running_emulator:
                 self.runner.device.connect()
             self.runner.start()
         except Exception as e:
             exc, val, tb = sys.exc_info()
             message = "Error possibly due to runner or device args: {}"
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_prefs.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_prefs.py
@@ -160,43 +160,8 @@ class TestPreferences(MarionetteTestCase
         try:
             with self.marionette.using_prefs({self.prefs["string"]: "def"}):
                 self.assertEquals(self.marionette.get_pref(self.prefs["string"]), "def")
                 self.marionette.execute_script("return foo.bar.baz;")
         except JavascriptException:
             pass
 
         self.assertEquals(self.marionette.get_pref(self.prefs["string"]), "abc")
-
-
-class TestEnforcePreferences(MarionetteTestCase):
-
-    def setUp(self):
-        super(TestEnforcePreferences, self).setUp()
-
-        self.marionette.enforce_gecko_prefs({
-            "marionette.test.bool": True,
-            "marionette.test.int": 3,
-            "marionette.test.string": "testing",
-        })
-        self.marionette.set_context("chrome")
-
-    def tearDown(self):
-        self.marionette.quit(clean=True)
-
-        super(TestEnforcePreferences, self).tearDown()
-
-    def test_preferences_are_set(self):
-        self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
-        self.assertEqual(self.marionette.get_pref("marionette.test.string"), "testing")
-        self.assertEqual(self.marionette.get_pref("marionette.test.int"), 3)
-
-    def test_change_preference(self):
-        self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
-
-        self.marionette.enforce_gecko_prefs({"marionette.test.bool": False})
-
-        self.assertFalse(self.marionette.get_pref("marionette.test.bool"))
-
-    def test_restart_with_clean_profile(self):
-        self.marionette.restart(clean=True)
-
-        self.assertEqual(self.marionette.get_pref("marionette.test.bool"), None)
--- a/testing/marionette/harness/marionette_harness/tests/unit/test_profile_management.py
+++ b/testing/marionette/harness/marionette_harness/tests/unit/test_profile_management.py
@@ -1,198 +1,34 @@
 # 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 os
-import shutil
-import tempfile
-
-import mozprofile
-
 from marionette_harness import MarionetteTestCase
 
 
-class BaseProfileManagement(MarionetteTestCase):
-
-    def setUp(self):
-        super(BaseProfileManagement, self).setUp()
-
-        self.orig_profile_path = self.profile_path
-
-        # Create external profile and mark it as not-removable
-        tmp_dir = tempfile.mkdtemp(suffix="external")
-        shutil.rmtree(tmp_dir, ignore_errors=True)
-
-        self.external_profile = mozprofile.Profile(profile=tmp_dir)
-        self.external_profile.create_new = False
-
-    def tearDown(self):
-        shutil.rmtree(self.external_profile.profile, ignore_errors=True)
-
-        self.marionette.profile = None
-
-        super(BaseProfileManagement, self).tearDown()
-
-    @property
-    def profile(self):
-        return self.marionette.instance.profile
-
-    @property
-    def profile_path(self):
-        return self.marionette.instance.profile.profile
-
-
-class WorkspaceProfileManagement(BaseProfileManagement):
+class TestProfileManagement(MarionetteTestCase):
 
     def setUp(self):
-        super(WorkspaceProfileManagement, self).setUp()
-
-        self.workspace = tempfile.mkdtemp()
-        self.marionette.instance.workspace = self.workspace
-
-    def tearDown(self):
-        self.marionette.instance.workspace = None
-
-        shutil.rmtree(self.workspace, ignore_errors=True)
-
-        super(WorkspaceProfileManagement, self).tearDown()
-
-
-class TestQuitRestartWithoutWorkspace(BaseProfileManagement):
+        MarionetteTestCase.setUp(self)
+        self.marionette.enforce_gecko_prefs(
+            {"marionette.test.bool": True,
+             "marionette.test.string": "testing",
+             "marionette.test.int": 3
+             })
+        self.marionette.set_context("chrome")
 
-    def test_quit_keeps_same_profile(self):
-        self.marionette.quit()
-        self.marionette.start_session()
-
-        self.assertEqual(self.profile_path, self.orig_profile_path)
-        self.assertTrue(os.path.exists(self.orig_profile_path))
-
-    def test_quit_clean_creates_new_profile(self):
-        self.marionette.quit(clean=True)
-        self.marionette.start_session()
+    def test_preferences_are_set(self):
+        self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
+        self.assertEqual(self.marionette.get_pref("marionette.test.string"), "testing")
+        self.assertEqual(self.marionette.get_pref("marionette.test.int"), 3)
 
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
+    def test_change_preference(self):
+        self.assertTrue(self.marionette.get_pref("marionette.test.bool"))
 
-    def test_restart_keeps_same_profile(self):
-        self.marionette.restart()
+        self.marionette.enforce_gecko_prefs({"marionette.test.bool": False})
 
-        self.assertEqual(self.profile_path, self.orig_profile_path)
-        self.assertTrue(os.path.exists(self.orig_profile_path))
+        self.assertFalse(self.marionette.get_pref("marionette.test.bool"))
 
-    def test_restart_clean_creates_new_profile(self):
+    def test_clean_profile(self):
         self.marionette.restart(clean=True)
 
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-
-class TestQuitRestartWithWorkspace(WorkspaceProfileManagement):
-
-    def test_quit_keeps_same_profile(self):
-        self.marionette.quit()
-        self.marionette.start_session()
-
-        self.assertEqual(self.profile_path, self.orig_profile_path)
-        self.assertNotIn(self.workspace, self.profile_path)
-        self.assertTrue(os.path.exists(self.orig_profile_path))
-
-    def test_quit_clean_creates_new_profile(self):
-        self.marionette.quit(clean=True)
-        self.marionette.start_session()
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertIn(self.workspace, self.profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-    def test_restart_keeps_same_profile(self):
-        self.marionette.restart()
-
-        self.assertEqual(self.profile_path, self.orig_profile_path)
-        self.assertNotIn(self.workspace, self.profile_path)
-        self.assertTrue(os.path.exists(self.orig_profile_path))
-
-    def test_restart_clean_creates_new_profile(self):
-        self.marionette.restart(clean=True)
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertIn(self.workspace, self.profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-
-class TestSwitchProfileWithoutWorkspace(BaseProfileManagement):
-
-    def setUp(self):
-        super(TestSwitchProfileWithoutWorkspace, self).setUp()
-
-        self.marionette.quit()
-
-    def tearDown(self):
-        super(TestSwitchProfileWithoutWorkspace, self).tearDown()
-
-    def test_new_random_profile_name(self):
-        self.marionette.instance.switch_profile()
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-    def test_new_named_profile(self):
-        self.marionette.instance.switch_profile("foobar")
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertIn("foobar", self.profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-    def test_clone_existing_profile(self):
-        self.marionette.instance.switch_profile(clone_from=self.external_profile)
-
-        self.assertIn(os.path.basename(self.external_profile.profile), self.profile_path)
-        self.assertTrue(os.path.exists(self.external_profile.profile))
-
-    def test_replace_with_current_profile(self):
-        self.marionette.instance.profile = self.profile
-
-        self.assertEqual(self.profile_path, self.orig_profile_path)
-        self.assertTrue(os.path.exists(self.orig_profile_path))
-
-    def test_replace_with_external_profile(self):
-        self.marionette.instance.profile = self.external_profile
-
-        self.assertEqual(self.profile_path, self.external_profile.profile)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-        # Set a new profile and ensure the external profile has not been deleted
-        self.marionette.instance.profile = None
-
-        self.assertNotEqual(self.profile_path, self.external_profile.profile)
-        self.assertTrue(os.path.exists(self.external_profile.profile))
-
-
-class TestSwitchProfileWithWorkspace(WorkspaceProfileManagement):
-
-    def setUp(self):
-        super(TestSwitchProfileWithWorkspace, self).setUp()
-
-        self.marionette.quit()
-
-    def test_new_random_profile_name(self):
-        self.marionette.instance.switch_profile()
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertIn(self.workspace, self.profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-    def test_new_named_profile(self):
-        self.marionette.instance.switch_profile("foobar")
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertIn("foobar", self.profile_path)
-        self.assertIn(self.workspace, self.profile_path)
-        self.assertFalse(os.path.exists(self.orig_profile_path))
-
-    def test_clone_existing_profile(self):
-        self.marionette.instance.switch_profile(clone_from=self.external_profile)
-
-        self.assertNotEqual(self.profile_path, self.orig_profile_path)
-        self.assertIn(self.workspace, self.profile_path)
-        self.assertIn(os.path.basename(self.external_profile.profile), self.profile_path)
-        self.assertTrue(os.path.exists(self.external_profile.profile))
+        self.assertEqual(self.marionette.get_pref("marionette.test.bool"), None)