Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import unittest | |
| 6 from collections import OrderedDict | |
| 7 from webkitpy.common.host_mock import MockHost | |
| 8 from webkitpy.layout_tests.models.test_expectations import TestExpectations | |
| 9 from webkitpy.layout_tests.port.test import LAYOUT_TEST_DIR | |
| 10 from webkitpy.layout_tests.update_test_expectations import RemoveFlakesOMatic | |
| 11 from webkitpy.layout_tests.port import builders | |
| 12 | |
| 13 | |
| 14 class FakeBotTestExpectations(object): | |
| 15 | |
| 16 def __init__(self, results_by_path): | |
| 17 self._results = results_by_path | |
| 18 | |
| 19 def all_results_by_path(self): | |
| 20 return self._results | |
| 21 | |
| 22 | |
| 23 class FakeBotTestExpectationsFactory(object): | |
| 24 | |
| 25 def __init__(self): | |
| 26 self._all_results_by_builder = {} | |
|
Dirk Pranke
2016/03/29 22:39:01
Just make these public instance variables and get
bokan
2016/04/05 12:28:57
Done.
| |
| 27 | |
| 28 def set_results(self, results_by_path_by_builder): | |
| 29 """Sets the results that will be returned by expectationts_for_builder. | |
| 30 | |
| 31 Args: | |
| 32 results_by_path_by_builder (dict): The distinct results seen in | |
| 33 at least one run of the test. E.g. if the bot results for | |
| 34 mytest.html are: | |
| 35 PASS PASS FAIL PASS TIMEOUT | |
| 36 then results_by_path_by_builder should be: | |
| 37 { | |
| 38 'WebKit Linux' : { | |
| 39 'mytest.html': ['FAIL', 'PASS', 'TIMEOUT'] | |
| 40 } | |
| 41 } | |
| 42 """ | |
| 43 self._all_results_by_builder = results_by_path_by_builder | |
| 44 | |
| 45 def expectations_for_builder(self, builder): | |
| 46 if builder not in self._all_results_by_builder: | |
| 47 return None | |
| 48 | |
| 49 return FakeBotTestExpectations(self._all_results_by_builder[builder]) | |
| 50 | |
| 51 | |
| 52 class UpdateTestExpectationsTest(unittest.TestCase): | |
| 53 | |
| 54 def __init__(self, testFunc): | |
|
qyearsley
2016/03/21 21:45:25
What is testFunc here?
Also, would it make sense
Dirk Pranke
2016/03/29 22:39:01
Don't override __init__ or use setUpClass or tearD
bokan
2016/04/05 12:28:57
It's part of the Python unittest framework. testFu
bokan
2016/04/05 12:28:57
Done.
| |
| 55 self._host = MockHost() | |
| 56 self._port = self._host.port_factory.get('test', None) | |
| 57 self._expectation_factory = FakeBotTestExpectationsFactory() | |
| 58 self._flake_remover = RemoveFlakesOMatic(self._host, | |
| 59 self._port, | |
| 60 self._expectation_factory) | |
| 61 unittest.TestCase.__init__(self, testFunc) | |
| 62 | |
| 63 filesystem = self._host.filesystem | |
| 64 for test in self._get_test_list(): | |
| 65 filesystem.write_binary_file(filesystem.join(LAYOUT_TEST_DIR, test), '') | |
| 66 | |
| 67 def setUp(self): | |
| 68 self._old_builders = builders._exact_matches | |
|
qyearsley
2016/03/21 21:45:26
Maybe this attribute would be clearer if it were c
bokan
2016/04/05 12:28:57
Done.
| |
| 69 self._port.set_configuration_specifier_macros({ | |
| 70 'mac': ['mac10.10'], | |
| 71 'win': ['win7'], | |
| 72 'linux': ['precise'] | |
| 73 }) | |
| 74 | |
| 75 def tearDown(self): | |
| 76 builders._exact_matches = self._old_builders | |
|
Dirk Pranke
2016/03/29 22:39:01
It is really ugly to be mutating module-level stat
bokan
2016/04/05 12:28:57
Yah, I agree. I'll look into doing this as a separ
| |
| 77 | |
| 78 def _get_test_list(self): | |
| 79 return ['test/a.html', | |
| 80 'test/b.html', | |
| 81 'test/c.html', | |
| 82 'test/d.html', | |
| 83 'test/e.html', | |
| 84 'test/f.html', | |
| 85 'test/g.html'] | |
| 86 | |
| 87 def _assert_expectations_match(self, expectations, expected_string): | |
| 88 self.assertIsNotNone(expectations) | |
| 89 stringified_expectations = "\n".join(x.to_string(None) for x in expectat ions) | |
| 90 expected_string = "\n".join(x.strip() for x in expected_string.split("\n ")) | |
| 91 self.assertEqual(stringified_expectations, expected_string) | |
| 92 | |
| 93 def _parse_expectations(self, expectations): | |
| 94 """Parses a TestExpectatoin file given as string. | |
|
Dirk Pranke
2016/03/29 22:39:01
nit: s/TestExpectatoin/TestExpectation/.
bokan
2016/04/05 12:28:57
Done.
| |
| 95 | |
| 96 This function takes a string representing the contents of the | |
| 97 TestExpectations file and parses it, producing the TestExpectations | |
| 98 object and sets it on the Port object where the script will read it | |
| 99 from. | |
| 100 | |
| 101 Args: | |
| 102 expectations: A string containing the contents of the | |
| 103 TestExpectations file to use. | |
| 104 """ | |
| 105 expectations_dict = OrderedDict() | |
| 106 expectations_dict['expectations'] = expectations | |
| 107 self._port.expectations_dict = lambda: expectations_dict | |
| 108 | |
| 109 def test_dont_remove_non_flakes(self): | |
| 110 """Tests that lines that aren't flaky are not touched. | |
| 111 | |
| 112 Lines are flaky if they contain a PASS as well as at least one other | |
| 113 failing result. | |
| 114 """ | |
| 115 test_expectations_before = """ | |
| 116 # Even though the results show all passing, none of the | |
| 117 # expectations are flaky so we shouldn't remove any. | |
| 118 Bug(test) test/a.html [ Pass ] | |
| 119 Bug(test) test/b.html [ Timeout ] | |
| 120 Bug(test) test/c.html [ Failure Timeout ] | |
| 121 Bug(test) test/d.html [ Rebaseline ] | |
| 122 Bug(test) test/e.html [ NeedsManualRebaseline ] | |
| 123 Bug(test) test/f.html [ NeedsRebaseline ]""" | |
| 124 | |
| 125 builders._exact_matches = { | |
| 126 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 127 } | |
| 128 self._port.set_all_build_types(('release',)) | |
| 129 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 130 | |
| 131 self._parse_expectations(test_expectations_before) | |
| 132 self._expectation_factory.set_results({'WebKit Linux': { | |
| 133 "test/a.html": ["PASS", "PASS"], | |
| 134 "test/b.html": ["PASS", "PASS"], | |
| 135 "test/c.html": ["PASS", "PASS"], | |
| 136 "test/d.html": ["PASS", "PASS"], | |
| 137 "test/e.html": ["PASS", "PASS"], | |
| 138 "test/f.html": ["PASS", "PASS"], | |
| 139 }}) | |
| 140 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 141 self._assert_expectations_match(updated_expectations, test_expectations_ before) | |
| 142 | |
| 143 def test_dont_remove_rebaselines(self): | |
| 144 """Tests that lines with rebaseline expectations are untouched. | |
| 145 """ | |
| 146 test_expectations_before = """ | |
| 147 # Even though the results show all passing, none of the | |
| 148 # expectations are flaky so we shouldn't remove any. | |
| 149 Bug(test) test/a.html [ Failure NeedsRebaseline Pass ] | |
| 150 Bug(test) test/b.html [ Failure Pass Rebaseline ] | |
| 151 Bug(test) test/c.html [ Failure NeedsManualRebaseline Pass ]""" | |
| 152 | |
| 153 builders._exact_matches = { | |
| 154 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 155 } | |
| 156 self._port.set_all_build_types(('release',)) | |
| 157 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 158 | |
| 159 self._parse_expectations(test_expectations_before) | |
| 160 self._expectation_factory.set_results({'WebKit Linux': { | |
| 161 "test/a.html": ["PASS", "PASS"], | |
| 162 "test/b.html": ["PASS", "PASS"], | |
| 163 "test/c.html": ["PASS", "PASS"] | |
| 164 }}) | |
| 165 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 166 self._assert_expectations_match(updated_expectations, test_expectations_ before) | |
| 167 | |
| 168 def test_all_failure_types(self): | |
| 169 """Tests that all failure types are treated as failure.""" | |
| 170 test_expectations_before = ( | |
| 171 """Bug(test) test/a.html [ Failure Pass ] | |
| 172 Bug(test) test/b.html [ Failure Pass ] | |
| 173 Bug(test) test/c.html [ Failure Pass ] | |
| 174 Bug(test) test/d.html [ Failure Pass ] | |
| 175 # Remove these two since CRASH and TIMEOUT aren't considered Failure . | |
| 176 Bug(test) test/e.html [ Failure Pass ] | |
| 177 Bug(test) test/f.html [ Failure Pass ]""") | |
| 178 | |
| 179 builders._exact_matches = { | |
| 180 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 181 } | |
| 182 self._port.set_all_build_types(('release',)) | |
| 183 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 184 | |
| 185 self._parse_expectations(test_expectations_before) | |
| 186 self._expectation_factory.set_results({'WebKit Linux': { | |
| 187 "test/a.html": ["PASS", "IMAGE"], | |
| 188 "test/b.html": ["PASS", "TEXT"], | |
| 189 "test/c.html": ["PASS", "IMAGE+TEXT"], | |
| 190 "test/d.html": ["PASS", "AUDIO"], | |
| 191 "test/e.html": ["PASS", "CRASH"], | |
| 192 "test/f.html": ["PASS", "TIMEOUT"], | |
| 193 }}) | |
| 194 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 195 self._assert_expectations_match(updated_expectations, ( | |
| 196 """Bug(test) test/a.html [ Failure Pass ] | |
| 197 Bug(test) test/b.html [ Failure Pass ] | |
| 198 Bug(test) test/c.html [ Failure Pass ] | |
| 199 Bug(test) test/d.html [ Failure Pass ]""")) | |
| 200 | |
| 201 def test_basic_one_builder(self): | |
| 202 """Tests basic functionality with a single builder. | |
| 203 | |
| 204 Test that flaky expectations with results from a single bot showing the | |
| 205 expected failure isn't occuring should be removed. Results with failures | |
| 206 of the expected type shouldn't be removed but other kinds of failures | |
| 207 allow removal. | |
| 208 """ | |
| 209 test_expectations_before = ( | |
| 210 """# Remove this since it's passing all runs. | |
| 211 Bug(test) test/a.html [ Failure Pass ] | |
| 212 # Remove this since, although there's a failure, it's not a timeout. | |
| 213 Bug(test) test/b.html [ Pass Timeout ] | |
| 214 # Keep since we have both crashes and passes. | |
| 215 Bug(test) test/c.html [ Crash Pass ]""") | |
|
qyearsley
2016/03/21 21:45:25
Formatting side note: If it's OK to have a newline
bokan
2016/04/05 12:28:57
Yah, but that includes the newline in the string a
| |
| 216 | |
| 217 builders._exact_matches = { | |
| 218 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 219 } | |
| 220 self._port.set_all_build_types(('release',)) | |
| 221 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 222 | |
| 223 self._parse_expectations(test_expectations_before) | |
| 224 self._expectation_factory.set_results({'WebKit Linux': { | |
| 225 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 226 "test/b.html": ["PASS", "IMAGE", "PASS"], | |
| 227 "test/c.html": ["PASS", "CRASH", "PASS"], | |
| 228 }}) | |
| 229 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 230 self._assert_expectations_match(updated_expectations, ( | |
| 231 """# Keep since we have both crashes and passes. | |
| 232 Bug(test) test/c.html [ Crash Pass ]""")) | |
| 233 | |
| 234 def test_all_failure_case(self): | |
| 235 """Tests that results with all failures are not treated as non-flaky.""" | |
| 236 test_expectations_before = ( | |
| 237 """# Keep since it's all failures. | |
| 238 Bug(test) test/a.html [ Failure Pass ]""") | |
| 239 | |
| 240 builders._exact_matches = { | |
| 241 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 242 } | |
| 243 self._port.set_all_build_types(('release',)) | |
| 244 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 245 | |
| 246 self._parse_expectations(test_expectations_before) | |
| 247 self._expectation_factory.set_results({'WebKit Linux': { | |
| 248 "test/a.html": ["IMAGE", "IMAGE", "IMAGE"], | |
| 249 }}) | |
| 250 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 251 self._assert_expectations_match(updated_expectations, ( | |
| 252 """# Keep since it's all failures. | |
| 253 Bug(test) test/a.html [ Failure Pass ]""")) | |
| 254 | |
| 255 def test_empty_test_expectations(self): | |
| 256 """Tests that results with all failures are not treated as non-flaky.""" | |
| 257 test_expectations_before = "" | |
| 258 | |
| 259 builders._exact_matches = { | |
| 260 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 261 } | |
| 262 self._port.set_all_build_types(('release',)) | |
| 263 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 264 | |
| 265 self._parse_expectations(test_expectations_before) | |
| 266 self._expectation_factory.set_results({'WebKit Linux': { | |
| 267 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 268 }}) | |
| 269 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 270 self._assert_expectations_match(updated_expectations, "") | |
| 271 | |
| 272 def test_basic_multiple_builders(self): | |
| 273 """Tests basic functionality with multiple builders.""" | |
| 274 test_expectations_before = ( | |
| 275 """# Remove since it's passing on both builders. | |
| 276 Bug(test) test/a.html [ Failure Pass ] | |
| 277 # Keep since it's failing on the Mac builder. | |
| 278 Bug(test) test/b.html [ Failure Pass ] | |
| 279 # Keep since it's failing on the Linux builder. | |
| 280 Bug(test) test/c.html [ Failure Pass ]""") | |
| 281 | |
| 282 builders._exact_matches = { | |
| 283 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 284 "WebKit Mac10.10": {"port_name": "mac-mac10.10", "specifiers": ['Mac 10.10', 'Release']}, | |
| 285 } | |
| 286 | |
| 287 self._port.set_all_build_types(('release',)) | |
| 288 self._port.set_all_systems((('mac10.10', 'x86'), | |
| 289 ('precise', 'x86_64'))) | |
| 290 | |
| 291 self._parse_expectations(test_expectations_before) | |
| 292 self._expectation_factory.set_results({ | |
| 293 'WebKit Linux': { | |
| 294 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 295 "test/b.html": ["PASS", "PASS", "PASS"], | |
| 296 "test/c.html": ["AUDIO", "AUDIO", "AUDIO"], | |
| 297 }, | |
| 298 'WebKit Mac10.10': { | |
| 299 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 300 "test/b.html": ["PASS", "PASS", "IMAGE"], | |
| 301 "test/c.html": ["PASS", "PASS", "PASS"], | |
| 302 }, | |
| 303 }) | |
| 304 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 305 self._assert_expectations_match(updated_expectations, ( | |
| 306 """# Keep since it's failing on the Mac builder. | |
| 307 Bug(test) test/b.html [ Failure Pass ] | |
| 308 # Keep since it's failing on the Linux builder. | |
| 309 Bug(test) test/c.html [ Failure Pass ]""")) | |
| 310 | |
| 311 def test_multiple_builders_and_platform_specifiers(self): | |
| 312 """Tests correct operation with platform specifiers.""" | |
| 313 test_expectations_before = ( | |
| 314 """# Keep since it's failing on Mac results. | |
| 315 Bug(test) [ Mac ] test/a.html [ Failure Pass ] | |
| 316 # Keep since it's failing on the Windows builder. | |
| 317 Bug(test) [ Linux Win ] test/b.html [ Failure Pass ] | |
| 318 # Remove since it's passing on both Linux and Windows builders. | |
| 319 Bug(test) [ Linux Win ] test/c.html [ Failure Pass ] | |
| 320 # Remove since it's passing on Mac results | |
| 321 Bug(test) [ Mac ] test/d.html [ Failure Pass ]""") | |
| 322 | |
| 323 builders._exact_matches = { | |
| 324 "WebKit Win7": {"port_name": "win-win7", "specifiers": ['Win7', 'Rel ease']}, | |
| 325 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 326 "WebKit Mac10.10": {"port_name": "mac-mac10.10", "specifiers": ['Mac 10.10', 'Release']}, | |
| 327 } | |
| 328 self._port.set_all_build_types(('release',)) | |
| 329 self._port.set_all_systems((('mac10.10', 'x86'), | |
| 330 ('win7', 'x86'), | |
| 331 ('precise', 'x86_64'))) | |
| 332 | |
| 333 self._parse_expectations(test_expectations_before) | |
| 334 self._expectation_factory.set_results({ | |
| 335 'WebKit Linux': { | |
| 336 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 337 "test/b.html": ["PASS", "PASS", "PASS"], | |
| 338 "test/c.html": ["PASS", "PASS", "PASS"], | |
| 339 "test/d.html": ["IMAGE", "PASS", "PASS"], | |
| 340 }, | |
| 341 'WebKit Mac10.10': { | |
| 342 "test/a.html": ["PASS", "PASS", "IMAGE"], | |
| 343 "test/b.html": ["PASS", "IMAGE", "PASS"], | |
| 344 "test/c.html": ["PASS", "IMAGE", "PASS"], | |
| 345 "test/d.html": ["PASS", "PASS", "PASS"], | |
| 346 }, | |
| 347 'WebKit Win7': { | |
| 348 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 349 "test/b.html": ["IMAGE", "PASS", "PASS"], | |
| 350 "test/c.html": ["PASS", "PASS", "PASS"], | |
| 351 "test/d.html": ["IMAGE", "PASS", "PASS"], | |
| 352 }, | |
| 353 }) | |
| 354 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 355 self._assert_expectations_match(updated_expectations, ( | |
| 356 """# Keep since it's failing on Mac results. | |
| 357 Bug(test) [ Mac ] test/a.html [ Failure Pass ] | |
| 358 # Keep since it's failing on the Windows builder. | |
| 359 Bug(test) [ Linux Win ] test/b.html [ Failure Pass ]""")) | |
| 360 | |
| 361 def test_debug_release_specifiers(self): | |
| 362 """Tests correct operation of Debug/Release specifiers.""" | |
| 363 test_expectations_before = ( | |
| 364 """# Keep since it fails in debug. | |
| 365 Bug(test) [ Linux ] test/a.html [ Failure Pass ] | |
| 366 # Remove since the failure is in Release, Debug is all PASS. | |
| 367 Bug(test) [ Debug ] test/b.html [ Failure Pass ] | |
| 368 # Keep since there's a failure in Linux Release. | |
| 369 Bug(test) [ Release ] test/c.html [ Failure Pass ] | |
| 370 # Remove since the Release Linux builder is all passing. | |
| 371 Bug(test) [ Release Linux ] test/d.html [ Failure Pass ] | |
| 372 # Remove since all the Linux builders PASS. | |
| 373 Bug(test) [ Linux ] test/e.html [ Failure Pass ]""") | |
| 374 | |
| 375 builders._exact_matches = { | |
| 376 "WebKit Win7": {"port_name": "win-win7", "specifiers": ['Win7', 'Rel ease']}, | |
| 377 "WebKit Win7 (dbg)": {"port_name": "win-win7", "specifiers": ['Win7' , 'Debug']}, | |
| 378 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 379 "WebKit Linux (dbg)": {"port_name": "linux-precise", "specifiers": [ 'Precise', 'Debug']}, | |
| 380 } | |
| 381 self._port.set_all_build_types(('release', 'debug')) | |
| 382 self._port.set_all_systems((('win7', 'x86'), | |
| 383 ('precise', 'x86_64'))) | |
| 384 | |
| 385 self._parse_expectations(test_expectations_before) | |
| 386 self._expectation_factory.set_results({ | |
| 387 'WebKit Linux': { | |
| 388 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 389 "test/b.html": ["PASS", "IMAGE", "PASS"], | |
| 390 "test/c.html": ["PASS", "IMAGE", "PASS"], | |
| 391 "test/d.html": ["PASS", "PASS", "PASS"], | |
| 392 "test/e.html": ["PASS", "PASS", "PASS"], | |
| 393 }, | |
| 394 'WebKit Linux (dbg)': { | |
| 395 "test/a.html": ["PASS", "IMAGE", "PASS"], | |
| 396 "test/b.html": ["PASS", "PASS", "PASS"], | |
| 397 "test/c.html": ["PASS", "PASS", "PASS"], | |
| 398 "test/d.html": ["IMAGE", "PASS", "PASS"], | |
| 399 "test/e.html": ["PASS", "PASS", "PASS"], | |
| 400 }, | |
| 401 'WebKit Win7 (dbg)': { | |
| 402 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 403 "test/b.html": ["PASS", "PASS", "PASS"], | |
| 404 "test/c.html": ["PASS", "PASS", "PASS"], | |
| 405 "test/d.html": ["PASS", "IMAGE", "PASS"], | |
| 406 "test/e.html": ["PASS", "PASS", "PASS"], | |
| 407 }, | |
| 408 'WebKit Win7': { | |
| 409 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 410 "test/b.html": ["PASS", "PASS", "IMAGE"], | |
| 411 "test/c.html": ["PASS", "PASS", "PASS"], | |
| 412 "test/d.html": ["PASS", "IMAGE", "PASS"], | |
| 413 "test/e.html": ["PASS", "PASS", "PASS"], | |
| 414 }, | |
| 415 }) | |
| 416 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 417 self._assert_expectations_match(updated_expectations, ( | |
| 418 """# Keep since it fails in debug. | |
| 419 Bug(test) [ Linux ] test/a.html [ Failure Pass ] | |
| 420 # Keep since there's a failure in Linux Release. | |
| 421 Bug(test) [ Release ] test/c.html [ Failure Pass ]""")) | |
| 422 | |
| 423 def test_preserve_comments_and_whitespace(self): | |
| 424 """Tests that comments and whitespace are preserved appropriately. | |
| 425 | |
| 426 Comments and whitespace should be kept unless all the tests grouped | |
| 427 below a comment are removed. In that case the comment block should also | |
| 428 be removed. | |
| 429 | |
| 430 Ex: | |
| 431 # This comment applies to the below tests. | |
| 432 Bug(test) test/a.html [ Failure Pass ] | |
| 433 Bug(test) test/b.html [ Failure Pass ] | |
| 434 | |
| 435 # <some prose> | |
| 436 | |
| 437 # This is another comment. | |
| 438 Bug(test) test/c.html [ Failure Pass ] | |
| 439 | |
| 440 Assuming we removed a.html and c.html we get: | |
| 441 # This comment applies to the below tests. | |
| 442 Bug(test) test/b.html [ Failure Pass ] | |
| 443 | |
| 444 # <some prose> | |
| 445 """ | |
| 446 test_expectations_before = """ | |
| 447 # Comment A - Keep since these aren't part of any test. | |
| 448 # Comment B - Keep since these aren't part of any test. | |
| 449 | |
| 450 # Comment C - Remove since it's a block belonging to a | |
| 451 # Comment D - and a is removed. | |
| 452 Bug(test) test/a.html [ Failure Pass ] | |
| 453 # Comment E - Keep since it's below a. | |
| 454 | |
| 455 | |
| 456 # Comment F - Keep since only b is removed | |
| 457 Bug(test) test/b.html [ Failure Pass ] | |
| 458 Bug(test) test/c.html [ Failure Pass ] | |
| 459 | |
| 460 # Comment G - Should be removed since both d and e will be removed. | |
| 461 Bug(test) test/d.html [ Failure Pass ] | |
| 462 Bug(test) test/e.html [ Failure Pass ]""" | |
| 463 | |
| 464 builders._exact_matches = { | |
| 465 "WebKit Linux": {"port_name": "linux-precise", "specifiers": ['Preci se', 'Release']}, | |
| 466 } | |
| 467 self._port.set_all_build_types(('release',)) | |
| 468 self._port.set_all_systems((('precise', 'x86_64'),)) | |
| 469 | |
| 470 self._parse_expectations(test_expectations_before) | |
| 471 self._expectation_factory.set_results({ | |
| 472 'WebKit Linux': { | |
| 473 "test/a.html": ["PASS", "PASS", "PASS"], | |
| 474 "test/b.html": ["PASS", "PASS", "PASS"], | |
| 475 "test/c.html": ["PASS", "IMAGE", "PASS"], | |
| 476 "test/d.html": ["PASS", "PASS", "PASS"], | |
| 477 "test/e.html": ["PASS", "PASS", "PASS"], | |
| 478 } | |
| 479 }) | |
| 480 updated_expectations = self._flake_remover.get_updated_test_expectations () | |
| 481 self._assert_expectations_match(updated_expectations, ( | |
| 482 """ | |
| 483 # Comment A - Keep since these aren't part of any test. | |
| 484 # Comment B - Keep since these aren't part of any test. | |
| 485 # Comment E - Keep since it's below a. | |
| 486 | |
| 487 | |
| 488 # Comment F - Keep since only b is removed | |
| 489 Bug(test) test/c.html [ Failure Pass ]""")) | |
| OLD | NEW |