Diff
Modified: trunk/Tools/ChangeLog (125122 => 125123)
--- trunk/Tools/ChangeLog 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/ChangeLog 2012-08-09 00:19:23 UTC (rev 125123)
@@ -1,3 +1,78 @@
+2012-08-08 Ryosuke Niwa <[email protected]>
+
+ Add Perf EWS IRC bot
+ https://bugs.webkit.org/show_bug.cgi?id=92913
+
+ Reviewed by Dirk Pranke.
+
+ Adds the preliminary implementation of perfalizer, a IRC bot that runs performance tests
+ based on IRC requests.
+
+ * Scripts/webkitpy/common/checkout/scm/scm_mock.py:
+ (MockSCM.head_svn_revision): The actual implementation returns string, so match that.
+ (MockSCM.svn_revision): Ditto.
+ * Scripts/webkitpy/common/net/bugzilla/bugzilla.py:
+ (Bugzilla.add_attachment_to_bug): Added mimetype.
+ * Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py:
+ (MockBugzilla.add_attachment_to_bug): Ditto.
+ * Scripts/webkitpy/common/system/filesystem.py:
+ (FileSystem.copytree): Added.
+ * Scripts/webkitpy/common/system/filesystem_mock.py:
+ (MockFileSystem.copytree): Added.
+ * Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py: Rebaselined tests
+ that had assumed revision numbers were integers.
+ (test_run_with_json_output):
+ (test_run_with_description):
+ (test_run_generates_json_by_default):
+ (test_run_generates_and_show_results_page):
+ (test_run_with_json_source):
+ (test_run_with_multiple_repositories):
+ * Scripts/webkitpy/tool/bot/flakytestreporter_unittest.py:
+ * Scripts/webkitpy/tool/commands/__init__.py:
+ * Scripts/webkitpy/tool/commands/perfalizer.py: Added.
+ (PerfalizerTask):
+ (PerfalizerTask.__init__):
+ (PerfalizerTask._copy_build_product_without_patch):
+ (PerfalizerTask.run):
+ (PerfalizerTask.parent_command):
+ (PerfalizerTask.run_webkit_patch):
+ (PerfalizerTask._json_path):
+ (PerfalizerTask._results_page_path):
+ (PerfalizerTask._run_perf_test):
+ (PerfalizerTask.run_command):
+ (PerfalizerTask.command_passed):
+ (PerfalizerTask.command_failed):
+ (PerfalizerTask.refetch_patch):
+ (PerfalizerTask.expected_failures):
+ (PerfalizerTask.build_style):
+ (PerfTest): IRC command.
+ (PerfTest.execute):
+ (Perfalizer): IRC bot.
+ (Perfalizer.begin_work_queue):
+ (Perfalizer.work_item_log_path):
+ (Perfalizer._is_old_failure):
+ (Perfalizer.next_work_item):
+ (Perfalizer.process_work_item):
+ (Perfalizer.handle_unexpected_error):
+ (Perfalizer.handle_script_error):
+ * Scripts/webkitpy/tool/commands/perfalizer_unittest.py: Added.
+ (PerfalizerTaskTest):
+ (PerfalizerTaskTest._create_and_run_perfalizer):
+ (PerfalizerTaskTest._create_and_run_perfalizer.logger):
+ (PerfalizerTaskTest._create_and_run_perfalizer.run_webkit_patch):
+ (PerfalizerTaskTest._create_and_run_perfalizer.run_perf_test):
+ (PerfalizerTaskTest.test_run):
+ (PerfalizerTaskTest.test_run_with_clean_fails):
+ (PerfalizerTaskTest.test_run_with_update_fails):
+ (PerfalizerTaskTest.test_run_with_build_fails):
+ (PerfalizerTaskTest.test_run_with_perf_test_fails):
+ (PerfalizerTaskTest.test_run_without_results_page):
+ * Scripts/webkitpy/tool/commands/queues_unittest.py:
+ (AbstractPatchQueueTest.test_upload_results_archive_for_patch): Rebaselined.
+ * Scripts/webkitpy/tool/commands/upload_unittest.py:
+ (test_attach_to_bug): Ditto.
+ (test_attach_to_bug_no_description_or_comment): Ditto.
+
2012-08-08 Dirk Pranke <[email protected]>
webkit-patch rebaseline-expectations needs to support multiple expectations files
Modified: trunk/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/common/checkout/scm/scm_mock.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -69,10 +69,10 @@
return ["MockFile1"]
def head_svn_revision(self):
- return 1234
+ return '1234'
def svn_revision(self, path):
- return 5678
+ return '5678'
def create_patch(self, git_commit, changed_files=None):
return "Patch1"
Modified: trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -578,19 +578,14 @@
return file_object.name
return "bug-%s-%s.%s" % (bug_id, timestamp(), extension)
- def add_attachment_to_bug(self,
- bug_id,
- file_or_string,
- description,
- filename=None,
- comment_text=None):
+ def add_attachment_to_bug(self, bug_id, file_or_string, description, filename=None, comment_text=None, mimetype=None):
self.authenticate()
log('Adding attachment "%s" to %s' % (description, self.bug_url_for_bug_id(bug_id)))
self.browser.open(self.add_attachment_url(bug_id))
self.browser.select_form(name="entryform")
file_object = self._file_object_for_upload(file_or_string)
filename = filename or self._filename_for_upload(file_object, bug_id)
- self._fill_attachment_form(description, file_object, filename=filename)
+ self._fill_attachment_form(description, file_object, filename=filename, mimetype=mimetype)
if comment_text:
log(comment_text)
self.browser['comment'] = comment_text
Modified: trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/common/net/bugzilla/bugzilla_mock.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -393,13 +393,9 @@
log("MOCK bug comment: bug_id=%s, cc=%s\n--- Begin comment ---\n%s\n--- End comment ---\n" % (
bug_id, cc, comment_text))
- def add_attachment_to_bug(self,
- bug_id,
- file_or_string,
- description,
- filename=None,
- comment_text=None):
- log("MOCK add_attachment_to_bug: bug_id=%s, description=%s filename=%s" % (bug_id, description, filename))
+ def add_attachment_to_bug(self, bug_id, file_or_string, description, filename=None, comment_text=None, mimetype=None):
+ log("MOCK add_attachment_to_bug: bug_id=%s, description=%s filename=%s mimetype=%s" %
+ (bug_id, description, filename, mimetype))
if comment_text:
log("-- Begin comment --")
log(comment_text)
Modified: trunk/Tools/Scripts/webkitpy/common/system/filesystem.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/common/system/filesystem.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/common/system/filesystem.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -262,6 +262,9 @@
"""Delete the directory rooted at path, whether empty or not."""
shutil.rmtree(path, ignore_errors=True)
+ def copytree(self, source, destination):
+ shutil.copytree(source, destination)
+
def split(self, path):
"""Return (dirname, basename + '.' + ext)"""
return os.path.split(path)
Modified: trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/common/system/filesystem_mock.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -378,6 +378,16 @@
self.dirs = set(filter(lambda d: not d.startswith(path), self.dirs))
+ def copytree(self, source, destination):
+ source = self.normpath(source)
+ destination = self.normpath(destination)
+
+ for source_file in self.files:
+ if source_file.startswith(source):
+ destination_path = self.join(destination, self.relpath(source_file, source))
+ self.maybe_make_directory(self.dirname(destination_path))
+ self.files[destination_path] = self.files[source_file]
+
def split(self, path):
idx = path.rfind(self.sep)
if idx == -1:
Modified: trunk/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/performance_tests/perftestsrunner_unittest.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -268,7 +268,7 @@
"timestamp": 123456789, "results":
{"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"},
"inspector/pass.html:group_name:test_name": 42},
- "webkit-revision": 5678, "branch": "webkit-trunk"})
+ "webkit-revision": "5678", "branch": "webkit-trunk"})
def test_run_with_description(self):
runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json',
@@ -278,7 +278,7 @@
"timestamp": 123456789, "description": "some description", "results":
{"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"},
"inspector/pass.html:group_name:test_name": 42},
- "webkit-revision": 5678, "branch": "webkit-trunk"})
+ "webkit-revision": "5678", "branch": "webkit-trunk"})
def create_runner_and_setup_results_template(self, args=[]):
runner, port = self.create_runner(args)
@@ -310,7 +310,7 @@
"timestamp": 123456789, "results":
{"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"},
"inspector/pass.html:group_name:test_name": 42},
- "webkit-revision": 5678, "branch": "webkit-trunk"}])
+ "webkit-revision": "5678", "branch": "webkit-trunk"}])
self.assertTrue(filesystem.isfile(output_json_path))
self.assertTrue(filesystem.isfile(results_page_path))
@@ -324,7 +324,7 @@
expected_entry = {"timestamp": 123456789, "results": {"Bindings/event-target-wrapper":
{"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"},
- "inspector/pass.html:group_name:test_name": 42}, "webkit-revision": 5678, "branch": "webkit-trunk"}
+ "inspector/pass.html:group_name:test_name": 42}, "webkit-revision": "5678", "branch": "webkit-trunk"}
self.maxDiff = None
json_output = port.host.filesystem.read_text_file('/mock-checkout/output.json')
@@ -373,7 +373,7 @@
"timestamp": 123456789, "results":
{"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"},
"inspector/pass.html:group_name:test_name": 42},
- "webkit-revision": 5678, "branch": "webkit-trunk",
+ "webkit-revision": "5678", "branch": "webkit-trunk",
"key": "value"})
def test_run_with_bad_json_source(self):
@@ -394,7 +394,7 @@
"timestamp": 123456789, "results":
{"Bindings/event-target-wrapper": {"max": 1510, "avg": 1489.05, "median": 1487, "min": 1471, "stdev": 14.46, "unit": "ms"},
"inspector/pass.html:group_name:test_name": 42.0},
- "webkit-revision": 5678, "some-revision": 5678, "branch": "webkit-trunk"})
+ "webkit-revision": "5678", "some-revision": "5678", "branch": "webkit-trunk"})
def test_run_with_upload_json(self):
runner, port = self.create_runner(args=['--output-json-path=/mock-checkout/output.json',
Modified: trunk/Tools/Scripts/webkitpy/tool/bot/flakytestreporter_unittest.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/tool/bot/flakytestreporter_unittest.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/tool/bot/flakytestreporter_unittest.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -125,7 +125,7 @@
component: Tools / Tests
cc: [email protected]
blocked: 50856
-MOCK add_attachment_to_bug: bug_id=60001, description=Failure diff from mock-bot-id filename=failure.diff
+MOCK add_attachment_to_bug: bug_id=60001, description=Failure diff from mock-bot-id filename=failure.diff mimetype=None
MOCK bug comment: bug_id=50000, cc=None
--- Begin comment ---
The dummy-queue encountered the following flaky tests while processing attachment 10000:
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/__init__.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -12,6 +12,7 @@
from webkitpy.tool.commands.findusers import FindUsers
from webkitpy.tool.commands.gardenomatic import GardenOMatic
from webkitpy.tool.commands.openbugs import OpenBugs
+from webkitpy.tool.commands.perfalizer import Perfalizer
from webkitpy.tool.commands.prettydiff import PrettyDiff
from webkitpy.tool.commands.queries import *
from webkitpy.tool.commands.queues import *
Added: trunk/Tools/Scripts/webkitpy/tool/commands/perfalizer.py (0 => 125123)
--- trunk/Tools/Scripts/webkitpy/tool/commands/perfalizer.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/perfalizer.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -0,0 +1,215 @@
+# Copyright (c) 2012 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# 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 Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software 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.
+
+from webkitpy.common.system.deprecated_logging import log
+from webkitpy.tool.bot.expectedfailures import ExpectedFailures
+from webkitpy.tool.bot.irc_command import IRCCommand
+from webkitpy.tool.bot.irc_command import Help
+from webkitpy.tool.bot.irc_command import Hi
+from webkitpy.tool.bot.irc_command import Restart
+from webkitpy.tool.bot.ircbot import IRCBot
+from webkitpy.tool.bot.patchanalysistask import PatchAnalysisTask, PatchAnalysisTaskDelegate, UnableToApplyPatch
+from webkitpy.tool.bot.sheriff import Sheriff
+from webkitpy.tool.commands.queues import AbstractQueue
+from webkitpy.tool.commands.stepsequence import StepSequenceErrorHandler
+
+
+class PerfalizerTask(PatchAnalysisTask):
+ def __init__(self, tool, patch, logger):
+ PatchAnalysisTask.__init__(self, self, patch)
+ self._port = tool.port_factory.get()
+ self._tool = tool
+ self._logger = logger
+
+ def _copy_build_product_without_patch(self):
+ filesystem = self._tool.filesystem
+ configuration = filesystem.basename(self._port._build_path())
+ self._build_directory = filesystem.dirname(self._port._build_path())
+ self._build_directory_without_patch = self._build_directory + 'WithoutPatch'
+
+ try:
+ filesystem.rmtree(self._build_directory_without_patch)
+ filesystem.copytree(filesystem.join(self._build_directory, configuration),
+ filesystem.join(self._build_directory_without_patch, configuration))
+ return True
+ except:
+ return False
+
+ def run(self):
+ if not self._patch.committer() and not self._patch.attacher().can_commit:
+ self._logger('The patch %d is not authorized by a commmitter' % self._patch.id())
+ return False
+
+ self._logger('Preparing to run performance tests for the attachment %d...' % self._patch.id())
+ if not self._clean() or not self._update():
+ return False
+
+ head_revision = self._tool.scm().head_svn_revision()
+
+ self._logger('Building WebKit at r%s without the patch' % head_revision)
+ if not self._build():
+ return False
+
+ if not self._port.check_build(needs_http=False):
+ self._logger('Failed to build DumpRenderTree.')
+ return False
+
+ if not self._copy_build_product_without_patch():
+ self._logger('Failed to copy the build product from %s to %s' % (self._build_directory, self._build_directory_without_patch))
+ return False
+
+ self._logger('Building WebKit at r%s with the patch' % head_revision)
+ if not self._apply() or not self._build():
+ return False
+
+ if not self._port.check_build(needs_http=False):
+ self._logger('Failed to build DumpRenderTree.')
+ return False
+
+ filesystem = self._tool.filesystem
+ if filesystem.exists(self._json_path()):
+ filesystem.remove(self._json_path())
+
+ self._logger("Running performance tests...")
+ if self._run_perf_test(self._build_directory_without_patch) < 0:
+ self._logger('Failed to run performance tests without the patch.')
+ return False
+
+ if self._run_perf_test(self._build_directory) < 0:
+ self._logger('Failed to run performance tests with the patch.')
+ return False
+
+ if not filesystem.exists(self._results_page_path()):
+ self._logger('Failed to generate the results page.')
+ return False
+
+ results_page = filesystem.read_text_file(self._results_page_path())
+ self._tool.bugs.add_attachment_to_bug(self._patch.bug_id(), results_page,
+ description="Performance tests results for %d" % self._patch.id(), mimetype='text/html')
+
+ self._logger("Uploaded the results on the bug %d" % self._patch.bug_id())
+ return True
+
+ def parent_command(self):
+ return "perfalizer"
+
+ def run_webkit_patch(self, args):
+ webkit_patch_args = [self._tool.path()]
+ webkit_patch_args.extend(args)
+ return self._tool.executive.run_and_throw_if_fail(webkit_patch_args, cwd=self._tool.scm().checkout_root)
+
+ def _json_path(self):
+ return self._tool.filesystem.join(self._build_directory, 'PerformanceTestResults.json')
+
+ def _results_page_path(self):
+ return self._tool.filesystem.join(self._build_directory, 'PerformanceTestResults.html')
+
+ def _run_perf_test(self, build_path):
+ filesystem = self._tool.filesystem
+ script_path = filesystem.join(filesystem.dirname(self._tool.path()), 'run-perf-tests')
+ perf_test_runner_args = [script_path, '--no-build', '--no-show-results', '--build-directory', build_path,
+ '--output-json-path', self._json_path()]
+ return self._tool.executive.run_and_throw_if_fail(perf_test_runner_args, cwd=self._tool.scm().checkout_root)
+
+ def run_command(self, command):
+ self.run_webkit_patch(command)
+
+ def command_passed(self, message, patch):
+ pass
+
+ def command_failed(self, message, script_error, patch):
+ self._logger(message)
+
+ def refetch_patch(self, patch):
+ return self._tool.bugs.fetch_attachment(patch.id())
+
+ def expected_failures(self):
+ return ExpectedFailures()
+
+ def build_style(self):
+ return "release"
+
+
+class PerfTest(IRCCommand):
+ def execute(self, nick, args, tool, sheriff):
+ if not args:
+ tool.irc().post(nick + ": Please specify an attachment/patch id")
+ return
+
+ patch_id = args[0]
+ patch = tool.bugs.fetch_attachment(patch_id)
+ if not patch:
+ tool.irc().post(nick + ": Could not fetch the patch")
+ return
+
+ task = PerfalizerTask(tool, patch, lambda message: tool.irc().post('%s: %s' % (nick, message)))
+ task.run()
+
+
+class Perfalizer(AbstractQueue, StepSequenceErrorHandler):
+ name = "perfalizer"
+ watchers = AbstractQueue.watchers + ["[email protected]"]
+
+ _commands = {
+ "help": Help,
+ "hi": Hi,
+ "restart": Restart,
+ "test": PerfTest,
+ }
+
+ # AbstractQueue methods
+
+ def begin_work_queue(self):
+ AbstractQueue.begin_work_queue(self)
+ self._sheriff = Sheriff(self._tool, self)
+ self._irc_bot = IRCBot("perfalizer", self._tool, self._sheriff, self._commands)
+ self._tool.ensure_irc_connected(self._irc_bot.irc_delegate())
+
+ def work_item_log_path(self, failure_map):
+ return None
+
+ def _is_old_failure(self, revision):
+ return self._tool.status_server.svn_revision(revision)
+
+ def next_work_item(self):
+ self._irc_bot.process_pending_messages()
+ return
+
+ def process_work_item(self, failure_map):
+ return True
+
+ def handle_unexpected_error(self, failure_map, message):
+ log(message)
+
+ # StepSequenceErrorHandler methods
+
+ @classmethod
+ def handle_script_error(cls, tool, state, script_error):
+ # Ideally we would post some information to IRC about what went wrong
+ # here, but we don't have the IRC password in the child process.
+ pass
Added: trunk/Tools/Scripts/webkitpy/tool/commands/perfalizer_unittest.py (0 => 125123)
--- trunk/Tools/Scripts/webkitpy/tool/commands/perfalizer_unittest.py (rev 0)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/perfalizer_unittest.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -0,0 +1,111 @@
+# Copyright (C) 2012 Google Inc. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above
+# 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 Google Inc. nor the names of its
+# contributors may be used to endorse or promote products derived from
+# this software 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.
+
+import unittest
+
+from webkitpy.common.net.buildbot import Builder
+from webkitpy.common.system.executive import ScriptError
+from webkitpy.common.system.outputcapture import OutputCapture
+from webkitpy.layout_tests.port.test import TestPort
+from webkitpy.tool.commands.perfalizer import PerfalizerTask
+from webkitpy.tool.mocktool import MockTool
+
+
+class PerfalizerTaskTest(unittest.TestCase):
+ def _create_and_run_perfalizer(self, commands_to_fail=[]):
+ tool = MockTool()
+ patch = tool.bugs.fetch_attachment(10000)
+
+ logs = []
+
+ def logger(message):
+ logs.append(message)
+
+ def run_webkit_patch(args):
+ if args[0] in commands_to_fail:
+ raise ScriptError
+
+ def run_perf_test(build_path):
+ if 'run-perf-tests' in commands_to_fail:
+ return -1
+ if 'results-page' not in commands_to_fail:
+ tool.filesystem.write_text_file(tool.filesystem.join(build_path, 'PerformanceTestResults.html'), 'results page')
+ return 0
+
+ perfalizer = PerfalizerTask(tool, patch, logger)
+ perfalizer._port = TestPort(tool)
+ perfalizer.run_webkit_patch = run_webkit_patch
+ perfalizer._run_perf_test = run_perf_test
+
+ capture = OutputCapture()
+ capture.capture_output()
+
+ if commands_to_fail:
+ self.assertFalse(perfalizer.run())
+ else:
+ self.assertTrue(perfalizer.run())
+
+ capture.restore_output()
+
+ return logs
+
+ def test_run(self):
+ self.assertEqual(self._create_and_run_perfalizer(), [
+ 'Preparing to run performance tests for the attachment 10000...',
+ 'Building WebKit at r1234 without the patch',
+ 'Building WebKit at r1234 with the patch',
+ 'Running performance tests...',
+ 'Uploaded the results on the bug 50000'])
+
+ def test_run_with_clean_fails(self):
+ self.assertEqual(self._create_and_run_perfalizer(['clean']), [
+ 'Preparing to run performance tests for the attachment 10000...',
+ 'Unable to clean working directory'])
+
+ def test_run_with_update_fails(self):
+ logs = self._create_and_run_perfalizer(['update'])
+ self.assertEqual(len(logs), 2)
+ self.assertEqual(logs[-1], 'Unable to update working directory')
+
+ def test_run_with_build_fails(self):
+ logs = self._create_and_run_perfalizer(['build'])
+ self.assertEqual(len(logs), 3)
+
+ def test_run_with_build_fails(self):
+ logs = self._create_and_run_perfalizer(['apply-attachment'])
+ self.assertEqual(len(logs), 4)
+
+ def test_run_with_perf_test_fails(self):
+ logs = self._create_and_run_perfalizer(['run-perf-tests'])
+ self.assertEqual(len(logs), 5)
+ self.assertEqual(logs[-1], 'Failed to run performance tests without the patch.')
+
+ def test_run_without_results_page(self):
+ logs = self._create_and_run_perfalizer(['results-page'])
+ self.assertEqual(len(logs), 5)
+ self.assertEqual(logs[-1], 'Failed to generate the results page.')
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -173,7 +173,7 @@
queue._options = Mock()
queue._options.port = None
patch = queue._tool.bugs.fetch_attachment(10001)
- expected_stderr = """MOCK add_attachment_to_bug: bug_id=50000, description=Archive of layout-test-results from bot filename=layout-test-results.zip
+ expected_stderr = """MOCK add_attachment_to_bug: bug_id=50000, description=Archive of layout-test-results from bot filename=layout-test-results.zip mimetype=None
-- Begin comment --
The attached test failures were seen while running run-webkit-tests on the mock-queue.
Port: MockPort Platform: MockPlatform 1.0
@@ -405,14 +405,14 @@
Port: MockPort Platform: MockPlatform 1.0
--- End comment ---
-MOCK add_attachment_to_bug: bug_id=50002, description=Failure diff from bot filename=failure.diff
+MOCK add_attachment_to_bug: bug_id=50002, description=Failure diff from bot filename=failure.diff mimetype=None
MOCK bug comment: bug_id=50002, cc=None
--- Begin comment ---
The commit-queue just saw bar/baz.html flake (Text diff mismatch) while processing attachment 10000 on bug 50000.
Port: MockPort Platform: MockPlatform 1.0
--- End comment ---
-MOCK add_attachment_to_bug: bug_id=50002, description=Archive of layout-test-results from bot filename=layout-test-results.zip
+MOCK add_attachment_to_bug: bug_id=50002, description=Archive of layout-test-results from bot filename=layout-test-results.zip mimetype=None
MOCK bug comment: bug_id=50000, cc=None
--- Begin comment ---
The commit-queue encountered the following flaky tests while processing attachment 10000:
Modified: trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py (125122 => 125123)
--- trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py 2012-08-09 00:18:23 UTC (rev 125122)
+++ trunk/Tools/Scripts/webkitpy/tool/commands/upload_unittest.py 2012-08-09 00:19:23 UTC (rev 125123)
@@ -79,7 +79,7 @@
options = MockOptions()
options.comment = "extra comment"
options.description = "file description"
- expected_stderr = """MOCK add_attachment_to_bug: bug_id=50000, description=file description filename=None
+ expected_stderr = """MOCK add_attachment_to_bug: bug_id=50000, description=file description filename=None mimetype=None
-- Begin comment --
extra comment
-- End comment --
@@ -90,7 +90,7 @@
options = MockOptions()
options.comment = None
options.description = None
- expected_stderr = """MOCK add_attachment_to_bug: bug_id=50000, description=file.txt filename=None
+ expected_stderr = """MOCK add_attachment_to_bug: bug_id=50000, description=file.txt filename=None mimetype=None
"""
self.assert_execute_outputs(AttachToBug(), [50000, "path/to/file.txt"], options=options, expected_stderr=expected_stderr)