tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

taskcluster-run.py (4745B)


      1 #!/usr/bin/env python3
      2 # mypy: allow-untyped-defs
      3 
      4 import argparse
      5 import gzip
      6 import logging
      7 import os
      8 import shutil
      9 import subprocess
     10 import sys
     11 
     12 
     13 def get_browser_args(product, channel, artifact_path):
     14    if product == "firefox":
     15        local_binary = os.path.expanduser(os.path.join("~", "build", "firefox", "firefox"))
     16        if os.path.exists(local_binary):
     17            return ["--binary=%s" % local_binary]
     18        print("WARNING: Local firefox binary not found")
     19        return ["--install-browser", "--install-webdriver"]
     20    if product == "firefox_android":
     21        return ["--install-browser", "--install-webdriver", "--logcat-dir", artifact_path]
     22    if product == "servo":
     23        return ["--install-browser", "--processes=12"]
     24    if product == "chrome" or product == "chromium":
     25        # Taskcluster machines do not have GPUs, so use software rendering via --enable-swiftshader.
     26        return ["--enable-swiftshader", "--install-browser", "--install-webdriver"]
     27    if product in ["webkitgtk_minibrowser", "wpewebkit_minibrowser"]:
     28        # Using 4 parallel jobs gives 4x speed-up even on a 1-core machine and doesn't cause extra timeouts.
     29        # See: https://github.com/web-platform-tests/wpt/issues/38723#issuecomment-1470938179
     30        return ["--install-browser", "--processes=4"]
     31    return []
     32 
     33 
     34 def find_wptreport(args):
     35    parser = argparse.ArgumentParser()
     36    parser.add_argument('--log-wptreport')
     37    return parser.parse_known_args(args)[0].log_wptreport
     38 
     39 
     40 def find_wptscreenshot(args):
     41    parser = argparse.ArgumentParser()
     42    parser.add_argument('--log-wptscreenshot')
     43    return parser.parse_known_args(args)[0].log_wptscreenshot
     44 
     45 
     46 def gzip_file(filename, delete_original=True):
     47    with open(filename, 'rb') as f_in:
     48        with gzip.open('%s.gz' % filename, 'wb') as f_out:
     49            shutil.copyfileobj(f_in, f_out)
     50    if delete_original:
     51        os.unlink(filename)
     52 
     53 
     54 def main(product, channel, commit_range, artifact_path, wpt_args):
     55    """Invoke the `wpt run` command according to the needs of the Taskcluster
     56    continuous integration service."""
     57 
     58    logger = logging.getLogger("tc-run")
     59    logger.setLevel(logging.INFO)
     60    handler = logging.StreamHandler()
     61    handler.setFormatter(
     62        logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
     63    )
     64    logger.addHandler(handler)
     65 
     66    subprocess.call(['python3', './wpt', 'manifest-download'])
     67 
     68    if commit_range:
     69        logger.info(
     70            "Running tests affected in range '%s'..." % commit_range
     71        )
     72        wpt_args += ['--affected', commit_range]
     73    else:
     74        logger.info("Running all tests")
     75 
     76    wpt_args += [
     77        "--log-mach-level=info",
     78        "--log-mach=-",
     79        "-y",
     80        "--no-pause",
     81        "--no-restart-on-unexpected",
     82        "--install-fonts",
     83        "--verify-log-full"
     84    ]
     85    # Enable headless mode for WPE MiniBrowser and Servo because they do not work under Xvfb/X11 (needs Wayland)
     86    wpt_args.append("--headless" if product in ("wpewebkit_minibrowser", "servo") else "--no-headless")
     87 
     88    wpt_args += get_browser_args(product, channel, artifact_path)
     89 
     90    # Hack to run servo with one process only for wdspec
     91    if product == "servo" and "--test-type=wdspec" in wpt_args:
     92        wpt_args = [item for item in wpt_args if not item.startswith("--processes")]
     93 
     94    wpt_args.append(product)
     95 
     96    command = ["python3", "./wpt", "run"] + wpt_args
     97 
     98    logger.info("Executing command: %s" % " ".join(command))
     99    with open(os.path.join(artifact_path, "checkrun.md"), "a") as f:
    100        f.write("\n**WPT Command:** `%s`\n\n" % " ".join(command))
    101 
    102    retcode = subprocess.call(command, env=dict(os.environ, TERM="dumb"))
    103    if retcode != 0:
    104        sys.exit(retcode)
    105 
    106    wptreport = find_wptreport(wpt_args)
    107    if wptreport:
    108        gzip_file(wptreport)
    109    wptscreenshot = find_wptscreenshot(wpt_args)
    110    if wptscreenshot:
    111        gzip_file(wptscreenshot)
    112 
    113 
    114 if __name__ == "__main__":
    115    parser = argparse.ArgumentParser(description=main.__doc__)
    116    parser.add_argument("--commit-range",
    117                        help="""Git commit range. If specified, this will be
    118                             supplied to the `wpt tests-affected` command to
    119                             determine the list of test to execute""")
    120    parser.add_argument("--artifact-path", default="/home/test/artifacts/",
    121                        help="Path to store output files")
    122    parser.add_argument("product", help="Browser to run tests in")
    123    parser.add_argument("channel", help="Channel of the browser")
    124    parser.add_argument("wpt_args", nargs="*",
    125                        help="Arguments to forward to `wpt run` command")
    126    main(**vars(parser.parse_args()))  # type: ignore