Merge from Chromium at DEPS revision r213371
This commit was generated by merge_to_master.py.
Change-Id: I03fae1c1dae6e5de12e56e0a6c3780252291bfae
diff --git a/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.cpp b/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.cpp
index 0cd4164..1b2b9ff 100644
--- a/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.cpp
+++ b/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.cpp
@@ -258,8 +258,6 @@
bindMethod("setPrinting", &TestRunner::setPrinting);
bindMethod("setShouldStayOnPageAfterHandlingBeforeUnload", &TestRunner::setShouldStayOnPageAfterHandlingBeforeUnload);
bindMethod("setWillSendRequestClearHeader", &TestRunner::setWillSendRequestClearHeader);
- bindMethod("setWillSendRequestReturnsNull", &TestRunner::setWillSendRequestReturnsNull);
- bindMethod("setWillSendRequestReturnsNullOnRedirect", &TestRunner::setWillSendRequestReturnsNullOnRedirect);
bindMethod("dumpResourceRequestPriorities", &TestRunner::dumpResourceRequestPriorities);
// The following methods interact with the WebTestProxy.
@@ -419,8 +417,6 @@
m_sweepHorizontally = false;
m_isPrinting = false;
m_shouldStayOnPageAfterHandlingBeforeUnload = false;
- m_shouldBlockRedirects = false;
- m_willSendRequestShouldReturnNull = false;
m_shouldDumpResourcePriorities = false;
m_httpHeadersToClear.clear();
@@ -628,16 +624,6 @@
return &m_httpHeadersToClear;
}
-bool TestRunner::shouldBlockRedirects() const
-{
- return m_shouldBlockRedirects;
-}
-
-bool TestRunner::willSendRequestShouldReturnNull() const
-{
- return m_willSendRequestShouldReturnNull;
-}
-
void TestRunner::setTopLoadingFrame(WebFrame* frame, bool clear)
{
if (frame->top()->view() != m_webView)
@@ -1111,20 +1097,6 @@
result->setNull();
}
-void TestRunner::setWillSendRequestReturnsNullOnRedirect(const CppArgumentList& arguments, CppVariant* result)
-{
- if (arguments.size() > 0 && arguments[0].isBool())
- m_shouldBlockRedirects = arguments[0].toBoolean();
- result->setNull();
-}
-
-void TestRunner::setWillSendRequestReturnsNull(const CppArgumentList& arguments, CppVariant* result)
-{
- if (arguments.size() > 0 && arguments[0].isBool())
- m_willSendRequestShouldReturnNull = arguments[0].toBoolean();
- result->setNull();
-}
-
void TestRunner::setTabKeyCyclesThroughElements(const CppArgumentList& arguments, CppVariant* result)
{
if (arguments.size() > 0 && arguments[0].isBool())
diff --git a/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.h b/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.h
index faa8a70..84f1eb8 100644
--- a/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.h
+++ b/Tools/DumpRenderTree/chromium/TestRunner/src/TestRunner.h
@@ -114,8 +114,6 @@
bool shouldStayOnPageAfterHandlingBeforeUnload() const;
void setTitleTextDirection(WebKit::WebTextDirection);
const std::set<std::string>* httpHeadersToClear() const;
- bool shouldBlockRedirects() const;
- bool willSendRequestShouldReturnNull() const;
void setTopLoadingFrame(WebKit::WebFrame*, bool);
WebKit::WebFrame* topLoadingFrame() const;
void policyDelegateDone();
@@ -406,12 +404,6 @@
// Causes WillSendRequest to clear certain headers.
void setWillSendRequestClearHeader(const CppArgumentList&, CppVariant*);
- // Causes WillSendRequest to block redirects.
- void setWillSendRequestReturnsNullOnRedirect(const CppArgumentList&, CppVariant*);
-
- // Causes WillSendRequest to return an empty request.
- void setWillSendRequestReturnsNull(const CppArgumentList&, CppVariant*);
-
// This function sets a flag that tells the test_shell to dump a descriptive
// line for each resource load's priority and any time that priority
// changes. It takes no arguments, and ignores any that may be present.
@@ -675,10 +667,6 @@
bool m_shouldStayOnPageAfterHandlingBeforeUnload;
- bool m_shouldBlockRedirects;
-
- bool m_willSendRequestShouldReturnNull;
-
bool m_shouldDumpResourcePriorities;
std::set<std::string> m_httpHeadersToClear;
diff --git a/Tools/DumpRenderTree/chromium/TestRunner/src/WebTestProxy.cpp b/Tools/DumpRenderTree/chromium/TestRunner/src/WebTestProxy.cpp
index b902648..2e2659e 100644
--- a/Tools/DumpRenderTree/chromium/TestRunner/src/WebTestProxy.cpp
+++ b/Tools/DumpRenderTree/chromium/TestRunner/src/WebTestProxy.cpp
@@ -235,7 +235,7 @@
void blockRequest(WebURLRequest& request)
{
- request.setURL(WebURL());
+ request.setURL(GURL("255.255.255.255"));
}
bool isLocalhost(const string& host)
@@ -1321,17 +1321,6 @@
m_delegate->printMessage("\n");
}
- if (!redirectResponse.isNull() && m_testInterfaces->testRunner()->shouldBlockRedirects()) {
- m_delegate->printMessage("Returning null for this redirect\n");
- blockRequest(request);
- return;
- }
-
- if (m_testInterfaces->testRunner()->willSendRequestShouldReturnNull()) {
- blockRequest(request);
- return;
- }
-
if (m_testInterfaces->testRunner()->httpHeadersToClear()) {
const set<string> *clearHeaders = m_testInterfaces->testRunner()->httpHeadersToClear();
for (set<string>::const_iterator header = clearHeaders->begin(); header != clearHeaders->end(); ++header)
diff --git a/Tools/Scripts/update-webgl-conformance-tests b/Tools/Scripts/update-webgl-conformance-tests
index b930836..cf9bd7f 100755
--- a/Tools/Scripts/update-webgl-conformance-tests
+++ b/Tools/Scripts/update-webgl-conformance-tests
@@ -29,8 +29,8 @@
"""Wrapper around webkitpy/layout_tests/update-webgl-conformance-tests.py"""
-import webkitpy.to_be_moved.update_webgl_conformance_tests
+import webkitpy.webgl.update_webgl_conformance_tests
import sys
if __name__ == '__main__':
- sys.exit(webkitpy.to_be_moved.update_webgl_conformance_tests.main())
+ sys.exit(webkitpy.webgl.update_webgl_conformance_tests.main())
diff --git a/Tools/Scripts/webkitpy/common/checkout/scm/git.py b/Tools/Scripts/webkitpy/common/checkout/scm/git.py
index 71a34d6..c69a098 100644
--- a/Tools/Scripts/webkitpy/common/checkout/scm/git.py
+++ b/Tools/Scripts/webkitpy/common/checkout/scm/git.py
@@ -178,11 +178,11 @@
def _branch_from_ref(self, ref):
return ref.replace('refs/heads/', '')
- def _current_branch(self):
+ def current_branch(self):
return self._branch_from_ref(self._run_git(['symbolic-ref', '-q', 'HEAD']).strip())
def _upstream_branch(self):
- current_branch = self._current_branch()
+ current_branch = self.current_branch()
return self._branch_from_ref(self.read_git_config('branch.%s.merge' % current_branch, cwd=self.checkout_root, executive=self._executive).strip())
def merge_base(self, git_commit):
@@ -393,8 +393,14 @@
self.commit_locally_with_message(message)
return self.push_local_commits_to_server(username=username, password=password)
+ def checkout_branch(self, name):
+ self._run_git(['checkout', '-q', name])
+
+ def create_clean_branch(self, name):
+ self._run_git(['checkout', '-q', '-b', name, self.remote_branch_ref()])
+
def _commit_on_branch(self, message, git_commit, username=None, password=None):
- branch_name = self._current_branch()
+ branch_name = self.current_branch()
commit_ids = self.commit_ids_from_commitish_arguments([git_commit])
# We want to squash all this branch's commits into one commit with the proper description.
@@ -412,7 +418,7 @@
# We wrap in a try...finally block so if anything goes wrong, we clean up the branches.
commit_succeeded = True
try:
- self._run_git(['checkout', '-q', '-b', MERGE_BRANCH_NAME, self.remote_branch_ref()])
+ self.create_clean_branch(MERGE_BRANCH_NAME)
for commit in commit_ids:
# We're on a different branch now, so convert "head" to the branch name.
@@ -430,7 +436,7 @@
finally:
# And then swap back to the original branch and clean up.
self.discard_working_directory_changes()
- self._run_git(['checkout', '-q', branch_name])
+ self.checkout_branch(branch_name)
self.delete_branch(MERGE_BRANCH_NAME)
return output
@@ -442,6 +448,9 @@
def last_svn_commit_log(self):
return self._run_git(['svn', 'log', '--limit=1'])
+ def blame(self, path):
+ return self._run_git(['blame', path])
+
def svn_blame(self, path):
return self._run_git(['svn', 'blame', path])
@@ -548,7 +557,7 @@
def is_cleanly_tracking_remote_master(self):
if self.has_working_directory_changes():
return False
- if self._current_branch() != self._branch_tracking_remote_master():
+ if self.current_branch() != self._branch_tracking_remote_master():
return False
if len(self.local_commits(self._branch_tracking_remote_master())) > 0:
return False
diff --git a/Tools/Scripts/webkitpy/common/checkout/scm/scm.py b/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
index a972ca4..c57aec9 100644
--- a/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
+++ b/Tools/Scripts/webkitpy/common/checkout/scm/scm.py
@@ -209,6 +209,9 @@
def last_svn_commit_log(self):
self._subclass_must_implement()
+ def blame(self, path):
+ self._subclass_must_implement()
+
def svn_blame(self, path):
self._subclass_must_implement()
diff --git a/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py b/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
index 961a7fd..192c03c 100644
--- a/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
+++ b/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py
@@ -32,6 +32,8 @@
class MockSCM(object):
+ executable_name = "MockSCM"
+
def __init__(self, filesystem=None, executive=None):
self.checkout_root = "/mock-checkout"
self.added_paths = set()
@@ -52,6 +54,21 @@
def discard_working_directory_changes(self):
pass
+ def ensure_cleanly_tracking_remote_master(self):
+ pass
+
+ def current_branch(self):
+ return "mock-branch-name"
+
+ def checkout_branch(self, name):
+ pass
+
+ def create_clean_branch(self, name):
+ pass
+
+ def delete_branch(self, name):
+ pass
+
def supports_local_commits(self):
return True
@@ -126,6 +143,15 @@
def svn_revision_from_commit_text(self, commit_text):
return "49824"
+ def svn_revision_from_git_commit(self, git_commit):
+ if git_commit == '6469e754a1':
+ return 1234
+ if git_commit == '624c3081c0':
+ return 5678
+ if git_commit == '624caaaaaa':
+ return 10000
+ return None
+
def delete(self, path):
return self.delete_list([path])
diff --git a/Tools/Scripts/webkitpy/common/checkout/scm/svn.py b/Tools/Scripts/webkitpy/common/checkout/scm/svn.py
index dc9ad53..7c37ac8 100644
--- a/Tools/Scripts/webkitpy/common/checkout/scm/svn.py
+++ b/Tools/Scripts/webkitpy/common/checkout/scm/svn.py
@@ -361,6 +361,9 @@
# http://svnbook.red-bean.com/en/1.0/ch03s03.html
return self.svn_commit_log('BASE')
+ def blame(self, path):
+ return self._run_svn(['blame', path])
+
def svn_blame(self, path):
return self._run_svn(['blame', path])
diff --git a/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py b/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py
index 3ca01a3..25607df 100644
--- a/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py
+++ b/Tools/Scripts/webkitpy/common/net/buildbot/buildbot.py
@@ -79,7 +79,7 @@
def fetch_layout_test_results(self, results_url):
# FIXME: This should cache that the result was a 404 and stop hitting the network.
- results_file = NetworkTransaction(convert_404_to_None=True).run(lambda: self._fetch_file_from_results(results_url, "full_results.json"))
+ results_file = NetworkTransaction(convert_404_to_None=True).run(lambda: self._fetch_file_from_results(results_url, "failing_results.json"))
return LayoutTestResults.results_from_string(results_file)
def url_encoded_name(self):
diff --git a/Tools/Scripts/webkitpy/common/system/executive.py b/Tools/Scripts/webkitpy/common/system/executive.py
index 1af0831..94121da 100644
--- a/Tools/Scripts/webkitpy/common/system/executive.py
+++ b/Tools/Scripts/webkitpy/common/system/executive.py
@@ -484,6 +484,9 @@
string_args = self._stringify_args(args)
return subprocess.Popen(string_args, **kwargs)
+ def call(self, args, **kwargs):
+ return subprocess.call(self._stringify_args(args), **kwargs)
+
def run_in_parallel(self, command_lines_and_cwds, processes=None):
"""Runs a list of (cmd_line list, cwd string) tuples in parallel and returns a list of (retcode, stdout, stderr) tuples."""
assert len(command_lines_and_cwds)
diff --git a/Tools/Scripts/webkitpy/common/system/executive_mock.py b/Tools/Scripts/webkitpy/common/system/executive_mock.py
index 48a9bc1..6a3d018 100644
--- a/Tools/Scripts/webkitpy/common/system/executive_mock.py
+++ b/Tools/Scripts/webkitpy/common/system/executive_mock.py
@@ -143,6 +143,9 @@
self._proc = MockProcess()
return self._proc
+ def call(self, args, **kwargs):
+ _log.info('Mock call: %s' % args)
+
def run_in_parallel(self, commands):
num_previous_calls = len(self.calls)
command_outputs = []
diff --git a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
index 0bd8f5e..72c0e26 100644
--- a/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
+++ b/Tools/Scripts/webkitpy/layout_tests/models/test_expectations.py
@@ -984,6 +984,9 @@
def model(self):
return self._model
+ def get_needs_rebaseline_failures(self):
+ return self._model.get_test_set_for_keyword(TestExpectationParser.NEEDS_REBASELINE_MODIFIER)
+
def get_rebaselining_failures(self):
return self._model.get_test_set(REBASELINE)
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/android_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/android_unittest.py
index e11307c..14db692 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/android_unittest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/android_unittest.py
@@ -145,6 +145,10 @@
port._executive = MockExecutive2(run_command_fn=port._mock_adb.run_command)
return port
+ def make_wdiff_available(self, port):
+ port._wdiff_available = True
+ port._host_port._wdiff_available = True
+
# Test that content_shell currently is the only supported driver.
def test_non_content_shell_driver(self):
self.assertRaises(self.make_port, options=optparse.Values({'driver_name': 'foobar'}))
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/base.py b/Tools/Scripts/webkitpy/layout_tests/port/base.py
index 5b9c9de..55f42ec 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/base.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/base.py
@@ -1139,6 +1139,8 @@
error_handler=self._handle_wdiff_error)
return self._format_wdiff_output_as_html(wdiff)
+ _wdiff_error_html = "Failed to run wdiff, see error log."
+
def wdiff_text(self, actual_filename, expected_filename):
"""Returns a string of HTML indicating the word-level diff of the
contents of the two filenames. Returns an empty string if word-level
@@ -1148,12 +1150,16 @@
try:
# It's possible to raise a ScriptError we pass wdiff invalid paths.
return self._run_wdiff(actual_filename, expected_filename)
- except OSError, e:
+ except OSError as e:
if e.errno in [errno.ENOENT, errno.EACCES, errno.ECHILD]:
# Silently ignore cases where wdiff is missing.
self._wdiff_available = False
return ""
raise
+ except ScriptError as e:
+ _log.error("Failed to run wdiff: %s" % e)
+ self._wdiff_available = False
+ return self._wdiff_error_html
# This is a class variable so we can test error output easily.
_pretty_patch_error_html = "Failed to run PrettyPatch, see error log."
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py
index 8ab92cf..2ee659c 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt.py
@@ -125,6 +125,9 @@
def show_results_html_file(self, results_filename):
pass
+ def _make_wdiff_available(self):
+ self.__delegate._wdiff_available = True
+
def main(argv, host, stdin, stdout, stderr):
"""Run the tests."""
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py
index 56e1581..1dde3b9 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/mock_drt_unittest.py
@@ -45,11 +45,14 @@
class MockDRTPortTest(port_testcase.PortTestCase):
- def make_port(self, options=mock_options):
- host = MockSystemHost()
+ def make_port(self, host=None, options=mock_options):
+ host = host or MockSystemHost()
test.add_unit_tests_to_mock_filesystem(host.filesystem)
return mock_drt.MockDRTPort(host, port_name='mock-mac', options=options)
+ def make_wdiff_available(self, port):
+ port._make_wdiff_available()
+
def test_port_name_in_constructor(self):
self.assertTrue(mock_drt.MockDRTPort(MockSystemHost(), port_name='mock-test'))
diff --git a/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py b/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
index 82524bc..6b5baa3 100644
--- a/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
+++ b/Tools/Scripts/webkitpy/layout_tests/port/port_testcase.py
@@ -88,6 +88,9 @@
port._config.build_directory = lambda configuration: '/mock-build'
return port
+ def make_wdiff_available(self, port):
+ port._wdiff_available = True
+
def test_default_max_locked_shards(self):
port = self.make_port()
port.default_child_processes = lambda: 16
@@ -174,6 +177,20 @@
port = self.make_port()
port.check_wdiff()
+ def test_wdiff_text_fails(self):
+ host = MockSystemHost(os_name=self.os_name, os_version=self.os_version)
+ host.executive = MockExecutive(should_throw=True)
+ port = self.make_port(host=host)
+ port._executive = host.executive # AndroidPortTest.make_port sets its own executive, so reset that as well.
+
+ # This should raise a ScriptError that gets caught and turned into the
+ # error text, and also mark wdiff as not available.
+ self.make_wdiff_available(port)
+ self.assertTrue(port.wdiff_available())
+ diff_txt = port.wdiff_text("/tmp/foo.html", "/tmp/bar.html")
+ self.assertEqual(diff_txt, port._wdiff_error_html)
+ self.assertFalse(port.wdiff_available())
+
def test_test_configuration(self):
port = self.make_port()
self.assertTrue(port.test_configuration())
diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
index 48f1ebb..717172d 100644
--- a/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
+++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline.py
@@ -29,7 +29,10 @@
import json
import logging
import optparse
+import re
import sys
+import time
+import urllib2
from webkitpy.common.checkout.baselineoptimizer import BaselineOptimizer
from webkitpy.common.memoized import memoized
@@ -299,7 +302,7 @@
verbose_args = ['--verbose'] if verbose else []
stderr = self._tool.executive.run_command([self._tool.path()] + verbose_args + args, cwd=self._tool.scm().checkout_root, return_stderr=True)
for line in stderr.splitlines():
- print >> sys.stderr, line
+ _log.warning(line)
except ScriptError, e:
_log.error(e)
@@ -524,3 +527,186 @@
_log.debug("rebaseline-json: " + str(test_prefix_list))
self._rebaseline(options, test_prefix_list)
+
+
+class AutoRebaseline(AbstractParallelRebaselineCommand):
+ name = "auto-rebaseline"
+ help_text = "Rebaselines any NeedsRebaseline lines in TestExpectations that have cycled through all the bots."
+ AUTO_REBASELINE_BRANCH_NAME = "auto-rebaseline-temporary-branch"
+
+ # Rietveld uploader stinks. Limit the number of rebaselines in a given patch to keep upload from failing.
+ # FIXME: http://crbug.com/263676 Obviously we should fix the uploader here.
+ MAX_LINES_TO_REBASELINE = 200
+
+ def __init__(self):
+ super(AutoRebaseline, self).__init__(options=[
+ # FIXME: Remove this option.
+ self.no_optimize_option,
+ # FIXME: Remove this option.
+ self.results_directory_option,
+ ])
+
+ def latest_revision_processed_on_all_bots(self):
+ revisions = []
+ for builder_name in self._release_builders():
+ builder = self._tool.buildbot_for_builder_name(builder_name).builder_with_name(builder_name)
+ result = builder.latest_layout_test_results()
+ if result.run_was_interrupted():
+ _log.error("Can't rebaseline. The latest run on %s did not complete." % builder_name)
+ return 0
+ revisions.append(result.blink_revision())
+ return int(min(revisions))
+
+ def tests_to_rebaseline(self, tool, min_revision, print_revisions):
+ port = tool.port_factory.get()
+ expectations_file_path = port.path_to_generic_test_expectations_file()
+
+ tests = set()
+ revision = None
+ author = None
+ bugs = set()
+
+ for line in tool.scm().blame(expectations_file_path).split("\n"):
+ if "NeedsRebaseline" not in line:
+ continue
+ parsed_line = re.match("^(\S*)[^(]*\((\S*).*?([^ ]*)\ \[[^[]*$", line)
+
+ commit_hash = parsed_line.group(1)
+ svn_revision = tool.scm().svn_revision_from_git_commit(commit_hash)
+
+ test = parsed_line.group(3)
+ if print_revisions:
+ _log.info("%s is waiting for r%s" % (test, svn_revision))
+
+ if not svn_revision or svn_revision > min_revision:
+ continue
+
+ if revision and svn_revision != revision:
+ continue
+
+ if not revision:
+ revision = svn_revision
+ author = parsed_line.group(2)
+
+ bugs.update(re.findall("crbug\.com\/(\d+)", line))
+ tests.add(test)
+
+ if len(tests) >= self.MAX_LINES_TO_REBASELINE:
+ _log.info("Too many tests to rebaseline in one patch. Doing the first %d." % self.MAX_LINES_TO_REBASELINE)
+ break
+
+ return tests, revision, author, bugs
+
+ def link_to_patch(self, revision):
+ return "http://src.chromium.org/viewvc/blink?view=revision&revision=" + str(revision)
+
+ def commit_message(self, author, revision, bugs):
+ bug_string = ""
+ if bugs:
+ bug_string = "BUG=%s\n" % ",".join(bugs)
+
+ return """Auto-rebaseline for r%s
+
+%s
+
+%sTBR=%s
+""" % (revision, self.link_to_patch(revision), bug_string, author)
+
+ def get_test_prefix_list(self, tests):
+ test_prefix_list = {}
+
+ for builder_name in self._release_builders():
+ port_name = builders.port_name_for_builder_name(builder_name)
+ port = self._tool.port_factory.get(port_name)
+ expectations = TestExpectations(port, include_overrides=True)
+ for test in expectations.get_needs_rebaseline_failures():
+ if test not in tests:
+ continue
+ if test not in test_prefix_list:
+ test_prefix_list[test] = {}
+ test_prefix_list[test][builder_name] = BASELINE_SUFFIX_LIST
+
+ return test_prefix_list
+
+ def _run_git_cl_command(self, options, command):
+ subprocess_command = ['git', 'cl'] + command
+ if options.verbose:
+ subprocess_command.append('--verbose')
+ # Use call instead of run_command so that stdout doesn't get swallowed.
+ self._tool.executive.call(subprocess_command)
+
+ # FIXME: Move this somewhere more general.
+ def tree_status(self):
+ blink_tree_status_url = "http://blink-status.appspot.com/status"
+ status = urllib2.urlopen(blink_tree_status_url).read().lower()
+ if status.find('closed') != -1 or status == 0:
+ return 'closed'
+ elif status.find('open') != -1 or status == 1:
+ return 'open'
+ return 'unknown'
+
+ def execute(self, options, args, tool):
+ if tool.scm().executable_name == "svn":
+ _log.error("Auto rebaseline only works with a git checkout.")
+ return
+
+ if tool.scm().has_working_directory_changes():
+ _log.error("Cannot proceed with working directory changes. Clean working directory first.")
+ return
+
+ min_revision = self.latest_revision_processed_on_all_bots()
+ if not min_revision:
+ return
+
+ if options.verbose:
+ _log.info("Bot min revision is %s." % min_revision)
+
+ tests, revision, author, bugs = self.tests_to_rebaseline(tool, min_revision, print_revisions=options.verbose)
+ test_prefix_list = self.get_test_prefix_list(tests)
+
+ if not tests:
+ _log.debug('No tests to rebaseline.')
+ return
+ _log.info('Rebaselining %s for r%s by %s.' % (list(tests), revision, author))
+
+ if self.tree_status() == 'closed':
+ _log.info('Cannot proceed. Tree is closed.')
+ return
+
+ try:
+ old_branch_name = tool.scm().current_branch()
+ tool.scm().delete_branch(self.AUTO_REBASELINE_BRANCH_NAME)
+ tool.scm().create_clean_branch(self.AUTO_REBASELINE_BRANCH_NAME)
+
+ self._rebaseline(options, test_prefix_list)
+
+ tool.scm().commit_locally_with_message(self.commit_message(author, revision, bugs))
+
+ # FIXME: It would be nice if we could dcommit the patch without uploading, but still
+ # go through all the precommit hooks. For rebaselines with lots of files, uploading
+ # takes a long time and sometimes fails, but we don't want to commit if, e.g. the
+ # tree is closed.
+ self._run_git_cl_command(options, ['upload', '-f'])
+ self._run_git_cl_command(options, ['dcommit', '-f'])
+ finally:
+ self._run_git_cl_command(options, ['set_close'])
+ tool.scm().ensure_cleanly_tracking_remote_master()
+ tool.scm().checkout_branch(old_branch_name)
+ tool.scm().delete_branch(self.AUTO_REBASELINE_BRANCH_NAME)
+
+
+class RebaselineOMatic(AbstractDeclarativeCommand):
+ name = "rebaseline-o-matic"
+ help_text = "Calls webkit-patch auto-rebaseline in a loop."
+
+ SLEEP_TIME_IN_SECONDS = 30
+
+ def execute(self, options, args, tool):
+ while True:
+ tool.executive.run_command(['git', 'pull'])
+ rebaseline_command = [tool.filesystem.join(tool.scm().checkout_root, 'Tools', 'Scripts', 'webkit-patch'), 'auto-rebaseline']
+ if options.verbose:
+ rebaseline_command.append('--verbose')
+ # Use call instead of run_command so that stdout doesn't get swallowed.
+ tool.executive.call(rebaseline_command)
+ time.sleep(self.SLEEP_TIME_IN_SECONDS)
diff --git a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
index 98ee4ed..be814a5 100644
--- a/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
+++ b/Tools/Scripts/webkitpy/tool/commands/rebaseline_unittest.py
@@ -504,3 +504,158 @@
['passes/text-expected.png: (no baselines found)',
'passes/text-expected.txt:',
' (generic): 123456'])
+
+
+class TestAutoRebaseline(_BaseTestCase):
+ command_constructor = AutoRebaseline
+
+ def _write_test_file(self, port, path, contents):
+ abs_path = self.tool.filesystem.join(port.layout_tests_dir(), path)
+ self.tool.filesystem.write_text_file(abs_path, contents)
+
+ def setUp(self):
+ super(TestAutoRebaseline, self).setUp()
+ self.command.latest_revision_processed_on_all_bots = lambda: 9000
+
+ def test_tests_to_rebaseline(self):
+ def blame(path):
+ return """
+624c3081c0 path/to/TestExpectations (foobarbaz1@chromium.org 2013-06-14 20:18:46 +0000 11) crbug.com/24182 [ Debug ] path/to/norebaseline.html [ ImageOnlyFailure ]
+624c3081c0 path/to/TestExpectations (foobarbaz1@chromium.org 2013-04-28 04:52:41 +0000 13) Bug(foo) path/to/rebaseline-without-bug-number.html [ NeedsRebaseline ]
+624c3081c0 path/to/TestExpectations (foobarbaz1@chromium.org 2013-06-14 20:18:46 +0000 11) crbug.com/24182 [ Debug ] path/to/rebaseline-with-modifiers.html [ NeedsRebaseline ]
+624c3081c0 path/to/TestExpectations (foobarbaz1@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 crbug.com/234 path/to/rebaseline-without-modifiers.html [ NeedsRebaseline ]
+6469e754a1 path/to/TestExpectations (foobarbaz1@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 path/to/rebaseline-new-revision.html [ NeedsRebaseline ]
+624caaaaaa path/to/TestExpectations (foo@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 path/to/not-cycled-through-bots.html [ NeedsRebaseline ]
+0000000000 path/to/TestExpectations (foo@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 path/to/locally-changed-lined.html [ NeedsRebaseline ]
+"""
+ self.tool.scm().blame = blame
+
+ min_revision = 9000
+ self.assertEqual(self.command.tests_to_rebaseline(self.tool, min_revision, print_revisions=False), (
+ set(['path/to/rebaseline-without-bug-number.html', 'path/to/rebaseline-with-modifiers.html', 'path/to/rebaseline-without-modifiers.html']),
+ 5678,
+ 'foobarbaz1@chromium.org',
+ set(['24182', '234'])))
+
+ def test_tests_to_rebaseline_over_limit(self):
+ def blame(path):
+ result = ""
+ for i in range(0, self.command.MAX_LINES_TO_REBASELINE + 1):
+ result += "624c3081c0 path/to/TestExpectations (foobarbaz1@chromium.org 2013-04-28 04:52:41 +0000 13) crbug.com/24182 path/to/rebaseline-%s.html [ NeedsRebaseline ]\n" % i
+ return result
+ self.tool.scm().blame = blame
+
+ expected_list_of_tests = []
+ for i in range(0, self.command.MAX_LINES_TO_REBASELINE):
+ expected_list_of_tests.append("path/to/rebaseline-%s.html" % i)
+
+ min_revision = 9000
+ self.assertEqual(self.command.tests_to_rebaseline(self.tool, min_revision, print_revisions=False), (
+ set(expected_list_of_tests),
+ 5678,
+ 'foobarbaz1@chromium.org',
+ set(['24182'])))
+
+ def test_commit_message(self):
+ author = "foo@chromium.org"
+ revision = 1234
+ bugs = set()
+ self.assertEqual(self.command.commit_message(author, revision, bugs),
+ """Auto-rebaseline for r1234
+
+http://src.chromium.org/viewvc/blink?view=revision&revision=1234
+
+TBR=foo@chromium.org
+""")
+
+ bugs = set(["234", "345"])
+ self.assertEqual(self.command.commit_message(author, revision, bugs),
+ """Auto-rebaseline for r1234
+
+http://src.chromium.org/viewvc/blink?view=revision&revision=1234
+
+BUG=234,345
+TBR=foo@chromium.org
+""")
+
+ def test_no_needs_rebaseline_lines(self):
+ def blame(path):
+ return """
+6469e754a1 path/to/TestExpectations (foobarbaz1@chromium.org 2013-06-14 20:18:46 +0000 11) crbug.com/24182 [ Debug ] path/to/norebaseline.html [ ImageOnlyFailure ]
+"""
+ self.tool.scm().blame = blame
+
+ self.command.execute(MockOptions(optimize=True, verbose=False, move_overwritten_baselines=False, results_directory=False), [], self.tool)
+ self.assertEqual(self.tool.executive.calls, [])
+
+ def test_execute(self):
+ def blame(path):
+ return """
+6469e754a1 path/to/TestExpectations (foobarbaz1@chromium.org 2013-06-14 20:18:46 +0000 11) crbug.com/24182 [ Debug ] path/to/norebaseline.html [ ImageOnlyFailure ]
+6469e754a1 path/to/TestExpectations (foobarbaz1@chromium.org 2013-04-28 04:52:41 +0000 13) Bug(foo) path/to/rebaseline-without-bug-number.html [ NeedsRebaseline ]
+6469e754a1 path/to/TestExpectations (foobarbaz1@chromium.org 2013-06-14 20:18:46 +0000 11) crbug.com/24182 [ SnowLeopard ] path/to/rebaseline-with-modifiers.html [ NeedsRebaseline ]
+6469e754a1 path/to/TestExpectations (foobarbaz1@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 path/to/rebaseline-without-modifiers.html [ NeedsRebaseline ]
+624caaaaaa path/to/TestExpectations (foo@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 path/to/not-cycled-through-bots.html [ NeedsRebaseline ]
+0000000000 path/to/TestExpectations (foo@chromium.org 2013-04-28 04:52:41 +0000 12) crbug.com/24182 path/to/locally-changed-lined.html [ NeedsRebaseline ]
+"""
+ self.tool.scm().blame = blame
+
+ test_port = self.tool.port_factory.get('test')
+ original_get = self.tool.port_factory.get
+
+ def get_test_port(port_name=None, options=None, **kwargs):
+ if not port_name:
+ return test_port
+ return original_get(port_name, options, **kwargs)
+ # Need to make sure all the ports grabbed use the test checkout path instead of the mock checkout path.
+ self.tool.port_factory.get = get_test_port
+
+ self.tool.filesystem.write_text_file(test_port.path_to_generic_test_expectations_file(), """
+crbug.com/24182 [ Debug ] path/to/norebaseline.html [ Rebaseline ]
+Bug(foo) path/to/rebaseline-without-bug-number.html [ NeedsRebaseline ]
+crbug.com/24182 [ SnowLeopard ] path/to/rebaseline-with-modifiers.html [ NeedsRebaseline ]
+crbug.com/24182 path/to/rebaseline-without-modifiers.html [ NeedsRebaseline ]
+crbug.com/24182 path/to/not-cycled-through-bots.html [ NeedsRebaseline ]
+crbug.com/24182 path/to/locally-changed-lined.html [ NeedsRebaseline ]
+""")
+
+ self._write_test_file(test_port, 'path/to/rebaseline-without-bug-number.html', "Dummy test contents")
+ self._write_test_file(test_port, 'path/to/rebaseline-with-modifiers.html', "Dummy test contents")
+ self._write_test_file(test_port, 'path/to/rebaseline-without-modifiers.html', "Dummy test contents")
+
+ old_exact_matches = builders._exact_matches
+ try:
+ builders._exact_matches = {
+ "MOCK Leopard": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
+ "MOCK SnowLeopard": {"port_name": "test-mac-snowleopard", "specifiers": set(["mock-specifier"])},
+ }
+
+ self.command.tree_status = lambda: 'closed'
+ self.command.execute(MockOptions(optimize=True, verbose=False, move_overwritten_baselines=False, results_directory=False), [], self.tool)
+ self.assertEqual(self.tool.executive.calls, [])
+
+ self.command.tree_status = lambda: 'open'
+
+ self.tool.executive.calls = []
+ self.command.execute(MockOptions(optimize=True, verbose=False, move_overwritten_baselines=False, results_directory=False), [], self.tool)
+ self.assertEqual(self.tool.executive.calls, [
+ [
+ ['echo', 'copy-existing-baselines-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK Leopard', '--test', 'path/to/rebaseline-without-modifiers.html'],
+ ['echo', 'copy-existing-baselines-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK SnowLeopard', '--test', 'path/to/rebaseline-without-modifiers.html'],
+ ['echo', 'copy-existing-baselines-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK Leopard', '--test', 'path/to/rebaseline-without-bug-number.html'],
+ ['echo', 'copy-existing-baselines-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK SnowLeopard', '--test', 'path/to/rebaseline-without-bug-number.html'],
+ ['echo', 'copy-existing-baselines-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK SnowLeopard', '--test', 'path/to/rebaseline-with-modifiers.html'],
+ ],
+ [
+ ['echo', 'rebaseline-test-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK Leopard', '--test', 'path/to/rebaseline-without-modifiers.html'],
+ ['echo', 'rebaseline-test-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK SnowLeopard', '--test', 'path/to/rebaseline-without-modifiers.html'],
+ ['echo', 'rebaseline-test-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK Leopard', '--test', 'path/to/rebaseline-without-bug-number.html'],
+ ['echo', 'rebaseline-test-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK SnowLeopard', '--test', 'path/to/rebaseline-without-bug-number.html'],
+ ['echo', 'rebaseline-test-internal', '--suffixes', 'png,wav,txt', '--builder', 'MOCK SnowLeopard', '--test', 'path/to/rebaseline-with-modifiers.html'],
+ ],
+ ['echo', 'optimize-baselines', '--suffixes', 'wav,txt,png', 'path/to/rebaseline-without-modifiers.html'],
+ ['echo', 'optimize-baselines', '--suffixes', 'wav,txt,png', 'path/to/rebaseline-without-bug-number.html'],
+ ['echo', 'optimize-baselines', '--suffixes', 'wav,txt,png', 'path/to/rebaseline-with-modifiers.html'],
+ ])
+ finally:
+ builders._exact_matches = old_exact_matches
diff --git a/Tools/Scripts/webkitpy/to_be_moved/__init__.py b/Tools/Scripts/webkitpy/webgl/__init__.py
similarity index 100%
rename from Tools/Scripts/webkitpy/to_be_moved/__init__.py
rename to Tools/Scripts/webkitpy/webgl/__init__.py
diff --git a/Tools/Scripts/webkitpy/to_be_moved/update_webgl_conformance_tests.py b/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests.py
similarity index 100%
rename from Tools/Scripts/webkitpy/to_be_moved/update_webgl_conformance_tests.py
rename to Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests.py
diff --git a/Tools/Scripts/webkitpy/to_be_moved/update_webgl_conformance_tests_unittest.py b/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests_unittest.py
similarity index 97%
rename from Tools/Scripts/webkitpy/to_be_moved/update_webgl_conformance_tests_unittest.py
rename to Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests_unittest.py
index 9a7823e..42e0925 100644
--- a/Tools/Scripts/webkitpy/to_be_moved/update_webgl_conformance_tests_unittest.py
+++ b/Tools/Scripts/webkitpy/webgl/update_webgl_conformance_tests_unittest.py
@@ -29,7 +29,7 @@
"""Unit tests for update_webgl_conformance_tests."""
import webkitpy.thirdparty.unittest2 as unittest
-from webkitpy.to_be_moved import update_webgl_conformance_tests as webgl
+from webkitpy.webgl import update_webgl_conformance_tests as webgl
def construct_script(name):
diff --git a/Tools/TestResultServer/model/datastorefile.py b/Tools/TestResultServer/model/datastorefile.py
index 8dca34d..6161c37 100755
--- a/Tools/TestResultServer/model/datastorefile.py
+++ b/Tools/TestResultServer/model/datastorefile.py
@@ -32,7 +32,7 @@
from google.appengine.ext import blobstore
from google.appengine.ext import db
-MAX_DATA_ENTRY_PER_FILE = 20
+MAX_DATA_ENTRY_PER_FILE = 30
MAX_ENTRY_LEN = 1000 * 1000
diff --git a/Tools/TestResultServer/model/jsonresults.py b/Tools/TestResultServer/model/jsonresults.py
index 35b56c9..9976b67 100755
--- a/Tools/TestResultServer/model/jsonresults.py
+++ b/Tools/TestResultServer/model/jsonresults.py
@@ -449,7 +449,7 @@
aggregated_json[builder][FAILURE_MAP_KEY] = CHAR_TO_FAILURE
is_debug_builder = re.search(r"(Debug|Dbg)", builder, re.I)
- run_time_pruning_threshold = 2 * JSON_RESULTS_MIN_TIME if is_debug_builder else JSON_RESULTS_MIN_TIME
+ run_time_pruning_threshold = 3 * JSON_RESULTS_MIN_TIME if is_debug_builder else JSON_RESULTS_MIN_TIME
cls._normalize_results(aggregated_json[builder][TESTS_KEY], num_runs, run_time_pruning_threshold)
return cls._generate_file_data(aggregated_json, sort_keys), 200
diff --git a/Tools/TestResultServer/model/jsonresults_unittest.py b/Tools/TestResultServer/model/jsonresults_unittest.py
index def7004..cef590b 100755
--- a/Tools/TestResultServer/model/jsonresults_unittest.py
+++ b/Tools/TestResultServer/model/jsonresults_unittest.py
@@ -848,7 +848,7 @@
{"builds": ["2", "1"],
"tests": {"001.html": {
"results": [[200, PASS]],
- "times": [[200, 2 * jsonresults.JSON_RESULTS_MIN_TIME]]},
+ "times": [[200, 3 * jsonresults.JSON_RESULTS_MIN_TIME]]},
"002.html": {
"results": [[10, TEXT]],
"times": [[10, 0]]}}},
@@ -867,7 +867,7 @@
{"builds": ["3", "2", "1"],
"tests": {"001.html": {
"results": [[201, PASS]],
- "times": [[1, 1], [200, 2 * jsonresults.JSON_RESULTS_MIN_TIME]]},
+ "times": [[1, 1], [200, 3 * jsonresults.JSON_RESULTS_MIN_TIME]]},
"002.html": {
"results": [[1, PASS], [10, TEXT]],
"times": [[11, 0]]}}})
diff --git a/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js b/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js
index c944b4c..b426032 100644
--- a/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js
+++ b/Tools/TestResultServer/static-dashboards/flakiness_dashboard.js
@@ -31,7 +31,6 @@
//////////////////////////////////////////////////////////////////////////////
var FORWARD = 'forward';
var BACKWARD = 'backward';
-var GTEST_MODIFIERS = ['FLAKY', 'FAILS', 'MAYBE', 'DISABLED'];
var TEST_URL_BASE_PATH_FOR_BROWSING = 'http://src.chromium.org/viewvc/blink/trunk/LayoutTests/';
var TEST_URL_BASE_PATH_FOR_XHR = 'http://src.chromium.org/blink/trunk/LayoutTests/';
var TEST_RESULTS_BASE_PATH = 'http://build.chromium.org/f/chromium/layout_test_results/';
@@ -110,7 +109,8 @@
function() {
// Get all possible headers since the actual used set of headers
// depends on the values in historyInstance.dashboardSpecificState, which are currently being set.
- var headers = tableHeaders(true);
+ var getAllTableHeaders = true;
+ var headers = tableHeaders(getAllTableHeaders);
for (var i = 0; i < headers.length; i++) {
if (value == sortColumnFromTableHeader(headers[i]))
return true;
@@ -315,29 +315,16 @@
return individualTestsForSubstringList();
}
-function substringList()
+function splitTestList()
{
- // Convert windows slashes to unix slashes.
- var tests = g_history.dashboardSpecificState.tests.replace(/\\/g, '/');
- var separator = string.contains(tests, ' ') ? ' ' : ',';
- var testList = tests.split(separator);
-
- if (g_history.isLayoutTestResults())
- return testList;
-
- var testListWithoutModifiers = [];
- testList.forEach(function(path) {
- GTEST_MODIFIERS.forEach(function(modifier) {
- path = path.replace('.' + modifier + '_', '.');
- });
- testListWithoutModifiers.push(path);
- });
- return testListWithoutModifiers;
+ // Convert windows slashes to unix slashes and spaces/newlines to commas.
+ var tests = g_history.dashboardSpecificState.tests.replace(/\\/g, '/').replace('\n', ' ').replace(/\s+/g, ',');
+ return tests.split(',');
}
function individualTestsForSubstringList()
{
- var testList = substringList();
+ var testList = splitTestList();
// If listing a lot of tests, assume you've passed in an explicit list of tests
// instead of patterns to match against. The matching code below is super slow.
//
@@ -662,19 +649,15 @@
return html;
}
-function htmlForSingleTestRow(test)
+function htmlForSingleTestRow(test, showBuilderNames)
{
var headers = tableHeaders();
var html = '';
for (var i = 0; i < headers.length; i++) {
var header = headers[i];
if (string.startsWith(header, 'test') || string.startsWith(header, 'builder')) {
- // If isCrossBuilderView() is true, we're just viewing a single test
- // with results for many builders, so the first column is builder names
- // instead of test paths.
- var testCellClassName = 'test-link' + (isCrossBuilderView() ? ' builder-name' : '');
- var testCellHTML = isCrossBuilderView() ? test.builder : '<span class="link" onclick="g_history.setQueryParameter(\'tests\',\'' + test.test +'\');">' + test.test + '</span>';
-
+ var testCellClassName = 'test-link' + (showBuilderNames ? ' builder-name' : '');
+ var testCellHTML = showBuilderNames ? test.builder : '<span class="link" onclick="g_history.setQueryParameter(\'tests\',\'' + test.test +'\');">' + test.test + '</span>';
html += '<tr><td class="' + testCellClassName + '">' + testCellHTML;
} else if (string.startsWith(header, 'bugs'))
// FIXME: linkify bugs.
@@ -812,7 +795,8 @@
var shownBuilders = [];
for (var j = 0; j < testResults.length; j++) {
shownBuilders.push(testResults[j].builder);
- html += htmlForSingleTestRow(testResults[j]);
+ var showBuilderNames = true;
+ html += htmlForSingleTestRow(testResults[j], showBuilderNames);
}
var skippedBuilders = []
@@ -1061,7 +1045,7 @@
expectationsContainer.appendChild(container);
for (var i = 0; i < failureIndexes.length; i++) {
// FIXME: This doesn't seem to work anymore. Did the paths change?
- // Once that's resolved, see if we need to try each GTEST_MODIFIERS prefix as well.
+ // Once that's resolved, see if we need to try each gtest modifier prefix as well.
var buildNumber = g_resultsByBuilder[builder].buildNumbers[failureIndexes[i]];
var pathToLog = builders.master(builder).logPath(builder, buildNumber) + pathToFailureLog(test);
appendNonWebKitResults(container, pathToLog, 'non-webkit-results');
@@ -1276,8 +1260,9 @@
var testsHTML = '';
if (filteredResults.length) {
var tableRowsHTML = '';
+ var showBuilderNames = false;
for (var i = 0; i < filteredResults.length; i++)
- tableRowsHTML += htmlForSingleTestRow(filteredResults[i])
+ tableRowsHTML += htmlForSingleTestRow(filteredResults[i], showBuilderNames)
testsHTML = htmlForTestTable(tableRowsHTML);
} else {
if (g_history.isLayoutTestResults())
diff --git a/Tools/TestResultServer/static-dashboards/flakiness_dashboard_unittests.js b/Tools/TestResultServer/static-dashboards/flakiness_dashboard_unittests.js
index a9c39c9..bcccd2f 100644
--- a/Tools/TestResultServer/static-dashboards/flakiness_dashboard_unittests.js
+++ b/Tools/TestResultServer/static-dashboards/flakiness_dashboard_unittests.js
@@ -62,17 +62,12 @@
var FAILURE_MAP = {"A": "AUDIO", "C": "CRASH", "F": "TEXT", "I": "IMAGE", "O": "MISSING",
"N": "NO DATA", "P": "PASS", "T": "TIMEOUT", "Y": "NOTRUN", "X": "SKIP", "Z": "IMAGE+TEXT"}
-test('substringList', 2, function() {
+test('splitTestList', 1, function() {
var historyInstance = new history.History(flakinessConfig);
// FIXME(jparent): Remove this once global isn't used.
g_history = historyInstance;
- historyInstance.crossDashboardState.testType = 'gtest';
- historyInstance.dashboardSpecificState.tests = 'test.FLAKY_foo test.FAILS_foo1 test.DISABLED_foo2 test.MAYBE_foo3 test.foo4';
- equal(substringList().toString(), 'test.foo,test.foo1,test.foo2,test.foo3,test.foo4');
-
- historyInstance.crossDashboardState.testType = 'layout-tests';
- historyInstance.dashboardSpecificState.tests = 'foo/bar.FLAKY_foo.html';
- equal(substringList().toString(), 'foo/bar.FLAKY_foo.html');
+ historyInstance.dashboardSpecificState.tests = 'test.foo test.foo1\ntest.foo2\ntest.foo3,foo\\bar\\baz.html';
+ equal(splitTestList().toString(), 'test.foo,test.foo1,test.foo2,test.foo3,foo/bar/baz.html');
});
test('headerForTestTableHtml', 1, function() {
@@ -147,7 +142,7 @@
'<th sortValue=flakiness colspan=10000><div class=table-header-content><span></span><span class=header-text>flakiness (numbers are runtimes in seconds)</span></div></th>' +
'</tr></thead>' +
'<tbody><tr>' +
- '<td class="test-link"><span class="link" onclick="g_history.setQueryParameter(\'tests\',\'dummytest.html\');">dummytest.html</span>' +
+ '<td class="test-link builder-name">WebKit Linux' +
'<td class=options-container>' +
'<div><a href="http://crbug.com/1234">crbug.com/1234</a></div>' +
'<div><a href="http://webkit.org/5678">webkit.org/5678</a></div>' +