Bug 1619198 - add mach commands for condprofs r=Bebe

Refactored condprof so we can drive it with mach

Differential Revision: https://phabricator.services.mozilla.com/D64962

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Tarek Ziadé 2020-03-05 10:27:05 +00:00
parent c8f4578a7f
commit 0165728187
19 changed files with 441 additions and 257 deletions

View File

@ -58,6 +58,7 @@ MACH_MODULES = [
'remote/mach_commands.py',
'taskcluster/mach_commands.py',
'testing/awsy/mach_commands.py',
'testing/condprofile/mach_commands.py',
'testing/firefox-ui/mach_commands.py',
'testing/geckodriver/mach_commands.py',
'testing/mach_commands.py',

View File

@ -52,7 +52,7 @@ jobs:
using: run-task
command: >-
cd %CONDPROF_ROOT% &&
python3.exe condprof/runner.py --geckodriver z:/%USERNAME%/fetches/bin/geckodriver.exe --firefox firefox/firefox.exe z:/%USERNAME%/archive
python3.exe condprof/main.py --geckodriver z:/%USERNAME%/fetches/bin/geckodriver.exe --firefox firefox/firefox.exe z:/%USERNAME%/archive
worker:
artifacts:
- name: public/condprof
@ -80,7 +80,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3.7 $CONDPROF_ROOT &&
cd $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
bin/python3.7 condprof/runner.py --firefox $MOZ_FETCHES_DIR/firefox/firefox-bin $CONDPROF_ARCHIVES
bin/python3.7 condprof/main.py --firefox $MOZ_FETCHES_DIR/firefox/firefox-bin $CONDPROF_ARCHIVES
worker:
docker-image: {in-tree: condprof}
artifacts:
@ -109,7 +109,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3 $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
cd $CONDPROF_ROOT &&
bin/python3 condprof/runner.py --firefox $MOZ_FETCHES_DIR/target.dmg ../../archive
bin/python3 condprof/main.py --firefox $MOZ_FETCHES_DIR/target.dmg ../../archive
worker:
artifacts:
- name: public/condprof
@ -141,7 +141,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3 $CONDPROF_ROOT &&
cd $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
bin/python3 condprof/runner.py --device-name g5 --firefox org.mozilla.geckoview_example ../../archive
bin/python3 condprof/main.py --device-name g5 --firefox org.mozilla.geckoview_example ../../archive
worker:
artifacts:
- name: public/condprof
@ -171,7 +171,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3 $CONDPROF_ROOT &&
cd $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
bin/python3 condprof/runner.py --device-name g5 --firefox org.mozilla.fenix.performancetest ../../archive
bin/python3 condprof/main.py --device-name g5 --firefox org.mozilla.fenix.performancetest ../../archive
worker:
artifacts:
- name: public/condprof
@ -201,7 +201,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3 $CONDPROF_ROOT &&
cd $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
bin/python3 condprof/runner.py --device-name p2_aarch64 --firefox org.mozilla.fenix.performancetest ../../archive
bin/python3 condprof/main.py --device-name p2_aarch64 --firefox org.mozilla.fenix.performancetest ../../archive
worker:
artifacts:
- name: public/condprof
@ -233,7 +233,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3 $CONDPROF_ROOT &&
cd $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
bin/python3 condprof/runner.py --device-name p2_aarch64 --firefox org.mozilla.geckoview_example ../../archive
bin/python3 condprof/main.py --device-name p2_aarch64 --firefox org.mozilla.geckoview_example ../../archive
worker:
artifacts:
- name: public/condprof
@ -263,7 +263,7 @@ jobs:
$CONDPROF_ROOT/virtualenv/virtualenv.py -p python3 $CONDPROF_ROOT &&
cd $CONDPROF_ROOT &&
export PATH="$PATH:$MOZ_FETCHES_DIR/bin" &&
bin/python3 condprof/runner.py --device-name p2_aarch64 --firefox org.mozilla.fennec_aurora ../../archive
bin/python3 condprof/main.py --device-name p2_aarch64 --firefox org.mozilla.fennec_aurora ../../archive
worker:
artifacts:
- name: public/condprof

View File

@ -29,17 +29,52 @@ For each combination of scenario, customization and platform:
It's based on the Arsenic webdriver client https://github.com/HDE/arsenic
A client that wants to use a profile can download it from the indexed artifacts
by using a simple HTTP client or the provided client in **condprof.client**.
The project provides two **Mach** commands to interact with the conditioned
profile:
- **fetch-condprofile**: downloads a conditioned profile and deecompress it
- **run-condprofile**: runs on or all conditioned profiles scenarii locally
Scenario
========
How to download a conditioned profile
=====================================
From your mozilla-central root, run:
::
$ ./mach fetch-condprofile
This will grab the latest conditioned profile for your platform. But
you can also grab a specific profile built from any scenario or platform.
You can look at all the options with --help
How to run a conditioned profile
================================
If you want to play a scenario locally to modify it, run for example:
::
$ ./mach run-condprofile --scenario settled --visible /path/to/generated/profile
The project will run a webdriver session against Firefox and generate the profile.
You can look at all the options with --help
Architecture
============
The conditioned profile project is organized into webdriver **scenarii** and
**customization** files.
Scenarii
--------
Scenarii are coroutines registered under a unique name in condprof/scenarii/__init__.py.
Scenarii are coroutines registered under a unique name in condprof/scenarii.
They get a **session** object and some **options**.
The scenario can do whatever it wants with the browser, through the session
The scenario can do whatever it wants with the browser, through the webdriver session
instance.
See Arsenic's `API documentation <https://arsenic.readthedocs.io/en/latest/reference/session.html>`_ for the session class.
@ -49,7 +84,7 @@ and register it in condprof/scenarii/__init__.py
Customization
=============
-------------
A customization is a configuration file that can be used to set some
prefs in the browser and install some webextensions.
@ -78,34 +113,3 @@ In the example below, we install uBlock, set a pref, and pass the
}
}
Getting conditioned profiles
============================
Unlike the profile creator, the client is Python 2 and 3 compatible.
You can grab a conditioned profile using the client API::
>>> from condprof.client import get_profile
>>> get_profile(".", "win64", "settled", "default")
or the **cp-client** script that gets install when you run the
conditioned profile installer.
Running locally
===============
Unfortunately, we can't hook the conditioned profile builder into mach
at this point. We need to wait for everything in the tree to be fully
Python 3 compatible.
Until then, if you want to build profiles locally, to try out one
of your scenario for instance, you can install a local Python 3
virtual env and use the script from there.
Get a mozilla-central source clone and do the following::
$ cd testing/condprofile
$ virtualenv .
From there you can trigger profiles creation using **bin/cp-creator**.

