OLD | NEW |
1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import os | 5 import os |
6 | 6 |
7 from testing_utils import testing | |
8 | |
9 from model.wf_analysis import WfAnalysis | 7 from model.wf_analysis import WfAnalysis |
10 from model.wf_step import WfStep | 8 from model.wf_step import WfStep |
11 from pipeline_wrapper import pipeline_handlers | 9 from pipeline_wrapper import pipeline_handlers |
12 from waterfall import buildbot | 10 from waterfall import buildbot |
13 from waterfall import try_job_util | 11 from waterfall import try_job_util |
14 from waterfall import waterfall_config | |
15 from waterfall.extract_signal_pipeline import ExtractSignalPipeline | 12 from waterfall.extract_signal_pipeline import ExtractSignalPipeline |
| 13 from waterfall.test import wf_testcase |
16 | 14 |
17 | 15 |
18 class ExtractSignalPipelineTest(testing.AppengineTestCase): | 16 class ExtractSignalPipelineTest(wf_testcase.WaterfallTestCase): |
19 app_module = pipeline_handlers._APP | 17 app_module = pipeline_handlers._APP |
20 | 18 |
21 def setUp(self): | 19 def setUp(self): |
22 super(ExtractSignalPipelineTest, self).setUp() | 20 super(ExtractSignalPipelineTest, self).setUp() |
23 | 21 |
24 def Mocked_ScheduleTryJobIfNeeded(*_, **__): | 22 def Mocked_ScheduleTryJobIfNeeded(*_, **__): |
25 pass | 23 pass |
26 self.mock( | 24 self.mock( |
27 try_job_util, 'ScheduleTryJobIfNeeded', Mocked_ScheduleTryJobIfNeeded) | 25 try_job_util, 'ScheduleTryJobIfNeeded', Mocked_ScheduleTryJobIfNeeded) |
28 | 26 |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
84 step_name = 'abc_test' | 82 step_name = 'abc_test' |
85 step = WfStep.Create(master_name, builder_name, build_number, step_name) | 83 step = WfStep.Create(master_name, builder_name, build_number, step_name) |
86 step.log_data = self.ABC_TEST_FAILURE_LOG | 84 step.log_data = self.ABC_TEST_FAILURE_LOG |
87 step.put() | 85 step.put() |
88 | 86 |
89 step_log_url = buildbot.CreateStdioLogUrl( | 87 step_log_url = buildbot.CreateStdioLogUrl( |
90 master_name, builder_name, build_number, step_name) | 88 master_name, builder_name, build_number, step_name) |
91 with self.mock_urlfetch() as urlfetch: | 89 with self.mock_urlfetch() as urlfetch: |
92 urlfetch.register_handler(step_log_url, 'If used, test should fail!') | 90 urlfetch.register_handler(step_log_url, 'If used, test should fail!') |
93 | 91 |
94 def MockStepIsSupportedForMaster(*_): | |
95 return True | |
96 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
97 MockStepIsSupportedForMaster) | |
98 self._CreateAndSaveWfAnanlysis( | 92 self._CreateAndSaveWfAnanlysis( |
99 master_name, builder_name, build_number) | 93 master_name, builder_name, build_number) |
100 | 94 |
101 pipeline = ExtractSignalPipeline(self.FAILURE_INFO) | 95 pipeline = ExtractSignalPipeline(self.FAILURE_INFO) |
102 signals = pipeline.run(self.FAILURE_INFO, False) | 96 signals = pipeline.run(self.FAILURE_INFO, False) |
103 | 97 |
104 self.assertEqual(self.FAILURE_SIGNALS, signals) | 98 self.assertEqual(self.FAILURE_SIGNALS, signals) |
105 | 99 |
106 def MockGetStdiolog(self, master_name, builder_name, build_number, step_name): | 100 def MockGetStdiolog(self, master_name, builder_name, build_number, step_name): |
107 step_log_url = buildbot.CreateStdioLogUrl( | 101 step_log_url = buildbot.CreateStdioLogUrl( |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 build_number = 123 | 188 build_number = 123 |
195 step_name = 'abc_test' | 189 step_name = 'abc_test' |
196 | 190 |
197 # Mock both stdiolog and gtest json results to test whether Findit will | 191 # Mock both stdiolog and gtest json results to test whether Findit will |
198 # go to step log first when both logs exist. | 192 # go to step log first when both logs exist. |
199 self.MockGetStdiolog(master_name, builder_name, build_number, step_name) | 193 self.MockGetStdiolog(master_name, builder_name, build_number, step_name) |
200 self.MockGetGtestJsonResult() | 194 self.MockGetGtestJsonResult() |
201 self._CreateAndSaveWfAnanlysis( | 195 self._CreateAndSaveWfAnanlysis( |
202 master_name, builder_name, build_number) | 196 master_name, builder_name, build_number) |
203 | 197 |
204 def MockStepIsSupportedForMaster(*_): | |
205 return True | |
206 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
207 MockStepIsSupportedForMaster) | |
208 | |
209 pipeline = ExtractSignalPipeline(self.FAILURE_INFO) | 198 pipeline = ExtractSignalPipeline(self.FAILURE_INFO) |
210 signals = pipeline.run(self.FAILURE_INFO, False) | 199 signals = pipeline.run(self.FAILURE_INFO, False) |
211 | 200 |
212 step = WfStep.Get(master_name, builder_name, build_number, step_name) | 201 step = WfStep.Get(master_name, builder_name, build_number, step_name) |
213 | 202 |
214 expected_files = { | 203 expected_files = { |
215 'a/b/u2s1.cc': [567], | 204 'a/b/u2s1.cc': [567], |
216 'a/b/u3s2.cc': [110] | 205 'a/b/u3s2.cc': [110] |
217 } | 206 } |
218 | 207 |
219 self.assertIsNotNone(step) | 208 self.assertIsNotNone(step) |
220 self.assertIsNotNone(step.log_data) | 209 self.assertIsNotNone(step.log_data) |
221 self.assertEqual(expected_files, signals['abc_test']['files']) | 210 self.assertEqual(expected_files, signals['abc_test']['files']) |
222 | 211 |
223 def testGetSignalFromStepLogFlaky(self): | 212 def testGetSignalFromStepLogFlaky(self): |
224 master_name = 'm' | 213 master_name = 'm' |
225 builder_name = 'b' | 214 builder_name = 'b' |
226 build_number = 124 | 215 build_number = 124 |
227 step_name = 'abc_test' | 216 step_name = 'abc_test' |
228 | 217 |
229 failure_info = { | 218 failure_info = { |
230 'master_name': 'm', | 219 'master_name': master_name, |
231 'builder_name': 'b', | 220 'builder_name': builder_name, |
232 'build_number': 124, | 221 'build_number': build_number, |
233 'failed': True, | 222 'failed': True, |
234 'chromium_revision': 'a_git_hash', | 223 'chromium_revision': 'a_git_hash', |
235 'failed_steps': { | 224 'failed_steps': { |
236 'abc_test': { | 225 'abc_test': { |
237 'last_pass': 123, | 226 'last_pass': 123, |
238 'current_failure': 124, | 227 'current_failure': 124, |
239 'first_failure': 124, | 228 'first_failure': 124, |
240 } | 229 } |
241 } | 230 } |
242 } | 231 } |
243 | 232 |
244 self.MockGetStdiolog(master_name, builder_name, build_number, step_name) | 233 self.MockGetStdiolog(master_name, builder_name, build_number, step_name) |
245 self.MockGetGtestJsonResult() | 234 self.MockGetGtestJsonResult() |
246 self._CreateAndSaveWfAnanlysis( | 235 self._CreateAndSaveWfAnanlysis( |
247 master_name, builder_name, build_number) | 236 master_name, builder_name, build_number) |
248 | 237 |
249 def MockStepIsSupportedForMaster(*_): | |
250 return True | |
251 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
252 MockStepIsSupportedForMaster) | |
253 | |
254 pipeline = ExtractSignalPipeline() | 238 pipeline = ExtractSignalPipeline() |
255 signals = pipeline.run(failure_info, False) | 239 signals = pipeline.run(failure_info, False) |
256 | 240 |
257 step = WfStep.Get(master_name, builder_name, build_number, step_name) | 241 step = WfStep.Get(master_name, builder_name, build_number, step_name) |
258 | 242 |
259 self.assertIsNotNone(step) | 243 self.assertIsNotNone(step) |
260 self.assertIsNotNone(step.log_data) | 244 self.assertIsNotNone(step.log_data) |
261 self.assertEqual('flaky', step.log_data) | 245 self.assertEqual('flaky', step.log_data) |
262 self.assertEqual({}, signals['abc_test']['files']) | 246 self.assertEqual({}, signals['abc_test']['files']) |
263 | 247 |
264 def testGetSignalFromStepLogInvalid(self): | 248 def testGetSignalFromStepLogInvalid(self): |
265 master_name = 'm' | 249 master_name = 'm' |
266 builder_name = 'b' | 250 builder_name = 'b' |
267 build_number = 125 | 251 build_number = 125 |
268 step_name = 'abc_test' | 252 step_name = 'abc_test' |
269 | 253 |
270 failure_info = { | 254 failure_info = { |
271 'master_name': 'm', | 255 'master_name': master_name, |
272 'builder_name': 'b', | 256 'builder_name': builder_name, |
273 'build_number': 125, | 257 'build_number': build_number, |
274 'failed': True, | 258 'failed': True, |
275 'chromium_revision': 'a_git_hash', | 259 'chromium_revision': 'a_git_hash', |
276 'failed_steps': { | 260 'failed_steps': { |
277 'abc_test': { | 261 step_name: { |
278 'last_pass': 124, | 262 'last_pass': 124, |
279 'current_failure': 125, | 263 'current_failure': 125, |
280 'first_failure': 125, | 264 'first_failure': 125, |
281 } | 265 } |
282 } | 266 } |
283 } | 267 } |
284 | 268 |
285 self.MockGetStdiolog(master_name, builder_name, build_number, step_name) | 269 self.MockGetStdiolog(master_name, builder_name, build_number, step_name) |
286 self.MockGetGtestJsonResult() | 270 self.MockGetGtestJsonResult() |
287 self._CreateAndSaveWfAnanlysis( | 271 self._CreateAndSaveWfAnanlysis( |
288 master_name, builder_name, build_number) | 272 master_name, builder_name, build_number) |
289 | 273 |
290 def MockStepIsSupportedForMaster(*_): | |
291 return True | |
292 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
293 MockStepIsSupportedForMaster) | |
294 | |
295 pipeline = ExtractSignalPipeline() | 274 pipeline = ExtractSignalPipeline() |
296 signals = pipeline.run(failure_info, False) | 275 signals = pipeline.run(failure_info, False) |
297 | 276 |
298 step = WfStep.Get(master_name, builder_name, build_number, step_name) | 277 step = WfStep.Get(master_name, builder_name, build_number, step_name) |
299 | 278 |
300 expected_files = { | 279 expected_files = { |
301 'content/common/gpu/media/v4l2_video_encode_accelerator.cc': [306] | 280 'content/common/gpu/media/v4l2_video_encode_accelerator.cc': [306] |
302 } | 281 } |
303 | 282 |
304 self.assertIsNotNone(step) | 283 self.assertIsNotNone(step) |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
386 'Unittest3.Subtest2': { | 365 'Unittest3.Subtest2': { |
387 'files': { | 366 'files': { |
388 'a/b/u3s2.cc': [110, 123] | 367 'a/b/u3s2.cc': [110, 123] |
389 }, | 368 }, |
390 'keywords': {} | 369 'keywords': {} |
391 } | 370 } |
392 } | 371 } |
393 } | 372 } |
394 } | 373 } |
395 | 374 |
396 def MockStepIsSupportedForMaster(*_): | |
397 return True | |
398 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
399 MockStepIsSupportedForMaster) | |
400 | |
401 self._CreateAndSaveWfAnanlysis( | 375 self._CreateAndSaveWfAnanlysis( |
402 master_name, builder_name, build_number) | 376 master_name, builder_name, build_number) |
403 | 377 |
404 pipeline = ExtractSignalPipeline() | 378 pipeline = ExtractSignalPipeline() |
405 signals = pipeline.run(failure_info, False) | 379 signals = pipeline.run(failure_info, False) |
406 self.assertEqual(expected_signals, signals) | 380 self.assertEqual(expected_signals, signals) |
407 | 381 |
408 def testExtractSignalsForTestsFlaky(self): | 382 def testExtractSignalsForTestsFlaky(self): |
409 master_name = 'm' | 383 master_name = 'm' |
410 builder_name = 'b' | 384 builder_name = 'b' |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
443 step.put() | 417 step.put() |
444 | 418 |
445 expected_signals = { | 419 expected_signals = { |
446 'abc_test': { | 420 'abc_test': { |
447 'files': {}, | 421 'files': {}, |
448 'keywords': {}, | 422 'keywords': {}, |
449 'tests': {} | 423 'tests': {} |
450 } | 424 } |
451 } | 425 } |
452 | 426 |
453 def MockStepIsSupportedForMaster(*_): | |
454 return True | |
455 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
456 MockStepIsSupportedForMaster) | |
457 self._CreateAndSaveWfAnanlysis( | 427 self._CreateAndSaveWfAnanlysis( |
458 master_name, builder_name, build_number) | 428 master_name, builder_name, build_number) |
459 | 429 |
460 pipeline = ExtractSignalPipeline() | 430 pipeline = ExtractSignalPipeline() |
461 signals = pipeline.run(failure_info, False) | 431 signals = pipeline.run(failure_info, False) |
462 self.assertEqual(expected_signals, signals) | 432 self.assertEqual(expected_signals, signals) |
463 | 433 |
464 def testBailOutForUnsupportedStep(self): | 434 def testBailOutForUnsupportedStep(self): |
465 master_name = 'm' | 435 master_name = 'm' |
466 builder_name = 'b' | 436 builder_name = 'b' |
467 build_number = 123 | 437 build_number = 123 |
468 supported_step_name = 'abc_test' | 438 supported_step_name = 'abc_test' |
| 439 unsupported_step_name = 'unsupported_step6' |
469 failure_info = { | 440 failure_info = { |
470 'master_name': master_name, | 441 'master_name': master_name, |
471 'builder_name': 'b', | 442 'builder_name': 'b', |
472 'build_number': 123, | 443 'build_number': 123, |
473 'failed': True, | 444 'failed': True, |
474 'chromium_revision': 'a_git_hash', | 445 'chromium_revision': 'a_git_hash', |
475 'failed_steps': { | 446 'failed_steps': { |
476 supported_step_name: { | 447 supported_step_name: { |
477 'last_pass': 122, | 448 'last_pass': 122, |
478 'current_failure': 123, | 449 'current_failure': 123, |
479 'first_failure': 123, | 450 'first_failure': 123, |
480 }, | 451 }, |
481 'not_supported': { | 452 unsupported_step_name: { |
482 } | 453 } |
483 } | 454 } |
484 } | 455 } |
485 | 456 |
486 def MockStepIsSupportedForMaster(step_name, _): | |
487 return step_name == supported_step_name | |
488 | |
489 def MockGetGtestResultLog(*_): | 457 def MockGetGtestResultLog(*_): |
490 return None | 458 return None |
491 | 459 |
492 self.mock(waterfall_config, 'StepIsSupportedForMaster', | |
493 MockStepIsSupportedForMaster) | |
494 self.MockGetStdiolog(master_name, builder_name, build_number, | 460 self.MockGetStdiolog(master_name, builder_name, build_number, |
495 supported_step_name) | 461 supported_step_name) |
496 self.mock(buildbot, 'GetGtestResultLog', MockGetGtestResultLog) | 462 self.mock(buildbot, 'GetGtestResultLog', MockGetGtestResultLog) |
497 self._CreateAndSaveWfAnanlysis( | 463 self._CreateAndSaveWfAnanlysis( |
498 master_name, builder_name, build_number) | 464 master_name, builder_name, build_number) |
499 | 465 |
500 pipeline = ExtractSignalPipeline() | 466 pipeline = ExtractSignalPipeline() |
501 signals = pipeline.run(failure_info, False) | 467 signals = pipeline.run(failure_info, False) |
502 self.assertEqual(self.FAILURE_SIGNALS, signals) | 468 self.assertEqual(self.FAILURE_SIGNALS, signals) |
OLD | NEW |