| Index: appengine/findit/waterfall/test/identify_try_job_culprit_pipeline_test.py | 
| diff --git a/appengine/findit/waterfall/test/identify_try_job_culprit_pipeline_test.py b/appengine/findit/waterfall/test/identify_try_job_culprit_pipeline_test.py | 
| index 4557aa46735982ce6fdb8ad322e11d8652b2dbe7..64b2ef038b14d8038861cedaaf52d7b6be1ec644 100644 | 
| --- a/appengine/findit/waterfall/test/identify_try_job_culprit_pipeline_test.py | 
| +++ b/appengine/findit/waterfall/test/identify_try_job_culprit_pipeline_test.py | 
| @@ -21,6 +21,7 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| self.code_review_url = code_review_url | 
|  | 
| mock_change_logs = {} | 
| +    mock_change_logs['rev1'] = MockedChangeLog('1', 'url_1') | 
| mock_change_logs['rev2'] = MockedChangeLog('2', 'url_2') | 
| return mock_change_logs.get(revision) | 
|  | 
| @@ -28,13 +29,11 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| master_name = 'm' | 
| builder_name = 'b' | 
| build_number = 1 | 
| -    try_job_id = '1' | 
| -    compile_result = None | 
|  | 
| WfTryJob.Create(master_name, builder_name, build_number).put() | 
| pipeline = IdentifyTryJobCulpritPipeline() | 
| culprit = pipeline.run( | 
| -        master_name, builder_name, build_number, try_job_id, compile_result) | 
| +        master_name, builder_name, build_number, ['rev1'], 'compile', '1', None) | 
| try_job = WfTryJob.Get(master_name, builder_name, build_number) | 
|  | 
| self.assertIsNone(culprit) | 
| @@ -44,7 +43,6 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| master_name = 'm' | 
| builder_name = 'b' | 
| build_number = 1 | 
| -    try_job_id = '1' | 
| compile_result = { | 
| 'result': [], | 
| 'url': 'url', | 
| @@ -54,7 +52,8 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
|  | 
| pipeline = IdentifyTryJobCulpritPipeline() | 
| culprit = pipeline.run( | 
| -        master_name, builder_name, build_number, try_job_id, compile_result) | 
| +        master_name, builder_name, build_number, ['rev1'], 'compile', '1', | 
| +        compile_result) | 
| try_job = WfTryJob.Get(master_name, builder_name, build_number) | 
|  | 
| self.assertIsNone(culprit) | 
| @@ -64,7 +63,6 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| master_name = 'm' | 
| builder_name = 'b' | 
| build_number = 1 | 
| -    try_job_id = '1' | 
| compile_result = { | 
| 'result': [ | 
| ['rev1', 'passed'], | 
| @@ -77,7 +75,8 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
|  | 
| pipeline = IdentifyTryJobCulpritPipeline() | 
| culprit = pipeline.run( | 
| -        master_name, builder_name, build_number, try_job_id, compile_result) | 
| +        master_name, builder_name, build_number, ['rev1'], 'compile', '1', | 
| +        compile_result) | 
| try_job = WfTryJob.Get(master_name, builder_name, build_number) | 
|  | 
| self.assertIsNone(culprit) | 
| @@ -87,10 +86,9 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| master_name = 'm' | 
| builder_name = 'b' | 
| build_number = 1 | 
| -    try_job_id = '1' | 
| compile_result = { | 
| 'result': [ | 
| -            ['rev1', 'failed'] | 
| +            ['rev0', 'failed'] | 
| ], | 
| 'url': 'url', | 
| 'try_job_id': '1', | 
| @@ -101,7 +99,8 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
|  | 
| pipeline = IdentifyTryJobCulpritPipeline() | 
| culprit = pipeline.run( | 
| -        master_name, builder_name, build_number, try_job_id, compile_result) | 
| +        master_name, builder_name, build_number, ['rev1'], 'compile', '1', | 
| +        compile_result) | 
| try_job = WfTryJob.Get(master_name, builder_name, build_number) | 
|  | 
| self.assertIsNone(culprit) | 
| @@ -111,7 +110,6 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| master_name = 'm' | 
| builder_name = 'b' | 
| build_number = 1 | 
| -    try_job_id = '1' | 
| compile_result = { | 
| 'result': [ | 
| ['rev1', 'passed'], | 
| @@ -123,21 +121,15 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
|  | 
| try_job = WfTryJob.Create(master_name, builder_name, build_number) | 
| try_job.status = wf_analysis_status.ANALYZING | 
| -    try_job.compile_results = [{ | 
| -        'result': [ | 
| -            ['rev1', 'passed'], | 
| -            ['rev2', 'failed'] | 
| -        ], | 
| -        'url': 'url', | 
| -        'try_job_id': '1', | 
| -    }] | 
| +    try_job.compile_results = [compile_result] | 
| try_job.put() | 
|  | 
| self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | 
|  | 
| pipeline = IdentifyTryJobCulpritPipeline() | 
| culprit = pipeline.run( | 
| -        master_name, builder_name, build_number, try_job_id, compile_result) | 
| +        master_name, builder_name, build_number, ['rev1'], 'compile', '1', | 
| +        compile_result) | 
|  | 
| expected_compile_result = { | 
| 'result': [ | 
| @@ -158,3 +150,214 @@ class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): | 
| try_job = WfTryJob.Get(master_name, builder_name, build_number) | 
| self.assertEqual(expected_compile_result, try_job.compile_results[-1]) | 
| self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 
| + | 
| +  def testIdentifyCulpritForTestTryJobReturnNoneIfNoTryJobResult(self): | 
| +    master_name = 'm' | 
| +    builder_name = 'b' | 
| +    build_number = 1 | 
| + | 
| +    try_job = WfTryJob.Create(master_name, builder_name, build_number) | 
| +    try_job.status = wf_analysis_status.ANALYZING | 
| +    try_job.put() | 
| + | 
| +    pipeline = IdentifyTryJobCulpritPipeline() | 
| +    culprit = pipeline.run( | 
| +        master_name, builder_name, build_number, ['rev1', 'rev2'], 'test', '1', | 
| +        None) | 
| + | 
| +    self.assertIsNone(culprit) | 
| + | 
| +  def testIdentifyCulpritForTestTryJobReturnNoneIfNoRevisionToCheck(self): | 
| +    master_name = 'm' | 
| +    builder_name = 'b' | 
| +    build_number = 1 | 
| +    test_result = { | 
| +        'result': { | 
| +            'rev1': { | 
| +                'a_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['a_test1'] | 
| +                } | 
| +            } | 
| +        }, | 
| +        'url': 'url', | 
| +        'try_job_id': '1' | 
| +    } | 
| + | 
| +    try_job = WfTryJob.Create(master_name, builder_name, build_number) | 
| +    try_job.status = wf_analysis_status.ANALYZING | 
| +    try_job.put() | 
| + | 
| +    pipeline = IdentifyTryJobCulpritPipeline() | 
| +    culprit = pipeline.run( | 
| +        master_name, builder_name, build_number, [], 'test', '1', | 
| +        test_result) | 
| + | 
| +    self.assertIsNone(culprit) | 
| + | 
| +  def testIdentifyCulpritForTestTryJobReturnNoneIfNoCulpritInfo(self): | 
| +    master_name = 'm' | 
| +    builder_name = 'b' | 
| +    build_number = 1 | 
| +    test_result = { | 
| +        'result': { | 
| +            'rev3': { | 
| +                'a_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['a_test1'] | 
| +                } | 
| +            } | 
| +        }, | 
| +        'url': 'url', | 
| +        'try_job_id': '1' | 
| +    } | 
| + | 
| +    try_job = WfTryJob.Create(master_name, builder_name, build_number) | 
| +    try_job.status = wf_analysis_status.ANALYZING | 
| +    try_job.put() | 
| + | 
| +    pipeline = IdentifyTryJobCulpritPipeline() | 
| +    culprit = pipeline.run( | 
| +        master_name, builder_name, build_number, ['rev3'], 'test', '1', | 
| +        test_result) | 
| + | 
| +    self.assertIsNone(culprit) | 
| + | 
| +  def testIdentifyCulpritForTestTryJobSuccess(self): | 
| +    master_name = 'm' | 
| +    builder_name = 'b' | 
| +    build_number = 1 | 
| +    test_result = { | 
| +        'result': { | 
| +            'rev1': { | 
| +                'a_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['a_test1'] | 
| +                }, | 
| +                'b_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['b_test1'] | 
| +                }, | 
| +                'c_test': { | 
| +                    'status': 'passed', | 
| +                    'valid': True | 
| +                } | 
| +            }, | 
| +            'rev2': { | 
| +                'a_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['a_test1', 'a_test2'] | 
| +                }, | 
| +                'b_test': { | 
| +                    'status': 'passed', | 
| +                    'valid': True | 
| +                }, | 
| +                'c_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': [] | 
| +                } | 
| +            } | 
| +        }, | 
| +        'url': 'url', | 
| +        'try_job_id': '1' | 
| +    } | 
| + | 
| +    try_job = WfTryJob.Create(master_name, builder_name, build_number) | 
| +    try_job.status = wf_analysis_status.ANALYZING | 
| +    try_job.test_results = [test_result] | 
| +    try_job.put() | 
| + | 
| +    self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) | 
| + | 
| +    pipeline = IdentifyTryJobCulpritPipeline() | 
| +    culprit = pipeline.run( | 
| +        master_name, builder_name, build_number, ['rev1', 'rev2'], 'test', '1', | 
| +        test_result) | 
| + | 
| +    expected_test_result = { | 
| +        'result': { | 
| +            'rev1': { | 
| +                'a_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['a_test1'] | 
| +                }, | 
| +                'b_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['b_test1'] | 
| +                }, | 
| +                'c_test': { | 
| +                    'status': 'passed', | 
| +                    'valid': True | 
| +                } | 
| +            }, | 
| +            'rev2': { | 
| +                'a_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': ['a_test1', 'a_test2'] | 
| +                }, | 
| +                'b_test': { | 
| +                    'status': 'passed', | 
| +                    'valid': True | 
| +                }, | 
| +                'c_test': { | 
| +                    'status': 'failed', | 
| +                    'valid': True, | 
| +                    'failures': [] | 
| +                } | 
| +            } | 
| +        }, | 
| +        'url': 'url', | 
| +        'try_job_id': '1', | 
| +        'culprit': { | 
| +            'a_test': { | 
| +                'revision': 'rev1', | 
| +                'commit_position': '1', | 
| +                'review_url': 'url_1', | 
| +                'tests': { | 
| +                    'a_test1': { | 
| +                      'revision': 'rev1', | 
| +                      'commit_position': '1', | 
| +                      'review_url': 'url_1' | 
| +                    }, | 
| +                    'a_test2': { | 
| +                      'revision': 'rev2', | 
| +                      'commit_position': '2', | 
| +                      'review_url': 'url_2' | 
| +                    } | 
| +                } | 
| +            }, | 
| +            'b_test': { | 
| +                'revision': 'rev1', | 
| +                'commit_position': '1', | 
| +                'review_url': 'url_1', | 
| +                'tests': { | 
| +                    'b_test1': { | 
| +                      'revision': 'rev1', | 
| +                      'commit_position': '1', | 
| +                      'review_url': 'url_1' | 
| +                    } | 
| +                } | 
| +            }, | 
| +            'c_test': { | 
| +                'revision': 'rev2', | 
| +                'commit_position': '2', | 
| +                'review_url': 'url_2', | 
| +                'tests': {} | 
| +            } | 
| +        } | 
| +    } | 
| + | 
| +    self.assertEqual(expected_test_result['culprit'], culprit) | 
| + | 
| +    try_job = WfTryJob.Get(master_name, builder_name, build_number) | 
| +    self.assertEqual(expected_test_result, try_job.test_results[-1]) | 
| +    self.assertEqual(wf_analysis_status.ANALYZED, try_job.status) | 
|  |