View File

@ -60,29 +60,41 @@ def install_reqs():
return False
except Exception:
if not os.path.exists(os.path.join(TOPDIR, "mozfile")):
req_file = PY3 and "local-requirements.txt" or "local-py2-requirements.txt"
# we're detecting here that this is running in Taskcluster
# by checking for the presence of the mozfile directory
# that was decompressed from target.condprof.tests.tar.gz
run_in_ci = os.path.exists(os.path.join(TOPDIR, "mozfile"))
# On Python 2 we only install what's required for condprof.client
# On Python 3 it's the full thing
if not run_in_ci:
req_files = PY3 and ["base.txt", "local.txt"] or ["local-client.txt"]
else:
req_file = PY3 and "requirements.txt" or "py2-requirements.txt"
req_files = PY3 and ["base.txt", "ci.txt"] or ["ci-client.txt"]
req_file = os.path.join(TOPDIR, req_file)
for req_file in req_files:
req_file = os.path.join(TOPDIR, "requirements", req_file)
with open(req_file) as f:
reqs = [req for req in f.read().split("\n") if req.strip() != ""]
for req in reqs:
subprocess.check_call(
[
sys.executable,
"-m",
"pip",
"install",
"--no-cache-dir",
"--isolated",
"--find-links",
"https://pypi.pub.build.mozilla.org/pub",
req,
]
)
with open(req_file) as f:
reqs = [
req
for req in f.read().split("\n")
if req.strip() != "" and not req.startswith("#")
]
for req in reqs:
subprocess.check_call(
[
sys.executable,
"-m",
"pip",
"install",
"--no-cache-dir",
"--isolated",
"--find-links",
"https://pypi.pub.build.mozilla.org/pub",
req,
]
)
return True

View File

@ -138,17 +138,3 @@ def read_changelog(platform, repo="mozilla-central"):
shutil.rmtree(download_dir)
raise ProfileNotFoundError(changelog_url)
return Changelog(download_dir)
def main():
# XXX demo. download an older version of a profile, given a task id
# plat = get_current_platform()
older_change = read_changelog("win64").history()[0]
task_id = older_change["TASK_ID"]
target_dir = tempfile.mkdtemp()
filename = get_profile(target_dir, "win64", "settled", "default", task_id)
print("Profile downloaded and extracted at %s" % filename)
if __name__ == "__main__":
main()

