| 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 | 7 from model.test import configured_test_case |
| 8 | |
| 9 from model.wf_analysis import WfAnalysis | 8 from model.wf_analysis import WfAnalysis |
| 10 from model.wf_step import WfStep | 9 from model.wf_step import WfStep |
| 11 from pipeline_wrapper import pipeline_handlers | 10 from pipeline_wrapper import pipeline_handlers |
| 12 from waterfall import buildbot | 11 from waterfall import buildbot |
| 13 from waterfall import try_job_util | 12 from waterfall import try_job_util |
| 14 from waterfall import waterfall_config | |
| 15 from waterfall.extract_signal_pipeline import ExtractSignalPipeline | 13 from waterfall.extract_signal_pipeline import ExtractSignalPipeline |
| 16 | 14 |
| 17 | 15 |
| 18 class ExtractSignalPipelineTest(testing.AppengineTestCase): | 16 class ExtractSignalPipelineTest(configured_test_case.ConfiguredTestCase): |
| 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 = '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 |