Changeset 138826 in webkit
- Timestamp:
- Jan 4, 2013 12:05:24 PM (11 years ago)
- Location:
- trunk/Tools
- Files:
-
- 11 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r138814 r138826 1 2013-01-04 Eric Seidel <eric@webkit.org> 2 3 FlakyTestReporter should be re-enabled and taught how to post patches 4 https://bugs.webkit.org/show_bug.cgi?id=103839 5 6 Reviewed by Adam Barth. 7 8 This moves LayoutTestResultsReader off of the DeprecatedPort object. 9 It also adds a real Port object to the EWS and CommitQueue objects 10 using a new PatchProcessingQueue superclass. 11 PatchProcessingQueue doesn't seem to be the cleanest insertion point 12 but works for this purpose. 13 I also moved _upload_results_archive_for_patch into PatchProcessingQueue 14 to resolve a FIXME. 15 16 This required some hacks/shiming between the non-specific "old" 17 port names which the EWS system is currently using, and the new 18 port objects. This shimming is done in PatchProcessingQueue._new_port_name_from_old. 19 20 Hopefully this will fix the flaky test reporter and results uploading. 21 Certainly it's another small step towards getting rid of the old ports.py 22 infrastructure and making the NRWT Port class common webkitpy infrastructure. 23 24 Now that DeprecatedPort is no longer used for the results directory 25 I removed all the explicit results-dir code which webkit-patch was using 26 in --non-interactive mode to tell NRWT to use a results-dir it understood. :) 27 28 * Scripts/webkitpy/common/config/ports.py: 29 (DeprecatedPort.run_perl_unittests_command): 30 * Scripts/webkitpy/common/config/ports_mock.py: 31 (MockPort.name): 32 * Scripts/webkitpy/common/system/outputcapture.py: 33 (OutputCapture.assert_outputs): 34 * Scripts/webkitpy/layout_tests/port/apple.py: 35 (ApplePort.determine_full_port_name): 36 * Scripts/webkitpy/tool/bot/layouttestresultsreader.py: 37 (LayoutTestResultsReader.__init__): 38 (LayoutTestResultsReader): 39 (LayoutTestResultsReader._read_file_contents): 40 (LayoutTestResultsReader._create_layout_test_results): 41 (LayoutTestResultsReader._create_unit_test_results): 42 (LayoutTestResultsReader.results): 43 (LayoutTestResultsReader.archive): 44 * Scripts/webkitpy/tool/bot/layouttestresultsreader_unittest.py: 45 (LayoutTestResultsReaderTest.test_missing_layout_test_results): 46 (LayoutTestResultsReaderTest.test_create_unit_test_results): 47 (test_missing_unit_test_results_path): 48 (test_layout_test_results): 49 (test_archive_last_layout_test_results): 50 * Scripts/webkitpy/tool/commands/earlywarningsystem.py: 51 (AbstractEarlyWarningSystem): 52 (AbstractEarlyWarningSystem.__init__): 53 (AbstractEarlyWarningSystem.begin_work_queue): 54 (AbstractEarlyWarningSystem.run_command): 55 * Scripts/webkitpy/tool/commands/queues.py: 56 (AbstractPatchQueue.work_item_log_path): 57 (PatchProcessingQueue): 58 (PatchProcessingQueue._new_port_name_from_old): 59 (PatchProcessingQueue.begin_work_queue): 60 (PatchProcessingQueue._upload_results_archive_for_patch): 61 (CommitQueue): 62 (CommitQueue.begin_work_queue): 63 (CommitQueue.run_command): 64 (AbstractReviewQueue): 65 (AbstractReviewQueue.__init__): 66 (AbstractReviewQueue.begin_work_queue): 67 * Scripts/webkitpy/tool/commands/queues_unittest.py: 68 (AbstractPatchQueueTest.test_next_patch): 69 (PatchProcessingQueueTest): 70 (PatchProcessingQueueTest.test_upload_results_archive_for_patch): 71 * Scripts/webkitpy/tool/steps/runtests.py: 72 (RunTests.run): 73 * Scripts/webkitpy/tool/steps/runtests_unittest.py: 74 1 75 2013-01-04 Dana Jansens <danakj@chromium.org> 2 76 -
trunk/Tools/Scripts/webkitpy/common/config/ports.py
r134371 r138826 117 117 return self.script_shell_command("test-webkitperl") 118 118 119 def layout_tests_results_path(self):120 return os.path.join(self.results_directory, "full_results.json")121 122 def unit_tests_results_path(self):123 return os.path.join(self.results_directory, "webkit_unit_tests_output.xml")124 125 119 126 120 class MacPort(DeprecatedPort): -
trunk/Tools/Scripts/webkitpy/common/config/ports_mock.py
r113499 r138826 29 29 30 30 class MockPort(object): 31 results_directory = "/mock-results"32 33 31 def name(self): 34 32 return "MockPort" 35 36 def layout_tests_results_path(self):37 return "/mock-results/full_results.json"38 39 def unit_tests_results_path(self):40 return "/mock-results/webkit_unit_tests_output.xml"41 33 42 34 def check_webkit_style_command(self): -
trunk/Tools/Scripts/webkitpy/layout_tests/port/apple.py
r137650 r138826 63 63 # being run, so this won't work if you're not on mac or win (respectively). 64 64 # If you're not on the o/s in question, you must specify a full version or -future (cf. above). 65 assert host.platform.os_name in port_name 65 assert host.platform.os_name in port_name, "%s is not in %s!" % (host.platform.os_name, port_name) 66 66 if port_name == cls.port_name and not getattr(options, 'webkit_test_runner', False): 67 67 port_name = cls.port_name + '-' + host.platform.os_version -
trunk/Tools/Scripts/webkitpy/tool/bot/layouttestresultsreader.py
r138775 r138826 1 # Copyright (c) 201 1Google Inc. All rights reserved.1 # Copyright (c) 2013 Google Inc. All rights reserved. 2 2 # 3 3 # Redistribution and use in source and binary forms, with or without … … 36 36 37 37 38 # FIXME: This class no longer has a clear purpose, and should probably 39 # be made part of Port, or renamed to LayoutTestResultsArchiver or something more fitting? 38 40 class LayoutTestResultsReader(object): 39 def __init__(self, tool, archive_directory): 40 self._tool = tool 41 def __init__(self, host, results_directory, archive_directory): 42 self._host = host 43 self._results_directory = results_directory 41 44 self._archive_directory = archive_directory 42 45 43 46 # FIXME: This exists for mocking, but should instead be mocked via 44 # tool.filesystem.read_text_file. They have different error handling at the moment.47 # host.filesystem.read_text_file. They have different error handling at the moment. 45 48 def _read_file_contents(self, path): 46 49 try: 47 return self._ tool.filesystem.read_text_file(path)50 return self._host.filesystem.read_text_file(path) 48 51 except IOError, e: # File does not exist or can't be read. 49 52 return None … … 51 54 # FIXME: This logic should move to the port object. 52 55 def _create_layout_test_results(self): 53 results_path = self._ tool.deprecated_port().layout_tests_results_path()56 results_path = self._host.filesystem.join(self._results_directory, "full_results.json") 54 57 results_html = self._read_file_contents(results_path) 55 58 if not results_html: … … 58 61 59 62 def _create_unit_test_results(self): 60 results_path = self._tool.deprecated_port().unit_tests_results_path() 61 if not results_path: 62 return None 63 results_path = self._host.filesystem.join(self._results_directory, "webkit_unit_tests_output.xml") 63 64 results_xml = self._read_file_contents(results_path) 64 65 if not results_xml: … … 70 71 unit_test_results = self._create_unit_test_results() 71 72 if layout_test_results: 72 # FIXME: We should not have to set failure_limit_count, but we 73 # do until run-webkit-tests can be updated save off the value 74 # of --exit-after-N-failures in results.html/results.json. 75 # https://bugs.webkit.org/show_bug.cgi?id=58481 73 # FIXME: This is used to detect if we had N failures due to 74 # N tests failing, or if we hit the "exit-after-n-failures" limit. 75 # These days we could just check for the "interrupted" key in results.json instead! 76 76 layout_test_results.set_failure_limit_count(RunTests.NON_INTERACTIVE_FAILURE_LIMIT_COUNT) 77 77 if unit_test_results: … … 79 79 return layout_test_results 80 80 81 def _results_directory(self):82 results_path = self._tool.deprecated_port().layout_tests_results_path()83 # FIXME: This is wrong in two ways:84 # 1. It assumes that results.html is at the top level of the results tree.85 # 2. This uses the "old" ports.py infrastructure instead of the new layout_tests/port86 # which will not support Chromium. However the new arch doesn't work with old-run-webkit-tests87 # so we have to use this for now.88 return self._tool.filesystem.dirname(results_path)89 90 81 def archive(self, patch): 91 results_directory = self._results_directory() 92 results_name, _ = self._tool.filesystem.splitext(self._tool.filesystem.basename(results_directory)) 82 filesystem = self._host.filesystem 83 workspace = self._host.workspace 84 results_directory = self._results_directory 85 results_name, _ = filesystem.splitext(filesystem.basename(results_directory)) 93 86 # Note: We name the zip with the bug_id instead of patch_id to match work_item_log_path(). 94 zip_path = self._tool.workspace.find_unused_filename(self._archive_directory, "%s-%s" % (patch.bug_id(), results_name), "zip")87 zip_path = workspace.find_unused_filename(self._archive_directory, "%s-%s" % (patch.bug_id(), results_name), "zip") 95 88 if not zip_path: 96 89 return None 97 if not self._tool.filesystem.isdir(results_directory):90 if not filesystem.isdir(results_directory): 98 91 _log.info("%s does not exist, not archiving." % results_directory) 99 92 return None 100 archive = self._tool.workspace.create_zip(zip_path, results_directory)93 archive = workspace.create_zip(zip_path, results_directory) 101 94 # Remove the results directory to prevent http logs, etc. from getting huge between runs. 102 95 # We could have create_zip remove the original, but this is more explicit. 103 self._tool.filesystem.rmtree(results_directory)96 filesystem.rmtree(results_directory) 104 97 return archive -
trunk/Tools/Scripts/webkitpy/tool/bot/layouttestresultsreader_unittest.py
r138775 r138826 32 32 from webkitpy.common.system.outputcapture import OutputCapture 33 33 from webkitpy.common.net.layouttestresults import LayoutTestResults 34 from webkitpy.tool.bot.layouttestresultsreader import * 35 from webkitpy.tool.mocktool import MockTool 34 from webkitpy.common.host_mock import MockHost 35 36 from .layouttestresultsreader import LayoutTestResultsReader 36 37 37 38 38 39 class LayoutTestResultsReaderTest(unittest.TestCase): 39 40 def test_missing_layout_test_results(self): 40 tool = MockTool()41 reader = LayoutTestResultsReader( tool, "/var/logs")41 host = MockHost() 42 reader = LayoutTestResultsReader(host, "/mock-results", "/var/logs") 42 43 layout_tests_results_path = '/mock-results/full_results.json' 43 44 unit_tests_results_path = '/mock-results/webkit_unit_tests_output.xml' 44 tool.filesystem = MockFileSystem({layout_tests_results_path: None,45 host.filesystem = MockFileSystem({layout_tests_results_path: None, 45 46 unit_tests_results_path: None}) 46 47 # Make sure that our filesystem mock functions as we expect. 47 self.assertRaises(IOError, tool.filesystem.read_text_file, layout_tests_results_path)48 self.assertRaises(IOError, tool.filesystem.read_text_file, unit_tests_results_path)48 self.assertRaises(IOError, host.filesystem.read_text_file, layout_tests_results_path) 49 self.assertRaises(IOError, host.filesystem.read_text_file, unit_tests_results_path) 49 50 # layout_test_results shouldn't raise even if the results.json file is missing. 50 51 self.assertEqual(reader.results(), None) 51 52 52 53 def test_create_unit_test_results(self): 53 tool = MockTool()54 reader = LayoutTestResultsReader( tool, "/var/logs")54 host = MockHost() 55 reader = LayoutTestResultsReader(host, "/mock-results", "/var/logs") 55 56 unit_tests_results_path = '/mock-results/webkit_unit_tests_output.xml' 56 57 no_failures_xml = """<?xml version="1.0" encoding="UTF-8"?> … … 62 63 </testsuite> 63 64 </testsuites>""" 64 tool.filesystem = MockFileSystem({unit_tests_results_path: no_failures_xml})65 host.filesystem = MockFileSystem({unit_tests_results_path: no_failures_xml}) 65 66 self.assertEqual(reader._create_unit_test_results(), []) 66 67 67 68 def test_missing_unit_test_results_path(self): 68 tool = MockTool() 69 tool.deprecated_port().unit_tests_results_path = lambda: None 70 reader = LayoutTestResultsReader(tool, "/var/logs") 69 host = MockHost() 70 reader = LayoutTestResultsReader(host, "/mock-results", "/var/logs") 71 71 reader._create_layout_test_results = lambda: LayoutTestResults([]) 72 reader._create_unit_test_results = lambda: None 72 73 # layout_test_results shouldn't raise even if the unit tests xml file is missing. 73 74 self.assertNotEquals(reader.results(), None) … … 76 77 77 78 def test_layout_test_results(self): 78 reader = LayoutTestResultsReader(Mock Tool(), "/var/logs")79 reader = LayoutTestResultsReader(MockHost(), "/mock-results", "/var/logs") 79 80 reader._read_file_contents = lambda path: None 80 81 self.assertEqual(reader.results(), None) … … 87 88 88 89 def test_archive_last_layout_test_results(self): 89 tool = MockTool() 90 reader = LayoutTestResultsReader(tool, "/var/logs") 91 patch = tool.bugs.fetch_attachment(10001) 92 tool.filesystem = MockFileSystem() 90 host = MockHost() 91 results_directory = "/mock-results" 92 reader = LayoutTestResultsReader(host, results_directory, "/var/logs") 93 patch = host.bugs.fetch_attachment(10001) 94 host.filesystem = MockFileSystem() 93 95 # Should fail because the results_directory does not exist. 94 96 expected_logs = "/mock-results does not exist, not archiving.\n" … … 96 98 self.assertEqual(archive, None) 97 99 98 results_directory = "/mock-results" 99 # Sanity check what we assume our mock results directory is. 100 self.assertEqual(reader._results_directory(), results_directory) 101 tool.filesystem.maybe_make_directory(results_directory) 102 self.assertTrue(tool.filesystem.exists(results_directory)) 100 host.filesystem.maybe_make_directory(results_directory) 101 self.assertTrue(host.filesystem.exists(results_directory)) 103 102 104 103 self.assertNotEqual(reader.archive(patch), None) 105 self.assertFalse( tool.filesystem.exists(results_directory))104 self.assertFalse(host.filesystem.exists(results_directory)) -
trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py
r135744 r138826 48 48 _default_run_tests = False 49 49 50 # Subclasses must override.51 port_name = None52 53 50 def __init__(self): 54 51 options = [make_option("--run-tests", action="store_true", dest="run_tests", default=self._default_run_tests, help="Run the Layout tests for each patch")] 55 52 AbstractReviewQueue.__init__(self, options=options) 56 self.port = DeprecatedPort.port(self.port_name)57 53 58 54 def begin_work_queue(self): 59 # FIXME: This violates abstraction60 self._tool._deprecated_port = self.port61 55 AbstractReviewQueue.begin_work_queue(self) 62 56 self._expected_failures = ExpectedFailures() 63 self._layout_test_results_reader = LayoutTestResultsReader(self._tool, self._ log_directory())57 self._layout_test_results_reader = LayoutTestResultsReader(self._tool, self._port.results_directory(), self._log_directory()) 64 58 65 59 def _failing_tests_message(self, task, patch): … … 106 100 107 101 def run_command(self, command): 108 self.run_webkit_patch(command + [self. port.flag()])102 self.run_webkit_patch(command + [self._deprecated_port.flag()]) 109 103 110 104 def command_passed(self, message, patch): -
trunk/Tools/Scripts/webkitpy/tool/commands/queues.py
r138264 r138826 247 247 self._release_work_item(patch) 248 248 249 # FIXME: This probably belongs at a layer below AbstractPatchQueue, but shared by CommitQueue and the EarlyWarningSystem. 249 def work_item_log_path(self, patch): 250 return os.path.join(self._log_directory(), "%s.log" % patch.bug_id()) 251 252 253 # Used to share code between the EWS and commit-queue. 254 class PatchProcessingQueue(AbstractPatchQueue): 255 # Subclasses must override. 256 port_name = None 257 258 # FIXME: This is a hack to map between the old port names and the new port names. 259 def _new_port_name_from_old(self, port_name): 260 # The new port system has no concept of xvfb yet. 261 if port_name == 'chromium-xvfb': 262 return 'chromium' 263 # ApplePort.determine_full_port_name asserts if the name doesn't include version. 264 if port_name == 'mac': 265 return 'mac-future' 266 if port_name == 'win': 267 return 'win-future' 268 return port_name 269 270 def begin_work_queue(self): 271 AbstractPatchQueue.begin_work_queue(self) 272 if not self.port_name: 273 return 274 # FIXME: This is only used for self._deprecated_port.flag() 275 self._deprecated_port = DeprecatedPort.port(self.port_name) 276 # FIXME: This violates abstraction 277 self._tool._deprecated_port = self._deprecated_port 278 self._port = self._tool.port_factory.get(self._new_port_name_from_old(self.port_name)) 279 250 280 def _upload_results_archive_for_patch(self, patch, results_archive_zip): 251 281 bot_id = self._tool.status_server.bot_id or "bot" … … 264 294 self._tool.bugs.add_attachment_to_bug(patch.bug_id(), results_archive_file, description, filename="layout-test-results.zip", comment_text=comment_text) 265 295 266 def work_item_log_path(self, patch): 267 return os.path.join(self._log_directory(), "%s.log" % patch.bug_id()) 268 269 270 class CommitQueue(AbstractPatchQueue, StepSequenceErrorHandler, CommitQueueTaskDelegate): 296 297 class CommitQueue(PatchProcessingQueue, StepSequenceErrorHandler, CommitQueueTaskDelegate): 271 298 name = "commit-queue" 272 299 port_name = "chromium-xvfb" 273 300 274 def __init__(self):275 AbstractPatchQueue.__init__(self)276 self.port = DeprecatedPort.port(self.port_name)277 278 301 # AbstractPatchQueue methods 279 302 280 303 def begin_work_queue(self): 281 # FIXME: This violates abstraction 282 self._tool._deprecated_port = self.port 283 AbstractPatchQueue.begin_work_queue(self) 304 PatchProcessingQueue.begin_work_queue(self) 284 305 self.committer_validator = CommitterValidator(self._tool) 285 306 self._expected_failures = ExpectedFailures() 286 self._layout_test_results_reader = LayoutTestResultsReader(self._tool, self._ log_directory())307 self._layout_test_results_reader = LayoutTestResultsReader(self._tool, self._port.results_directory(), self._log_directory()) 287 308 288 309 def next_work_item(self): … … 325 346 326 347 def run_command(self, command): 327 self.run_webkit_patch(command + [self. port.flag()])348 self.run_webkit_patch(command + [self._deprecated_port.flag()]) 328 349 329 350 def command_passed(self, message, patch): … … 382 403 383 404 384 class AbstractReviewQueue( AbstractPatchQueue, StepSequenceErrorHandler):405 class AbstractReviewQueue(PatchProcessingQueue, StepSequenceErrorHandler): 385 406 """This is the base-class for the EWS queues and the style-queue.""" 386 407 def __init__(self, options=None): 387 AbstractPatchQueue.__init__(self, options)408 PatchProcessingQueue.__init__(self, options) 388 409 389 410 def review_patch(self, patch): … … 393 414 394 415 def begin_work_queue(self): 395 AbstractPatchQueue.begin_work_queue(self)416 PatchProcessingQueue.begin_work_queue(self) 396 417 397 418 def next_work_item(self): -
trunk/Tools/Scripts/webkitpy/tool/commands/queues_unittest.py
r138264 r138826 167 167 self.assertEqual(queue._next_patch(), None) # When the queue is empty 168 168 169 170 class PatchProcessingQueueTest(CommandsTest): 169 171 def test_upload_results_archive_for_patch(self): 170 queue = AbstractPatchQueue()172 queue = PatchProcessingQueue() 171 173 queue.name = "mock-queue" 172 174 tool = MockTool() -
trunk/Tools/Scripts/webkitpy/tool/steps/runtests.py
r138775 r138826 73 73 _log.info("Running WebKit unit tests") 74 74 args = webkit_unit_tests_command 75 if self._options.non_interactive:76 args.append("--gtest_output=xml:%s/webkit_unit_tests_output.xml" % self._tool.deprecated_port().results_directory)77 75 try: 78 76 self._tool.executive.run_and_throw_if_fail(args, cwd=self._tool.scm().checkout_root) … … 88 86 "--skip-failing-tests", 89 87 "--exit-after-n-failures=%s" % self.NON_INTERACTIVE_FAILURE_LIMIT_COUNT, 90 "--results-directory=%s" % self._tool.deprecated_port().results_directory,91 88 "--quiet", 92 89 ]) -
trunk/Tools/Scripts/webkitpy/tool/steps/runtests_unittest.py
r137237 r138826 40 40 step = RunTests(tool, MockOptions(test=True, non_interactive=True, quiet=False)) 41 41 expected_logs = """Running WebKit unit tests 42 MOCK run_and_throw_if_fail: ['mock-run-webkit-unit-tests' , '--gtest_output=xml:/mock-results/webkit_unit_tests_output.xml'], cwd=/mock-checkout42 MOCK run_and_throw_if_fail: ['mock-run-webkit-unit-tests'], cwd=/mock-checkout 43 43 Running run-webkit-tests 44 MOCK run_and_throw_if_fail: ['mock-run-webkit-tests', '--no-new-test-results', '--no-show-results', '--skip-failing-tests', '--exit-after-n-failures=30', '-- results-directory=/mock-results', '--quiet'], cwd=/mock-checkout44 MOCK run_and_throw_if_fail: ['mock-run-webkit-tests', '--no-new-test-results', '--no-show-results', '--skip-failing-tests', '--exit-after-n-failures=30', '--quiet'], cwd=/mock-checkout 45 45 """ 46 46 OutputCapture().assert_outputs(self, step.run, [{}], expected_logs=expected_logs)
Note: See TracChangeset
for help on using the changeset viewer.