View File

@ -0,0 +1,77 @@
# 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/.
""" Script that launches profiles creation.
"""
import os
import argparse
import sys
# easier than setting PYTHONPATH in various platforms
if __name__ == "__main__":
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
from condprof.check_install import check # NOQA
if "MANUAL_MACH_RUN" not in os.environ:
check()
from condprof.runner import run # NOQA
def main(args=sys.argv[1:]):
parser = argparse.ArgumentParser(description="Profile Creator")
parser.add_argument("archive", help="Archives Dir", type=str, default=None)
parser.add_argument("--firefox", help="Firefox Binary", type=str, default=None)
parser.add_argument("--scenario", help="Scenario to use", type=str, default="all")
parser.add_argument(
"--profile", help="Existing profile Dir", type=str, default=None
)
parser.add_argument(
"--customization", help="Profile customization to use", type=str, default="all"
)
parser.add_argument(
"--visible", help="Don't use headless mode", action="store_true", default=False
)
parser.add_argument(
"--archives-dir", help="Archives local dir", type=str, default="/tmp/archives"
)
parser.add_argument(
"--force-new", help="Create from scratch", action="store_true", default=False
)
parser.add_argument(
"--strict",
help="Errors out immediatly on a scenario failure",
action="store_true",
default=True,
)
parser.add_argument(
"--geckodriver",
help="Path to the geckodriver binary",
type=str,
default=sys.platform.startswith("win") and "geckodriver.exe" or "geckodriver",
)
parser.add_argument(
"--device-name", help="Name of the device", type=str, default=None
)
args = parser.parse_args(args=args)
run(
args.archive,
args.firefox,
args.scenario,
args.profile,
args.customization,
args.visible,
args.archives_dir,
args.force_new,
args.strict,
args.geckodriver,
args.device_name,
)
if __name__ == "__main__":
main()

View File

