Bug 1458571 - Use base testing/profiles in talos, r?rwood draft
authorAndrew Halberstadt <ahalberstadt@mozilla.com>
Wed, 09 May 2018 15:06:53 -0400
changeset 794165 9b5c0274098f115035d3bcd54e810b6490a225e5
parent 794135 21f09d7e7214eaebf1e0980494159bd846e1bdd9
child 794166 151b8ac8e37b9e11c523f667a5262aaf7351c075
push id109588
push userahalberstadt@mozilla.com
push dateFri, 11 May 2018 13:03:42 +0000
reviewersrwood
bugs1458571
milestone62.0a1
Bug 1458571 - Use base testing/profiles in talos, r?rwood This moves all of the global prefs that were previously defined in testing/talos/talos/config.py, into a new "perf" profile under testing/profiles/perf/user.js. This perf profile will be shared with raptor, so changes to one framework will result in changes to the other. MozReview-Commit-ID: JRxZEDlPu6b
python/mozbuild/mozbuild/action/test_archive.py
testing/profiles/moz.build
testing/profiles/perf/extensions/README.txt
testing/profiles/perf/user.js
testing/profiles/profiles.json
testing/talos/talos/config.py
testing/talos/talos/ffsetup.py
--- a/python/mozbuild/mozbuild/action/test_archive.py
+++ b/python/mozbuild/mozbuild/action/test_archive.py
@@ -396,16 +396,22 @@ ARCHIVE_FILES = {
     'talos': [
         {
             'source': buildconfig.topsrcdir,
             'base': 'testing',
             'pattern': 'talos/**',
         },
         {
             'source': buildconfig.topsrcdir,
+            'base': 'testing/profiles',
+            'pattern': '**',
+            'dest': 'talos/talos/profile_data',
+        },
+        {
+            'source': buildconfig.topsrcdir,
             'base': 'third_party/webkit/PerformanceTests',
             'pattern': '**',
             'dest': 'talos/talos/tests/webkit/PerformanceTests/',
         },
     ],
     'raptor': [
         {
             'source': buildconfig.topsrcdir,
--- a/testing/profiles/moz.build
+++ b/testing/profiles/moz.build
@@ -1,16 +1,17 @@
 # -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 profile_files = [
     'common/*',
+    'perf/*',
     'profiles.json',
 ]
 
 TEST_HARNESS_FILES.testing.mochitest.profile_data += profile_files
 TEST_HARNESS_FILES['web-platform'].prefs += profile_files
 
 with Files("**"):
     BUG_COMPONENT = ("Testing", "General")
new file mode 100644
--- /dev/null
+++ b/testing/profiles/perf/extensions/README.txt
@@ -0,0 +1,2 @@
+Dropping extensions here will get them installed in all test harnesses
+that make use of this profile.
new file mode 100644
--- /dev/null
+++ b/testing/profiles/perf/user.js
@@ -0,0 +1,108 @@
+// Base preferences file used by performance harnesses
+/* globals user_pref */
+user_pref("app.normandy.api_url", "https://127.0.0.1/selfsupport-dummy/");
+user_pref("app.update.enabled", false);
+user_pref("browser.EULA.override", true);
+user_pref("browser.aboutHomeSnippets.updateUrl", "https://127.0.0.1/about-dummy/");
+user_pref("browser.addon-watch.interval", -1); // Deactivate add-on watching
+user_pref("browser.bookmarks.max_backups", 0);
+user_pref("browser.cache.disk.smart_size.enabled", false);
+user_pref("browser.cache.disk.smart_size.first_run", false);
+user_pref("browser.chrome.dynamictoolbar", false);
+user_pref("browser.contentHandlers.types.0.uri", "http://127.0.0.1/rss?url=%s");
+user_pref("browser.contentHandlers.types.1.uri", "http://127.0.0.1/rss?url=%s");
+user_pref("browser.contentHandlers.types.2.uri", "http://127.0.0.1/rss?url=%s");
+user_pref("browser.contentHandlers.types.3.uri", "http://127.0.0.1/rss?url=%s");
+user_pref("browser.contentHandlers.types.4.uri", "http://127.0.0.1/rss?url=%s");
+user_pref("browser.contentHandlers.types.5.uri", "http://127.0.0.1/rss?url=%s");
+user_pref("browser.dom.window.dump.enabled", true);
+user_pref("browser.link.open_newwindow", 2);
+user_pref("browser.newtabpage.activity-stream.default.sites", "");
+user_pref("browser.newtabpage.activity-stream.feeds.section.topstories", false);
+user_pref("browser.newtabpage.activity-stream.feeds.snippets", false);
+user_pref("browser.newtabpage.activity-stream.telemetry", false);
+user_pref("browser.newtabpage.activity-stream.tippyTop.service.endpoint", "");
+user_pref("browser.ping-centre.production.endpoint", "https://127.0.0.1/pingcentre/dummy/");
+user_pref("browser.ping-centre.staging.endpoint", "https://127.0.0.1/pingcentre/dummy/");
+user_pref("browser.reader.detectedFirstArticle", true);
+user_pref("browser.safebrowsing.blockedURIs.enabled", false);
+user_pref("browser.safebrowsing.downloads.enabled", false);
+user_pref("browser.safebrowsing.downloads.remote.url", "http://127.0.0.1/safebrowsing-dummy/downloads");
+user_pref("browser.safebrowsing.malware.enabled", false);
+user_pref("browser.safebrowsing.passwords.enabled", false);
+user_pref("browser.safebrowsing.phishing.enabled", false);
+user_pref("browser.safebrowsing.provider.google.gethashURL", "http://127.0.0.1/safebrowsing-dummy/gethash");
+user_pref("browser.safebrowsing.provider.google.updateURL", "http://127.0.0.1/safebrowsing-dummy/update");
+user_pref("browser.safebrowsing.provider.google4.gethashURL", "http://127.0.0.1/safebrowsing4-dummy/gethash");
+user_pref("browser.safebrowsing.provider.google4.updateURL", "http://127.0.0.1/safebrowsing4-dummy/update");
+user_pref("browser.safebrowsing.provider.mozilla.gethashURL", "http://127.0.0.1/safebrowsing-dummy/gethash");
+user_pref("browser.safebrowsing.provider.mozilla.updateURL", "http://127.0.0.1/safebrowsing-dummy/update");
+user_pref("browser.search.countryCode", "US");
+user_pref("browser.search.geoSpecificDefaults", false);
+user_pref("browser.search.geoip.url", "");
+user_pref("browser.search.isUS", true);
+user_pref("browser.shell.checkDefaultBrowser", false);
+user_pref("browser.snippets.enabled", false);
+user_pref("browser.snippets.syncPromo.enabled", false);
+user_pref("browser.tabs.remote.autostart", true);
+user_pref("browser.urlbar.userMadeSearchSuggestionsChoice", true);
+user_pref("browser.warnOnQuit", false);
+user_pref("browser.webapps.checkForUpdates", 0);
+user_pref("datareporting.healthreport.documentServerURI", "http://127.0.0.1/healthreport/");
+user_pref("datareporting.policy.dataSubmissionPolicyBypassNotification", true);
+user_pref("devtools.chrome.enabled", false);
+user_pref("devtools.debugger.remote-enabled", false);
+user_pref("devtools.theme", "light");
+user_pref("devtools.timeline.enabled", false);
+user_pref("dom.allow_scripts_to_close_windows", true);
+user_pref("dom.disable_open_during_load", false);
+user_pref("dom.disable_window_flip", true);
+user_pref("dom.disable_window_move_resize", true);
+user_pref("dom.max_chrome_script_run_time", 0);
+user_pref("dom.max_script_run_time", 0);
+user_pref("dom.send_after_paint_to_content", true);
+user_pref("extensions.autoDisableScopes", 10);
+user_pref("extensions.blocklist.enabled", false);
+user_pref("extensions.blocklist.url", "http://127.0.0.1/extensions-dummy/blocklistURL");
+user_pref("extensions.checkCompatibility", false);
+user_pref("extensions.enabledScopes", 5);
+user_pref("extensions.getAddons.get.url", "http://127.0.0.1/extensions-dummy/repositoryGetURL");
+user_pref("extensions.getAddons.getWithPerformance.url", "http://127.0.0.1/extensions-dummy/repositoryGetWithPerformanceURL");
+user_pref("extensions.getAddons.search.browseURL", "http://127.0.0.1/extensions-dummy/repositoryBrowseURL");
+user_pref("extensions.hotfix.url", "http://127.0.0.1/extensions-dummy/hotfixURL");
+user_pref("extensions.legacy.enabled", true);
+user_pref("extensions.systemAddon.update.url", "http://127.0.0.1/dummy-system-addons.xml");
+user_pref("extensions.update.background.url", "http://127.0.0.1/extensions-dummy/updateBackgroundURL");
+user_pref("extensions.update.enabled", false);
+user_pref("extensions.update.notifyUser", false);
+user_pref("extensions.update.url", "http://127.0.0.1/extensions-dummy/updateURL");
+user_pref("extensions.webservice.discoverURL", "http://127.0.0.1/extensions-dummy/discoveryURL");
+user_pref("general.useragent.updates.enabled", false);
+user_pref("hangmonitor.timeout", 0);
+user_pref("identity.fxaccounts.auth.uri", "https://127.0.0.1/fxa-dummy/");
+user_pref("identity.fxaccounts.migrateToDevEdition", false);
+user_pref("lightweightThemes.selectedThemeID", "");
+user_pref("media.capturestream_hints.enabled", true);
+user_pref("media.gmp-manager.updateEnabled", false);
+user_pref("media.gmp-manager.url", "http://127.0.0.1/gmpmanager-dummy/update.xml");
+user_pref("media.libavcodec.allow-obsolete", true);
+user_pref("media.navigator.enabled", true);
+user_pref("media.navigator.permission.disabled", true);
+user_pref("media.peerconnection.enabled", true);
+user_pref("network.http.speculative-parallel-limit", 0);
+user_pref("network.proxy.http", "localhost");
+user_pref("network.proxy.http_port", 80);
+user_pref("network.proxy.type", 1);
+user_pref("places.database.lastMaintenance", 2147483647); // Set places maintenance far in the future (the maximum time possible in an int32_t)
+user_pref("plugin.state.flash", 0);
+user_pref("plugins.flashBlock.enabled", false);
+user_pref("privacy.reduceTimerPrecision", false); // Bug 1445243 - reduces precision of tests
+user_pref("privacy.trackingprotection.annotate_channels", false);
+user_pref("privacy.trackingprotection.enabled", false);
+user_pref("privacy.trackingprotection.introURL", "http://127.0.0.1/trackingprotection/tour");
+user_pref("privacy.trackingprotection.pbmode.enabled", false);
+user_pref("security.enable_java", false);
+user_pref("security.fileuri.strict_origin_policy", false);
+user_pref("security.turn_off_all_security_so_that_viruses_can_take_over_this_computer", true);
+user_pref("toolkit.telemetry.server", "https://127.0.0.1/telemetry-dummy/");
+user_pref("xpinstall.signatures.required", false);
--- a/testing/profiles/profiles.json
+++ b/testing/profiles/profiles.json
@@ -1,6 +1,7 @@
 {
     "mochitest": ["common"],
     "profileserver": ["common"],
     "web-platform-tests": ["common"],
+    "talos": ["perf"],
     "valgrind": ["common"]
 }
--- a/testing/talos/talos/config.py
+++ b/testing/talos/talos/config.py
@@ -14,22 +14,16 @@ from mozlog.commandline import setup_log
 from talos import utils, test
 from talos.cmdline import parse_args
 
 
 class ConfigurationError(Exception):
     pass
 
 
-# Set places maintenance far in the future (the maximum time possible in an
-# int32_t) to avoid it kicking in during tests. The maintenance can take a
-# relatively long time which may cause unnecessary intermittents and slow
-# things down. This, like many things, will stop working correctly in 2038.
-FAR_IN_FUTURE = 2147483647
-
 DEFAULTS = dict(
     # args to pass to browser
     extra_args='',
     buildid='testbuildid',
     init_url='getInfo.html',
     env={'NO_EM_RESTART': '1'},
     # base data for all tests
     basetest=dict(
@@ -60,156 +54,16 @@ DEFAULTS = dict(
         w7_counters=[],
         linux_counters=[],
         mac_counters=[],
         xperf_counters=[],
         setup=None,
         cleanup=None,
         preferences={},
     ),
-    # default preferences to run with
-    # these are updated with --extraPrefs from the commandline
-    # for extension scopes, see
-    # see https://developer.mozilla.org/en/Installing_extensions
-    preferences={
-        'app.update.enabled': False,
-        'browser.addon-watch.interval': -1,  # Deactivate add-on watching
-        'browser.aboutHomeSnippets.updateUrl':
-            'https://127.0.0.1/about-dummy/',
-        'browser.bookmarks.max_backups': 0,
-        'browser.cache.disk.smart_size.enabled': False,
-        'browser.cache.disk.smart_size.first_run': False,
-        'browser.chrome.dynamictoolbar': False,
-        'browser.dom.window.dump.enabled': True,
-        'browser.EULA.override': True,
-        'browser.link.open_newwindow': 2,
-        'browser.reader.detectedFirstArticle': True,
-        'browser.shell.checkDefaultBrowser': False,
-        'browser.warnOnQuit': False,
-        'browser.tabs.remote.autostart': False,
-        'dom.allow_scripts_to_close_windows': True,
-        'dom.disable_open_during_load': False,
-        'dom.disable_window_flip': True,
-        'dom.disable_window_move_resize': True,
-        'dom.max_chrome_script_run_time': 0,
-        'dom.max_script_run_time': 0,
-        'extensions.autoDisableScopes': 10,
-        'extensions.checkCompatibility': False,
-        'extensions.enabledScopes': 5,
-        'extensions.update.notifyUser': False,
-        'hangmonitor.timeout': 0,
-        'network.proxy.http': 'localhost',
-        'network.proxy.http_port': 80,
-        'network.proxy.type': 1,
-        # Bug 1383896 - reduces noise in tests
-        'idle.lastDailyNotification': int(time.time()),
-        # Bug 1445243 - reduces precision of tests
-        'privacy.reduceTimerPrecision': False,
-        'places.database.lastMaintenance': FAR_IN_FUTURE,
-        'security.enable_java': False,
-        'security.fileuri.strict_origin_policy': False,
-        'dom.send_after_paint_to_content': True,
-        'security.turn_off_all_security_so_that_viruses_can_'
-        'take_over_this_computer': True,
-        'browser.newtabpage.activity-stream.default.sites': '',
-        'browser.newtabpage.activity-stream.telemetry': False,
-        'browser.newtabpage.activity-stream.tippyTop.service.endpoint': '',
-        'browser.newtabpage.activity-stream.feeds.section.topstories': False,
-        'browser.newtabpage.activity-stream.feeds.snippets': False,
-        'browser.safebrowsing.downloads.remote.url':
-            'http://127.0.0.1/safebrowsing-dummy/downloads',
-        'browser.safebrowsing.provider.google.gethashURL':
-            'http://127.0.0.1/safebrowsing-dummy/gethash',
-        'browser.safebrowsing.provider.google.updateURL':
-            'http://127.0.0.1/safebrowsing-dummy/update',
-        'browser.safebrowsing.provider.google4.gethashURL':
-            'http://127.0.0.1/safebrowsing4-dummy/gethash',
-        'browser.safebrowsing.provider.google4.updateURL':
-            'http://127.0.0.1/safebrowsing4-dummy/update',
-        'browser.safebrowsing.provider.mozilla.gethashURL':
-            'http://127.0.0.1/safebrowsing-dummy/gethash',
-        'browser.safebrowsing.provider.mozilla.updateURL':
-            'http://127.0.0.1/safebrowsing-dummy/update',
-        'privacy.trackingprotection.introURL':
-            'http://127.0.0.1/trackingprotection/tour',
-        'browser.safebrowsing.phishing.enabled': False,
-        'browser.safebrowsing.malware.enabled': False,
-        'browser.safebrowsing.blockedURIs.enabled': False,
-        'browser.safebrowsing.downloads.enabled': False,
-        'browser.safebrowsing.passwords.enabled': False,
-        'plugins.flashBlock.enabled': False,
-        'privacy.trackingprotection.annotate_channels': False,
-        'privacy.trackingprotection.enabled': False,
-        'privacy.trackingprotection.pbmode.enabled': False,
-        'browser.search.isUS': True,
-        'browser.search.countryCode': 'US',
-        'browser.search.geoip.url': '',
-        'browser.urlbar.userMadeSearchSuggestionsChoice': True,
-        'extensions.update.url':
-            'http://127.0.0.1/extensions-dummy/updateURL',
-        'extensions.update.background.url':
-            'http://127.0.0.1/extensions-dummy/updateBackgroundURL',
-        'extensions.blocklist.enabled': False,
-        'extensions.blocklist.url':
-            'http://127.0.0.1/extensions-dummy/blocklistURL',
-        'extensions.hotfix.url':
-            'http://127.0.0.1/extensions-dummy/hotfixURL',
-        'extensions.update.enabled': False,
-        'extensions.webservice.discoverURL':
-            'http://127.0.0.1/extensions-dummy/discoveryURL',
-        'extensions.getAddons.get.url':
-            'http://127.0.0.1/extensions-dummy/repositoryGetURL',
-        'extensions.getAddons.getWithPerformance.url':
-            'http://127.0.0.1/extensions-dummy'
-            '/repositoryGetWithPerformanceURL',
-        'extensions.getAddons.search.browseURL':
-            'http://127.0.0.1/extensions-dummy/repositoryBrowseURL',
-        'media.gmp-manager.url':
-            'http://127.0.0.1/gmpmanager-dummy/update.xml',
-        'media.gmp-manager.updateEnabled': False,
-        'extensions.systemAddon.update.url':
-            'http://127.0.0.1/dummy-system-addons.xml',
-        'app.normandy.api_url':
-            'https://127.0.0.1/selfsupport-dummy/',
-        'browser.ping-centre.staging.endpoint':
-            'https://127.0.0.1/pingcentre/dummy/',
-        'browser.ping-centre.production.endpoint':
-            'https://127.0.0.1/pingcentre/dummy/',
-        'media.navigator.enabled': True,
-        'media.peerconnection.enabled': True,
-        'media.navigator.permission.disabled': True,
-        'media.capturestream_hints.enabled': True,
-        'browser.contentHandlers.types.0.uri': 'http://127.0.0.1/rss?url=%s',
-        'browser.contentHandlers.types.1.uri': 'http://127.0.0.1/rss?url=%s',
-        'browser.contentHandlers.types.2.uri': 'http://127.0.0.1/rss?url=%s',
-        'browser.contentHandlers.types.3.uri': 'http://127.0.0.1/rss?url=%s',
-        'browser.contentHandlers.types.4.uri': 'http://127.0.0.1/rss?url=%s',
-        'browser.contentHandlers.types.5.uri': 'http://127.0.0.1/rss?url=%s',
-        'identity.fxaccounts.auth.uri': 'https://127.0.0.1/fxa-dummy/',
-        'datareporting.healthreport.documentServerURI':
-            'http://127.0.0.1/healthreport/',
-        'datareporting.policy.dataSubmissionPolicyBypassNotification': True,
-        'general.useragent.updates.enabled': False,
-        'browser.webapps.checkForUpdates': 0,
-        'browser.search.geoSpecificDefaults': False,
-        'browser.snippets.enabled': False,
-        'browser.snippets.syncPromo.enabled': False,
-        'toolkit.telemetry.server': 'https://127.0.0.1/telemetry-dummy/',
-        'network.http.speculative-parallel-limit': 0,
-        'lightweightThemes.selectedThemeID': "",
-        'devtools.chrome.enabled': False,
-        'devtools.debugger.remote-enabled': False,
-        'devtools.theme': "light",
-        'devtools.timeline.enabled': False,
-        'identity.fxaccounts.migrateToDevEdition': False,
-        'plugin.state.flash': 0,
-        'media.libavcodec.allow-obsolete': True,
-        'extensions.legacy.enabled': True,
-        'xpinstall.signatures.required': False,
-    }
 )
 
 
 # keys to generated self.config that are global overrides to tests
 GLOBAL_OVERRIDES = (
     'cycles',
     'gecko_profile',
     'gecko_profile_interval',
@@ -281,17 +135,21 @@ def set_webserver(config):
     port = sock.getsockname()[1]
     sock.close()
 
     config['webserver'] = 'localhost:%d' % port
 
 
 @validator
 def update_prefs(config):
-    config['preferences']['browser.tabs.remote.autostart'] = True
+    config.setdefault('preferences', {}).update({
+        # Bug 1383896 - reduces noise in tests
+        'idle.lastDailyNotification': int(time.time()),
+    })
+
     # update prefs from command line
     prefs = config.pop('extraPrefs')
     if prefs:
         for arg in prefs:
             k, v = arg.split('=', 1)
             config['preferences'][k] = utils.parse_pref(v)
 
 
@@ -453,17 +311,17 @@ def tests(config):
     for test_name in activeTests:
         test_class = test_dict[test_name]
         tests.append(get_test(config, global_overrides, counters,
                               test_class()))
     config['tests'] = tests
 
 
 def get_browser_config(config):
-    required = ('preferences', 'extensions', 'browser_path', 'browser_wait',
+    required = ('extensions', 'browser_path', 'browser_wait',
                 'extra_args', 'buildid', 'env', 'init_url', 'webserver')
     optional = {'bcontroller_config': '${talos}/bcontroller.json',
                 'branch_name': '',
                 'child_process': 'plugin-container',
                 'debug': False,
                 'debugger': None,
                 'debugger_args': None,
                 'develop': False,
@@ -473,16 +331,17 @@ def get_browser_config(config):
                 'sourcestamp': None,
                 'symbols_path': None,
                 'test_timeout': 1200,
                 'xperf_path': None,
                 'error_filename': None,
                 'no_upload_results': False,
                 'stylothreads': 0,
                 'subtests': None,
+                'preferences': {},
                 }
     browser_config = dict(title=config['title'])
     browser_config.update(dict([(i, config[i]) for i in required]))
     browser_config.update(dict([(i, config.get(i, j))
                           for i, j in optional.items()]))
     return browser_config
 
 
--- a/testing/talos/talos/ffsetup.py
+++ b/testing/talos/talos/ffsetup.py
@@ -2,30 +2,33 @@
 # 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/.
 
 """
 Set up a browser environment before running a test.
 """
 from __future__ import absolute_import, print_function
 
+import json
 import os
 import shutil
 import tempfile
 
 import mozfile
 import mozinfo
 import mozrunner
 from mozlog import get_proxy_logger
 from mozprofile.profile import Profile
 from talos import utils
 from talos.gecko_profile import GeckoProfile
 from talos.utils import TalosError, run_in_debug_mode
 from talos import heavy
 
+here = os.path.abspath(os.path.dirname(__file__))
+
 LOG = get_proxy_logger()
 
 
 class FFSetup(object):
     """
     Initialize the browser environment before running a test.
 
     This prepares:
@@ -53,48 +56,38 @@ class FFSetup(object):
         self._tmp_dir = tempfile.mkdtemp()
         self.env = None
         # The profile dir must be named 'profile' because of xperf analysis
         # (in etlparser.py). TODO fix that ?
         self.profile_dir = os.path.join(self._tmp_dir, 'profile')
         self.gecko_profile = None
         self.debug_mode = run_in_debug_mode(browser_config)
 
+    @property
+    def profile_data_dir(self):
+        if 'MOZ_DEVELOPER_REPO_DIR' in os.environ:
+            return os.path.join(os.environ['MOZ_DEVELOPER_REPO_DIR'], 'testing', 'profiles')
+        return os.path.join(here, 'profile_data')
+
     def _init_env(self):
         self.env = dict(os.environ)
         for k, v in self.browser_config['env'].iteritems():
             self.env[k] = str(v)
         self.env['MOZ_CRASHREPORTER_NO_REPORT'] = '1'
         if self.browser_config['symbols_path']:
             self.env['MOZ_CRASHREPORTER'] = '1'
         else:
             self.env['MOZ_CRASHREPORTER_DISABLE'] = '1'
 
         self.env['MOZ_DISABLE_NONLOCAL_CONNECTIONS'] = '1'
 
         self.env["LD_LIBRARY_PATH"] = \
             os.path.dirname(self.browser_config['browser_path'])
 
     def _init_profile(self):
-        preferences = dict(self.browser_config['preferences'])
-        if self.test_config.get('preferences'):
-            test_prefs = dict(
-                [(i, utils.parse_pref(j))
-                 for i, j in self.test_config['preferences'].items()]
-            )
-            preferences.update(test_prefs)
-        # interpolate webserver value in prefs
-        webserver = self.browser_config['webserver']
-        if '://' not in webserver:
-            webserver = 'http://' + webserver
-        for name, value in preferences.items():
-            if type(value) is str:
-                value = utils.interpolate(value, webserver=webserver)
-                preferences[name] = value
-
         extensions = self.browser_config['extensions'][:]
         if self.test_config.get('extensions'):
             extensions.extend(self.test_config['extensions'])
 
         # downloading a profile instead of using the empty one
         if self.test_config['profile'] is not None:
             path = heavy.download_profile(self.test_config['profile'])
             self.test_config['profile_path'] = path
@@ -114,16 +107,47 @@ class FFSetup(object):
                 LOG.info("=> %s" % sub)
             return []
 
         profile = Profile.clone(profile_path,
                                 self.profile_dir,
                                 ignore=_feedback,
                                 restore=False)
 
+        # build pref interpolation context
+        webserver = self.browser_config['webserver']
+        if '://' not in webserver:
+            webserver = 'http://' + webserver
+
+        interpolation = {
+            'webserver': webserver,
+        }
+
+        # merge base profiles
+        with open(os.path.join(self.profile_data_dir, 'profiles.json'), 'r') as fh:
+            base_profiles = json.load(fh)['talos']
+
+        for name in base_profiles:
+            path = os.path.join(self.profile_data_dir, name)
+            LOG.info("Merging profile: {}".format(path))
+            profile.merge(path, interpolation=interpolation)
+
+        # set test preferences
+        preferences = self.browser_config.get('preferences', {}).copy()
+        if self.test_config.get('preferences'):
+            test_prefs = dict(
+                [(i, utils.parse_pref(j))
+                 for i, j in self.test_config['preferences'].items()]
+            )
+            preferences.update(test_prefs)
+
+        for name, value in preferences.items():
+            if type(value) is str:
+                value = utils.interpolate(value, **interpolation)
+                preferences[name] = value
         profile.set_preferences(preferences)
 
         # installing addons
         LOG.info("Installing Add-ons:")
         LOG.info(extensions)
         profile.addons.install(extensions)
 
         # installing webextensions