From 6011e485b4c969f53e0ddb94aa25b5e1e495501e Mon Sep 17 00:00:00 2001 From: Richard Pappalardo Date: Wed, 15 Jun 2016 10:10:20 +0100 Subject: [PATCH] Refactor cloud-services centric args (#92) * Add multi prefs-dirs option (WIP). * Complete prefs path option --prefs-dirs replaces cloud-services centric -a -t test-type and -f prefs with a single -d * Fix string split on prefs_dirs * Fix none check on prefs_dirs in firefox_profile * Add support for offline use * flake8 * README update for --no-download option --- README.rst | 22 +++++++++++++- fftool/__init__.py | 1 - fftool/arg_parser.py | 28 +++++++----------- fftool/firefox_download.py | 29 +++++++++++++------ fftool/firefox_profile.py | 59 +++++++++++++++++++++++--------------- fftool/main.py | 9 +++--- 6 files changed, 92 insertions(+), 56 deletions(-) diff --git a/README.rst b/README.rst index d2ae3c9..a78ae44 100644 --- a/README.rst +++ b/README.rst @@ -181,6 +181,25 @@ Example prefs.ini: [vegetables] asparagus = green + +Offline use +===================== + +ff-tool has a --no-download option. + +:: + + $ ff --no-download + + +This may may be useful if wifi is down / internet unavailable or you simply want +to use ff-tool with a cached version of Firefox. + +NOTE: +The --no-download option will not work if you don't have a cached version of firefox +in your _temp (cache) folder. + + Cloud Services (only) ===================== @@ -198,5 +217,6 @@ new one with that name. :: - $ ff -c beta -p my_cool_profile1 -a loop-server -t e2e-test -f stage + $ ff -c beta -p my_cool_profile1 -d loop-server/e2e-test:stage + $ ff -c nightly -p my_cool_profile2 -d shavar/e2e-test:stage+moztestpub diff --git a/fftool/__init__.py b/fftool/__init__.py index 4464896..154296d 100644 --- a/fftool/__init__.py +++ b/fftool/__init__.py @@ -20,7 +20,6 @@ DIR_CONFIGS = '{0}/configs'.format(HERE) DIR_TEMP_PROFILES = os.path.join(DIR_TEMP, 'profiles') PATH_PREFS_ROOT = os.environ.get('PATH_PREFS_ROOT') FILE_PREFS = 'prefs.ini' -PLUS = '+' Log = Outlawg() diff --git a/fftool/arg_parser.py b/fftool/arg_parser.py index 46c66a4..ad18859 100644 --- a/fftool/arg_parser.py +++ b/fftool/arg_parser.py @@ -22,23 +22,11 @@ def arg_parser(): ) parser.add_argument( - '-a', - '--app', - help="Name of the application to test (ie: loop-server)." - ) - - parser.add_argument( - '-t', - '--test-type', - help="Name of the test-type (ie: e2e-test, stack-check)." - ) - - parser.add_argument( - '-f', - '--prefs', - help='prefs to specify (i.e. dev, stage, prod) or \ - specify multiple prefs contatenated with a "+" \ - (i.e. stage+mozfull, pre-prod+mozstd, etc.)' + '-d', + '--prefs-dirs', + action='append', + help="Relative path(s) to prefs file(s) - OK to specify multiple. \ + NOTE: pref file must be called: prefs.ini" ) parser.add_argument( @@ -55,6 +43,12 @@ def arg_parser(): https://developer.mozilla.org/docs/Mozilla/Projects/NSPR/Reference/NSPR_LOG_MODULES" # noqa ) + parser.add_argument( + '--no-download', + action='store_true', + help="Use cached Firefox (no download)." + ) + parser.add_argument( '--install-only', action='store_true', diff --git a/fftool/firefox_download.py b/fftool/firefox_download.py index aeba23c..0c2f5ff 100644 --- a/fftool/firefox_download.py +++ b/fftool/firefox_download.py @@ -7,6 +7,7 @@ import os import time +from requests.exceptions import ConnectionError import ConfigParser as configparser # Python 2 only! from outlawg import Outlawg @@ -30,7 +31,13 @@ Log = Outlawg() def modification_date(filename): - return os.path.getmtime(filename) + try: + mtime = os.path.getmtime(filename) + except OSError as e: + Log.header('ERROR!') + print(e) + exit() + return mtime def download(channel): @@ -50,14 +57,18 @@ def download(channel): args = {"channel": channel, "download_path": download_path} print("Downloading {channel} to {download_path}".format(**args)) - scraper = FactoryScraper( - ch_type, - version=ch_version, - branch=ch_branch, - destination=download_path, - platform=ch_platform - ) - scraper.download() + try: + scraper = FactoryScraper( + ch_type, + version=ch_version, + branch=ch_branch, + destination=download_path, + platform=ch_platform + ) + scraper.download() + except ConnectionError: + Log.header('WARNING!') + print('HTTPS connection unavailable.\nLooking for cached browser...') is_recent_file = modification_date(download_path) > SCRIPT_START_TIME firefox_bin = env.get(channel, 'PATH_FIREFOX_BIN_ENV') diff --git a/fftool/firefox_profile.py b/fftool/firefox_profile.py index b5ffed7..e8e5f81 100644 --- a/fftool/firefox_profile.py +++ b/fftool/firefox_profile.py @@ -1,5 +1,5 @@ """This module creates a Firefox Profile by concatenating the -following preferences files: +preferences files specified by --prefs-dirs, like so: - ./_utils/prefs.ini - .//prefs.ini - .///prefs.ini @@ -20,7 +20,6 @@ from fftool import ( DIR_CONFIGS, PATH_PREFS_ROOT, FILE_PREFS, - PLUS ) @@ -43,28 +42,41 @@ def valid_path_list(prefs, valid_paths, path_app): return valid_paths -def prefs_paths(application, test_type, option_prefs=''): +def prefs_paths(prefs_dirs): + # we'll always use seed with this global set of testing prefs path_global = os.path.join(PATH_PREFS_GLOBAL, DIR_CONFIGS, FILE_PREFS) valid_paths = [path_global] - # convert prefs option to an iterable - if option_prefs is None: - option_prefs = '' - prefs = option_prefs.split(PLUS) + # user can specify prefs for a given file like so: + # -d my/path/here + # or + # -d my/path/here:section1+section2+section3 + # (in this case we'll only grab specified sections) + # We'll also convert this to format mozprofile can work with: + # /Abs/path/my/path/here:section1 + # /Abs/path/my/path/here:section2 + # /Abs/path/my/path/here:section3 - if application: - path_app_dir = os.path.join(PATH_PREFS_ROOT, application) + for prefs_dir in prefs_dirs: + prefs_dir_chunks = prefs_dir.split(':') + path_pref_file = os.path.join( + PATH_PREFS_ROOT, + prefs_dir_chunks[0], + FILE_PREFS + ) + # TODO: + # add in valid_paths_list checker + if ':' in prefs_dir: + if '+' in prefs_dir: + sections = prefs_dir_chunks[1].split('+') + else: + sections = [prefs_dir_chunks[1]] - path_app = os.path.join(path_app_dir, FILE_PREFS) - - valid_paths = valid_path_list(prefs, valid_paths, path_app) - - if test_type: - path_app_test_type = os.path.join( - path_app_dir, test_type, FILE_PREFS) - - valid_paths = valid_path_list(prefs, valid_paths, - path_app_test_type) + for section in sections: + path_tmp = '{0}:{1}'.format(path_pref_file, section) + valid_paths.append(path_tmp) + else: + valid_paths.append(path_pref_file) return valid_paths @@ -83,8 +95,7 @@ def clean_profiles(): shutil.rmtree(profile_dir, True) -def create_mozprofile(profile_dir, application=None, test_type=None, env=None): - +def create_mozprofile(profile_dir, prefs_dirs=None, env=None): # Ensure base `_temp/profiles/` dir exists before trying to # create a nested directory. if not os.path.exists(BASE_PROFILE_DIR): @@ -106,8 +117,10 @@ def create_mozprofile(profile_dir, application=None, test_type=None, env=None): prefs = Preferences() - for path in prefs_paths(application, test_type, env): - prefs.add_file(path) + if prefs_dirs: + for path in prefs_paths(prefs_dirs): + print('PREFS.ADD_FILE(PATH): ' + path) + prefs.add_file(path) # Add custom user pref: `fftool.profile.name` # so we can go to about:config and verify our current profile. diff --git a/fftool/main.py b/fftool/main.py index 0aaf5d1..56c734f 100755 --- a/fftool/main.py +++ b/fftool/main.py @@ -18,7 +18,7 @@ def main(): print('FF-TOOL VERSION: {0}'.format(__version__)) return - if options.app and not PATH_PREFS_ROOT: + if (options.prefs_dirs) and not PATH_PREFS_ROOT: Log.header("ERROR") print("Missing path to $PATH_PREFS_ROOT directory.") print("Please set the `PATH_PREFS_ROOT` environment variable and " + @@ -30,7 +30,8 @@ def main(): return # DOWNLOAD/INSTALL - download(options.channel) + if not (options.no_download): + download(options.channel) # If user specified `--install-only`, then # download/install specified channel(s) and exit early. @@ -40,9 +41,7 @@ def main(): # PROFILE profile_path = create_mozprofile( options.profile, - application=options.app, - test_type=options.test_type, - env=options.prefs + prefs_dirs=options.prefs_dirs, ) # LAUNCH