Bug 1370203 - Change wptrun to raise an exception instead of exiting directly, r=farre
authorJames Graham <james@hoppipolla.co.uk>
Mon, 05 Jun 2017 13:28:49 +0100
changeset 412824 0ec65d58e0ae4baf5e7ba1c47ea7b56bd03d2272
parent 412823 64af9e5dd9e148dd2b8392d233025a596193ae41
child 412825 ae7d51d0a455bda907d599f7f127c135ad2b3dff
push id1490
push usermtabara@mozilla.com
push dateMon, 31 Jul 2017 14:08:16 +0000
treeherdermozilla-release@70e32e6bf15e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersfarre
bugs1370203
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1370203 - Change wptrun to raise an exception instead of exiting directly, r=farre This makes integration with other frontends a little easier. MozReview-Commit-ID: 3gGeJqMPiZf
testing/web-platform/tests/tools/wptrun.py
--- a/testing/web-platform/tests/tools/wptrun.py
+++ b/testing/web-platform/tests/tools/wptrun.py
@@ -9,16 +9,19 @@ from distutils.spawn import find_executa
 
 import localpaths
 from browserutils import browser, utils, virtualenv
 logger = None
 
 wpt_root = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
 
 
+class WptrunError(Exception):
+    pass
+
 class WptrunnerHelpAction(argparse.Action):
     def __init__(self,
                  option_strings,
                  dest=argparse.SUPPRESS,
                  default=argparse.SUPPRESS,
                  help=None):
         super(WptrunnerHelpAction, self).__init__(
             option_strings=option_strings,
@@ -59,79 +62,86 @@ def exit(msg):
 def args_general(kwargs):
     kwargs.set_if_none("tests_root", wpt_root)
     kwargs.set_if_none("metadata_root", wpt_root)
     kwargs.set_if_none("manifest_update", True)
 
     if kwargs["ssl_type"] == "openssl":
         if not find_executable(kwargs["openssl_binary"]):
             if os.uname()[0] == "Windows":
-                exit("""OpenSSL binary not found. If you need HTTPS tests, install OpenSSL from
+                raise WptrunError("""OpenSSL binary not found. If you need HTTPS tests, install OpenSSL from
 
 https://slproweb.com/products/Win32OpenSSL.html
 
 Ensuring that libraries are added to /bin and add the resulting bin directory to
 your PATH.
 
 Otherwise run with --ssl-type=none""")
             else:
-                exit("""OpenSSL not found. If you don't need HTTPS support run with --ssl-type=none,
+                raise WptrunError("""OpenSSL not found. If you don't need HTTPS support run with --ssl-type=none,
 otherwise install OpenSSL and ensure that it's on your $PATH.""")
 
 
 def check_environ(product):
     if product != "firefox":
-        expected_hosts = set(["web-platform.test",
-                              "www.web-platform.test",
-                              "www1.web-platform.test",
-                              "www2.web-platform.test",
-                              "xn--n8j6ds53lwwkrqhv28a.web-platform.test",
-                              "xn--lve-6lad.web-platform.test",
-                              "nonexistent-origin.web-platform.test"])
+        expected_hosts = ["web-platform.test",
+                          "www.web-platform.test",
+                          "www1.web-platform.test",
+                          "www2.web-platform.test",
+                          "xn--n8j6ds53lwwkrqhv28a.web-platform.test",
+                          "xn--lve-6lad.web-platform.test",
+                          "nonexistent-origin.web-platform.test"]
+        missing_hosts = set(expected_hosts)
         if platform.uname()[0] != "Windows":
             hosts_path = "/etc/hosts"
         else:
             hosts_path = "C:\Windows\System32\drivers\etc\hosts"
         with open(hosts_path, "r") as f:
             for line in f:
                 line = line.split("#", 1)[0].strip()
                 parts = line.split()
                 if len(parts) == 2:
                     host = parts[1]
-                    expected_hosts.discard(host)
-            if expected_hosts:
-                exit("""Missing hosts file configuration for %s.
-See README.md for more details.""" % ",".join(expected_hosts))
+                    missing_hosts.discard(host)
+            if missing_hosts:
+                raise WptrunError("""Missing hosts file configuration. Expected entries like:
+
+%s
+
+See README.md for more details.""" % "\n".join("%s\t%s" %
+                                               ("127.0.0.1" if "nonexistent" not in host else "0.0.0.0", host)
+                                               for host in expected_hosts))
+
 
 def prompt_install(component, prompt):
     if not prompt:
         return True
     while True:
         resp = raw_input("Download and install %s [Y/n]? " % component).strip().lower()
         if not resp or resp == "y":
             return True
         elif resp == "n":
             return False
 
 
 def args_firefox(venv, kwargs, firefox, prompt=True):
     if kwargs["binary"] is None:
         binary = firefox.find_binary()
         if binary is None:
-            exit("""Firefox binary not found on $PATH.
+            raise WptrunError("""Firefox binary not found on $PATH.
 
 Install Firefox or use --binary to set the binary path""")
         kwargs["binary"] = binary
 
     if kwargs["certutil_binary"] is None and kwargs["ssl_type"] != "none":
         certutil = firefox.find_certutil()
 
         if certutil is None:
             # Can't download this for now because it's missing the libnss3 library
-            exit("""Can't find certutil.
+            raise WptrunError("""Can't find certutil.
 
 This must be installed using your OS package manager or directly e.g.
 
 Debian/Ubuntu:
 sudo apt install libnss3-tools
 
 macOS/Homebrew:
 brew install nss
@@ -194,31 +204,31 @@ def args_chrome(venv, kwargs, chrome, pr
                 print("Downloading chromedriver")
                 webdriver_binary = chrome.install_webdriver(dest=venv.bin_path)
         else:
             print("Using webdriver binary %s" % webdriver_binary)
 
         if webdriver_binary:
             kwargs["webdriver_binary"] = webdriver_binary
         else:
-            exit("Unable to locate or install chromedriver binary")
+            raise WptrunError("Unable to locate or install chromedriver binary")
 
 
 def setup_chrome(venv, kwargs, prompt=True):
     chrome = browser.Chrome()
     args_chrome(venv, kwargs, chrome, prompt)
     venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", chrome.requirements))
 
 
 def args_edge(venv, kwargs, edge, prompt=True):
     if kwargs["webdriver_binary"] is None:
         webdriver_binary = edge.find_webdriver()
 
         if webdriver_binary is None:
-            exit("""Unable to find WebDriver and we aren't yet clever enough to work out which
+            raise WptrunError("""Unable to find WebDriver and we aren't yet clever enough to work out which
 version to download. Please go to the following URL and install the correct
 version for your Edge/Windows release somewhere on the %PATH%:
 
 https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/
  """)
         kwargs["webdriver_binary"] = webdriver_binary
 
 
@@ -232,17 +242,17 @@ def setup_sauce(kwargs):
     raise NotImplementedError
 
 
 def args_servo(venv, kwargs, servo, prompt=True):
     if kwargs["binary"] is None:
         binary = servo.find_binary()
 
         if binary is None:
-            exit("Unable to find servo binary on the PATH")
+            raise WptrunError("Unable to find servo binary on the PATH")
         kwargs["binary"] = binary
 
 
 def setup_servo(venv, kwargs, prompt=True):
     servo = browser.Servo()
     args_servo(venv, kwargs, servo, prompt)
     venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", servo.requirements))
 
@@ -268,41 +278,44 @@ def setup_wptrunner(venv, product, tests
 
     kwargs["product"] = product
     kwargs["test_list"] = tests
 
     check_environ(product)
     args_general(kwargs)
 
     if product not in product_setup:
-        exit("Unsupported product %s" % product)
+        raise WptrunError("Unsupported product %s" % product)
 
     product_setup[product](venv, kwargs, prompt)
 
     wptcommandline.check_args(kwargs)
 
     wptrunner_path = os.path.join(wpt_root, "tools", "wptrunner")
 
     venv.install_requirements(os.path.join(wptrunner_path, "requirements.txt"))
 
     return kwargs
 
 
 def main():
-    parser = create_parser()
-    args = parser.parse_args()
+    try:
+        parser = create_parser()
+        args = parser.parse_args()
 
-    venv = virtualenv.Virtualenv(os.path.join(wpt_root, "_venv_%s") % platform.uname()[0])
-    venv.start()
-    venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", "requirements.txt"))
-    venv.install("requests")
+        venv = virtualenv.Virtualenv(os.path.join(wpt_root, "_venv_%s") % platform.uname()[0])
+        venv.start()
+        venv.install_requirements(os.path.join(wpt_root, "tools", "wptrunner", "requirements.txt"))
+        venv.install("requests")
 
-    kwargs = setup_wptrunner(venv, args.product, args.tests, args.wptrunner_args, prompt=args.prompt)
-    from wptrunner import wptrunner
-    wptrunner.start(**kwargs)
+        kwargs = setup_wptrunner(venv, args.product, args.tests, args.wptrunner_args, prompt=args.prompt)
+        from wptrunner import wptrunner
+        wptrunner.start(**kwargs)
+    except WptrunError as e:
+        exit(e.message)
 
 
 if __name__ == "__main__":
     import pdb
     try:
         main()
     except:
         pdb.post_mortem()