Bug 1459598 - Use profiles.json file to map test suites to the base profiles they use, r=jgraham

This serves two purposes:

1) It makes web-platform-tests pref downloading/handling a little more robust. When
run externally, it now downloads the entire testing/profiles directory. When loading
prefs it will look for both prefs_general.js (to support older versions of Firefox)
and profiles.json (for support moving forward).

This way we can add/remove/rename pref files under these directories without needing
to worry about breaking upstream wpt.

2) It provides developers an overview of which harnesses are using which base profiles.
Instead of hunting through test harness code to find this information, they can glance
at profiles.json.

MozReview-Commit-ID: AMzdnD8aGA2

--HG--
extra : rebase_source : 6fa0a802680417e49fcef99f3d03de7458a8fcba
This commit is contained in:
Andrew Halberstadt 2018-05-07 09:43:12 -04:00
Родитель 0909d2c724
Коммит ac08b89a81
8 изменённых файлов: 88 добавлений и 44 удалений

Просмотреть файл

@ -4,6 +4,7 @@
# 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 json
import os
from buildconfig import substs
@ -43,14 +44,17 @@ if __name__ == '__main__':
with TemporaryDirectory() as profilePath:
# TODO: refactor this into mozprofile
prefpath = os.path.join(
build.topsrcdir, "testing", "profiles", "common", "user.js")
overridepath = os.path.join(
build.topsrcdir, "build", "pgo", "prefs_override.js")
profile_data_dir = os.path.join(build.topsrcdir, 'testing', 'profiles')
with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh:
base_profiles = json.load(fh)['profileserver']
prefpaths = [os.path.join(profile_data_dir, profile, 'user.js')
for profile in base_profiles]
prefpaths.append(os.path.join(build.topsrcdir, "build", "pgo", "prefs_override.js"))
prefs = {}
prefs.update(Preferences.read_prefs(prefpath))
prefs.update(Preferences.read_prefs(overridepath))
for path in prefpaths:
prefs.update(Preferences.read_prefs(path))
interpolation = {"server": "%s:%d" % httpd.httpd.server_address,
"OOP": "false"}

Просмотреть файл

@ -4,6 +4,7 @@
from __future__ import absolute_import, unicode_literals
import json
import logging
import mozinfo
import os
@ -65,9 +66,16 @@ class MachCommands(MachCommandBase):
with TemporaryDirectory() as profilePath:
#TODO: refactor this into mozprofile
prefpath = os.path.join(self.topsrcdir, 'testing', 'profiles', 'common', 'user.js')
profile_data_dir = os.path.join(self.topsrcdir, 'testing', 'profiles')
with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh:
base_profiles = json.load(fh)['valgrind']
prefpaths = [os.path.join(profile_data_dir, profile, 'user.js')
for profile in base_profiles]
prefs = {}
prefs.update(Preferences.read_prefs(prefpath))
for path in prefpaths:
prefs.update(Preferences.read_prefs(path))
interpolation = {
'server': '%s:%d' % httpd.httpd.server_address,
}

Просмотреть файл

@ -851,7 +851,6 @@ class MochitestDesktop(object):
mediaDevices = None
patternFiles = {}
base_profiles = ('common',)
# XXX use automation.py for test name to avoid breaking legacy
# TODO: replace this with 'runtests.py' or 'mochitest' or the like
@ -1851,12 +1850,15 @@ toolbar#nav-bar {
if os.path.isdir(path):
profile_data_dir = path
with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh:
base_profiles = json.load(fh)['mochitest']
# values to use when interpolating preferences
interpolation = {
"server": "%s:%s" % (options.webServer, options.httpPort),
}
for profile in self.base_profiles:
for profile in base_profiles:
path = os.path.join(profile_data_dir, profile)
self.profile.merge(path, interpolation=interpolation)

Просмотреть файл

@ -4,9 +4,11 @@
from __future__ import print_function, unicode_literals
import json
import os
from argparse import Namespace
from mozbuild.base import MozbuildObject
from mozprofile.prefs import Preferences
from mozprofile import Profile
from six import string_types
@ -15,6 +17,8 @@ import mozunit
import pytest
from conftest import setup_args
here = os.path.abspath(os.path.dirname(__file__))
@pytest.fixture
def build_profile(monkeypatch, setup_test_harness, parser):
@ -36,8 +40,9 @@ def build_profile(monkeypatch, setup_test_harness, parser):
@pytest.fixture
def profile_data_dir(build_obj):
return os.path.join(build_obj.topsrcdir, 'testing', 'profiles')
def profile_data_dir():
build = MozbuildObject.from_environment(cwd=here)
return os.path.join(build.topsrcdir, 'testing', 'profiles')
def test_common_prefs_are_all_set(build_profile, profile_data_dir):
@ -46,9 +51,12 @@ def test_common_prefs_are_all_set(build_profile, profile_data_dir):
# TODO stop setting browser.tabs.remote.autostart in the base profile
md, result = build_profile(e10s=False)
with open(os.path.join(profile_data_dir, 'profiles.json'), 'r') as fh:
base_profiles = json.load(fh)['mochitest']
# build the expected prefs
expected_prefs = {}
for profile in md.base_profiles:
for profile in base_profiles:
for name in Profile.preference_file_names:
path = os.path.join(profile_data_dir, profile, name)
if os.path.isfile(path):

