Update web-platform-tests to revision 5e3ea8f49fee68c327388bfd1dd1375a8ce12a0e.

This commit is contained in:
Ms2ger 2015-07-09 14:05:01 +02:00
parent 12195a5c4a
commit bfb96b9448
1166 changed files with 35123 additions and 900 deletions

View file

@ -121,6 +121,7 @@
<th>Failed
<th>Timeouts
<th>Errors
<th>Not Run</th>
</tr>
</thead>
<tbody>
@ -129,6 +130,7 @@
<td class='FAIL'>0
<td class='TIMEOUT'>0
<td class='ERROR'>0
<td class='NOTRUN'>0
</tr>
</tbody>
</table>

View file

@ -153,6 +153,10 @@ td.TIMEOUT {
color: #f6bb42;
}
td.NOTRUN {
color: #00c;
}
td.ERROR {
color: #da4453;
font-weight: bold;

View file

@ -145,7 +145,8 @@ VisualOutput.prototype = {
this.result_count = {"PASS":0,
"FAIL":0,
"ERROR":0,
"TIMEOUT":0};
"TIMEOUT":0,
"NOTRUN":0};
for (var p in this.result_count) {
if (this.result_count.hasOwnProperty(p)) {
this.elem.querySelector("td." + p).textContent = 0;
@ -183,12 +184,19 @@ VisualOutput.prototype = {
var subtest_pass_count = subtests.reduce(function(prev, current) {
return (current.status === "PASS") ? prev + 1 : prev;
}, 0);
var subtest_notrun_count = subtests.reduce(function(prev, current) {
return (current.status === "NOTRUN") ? prev +1 : prev;
}, 0);
var subtests_count = subtests.length;
var test_status;
if (subtest_pass_count === subtests_count &&
(status == "OK" || status == "PASS")) {
test_status = "PASS";
} else if (subtest_notrun_count == subtests_count) {
test_status = "NOTRUN";
} else if (subtests_count > 0 && status === "OK") {
test_status = "FAIL";
} else {
@ -225,7 +233,7 @@ VisualOutput.prototype = {
}
}
var status_arr = ["PASS", "FAIL", "ERROR", "TIMEOUT"];
var status_arr = ["PASS", "FAIL", "ERROR", "TIMEOUT", "NOTRUN"];
for (var i = 0; i < status_arr.length; i++) {
this.elem.querySelector("td." + status_arr[i]).textContent = this.result_count[status_arr[i]];
}
@ -707,7 +715,7 @@ function setup() {
}
window.completion_callback = function(tests, status) {
var harness_status_map = {0:"OK", 1:"ERROR", 2:"TIMEOUT"};
var harness_status_map = {0:"OK", 1:"ERROR", 2:"TIMEOUT", 3:"NOTRUN"};
var subtest_status_map = {0:"PASS", 1:"FAIL", 2:"TIMEOUT", 3:"NOTRUN"};
// this ugly hack is because IE really insists on holding on to the objects it creates in

View file

@ -17,6 +17,7 @@ from .. import localpaths
import sslutils
from wptserve import server as wptserve, handlers
from wptserve import stash
from wptserve.logger import set_logger
from mod_pywebsocket import standalone as pywebsocket
@ -356,7 +357,6 @@ def get_ssl_config(config, external_domains, ssl_environment):
"cert_path": cert_path,
"encrypt_after_connect": config["ssl"]["encrypt_after_connect"]}
def start(config, ssl_environment, routes, **kwargs):
host = config["host"]
domains = get_subdomains(host)
@ -485,12 +485,13 @@ def main():
setup_logger(config["log_level"])
with get_ssl_environment(config) as ssl_env:
config_, servers = start(config, ssl_env, default_routes(), **kwargs)
with stash.StashServer((config["host"], get_port()), authkey=str(uuid.uuid4())):
with get_ssl_environment(config) as ssl_env:
config_, servers = start(config, ssl_env, default_routes(), **kwargs)
try:
while any(item.is_alive() for item in iter_procs(servers)):
for item in iter_procs(servers):
item.join(1)
except KeyboardInterrupt:
logger.info("Shutting down")
try:
while any(item.is_alive() for item in iter_procs(servers)):
for item in iter_procs(servers):
item.join(1)
except KeyboardInterrupt:
logger.info("Shutting down")

View file

@ -0,0 +1,30 @@
W3C 3-clause BSD License
http://www.w3.org/Consortium/Legal/2008/03-bsd-license.html
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
* Redistributions of works must retain the original copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the original copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of the W3C nor the names of its contributors may be
used to endorse or promote products derived from this work without
specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View file

@ -1,6 +1,7 @@
import base64
import cgi
import Cookie
import os
import StringIO
import tempfile
import urlparse
@ -27,7 +28,15 @@ class Server(object):
config = None
def __init__(self, request):
self.stash = stash.Stash(request.url_parts.path)
self._stash = None
self._request = request
@property
def stash(self):
if self._stash is None:
address, authkey = stash.load_env_config()
self._stash = stash.Stash(self._request.url_parts.path, address, authkey)
return self._stash
class InputFile(object):

View file

@ -1,17 +1,76 @@
import base64
import json
import os
import uuid
from multiprocessing import Process
from multiprocessing.managers import BaseManager, DictProxy
class ServerDictManager(BaseManager):
shared_data = {}
def _get_shared():
return ServerDictManager.shared_data
ServerDictManager.register("get_dict",
callable=_get_shared,
proxytype=DictProxy)
class ClientDictManager(BaseManager):
pass
ClientDictManager.register("get_dict")
class StashServer(object):
def __init__(self, address=None, authkey=None):
self.address = address
self.authkey = authkey
self.manager = None
def __enter__(self):
self.manager, self.address, self.authkey = start_server(self.address, self.authkey)
store_env_config(self.address, self.authkey)
def __exit__(self, *args, **kwargs):
if self.manager is not None:
self.manager.shutdown()
def load_env_config():
address, authkey = json.loads(os.environ["WPT_STASH_CONFIG"])
if isinstance(address, list):
address = tuple(address)
else:
address = str(address)
authkey = base64.decodestring(authkey)
return address, authkey
def store_env_config(address, authkey):
authkey = base64.encodestring(authkey)
os.environ["WPT_STASH_CONFIG"] = json.dumps((address, authkey))
def start_server(address=None, authkey=None):
manager = ServerDictManager(address, authkey)
manager.start()
return (manager, manager._address, manager._authkey)
#TODO: Consider expiring values after some fixed time for long-running
#servers
# TODO(kristijanburnik): Provide shared Stash support for WebSockets.
class Stash(object):
"""Key-value store for persisting data across HTTP requests.
"""Key-value store for persisting data across HTTP/S requests.
This data store specifically designed for persisting data across
HTTP requests. It is entirely in-memory so data will not be
persisted across server restarts.
This data store is specifically designed for persisting data across
HTTP and HTTPS requests. The synchronization model is usually done by using
the SyncManager from the multiprocessing module.
This has several unusual properties. Keys are of the form (path,
Stash can be used interchangeably between HTTP and HTTPS requests as both
processes are accessing the same resource (e.g. a Manager.dict).
The WS and WSS servers are currently not supported.
The store has several unusual properties. Keys are of the form (path,
uuid), where path is, by default, the path in the HTTP request and
uuid is a unique id. In addition, the store is write-once, read-once,
i.e. the value associated with a particular key cannot be changed once
@ -19,66 +78,66 @@ class Stash(object):
these properties make it difficult for data to accidentally leak
between different resources or different requests for the same
resource.
"""
data = {}
_proxy = None
def __init__(self, default_path):
def __init__(self, default_path, address=None, authkey=None):
self.default_path = default_path
self.data = self._get_proxy(address, authkey)
def _get_proxy(self, address=None, authkey=None):
if address is None and authkey is None:
Stash._proxy = {}
if Stash._proxy is None:
manager = ClientDictManager(address, authkey)
manager.connect()
Stash._proxy = manager.get_dict()
return Stash._proxy
def _wrap_key(self, key, path):
if path is None:
path = self.default_path
# This key format is required to support using the path. Since the data
# passed into the stash can be a DictProxy which wouldn't detect changes
# when writing to a subdict.
return (str(path), str(uuid.UUID(key)))
def put(self, key, value, path=None):
"""Place a value in the stash.
"""Place a value in the shared stash.
:param key: A UUID to use as the data's key.
:param value: The data to store. This can be any python object.
:param path: The path that has access to read the data (by default
the current request path)"""
if path is None:
path = self.default_path
if path not in self.data:
self.data[path] = PathStash(path)
self.data[path][key] = value
if value is None:
raise ValueError("SharedStash value may not be set to None")
internal_key = self._wrap_key(key, path)
if internal_key in self.data:
raise StashError("Tried to overwrite existing shared stash value "
"for key %s (old value was %s, new value is %s)" %
(internal_key, self[str(internal_key)], value))
else:
self.data[internal_key] = value
def take(self, key, path=None):
"""Remove a value from the stash and return it.
"""Remove a value from the shared stash and return it.
:param key: A UUID to use as the data's key.
:param path: The path that has access to read the data (by default
the current request path)"""
if path is None:
path = self.default_path
internal_key = self._wrap_key(key, path)
value = self.data.get(internal_key, None)
if not value is None:
try:
self.data.pop(internal_key)
except KeyError:
# Silently continue when pop error occurs.
pass
if path in self.data:
value = self.data[path][key]
else:
value = None
return value
class PathStash(dict):
def __init__(self, path):
self.path = path
def __setitem__(self, key, value):
key = uuid.UUID(key)
if value is None:
raise ValueError("Stash value may not be set to None")
if key in self:
raise StashError("Tried to overwrite existing stash value "
"for path %s and key %s (old value was %s, new value is %s)" %
(self.path, key, self[str(key)], value))
else:
dict.__setitem__(self, key, value)
def __getitem__(self, key):
key = uuid.UUID(key)
rv = dict.get(self, key, None)
if rv is not None:
del self[key]
return rv
class StashError(Exception):
pass