@ -4,155 +4,145 @@
""" Script that launches profiles creation.
"""
import os
import argparse
import asyncio
import sys
import shutil
import asyncio
# easier than setting PYTHONPATH in various platforms
if __name__ == "__main__":
sys.path.append(os.path.join(os.path.dirname(__file__), ".."))
from condprof.check_install import check # NOQA
check() # NOQA
from condprof.creator import ProfileCreator # NOQA
from condprof.desktop import DesktopEnv # NOQA
from condprof.android import AndroidEnv # NOQA
from condprof.changelog import Changelog # NOQA
from condprof.scenarii import scenarii # NOQA
from condprof.creator import ProfileCreator
from condprof.desktop import DesktopEnv
from condprof.android import AndroidEnv
from condprof.changelog import Changelog
from condprof.scenarii import scenarii
from condprof.util import (
logger,
get_version,
get_current_platform,
extract_from_dmg,
) # NOQA
from condprof.customization import get_customizations, find_customization # NOQA
from condprof.client import read_changelog, ProfileNotFoundError # NOQA
)
from condprof.customization import get_customizations, find_customization
from condprof.client import read_changelog, ProfileNotFoundError
def main(args=sys.argv[1:]):
parser = argparse.ArgumentParser(description="Profile Creator")
parser.add_argument("archive", help="Archives Dir", type=str, default=None)
parser.add_argument("--firefox", help="Firefox Binary", type=str, default=None)
parser.add_argument("--scenario", help="Scenario to use", type=str, default="all")
parser.add_argument(
"--profile", help="Existing profile Dir", type=str, default=None
)
parser.add_argument(
"--customization", help="Profile customization to use", type=str, default="all"
)
parser.add_argument(
"--visible", help="Don't use headless mode", action="store_true", default=False
)
parser.add_argument(
"--archives-dir", help="Archives local dir", type=str, default="/tmp/archives"
)
parser.add_argument(
"--force-new", help="Create from scratch", action="store_true", default=False
)
parser.add_argument(
"--strict",
help="Errors out immediatly on a scenario failure",
action="store_true",
default=True,
)
parser.add_argument(
"--geckodriver",
help="Path to the geckodriver binary",
type=str,
default=sys.platform.startswith("win") and "geckodriver.exe" or "geckodriver",
)
class Runner:
def __init__(
self,
profile,
firefox,
geckodriver,
archive,
device_name,
strict,
force_new,
visible,
):
self.force_new = force_new
self.profile = profile
self.geckodriver = geckodriver
self.archive = archive
self.device_name = device_name
self.strict = strict
self.visible = visible
# unpacking a dmg
# XXX do something similar if we get an apk (but later)
# XXX we want to do
# adb install -r target.apk
# and get the installed app name
if firefox is not None and firefox.endswith("dmg"):
target = os.path.join(os.path.dirname(firefox), "firefox.app")
extract_from_dmg(firefox, target)
firefox = os.path.join(target, "Contents", "MacOS", "firefox")
self.firefox = firefox
self.android = self.firefox is not None and self.firefox.startswith(
"org.mozilla"
)
parser.add_argument(
"--device-name", help="Name of the device", type=str, default=None
)
def prepare(self, scenario, customization):
self.scenario = scenario
self.customization = customization
args = parser.parse_args(args=args)
# early checks to avoid extra work
if self.customization != "all":
if find_customization(self.customization) is None:
raise IOError("Cannot find customization %r" % self.customization)
# unpacking a dmg
# XXX do something similar if we get an apk (but later)
# XXX we want to do
# adb install -r target.apk
# and get the installed app name
if args.firefox is not None and args.firefox.endswith("dmg"):
target = os.path.join(os.path.dirname(args.firefox), "firefox.app")
extract_from_dmg(args.firefox, target)
args.firefox = os.path.join(target, "Contents", "MacOS", "firefox")
if self.scenario != "all" and self.scenario not in scenarii:
raise IOError("Cannot find scenario %r" % self.scenario)
args.android = args.firefox is not None and args.firefox.startswith("org.mozilla")
if not self.android and self.firefox is not None:
logger.info("Verifying Desktop Firefox binary")
# we want to verify we do have a firefox binary
# XXX so lame
if not os.path.exists(self.firefox):
if "MOZ_FETCHES_DIR" in os.environ:
target = os.path.join(os.environ["MOZ_FETCHES_DIR"], self.firefox)
if os.path.exists(target):
self.firefox = target
# early checks to avoid extra work
if args.customization != "all":
if find_customization(args.customization) is None:
raise IOError("Cannot find customization %r" % args.customization)
if not os.path.exists(self.firefox):
raise IOError("Cannot find %s" % self.firefox)
if args.scenario != "all" and args.scenario not in scenarii:
raise IOError("Cannot find scenario %r" % args.scenario)
version = get_version(self.firefox)
logger.info("Working with Firefox %s" % version)
if not args.android and args.firefox is not None:
logger.info("Verifying Desktop Firefox binary")
# we want to verify we do have a firefox binary
# XXX so lame
if not os.path.exists(args.firefox):
if "MOZ_FETCHES_DIR" in os.environ:
target = os.path.join(os.environ["MOZ_FETCHES_DIR"], args.firefox)
if os.path.exists(target):
args.firefox = target
logger.info(os.environ)
self.archive = os.path.abspath(self.archive)
logger.info("Archives directory is %s" % self.archive)
if not os.path.exists(self.archive):
os.makedirs(self.archive, exist_ok=True)
if not os.path.exists(args.firefox):
raise IOError("Cannot find %s" % args.firefox)
logger.info("Verifying Geckodriver binary presence")
if shutil.which(self.geckodriver) is None and not os.path.exists(
self.geckodriver
):
raise IOError("Cannot find %s" % self.geckodriver)
version = get_version(args.firefox)
logger.info("Working with Firefox %s" % version)
try:
if self.android:
plat = "%s-%s" % (
self.device_name,
self.firefox.split("org.mozilla.")[-1],
)
else:
plat = get_current_platform()
self.changelog = read_changelog(plat)
logger.info("Got the changelog from TaskCluster")
except ProfileNotFoundError:
logger.info("changelog not found on TaskCluster, creating a local one.")
self.changelog = Changelog(self.archive)
logger.info(os.environ)
args.archive = os.path.abspath(args.archive)
logger.info("Archives directory is %s" % args.archive)
if not os.path.exists(args.archive):
os.makedirs(args.archive, exist_ok=True)
logger.info("Verifying Geckodriver binary presence")
if shutil.which(args.geckodriver) is None and not os.path.exists(args.geckodriver):
raise IOError("Cannot find %s" % args.geckodriver)
try:
if args.android:
plat = "%s-%s" % (args.device_name, args.firefox.split("org.mozilla.")[-1])
def _create_env(self):
if self.android:
klass = AndroidEnv
else:
plat = get_current_platform()
changelog = read_changelog(plat)
logger.info("Got the changelog from TaskCluster")
except ProfileNotFoundError:
logger.info("changelog not found on TaskCluster, creating a local one.")
changelog = Changelog(args.archive)
loop = asyncio.get_event_loop()
klass = DesktopEnv
async def one_run(scenario, customization):
if args.android:
env = AndroidEnv(
args.profile,
args.firefox,
args.geckodriver,
args.archive,
args.device_name,
)
else:
env = DesktopEnv(
args.profile,
args.firefox,
args.geckodriver,
args.archive,
args.device_name,
)
return klass(
self.profile,
self.firefox,
self.geckodriver,
self.archive,
self.device_name,
)
def display_error(self, scenario, customization):
logger.error("%s x %s failed." % (scenario, customization), exc_info=True)
if self.strict:
raise
async def one_run(self, scenario, customization):
"""Runs one single conditioned profile.
Create an instance of the environment and run the ProfileCreator.
"""
env = self._create_env()
return await ProfileCreator(
scenario, customization, args.archive, changelog, args.force_new, env
).run(not args.visible)
scenario, customization, self.archive, self.changelog, self.force_new, env
).run(not self.visible)
async def run_all(args):
if args.scenario != "all":
selected_scenario = [args.scenario]
async def run_all(self):
"""Runs the conditioned profile builders
"""
if self.scenario != "all":
selected_scenario = [self.scenario]
else:
selected_scenario = scenarii.keys()
@ -160,40 +150,53 @@ def main(args=sys.argv[1:]):
# for the current platform when "all" is selected
res = []
failures = 0
def display_error(scenario, customization):
logger.error("%s x %s failed." % (scenario, customization), exc_info=True)
for scenario in selected_scenario:
if args.customization != "all":
if self.customization != "all":
try:
res.append(await one_run(scenario, args.customization))
res.append(await self.one_run(scenario, self.customization))
except Exception:
failures += 1
display_error(scenario, args.customization)
if args.strict:
raise
self.display_error(scenario, self.customization)
else:
for customization in get_customizations():
logger.info("Customization %s" % customization)
try:
res.append(await one_run(scenario, customization))
res.append(await self.one_run(scenario, customization))
except Exception:
failures += 1
display_error(scenario, customization)
if args.strict:
raise
self.display_error(scenario, customization)
return failures, [one_res for one_res in res if one_res]
def save(self):
self.changelog.save(self.archive)
def run(
archive,
firefox=None,
scenario="all",
profile=None,
customization="all",
visible=False,
archives_dir="/tmp/archives",
force_new=False,
strict=True,
geckodriver="geckodriver",
device_name=None,
):
runner = Runner(
profile, firefox, geckodriver, archive, device_name, strict, force_new, visible
)
runner.prepare(scenario, customization)
loop = asyncio.get_event_loop()
try:
failures, results = loop.run_until_complete(run_all(args))
logger.info("Saving changelog in %s" % args.archive)
changelog.save(args.archive)
failures, results = loop.run_until_complete(runner.run_all())
logger.info("Saving changelog in %s" % archive)
runner.save()
if failures > 0:
raise Exception("At least one scenario failed")
finally:
loop.close()
if __name__ == "__main__":
main()

