| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 import re | 6 import re |
| 7 | 7 |
| 8 from google.appengine.ext import testbed | 8 from google.appengine.ext import testbed |
| 9 | 9 |
| 10 import webapp2 | 10 import webapp2 |
| 11 import webtest | 11 import webtest |
| 12 | 12 |
| 13 from handlers import build_failure | 13 from handlers import build_failure |
| 14 from handlers import handlers_util | 14 from handlers import handlers_util |
| 15 from handlers import result_status | 15 from handlers import result_status |
| 16 from model.wf_analysis import WfAnalysis | 16 from model.wf_analysis import WfAnalysis |
| 17 from model.wf_try_job import WfTryJob | 17 from model.wf_try_job import WfTryJob |
| 18 from model import analysis_status | 18 from model import analysis_status |
| 19 from model.wf_analysis import WfAnalysis | 19 from model.wf_analysis import WfAnalysis |
| 20 from waterfall import buildbot | 20 from waterfall import buildbot |
| 21 from waterfall.test import wf_testcase | 21 from waterfall.test import wf_testcase |
| 22 | 22 |
| 23 # Root directory appengine/findit. | 23 # Root directory appengine/findit. |
| 24 ROOT_DIR = os.path.join(os.path.dirname(__file__), | 24 ROOT_DIR = os.path.join(os.path.dirname(__file__), |
| 25 os.path.pardir, os.path.pardir) | 25 os.path.pardir, os.path.pardir) |
| 26 | 26 |
| 27 SAMPLE_TRY_JOB_INFO = { | 27 SAMPLE_TRY_JOB_INFO = { |
| 28 'm/b/119': { | 28 'm/b/119': { |
| 29 'step1 on platform':{ | 29 'step1 on platform': { |
| 30 'try_jobs': [ | 30 'try_jobs': [ |
| 31 { | 31 { |
| 32 'ref_name': 'step1', | 32 'ref_name': 'step1', |
| 33 'try_job_key': 'm/b/119', | 33 'try_job_key': 'm/b/119', |
| 34 'task_id': 'task1', | 34 'task_id': 'task1', |
| 35 'task_url': 'url/task1', | 35 'task_url': 'url/task1', |
| 36 'status': analysis_status.COMPLETED, | 36 'status': analysis_status.COMPLETED, |
| 37 'try_job_url': ( | 37 'try_job_url': ( |
| 38 'http://build.chromium.org/p/tryserver.chromium.' | 38 'http://build.chromium.org/p/tryserver.chromium.' |
| 39 'linux/builders/linux_variable/builds/121'), | 39 'linux/builders/linux_variable/builds/121'), |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 114 | 114 |
| 115 def setUp(self): | 115 def setUp(self): |
| 116 super(BuildFailureTest, self).setUp() | 116 super(BuildFailureTest, self).setUp() |
| 117 | 117 |
| 118 # Setup clean task queues. | 118 # Setup clean task queues. |
| 119 self.testbed.init_taskqueue_stub(root_path=ROOT_DIR) | 119 self.testbed.init_taskqueue_stub(root_path=ROOT_DIR) |
| 120 self.taskqueue_stub = self.testbed.get_stub(testbed.TASKQUEUE_SERVICE_NAME) | 120 self.taskqueue_stub = self.testbed.get_stub(testbed.TASKQUEUE_SERVICE_NAME) |
| 121 for queue in self.taskqueue_stub.GetQueues(): | 121 for queue in self.taskqueue_stub.GetQueues(): |
| 122 self.taskqueue_stub.FlushQueue(queue['name']) | 122 self.taskqueue_stub.FlushQueue(queue['name']) |
| 123 | 123 |
| 124 def MockedGetAllTryJobResults(master_name, builder_name, build_number): | 124 def MockedGetAllTryJobResults(master_name, builder_name, build_number, _): |
| 125 build_key = '%s/%s/%d' % (master_name, builder_name, build_number) | 125 build_key = '%s/%s/%d' % (master_name, builder_name, build_number) |
| 126 return SAMPLE_TRY_JOB_INFO.get(build_key, None) | 126 return SAMPLE_TRY_JOB_INFO.get(build_key, None) |
| 127 self.mock(handlers_util, 'GetAllTryJobResults', MockedGetAllTryJobResults) | 127 self.mock(handlers_util, 'GetAllTryJobResults', MockedGetAllTryJobResults) |
| 128 | 128 |
| 129 def testGetTriageHistoryWhenUserIsNotAdmin(self): | 129 def testGetTriageHistoryWhenUserIsNotAdmin(self): |
| 130 analysis = WfAnalysis.Create('m', 'b', 1) | 130 analysis = WfAnalysis.Create('m', 'b', 1) |
| 131 analysis.status = analysis_status.COMPLETED | 131 analysis.status = analysis_status.COMPLETED |
| 132 analysis.triage_history = [ | 132 analysis.triage_history = [ |
| 133 { | 133 { |
| 134 'triage_timestamp': 1438380761, | 134 'triage_timestamp': 1438380761, |
| (...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 402 ], | 402 ], |
| 403 'tests': ['test2', 'test3'] | 403 'tests': ['test2', 'test3'] |
| 404 }, | 404 }, |
| 405 { | 405 { |
| 406 'first_failure': 119, | 406 'first_failure': 119, |
| 407 'last_pass': 118, | 407 'last_pass': 118, |
| 408 'supported': True, | 408 'supported': True, |
| 409 'suspected_cls': [], | 409 'suspected_cls': [], |
| 410 'tests': ['test4'] | 410 'tests': ['test4'] |
| 411 }, | 411 }, |
| 412 { | 412 { |
| 413 'first_failure': 120, | 413 'first_failure': 120, |
| 414 'last_pass': 119, | 414 'last_pass': 119, |
| 415 'supported': True, | 415 'supported': True, |
| 416 'suspected_cls': [], | 416 'suspected_cls': [], |
| 417 'tests': ['test1', 'test5'] | 417 'tests': ['test1', 'test5'] |
| 418 } | 418 } |
| 419 ] | 419 ] |
| 420 } | 420 } |
| 421 | 421 |
| 422 updated_result = build_failure._GetAnalysisResultWithTryJobInfo( | 422 updated_result = build_failure._GetAnalysisResultWithTryJobInfo( |
| 423 organized_results, master_name, builder_name, build_number) | 423 False, organized_results, master_name, builder_name, build_number) |
| 424 | 424 |
| 425 expected_result = { | 425 expected_result = { |
| 426 'step1 on platform':{ | 426 'step1 on platform': { |
| 427 'results': { | 427 'results': { |
| 428 'reliable_failures': [ | 428 'reliable_failures': [ |
| 429 { | 429 { |
| 430 'try_job':{ | 430 'try_job': { |
| 431 'ref_name': 'step1', | 431 'ref_name': 'step1', |
| 432 'try_job_key': 'm/b/119', | 432 'try_job_key': 'm/b/119', |
| 433 'task_id': 'task1', | 433 'task_id': 'task1', |
| 434 'task_url': 'url/task1', | 434 'task_url': 'url/task1', |
| 435 'status': analysis_status.COMPLETED, | 435 'status': analysis_status.COMPLETED, |
| 436 'try_job_url': ( | 436 'try_job_url': ( |
| 437 'http://build.chromium.org/p/tryserver.chromium' | 437 'http://build.chromium.org/p/tryserver.chromium' |
| 438 '.linux/builders/linux_variable/builds/121'), | 438 '.linux/builders/linux_variable/builds/121'), |
| 439 'try_job_build_number': 121, | 439 'try_job_build_number': 121, |
| 440 'tests': ['test3'], | 440 'tests': ['test3'], |
| (...skipping 14 matching lines...) Expand all Loading... |
| 455 }, | 455 }, |
| 456 } | 456 } |
| 457 ] | 457 ] |
| 458 }, | 458 }, |
| 459 'tests': ['test3'], | 459 'tests': ['test3'], |
| 460 'first_failure': 119, | 460 'first_failure': 119, |
| 461 'last_pass': 118, | 461 'last_pass': 118, |
| 462 'supported': True | 462 'supported': True |
| 463 }, | 463 }, |
| 464 { | 464 { |
| 465 'try_job':{ | 465 'try_job': { |
| 466 'ref_name': 'step1', | 466 'ref_name': 'step1', |
| 467 'try_job_key': 'm/b/119', | 467 'try_job_key': 'm/b/119', |
| 468 'task_id': 'task1', | 468 'task_id': 'task1', |
| 469 'task_url': 'url/task1', | 469 'task_url': 'url/task1', |
| 470 'status': analysis_status.COMPLETED, | 470 'status': analysis_status.COMPLETED, |
| 471 'try_job_url': ( | 471 'try_job_url': ( |
| 472 'http://build.chromium.org/p/tryserver.chromium' | 472 'http://build.chromium.org/p/tryserver.chromium' |
| 473 '.linux/builders/linux_variable/builds/121'), | 473 '.linux/builders/linux_variable/builds/121'), |
| 474 'try_job_build_number': 121, | 474 'try_job_build_number': 121, |
| 475 'culprit': { | 475 'culprit': { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 496 ] | 496 ] |
| 497 }, | 497 }, |
| 498 'tests': ['test2'], | 498 'tests': ['test2'], |
| 499 'first_failure': 119, | 499 'first_failure': 119, |
| 500 'last_pass': 118, | 500 'last_pass': 118, |
| 501 'supported': True | 501 'supported': True |
| 502 } | 502 } |
| 503 ], | 503 ], |
| 504 'flaky_failures': [ | 504 'flaky_failures': [ |
| 505 { | 505 { |
| 506 'try_job':{ | 506 'try_job': { |
| 507 'ref_name': 'step1', | 507 'ref_name': 'step1', |
| 508 'try_job_key': 'm/b/119', | 508 'try_job_key': 'm/b/119', |
| 509 'status': result_status.FLAKY, | 509 'status': result_status.FLAKY, |
| 510 'task_id': 'task1', | 510 'task_id': 'task1', |
| 511 'task_url': 'url/task1', | 511 'task_url': 'url/task1', |
| 512 'tests': ['test4'] | 512 'tests': ['test4'] |
| 513 }, | 513 }, |
| 514 'heuristic_analysis': { | 514 'heuristic_analysis': { |
| 515 'suspected_cls': [] | 515 'suspected_cls': [] |
| 516 }, | 516 }, |
| 517 'tests': ['test4'], | 517 'tests': ['test4'], |
| 518 'first_failure': 119, | 518 'first_failure': 119, |
| 519 'last_pass': 118, | 519 'last_pass': 118, |
| 520 'supported': True | 520 'supported': True |
| 521 } | 521 } |
| 522 ], | 522 ], |
| 523 'unclassified_failures': [ | 523 'unclassified_failures': [ |
| 524 { | 524 { |
| 525 'try_job':{ | 525 'try_job': { |
| 526 'ref_name': 'step1', | 526 'ref_name': 'step1', |
| 527 'try_job_key': 'm/b/120', | 527 'try_job_key': 'm/b/120', |
| 528 'status': result_status.UNKNOWN, | 528 'status': result_status.UNKNOWN, |
| 529 'task_id': 'task2', | 529 'task_id': 'task2', |
| 530 'task_url': 'url/task2', | 530 'task_url': 'url/task2', |
| 531 'tests': ['test5'] | 531 'tests': ['test5'] |
| 532 }, | 532 }, |
| 533 'heuristic_analysis': { | 533 'heuristic_analysis': { |
| 534 'suspected_cls': [] | 534 'suspected_cls': [] |
| 535 }, | 535 }, |
| 536 'tests': ['test5'], | 536 'tests': ['test5'], |
| 537 'first_failure': 120, | 537 'first_failure': 120, |
| 538 'last_pass': 119, | 538 'last_pass': 119, |
| 539 'supported': True | 539 'supported': True |
| 540 }, | 540 }, |
| 541 { | 541 { |
| 542 'try_job':{ | 542 'try_job': { |
| 543 'ref_name': 'step1', | 543 'ref_name': 'step1', |
| 544 'try_job_key': 'm/b/120', | 544 'try_job_key': 'm/b/120', |
| 545 'status': result_status.NO_TRY_JOB_REASON_MAP[ | 545 'status': result_status.NO_TRY_JOB_REASON_MAP[ |
| 546 analysis_status.PENDING], | 546 analysis_status.PENDING], |
| 547 'task_id': 'task2', | 547 'task_id': 'task2', |
| 548 'task_url': 'url/task2', | 548 'task_url': 'url/task2', |
| 549 'tests': ['test1'] | 549 'tests': ['test1'] |
| 550 }, | 550 }, |
| 551 'heuristic_analysis': { | 551 'heuristic_analysis': { |
| 552 'suspected_cls': [] | 552 'suspected_cls': [] |
| 553 }, | 553 }, |
| 554 'tests': ['test1'], | 554 'tests': ['test1'], |
| 555 'first_failure': 120, | 555 'first_failure': 120, |
| 556 'last_pass': 119, | 556 'last_pass': 119, |
| 557 'supported': True | 557 'supported': True |
| 558 } | 558 } |
| 559 ] | 559 ] |
| 560 } | 560 } |
| 561 } | 561 } |
| 562 } | 562 } |
| 563 | 563 |
| 564 self.assertEqual(expected_result, updated_result) | 564 self.assertEqual(expected_result, updated_result) |
| 565 | 565 |
| 566 def testGetAnalysisResultWithTryJobInfoNoTryJobInfo(self): | 566 def testGetAnalysisResultWithTryJobInfoNoTryJobInfo(self): |
| 567 organized_results = { | 567 organized_results = { |
| 568 'step1 on platform':{} | 568 'step1 on platform': {} |
| 569 } | 569 } |
| 570 result = build_failure._GetAnalysisResultWithTryJobInfo( | 570 result = build_failure._GetAnalysisResultWithTryJobInfo( |
| 571 organized_results, 'n', 'b', 120) | 571 False, organized_results, 'n', 'b', 120) |
| 572 self.assertEqual({}, result) | 572 self.assertEqual({}, result) |
| 573 | 573 |
| 574 def testGetAnalysisResultWithTryJobInfoCompile(self): | 574 def testGetAnalysisResultWithTryJobInfoCompile(self): |
| 575 organized_results = { | 575 organized_results = { |
| 576 'compile': [ | 576 'compile': [ |
| 577 { | 577 { |
| 578 'first_failure': 120, | 578 'first_failure': 120, |
| 579 'last_pass': 119, | 579 'last_pass': 119, |
| 580 'supported': True, | 580 'supported': True, |
| 581 'suspected_cls': [ | 581 'suspected_cls': [ |
| 582 { | 582 { |
| 583 'build_number': 120, | 583 'build_number': 120, |
| 584 'repo_name': 'chromium', | 584 'repo_name': 'chromium', |
| 585 'revision': 'rev2', | 585 'revision': 'rev2', |
| 586 'commit_position': None, | 586 'commit_position': None, |
| 587 'url': None, | 587 'url': None, |
| 588 'score': 2, | 588 'score': 2, |
| 589 'hints': { | 589 'hints': { |
| 590 'modified f99_2.cc (and it was in log)': 2, | 590 'modified f99_2.cc (and it was in log)': 2, |
| 591 }, | 591 }, |
| 592 } | 592 } |
| 593 ], | 593 ], |
| 594 'tests': [] | 594 'tests': [] |
| 595 } | 595 } |
| 596 ] | 596 ] |
| 597 } | 597 } |
| 598 result = build_failure._GetAnalysisResultWithTryJobInfo( | 598 result = build_failure._GetAnalysisResultWithTryJobInfo( |
| 599 organized_results, 'm', 'b', 120) | 599 False, organized_results, 'm', 'b', 120) |
| 600 | 600 |
| 601 expected_result = { | 601 expected_result = { |
| 602 'compile':{ | 602 'compile': { |
| 603 'results': { | 603 'results': { |
| 604 'reliable_failures': [ | 604 'reliable_failures': [ |
| 605 { | 605 { |
| 606 'try_job': { | 606 'try_job': { |
| 607 'try_job_key': 'm/b/120', | 607 'try_job_key': 'm/b/120', |
| 608 'status': analysis_status.COMPLETED, | 608 'status': analysis_status.COMPLETED, |
| 609 'try_job_build_number': 120, | 609 'try_job_build_number': 120, |
| 610 'try_job_url': ( | 610 'try_job_url': ( |
| 611 'http://build.chromium.org/p/tryserver.chromium' | 611 'http://build.chromium.org/p/tryserver.chromium' |
| 612 '.linux/builders/linux_variable/builds/120'), | 612 '.linux/builders/linux_variable/builds/120'), |
| 613 'culprit': { | 613 'culprit': { |
| 614 'revision': 'rev2', | 614 'revision': 'rev2', |
| 615 'commit_position': '2', | 615 'commit_position': '2', |
| 616 'review_url': 'url_2' | 616 'review_url': 'url_2' |
| 617 } | 617 } |
| 618 }, | 618 }, |
| 619 'heuristic_analysis': { | 619 'heuristic_analysis': { |
| 620 'suspected_cls': [ | 620 'suspected_cls': [ |
| 621 { | 621 { |
| 622 'build_number': 120, | 622 'build_number': 120, |
| 623 'repo_name': 'chromium', | 623 'repo_name': 'chromium', |
| 624 'revision': 'rev2', | 624 'revision': 'rev2', |
| 625 'commit_position': None, | 625 'commit_position': None, |
| 626 'url': None, | 626 'url': None, |
| 627 'score': 2, | 627 'score': 2, |
| 628 'hints': {('modified f99_2.cc ' | 628 'hints': { |
| 629 '(and it was in log)'): 2 | 629 ('modified f99_2.cc ' |
| 630 '(and it was in log)'): 2 |
| 630 }, | 631 }, |
| 631 } | 632 } |
| 632 ] | 633 ] |
| 633 }, | 634 }, |
| 634 'tests': [], | 635 'tests': [], |
| 635 'first_failure': 120, | 636 'first_failure': 120, |
| 636 'last_pass': 119, | 637 'last_pass': 119, |
| 637 'supported': True | 638 'supported': True |
| 638 } | 639 } |
| 639 ] | 640 ] |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 761 }, | 762 }, |
| 762 'failed': False, | 763 'failed': False, |
| 763 } | 764 } |
| 764 | 765 |
| 765 build_url = buildbot.CreateBuildUrl('m', 'b', 123) | 766 build_url = buildbot.CreateBuildUrl('m', 'b', 123) |
| 766 response = self.test_app.get('/build-failure', | 767 response = self.test_app.get('/build-failure', |
| 767 params={'url': build_url, 'format': 'json'}) | 768 params={'url': build_url, 'format': 'json'}) |
| 768 | 769 |
| 769 self.assertEquals(200, response.status_int) | 770 self.assertEquals(200, response.status_int) |
| 770 self.assertEqual(expected_try_job_result, response.json_body['try_job']) | 771 self.assertEqual(expected_try_job_result, response.json_body['try_job']) |
| OLD | NEW |