зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1769110 - Add support to mochitest harness for conditioned profiles to be used while testing. r=gbrown,asuth
Differential Revision: https://phabricator.services.mozilla.com/D146317
This commit is contained in:
Родитель
0e50e38f5d
Коммит
e09607114a
|
@ -406,6 +406,15 @@ class MochitestArguments(ArgumentContainer):
|
|||
"suppress": True,
|
||||
},
|
||||
],
|
||||
[
|
||||
["--conditioned-profile"],
|
||||
{
|
||||
"dest": "conditionedProfile",
|
||||
"action": "store_true",
|
||||
"default": False,
|
||||
"help": "Download and run with a full conditioned profile.",
|
||||
},
|
||||
],
|
||||
[
|
||||
["--testing-modules-dir"],
|
||||
{
|
||||
|
|
|
@ -128,7 +128,7 @@ class MessageLogger(object):
|
|||
|
||||
BUFFERING_THRESHOLD = 100
|
||||
# This is a delimiter used by the JS side to avoid logs interleaving
|
||||
DELIMITER = u"\ue175\uee31\u2c32\uacbf"
|
||||
DELIMITER = "\ue175\uee31\u2c32\uacbf"
|
||||
BUFFERED_ACTIONS = set(["test_status", "log"])
|
||||
VALID_ACTIONS = set(
|
||||
[
|
||||
|
@ -959,6 +959,7 @@ class MochitestDesktop(object):
|
|||
self.extraPrefs = {}
|
||||
self.extraEnv = {}
|
||||
self.extraTestsDirs = []
|
||||
self.conditioned_profile_dir = None
|
||||
|
||||
if logger_options.get("log"):
|
||||
self.log = logger_options["log"]
|
||||
|
@ -1578,6 +1579,12 @@ toolbar#nav-bar {
|
|||
subsuite(options.subsuite),
|
||||
]
|
||||
|
||||
# Allow for only running tests/manifests which match this tag
|
||||
if options.conditionedProfile:
|
||||
if not options.test_tags:
|
||||
options.test_tags = []
|
||||
options.test_tags.append("condprof")
|
||||
|
||||
if options.test_tags:
|
||||
filters.append(tags(options.test_tags))
|
||||
|
||||
|
@ -2129,6 +2136,64 @@ toolbar#nav-bar {
|
|||
path = os.path.join(profile_data_dir, profile)
|
||||
self.profile.merge(path, interpolation=interpolation)
|
||||
|
||||
@property
|
||||
def conditioned_profile_copy(self):
|
||||
"""Returns a copy of the original conditioned profile that was created."""
|
||||
|
||||
condprof_copy = os.path.join(tempfile.mkdtemp(), "profile")
|
||||
shutil.copytree(
|
||||
self.conditioned_profile_dir,
|
||||
condprof_copy,
|
||||
ignore=shutil.ignore_patterns("lock"),
|
||||
)
|
||||
self.log.info("Created a conditioned-profile copy: %s" % condprof_copy)
|
||||
return condprof_copy
|
||||
|
||||
def downloadConditionedProfile(self, profile_scenario):
|
||||
from condprof.client import get_profile
|
||||
from condprof.util import get_current_platform
|
||||
|
||||
if self.conditioned_profile_dir:
|
||||
# We already have a directory, so provide a copy that
|
||||
# will get deleted after it's done with
|
||||
return self.conditioned_profile_copy
|
||||
|
||||
temp_download_dir = tempfile.mkdtemp()
|
||||
|
||||
# Call condprof's client API to yield our platform-specific
|
||||
# conditioned-profile binary
|
||||
platform = get_current_platform()
|
||||
|
||||
if not profile_scenario:
|
||||
profile_scenario = "settled"
|
||||
|
||||
cond_prof_target_dir = get_profile(
|
||||
temp_download_dir,
|
||||
platform,
|
||||
profile_scenario,
|
||||
repo="mozilla-central",
|
||||
)
|
||||
|
||||
# Now get the full directory path to our fetched conditioned profile
|
||||
self.conditioned_profile_dir = os.path.join(
|
||||
temp_download_dir, cond_prof_target_dir
|
||||
)
|
||||
if not os.path.exists(cond_prof_target_dir):
|
||||
self.log.critical(
|
||||
"Can't find target_dir {}, from get_profile()"
|
||||
"temp_download_dir {}, platform {}, scenario {}".format(
|
||||
cond_prof_target_dir, temp_download_dir, platform, profile_scenario
|
||||
)
|
||||
)
|
||||
raise OSError
|
||||
|
||||
self.log.info(
|
||||
"Original self.conditioned_profile_dir is now set: {}".format(
|
||||
self.conditioned_profile_dir
|
||||
)
|
||||
)
|
||||
return self.conditioned_profile_copy
|
||||
|
||||
def buildProfile(self, options):
|
||||
"""create the profile and add optional chrome bits and files if requested"""
|
||||
# get extensions to install
|
||||
|
@ -2146,6 +2211,20 @@ toolbar#nav-bar {
|
|||
os.path.join(p, "") for p in sandbox_whitelist_paths
|
||||
]
|
||||
|
||||
if options.conditionedProfile:
|
||||
if options.profilePath and os.path.exists(options.profilePath):
|
||||
shutil.rmtree(options.profilePath, ignore_errors=True)
|
||||
options.profilePath = self.downloadConditionedProfile("full")
|
||||
|
||||
# This is causing `certutil -N -d -f`` to not use -f (pwd file)
|
||||
try:
|
||||
os.remove(os.path.join(options.profilePath, "key4.db"))
|
||||
except Exception as e:
|
||||
self.log.info(
|
||||
"Caught exception while removing key4.db"
|
||||
"during setup of conditioned profile: %s" % e
|
||||
)
|
||||
|
||||
# Create the profile
|
||||
self.profile = Profile(
|
||||
profile=options.profilePath,
|
||||
|
@ -2736,6 +2815,12 @@ toolbar#nav-bar {
|
|||
This method is used to clear the contents before each run of for loop.
|
||||
This method is used for --run-by-dir and --bisect-chunk.
|
||||
"""
|
||||
if options.conditionedProfile:
|
||||
if options.profilePath and os.path.exists(options.profilePath):
|
||||
shutil.rmtree(options.profilePath, ignore_errors=True)
|
||||
if options.manifestFile and os.path.exists(options.manifestFile):
|
||||
os.remove(options.manifestFile)
|
||||
|
||||
self.expectedError.clear()
|
||||
self.result.clear()
|
||||
options.manifestFile = None
|
||||
|
@ -3042,6 +3127,7 @@ toolbar#nav-bar {
|
|||
"verify_fission": options.verify_fission,
|
||||
"webgl_ipc": self.extraPrefs.get("webgl.out-of-process", False),
|
||||
"xorigin": options.xOriginTests,
|
||||
"condprof": options.conditionedProfile,
|
||||
}
|
||||
)
|
||||
|
||||
|
@ -3363,6 +3449,9 @@ toolbar#nav-bar {
|
|||
if options.timeoutAsPass:
|
||||
testURL += "&timeoutAsPass=true"
|
||||
|
||||
if options.conditionedProfile:
|
||||
testURL += "&conditionedProfile=true"
|
||||
|
||||
self.log.info("runtests.py | Running with scheme: {}".format(scheme))
|
||||
self.log.info(
|
||||
"runtests.py | Running with e10s: {}".format(options.e10s)
|
||||
|
|
|
@ -1433,11 +1433,22 @@ SimpleTest.finish = function() {
|
|||
);
|
||||
}
|
||||
} else if (workers.length > 0) {
|
||||
let FULL_PROFILE_WORKERS_TO_IGNORE = [];
|
||||
if (parentRunner.conditionedProfile) {
|
||||
// Full profile has service workers in the profile, without clearing the profile
|
||||
// service workers will be leftover, in all my testing youtube is the only one.
|
||||
FULL_PROFILE_WORKERS_TO_IGNORE = ["https://www.youtube.com/sw.js"];
|
||||
} else {
|
||||
SimpleTest.ok(
|
||||
false,
|
||||
"This test left a service worker registered without cleaning it up"
|
||||
);
|
||||
}
|
||||
|
||||
for (let worker of workers) {
|
||||
if (FULL_PROFILE_WORKERS_TO_IGNORE.includes(worker.scriptSpec)) {
|
||||
continue;
|
||||
}
|
||||
SimpleTest.ok(
|
||||
false,
|
||||
`Left over worker: ${worker.scriptSpec} (scope: ${worker.scope})`
|
||||
|
|
|
@ -120,7 +120,8 @@ TestRunner.slowestTestTime = 0;
|
|||
TestRunner.slowestTestURL = "";
|
||||
TestRunner.interactiveDebugger = false;
|
||||
TestRunner.cleanupCrashes = false;
|
||||
TestRunner.timeoutAspass = false;
|
||||
TestRunner.timeoutAsPass = false;
|
||||
TestRunner.conditionedProfile = false;
|
||||
|
||||
TestRunner._expectingProcessCrash = false;
|
||||
TestRunner._structuredFormatter = new StructuredFormatter();
|
||||
|
|
|
@ -189,6 +189,10 @@ if (params.timeoutAsPass) {
|
|||
TestRunner.timeoutAsPass = true;
|
||||
}
|
||||
|
||||
if (params.conditionedProfile) {
|
||||
TestRunner.conditionedProfile = true;
|
||||
}
|
||||
|
||||
// Log things to the console if appropriate.
|
||||
TestRunner.logger.addListener("dumpListener", consoleLevel + "", function(msg) {
|
||||
dump(msg.info.join(" ") + "\n");
|
||||
|
|
Загрузка…
Ссылка в новой задаче