View File

@ -1,9 +0,0 @@
../mozbase/mozfile
../mozbase/mozprofile
../mozbase/mozdevice
../mozbase/mozlog
aiohttp==3.5.4
https://pypi.pub.build.mozilla.org/pub/arsenic-19.1-py3-none-any.whl
requests==2.22.0
pyyaml==5.1.2

View File

@ -0,0 +1,97 @@
# 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 sys
import os
import tempfile
from mach.decorators import CommandArgument, CommandProvider, Command
from mozbuild.base import MachCommandBase
requirements = os.path.join(os.path.dirname(__file__), "requirements", "base.txt")
@CommandProvider
class CondprofileCommandProvider(MachCommandBase):
def _init(self):
self._activate_virtualenv()
self.virtualenv_manager.install_pip_requirements(
requirements, require_hashes=False
)
@Command("fetch-condprofile", category="testing")
@CommandArgument("--target-dir", default=None, help="Target directory")
@CommandArgument("--platform", default=None, help="Platform")
@CommandArgument("--scenario", default="full", help="Scenario") # grab choices
@CommandArgument("--customization", default="default", help="Customization") # same
@CommandArgument("--task-id", default=None, help="Task ID")
@CommandArgument("--download-cache", action="store_true", default=True)
@CommandArgument(
"--repo",
default="mozilla-central",
choices=["mozilla-central", "try"],
help="Repository",
)
def fetch(
self,
target_dir,
platform,
scenario,
customization,
task_id,
download_cache,
repo,
):
self._init()
from condprof.client import get_profile
from condprof.util import get_current_platform
if platform is None:
platform = get_current_platform()
if target_dir is None:
target_dir = tempfile.mkdtemp()
get_profile(
target_dir, platform, scenario, customization, task_id, download_cache, repo
)
@Command("run-condprofile", category="testing")
@CommandArgument("archive", help="Archives Dir", type=str, default=None)
@CommandArgument("--firefox", help="Firefox Binary", type=str, default=None)
@CommandArgument("--scenario", help="Scenario to use", type=str, default="all")
@CommandArgument("--profile", help="Existing profile Dir", type=str, default=None)
@CommandArgument(
"--customization", help="Profile customization to use", type=str, default="all"
)
@CommandArgument(
"--visible", help="Don't use headless mode", action="store_true", default=False
)
@CommandArgument(
"--archives-dir", help="Archives local dir", type=str, default="/tmp/archives"
)
@CommandArgument(
"--force-new", help="Create from scratch", action="store_true", default=False
)
@CommandArgument(
"--strict",
help="Errors out immediatly on a scenario failure",
action="store_true",
default=True,
)
@CommandArgument(
"--geckodriver",
help="Path to the geckodriver binary",
type=str,
default=sys.platform.startswith("win") and "geckodriver.exe" or "geckodriver",
)
@CommandArgument("--device-name", help="Name of the device", type=str, default=None)
def run(self, **kw):
os.environ["MANUAL_MACH_RUN"] = "1"
self._init()
if kw["firefox"] is None:
kw["firefox"] = self.get_binary_path()
from condprof.runner import run
run(**kw)

