Changeset 213722 in webkit
- Timestamp:
- Mar 10, 2017 11:24:47 AM (7 years ago)
- Location:
- trunk/Tools
- Files:
-
- 10 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
trunk/Tools/ChangeLog
r213719 r213722 1 2017-03-10 Srinivasan Vijayaraghavan <svijayaraghavan@apple.com> 2 3 Add support for Bindings EWS 4 https://bugs.webkit.org/show_bug.cgi?id=169308 5 6 Reviewed by Alexey Proskuryakov. 7 8 * Scripts/webkitpy/common/config/ews.json: Add bindings-ews. Can test without building; should_build = False. 9 * Scripts/webkitpy/common/net/bindingstestresults.py: 10 (BindingsTestResults.__init__): Removed 'errors'. 11 (BindingsTestResults.results_from_string): Ditto. 12 (BindingsTestResults.is_subset): Ditto. 13 (BindingsTestResults.equals): Ditto. 14 (BindingsTestResults.all_passed): Ditto. 15 (BindingsTestResults.failing_tests): Ditto. 16 * Scripts/webkitpy/common/net/bindingstestresults_unittest.py: 17 (BindingsTestResultsTest.test_results_from_string): Removed 'errors'. 18 (BindingsTestResultsTest.test_results_from_string_success): Removed 'errors'. 19 * Scripts/webkitpy/tool/bot/earlywarningsystemtask.py: 20 (EarlyWarningSystemTask.__init__): Add should_build parameter. 21 (EarlyWarningSystemTask.run): Check should_build before calling self._build(). 22 * Scripts/webkitpy/tool/bot/retrylogic_unittest.py: Renamed from Tools/Scripts/webkitpy/tool/bot/jscews_unittest.py. 23 (MockBindingsEarlyWarningSystem): Based of MockJSCEarlyWarningSystem. Mocked so we can provide test results. 24 (MockBindingsEarlyWarningSystem.__init__): Sets attributes. 25 (MockBindingsEarlyWarningSystem.test_results): Returns test results provided by us, instead of JSON output. 26 (BindingsEarlyWarningSystemTest): Class to test retry logic in below situations. 27 (BindingsEarlyWarningSystemTest._results_indicate_all_passed): False if None or or has failures, else True. 28 (BindingsEarlyWarningSystemTest._create_task): 29 (BindingsEarlyWarningSystemTest.test_success_case): Clean patch on clean tree. 30 (BindingsEarlyWarningSystemTest.test_test_failure): Red patch on clean tree. 31 (BindingsEarlyWarningSystemTest.test_fix): Clean patch on red tree. 32 (BindingsEarlyWarningSystemTest.test_ineffective_patch): Red patch on red tree. 33 (BindingsEarlyWarningSystemTest.test_partially_effective_patch): Red patch on redder tree. 34 (BindingsEarlyWarningSystemTest.test_different_test_failures_in_patch_and_tree): Red patch on red tree. 35 * Scripts/webkitpy/tool/bot/patchanalysistask.py: 36 (PatchAnalysisTask._build_and_test_without_patch): Don't build if should_build is False (eg. on Bindings EWS). 37 (PatchAnalysisTask._retry_bindings_tests): Retry logic for Bindings tests. 38 (PatchAnalysisTask._test_patch): If tests failed on Bindings EWS, and call _retry_bindings_tests. 39 * Scripts/webkitpy/tool/commands/earlywarningsystem.py: 40 (AbstractEarlyWarningSystem.begin_work_queue): Use BindingsTestResultsReader on Bindings EWS. 41 (AbstractEarlyWarningSystem._create_task): Pass should_build argument. 42 (AbstractEarlyWarningSystem.load_ews_classes): Add should_build argument (True by default). 43 * Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py: 44 (TestBindingsEWS): Bindings EWS class, derived from AbstractEarlyWarningSystem. 45 (AbstractEarlyWarningSystemTest.test_failing_bindings_tests_message): Unit test message posted to Bugzilla. 46 (EarlyWarningSystemTest._default_expected_logs): Not building on all ewses anymore; make build line optional. 47 (EarlyWarningSystemTest.test_ews_name): Add bindings-ews. 48 * Scripts/webkitpy/tool/steps/checkpatchrelevance.py: 49 (CheckPatchRelevance): Add bindings paths. 50 (CheckPatchRelevance._changes_are_relevant): Cleaner way to check if we should perform this step. 51 * Scripts/webkitpy/tool/steps/steps_unittest.py: Add unit tests for Bindings EWS patch relevance. 52 (test_patch_relevant_bindings): Test for patch relevant to bindings. 53 (test_patch_not_relevant_bindings): Test for patch not relevant to bindings. 54 1 55 2017-03-09 Simon Fraser <simon.fraser@apple.com> 2 56 -
trunk/Tools/Scripts/webkitpy/common/config/ews.json
r213654 r213722 52 52 "group": "jsc", 53 53 "runTests": true 54 }, 55 "Bindings EWS": { 56 "port": "mac", 57 "name": "bindings-ews", 58 "group": "bindings", 59 "runTests": true, 60 "shouldBuild": false 54 61 } 55 62 } -
trunk/Tools/Scripts/webkitpy/common/net/bindingstestresults.py
r213321 r213722 29 29 30 30 class BindingsTestResults(AbstractTestResults): 31 def __init__(self, failures , errors):31 def __init__(self, failures): 32 32 self._failures = failures 33 self._errors = errors34 35 self._failing_test_names = failures + errors36 33 37 34 @classmethod … … 41 38 return None 42 39 43 if 'failures' not in parsed_results or 'errors' not in parsed_results:40 if 'failures' not in parsed_results: 44 41 return None 45 42 46 return cls(parsed_results['failures'] , parsed_results['errors'])43 return cls(parsed_results['failures']) 47 44 48 45 def is_subset(self, other): 49 return set(self._failures) <= set(other._failures) and set(self._errors) <= set(other._errors)46 return set(self._failures) <= set(other._failures) 50 47 51 48 def equals(self, other): 52 return set(self._failures) == set(other._failures) and set(self._errors) == set(other._errors)49 return set(self._failures) == set(other._failures) 53 50 54 51 def all_passed(self): 55 return not self._failures and not self._errors52 return not self._failures 56 53 57 54 def failing_tests(self): 58 return self._fail ing_test_names55 return self._failures 59 56 60 57 # No defined failure limit for bindings tests. -
trunk/Tools/Scripts/webkitpy/common/net/bindingstestresults_unittest.py
r213321 r213722 28 28 class BindingsTestResultsTest(unittest.TestCase): 29 29 def test_results_from_string(self): 30 incomplete_json_v1 = '{"failures": []}' 31 incomplete_json_v2 = '{"errors":[]}' 32 self.assertEqual(None, BindingsTestResults.results_from_string(incomplete_json_v1)) 33 self.assertEqual(None, BindingsTestResults.results_from_string(incomplete_json_v2)) 30 incomplete_json = '{"key2": []}' 31 self.assertEqual(None, BindingsTestResults.results_from_string(incomplete_json)) 34 32 35 33 def test_results_from_string_success(self): 36 no_failures_string = '{"failures": [] , "errors":[]}'37 no_failures_results = BindingsTestResults([] , [])34 no_failures_string = '{"failures": []}' 35 no_failures_results = BindingsTestResults([]) 38 36 self.assertTrue(no_failures_results.equals(BindingsTestResults.results_from_string(no_failures_string))) 39 37 self.assertTrue(no_failures_results.all_passed()) 40 38 41 test_string = '{"failures": ["failure1"] , "errors": ["error1", "error2"]}'42 test_results = BindingsTestResults(["failure1"] , ["error1", "error2"])39 test_string = '{"failures": ["failure1"]}' 40 test_results = BindingsTestResults(["failure1"]) 43 41 self.assertTrue(test_results.equals(BindingsTestResults.results_from_string(test_string))) -
trunk/Tools/Scripts/webkitpy/tool/bot/earlywarningsystemtask.py
r212579 r213722 36 36 37 37 class EarlyWarningSystemTask(PatchAnalysisTask): 38 def __init__(self, delegate, patch, should_run_tests=True ):38 def __init__(self, delegate, patch, should_run_tests=True, should_build=True): 39 39 PatchAnalysisTask.__init__(self, delegate, patch) 40 40 self._should_run_tests = should_run_tests 41 self._should_build = should_build 41 42 42 43 def validate(self): … … 62 63 if not self._check_patch_relevance(): 63 64 raise PatchIsNotApplicable(self._patch) 64 if not self._build(): 65 if not self._build_without_patch(): 66 return False 67 return self.report_failure() 65 if self._should_build: 66 if not self._build(): 67 if not self._build_without_patch(): 68 return False 69 return self.report_failure() 68 70 if not self._should_run_tests: 69 71 return True -
trunk/Tools/Scripts/webkitpy/tool/bot/patchanalysistask.py
r212579 r213722 187 187 "--force-clean", 188 188 "--no-update", 189 "--build",190 189 "--test", 191 190 "--non-interactive", 192 191 "--build-style=%s" % self._delegate.build_style(), 193 192 ] 193 194 if getattr(self._delegate, 'should_build', True): 195 args.append("--build") 194 196 195 197 if hasattr(self._delegate, 'group'): … … 236 238 return False 237 239 240 def _retry_bindings_tests(self): 241 first_results = self._delegate.test_results() 242 first_script_error = self._script_error 243 first_failure_status_id = self.failure_status_id 244 if first_results is None: 245 return False 246 247 # Some errors are not correctly reported by the run-bindings-tests script 248 # https://bugs.webkit.org/show_bug.cgi?id=169449 249 # In affected cases, add a message requesting to look at test output instead. 250 if not first_results._failures: 251 first_results._failures = ["Please see test output for results"] 252 253 self._build_and_test_without_patch() 254 clean_tree_results = self._delegate.test_results() 255 if clean_tree_results is None: 256 return False 257 258 if first_results.is_subset(clean_tree_results): 259 return True 260 261 self.failure_status_id = first_failure_status_id 262 return self.report_failure(None, first_results, first_script_error) 263 238 264 # FIXME: Abstract out common parts of the retry logic. 239 265 def _retry_jsc_tests(self): … … 339 365 if hasattr(self._delegate, 'group') and self._delegate.group() == "jsc": 340 366 return self._retry_jsc_tests() 367 elif hasattr(self._delegate, 'group') and self._delegate.group() == "bindings": 368 return self._retry_bindings_tests() 341 369 else: 342 370 return self._retry_layout_tests() -
trunk/Tools/Scripts/webkitpy/tool/bot/retrylogic_unittest.py
r213719 r213722 24 24 import unittest 25 25 26 from webkitpy.common.net.bindingstestresults import BindingsTestResults 26 27 from webkitpy.common.net.jsctestresults import JSCTestResults 27 28 from webkitpy.common.system.executive import ScriptError … … 217 218 self.assertTrue(return_value) 218 219 self.assertEqual(task.test_run_count(), 3) 220 221 222 class MockBindingsEarlyWarningSystem(AbstractEarlyWarningSystem): 223 def __init__(self, first_test_results, clean_test_results): 224 AbstractEarlyWarningSystem.__init__(self) 225 self._group = 'bindings' 226 self._results_in_order = [clean_test_results, first_test_results] 227 228 def test_results(self): 229 return self._results_in_order.pop() 230 231 232 class BindingsEarlyWarningSystemTest(unittest.TestCase): 233 def _results_indicate_all_passed(self, results): 234 if results == None: 235 return False 236 return results.all_passed() 237 238 def _create_task(self, first_test_results, clean_test_results): 239 queue = MockBindingsEarlyWarningSystem(first_test_results, clean_test_results) 240 tool = MockTool(log_executive=True) 241 patch = tool.bugs.fetch_attachment(10000) 242 patches_passed_all_tests = [self._results_indicate_all_passed(first_test_results)] 243 return MockPatchAnalysisTask(queue, patch, patches_passed_all_tests) 244 245 def test_success_case(self): 246 first_test_results = BindingsTestResults([]) 247 clean_test_results = BindingsTestResults([]) 248 task = self._create_task(first_test_results, clean_test_results) 249 250 return_value = task._test_patch() 251 self.assertEqual(task.test_run_count(), 1) 252 self.assertTrue(return_value) 253 254 def test_test_failure(self): 255 first_test_results = BindingsTestResults(['TestMapLike.idl']) 256 clean_test_results = BindingsTestResults([]) 257 task = self._create_task(first_test_results, clean_test_results) 258 259 with self.assertRaises(ScriptError): 260 return_value = task._test_patch() 261 self.assertEqual(task.test_run_count(), 2) 262 263 def test_fix(self): 264 first_test_results = BindingsTestResults([]) 265 clean_test_results = BindingsTestResults(['TestMapLike.idl']) 266 task = self._create_task(first_test_results, clean_test_results) 267 268 return_value = task._test_patch() 269 self.assertEqual(task.test_run_count(), 1) 270 self.assertTrue(return_value) 271 272 def test_ineffective_patch(self): 273 first_test_results = BindingsTestResults(['TestMapLike.idl']) 274 clean_test_results = BindingsTestResults(['TestMapLike.idl']) 275 task = self._create_task(first_test_results, clean_test_results) 276 277 return_value = task._test_patch() 278 self.assertEqual(task.test_run_count(), 2) 279 self.assertTrue(return_value) 280 281 def test_partially_effective_patch(self): 282 first_test_results = BindingsTestResults(['TestMapLike.idl']) 283 clean_test_results = BindingsTestResults(['TestMapLike.idl', 'TestNode.idl']) 284 task = self._create_task(first_test_results, clean_test_results) 285 286 return_value = task._test_patch() 287 self.assertEqual(task.test_run_count(), 2) 288 self.assertTrue(return_value) 289 290 def test_different_test_failures_in_patch_and_tree(self): 291 first_test_results = BindingsTestResults(['TestNode.idl']) 292 clean_test_results = BindingsTestResults(['TestMapLike.idl']) 293 task = self._create_task(first_test_results, clean_test_results) 294 295 with self.assertRaises(ScriptError): 296 return_value = task._test_patch() 297 self.assertEqual(task.test_run_count(), 2) -
trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem.py
r212579 r213722 38 38 from webkitpy.common.system.executive import ScriptError 39 39 from webkitpy.tool.bot.earlywarningsystemtask import EarlyWarningSystemTask, EarlyWarningSystemTaskDelegate 40 from webkitpy.tool.bot.bindingstestresultsreader import BindingsTestResultsReader 40 41 from webkitpy.tool.bot.layouttestresultsreader import LayoutTestResultsReader 41 42 from webkitpy.tool.bot.jsctestresultsreader import JSCTestResultsReader … … 60 61 if self.group() == "jsc": 61 62 self._test_results_reader = JSCTestResultsReader(self._tool, self._port.jsc_results_directory()) 63 elif self.group() == "bindings": 64 self._test_results_reader = BindingsTestResultsReader(self._tool, self._port.jsc_results_directory()) 62 65 else: 63 66 self._test_results_reader = LayoutTestResultsReader(self._tool, self._port.results_directory(), self._log_directory()) … … 89 92 # This exists for mocking 90 93 def _create_task(self, patch): 91 return EarlyWarningSystemTask(self, patch, s elf._options.run_tests)94 return EarlyWarningSystemTask(self, patch, should_run_tests=self._options.run_tests, should_build=self.should_build) 92 95 93 96 def review_patch(self, patch): … … 175 178 'run_tests': config.get('runTests', cls.run_tests), 176 179 '_group': config.get('group', None), 180 'should_build': config.get('shouldBuild', True), 177 181 })) 178 182 return classes -
trunk/Tools/Scripts/webkitpy/tool/commands/earlywarningsystem_unittest.py
r213651 r213722 31 31 from webkitpy.common.host import Host 32 32 from webkitpy.common.host_mock import MockHost 33 from webkitpy.common.net.bindingstestresults import BindingsTestResults 33 34 from webkitpy.common.net.jsctestresults import JSCTestResults 34 35 from webkitpy.common.net.layouttestresults import LayoutTestResults … … 55 56 _build_style = None 56 57 _group = "jsc" 58 59 60 class TestBindingsEWS(AbstractEarlyWarningSystem): 61 port_name = "mac" 62 _build_style = None 63 _group = "bindings" 57 64 58 65 … … 82 89 self._test_message(ews, results, message) 83 90 91 def test_failing_bindings_tests_message(self): 92 ews = TestBindingsEWS() 93 results = lambda a: BindingsTestResults(["(JS) TestMapLike.idl", "(JS) TestNode.idl"]) 94 message = "New failing tests:\n(JS) TestMapLike.idl\n(JS) TestNode.idl" 95 self._test_message(ews, results, message) 96 84 97 85 98 class MockEarlyWarningSystemTaskForInconclusiveJSCResults(EarlyWarningSystemTask): … … 105 118 "group": ews.group(), 106 119 } 120 121 if ews.should_build: 122 build_line = "Running: webkit-patch --status-host=example.com build --no-clean --no-update --build-style=%(build_style)s --group=%(group)s --port=%(port)s%(architecture)s\n" % string_replacements 123 else: 124 build_line = "" 125 string_replacements['build_line'] = build_line 126 107 127 if ews.run_tests: 108 128 run_tests_line = "Running: webkit-patch --status-host=example.com build-and-test --no-clean --no-update --test --non-interactive --build-style=%(build_style)s --group=%(group)s --port=%(port)s%(architecture)s\n" % string_replacements … … 124 144 Running: webkit-patch --status-host=example.com apply-attachment --no-update --non-interactive 10000 --port=%(port)s%(architecture)s 125 145 Running: webkit-patch --status-host=example.com check-patch-relevance --group=%(group)s --port=%(port)s%(architecture)s 126 Running: webkit-patch --status-host=example.com build --no-clean --no-update --build-style=%(build_style)s --group=%(group)s --port=%(port)s%(architecture)s 127 %(run_tests_line)s%(result_lines)s""" % string_replacements, 146 %(build_line)s%(run_tests_line)s%(result_lines)s""" % string_replacements, 128 147 "handle_unexpected_error": "Mock error message\n", 129 148 "handle_script_error": "ScriptError error message\n\nMOCK output\n", … … 165 184 'mac-debug-ews', 166 185 'mac-32bit-ews', 186 'bindings-ews', 167 187 'jsc-ews', 168 188 } -
trunk/Tools/Scripts/webkitpy/tool/steps/checkpatchrelevance.py
r213658 r213722 38 38 ] 39 39 40 bindings_paths = [ 41 "Source/WebCore", 42 "Tools", 43 ] 44 40 45 jsc_paths = [ 41 46 "JSTests/", … … 53 58 54 59 group_to_paths_mapping = { 60 'bindings': bindings_paths, 55 61 'jsc': jsc_paths, 56 62 } … … 58 64 def _changes_are_relevant(self, changed_files): 59 65 # In the default case, all patches are relevant 60 if self._options.group != 'jsc':66 if self._options.group not in self.group_to_paths_mapping: 61 67 return True 62 68 -
trunk/Tools/Scripts/webkitpy/tool/steps/steps_unittest.py
r213185 r213722 257 257 """ 258 258 OutputCapture().assert_outputs(self, step.run, [{}], expected_logs=expected_logs) 259 260 def test_patch_relevant_bindings(self): 261 self.maxDiff = None 262 mock_options = self._step_options() 263 mock_options.group = "bindings" 264 tool = MockTool(log_executive=True) 265 tool.scm()._mockChangedFiles = ["Source/WebCore/features.json", "Source/ChangeLog"] 266 # FIXME: We shouldn't use a real port-object here, but there is too much to mock at the moment. 267 tool._deprecated_port = DeprecatedPort() 268 step = steps.CheckPatchRelevance(tool, mock_options) 269 expected_logs = """Checking relevance of patch 270 """ 271 OutputCapture().assert_outputs(self, step.run, [{}], expected_logs=expected_logs) 272 273 def test_patch_not_relevant_bindings(self): 274 self.maxDiff = None 275 mock_options = self._step_options() 276 mock_options.group = "bindings" 277 tool = MockTool(log_executive=True) 278 tool.scm()._mockChangedFiles = ["Source/JavaScriptCore/Makefile", "Source/ChangeLog"] 279 # FIXME: We shouldn't use a real port-object here, but there is too much to mock at the moment. 280 tool._deprecated_port = DeprecatedPort() 281 step = steps.CheckPatchRelevance(tool, mock_options) 282 expected_logs = """Checking relevance of patch 283 This patch does not have relevant changes. 284 """
Note: See TracChangeset
for help on using the changeset viewer.