[inspector] added inspector test runner [part 4]
- added inspector test suite definition in testcfg.py - added JS infrastructure for tests in protocol-test.js BUG=chromium:635948 R=dgozman@chromium.org,alph@chromium.org Committed: https://crrev.com/4a5f5d0991656a6aa45b0021a0f5ba6a7ceabe15 Review-Url: https://codereview.chromium.org/2370743003 Cr-Original-Commit-Position: refs/heads/master@{#39895} Cr-Commit-Position: refs/heads/master@{#39930}
This commit is contained in:
parent
f0649c8f08
commit
d1191e1b8a
7
test/inspector/inspector.status
Normal file
7
test/inspector/inspector.status
Normal file
@ -0,0 +1,7 @@
|
||||
# Copyright 2016 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
[
|
||||
|
||||
]
|
177
test/inspector/protocol-test.js
Normal file
177
test/inspector/protocol-test.js
Normal file
@ -0,0 +1,177 @@
|
||||
// Copyright 2016 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
InspectorTest = {};
|
||||
InspectorTest._dispatchTable = new Map();
|
||||
InspectorTest._requestId = 0;
|
||||
InspectorTest._dumpInspectorProtocolMessages = false;
|
||||
InspectorTest.eventHandler = {};
|
||||
|
||||
InspectorTest.startDumpingProtocolMessages = function()
|
||||
{
|
||||
InspectorTest._dumpInspectorProtocolMessages = true;
|
||||
}
|
||||
|
||||
InspectorTest.sendCommand = function(method, params, handler)
|
||||
{
|
||||
var requestId = ++InspectorTest._requestId;
|
||||
var messageObject = { "id": requestId, "method": method, "params": params };
|
||||
InspectorTest.sendRawCommand(requestId, JSON.stringify(messageObject), handler);
|
||||
}
|
||||
|
||||
InspectorTest.sendRawCommand = function(requestId, command, handler)
|
||||
{
|
||||
if (InspectorTest._dumpInspectorProtocolMessages)
|
||||
print("frontend: " + command);
|
||||
InspectorTest._dispatchTable.set(requestId, handler);
|
||||
sendMessageToBackend(command);
|
||||
}
|
||||
|
||||
InspectorTest.sendCommandOrDie = function(command, properties, callback)
|
||||
{
|
||||
InspectorTest.sendCommand(command, properties, commandCallback);
|
||||
function commandCallback(msg)
|
||||
{
|
||||
if (msg.error) {
|
||||
InspectorTest.log("ERROR: " + msg.error.message);
|
||||
InspectorTest.completeTest();
|
||||
return;
|
||||
}
|
||||
if (callback)
|
||||
callback(msg.result);
|
||||
}
|
||||
}
|
||||
|
||||
InspectorTest.sendCommandPromise = function(method, params)
|
||||
{
|
||||
return new Promise(fulfill => InspectorTest.sendCommand(method, params, fulfill));
|
||||
}
|
||||
|
||||
InspectorTest.waitForEventPromise = function(eventName)
|
||||
{
|
||||
return new Promise(fulfill => InspectorTest.eventHandler[eventName] = fullfillAndClearListener.bind(null, fulfill));
|
||||
|
||||
function fullfillAndClearListener(fulfill, result)
|
||||
{
|
||||
delete InspectorTest.eventHandler[eventName];
|
||||
fulfill(result);
|
||||
}
|
||||
}
|
||||
|
||||
InspectorTest.dispatchMessage = function(messageObject)
|
||||
{
|
||||
if (InspectorTest._dumpInspectorProtocolMessages)
|
||||
print("backend: " + JSON.stringify(messageObject));
|
||||
try {
|
||||
var messageId = messageObject["id"];
|
||||
if (typeof messageId === "number") {
|
||||
var handler = InspectorTest._dispatchTable.get(messageId);
|
||||
if (handler) {
|
||||
handler(messageObject);
|
||||
InspectorTest._dispatchTable.delete(messageId);
|
||||
}
|
||||
} else {
|
||||
var eventName = messageObject["method"];
|
||||
var eventHandler = InspectorTest.eventHandler[eventName];
|
||||
if (eventHandler)
|
||||
eventHandler(messageObject);
|
||||
}
|
||||
} catch (e) {
|
||||
InspectorTest.log("Exception when dispatching message: " + e + "\n" + e.stack + "\n message = " + JSON.stringify(messageObject, null, 2));
|
||||
InspectorTest.completeTest();
|
||||
}
|
||||
}
|
||||
|
||||
InspectorTest.log = print.bind(null);
|
||||
|
||||
InspectorTest.logObject = function(object, title)
|
||||
{
|
||||
var lines = [];
|
||||
|
||||
function dumpValue(value, prefix, prefixWithName)
|
||||
{
|
||||
if (typeof value === "object" && value !== null) {
|
||||
if (value instanceof Array)
|
||||
dumpItems(value, prefix, prefixWithName);
|
||||
else
|
||||
dumpProperties(value, prefix, prefixWithName);
|
||||
} else {
|
||||
lines.push(prefixWithName + String(value).replace(/\n/g, " "));
|
||||
}
|
||||
}
|
||||
|
||||
function dumpProperties(object, prefix, firstLinePrefix)
|
||||
{
|
||||
prefix = prefix || "";
|
||||
firstLinePrefix = firstLinePrefix || prefix;
|
||||
lines.push(firstLinePrefix + "{");
|
||||
|
||||
var propertyNames = Object.keys(object);
|
||||
propertyNames.sort();
|
||||
for (var i = 0; i < propertyNames.length; ++i) {
|
||||
var name = propertyNames[i];
|
||||
if (!object.hasOwnProperty(name))
|
||||
continue;
|
||||
var prefixWithName = " " + prefix + name + " : ";
|
||||
dumpValue(object[name], " " + prefix, prefixWithName);
|
||||
}
|
||||
lines.push(prefix + "}");
|
||||
}
|
||||
|
||||
function dumpItems(object, prefix, firstLinePrefix)
|
||||
{
|
||||
prefix = prefix || "";
|
||||
firstLinePrefix = firstLinePrefix || prefix;
|
||||
lines.push(firstLinePrefix + "[");
|
||||
for (var i = 0; i < object.length; ++i)
|
||||
dumpValue(object[i], " " + prefix, " " + prefix + "[" + i + "] : ");
|
||||
lines.push(prefix + "]");
|
||||
}
|
||||
|
||||
dumpValue(object, "", title);
|
||||
InspectorTest.log(lines.join("\n"));
|
||||
}
|
||||
|
||||
InspectorTest.completeTest = quit.bind(null);
|
||||
|
||||
InspectorTest.evaluateInPage = function(string, callback)
|
||||
{
|
||||
InspectorTest.sendCommand("Runtime.evaluate", { "expression": string }, function(message) {
|
||||
if (message.error) {
|
||||
InspectorTest.log("Error while executing '" + string + "': " + message.error.message);
|
||||
InspectorTest.completeTest();
|
||||
}
|
||||
else if (callback)
|
||||
callback(message.result.result.value);
|
||||
});
|
||||
};
|
||||
|
||||
InspectorTest.checkExpectation = function(fail, name, messageObject)
|
||||
{
|
||||
if (fail === !!messageObject.error) {
|
||||
InspectorTest.log("PASS: " + name);
|
||||
return true;
|
||||
}
|
||||
|
||||
InspectorTest.log("FAIL: " + name + ": " + JSON.stringify(messageObject));
|
||||
InspectorTest.completeTest();
|
||||
return false;
|
||||
}
|
||||
InspectorTest.expectedSuccess = InspectorTest.checkExpectation.bind(null, false);
|
||||
InspectorTest.expectedError = InspectorTest.checkExpectation.bind(null, true);
|
||||
|
||||
InspectorTest.runTestSuite = function(testSuite)
|
||||
{
|
||||
function nextTest()
|
||||
{
|
||||
if (!testSuite.length) {
|
||||
InspectorTest.completeTest();
|
||||
return;
|
||||
}
|
||||
var fun = testSuite.shift();
|
||||
InspectorTest.log("\nRunning test: " + fun.name);
|
||||
fun(nextTest);
|
||||
}
|
||||
nextTest();
|
||||
}
|
109
test/inspector/testcfg.py
Normal file
109
test/inspector/testcfg.py
Normal file
@ -0,0 +1,109 @@
|
||||
# Copyright 2016 the V8 project authors. All rights reserved.
|
||||
# Use of this source code is governed by a BSD-style license that can be
|
||||
# found in the LICENSE file.
|
||||
|
||||
import itertools
|
||||
import os
|
||||
import re
|
||||
|
||||
from testrunner.local import testsuite
|
||||
from testrunner.local import utils
|
||||
from testrunner.objects import testcase
|
||||
|
||||
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
|
||||
PROTOCOL_TEST_JS = "protocol-test.js"
|
||||
EXPECTED_SUFFIX = "-expected.txt"
|
||||
|
||||
class InspectorProtocolTestSuite(testsuite.TestSuite):
|
||||
|
||||
def __init__(self, name, root):
|
||||
super(InspectorProtocolTestSuite, self).__init__(name, root)
|
||||
|
||||
def ListTests(self, context):
|
||||
tests = []
|
||||
for dirname, dirs, files in os.walk(os.path.join(self.root), followlinks=True):
|
||||
for dotted in [x for x in dirs if x.startswith('.')]:
|
||||
dirs.remove(dotted)
|
||||
dirs.sort()
|
||||
files.sort()
|
||||
for filename in files:
|
||||
if filename.endswith(".js") and filename != PROTOCOL_TEST_JS:
|
||||
fullpath = os.path.join(dirname, filename)
|
||||
relpath = fullpath[len(self.root) + 1 : -3]
|
||||
testname = relpath.replace(os.path.sep, "/")
|
||||
test = testcase.TestCase(self, testname)
|
||||
tests.append(test)
|
||||
return tests
|
||||
|
||||
def GetFlagsForTestCase(self, testcase, context):
|
||||
source = self.GetSourceForTest(testcase)
|
||||
flags_match = re.findall(FLAGS_PATTERN, source)
|
||||
flags = []
|
||||
for match in flags_match:
|
||||
flags += match.strip().split()
|
||||
testname = testcase.path.split(os.path.sep)[-1]
|
||||
testfilename = os.path.join(self.root, testcase.path + self.suffix())
|
||||
protocoltestfilename = os.path.join(self.root, PROTOCOL_TEST_JS)
|
||||
return [ protocoltestfilename, testfilename ] + flags
|
||||
|
||||
def GetSourceForTest(self, testcase):
|
||||
filename = os.path.join(self.root, testcase.path + self.suffix())
|
||||
with open(filename) as f:
|
||||
return f.read()
|
||||
|
||||
def shell(self):
|
||||
return "inspector-test"
|
||||
|
||||
def _IgnoreLine(self, string):
|
||||
"""Ignore empty lines, valgrind output and Android output."""
|
||||
if not string: return True
|
||||
return (string.startswith("==") or string.startswith("**") or
|
||||
string.startswith("ANDROID") or
|
||||
# FIXME(machenbach): The test driver shouldn't try to use slow
|
||||
# asserts if they weren't compiled. This fails in optdebug=2.
|
||||
string == "Warning: unknown flag --enable-slow-asserts." or
|
||||
string == "Try --help for options")
|
||||
|
||||
def IsFailureOutput(self, testcase):
|
||||
file_name = os.path.join(self.root, testcase.path) + EXPECTED_SUFFIX
|
||||
with file(file_name, "r") as expected:
|
||||
expected_lines = expected.readlines()
|
||||
|
||||
def ExpIterator():
|
||||
for line in expected_lines:
|
||||
if line.startswith("#") or not line.strip(): continue
|
||||
yield line.strip()
|
||||
|
||||
def ActIterator(lines):
|
||||
for line in lines:
|
||||
if self._IgnoreLine(line.strip()): continue
|
||||
yield line.strip()
|
||||
|
||||
def ActBlockIterator():
|
||||
"""Iterates over blocks of actual output lines."""
|
||||
lines = testcase.output.stdout.splitlines()
|
||||
start_index = 0
|
||||
found_eqeq = False
|
||||
for index, line in enumerate(lines):
|
||||
# If a stress test separator is found:
|
||||
if line.startswith("=="):
|
||||
# Iterate over all lines before a separator except the first.
|
||||
if not found_eqeq:
|
||||
found_eqeq = True
|
||||
else:
|
||||
yield ActIterator(lines[start_index:index])
|
||||
# The next block of output lines starts after the separator.
|
||||
start_index = index + 1
|
||||
# Iterate over complete output if no separator was found.
|
||||
if not found_eqeq:
|
||||
yield ActIterator(lines)
|
||||
|
||||
for act_iterator in ActBlockIterator():
|
||||
for (expected, actual) in itertools.izip_longest(
|
||||
ExpIterator(), act_iterator, fillvalue=''):
|
||||
if expected != actual:
|
||||
return True
|
||||
return False
|
||||
|
||||
def GetSuite(name, root):
|
||||
return InspectorProtocolTestSuite(name, root)
|
Loading…
Reference in New Issue
Block a user