View File

@ -1,6 +0,0 @@
./mozfile
./mozlog
./mozprofile
requests==2.22.0
pyyaml==5.1.2

View File

@ -1,8 +1,3 @@
./mozfile
./mozlog
./mozprofile
./mozdevice
aiohttp==3.5.4
https://pypi.pub.build.mozilla.org/pub/arsenic-19.1-py3-none-any.whl
requests==2.22.0

View File

@ -0,0 +1,10 @@
# pulled when running in TaskCluster for python 2 only
# we just pull dependencies required by condprof.client
requests==2.22.0
pyyaml==5.1.2
# the target.condprof.tests.tar.gz archive pulls those dependencies
# directly into the condprof project root
./mozfile
./mozprofile
./mozlog

View File

@ -0,0 +1,7 @@
# pulled when running in TaskCluster
# the target.condprof.tests.tar.gz archive pulls those dependencies
# directly into the condprof project root.
./mozfile
./mozprofile
./mozdevice
./mozlog

View File

@ -0,0 +1,6 @@
./mozbase/mozfile
./mozbase/mozprofile
./mozbase/mozlog
requests==2.22.0
pyyaml==5.1.2

View File

@ -1,6 +1,5 @@
# pulled when running locally
../mozbase/mozfile
../mozbase/mozprofile
../mozbase/mozdevice
../mozbase/mozlog
requests==2.22.0
pyyaml==5.1.2

View File

@ -0,0 +1,8 @@
# pulled when running tox locally
-r requirements/local.txt
pytest
pytest-cov
pytest-random-order
coveralls
responses

View File

@ -7,7 +7,7 @@ PY3 = sys.version_info.major == 3
if PY3:
entry_points = """
[console_scripts]
cp-creator = condprof.runner:main
cp-creator = condprof.main:main
cp-client = condprof.client:main
"""
else:

View File

@ -1,5 +0,0 @@
pytest
pytest-cov
pytest-random-order
coveralls
responses

View File

@ -4,8 +4,7 @@ envlist = py36,flake8
[testenv]
passenv = TRAVIS TRAVIS_JOB_ID TRAVIS_BRANCH
deps = -rtox-requirements.txt
-rlocal-requirements.txt
deps = -rrequirements/tox.txt
commands =
pytest --random-order-bucket=global -sv --cov-report= --cov-config .coveragerc --cov condprof condprof/tests
- coverage report -m