Bug 1309933 - Import wpt-tools manifest changes from upstream, a=testonly
authorJames Graham <james@hoppipolla.co.uk>
Wed, 12 Oct 2016 19:07:30 +0100
changeset 323430 c59e198408e1fb0c36091872ecd58ffd13c25006
parent 323429 843c954493efe2143df2ce6e28b8a12cd95e0853
child 323431 7284d58972a75c7281dc83a684f6ba56125a0b1e
push id30978
push usercbook@mozilla.com
push dateMon, 21 Nov 2016 14:44:46 +0000
treeherdermozilla-central@0534254e9a40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1309933
milestone53.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 1309933 - Import wpt-tools manifest changes from upstream, a=testonly Including unlanded PR to allow worker tests to have a long timeout set MozReview-Commit-ID: 5Au4uEzmGEk
testing/web-platform/tests/tools/manifest/log.py
testing/web-platform/tests/tools/manifest/sourcefile.py
testing/web-platform/tests/tools/manifest/tests/test_sourcefile.py
testing/web-platform/tests/tools/serve/serve.py
--- a/testing/web-platform/tests/tools/manifest/log.py
+++ b/testing/web-platform/tests/tools/manifest/log.py
@@ -1,8 +1,8 @@
 import logging
 
-logging.basicConfig()
 logger = logging.getLogger("manifest")
+logger.addHandler(logging.StreamHandler())
 logger.setLevel(logging.DEBUG)
 
 def get_logger():
     return logger
--- a/testing/web-platform/tests/tools/manifest/sourcefile.py
+++ b/testing/web-platform/tests/tools/manifest/sourcefile.py
@@ -1,23 +1,25 @@
 import os
+import re
 from six.moves.urllib.parse import urljoin
 from fnmatch import fnmatch
 try:
     from xml.etree import cElementTree as ElementTree
 except ImportError:
     from xml.etree import ElementTree
 
 import html5lib
 
 from . import vcs
 from .item import Stub, ManualTest, WebdriverSpecTest, RefTest, TestharnessTest
 from .utils import rel_path_to_url, is_blacklisted, ContextManagerBytesIO, cached_property
 
 wd_pattern = "*.py"
+meta_re = re.compile("//\s*<meta>\s*(\w*)=(.*)$")
 
 def replace_end(s, old, new):
     """
     Given a string `s` that ends with `old`, replace that occurrence of `old`
     with `new`.
     """
     assert s.endswith(old)
     return s[:-len(old)] + new
@@ -199,16 +201,25 @@ class SourceFile(object):
         """List of ElementTree Elements corresponding to nodes in a test that
         specify timeouts"""
         return self.root.findall(".//{http://www.w3.org/1999/xhtml}meta[@name='timeout']")
 
     @cached_property
     def timeout(self):
         """The timeout of a test or reference file. "long" if the file has an extended timeout
         or None otherwise"""
+        if self.name_is_worker:
+            with self.open() as f:
+                for line in f:
+                    m = meta_re.match(line)
+                    if m and m.groups()[0] == "timeout":
+                        if m.groups()[1].lower() == "long":
+                            return "long"
+                        return
+
         if not self.root:
             return
 
         if self.timeout_nodes:
             timeout_str = self.timeout_nodes[0].attrib.get("content", None)
             if timeout_str and timeout_str.lower() == "long":
                 return timeout_str
 
@@ -326,17 +337,18 @@ class SourceFile(object):
 
         elif self.name_is_multi_global:
             rv = [
                 TestharnessTest(self, replace_end(self.url, ".any.js", ".any.html")),
                 TestharnessTest(self, replace_end(self.url, ".any.js", ".any.worker.html")),
             ]
 
         elif self.name_is_worker:
-            rv = [TestharnessTest(self, replace_end(self.url, ".worker.js", ".worker.html"))]
+            rv = [TestharnessTest(self, replace_end(self.url, ".worker.js", ".worker.html"),
+                                  timeout=self.timeout)]
 
         elif self.name_is_webdriver:
             rv = [WebdriverSpecTest(self, self.url)]
 
         elif self.content_is_testharness:
             rv = []
             for variant in self.test_variants:
                 url = self.url + variant
--- a/testing/web-platform/tests/tools/manifest/tests/test_sourcefile.py
+++ b/testing/web-platform/tests/tools/manifest/tests/test_sourcefile.py
@@ -57,16 +57,26 @@ def test_worker():
     assert not s.name_is_multi_global
     assert s.name_is_worker
     assert not s.name_is_reference
 
     assert not s.content_is_testharness
 
     assert items(s) == [("testharness", "/html/test.worker.html")]
 
+def test_worker_long_timeout():
+    s = create("html/test.worker.js",
+               contents="""// <meta> timeout=long
+importScripts('/resources/testharnes.js')
+test()""")
+
+    manifest_items = s.manifest_items()
+    assert len(manifest_items) == 1
+    assert manifest_items[0].timeout == "long"
+
 
 def test_multi_global():
     s = create("html/test.any.js")
     assert not s.name_is_non_test
     assert not s.name_is_manual
     assert s.name_is_multi_global
     assert not s.name_is_worker
     assert not s.name_is_reference
--- a/testing/web-platform/tests/tools/serve/serve.py
+++ b/testing/web-platform/tests/tools/serve/serve.py
@@ -13,48 +13,69 @@ import traceback
 import urllib2
 import uuid
 from collections import defaultdict, OrderedDict
 from multiprocessing import Process, Event
 
 from ..localpaths import repo_root
 
 import sslutils
+from manifest.sourcefile import meta_re
 from wptserve import server as wptserve, handlers
 from wptserve import stash
 from wptserve.logger import set_logger
+from wptserve.handlers import filesystem_path
 from mod_pywebsocket import standalone as pywebsocket
 
 def replace_end(s, old, new):
     """
     Given a string `s` that ends with `old`, replace that occurrence of `old`
     with `new`.
     """
     assert s.endswith(old)
     return s[:-len(old)] + new
 
 
 class WorkersHandler(object):
-    def __init__(self):
+    def __init__(self, base_path=None, url_base="/"):
+        self.base_path = base_path
+        self.url_base = url_base
         self.handler = handlers.handler(self.handle_request)
 
     def __call__(self, request, response):
         return self.handler(request, response)
 
     def handle_request(self, request, response):
         worker_path = replace_end(request.url_parts.path, ".worker.html", ".worker.js")
+        meta = self._get_meta(request)
         return """<!doctype html>
 <meta charset=utf-8>
+%(meta)s
 <script src="/resources/testharness.js"></script>
 <script src="/resources/testharnessreport.js"></script>
 <div id=log></div>
 <script>
-fetch_tests_from_worker(new Worker("%s"));
+fetch_tests_from_worker(new Worker("%(worker_path)s"));
 </script>
-""" % (worker_path,)
+""" % {"meta": meta, "worker_path": worker_path}
+
+    def _get_meta(self, request):
+        path = filesystem_path(self.base_path, request, self.url_base)
+        path = path.replace(".worker.html", ".worker.js")
+        meta_values = []
+        with open(path) as f:
+            for line in f:
+                m = meta_re.match(line)
+                if m:
+                    name, content = m.groups()
+                    name = name.replace('"', '\\"').replace(">", "&gt;")
+                    content = content.replace('"', '\\"').replace(">", "&gt;")
+                    meta_values.append((name, content))
+        return "\n".join('<meta name="%s" content="%s">' % item for item in meta_values)
+
 
 
 class AnyHtmlHandler(object):
     def __init__(self):
         self.handler = handlers.handler(self.handle_request)
 
     def __call__(self, request, response):
         return self.handler(request, response)