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 375133 60ef59a1b9e61a4a4c285b6c4495e284750310af
parent 375132 2f984d729523af6bdcbfd4d1b624658b7e6cbd0a
child 375134 046d857def353c1ebc3f29572ef3baaeaa14a9cd
push id6996
push userjlorenzo@mozilla.com
push dateMon, 06 Mar 2017 20:48:21 +0000
treeherdermozilla-beta@d89512dab048 [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,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)