| 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 from testing_utils import testing | 5 from testing_utils import testing |
| 6 | 6 |
| 7 from common.git_repository import GitRepository | 7 from common.git_repository import GitRepository |
| 8 from common.waterfall import failure_type |
| 8 from model import analysis_status | 9 from model import analysis_status |
| 9 from model import result_status | 10 from model import result_status |
| 10 from model.wf_analysis import WfAnalysis | 11 from model.wf_analysis import WfAnalysis |
| 11 from model.wf_try_job import WfTryJob | 12 from model.wf_try_job import WfTryJob |
| 12 from model.wf_try_job_data import WfTryJobData | 13 from model.wf_try_job_data import WfTryJobData |
| 13 from waterfall import identify_try_job_culprit_pipeline | 14 from waterfall import identify_try_job_culprit_pipeline |
| 14 from waterfall.identify_try_job_culprit_pipeline import( | 15 from waterfall.identify_try_job_culprit_pipeline import( |
| 15 IdentifyTryJobCulpritPipeline) | 16 IdentifyTryJobCulpritPipeline) |
| 16 from waterfall.try_job_type import TryJobType | |
| 17 | 17 |
| 18 | 18 |
| 19 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 19 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): |
| 20 | 20 |
| 21 def _MockGetChangeLog(self, revision): | 21 def _MockGetChangeLog(self, revision): |
| 22 class MockedChangeLog(object): | 22 class MockedChangeLog(object): |
| 23 | 23 |
| 24 def __init__(self, commit_position, code_review_url): | 24 def __init__(self, commit_position, code_review_url): |
| 25 self.commit_position = commit_position | 25 self.commit_position = commit_position |
| 26 self.code_review_url = code_review_url | 26 self.code_review_url = code_review_url |
| (...skipping 357 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 try_job.put() | 384 try_job.put() |
| 385 try_job_data = WfTryJobData.Create(try_job_id) | 385 try_job_data = WfTryJobData.Create(try_job_id) |
| 386 try_job_data.put() | 386 try_job_data.put() |
| 387 | 387 |
| 388 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 388 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 389 analysis.put() | 389 analysis.put() |
| 390 | 390 |
| 391 pipeline = IdentifyTryJobCulpritPipeline() | 391 pipeline = IdentifyTryJobCulpritPipeline() |
| 392 culprit = pipeline.run( | 392 culprit = pipeline.run( |
| 393 master_name, builder_name, build_number, ['rev1'], | 393 master_name, builder_name, build_number, ['rev1'], |
| 394 TryJobType.COMPILE, '1', None) | 394 failure_type.COMPILE, '1', None) |
| 395 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 395 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 396 | 396 |
| 397 self.assertEqual(analysis_status.COMPLETED, try_job.status) | 397 self.assertEqual(analysis_status.COMPLETED, try_job.status) |
| 398 self.assertEqual([], try_job.compile_results) | 398 self.assertEqual([], try_job.compile_results) |
| 399 self.assertIsNone(culprit) | 399 self.assertIsNone(culprit) |
| 400 self.assertIsNone(try_job_data.culprits) | 400 self.assertIsNone(try_job_data.culprits) |
| 401 self.assertIsNone(analysis.result_status) | 401 self.assertIsNone(analysis.result_status) |
| 402 self.assertIsNone(analysis.suspected_cls) | 402 self.assertIsNone(analysis.suspected_cls) |
| 403 | 403 |
| 404 def testIdentifyCulpritForCompileTryJobSuccess(self): | 404 def testIdentifyCulpritForCompileTryJobSuccess(self): |
| (...skipping 25 matching lines...) Expand all Loading... |
| 430 }, | 430 }, |
| 431 'try_job_id': try_job_id, | 431 'try_job_id': try_job_id, |
| 432 }] | 432 }] |
| 433 try_job.put() | 433 try_job.put() |
| 434 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 434 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 435 analysis.put() | 435 analysis.put() |
| 436 | 436 |
| 437 pipeline = IdentifyTryJobCulpritPipeline() | 437 pipeline = IdentifyTryJobCulpritPipeline() |
| 438 culprit = pipeline.run( | 438 culprit = pipeline.run( |
| 439 master_name, builder_name, build_number, ['rev1'], | 439 master_name, builder_name, build_number, ['rev1'], |
| 440 TryJobType.COMPILE, '1', compile_result) | 440 failure_type.COMPILE, '1', compile_result) |
| 441 | 441 |
| 442 expected_culprit = 'rev2' | 442 expected_culprit = 'rev2' |
| 443 expected_suspected_cl = { | 443 expected_suspected_cl = { |
| 444 'revision': 'rev2', | 444 'revision': 'rev2', |
| 445 'commit_position': '2', | 445 'commit_position': '2', |
| 446 'url': 'url_2', | 446 'url': 'url_2', |
| 447 'repo_name': 'chromium' | 447 'repo_name': 'chromium' |
| 448 } | 448 } |
| 449 expected_compile_result = { | 449 expected_compile_result = { |
| 450 'report': { | 450 'report': { |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 491 } | 491 } |
| 492 | 492 |
| 493 WfTryJobData.Create(try_job_id).put() | 493 WfTryJobData.Create(try_job_id).put() |
| 494 WfTryJob.Create(master_name, builder_name, build_number).put() | 494 WfTryJob.Create(master_name, builder_name, build_number).put() |
| 495 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 495 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 496 analysis.put() | 496 analysis.put() |
| 497 | 497 |
| 498 pipeline = IdentifyTryJobCulpritPipeline() | 498 pipeline = IdentifyTryJobCulpritPipeline() |
| 499 culprit = pipeline.run( | 499 culprit = pipeline.run( |
| 500 master_name, builder_name, build_number, ['rev1'], | 500 master_name, builder_name, build_number, ['rev1'], |
| 501 TryJobType.COMPILE, '1', compile_result) | 501 failure_type.COMPILE, '1', compile_result) |
| 502 try_job = WfTryJob.Get(master_name, builder_name, build_number) | 502 try_job = WfTryJob.Get(master_name, builder_name, build_number) |
| 503 | 503 |
| 504 self.assertIsNone(culprit) | 504 self.assertIsNone(culprit) |
| 505 self.assertEqual(analysis_status.COMPLETED, try_job.status) | 505 self.assertEqual(analysis_status.COMPLETED, try_job.status) |
| 506 | 506 |
| 507 try_job_data = WfTryJobData.Get(try_job_id) | 507 try_job_data = WfTryJobData.Get(try_job_id) |
| 508 self.assertIsNone(try_job_data.culprits) | 508 self.assertIsNone(try_job_data.culprits) |
| 509 | 509 |
| 510 self.assertIsNone(analysis.result_status) | 510 self.assertIsNone(analysis.result_status) |
| 511 self.assertIsNone(analysis.suspected_cls) | 511 self.assertIsNone(analysis.suspected_cls) |
| 512 | 512 |
| 513 def testIdentifyCulpritForTestTryJobNoTryJobResultNoHeuristicResult(self): | 513 def testIdentifyCulpritForTestTryJobNoTryJobResultNoHeuristicResult(self): |
| 514 master_name = 'm' | 514 master_name = 'm' |
| 515 builder_name = 'b' | 515 builder_name = 'b' |
| 516 build_number = 1 | 516 build_number = 1 |
| 517 try_job_id = '1' | 517 try_job_id = '1' |
| 518 | 518 |
| 519 WfTryJobData.Create(try_job_id).put() | 519 WfTryJobData.Create(try_job_id).put() |
| 520 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 520 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 521 try_job.status = analysis_status.RUNNING | 521 try_job.status = analysis_status.RUNNING |
| 522 try_job.put() | 522 try_job.put() |
| 523 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 523 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 524 analysis.put() | 524 analysis.put() |
| 525 | 525 |
| 526 pipeline = IdentifyTryJobCulpritPipeline() | 526 pipeline = IdentifyTryJobCulpritPipeline() |
| 527 culprit = pipeline.run( | 527 culprit = pipeline.run( |
| 528 master_name, builder_name, build_number, ['rev1', 'rev2'], | 528 master_name, builder_name, build_number, ['rev1', 'rev2'], |
| 529 TryJobType.TEST, '1', None) | 529 failure_type.TEST, '1', None) |
| 530 | 530 |
| 531 self.assertIsNone(culprit) | 531 self.assertIsNone(culprit) |
| 532 | 532 |
| 533 try_job_data = WfTryJobData.Get(try_job_id) | 533 try_job_data = WfTryJobData.Get(try_job_id) |
| 534 self.assertIsNone(try_job_data.culprits) | 534 self.assertIsNone(try_job_data.culprits) |
| 535 self.assertIsNone(analysis.result_status) | 535 self.assertIsNone(analysis.result_status) |
| 536 self.assertIsNone(analysis.suspected_cls) | 536 self.assertIsNone(analysis.suspected_cls) |
| 537 | 537 |
| 538 def testIdentifyCulpritForTestTryJobNoTryJobResultWithHeuristicResult(self): | 538 def testIdentifyCulpritForTestTryJobNoTryJobResultWithHeuristicResult(self): |
| 539 master_name = 'm' | 539 master_name = 'm' |
| (...skipping 15 matching lines...) Expand all Loading... |
| 555 | 555 |
| 556 # Heuristic analysis already provided some results. | 556 # Heuristic analysis already provided some results. |
| 557 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 557 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 558 analysis.result_status = result_status.FOUND_UNTRIAGED | 558 analysis.result_status = result_status.FOUND_UNTRIAGED |
| 559 analysis.suspected_cls = [suspected_cl] | 559 analysis.suspected_cls = [suspected_cl] |
| 560 analysis.put() | 560 analysis.put() |
| 561 | 561 |
| 562 pipeline = IdentifyTryJobCulpritPipeline() | 562 pipeline = IdentifyTryJobCulpritPipeline() |
| 563 culprit = pipeline.run( | 563 culprit = pipeline.run( |
| 564 master_name, builder_name, build_number, ['rev1', 'rev2'], | 564 master_name, builder_name, build_number, ['rev1', 'rev2'], |
| 565 TryJobType.TEST, '1', None) | 565 failure_type.TEST, '1', None) |
| 566 | 566 |
| 567 self.assertIsNone(culprit) | 567 self.assertIsNone(culprit) |
| 568 | 568 |
| 569 try_job_data = WfTryJobData.Get(try_job_id) | 569 try_job_data = WfTryJobData.Get(try_job_id) |
| 570 self.assertIsNone(try_job_data.culprits) | 570 self.assertIsNone(try_job_data.culprits) |
| 571 | 571 |
| 572 # Ensure analysis results are not updated since no culprit from try job. | 572 # Ensure analysis results are not updated since no culprit from try job. |
| 573 self.assertEqual(analysis.result_status, result_status.FOUND_UNTRIAGED) | 573 self.assertEqual(analysis.result_status, result_status.FOUND_UNTRIAGED) |
| 574 self.assertEqual(analysis.suspected_cls, [suspected_cl]) | 574 self.assertEqual(analysis.suspected_cls, [suspected_cl]) |
| 575 | 575 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 597 | 597 |
| 598 WfTryJobData.Create(try_job_id).put() | 598 WfTryJobData.Create(try_job_id).put() |
| 599 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 599 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 600 try_job.status = analysis_status.RUNNING | 600 try_job.status = analysis_status.RUNNING |
| 601 try_job.put() | 601 try_job.put() |
| 602 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 602 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 603 analysis.put() | 603 analysis.put() |
| 604 | 604 |
| 605 pipeline = IdentifyTryJobCulpritPipeline() | 605 pipeline = IdentifyTryJobCulpritPipeline() |
| 606 culprit = pipeline.run( | 606 culprit = pipeline.run( |
| 607 master_name, builder_name, build_number, [], TryJobType.TEST, '1', | 607 master_name, builder_name, build_number, [], failure_type.TEST, '1', |
| 608 test_result) | 608 test_result) |
| 609 | 609 |
| 610 self.assertIsNone(culprit) | 610 self.assertIsNone(culprit) |
| 611 | 611 |
| 612 try_job_data = WfTryJobData.Get(try_job_id) | 612 try_job_data = WfTryJobData.Get(try_job_id) |
| 613 self.assertIsNone(try_job_data.culprits) | 613 self.assertIsNone(try_job_data.culprits) |
| 614 | 614 |
| 615 self.assertIsNone(analysis.result_status) | 615 self.assertIsNone(analysis.result_status) |
| 616 self.assertIsNone(analysis.suspected_cls) | 616 self.assertIsNone(analysis.suspected_cls) |
| 617 | 617 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 639 | 639 |
| 640 WfTryJobData.Create(try_job_id).put() | 640 WfTryJobData.Create(try_job_id).put() |
| 641 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 641 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 642 try_job.status = analysis_status.RUNNING | 642 try_job.status = analysis_status.RUNNING |
| 643 try_job.put() | 643 try_job.put() |
| 644 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 644 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 645 analysis.put() | 645 analysis.put() |
| 646 | 646 |
| 647 pipeline = IdentifyTryJobCulpritPipeline() | 647 pipeline = IdentifyTryJobCulpritPipeline() |
| 648 culprit = pipeline.run( | 648 culprit = pipeline.run( |
| 649 master_name, builder_name, build_number, ['rev3'], TryJobType.TEST, | 649 master_name, builder_name, build_number, ['rev3'], failure_type.TEST, |
| 650 '1', test_result) | 650 '1', test_result) |
| 651 | 651 |
| 652 expected_suspected_cl = { | 652 expected_suspected_cl = { |
| 653 'revision': 'rev3', | 653 'revision': 'rev3', |
| 654 'repo_name': 'chromium' | 654 'repo_name': 'chromium' |
| 655 } | 655 } |
| 656 | 656 |
| 657 expected_culprit = { | 657 expected_culprit = { |
| 658 'a_test': { | 658 'a_test': { |
| 659 'tests': { | 659 'tests': { |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 726 try_job = WfTryJob.Create(master_name, builder_name, build_number) | 726 try_job = WfTryJob.Create(master_name, builder_name, build_number) |
| 727 try_job.status = analysis_status.RUNNING | 727 try_job.status = analysis_status.RUNNING |
| 728 try_job.test_results = [test_result] | 728 try_job.test_results = [test_result] |
| 729 try_job.put() | 729 try_job.put() |
| 730 analysis = WfAnalysis.Create(master_name, builder_name, build_number) | 730 analysis = WfAnalysis.Create(master_name, builder_name, build_number) |
| 731 analysis.put() | 731 analysis.put() |
| 732 | 732 |
| 733 pipeline = IdentifyTryJobCulpritPipeline() | 733 pipeline = IdentifyTryJobCulpritPipeline() |
| 734 culprit = pipeline.run( | 734 culprit = pipeline.run( |
| 735 master_name, builder_name, build_number, ['rev1', 'rev2'], | 735 master_name, builder_name, build_number, ['rev1', 'rev2'], |
| 736 TryJobType.TEST, '1', test_result) | 736 failure_type.TEST, '1', test_result) |
| 737 | 737 |
| 738 a_test1_suspected_cl = { | 738 a_test1_suspected_cl = { |
| 739 'revision': 'rev1', | 739 'revision': 'rev1', |
| 740 'commit_position': '1', | 740 'commit_position': '1', |
| 741 'url': 'url_1', | 741 'url': 'url_1', |
| 742 'repo_name': 'chromium' | 742 'repo_name': 'chromium' |
| 743 } | 743 } |
| 744 a_test2_suspected_cl = { | 744 a_test2_suspected_cl = { |
| 745 'revision': 'rev2', | 745 'revision': 'rev2', |
| 746 'commit_position': '2', | 746 'commit_position': '2', |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 872 'rev1': 'failed', | 872 'rev1': 'failed', |
| 873 }, | 873 }, |
| 874 }, | 874 }, |
| 875 'try_job_id': try_job_id, | 875 'try_job_id': try_job_id, |
| 876 }] | 876 }] |
| 877 | 877 |
| 878 try_job.put() | 878 try_job.put() |
| 879 | 879 |
| 880 pipeline = IdentifyTryJobCulpritPipeline() | 880 pipeline = IdentifyTryJobCulpritPipeline() |
| 881 pipeline.run(master_name, builder_name, build_number, ['rev1'], | 881 pipeline.run(master_name, builder_name, build_number, ['rev1'], |
| 882 TryJobType.COMPILE, '1', compile_result) | 882 failure_type.COMPILE, '1', compile_result) |
| 883 | 883 |
| 884 self.assertEqual(analysis.result_status, | 884 self.assertEqual(analysis.result_status, |
| 885 result_status.FOUND_UNTRIAGED) | 885 result_status.FOUND_UNTRIAGED) |
| 886 self.assertEqual(analysis.suspected_cls, [suspected_cl]) | 886 self.assertEqual(analysis.suspected_cls, [suspected_cl]) |
| 887 self.assertEqual(version, analysis.version) # No update to analysis. | 887 self.assertEqual(version, analysis.version) # No update to analysis. |
| 888 | 888 |
| 889 def testFindCulpritForEachTestFailureRevisionNotRun(self): | 889 def testFindCulpritForEachTestFailureRevisionNotRun(self): |
| 890 blame_list = ['rev1'] | 890 blame_list = ['rev1'] |
| 891 result = { | 891 result = { |
| 892 'report': { | 892 'report': { |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 culprits = { | 949 culprits = { |
| 950 'r1': { | 950 'r1': { |
| 951 'repo_name': 'chromium', | 951 'repo_name': 'chromium', |
| 952 'revision': 'r1', | 952 'revision': 'r1', |
| 953 } | 953 } |
| 954 } | 954 } |
| 955 | 955 |
| 956 identify_try_job_culprit_pipeline._NotifyCulprits('m', 'b', 1, culprits) | 956 identify_try_job_culprit_pipeline._NotifyCulprits('m', 'b', 1, culprits) |
| 957 self.assertEqual(1, len(instances)) | 957 self.assertEqual(1, len(instances)) |
| 958 self.assertTrue(instances[0].started) | 958 self.assertTrue(instances[0].started) |
| OLD | NEW |