Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(311)

Side by Side Diff: appengine/findit/waterfall/test/identify_try_job_culprit_pipeline_test.py

Issue 2230103002: [Findit] Pipeline change to save suspected cls to data store. (Closed) Base URL: https://chromium.googlesource.com/infra/infra.git@0808-resubmit-suspected_cl_model
Patch Set: Add todos and make sure analysis.suspected_cls have consistent format. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 common.waterfall import failure_type
9 from model import analysis_approach_type
9 from model import analysis_status 10 from model import analysis_status
10 from model import result_status 11 from model import result_status
11 from model.wf_analysis import WfAnalysis 12 from model.wf_analysis import WfAnalysis
13 from model.wf_suspected_cl import WfSuspectedCL
12 from model.wf_try_job import WfTryJob 14 from model.wf_try_job import WfTryJob
13 from model.wf_try_job_data import WfTryJobData 15 from model.wf_try_job_data import WfTryJobData
14 from waterfall import identify_try_job_culprit_pipeline 16 from waterfall import identify_try_job_culprit_pipeline
15 from waterfall.identify_try_job_culprit_pipeline import( 17 from waterfall.identify_try_job_culprit_pipeline import(
16 IdentifyTryJobCulpritPipeline) 18 IdentifyTryJobCulpritPipeline)
17 19
18 20
19 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase): 21 class IdentifyTryJobCulpritPipelineTest(testing.AppengineTestCase):
20 22
21 def _MockGetChangeLog(self, revision): 23 def _MockGetChangeLog(self, revision):
22 class MockedChangeLog(object): 24 class MockedChangeLog(object):
23 25
24 def __init__(self, commit_position, code_review_url): 26 def __init__(self, commit_position, code_review_url):
25 self.commit_position = commit_position 27 self.commit_position = commit_position
26 self.code_review_url = code_review_url 28 self.code_review_url = code_review_url
27 29
28 mock_change_logs = {} 30 mock_change_logs = {}
29 mock_change_logs['rev1'] = MockedChangeLog('1', 'url_1') 31 mock_change_logs['rev1'] = MockedChangeLog(1, 'url_1')
30 mock_change_logs['rev2'] = MockedChangeLog('2', 'url_2') 32 mock_change_logs['rev2'] = MockedChangeLog(2, 'url_2')
31 return mock_change_logs.get(revision) 33 return mock_change_logs.get(revision)
32 34
33 def setUp(self): 35 def setUp(self):
34 super(IdentifyTryJobCulpritPipelineTest, self).setUp() 36 super(IdentifyTryJobCulpritPipelineTest, self).setUp()
35 37
36 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog) 38 self.mock(GitRepository, 'GetChangeLog', self._MockGetChangeLog)
37 39
38 def testGetFailedRevisionFromResultsDict(self): 40 def testGetFailedRevisionFromResultsDict(self):
39 self.assertIsNone( 41 self.assertIsNone(
40 identify_try_job_culprit_pipeline._GetFailedRevisionFromResultsDict({})) 42 identify_try_job_culprit_pipeline._GetFailedRevisionFromResultsDict({}))
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
94 def testGetResultAnalysisStatusWithTryJobCulpritNotFoundUntriaged(self): 96 def testGetResultAnalysisStatusWithTryJobCulpritNotFoundUntriaged(self):
95 # Heuristic analysis provided no results, but the try job found a culprit. 97 # Heuristic analysis provided no results, but the try job found a culprit.
96 analysis = WfAnalysis.Create('m', 'b', 1) 98 analysis = WfAnalysis.Create('m', 'b', 1)
97 analysis.result_status = result_status.NOT_FOUND_UNTRIAGED 99 analysis.result_status = result_status.NOT_FOUND_UNTRIAGED
98 analysis.put() 100 analysis.put()
99 101
100 result = { 102 result = {
101 'culprit': { 103 'culprit': {
102 'compile': { 104 'compile': {
103 'revision': 'rev1', 105 'revision': 'rev1',
104 'commit_position': '1', 106 'commit_position': 1,
105 'url': 'url_1', 107 'url': 'url_1',
106 'repo_name': 'chromium' 108 'repo_name': 'chromium'
107 } 109 }
108 } 110 }
109 } 111 }
110 112
111 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus( 113 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus(
112 analysis, result) 114 analysis, result)
113 115
114 self.assertEqual(status, result_status.FOUND_UNTRIAGED) 116 self.assertEqual(status, result_status.FOUND_UNTRIAGED)
115 117
116 def testGetResultAnalysisStatusWithTryJobCulpritNotFoundCorrect(self): 118 def testGetResultAnalysisStatusWithTryJobCulpritNotFoundCorrect(self):
117 # Heuristic analysis found no results, which was correct. In this case, the 119 # Heuristic analysis found no results, which was correct. In this case, the
118 # try job result is actually a false positive. 120 # try job result is actually a false positive.
119 analysis = WfAnalysis.Create('m', 'b', 1) 121 analysis = WfAnalysis.Create('m', 'b', 1)
120 analysis.result_status = result_status.NOT_FOUND_CORRECT 122 analysis.result_status = result_status.NOT_FOUND_CORRECT
121 analysis.put() 123 analysis.put()
122 124
123 result = { 125 result = {
124 'culprit': { 126 'culprit': {
125 'compile': { 127 'compile': {
126 'revision': 'rev1', 128 'revision': 'rev1',
127 'commit_position': '1', 129 'commit_position': 1,
128 'url': 'url_1', 130 'url': 'url_1',
129 'repo_name': 'chromium' 131 'repo_name': 'chromium'
130 } 132 }
131 } 133 }
132 } 134 }
133 135
134 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus( 136 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus(
135 analysis, result) 137 analysis, result)
136 138
137 self.assertEqual(status, result_status.FOUND_UNTRIAGED) 139 self.assertEqual(status, result_status.FOUND_UNTRIAGED)
138 140
139 def testGetResultanalysisStatusWithTryJobCulpritNotFoundIncorrect(self): 141 def testGetResultanalysisStatusWithTryJobCulpritNotFoundIncorrect(self):
140 # Heuristic analysis found no results and was triaged to incorrect before a 142 # Heuristic analysis found no results and was triaged to incorrect before a
141 # try job result was found. In this case the try job result should override 143 # try job result was found. In this case the try job result should override
142 # the heuristic result. 144 # the heuristic result.
143 analysis = WfAnalysis.Create('m', 'b', 1) 145 analysis = WfAnalysis.Create('m', 'b', 1)
144 analysis.result_status = result_status.NOT_FOUND_INCORRECT 146 analysis.result_status = result_status.NOT_FOUND_INCORRECT
145 analysis.put() 147 analysis.put()
146 148
147 result = { 149 result = {
148 'culprit': { 150 'culprit': {
149 'compile': { 151 'compile': {
150 'revision': 'rev1', 152 'revision': 'rev1',
151 'commit_position': '1', 153 'commit_position': 1,
152 'url': 'url_1', 154 'url': 'url_1',
153 'repo_name': 'chromium' 155 'repo_name': 'chromium'
154 } 156 }
155 } 157 }
156 } 158 }
157 159
158 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus( 160 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus(
159 analysis, result) 161 analysis, result)
160 162
161 self.assertEqual(status, result_status.FOUND_UNTRIAGED) 163 self.assertEqual(status, result_status.FOUND_UNTRIAGED)
162 164
163 def testGetResultanalysisStatusWithTryJobCulpritNoHeuristicResult(self): 165 def testGetResultanalysisStatusWithTryJobCulpritNoHeuristicResult(self):
164 # In this case, the try job found a result before the heuristic result is 166 # In this case, the try job found a result before the heuristic result is
165 # available. This case should generally never happen, as heuristic analysis 167 # available. This case should generally never happen, as heuristic analysis
166 # is usually much faster than try jobs. 168 # is usually much faster than try jobs.
167 analysis = WfAnalysis.Create('m', 'b', 1) 169 analysis = WfAnalysis.Create('m', 'b', 1)
168 analysis.put() 170 analysis.put()
169 171
170 result = { 172 result = {
171 'culprit': { 173 'culprit': {
172 'compile': { 174 'compile': {
173 'revision': 'rev1', 175 'revision': 'rev1',
174 'commit_position': '1', 176 'commit_position': 1,
175 'url': 'url_1', 177 'url': 'url_1',
176 'repo_name': 'chromium' 178 'repo_name': 'chromium'
177 } 179 }
178 } 180 }
179 } 181 }
180 182
181 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus( 183 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus(
182 analysis, result) 184 analysis, result)
183 185
184 self.assertEqual(status, result_status.FOUND_UNTRIAGED) 186 self.assertEqual(status, result_status.FOUND_UNTRIAGED)
(...skipping 14 matching lines...) Expand all
199 # In this case, heuristic analysis found the correct culprit. The try job 201 # In this case, heuristic analysis found the correct culprit. The try job
200 # result should not overwrite it. 202 # result should not overwrite it.
201 analysis = WfAnalysis.Create('m', 'b', 1) 203 analysis = WfAnalysis.Create('m', 'b', 1)
202 analysis.result_status = result_status.FOUND_CORRECT 204 analysis.result_status = result_status.FOUND_CORRECT
203 analysis.put() 205 analysis.put()
204 206
205 result = { 207 result = {
206 'culprit': { 208 'culprit': {
207 'compile': { 209 'compile': {
208 'revision': 'rev1', 210 'revision': 'rev1',
209 'commit_position': '1', 211 'commit_position': 1,
210 'url': 'url_1', 212 'url': 'url_1',
211 'repo_name': 'chromium' 213 'repo_name': 'chromium'
212 } 214 }
213 } 215 }
214 } 216 }
215 217
216 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus( 218 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus(
217 analysis, result) 219 analysis, result)
218 self.assertEqual(status, result_status.FOUND_CORRECT) 220 self.assertEqual(status, result_status.FOUND_CORRECT)
219 221
(...skipping 21 matching lines...) Expand all
241 243
242 result = {} 244 result = {}
243 245
244 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus( 246 status = identify_try_job_culprit_pipeline._GetResultAnalysisStatus(
245 analysis, result) 247 analysis, result)
246 self.assertEqual(status, result_status.NOT_FOUND_INCORRECT) 248 self.assertEqual(status, result_status.NOT_FOUND_INCORRECT)
247 249
248 def testGetSuspectedCLsForCompileTryJob(self): 250 def testGetSuspectedCLsForCompileTryJob(self):
249 heuristic_suspected_cl = { 251 heuristic_suspected_cl = {
250 'revision': 'rev1', 252 'revision': 'rev1',
251 'commit_position': '1', 253 'commit_position': 1,
252 'url': 'url_1', 254 'url': 'url_1',
253 'repo_name': 'chromium' 255 'repo_name': 'chromium',
256 'failures': {'compile': []},
257 'top_score': 5
254 } 258 }
255 259
256 compile_suspected_cl = { 260 compile_suspected_cl = {
257 'revision': 'rev2', 261 'revision': 'rev2',
258 'commit_position': '2', 262 'commit_position': 2,
259 'url': 'url_2', 263 'url': 'url_2',
260 'repo_name': 'chromium' 264 'repo_name': 'chromium'
261 } 265 }
262 266
267 try_job_type = failure_type.COMPILE
268
263 analysis = WfAnalysis.Create('m', 'b', 1) 269 analysis = WfAnalysis.Create('m', 'b', 1)
264 analysis.suspected_cls = [heuristic_suspected_cl] 270 analysis.suspected_cls = [heuristic_suspected_cl]
265 analysis.put() 271 analysis.put()
266 272
267 result = { 273 try_job_suspected_cls = {
268 'culprit': { 274 'rev2': compile_suspected_cl
269 'compile': compile_suspected_cl
270 }
271 } 275 }
272 276
277 expected_cls = [
278 heuristic_suspected_cl,
279 {
280 'revision': 'rev2',
281 'commit_position': 2,
282 'url': 'url_2',
283 'repo_name': 'chromium',
284 'failures': {'compile': []},
285 'top_score': None
286 }
287 ]
288
273 self.assertEqual( 289 self.assertEqual(
274 identify_try_job_culprit_pipeline._GetSuspectedCLs(analysis, result), 290 identify_try_job_culprit_pipeline._GetSuspectedCLs(
275 [heuristic_suspected_cl, compile_suspected_cl]) 291 analysis, try_job_type, None, try_job_suspected_cls),
292 expected_cls)
276 293
277 def testGetSuspectedCLsForTestTryJobAndHeuristicResultsSame(self): 294 def testGetSuspectedCLsForTestTryJobAndHeuristicResultsSame(self):
278 suspected_cl = { 295 suspected_cl = {
279 'revision': 'rev1', 296 'revision': 'rev1',
280 'commit_position': '1', 297 'commit_position': 1,
281 'url': 'url_1', 298 'url': 'url_1',
282 'repo_name': 'chromium' 299 'repo_name': 'chromium'
283 } 300 }
284 301
285 analysis = WfAnalysis.Create('m', 'b', 1) 302 analysis = WfAnalysis.Create('m', 'b', 1)
286 analysis.suspected_cls = [suspected_cl] 303 analysis.suspected_cls = [suspected_cl]
287 analysis.put() 304 analysis.put()
288 305
289 result = { 306 try_job_suspected_cls = {
290 'culprit': { 307 'rev1': suspected_cl
291 'compile': suspected_cl
292 }
293 } 308 }
294 309
295 self.assertEqual( 310 updated_cls = identify_try_job_culprit_pipeline._GetSuspectedCLs(
296 identify_try_job_culprit_pipeline._GetSuspectedCLs(analysis, result), 311 analysis, failure_type.TEST, None, try_job_suspected_cls)
297 [suspected_cl]) 312 self.assertEqual(updated_cls, [suspected_cl])
298 313
299 def testGetSuspectedCLsForTestTryJob(self): 314 def testGetSuspectedCLsForTestTryJob(self):
300 suspected_cl1 = { 315 suspected_cl1 = {
301 'revision': 'rev1', 316 'revision': 'rev1',
302 'commit_position': '1', 317 'commit_position': 1,
303 'url': 'url_1', 318 'url': 'url_1',
304 'repo_name': 'chromium' 319 'repo_name': 'chromium'
305 } 320 }
306 suspected_cl2 = { 321 suspected_cl2 = {
307 'revision': 'rev2', 322 'revision': 'rev2',
308 'commit_position': '2', 323 'commit_position': 2,
309 'url': 'url_2', 324 'url': 'url_2',
310 'repo_name': 'chromium' 325 'repo_name': 'chromium'
311 } 326 }
312 suspected_cl3 = { 327 suspected_cl3 = {
313 'revision': 'rev3', 328 'revision': 'rev3',
314 'commit_position': '3', 329 'commit_position': 3,
315 'url': 'url_3', 330 'url': 'url_3',
316 'repo_name': 'chromium' 331 'repo_name': 'chromium'
317 } 332 }
318 333
319 analysis = WfAnalysis.Create('m', 'b', 1) 334 analysis = WfAnalysis.Create('m', 'b', 1)
320 analysis.suspected_cls = [] 335 analysis.suspected_cls = [suspected_cl3]
321 analysis.put() 336 analysis.put()
322 337
338 try_job_suspected_cls = {
339 'rev1': suspected_cl1,
340 'rev2': suspected_cl2
341 }
342
323 result = { 343 result = {
324 'culprit': { 344 'report': {
325 'a_test': { 345 'result': {
326 'tests': { 346 'rev1': {
327 'a_test1': suspected_cl1, 347 'step1': {
328 'a_test2': suspected_cl1 348 'status': 'failed',
349 'valid': True,
350 'failures': ['test1']
351 }
352 },
353 'rev2': {
354 'step1': {
355 'status': 'failed',
356 'valid': True,
357 'failures': ['test2']
358 }
329 } 359 }
330 },
331 'b_test': {
332 'tests': {
333 'b_test1': suspected_cl2
334 }
335 },
336 'c_test': {
337 'revision': 'rev3',
338 'commit_position': '3',
339 'url': 'url_3',
340 'repo_name': 'chromium',
341 'tests': {}
342 } 360 }
343 } 361 }
344 } 362 }
345 363
346 self.assertEqual( 364 expected_cls = [
347 identify_try_job_culprit_pipeline._GetSuspectedCLs(analysis, result), 365 suspected_cl3,
348 [suspected_cl3, suspected_cl2, suspected_cl1]) 366 {
367 'revision': 'rev1',
368 'commit_position': 1,
369 'url': 'url_1',
370 'repo_name': 'chromium',
371 'failures': {
372 'step1': ['test1']
373 },
374 'top_score': None
375 },
376 {
377 'revision': 'rev2',
378 'commit_position': 2,
379 'url': 'url_2',
380 'repo_name': 'chromium',
381 'failures': {
382 'step1': ['test2']
383 },
384 'top_score': None
385 }
386 ]
387
388 cl_result = identify_try_job_culprit_pipeline._GetSuspectedCLs(
389 analysis, failure_type.TEST, result, try_job_suspected_cls)
390 self.assertEqual(cl_result, expected_cls)
349 391
350 def testGetSuspectedCLsForTestTryJobWithHeuristicResult(self): 392 def testGetSuspectedCLsForTestTryJobWithHeuristicResult(self):
351 suspected_cl = { 393 suspected_cl = {
352 'revision': 'rev1', 394 'revision': 'rev1',
353 'commit_position': '1', 395 'commit_position': 1,
354 'url': 'url_1', 396 'url': 'url_1',
355 'repo_name': 'chromium' 397 'repo_name': 'chromium',
398 'failures': {
399 'step1': ['test1']
400 },
401 'top_score': 2
356 } 402 }
357 403
358 analysis = WfAnalysis.Create('m', 'b', 1) 404 analysis = WfAnalysis.Create('m', 'b', 1)
359 analysis.suspected_cls = [suspected_cl] 405 analysis.suspected_cls = [suspected_cl]
360 analysis.put() 406 analysis.put()
361 407
362 result = { 408 result = {
363 'culprit': { 409 'report': {
364 'a_test': { 410 'result': {
365 'revision': 'rev1', 411 'rev1': {
366 'commit_position': '1', 412 'step1': {
367 'url': 'url_1', 413 'status': 'failed',
368 'repo_name': 'chromium', 414 'valid': True,
369 'tests': {} 415 'failures': ['test1']
416 }
417 }
370 } 418 }
371 } 419 }
372 } 420 }
421
373 self.assertEqual( 422 self.assertEqual(
374 identify_try_job_culprit_pipeline._GetSuspectedCLs(analysis, result), 423 identify_try_job_culprit_pipeline._GetSuspectedCLs(
424 analysis, failure_type.TEST, result, {}),
375 [suspected_cl]) 425 [suspected_cl])
376 426
377 def testIdentifyCulpritForCompileTryJobNoCulprit(self): 427 def testIdentifyCulpritForCompileTryJobNoCulprit(self):
378 master_name = 'm' 428 master_name = 'm'
379 builder_name = 'b' 429 builder_name = 'b'
380 build_number = 1 430 build_number = 1
381 try_job_id = '1' 431 try_job_id = '1'
382 432
383 try_job = WfTryJob.Create(master_name, builder_name, build_number) 433 try_job = WfTryJob.Create(master_name, builder_name, build_number)
384 try_job.put() 434 try_job.put()
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
435 analysis.put() 485 analysis.put()
436 486
437 pipeline = IdentifyTryJobCulpritPipeline() 487 pipeline = IdentifyTryJobCulpritPipeline()
438 culprit = pipeline.run( 488 culprit = pipeline.run(
439 master_name, builder_name, build_number, ['rev1'], 489 master_name, builder_name, build_number, ['rev1'],
440 failure_type.COMPILE, '1', compile_result) 490 failure_type.COMPILE, '1', compile_result)
441 491
442 expected_culprit = 'rev2' 492 expected_culprit = 'rev2'
443 expected_suspected_cl = { 493 expected_suspected_cl = {
444 'revision': 'rev2', 494 'revision': 'rev2',
445 'commit_position': '2', 495 'commit_position': 2,
446 'url': 'url_2', 496 'url': 'url_2',
447 'repo_name': 'chromium' 497 'repo_name': 'chromium'
448 } 498 }
449 expected_compile_result = { 499 expected_compile_result = {
450 'report': { 500 'report': {
451 'result': { 501 'result': {
452 'rev1': 'passed', 502 'rev1': 'passed',
453 'rev2': 'failed' 503 'rev2': 'failed'
454 } 504 }
455 }, 505 },
456 'try_job_id': try_job_id, 506 'try_job_id': try_job_id,
457 'culprit': { 507 'culprit': {
458 'compile': expected_suspected_cl 508 'compile': expected_suspected_cl
459 } 509 }
460 } 510 }
511 expected_analysis_suspected_cls = [{
512 'revision': 'rev2',
513 'commit_position': 2,
514 'url': 'url_2',
515 'repo_name': 'chromium',
516 'failures': {'compile': []},
517 'top_score': None
518 }]
461 519
520 import json
521 print json.dumps(culprit, indent=2)
462 self.assertEqual(expected_compile_result['culprit'], culprit) 522 self.assertEqual(expected_compile_result['culprit'], culprit)
463 523
464 try_job = WfTryJob.Get(master_name, builder_name, build_number) 524 try_job = WfTryJob.Get(master_name, builder_name, build_number)
465 self.assertEqual(expected_compile_result, try_job.compile_results[-1]) 525 self.assertEqual(expected_compile_result, try_job.compile_results[-1])
466 self.assertEqual(analysis_status.COMPLETED, try_job.status) 526 self.assertEqual(analysis_status.COMPLETED, try_job.status)
467 527
468 try_job_data = WfTryJobData.Get(try_job_id) 528 try_job_data = WfTryJobData.Get(try_job_id)
469 analysis = WfAnalysis.Get(master_name, builder_name, build_number) 529 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
470 self.assertEqual({'compile': expected_culprit}, try_job_data.culprits) 530 self.assertEqual({'compile': expected_culprit}, try_job_data.culprits)
471 self.assertEqual(analysis.result_status, 531 self.assertEqual(analysis.result_status,
472 result_status.FOUND_UNTRIAGED) 532 result_status.FOUND_UNTRIAGED)
473 self.assertEqual(analysis.suspected_cls, 533 self.assertEqual(analysis.suspected_cls, expected_analysis_suspected_cls)
474 [expected_suspected_cl])
475 534
476 def testIdentifyCulpritForCompileReturnNoneIfAllPassed(self): 535 def testIdentifyCulpritForCompileReturnNoneIfAllPassed(self):
477 master_name = 'm' 536 master_name = 'm'
478 builder_name = 'b' 537 builder_name = 'b'
479 build_number = 1 538 build_number = 1
480 try_job_id = '1' 539 try_job_id = '1'
481 540
482 compile_result = { 541 compile_result = {
483 'report': { 542 'report': {
484 'result': { 543 'result': {
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
536 self.assertIsNone(analysis.suspected_cls) 595 self.assertIsNone(analysis.suspected_cls)
537 596
538 def testIdentifyCulpritForTestTryJobNoTryJobResultWithHeuristicResult(self): 597 def testIdentifyCulpritForTestTryJobNoTryJobResultWithHeuristicResult(self):
539 master_name = 'm' 598 master_name = 'm'
540 builder_name = 'b' 599 builder_name = 'b'
541 build_number = 1 600 build_number = 1
542 try_job_id = '1' 601 try_job_id = '1'
543 602
544 suspected_cl = { 603 suspected_cl = {
545 'revision': 'rev1', 604 'revision': 'rev1',
546 'commit_position': '1', 605 'commit_position': 1,
547 'url': 'url_1', 606 'url': 'url_1',
548 'repo_name': 'chromium' 607 'repo_name': 'chromium'
549 } 608 }
550 609
551 WfTryJobData.Create(try_job_id).put() 610 WfTryJobData.Create(try_job_id).put()
552 try_job = WfTryJob.Create(master_name, builder_name, build_number) 611 try_job = WfTryJob.Create(master_name, builder_name, build_number)
553 try_job.status = analysis_status.RUNNING 612 try_job.status = analysis_status.RUNNING
554 try_job.put() 613 try_job.put()
555 614
556 # Heuristic analysis already provided some results. 615 # Heuristic analysis already provided some results.
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
647 pipeline = IdentifyTryJobCulpritPipeline() 706 pipeline = IdentifyTryJobCulpritPipeline()
648 culprit = pipeline.run( 707 culprit = pipeline.run(
649 master_name, builder_name, build_number, ['rev3'], failure_type.TEST, 708 master_name, builder_name, build_number, ['rev3'], failure_type.TEST,
650 '1', test_result) 709 '1', test_result)
651 710
652 expected_suspected_cl = { 711 expected_suspected_cl = {
653 'revision': 'rev3', 712 'revision': 'rev3',
654 'repo_name': 'chromium' 713 'repo_name': 'chromium'
655 } 714 }
656 715
716 expected_analysis_suspected_cls = [
717 {
718 'revision': 'rev3',
719 'repo_name': 'chromium',
720 'failures': {'a_test' : ['a_test1']},
721 'top_score': None
722 }
723 ]
724
657 expected_culprit = { 725 expected_culprit = {
658 'a_test': { 726 'a_test': {
659 'tests': { 727 'tests': {
660 'a_test1': expected_suspected_cl 728 'a_test1': expected_suspected_cl
661 } 729 }
662 } 730 }
663 } 731 }
732
664 self.assertEqual(expected_culprit, culprit) 733 self.assertEqual(expected_culprit, culprit)
665 734
666 try_job_data = WfTryJobData.Get(try_job_id) 735 try_job_data = WfTryJobData.Get(try_job_id)
667 analysis = WfAnalysis.Get(master_name, builder_name, build_number) 736 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
668 expected_culprit_data = { 737 expected_culprit_data = {
669 'a_test': { 738 'a_test': {
670 'a_test1': 'rev3' 739 'a_test1': 'rev3'
671 } 740 }
672 } 741 }
673 self.assertEqual(expected_culprit_data, try_job_data.culprits) 742 self.assertEqual(expected_culprit_data, try_job_data.culprits)
674 self.assertEqual(analysis.result_status, 743 self.assertEqual(analysis.result_status,
675 result_status.FOUND_UNTRIAGED) 744 result_status.FOUND_UNTRIAGED)
676 self.assertEqual(analysis.suspected_cls, [expected_suspected_cl]) 745 self.assertEqual(analysis.suspected_cls, expected_analysis_suspected_cls)
677 746
678 def testIdentifyCulpritForTestTryJobSuccess(self): 747 def testIdentifyCulpritForTestTryJobSuccess(self):
679 master_name = 'm' 748 master_name = 'm'
680 builder_name = 'b' 749 builder_name = 'b'
681 build_number = 1 750 build_number = 1
682 try_job_id = '1' 751 try_job_id = '1'
683 752
684 test_result = { 753 test_result = {
685 'report': { 754 'report': {
686 'result': { 755 'result': {
687 'rev1': { 756 'rev1': {
688 'a_test': { 757 'a_test': {
689 'status': 'failed', 758 'status': 'failed',
690 'valid': True, 759 'valid': True,
691 'failures': ['a_test1'] 760 'failures': ['a_test1']
692 }, 761 },
693 'b_test': { 762 'b_test': {
694 'status': 'failed', 763 'status': 'failed',
695 'valid': True, 764 'valid': True,
696 'failures': ['b_test1'] 765 'failures': ['b_test1']
697 },
698 'c_test': {
699 'status': 'passed',
700 'valid': True
701 } 766 }
702 }, 767 },
703 'rev2': { 768 'rev2': {
704 'a_test': { 769 'a_test': {
705 'status': 'failed', 770 'status': 'failed',
706 'valid': True, 771 'valid': True,
707 'failures': ['a_test1', 'a_test2'] 772 'failures': ['a_test1', 'a_test2']
708 }, 773 },
709 'b_test': { 774 'b_test': {
710 'status': 'passed', 775 'status': 'passed',
711 'valid': True 776 'valid': True
712 },
713 'c_test': {
714 'status': 'failed',
715 'valid': True,
716 'failures': []
717 } 777 }
718 } 778 }
719 } 779 }
720 }, 780 },
721 'url': 'url', 781 'url': 'url',
722 'try_job_id': try_job_id 782 'try_job_id': try_job_id
723 } 783 }
724 784
725 WfTryJobData.Create(try_job_id).put() 785 WfTryJobData.Create(try_job_id).put()
726 try_job = WfTryJob.Create(master_name, builder_name, build_number) 786 try_job = WfTryJob.Create(master_name, builder_name, build_number)
727 try_job.status = analysis_status.RUNNING 787 try_job.status = analysis_status.RUNNING
728 try_job.test_results = [test_result] 788 try_job.test_results = [test_result]
729 try_job.put() 789 try_job.put()
730 analysis = WfAnalysis.Create(master_name, builder_name, build_number) 790 analysis = WfAnalysis.Create(master_name, builder_name, build_number)
731 analysis.put() 791 analysis.put()
732 792
733 pipeline = IdentifyTryJobCulpritPipeline() 793 pipeline = IdentifyTryJobCulpritPipeline()
734 culprit = pipeline.run( 794 culprit = pipeline.run(
735 master_name, builder_name, build_number, ['rev1', 'rev2'], 795 master_name, builder_name, build_number, ['rev1', 'rev2'],
736 failure_type.TEST, '1', test_result) 796 failure_type.TEST, '1', test_result)
737 797
738 a_test1_suspected_cl = { 798 a_test1_suspected_cl = {
739 'revision': 'rev1', 799 'revision': 'rev1',
740 'commit_position': '1', 800 'commit_position': 1,
741 'url': 'url_1', 801 'url': 'url_1',
742 'repo_name': 'chromium' 802 'repo_name': 'chromium'
743 } 803 }
744 a_test2_suspected_cl = { 804 a_test2_suspected_cl = {
745 'revision': 'rev2', 805 'revision': 'rev2',
746 'commit_position': '2', 806 'commit_position': 2,
747 'url': 'url_2', 807 'url': 'url_2',
748 'repo_name': 'chromium' 808 'repo_name': 'chromium'
749 } 809 }
750 810
751 b_test1_suspected_cl = a_test1_suspected_cl 811 b_test1_suspected_cl = a_test1_suspected_cl
752 812
753 expected_test_result = { 813 expected_test_result = {
754 'report': { 814 'report': {
755 'result': { 815 'result': {
756 'rev1': { 816 'rev1': {
757 'a_test': { 817 'a_test': {
758 'status': 'failed', 818 'status': 'failed',
759 'valid': True, 819 'valid': True,
760 'failures': ['a_test1'] 820 'failures': ['a_test1']
761 }, 821 },
762 'b_test': { 822 'b_test': {
763 'status': 'failed', 823 'status': 'failed',
764 'valid': True, 824 'valid': True,
765 'failures': ['b_test1'] 825 'failures': ['b_test1']
766 },
767 'c_test': {
768 'status': 'passed',
769 'valid': True
770 } 826 }
771 }, 827 },
772 'rev2': { 828 'rev2': {
773 'a_test': { 829 'a_test': {
774 'status': 'failed', 830 'status': 'failed',
775 'valid': True, 831 'valid': True,
776 'failures': ['a_test1', 'a_test2'] 832 'failures': ['a_test1', 'a_test2']
777 }, 833 },
778 'b_test': { 834 'b_test': {
779 'status': 'passed', 835 'status': 'passed',
780 'valid': True 836 'valid': True
781 },
782 'c_test': {
783 'status': 'failed',
784 'valid': True,
785 'failures': []
786 } 837 }
787 } 838 }
788 } 839 }
789 }, 840 },
790 'url': 'url', 841 'url': 'url',
791 'try_job_id': try_job_id, 842 'try_job_id': try_job_id,
792 'culprit': { 843 'culprit': {
793 'a_test': { 844 'a_test': {
794 'tests': { 845 'tests': {
795 'a_test1': a_test1_suspected_cl, 846 'a_test1': a_test1_suspected_cl,
796 'a_test2': a_test2_suspected_cl 847 'a_test2': a_test2_suspected_cl
797 } 848 }
798 }, 849 },
799 'b_test': { 850 'b_test': {
800 'tests': { 851 'tests': {
801 'b_test1': b_test1_suspected_cl 852 'b_test1': b_test1_suspected_cl
802 } 853 }
803 },
804 'c_test': {
805 'revision': 'rev2',
806 'commit_position': '2',
807 'url': 'url_2',
808 'repo_name': 'chromium',
809 'tests': {}
810 } 854 }
811 } 855 }
812 } 856 }
813 857
814 self.assertEqual(expected_test_result['culprit'], culprit) 858 self.assertEqual(expected_test_result['culprit'], culprit)
815 859
816 try_job = WfTryJob.Get(master_name, builder_name, build_number) 860 try_job = WfTryJob.Get(master_name, builder_name, build_number)
817 self.assertEqual(expected_test_result, try_job.test_results[-1]) 861 self.assertEqual(expected_test_result, try_job.test_results[-1])
818 self.assertEqual(analysis_status.COMPLETED, try_job.status) 862 self.assertEqual(analysis_status.COMPLETED, try_job.status)
819 863
820 try_job_data = WfTryJobData.Get(try_job_id) 864 try_job_data = WfTryJobData.Get(try_job_id)
821 analysis = WfAnalysis.Get(master_name, builder_name, build_number) 865 analysis = WfAnalysis.Get(master_name, builder_name, build_number)
822 expected_culprit_data = { 866 expected_culprit_data = {
823 'a_test': { 867 'a_test': {
824 'a_test1': 'rev1', 868 'a_test1': 'rev1',
825 'a_test2': 'rev2', 869 'a_test2': 'rev2',
826 }, 870 },
827 'b_test': { 871 'b_test': {
828 'b_test1': 'rev1', 872 'b_test1': 'rev1',
873 }
874 }
875
876 expected_cls = [
877 {
878 'revision': 'rev1',
879 'commit_position': 1,
880 'url': 'url_1',
881 'repo_name': 'chromium',
882 'failures': {
883 'a_test': ['a_test1'],
884 'b_test': ['b_test1'],
885 },
886 'top_score': None
829 }, 887 },
830 'c_test': 'rev2' 888 {
889 'revision': 'rev2',
890 'commit_position': 2,
891 'url': 'url_2',
892 'repo_name': 'chromium',
893 'failures': {
894 'a_test': ['a_test1', 'a_test2']
895 },
896 'top_score': None
831 } 897 }
898 ]
832 self.assertEqual(expected_culprit_data, try_job_data.culprits) 899 self.assertEqual(expected_culprit_data, try_job_data.culprits)
833 self.assertEqual(analysis.result_status, 900 self.assertEqual(analysis.result_status,
834 result_status.FOUND_UNTRIAGED) 901 result_status.FOUND_UNTRIAGED)
835 self.assertEqual(analysis.suspected_cls, 902 self.assertEqual(analysis.suspected_cls, expected_cls)
836 [a_test2_suspected_cl, a_test1_suspected_cl])
837 903
838 def testAnalysisIsUpdatedOnlyIfStatusOrSuspectedCLsChanged(self): 904 def testAnalysisIsUpdatedOnlyIfStatusOrSuspectedCLsChanged(self):
839 master_name = 'm' 905 master_name = 'm'
840 builder_name = 'b' 906 builder_name = 'b'
841 build_number = 1 907 build_number = 1
842 try_job_id = '1' 908 try_job_id = '1'
909 repo_name = 'chromium'
910 revision = 'rev1'
911 commit_position = 1
843 912
844 suspected_cl = { 913 heuristic_suspected_cl = {
845 'revision': 'rev1', 914 'revision': revision,
846 'commit_position': '1', 915 'commit_position': commit_position,
847 'url': 'url_1', 916 'url': 'url_1',
848 'repo_name': 'chromium' 917 'repo_name': repo_name
849 } 918 }
850 919
851 analysis = WfAnalysis.Create(master_name, builder_name, build_number) 920 analysis = WfAnalysis.Create(master_name, builder_name, build_number)
852 analysis.suspected_cls = [suspected_cl] 921 analysis.suspected_cls = [heuristic_suspected_cl]
853 analysis.result_status = result_status.FOUND_UNTRIAGED 922 analysis.result_status = result_status.FOUND_UNTRIAGED
854 analysis.put() 923 analysis.put()
855 version = analysis.version 924 version = analysis.version
925
926 build_key = '%s/%s/%d' % (master_name, builder_name, build_number)
927 suspected_cl = WfSuspectedCL.Create(repo_name, revision, commit_position)
928 suspected_cl.approach = analysis_approach_type.HEURISTIC
929 suspected_cl.builds = {
930 build_key: {
931 'approach': analysis_approach_type.HEURISTIC,
932 'failure_type':failure_type.COMPILE,
933 'failures': {'compile':[]},
934 'status': None,
935 'top_score': 4
936 }
937 }
938 suspected_cl.put()
939
856 compile_result = { 940 compile_result = {
857 'report': { 941 'report': {
858 'result': { 942 'result': {
859 'rev1': 'failed', 943 revision: 'failed',
860 }, 944 },
861 }, 945 },
862 } 946 }
863 947
864 try_job_data = WfTryJobData.Create(try_job_id) 948 try_job_data = WfTryJobData.Create(try_job_id)
865 try_job_data.put() 949 try_job_data.put()
866 950
867 try_job = WfTryJob.Create(master_name, builder_name, build_number) 951 try_job = WfTryJob.Create(master_name, builder_name, build_number)
868 try_job.status = analysis_status.RUNNING 952 try_job.status = analysis_status.RUNNING
869 try_job.compile_results = [{ 953 try_job.compile_results = [{
870 'report': { 954 'report': {
871 'result': { 955 'result': {
872 'rev1': 'failed', 956 revision: 'failed',
873 }, 957 },
874 }, 958 },
875 'try_job_id': try_job_id, 959 'try_job_id': try_job_id,
876 }] 960 }]
877 961
878 try_job.put() 962 try_job.put()
879 963
880 pipeline = IdentifyTryJobCulpritPipeline() 964 pipeline = IdentifyTryJobCulpritPipeline()
881 pipeline.run(master_name, builder_name, build_number, ['rev1'], 965 pipeline.run(master_name, builder_name, build_number, [revision],
882 failure_type.COMPILE, '1', compile_result) 966 failure_type.COMPILE, '1', compile_result)
883 967
884 self.assertEqual(analysis.result_status, 968 self.assertEqual(analysis.result_status,
885 result_status.FOUND_UNTRIAGED) 969 result_status.FOUND_UNTRIAGED)
886 self.assertEqual(analysis.suspected_cls, [suspected_cl]) 970 self.assertEqual(analysis.suspected_cls, [heuristic_suspected_cl])
887 self.assertEqual(version, analysis.version) # No update to analysis. 971 self.assertEqual(version, analysis.version) # No update to analysis.
888 972
973 expected_builds = {
974 build_key: {
975 'approach': analysis_approach_type.BOTH,
976 'failure_type':failure_type.COMPILE,
977 'failures': {'compile':[]},
978 'status': None,
979 'top_score': 4
980 }
981 }
982 suspected_cl = WfSuspectedCL.Get(repo_name, revision)
983 self.assertEqual(analysis_approach_type.BOTH, suspected_cl.approach)
984 self.assertEqual(expected_builds, suspected_cl.builds)
985
889 def testFindCulpritForEachTestFailureRevisionNotRun(self): 986 def testFindCulpritForEachTestFailureRevisionNotRun(self):
890 blame_list = ['rev1'] 987 blame_list = ['rev1']
891 result = { 988 result = {
892 'report': { 989 'report': {
893 'result': { 990 'result': {
894 'rev2': 'passed' 991 'rev2': 'passed'
895 } 992 }
896 } 993 }
897 } 994 }
898 995
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
939 try_job = WfTryJob.Create(master_name, builder_name, build_number).put() 1036 try_job = WfTryJob.Create(master_name, builder_name, build_number).put()
940 pipeline = IdentifyTryJobCulpritPipeline() 1037 pipeline = IdentifyTryJobCulpritPipeline()
941 culprit = pipeline.run(master_name, builder_name, build_number, ['rev1'], 1038 culprit = pipeline.run(master_name, builder_name, build_number, ['rev1'],
942 failure_type.TEST, None, None) 1039 failure_type.TEST, None, None)
943 self.assertIsNone(culprit) 1040 self.assertIsNone(culprit)
944 1041
945 try_job = WfTryJob.Get(master_name, builder_name, build_number) 1042 try_job = WfTryJob.Get(master_name, builder_name, build_number)
946 self.assertEqual(try_job.test_results, []) 1043 self.assertEqual(try_job.test_results, [])
947 self.assertEqual(try_job.status, analysis_status.COMPLETED) 1044 self.assertEqual(try_job.status, analysis_status.COMPLETED)
948 1045
949
950 def testNotifyCulprits(self): 1046 def testNotifyCulprits(self):
951 instances = [] 1047 instances = []
952 class Mocked_SendNotificationForCulpritPipeline(object): 1048 class Mocked_SendNotificationForCulpritPipeline(object):
953 def __init__(self, *args): 1049 def __init__(self, *args):
954 self.args = args 1050 self.args = args
955 self.started = False 1051 self.started = False
956 instances.append(self) 1052 instances.append(self)
957 1053
958 def start(self): 1054 def start(self):
959 self.started = True 1055 self.started = True
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 self.started = True 1158 self.started = True
1063 1159
1064 self.mock( 1160 self.mock(
1065 identify_try_job_culprit_pipeline, 'SendNotificationForCulpritPipeline', 1161 identify_try_job_culprit_pipeline, 'SendNotificationForCulpritPipeline',
1066 Mocked_SendNotificationForCulpritPipeline) 1162 Mocked_SendNotificationForCulpritPipeline)
1067 1163
1068 identify_try_job_culprit_pipeline._NotifyCulprits( 1164 identify_try_job_culprit_pipeline._NotifyCulprits(
1069 master_name, builder_name, build_number, None, 1165 master_name, builder_name, build_number, None,
1070 heuristic_cls, compile_suspected_cl) 1166 heuristic_cls, compile_suspected_cl)
1071 self.assertEqual(1, len(instances)) 1167 self.assertEqual(1, len(instances))
1072 self.assertTrue(instances[0].started) 1168 self.assertTrue(instances[0].started)
1169
1170 def testGetTestFailureCausedByCLResultNone(self):
1171 self.assertIsNone(
1172 identify_try_job_culprit_pipeline._GetTestFailureCausedByCL(None))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698