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