Commit 2e515b75 authored by ojan@chromium.org's avatar ojan@chromium.org

Move rebaseline-all command from the gardening-server down into webkit-patch

https://bugs.webkit.org/show_bug.cgi?id=90395

Reviewed by Adam Barth.

This is just moving code. It it in preparation for making rebaseline-expectations
use the same code in order to get the parallelism benefits and reduces the amount
of code we have for doing rebaselines.

* Scripts/webkitpy/common/checkout/checkout_unittest.py:
(CheckoutTest.test_apply_patch):
Updated due to the change to executive_mock.
* Scripts/webkitpy/common/system/executive_mock.py:
(MockExecutive.run_command):
Update to print out the input passed to stdin.
* Scripts/webkitpy/tool/commands/download_unittest.py:
Updated due to executive_mock change.
* Scripts/webkitpy/tool/commands/rebaseline.py:
(RebaselineAll):
(RebaselineAll._run_webkit_patch):
(RebaselineAll._builders_to_fetch_from):
(RebaselineAll._rebaseline_commands):
(RebaselineAll._files_to_add):
(RebaselineAll._optimize_baselines):
(RebaselineAll._rebaseline):
(RebaselineAll.execute):
All this code is just copy-pasted except for mechanical changes
(e.g. self.server.tool --> self._tool) and the reading in of the
JSON from stdin instead of the post body.
* Scripts/webkitpy/tool/commands/rebaseline_unittest.py:
(test_rebaseline_all):
Copied the test-case out of gardeningserver_unittest.py.
* Scripts/webkitpy/tool/servers/gardeningserver.py:
(GardeningHTTPRequestHandler):
(GardeningHTTPRequestHandler.rebaseline):
(GardeningHTTPRequestHandler.rebaselineall):
* Scripts/webkitpy/tool/servers/gardeningserver_unittest.py:
(GardeningServerTest.test_rebaselineall):
(GardeningServerTest.test_rebaselineall.run_command):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@121699 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 31426755
2012-07-02 Ojan Vafai <ojan@chromium.org>
Move rebaseline-all command from the gardening-server down into webkit-patch
https://bugs.webkit.org/show_bug.cgi?id=90395
Reviewed by Adam Barth.
This is just moving code. It it in preparation for making rebaseline-expectations
use the same code in order to get the parallelism benefits and reduces the amount
of code we have for doing rebaselines.
* Scripts/webkitpy/common/checkout/checkout_unittest.py:
(CheckoutTest.test_apply_patch):
Updated due to the change to executive_mock.
* Scripts/webkitpy/common/system/executive_mock.py:
(MockExecutive.run_command):
Update to print out the input passed to stdin.
* Scripts/webkitpy/tool/commands/download_unittest.py:
Updated due to executive_mock change.
* Scripts/webkitpy/tool/commands/rebaseline.py:
(RebaselineAll):
(RebaselineAll._run_webkit_patch):
(RebaselineAll._builders_to_fetch_from):
(RebaselineAll._rebaseline_commands):
(RebaselineAll._files_to_add):
(RebaselineAll._optimize_baselines):
(RebaselineAll._rebaseline):
(RebaselineAll.execute):
All this code is just copy-pasted except for mechanical changes
(e.g. self.server.tool --> self._tool) and the reading in of the
JSON from stdin instead of the post body.
* Scripts/webkitpy/tool/commands/rebaseline_unittest.py:
(test_rebaseline_all):
Copied the test-case out of gardeningserver_unittest.py.
* Scripts/webkitpy/tool/servers/gardeningserver.py:
(GardeningHTTPRequestHandler):
(GardeningHTTPRequestHandler.rebaseline):
(GardeningHTTPRequestHandler.rebaselineall):
* Scripts/webkitpy/tool/servers/gardeningserver_unittest.py:
(GardeningServerTest.test_rebaselineall):
(GardeningServerTest.test_rebaselineall.run_command):
2012-07-02 Ojan Vafai <ojan@chromium.org>
Remove Leopard support from the flakiness dashboard
......
......@@ -259,5 +259,5 @@ class CheckoutTest(unittest.TestCase):
mock_patch = Mock()
mock_patch.contents = lambda: "foo"
mock_patch.reviewer = lambda: None
expected_stderr = "MOCK run_command: ['svn-apply', '--force'], cwd=/mock-checkout\n"
expected_stderr = "MOCK run_command: ['svn-apply', '--force'], cwd=/mock-checkout, input=foo\n"
OutputCapture().assert_outputs(self, checkout.apply_patch, [mock_patch], expected_stderr=expected_stderr)
......@@ -88,7 +88,10 @@ class MockExecutive(object):
env_string = ""
if env:
env_string = ", env=%s" % env
log("MOCK run_command: %s, cwd=%s%s" % (args, cwd, env_string))
input_string = ""
if input:
input_string = ", input=%s" % input
log("MOCK run_command: %s, cwd=%s%s%s" % (args, cwd, env_string, input_string))
output = "MOCK output of child process"
if self._should_throw:
raise ScriptError("MOCK ScriptError", output=output)
......
......@@ -136,7 +136,7 @@ MockWatchList: determine_cc_and_messages
def test_land_cowboy(self):
expected_stderr = """MOCK run_and_throw_if_fail: ['mock-prepare-ChangeLog', '--email=MOCK email', '--merge-base=None', 'MockFile1'], cwd=/mock-checkout
MOCK run_and_throw_if_fail: ['mock-check-webkit-style', '--git-commit', 'MOCK git commit', '--diff-files', 'MockFile1', '--filter', '-changelog'], cwd=/mock-checkout
MOCK run_command: ['ruby', '-I', '/mock-checkout/Websites/bugs.webkit.org/PrettyPatch', '/mock-checkout/Websites/bugs.webkit.org/PrettyPatch/prettify.rb'], cwd=None
MOCK run_command: ['ruby', '-I', '/mock-checkout/Websites/bugs.webkit.org/PrettyPatch', '/mock-checkout/Websites/bugs.webkit.org/PrettyPatch/prettify.rb'], cwd=None, input=Patch1
MOCK: user.open_url: file://...
Was that diff correct?
Building WebKit
......
......@@ -32,6 +32,7 @@ import optparse
import os.path
import re
import shutil
import sys
import urllib
import webkitpy.common.config.urls as config_urls
......@@ -301,6 +302,81 @@ class RebaselineExpectations(AbstractDeclarativeCommand):
self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join(suffixes), test_name])
class RebaselineAll(AbstractDeclarativeCommand):
name = "rebaseline-all"
help_text = "Rebaseline based off JSON passed to stdin. Intended to only be called from other scripts."
def _run_webkit_patch(self, args):
try:
self._tool.executive.run_command([self._tool.path()] + args, cwd=self._tool.scm().checkout_root)
except ScriptError, e:
_log.error(e)
def _builders_to_fetch_from(self, builders):
# This routine returns the subset of builders that will cover all of the baseline search paths
# used in the input list. In particular, if the input list contains both Release and Debug
# versions of a configuration, we *only* return the Release version (since we don't save
# debug versions of baselines).
release_builders = set()
debug_builders = set()
builders_to_fallback_paths = {}
for builder in builders:
port = self._tool.port_factory.get_from_builder_name(builder)
if port.test_configuration().build_type == 'Release':
release_builders.add(builder)
else:
debug_builders.add(builder)
for builder in list(release_builders) + list(debug_builders):
port = self._tool.port_factory.get_from_builder_name(builder)
fallback_path = port.baseline_search_path()
if fallback_path not in builders_to_fallback_paths.values():
builders_to_fallback_paths[builder] = fallback_path
return builders_to_fallback_paths.keys()
def _rebaseline_commands(self, test_list):
path_to_webkit_patch = self._tool.path()
cwd = self._tool.scm().checkout_root
commands = []
for test in test_list:
for builder in self._builders_to_fetch_from(test_list[test]):
suffixes = ','.join(test_list[test][builder])
cmd_line = [path_to_webkit_patch, 'rebaseline-test', '--print-scm-changes', '--suffixes', suffixes, builder, test]
commands.append(tuple([cmd_line, cwd]))
return commands
def _files_to_add(self, command_results):
files_to_add = set()
for output in [result[1] for result in command_results]:
try:
files_to_add.update(json.loads(output)['add'])
except ValueError, e:
_log.warning('"%s" is not a JSON object, ignoring' % output)
return list(files_to_add)
def _optimize_baselines(self, test_list):
# We don't run this in parallel because modifying the SCM in parallel is unreliable.
for test in test_list:
all_suffixes = set()
for builder in self._builders_to_fetch_from(test_list[test]):
all_suffixes.update(test_list[test][builder])
self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join(all_suffixes), test])
def _rebaseline(self, json_input):
test_list = json.loads(json_input)
commands = self._rebaseline_commands(test_list)
command_results = self._tool.executive.run_in_parallel(commands)
files_to_add = self._files_to_add(command_results)
self._tool.scm().add_list(list(files_to_add))
self._optimize_baselines(test_list)
def execute(self, options, args, tool):
self._rebaseline(sys.stdin.read())
class Rebaseline(AbstractDeclarativeCommand):
name = "rebaseline"
help_text = "Replaces local expected.txt files with new results from build bots"
......
......@@ -189,6 +189,35 @@ Retrieving http://example.com/f/builders/Webkit Mac10.7/results/layout-test-resu
"""
OutputCapture().assert_outputs(self, command._rebaseline_test, ["Webkit Mac10.7", "userscripts/another-test.html", ["chromium-mac-snowleopard"], "txt"], expected_logs=expected_logs)
def test_rebaseline_all(self):
old_exact_matches = builders._exact_matches
builders._exact_matches = {
"MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
"MOCK builder (Debug)": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier", "debug"])},
}
command = RebaselineAll()
tool = MockTool()
command.bind_to_tool(tool)
tool.executive = MockExecutive(should_log=True)
expected_stderr = """MOCK run_command: ['echo', 'rebaseline-test', '--print-scm-changes', '--suffixes', u'txt,png', u'MOCK builder', u'user-scripts/another-test.html'], cwd=/mock-checkout
MOCK run_command: ['echo', 'optimize-baselines', '--suffixes', u'txt,png', u'user-scripts/another-test.html'], cwd=/mock-checkout
"""
OutputCapture().assert_outputs(self, command._rebaseline, ['{"user-scripts/another-test.html":{"MOCK builder": ["txt","png"]}}'], expected_stderr=expected_stderr)
expected_stderr = """MOCK run_command: ['echo', 'rebaseline-test', '--print-scm-changes', '--suffixes', u'txt,png', u'MOCK builder (Debug)', u'user-scripts/another-test.html'], cwd=/mock-checkout
MOCK run_command: ['echo', 'optimize-baselines', '--suffixes', u'txt,png', u'user-scripts/another-test.html'], cwd=/mock-checkout
"""
OutputCapture().assert_outputs(self, command._rebaseline, ['{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"]}}'], expected_stderr=expected_stderr)
expected_stderr = """MOCK run_command: ['echo', 'rebaseline-test', '--print-scm-changes', '--suffixes', u'txt', u'MOCK builder', u'user-scripts/another-test.html'], cwd=/mock-checkout
MOCK run_command: ['echo', 'optimize-baselines', '--suffixes', u'txt', u'user-scripts/another-test.html'], cwd=/mock-checkout
"""
OutputCapture().assert_outputs(self, command._rebaseline, ['{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"], "MOCK builder": ["txt"]}}'], expected_stderr=expected_stderr)
builders._exact_matches = old_exact_matches
def test_rebaseline_expectations(self):
command = RebaselineExpectations()
tool = MockTool()
......
......@@ -140,6 +140,7 @@ class GardeningHTTPRequestHandler(ReflectionHandler):
self._expectations_updater().update_expectations(self._read_entity_body_as_json())
self._serve_text('success')
# FIXME: Is this dead code?
def rebaseline(self):
builder = self.query['builder'][0]
command = [ 'rebaseline-test' ]
......@@ -155,64 +156,7 @@ class GardeningHTTPRequestHandler(ReflectionHandler):
self._run_webkit_patch(command)
self._serve_text('success')
def _builders_to_fetch_from(self, builders):
# This routine returns the subset of builders that will cover all of the baseline search paths
# used in the input list. In particular, if the input list contains both Release and Debug
# versions of a configuration, we *only* return the Release version (since we don't save
# debug versions of baselines).
release_builders = set()
debug_builders = set()
builders_to_fallback_paths = {}
for builder in builders:
port = self.server.tool.port_factory.get_from_builder_name(builder)
if port.test_configuration().build_type == 'Release':
release_builders.add(builder)
else:
debug_builders.add(builder)
for builder in list(release_builders) + list(debug_builders):
port = self.server.tool.port_factory.get_from_builder_name(builder)
fallback_path = port.baseline_search_path()
if fallback_path not in builders_to_fallback_paths.values():
builders_to_fallback_paths[builder] = fallback_path
return builders_to_fallback_paths.keys()
def _rebaseline_commands(self, test_list):
path_to_webkit_patch = self.server.tool.path()
cwd = self.server.tool.scm().checkout_root
commands = []
for test in test_list:
for builder in self._builders_to_fetch_from(test_list[test]):
suffixes = ','.join(test_list[test][builder])
cmd_line = [path_to_webkit_patch, 'rebaseline-test', '--print-scm-changes', '--suffixes', suffixes, builder, test]
commands.append(tuple([cmd_line, cwd]))
return commands
def _files_to_add(self, command_results):
files_to_add = set()
for output in [result[1] for result in command_results]:
try:
files_to_add.update(json.loads(output)['add'])
except ValueError, e:
_log.warning('"%s" is not a JSON object, ignoring' % output)
return list(files_to_add)
def _optimize_baselines(self, test_list):
# We don't run this in parallel because modifying the SCM in parallel is unreliable.
for test in test_list:
all_suffixes = set()
for builder in self._builders_to_fetch_from(test_list[test]):
all_suffixes.update(test_list[test][builder])
self._run_webkit_patch(['optimize-baselines', '--suffixes', ','.join(all_suffixes), test])
def rebaselineall(self):
test_list = self._read_entity_body_as_json()
commands = self._rebaseline_commands(test_list)
command_results = self.server.tool.executive.run_in_parallel(commands)
files_to_add = self._files_to_add(command_results)
self.server.tool.scm().add_list(list(files_to_add))
self._optimize_baselines(test_list)
command = ['rebaseline-all']
self.server.tool.executive.run_command([self.server.tool.path()] + command, input=self.read_entity_body(), cwd=self.server.tool.scm().checkout_root)
self._serve_text('success')
......@@ -69,7 +69,7 @@ class TestGardeningHTTPRequestHandler(GardeningHTTPRequestHandler):
def _expectations_updater(self):
return GardeningExpectationsUpdater(self.server.tool, TestPortFactory.create())
def _read_entity_body(self):
def read_entity_body(self):
return self.body if self.body else ''
def _serve_text(self, text):
......@@ -183,26 +183,20 @@ class GardeningServerTest(unittest.TestCase):
self._post_to_path("/rollout?revision=2314&reason=MOCK+rollout+reason", expected_stderr=expected_stderr, expected_stdout=expected_stdout)
def test_rebaselineall(self):
builders._exact_matches = {
"MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"])},
"MOCK builder (Debug)": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier", "debug"])},
}
expected_stderr = "MOCK run_command: ['echo', 'rebaseline-test', '--print-scm-changes', '--suffixes', u'%s', u'%s', u'user-scripts/another-test.html'], cwd=/mock-checkout\nMOCK run_command: ['echo', 'optimize-baselines', '--suffixes', u'%s', u'user-scripts/another-test.html'], cwd=/mock-checkout\n"
expected_stderr = "MOCK run_command: ['echo', 'rebaseline-all'], cwd=/mock-checkout, input={\"user-scripts/another-test.html\":{\"%s\": [%s]}}\n"
expected_stdout = "== Begin Response ==\nsuccess\n== End Response ==\n"
server = MockServer()
self.output = ['{"add": [], "delete": []}', '']
def run_command(args, cwd=None, **kwargs):
print >> sys.stderr, "MOCK run_command: %s, cwd=%s" % (args, cwd)
def run_command(args, cwd=None, input=None, **kwargs):
print >> sys.stderr, "MOCK run_command: %s, cwd=%s, input=%s" % (args, cwd, input)
return self.output.pop(0)
server.tool.executive.run_command = run_command
self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder": ["txt","png"]}}', expected_stderr=expected_stderr % ('txt,png', 'MOCK builder', 'txt,png'), expected_stdout=expected_stdout, server=server)
self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder": ["txt","png"]}}', expected_stderr=expected_stderr % ('MOCK builder', '"txt","png"'), expected_stdout=expected_stdout, server=server)
self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"]}}', expected_stderr=expected_stderr % ('txt,png', 'MOCK builder (Debug)', 'txt,png'), expected_stdout=expected_stdout)
self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"], "MOCK builder": ["txt"]}}', expected_stderr=expected_stderr % ('txt', 'MOCK builder', 'txt'), expected_stdout=expected_stdout)
self._post_to_path("/rebaselineall", body='{"user-scripts/another-test.html":{"MOCK builder (Debug)": ["txt","png"]}}', expected_stderr=expected_stderr % ('MOCK builder (Debug)', '"txt","png"'), expected_stdout=expected_stdout)
def test_rebaseline_new_port(self):
builders._exact_matches = {"MOCK builder": {"port_name": "test-mac-leopard", "specifiers": set(["mock-specifier"]), "move_overwritten_baselines_to": ["mock-port-fallback", "mock-port-fallback2"]}}
......
......@@ -59,12 +59,12 @@ class ReflectionHandler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_POST(self):
self._handle_request()
def _read_entity_body(self):
def read_entity_body(self):
length = int(self.headers.getheader('content-length'))
return self.rfile.read(length)
def _read_entity_body_as_json(self):
return json.loads(self._read_entity_body())
return json.loads(self.read_entity_body())
def _handle_request(self):
if "?" in self.path:
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment