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 358157 60ef59a1b9e61a4a4c285b6c4495e284750310af
parent 358156 2f984d729523af6bdcbfd4d1b624658b7e6cbd0a
child 358158 046d857def353c1ebc3f29572ef3baaeaa14a9cd
push id10621
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 16:02:43 +0000
treeherdermozilla-aurora@dca7b42e6c67 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1309933
milestone53.0a1
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,25 +1,27 @@
 import hashlib
 import re
 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 XMLParser
 from .item import Stub, ManualTest, WebdriverSpecTest, RefTestNode, RefTest, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest
 from .utils import rel_path_to_url, ContextManagerBytesIO, cached_property
 
 wd_pattern = "*.py"
+meta_re = re.compile("//\s*<meta>\s*(\w*)=(.*)$")
 
 reference_file_re = re.compile(r'(^|[\-_])(not)?ref[0-9]*([\-_]|$)')
 
 def replace_end(s, old, new):
     """
     Given a string `s` that ends with `old`, replace that occurrence of `old`
     with `new`.
     """
@@ -248,16 +250,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 self.root is None:
             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
 
@@ -446,17 +457,18 @@ class SourceFile(object):
         elif self.name_is_multi_global:
             rv = TestharnessTest.item_type, [
                 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.item_type,
-                  [TestharnessTest(self, replace_end(self.url, ".worker.js", ".worker.html"))])
+                  [TestharnessTest(self, replace_end(self.url, ".worker.js", ".worker.html"),
+                                   timeout=self.timeout)])
 
         elif self.name_is_webdriver:
             rv = WebdriverSpecTest.item_type, [WebdriverSpecTest(self, self.url)]
 
         elif self.content_is_css_manual and not self.name_is_reference:
             rv = ManualTest.item_type, [ManualTest(self, self.url)]
 
         elif self.content_is_testharness:
--- a/testing/web-platform/tests/tools/manifest/tests/test_sourcefile.py
+++ b/testing/web-platform/tests/tools/manifest/tests/test_sourcefile.py
@@ -119,16 +119,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 not s.name_is_visual
     assert s.name_is_multi_global
     assert not s.name_is_worker
--- 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)