Просмотреть файл

@ -4,12 +4,13 @@
# 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/.
profiles = [
profile_files = [
'common/*',
'profiles.json',
]
TEST_HARNESS_FILES.testing.mochitest.profile_data += profiles
TEST_HARNESS_FILES['web-platform'].prefs += ['common/user.js']
TEST_HARNESS_FILES.testing.mochitest.profile_data += profile_files
TEST_HARNESS_FILES['web-platform'].prefs += profile_files
with Files("**"):
BUG_COMPONENT = ("Testing", "Mochitest")
BUG_COMPONENT = ("Testing", "General")

Просмотреть файл

@ -0,0 +1,6 @@
{
"mochitest": ["common"],
"profileserver": ["common"],
"web-platform-tests": ["common"],
"valgrind": ["common"]
}

Просмотреть файл

@ -6,6 +6,7 @@ import shutil
import stat
import subprocess
import sys
import tempfile
from abc import ABCMeta, abstractmethod
from ConfigParser import RawConfigParser
from datetime import datetime, timedelta
@ -191,7 +192,7 @@ class Firefox(Browser):
channel = {"a": "nightly", "b": "beta"}
return version, channel.get(status, "stable")
def get_prefs_url(self, version, channel):
def get_profile_bundle_url(self, version, channel):
if channel == "stable":
repo = "https://hg.mozilla.org/releases/mozilla-release"
tag = "FIREFOX_%s_RELEASE" % version.replace(".", "_")
@ -205,7 +206,7 @@ class Firefox(Browser):
# can get if we have an application.ini file
tag = "tip"
return "%s/raw-file/%s/testing/profiles/common/user.js" % (repo, tag)
return "%s/archive/%s.zip/testing/profiles/" % (repo, tag)
def install_prefs(self, binary, dest=None):
version, channel = self.get_version_number(binary)
@ -213,36 +214,37 @@ class Firefox(Browser):
if dest is None:
dest = os.pwd
dest = os.path.join(dest, "profiles", "common")
if not os.path.exists(dest):
os.makedirs(dest)
prefs_file = os.path.join(dest, "user.js")
cache_file = os.path.join(dest,
"%s-%s.cache" % (version, channel)
if channel != "nightly"
else "nightly.cache")
dest = os.path.join(dest, "profiles", channel, version)
have_cache = False
if os.path.exists(cache_file):
if os.path.exists(dest):
if channel != "nightly":
have_cache = True
else:
now = datetime.now()
have_cache = (datetime.fromtimestamp(os.stat(cache_file).st_mtime) >
have_cache = (datetime.fromtimestamp(os.stat(dest).st_mtime) >
now - timedelta(days=1))
# If we don't have a recent download, grab the url
# If we don't have a recent download, grab and extract the latest one
if not have_cache:
url = self.get_prefs_url(version, channel)
if os.path.exists(dest):
shutil.rmtree(dest)
os.makedirs(dest)
with open(cache_file, "wb") as f:
print("Installing test prefs from %s" % url)
resp = get(url)
f.write(resp.content)
url = self.get_profile_bundle_url(version, channel)
print("Installing test prefs from %s" % url)
try:
extract_dir = tempfile.mkdtemp()
unzip(get(url).raw, dest=extract_dir)
profiles = os.path.join(extract_dir, os.listdir(extract_dir)[0], 'testing', 'profiles')
for name in os.listdir(profiles):
path = os.path.join(profiles, name)
shutil.move(path, dest)
finally:
shutil.rmtree(extract_dir)
else:
print("Using cached test prefs from %s" % cache_file)
shutil.copyfile(cache_file, prefs_file)
print("Using cached test prefs from %s" % dest)
return dest

Просмотреть файл

@ -1,3 +1,4 @@
import json
import os
import platform
import signal
@ -245,11 +246,23 @@ class FirefoxBrowser(Browser):
def load_prefs(self):
prefs = Preferences()
prefs_path = os.path.join(self.prefs_root, "user.js")
if os.path.exists(prefs_path):
prefs.add(Preferences.read_prefs(prefs_path))
else:
self.logger.warning("Failed to find base prefs file in %s" % prefs_path)
pref_paths = []
prefs_general = os.path.join(self.prefs_root, 'prefs_general.js')
if os.path.isfile(prefs_general):
# Old preference file used in Firefox 60 and earlier (remove when no longer supported)
pref_paths.append(prefs_general)
profiles = os.path.join(self.prefs_root, 'profiles.json')
if os.path.isfile(profiles):
with open(profiles, 'r') as fh:
for name in json.load(fh)['web-platform-tests']:
pref_paths.append(os.path.join(self.prefs_root, name, 'user.js'))
for path in pref_paths:
if os.path.exists(path):
prefs.add(Preferences.read_prefs(path))
else:
self.logger.warning("Failed to find base prefs file in %s" % path)
# Add any custom preferences
prefs.add(self.extra_prefs, cast=True)