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

Unified Diff: dashboard/dashboard/update_bug_with_results_test.py

Issue 1566013002: Add support for bisect bots to post results to dashboard. (Closed) Base URL: https://github.com/catapult-project/catapult.git@master
Patch Set: rebase Created 4 years, 10 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « dashboard/dashboard/update_bug_with_results.py ('k') | dashboard/dashboard/utils.py » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: dashboard/dashboard/update_bug_with_results_test.py
diff --git a/dashboard/dashboard/update_bug_with_results_test.py b/dashboard/dashboard/update_bug_with_results_test.py
index 67a3ad1f882a21e7726e0327147caaa358e704f4..14b7ca18241e1c330ba1db20620cf1dfa7d5acb6 100644
--- a/dashboard/dashboard/update_bug_with_results_test.py
+++ b/dashboard/dashboard/update_bug_with_results_test.py
@@ -1,7 +1,9 @@
-# Copyright 2015 The Chromium Authors. All rights reserved.
+# Copyright 2016 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+import copy
+import datetime
import json
import unittest
@@ -21,183 +23,52 @@ from dashboard.models import anomaly
from dashboard.models import bug_data
from dashboard.models import try_job
-# TODO(qyearsley): Shorten this module.
-# See https://github.com/catapult-project/catapult/issues/1917
-# pylint: disable=too-many-lines
-
-# Bisect log with multiple potential culprits with different authors.
-_BISECT_LOG_MULTI_OWNER = """
-@@@STEP_CURSOR Results@@@
-@@@STEP_STARTED@@@
-
-===== BISECT JOB RESULTS =====
-Status: Positive
-
-Test Command: python tools/perf/run_benchmark -v --browser=release sunspider
-Test Metric: Total/Total
-Relative Change: 1.23% (+/-1.26%)
-Estimated Confidence: 99.9%
-
-===== SUSPECTED CL(s) =====
-Subject : Subject 1
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Date : Sat, 22 Jun 2013 00:59:35 +0000
-
-Subject : Subject 2
-Author : prasadv, prasadv@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Date : Sat, 22 Jun 2013 00:57:48 +0000
-
-Subject : Subject 3
-Author : qyearsley@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Date : Sat, 22 Jun 2013 00:55:52 +0000
-"""
-
-# Bisect log with multiple potential culprits but same Author.
-_BISECT_LOG_MULTI_SAME_OWNER = """
-@@@STEP_CURSOR Results@@@
-@@@STEP_STARTED@@@
-
-===== BISECT JOB RESULTS =====
-Status: Positive
-
-Test Command: python tools/perf/run_benchmark -v --browser=release sunspider
-Test Metric: Total/Total
-Relative Change: 1.23% (+/-1.26%)
-Estimated Confidence: 99.9%
-
-===== SUSPECTED CL(s) =====
-Subject : Subject 1
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Date : Sat, 22 Jun 2013 00:59:35 +0000
-
-Subject : Subject 2
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Date : Sat, 22 Jun 2013 00:57:48 +0000:55:52 +0000
-"""
-
-# Bisect log with single potential culprits.
-_BISECT_LOG_SINGLE_OWNER = """
-@@@STEP_CURSOR Results@@@
-@@@STEP_STARTED@@@
-
-===== BISECT JOB RESULTS =====
-Status: Positive
-
-Test Command: python tools/perf/run_benchmark -v --browser=release sunspider
-Test Metric: Total/Total
-Relative Change: 1.23% (+/-1.26%)
-Estimated Confidence: 100%
-
-===== SUSPECTED CL(s) =====
-Subject : Subject 1
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Commit : d6432657771a9fd720179d8c3dd64c8daee025c7
-Date : Sat, 22 Jun 2013 00:59:35 +0000
-"""
-
-_EXPECTED_BISECT_LOG_SINGLE_OWNER = """
-
-===== BISECT JOB RESULTS =====
-Status: Positive
-
-Test Command: python tools/perf/run_benchmark -v --browser=release sunspider
-Test Metric: Total/Total
-Relative Change: 1.23% (+/-1.26%)
-Estimated Confidence: 100%
-
-===== SUSPECTED CL(s) =====
-Subject : Subject 1
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Commit : d6432657771a9fd720179d8c3dd64c8daee025c7
-Date : Sat, 22 Jun 2013 00:59:35 +0000"""
-
-_EXPECTED_BISECT_RESULTS_ON_BUG = """
-==== Auto-CCing suspected CL author sullivan@google.com ====
-
-Hi sullivan@google.com, the bisect results pointed to your CL below as possibly
-causing a regression. Please have a look at this info and see whether
-your CL be related.
-
-Bisect job status: Completed
-Bisect job ran on: win_perf_bisect
-
-
-
-===== BISECT JOB RESULTS =====
-Status: Positive
-
-Test Command: python tools/perf/run_benchmark -v --browser=release sunspider
-Test Metric: Total/Total\nRelative Change: 1.23% (+/-1.26%)
-Estimated Confidence: 100%
-
-===== SUSPECTED CL(s) =====
-Subject : Subject 1
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20798
-Commit : d6432657771a9fd720179d8c3dd64c8daee025c7
-Date : Sat, 22 Jun 2013 00:59:35 +0000
-
-Buildbot stdio: http://build.chromium.org/513
-Job details: https://test-rietveld.appspot.com/200037
-"""
-
-_BISECT_LOG_FAILED_REVISION = """
-@@@STEP_CURSOR Results@@@
-@@@STEP_STARTED@@@
-
-===== BISECT JOB RESULTS =====
-Status: Positive
-
-Test Command: python tools/perf/run_benchmark -v --browser=release sunspider
-Test Metric: Total/Total
-Relative Change: 1.23% (+/-1.26%)
-Estimated Confidence: 99.9%
-
-===== SUSPECTED CL(s) =====
-Subject : Subject 1
-Author : sullivan@google.com
-Link : http://src.chromium.org/viewvc/chrome?view=revision&revision=20799
-Commit : a80773bb263a9706cc8ee4e3f336d2d3d28fadd8
-Date : Sat, 22 Jun 2013 00:59:35 +0000
-"""
-
-_BISECT_LOG_PARTIAL_RESULT = """
-===== PARTIAL RESULTS =====
-Depot Commit SHA Mean Std. Error State
-chromium 282472 91730.00 +-0.00 Bad
-
-chromium 282469 92973.00 +-0.00 Good
-chromium 282460 93468.00 +-0.00 Good
-
-
-"""
-
-_EXPECTED_BISECT_LOG_PARTIAL_RESULT = u"""Bisect job status: Failure with \
-partial results
-Bisect job ran on: win_perf_bisect
-
-Completed 1/2 builds.
-Run time: 724/720 minutes.
-Bisect timed out! Try again with a smaller revision range.
-Failed steps: slave_steps, Working on def
-
-===== PARTIAL RESULTS =====
-Depot Commit SHA Mean Std. Error State
-chromium 282472 91730.00 +-0.00 Bad
-
-chromium 282469 92973.00 +-0.00 Good
-chromium 282460 93468.00 +-0.00 Good
-
-Buildbot stdio: http://build.chromium.org/builders/515
-Job details: https://test-rietveld.appspot.com/200039
-"""
+_SAMPLE_BISECT_RESULTS_JSON = {
+ 'try_job_id': 6789,
+ 'bug_id': 4567,
+ 'status': 'completed',
+ 'bisect_bot': 'linux',
+ 'buildbot_log_url': '',
+ 'command': ('tools/perf/run_benchmark -v '
+ '--browser=release page_cycler.intl_ar_fa_he'),
+ 'metric': 'warm_times/page_load_time',
+ 'change': '',
+ 'score': 99.9,
+ 'good_revision': '306475',
+ 'bad_revision': '306478',
+ 'warnings': None,
+ 'abort_reason': None,
+ 'issue_url': 'https://issue_url/123456',
+ 'culprit_data': {
+ 'subject': 'subject',
+ 'author': 'author',
+ 'email': 'author@email.com',
+ 'cl_date': '1/2/2015',
+ 'commit_info': 'commit_info',
+ 'revisions_links': ['http://src.chromium.org/viewvc/chrome?view='
+ 'revision&revision=20798'],
+ 'cl': '123'
+ },
+ 'revision_data': [
+ {
+ 'depot_name': 'chromium',
+ 'deps_revision': 1234,
+ 'commit_pos': 1234,
+ 'mean_value': 70,
+ 'std_dev': 0,
+ 'values': [70, 70, 70],
+ 'result': 'good'
+ }, {
+ 'depot_name': 'chromium',
+ 'deps_revision': 1235,
+ 'commit_pos': 1235,
+ 'mean_value': 80,
+ 'std_dev': 0,
+ 'values': [80, 80, 80],
+ 'result': 'bad'
+ }
+ ]
+}
_REVISION_RESPONSE = """
<html xmlns=....>
@@ -225,32 +96,6 @@ dromaeo.jslibstylejquery --profiler=trace',
'max_time_minutes': '120'
}"""
-_PERF_LOG_EXPECTED_TITLE_1 = 'With Patch - Profiler Data[0]'
-_PERF_LOG_EXPECTED_TITLE_2 = 'Without Patch - Profiler Data[0]'
-_PERF_LOG_EXPECTED_PROFILER_LINK1 = (
- 'https://console.developers.google.com/m/cloudstorage/b/chrome-telemetry/o/'
- 'profiler-file-id_0-2014-11-27_14-08-5560487.json')
-_PERF_LOG_EXPECTED_PROFILER_LINK2 = (
- 'https://console.developers.google.com/m/cloudstorage/b/chrome-telemetry/o/'
- 'profiler-file-id_0-2014-11-27_14-10-1644780.json')
-_PERF_LOG_EXPECTED_HTML_LINK = (
- 'http://storage.googleapis.com/chromium-telemetry/html-results/'
- 'results-2014-11-27_14-10-21')
-_PERF_LOG_WITH_RESULTS = """
-@@@STEP_CLOSED@@@
-
-
-@@@STEP_LINK@HTML Results@%s@@@
-
-
-@@@STEP_LINK@%s@%s@@@
-
-
-@@@STEP_LINK@%s@%s@@@
-""" % (_PERF_LOG_EXPECTED_HTML_LINK, _PERF_LOG_EXPECTED_TITLE_1,
- _PERF_LOG_EXPECTED_PROFILER_LINK1, _PERF_LOG_EXPECTED_TITLE_2,
- _PERF_LOG_EXPECTED_PROFILER_LINK2)
-
_ISSUE_RESPONSE = """
{
"description": "Issue Description.",
@@ -276,128 +121,9 @@ _ISSUE_RESPONSE = """
}
"""
-_BISECT_LOG_INFRA_FAILURE = 'Failed to produce build'
-
-# Globals that are set in mock functions and then checked in tests.
-_TEST_RECEIVED_EMAIL_RESULTS = None
-_TEST_RECEIVED_EMAIL = None
-
-
-def _MockGetJobStatus(job):
- id_to_response_map = {
- # Complete
- '1234567': {
- 'result': 'SUCCESS',
- 'result_details': {
- 'buildername': 'Fake_Bot',
- },
- 'url': 'http://build.chromium.org/bb1234567',
- 'status': 'COMPLETED',
- },
- # In progress
- '11111': {
- 'result_details': {
- 'buildername': 'Fake_Bot',
- },
- 'url': 'http://build.chromium.org/bb11111',
- 'status': 'STARTED',
- },
- # Failed
- '66666': {
- 'result': 'FAILURE',
- 'result_details': {
- 'buildername': 'Fake_Bot',
- },
- 'url': 'http://build.chromium.org/bb66666',
- 'status': 'COMPLETED',
- },
- }
- return id_to_response_map.get(str(job.buildbucket_job_id))
-
def _MockFetch(url=None):
url_to_response_map = {
- 'https://test-rietveld.appspot.com/api/200034/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '0',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/508'}]})
- ],
- 'https://test-rietveld.appspot.com/api/302304/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '2',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/509'}]})
- ],
- 'https://test-rietveld.appspot.com/api/100001/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '6',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/510'}]})
- ],
- 'https://test-rietveld.appspot.com/api/200035/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '0',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/511'}]})
- ],
- 'https://test-rietveld.appspot.com/api/200036/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '0',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/512'}]})
- ],
- 'https://test-rietveld.appspot.com/api/200037/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '0',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/513'}]})
- ],
- 'https://test-rietveld.appspot.com/api/200038/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '0',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/514'}]})
- ],
- 'https://test-rietveld.appspot.com/api/200039/1': [
- 200,
- json.dumps({'try_job_results': [{
- 'result': '0',
- 'builder': 'win_perf_bisect',
- 'url': 'http://build.chromium.org/builders/515'}]})
- ],
- 'http://build.chromium.org/json/builders/515': [
- 200,
- json.dumps({
- 'steps': [{'name': 'Working on abc', 'results': [0]},
- {'name': 'Working on def', 'results': [2]}],
- 'times': [1411501756.293642, 1411545237.89049],
- 'text': ['failed', 'slave_steps', 'failed', 'Working on def']})
- ],
- 'http://build.chromium.org/bb1234567/steps/Results/logs/stdio/text': [
- 200, _BISECT_LOG_SINGLE_OWNER
- ],
- 'http://build.chromium.org/bb66666': [
- 200,
- json.dumps({
- 'steps': [{'name': 'Working on abc', 'results': [0]},
- {'name': 'Working on def', 'results': [2]}],
- 'times': [1411501756.293642, 1411545237.89049],
- 'text': ['failed', 'slave_steps', 'failed', 'Working on def']})
- ],
- ('http://build.chromium.org/builders/bb66666'
- '/steps/Results/logs/stdio/text'): [404, ''],
- 'http://build.chromium.org/json/builders/516': [
- 200,
- json.dumps({'steps': [{'name': 'gclient', 'results': [2]}]})
- ],
'http://src.chromium.org/viewvc/chrome?view=revision&revision=20798': [
200, _REVISION_RESPONSE
],
@@ -407,43 +133,6 @@ def _MockFetch(url=None):
'https://codereview.chromium.org/api/17504006': [
200, json.dumps(json.loads(_ISSUE_RESPONSE))
],
- 'http://build.chromium.org/508/steps/Results/logs/stdio/text': [
- 200, '===== BISECT JOB RESULTS ====='
- ],
- 'http://build.chromium.org/509/steps/Results/logs/stdio/text': [
- 200, 'BISECT FAILURE! '
- ],
- 'http://build.chromium.org/511/steps/Results/logs/stdio/text': [
- 200, _BISECT_LOG_MULTI_OWNER
- ],
- 'http://build.chromium.org/512/steps/Results/logs/stdio/text': [
- 200, _BISECT_LOG_MULTI_SAME_OWNER
- ],
- 'http://build.chromium.org/513/steps/Results/logs/stdio/text': [
- 200, _BISECT_LOG_SINGLE_OWNER
- ],
- 'http://build.chromium.org/514/steps/Results/logs/stdio/text': [
- 200, _BISECT_LOG_FAILED_REVISION
- ],
- 'http://build.chromium.org/builders/515/steps/Results/logs/stdio/text': [
- 404, ''
- ],
- 'http://build.chromium.org/builders/515/steps/Working%20on%20abc/logs/'
- 'stdio/text': [
- 200, _BISECT_LOG_PARTIAL_RESULT
- ],
- 'http://build.chromium.org/builders/516/steps/slave_steps/logs/stdio/'
- 'text': [
- 200, _BISECT_LOG_INFRA_FAILURE
- ],
- 'http://build.chromium.org/508/steps/Running%20Bisection/logs/stdio/'
- 'text': [
- 200, _PERF_LOG_WITH_RESULTS
- ],
- 'http://build.chromium.org/511/steps/Running%20Bisection/logs/stdio/'
- 'text': [
- 200, ''
- ],
}
if url not in url_to_response_map:
@@ -454,21 +143,6 @@ def _MockFetch(url=None):
return testing_common.FakeResponseObject(response_code, response)
-def _MockMakeRequest(path, method): # pylint: disable=unused-argument
- url = 'https://test-rietveld.appspot.com/' + path
- return _MockFetch(url=url)
-
-
-def _MockSendPerfTryJobEmail(_, results):
- global _TEST_RECEIVED_EMAIL_RESULTS
- _TEST_RECEIVED_EMAIL_RESULTS = results
-
-
-def _MockSendMail(**kwargs):
- global _TEST_RECEIVED_EMAIL
- _TEST_RECEIVED_EMAIL = kwargs
-
-
# In this class, we patch apiclient.discovery.build so as to not make network
# requests, which are normally made when the IssueTrackerService is initialized.
@mock.patch('apiclient.discovery.build', mock.MagicMock())
@@ -501,80 +175,67 @@ class UpdateBugWithResultsTest(testing_common.TestCase):
server_url='https://test-rietveld.appspot.com',
internal_server_url='https://test-rietveld.appspot.com').put()
+ def _AddTryJob(self, bug_id, status, bot, **kwargs):
+ job = try_job.TryJob(bug_id=bug_id, status=status, bot=bot, **kwargs)
+ job.put()
+ bug_data.Bug(id=bug_id).put()
+ return job
+
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results.buildbucket_service, 'GetJobStatus',
- _MockGetJobStatus)
def testGet(self):
- # Put succeeded, failed, and not yet finished jobs in the datastore.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- try_job.TryJob(
- bug_id=54321, rietveld_issue_id=302304, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- try_job.TryJob(
- bug_id=99999, rietveld_issue_id=100001, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- try_job.TryJob(
- bug_id=77777, buildbucket_job_id='1234567', use_buildbucket=True,
- status='started', bot='win_perf').put()
- # Create bug.
- bug_data.Bug(id=12345).put()
- bug_data.Bug(id=54321).put()
- bug_data.Bug(id=99999).put()
- bug_data.Bug(id=77777).put()
+ # Put succeeded, failed, staled, and not yet finished jobs in the
+ # datastore.
+ self._AddTryJob(11111, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON)
+ staled_timestamp = (datetime.datetime.now() -
+ update_bug_with_results._STALE_TRYJOB_DELTA)
+ self._AddTryJob(22222, 'started', 'win_perf',
+ last_ran_timestamp=staled_timestamp)
+ self._AddTryJob(33333, 'failed', 'win_perf')
+ self._AddTryJob(44444, 'started', 'win_perf')
self.testapp.get('/update_bug_with_results')
pending_jobs = try_job.TryJob.query().fetch()
- # Expects a failed and not yet finished bisect job to be in datastore.
- self.assertEqual(3, len(pending_jobs))
- self.assertEqual(54321, pending_jobs[0].bug_id)
- self.assertEqual('failed', pending_jobs[0].status)
- self.assertEqual(99999, pending_jobs[1].bug_id)
- self.assertEqual(77777, pending_jobs[2].bug_id)
- self.assertEqual('started', pending_jobs[1].status)
- self.assertEqual('started', pending_jobs[2].status)
- self.assertEqual('bisect', pending_jobs[0].job_type)
- self.assertEqual('bisect', pending_jobs[1].job_type)
- self.assertEqual('bisect', pending_jobs[2].job_type)
+ # Expects no jobs to be deleted.
+ self.assertEqual(4, len(pending_jobs))
+ self.assertEqual(11111, pending_jobs[0].bug_id)
+ self.assertEqual('completed', pending_jobs[0].status)
+ self.assertEqual(22222, pending_jobs[1].bug_id)
+ self.assertEqual('staled', pending_jobs[1].status)
+ self.assertEqual(33333, pending_jobs[2].bug_id)
+ self.assertEqual('failed', pending_jobs[2].status)
+ self.assertEqual(44444, pending_jobs[3].bug_id)
+ self.assertEqual('started', pending_jobs[3].status)
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
mock.MagicMock())
def testCreateTryJob_WithoutExistingBug(self):
# Put succeeded job in the datastore.
try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
+ bug_id=12345, status='started', bot='win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON).put()
self.testapp.get('/update_bug_with_results')
pending_jobs = try_job.TryJob.query().fetch()
# Expects job to finish.
- self.assertEqual(0, len(pending_jobs))
+ self.assertEqual(1, len(pending_jobs))
+ self.assertEqual(12345, pending_jobs[0].bug_id)
+ self.assertEqual('completed', pending_jobs[0].status)
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service.IssueTrackerService,
'AddBugComment', mock.MagicMock(return_value=False))
@mock.patch('logging.error')
@@ -582,15 +243,10 @@ class UpdateBugWithResultsTest(testing_common.TestCase):
# Put a successful job and a failed job with partial results.
# Note that AddBugComment is mocked to always returns false, which
# simulates failing to post results to the issue tracker for all bugs.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- try_job.TryJob(
- bug_id=54321, rietveld_issue_id=200039, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- bug_data.Bug(id=12345).put()
- bug_data.Bug(id=54321).put()
-
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON)
+ self._AddTryJob(54321, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON)
self.testapp.get('/update_bug_with_results')
# Two errors should be logged.
@@ -606,304 +262,73 @@ class UpdateBugWithResultsTest(testing_common.TestCase):
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_BisectJobWithPartialResults(self, mock_update_bug):
- # Put failed job in the datastore.
- try_job.TryJob(
- bug_id=54321, rietveld_issue_id=200039, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- # Create bug.
- bug_data.Bug(id=54321).put()
-
- self.testapp.get('/update_bug_with_results')
-
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(1, len(pending_jobs))
- self.assertEqual('failed', pending_jobs[0].status)
- mock_update_bug.assert_called_once_with(
- 54321, _EXPECTED_BISECT_LOG_PARTIAL_RESULT, labels=None)
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service.IssueTrackerService,
'AddBugComment')
- def testGet_BisectCulpritHasMultipleAuthors_NoneCCd(self, mock_update_bug):
- # When a bisect finds multiple culprits for a perf regression,
- # owners of CLs shouldn't be cc'ed on issue update.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200035, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- bug_data.Bug(id=12345).put()
-
- self.testapp.get('/update_bug_with_results')
-
- mock_update_bug.assert_called_once_with(
- mock.ANY, mock.ANY, cc_list=[], merge_issue=None, labels=None,
- owner=None)
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(0, len(pending_jobs))
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_MultipleCulpritsSameAuthor_AssignsAuthor(self, mock_update_bug):
- # When a bisect finds multiple culprits by same Author for a perf
- # regression, owner of CLs should be cc'ed.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200036, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- bug_data.Bug(id=12345).put()
-
- self.testapp.get('/update_bug_with_results')
-
- mock_update_bug.assert_called_once_with(
- mock.ANY, mock.ANY,
- cc_list=['sullivan@google.com', 'prasadv@google.com'],
- merge_issue=None, labels=None, owner='sullivan@google.com')
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(0, len(pending_jobs))
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_BisectCulpritHasSingleAuthor_AssignsAuthor(self, mock_update_bug):
- # When a bisect finds a single culprit for a perf regression,
+ def testGet_BisectCulpritHasAuthor_AssignsAuthor(self, mock_update_bug):
+ # When a bisect has a culprit for a perf regression,
# author and reviewer of the CL should be cc'ed on issue update.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON)
- # Create bug.
- bug_data.Bug(id=12345).put()
self.testapp.get('/update_bug_with_results')
mock_update_bug.assert_called_once_with(
mock.ANY, mock.ANY,
- cc_list=['sullivan@google.com', 'prasadv@google.com'],
- merge_issue=None, labels=None, owner='sullivan@google.com')
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(0, len(pending_jobs))
-
- def testBeautifyContent(self):
- # Remove buildbot annotations (@@@), leading and trailing spaces from bisect
- # results log.
- actual_output = update_bug_with_results._BeautifyContent(
- _BISECT_LOG_SINGLE_OWNER)
- self.assertNotIn('@@@', actual_output)
- for line in actual_output.split('\n'):
- self.assertFalse(line.startswith(' '))
- self.assertFalse(line.endswith(' '))
- self.assertEqual(_EXPECTED_BISECT_LOG_SINGLE_OWNER, actual_output)
+ cc_list=['author@email.com', 'prasadv@google.com'],
+ merge_issue=None, labels=None, owner='author@email.com')
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service.IssueTrackerService,
'AddBugComment')
def testGet_FailedRevisionResponse(self, mock_add_bug):
- # When a Rietveld CL link fails to respond, only update CL owner in CC list.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200038, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
+ # When a Rietveld CL link fails to respond, only update CL owner in CC
+ # list.
+ sample_bisect_results = copy.deepcopy(_SAMPLE_BISECT_RESULTS_JSON)
+ sample_bisect_results['revisions_links'] = [
+ 'http://src.chromium.org/viewvc/chrome?view=revision&revision=20799']
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=sample_bisect_results)
- # Create bug.
- bug_data.Bug(id=12345).put()
self.testapp.get('/update_bug_with_results')
mock_add_bug.assert_called_once_with(mock.ANY,
mock.ANY,
- cc_list=['sullivan@google.com'],
+ cc_list=['author@email.com',
+ 'prasadv@google.com'],
merge_issue=None,
labels=None,
- owner='sullivan@google.com')
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(0, len(pending_jobs))
+ owner='author@email.com')
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_MergesBugIntoExistingBug(self, mock_update_bug):
- # When there exists a bug with the same revision (commit hash),
- # mark bug as duplicate and merge current issue into that.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- try_job.TryJob(
- bug_id=54321, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
-
- # Create bug.
- bug_data.Bug(id=12345).put()
- bug_data.Bug(id=54321).put()
- self.testapp.get('/update_bug_with_results')
- # Owners of CLs are not cc'ed for duplicate bugs and the issue should be
- # marked as duplicate.
- mock_update_bug.assert_called_with(mock.ANY,
- mock.ANY,
- cc_list=[],
- merge_issue='12345',
- labels=None,
- owner=None)
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(0, len(pending_jobs))
- # Add anomalies.
- test_keys = map(utils.TestKey, [
- 'ChromiumGPU/linux-release/scrolling-benchmark/first_paint',
- 'ChromiumGPU/linux-release/scrolling-benchmark/mean_frame_time'])
- anomaly.Anomaly(
- start_revision=9990, end_revision=9997, test=test_keys[0],
- median_before_anomaly=100, median_after_anomaly=200,
- sheriff=None, bug_id=12345).put()
- anomaly.Anomaly(
- start_revision=9990, end_revision=9996, test=test_keys[0],
- median_before_anomaly=100, median_after_anomaly=200,
- sheriff=None, bug_id=54321).put()
- # Map anomalies to base(dest_bug_id) bug.
- update_bug_with_results._MapAnomaliesToMergeIntoBug(
- dest_bug_id=12345, source_bug_id=54321)
- anomalies = anomaly.Anomaly.query(
- anomaly.Anomaly.bug_id == int(54321)).fetch()
- self.assertEqual(0, len(anomalies))
-
- @mock.patch.object(
update_bug_with_results.issue_tracker_service.IssueTrackerService,
'AddBugComment', mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('Status: Positive\n'
- 'Commit : abcd123\n'
- 'Author : culprit@chromium.org\n'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
def testGet_PositiveResult_StoresCommitHash(self):
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- self.testapp.get('/update_bug_with_results')
- self.assertEqual('12345', layered_cache.GetExternal('commit_hash_abcd123'))
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON)
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment', mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('Status: Negative\n'
- 'Commit : a121212\n'
- 'Author : culprit@chromium.org\n'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
- def testGet_NegativeResult_DoesNotStoreCommitHash(self):
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
self.testapp.get('/update_bug_with_results')
- self.assertIsNone(layered_cache.GetExternal('commit_hash_a121212'))
+ self.assertEqual('12345', layered_cache.GetExternal('commit_hash_123'))
+ @mock.patch(
+ 'google.appengine.api.urlfetch.fetch',
+ mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
update_bug_with_results.issue_tracker_service.IssueTrackerService,
'AddBugComment', mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('Status: Positive\n'
- 'Commit : a12\n'
- 'Commit : b23\n'
- 'Author : culprit@chromium.org\n'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
- def testGet_MultipleCommits_DoesNotStoreCommitHash(self):
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
+ def testGet_NegativeResult_DoesNotStoreCommitHash(self):
+ sample_bisect_results = copy.deepcopy(_SAMPLE_BISECT_RESULTS_JSON)
+ sample_bisect_results['culprit_data'] = None
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=sample_bisect_results)
self.testapp.get('/update_bug_with_results')
- self.assertIsNone(layered_cache.GetExternal('commit_hash_a12b23'))
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('Status: Positive\n'
- 'Commit : a121212\n'
- 'Author : culprit@chromium.org\n'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_PositiveResult_CCsAuthor(self, mock_update_bug):
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- bug_data.Bug(id=12345).put()
- self.testapp.get('/update_bug_with_results')
- mock_update_bug.assert_called_with(
- 12345, mock.ANY, cc_list=['culprit@chromium.org'],
- merge_issue=None, labels=None, owner='culprit@chromium.org')
-
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('Status: Negative\n'
- 'Commit : a121212\n'
- 'Author : culprit@chromium.org\n'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_NegativeResult_DoesNotCCAuthor(self, mock_update_bug):
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- bug_data.Bug(id=12345).put()
- self.testapp.get('/update_bug_with_results')
- mock_update_bug.assert_called_with(
- 12345, mock.ANY, cc_list=[], merge_issue=None, labels=None, owner=None)
+ caches = layered_cache.CachedPickledString.query().fetch()
+ # Only 1 cache for bisect stats.
+ self.assertEqual(1, len(caches))
def testMapAnomaliesToMergeIntoBug(self):
# Add anomalies.
@@ -929,372 +354,52 @@ class UpdateBugWithResultsTest(testing_common.TestCase):
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(update_bug_with_results, '_LogBisectInfraFailure')
- def testCheckBisectBotForInfraFailure_BotFailure(
- self, log_bisect_failure_mock):
- bug_id = 516
- build_data = {
- 'steps': [{'name': 'A', 'results': [0]},
- {'name': 'B', 'results': [2]}],
- 'times': [1411501756, 1411545237],
- }
- build_url = 'http://build.chromium.org/builders/516'
- update_bug_with_results._CheckBisectBotForInfraFailure(
- bug_id, build_data, build_url)
- log_bisect_failure_mock.assert_called_with(
- bug_id, 'Bot failure.', mock.ANY)
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(update_bug_with_results, '_LogBisectInfraFailure')
- def testCheckBisectBotForInfraFailure_BuildFailure(
- self, log_bisect_failure_mock):
- bug_id = 516
- build_data = {
- 'steps': [{'name': 'A', 'results': [0]},
- {'name': 'slave_steps', 'results': [2]}],
- 'times': [1411500000, 1411501000],
- }
- build_url = 'http://build.chromium.org/builders/516'
- update_bug_with_results._CheckBisectBotForInfraFailure(
- bug_id, build_data, build_url)
- log_bisect_failure_mock.assert_called_with(
- bug_id, 'Build failure.', mock.ANY)
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service.IssueTrackerService,
- 'AddBugComment')
- def testGet_BotInfoInBisectResults(self, mock_update_bug):
- # When a bisect finds multiple culprits by same Author for a perf
- # regression, owner of CLs should be cc'ed.
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
-
- # Create bug.
- bug_data.Bug(id=12345).put()
- self.testapp.get('/update_bug_with_results')
- mock_update_bug.assert_called_once_with(
- 12345,
- _EXPECTED_BISECT_RESULTS_ON_BUG,
- cc_list=['sullivan@google.com', 'prasadv@google.com'],
- merge_issue=None,
- labels=None,
- owner='sullivan@google.com')
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results, '_SendPerfTryJobEmail',
- mock.MagicMock(side_effect=_MockSendPerfTryJobEmail))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
- mock.MagicMock())
- def testGet_PerfTryJob(self):
- try_job.TryJob(
- rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf', email='just@atestemail.com',
- job_type='perf-try', config=_PERF_TEST_CONFIG).put()
- global _TEST_RECEIVED_EMAIL_RESULTS
- _TEST_RECEIVED_EMAIL_RESULTS = None
-
- self.testapp.get('/update_bug_with_results')
-
- results = _TEST_RECEIVED_EMAIL_RESULTS
- self.assertEqual('Completed', results['status'])
- self.assertEqual(2, len(results['profiler_results']))
- self.assertEqual(_PERF_LOG_EXPECTED_HTML_LINK,
- results['html_results'])
- self.assertEqual(_PERF_LOG_EXPECTED_TITLE_1,
- results['profiler_results'][0][0])
- self.assertEqual(_PERF_LOG_EXPECTED_PROFILER_LINK1,
- results['profiler_results'][0][1])
- self.assertEqual(_PERF_LOG_EXPECTED_TITLE_2,
- results['profiler_results'][1][0])
- self.assertEqual(_PERF_LOG_EXPECTED_PROFILER_LINK2,
- results['profiler_results'][1][1])
- self.assertEqual('win_perf_bisect', results['bisect_bot'])
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
- update_bug_with_results, '_SendPerfTryJobEmail',
- mock.MagicMock(side_effect=_MockSendPerfTryJobEmail))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
- mock.MagicMock())
- def testGet_PerfTryJobWithInvalidOutput_EmailResultsAreEmpty(self):
- try_job.TryJob(
- rietveld_issue_id=200035, rietveld_patchset_id=1,
- status='started', bot='win_perf', email='just@atestemail.com',
- job_type='perf-try', config=_PERF_TEST_CONFIG).put()
- global _TEST_RECEIVED_EMAIL_RESULTS
- _TEST_RECEIVED_EMAIL_RESULTS = None
-
- self.testapp.get('/update_bug_with_results')
-
- results = _TEST_RECEIVED_EMAIL_RESULTS
- self.assertEqual('Completed', results['status'])
- self.assertEqual(0, len(results['profiler_results']))
- self.assertEqual('', results['html_results'])
- self.assertEqual('win_perf_bisect', results['bisect_bot'])
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch(
- 'google.appengine.api.mail.send_mail',
- mock.MagicMock(side_effect=_MockSendMail))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
- mock.MagicMock())
- def testGet_CreatePerfSuccessEmail(self):
- try_job.TryJob(
- rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf', email='just@atestemail.com',
- job_type='perf-try', config=_PERF_TEST_CONFIG).put()
- global _TEST_RECEIVED_EMAIL
- _TEST_RECEIVED_EMAIL = {}
-
- self.testapp.get('/update_bug_with_results')
-
- self.assertIn('<a href="http://build.chromium.org/508">'
- 'http://build.chromium.org/508</a>.',
- _TEST_RECEIVED_EMAIL.get('html'))
- self.assertIn('With Patch', _TEST_RECEIVED_EMAIL.get('body'))
- self.assertIn('Without Patch', _TEST_RECEIVED_EMAIL.get('body'))
- self.assertIn('just@atestemail.com',
- _TEST_RECEIVED_EMAIL.get('to'))
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch(
- 'google.appengine.api.mail.send_mail',
- mock.MagicMock(side_effect=_MockSendMail))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
- mock.MagicMock())
- def testGet_CreatePerfFailureEmail(self):
- try_job.TryJob(
- rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf', email='just@atestemail.com',
- job_type='perf-try').put()
-
- global _TEST_RECEIVED_EMAIL
- _TEST_RECEIVED_EMAIL = {}
-
+ update_bug_with_results.email_template,
+ 'GetPerfTryJobEmailReport', mock.MagicMock(return_value=None))
+ def testSendPerfTryJobEmail_EmptyEmailReport_DontSendEmail(self):
+ self._AddTryJob(12345, 'started', 'win_perf', job_type='perf-try',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON)
self.testapp.get('/update_bug_with_results')
-
- self.assertIn('Perf Try Job FAILURE\n<br>',
- _TEST_RECEIVED_EMAIL.get('html'))
- self.assertIn('Perf Try Job FAILURE\n\n',
- _TEST_RECEIVED_EMAIL.get('body'))
- self.assertIn('just@atestemail.com',
- _TEST_RECEIVED_EMAIL.get('to'))
+ messages = self.mail_stub.get_sent_messages()
+ self.assertEqual(0, len(messages))
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service.IssueTrackerService,
'AddBugComment')
def testGet_InternalOnlyTryJob_AddsInternalOnlyBugLabel(
self, mock_update_bug):
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf', internal_only=True).put()
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON,
+ internal_only=True)
- # Create bug.
- bug_data.Bug(id=12345).put()
self.testapp.get('/update_bug_with_results')
mock_update_bug.assert_called_once_with(
mock.ANY, mock.ANY,
cc_list=mock.ANY,
merge_issue=None, labels=['Restrict-View-Google'], owner=mock.ANY)
- def testValidateAndConvertBuildbucketResponse_NoResults(self):
- buildbucket_response_scheduled = r"""{
- "build": {
- "status": "SCHEDULED",
- "id": "9043191319901995952"
- }
- }"""
- with self.assertRaises(update_bug_with_results.UnexpectedJsonError):
- update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- json.loads(buildbucket_response_scheduled))
-
- def testValidateAndConvertBuildbucketResponse_Failed(self):
- buildbucket_response_failed = r"""{
- "build": {
- "status": "COMPLETED",
- "url": "http://build.chromium.org/linux_perf_bisector/builds/41",
- "failure_reason": "BUILD_FAILURE",
- "result": "FAILURE",
- "id": "9043547105089652704"
- }
- }"""
- converted_response = (
- update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- json.loads(buildbucket_response_failed)))
- self.assertIn('http', converted_response['url'])
- self.assertEqual(converted_response['result'],
- update_bug_with_results.FAILURE)
-
- def testValidateAndConvertBuildbucketResponse_Success(self):
- buildbucket_response_success = r"""{
- "build": {
- "status": "COMPLETED",
- "url": "http://build.chromium.org/linux_perf_bisector/builds/47",
- "id": "9043278384371361584",
- "result": "SUCCESS"
- }
- }"""
- converted_response = (
- update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- json.loads(buildbucket_response_success)))
- self.assertIn('http', converted_response['url'])
- self.assertEqual(converted_response['result'],
- update_bug_with_results.SUCCESS)
-
- def testValidateAndConvertBuildbucketResponse_Canceled(self):
- buildbucket_response_canceled = r"""{
- "build": {
- "status": "COMPLETED",
- "cancellation_reason": "TIMEOUT",
- "id": "9043278384371361584",
- "result": "CANCELED"
- }
- }"""
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(1, len(pending_jobs))
- # Create bug.
- bug_data.Bug(id=12345).put()
- with self.assertRaises(update_bug_with_results.UnexpectedJsonError):
- update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- json.loads(buildbucket_response_canceled), pending_jobs[0])
- pending_jobs = try_job.TryJob.query(
- try_job.TryJob.status == 'failed').fetch()
- self.assertEqual(1, len(pending_jobs))
-
- def testValidateAndConvertBuildbucketResponse_InvalidConfig(self):
- buildbucket_response_canceled = r"""{
- "build": {
- "status": "COMPLETED",
- "failure_reason": "INVALID_BUILD_DEFINITION",
- "id": "9043278384371361584",
- "result": "FAILURE"
- }
- }"""
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200037, rietveld_patchset_id=1,
- status='started', bot='win_perf').put()
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(1, len(pending_jobs))
- # Create bug.
- bug_data.Bug(id=12345).put()
- with self.assertRaises(update_bug_with_results.UnexpectedJsonError):
- update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- json.loads(buildbucket_response_canceled), pending_jobs[0])
- pending_jobs = try_job.TryJob.query().fetch()
- self.assertEqual(0, len(pending_jobs))
-
- @mock.patch('logging.error')
- def testValidateAndConvertBuildbucketResponse_NoTesterInConfig(
- self, mock_logging_error):
- job_info = {
- 'build': {
- 'status': 'foo',
- 'url': 'www.baz.com',
- 'result': 'bar',
- }
- }
- result = update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- job_info)
- self.assertEqual('Unknown', result['builder'])
- self.assertEqual(1, mock_logging_error.call_count)
-
- def testValidateAndConvertBuildbucketResponse_TesterInConfig(self):
- job_info = {
- 'build': {
- 'status': 'foo',
- 'url': 'www.baz.com',
- 'result': 'bar',
- 'result_details_json': json.dumps({
- 'properties': {
- 'bisect_config': {'recipe_tester_name': 'my_perf_bisect'}
- }
- })
- }
- }
- result = update_bug_with_results._ValidateAndConvertBuildbucketResponse(
- job_info)
- self.assertEqual('my_perf_bisect', result['builder'])
-
@mock.patch(
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch.object(
update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('===== BISECT JOB RESULTS =====\n'
- 'Status: Positive\n'
- 'Commit : 2a1781d64d'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
def testFYI_Send_No_Email_On_Success(self):
stored_object.Set(
bisect_fyi._BISECT_FYI_CONFIGS_KEY,
bisect_fyi_test.TEST_FYI_CONFIGS)
test_config = bisect_fyi_test.TEST_FYI_CONFIGS['positive_culprit']
bisect_config = test_config.get('bisect_config')
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf',
- job_name='positive_culprit',
- job_type='bisect-fyi',
- config=utils.BisectConfigPythonString(bisect_config)).put()
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=_SAMPLE_BISECT_RESULTS_JSON,
+ internal_only=True,
+ config=utils.BisectConfigPythonString(bisect_config),
+ job_type='bisect-fyi',
+ job_name='positive_culprit',
+ email='chris@email.com')
self.testapp.get('/update_bug_with_results')
messages = self.mail_stub.get_sent_messages()
@@ -1304,93 +409,30 @@ class UpdateBugWithResultsTest(testing_common.TestCase):
'google.appengine.api.urlfetch.fetch',
mock.MagicMock(side_effect=_MockFetch))
@mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch(
- 'google.appengine.api.mail.send_mail',
- mock.MagicMock(side_effect=_MockSendMail))
+ update_bug_with_results.bisect_fyi, 'IsBugUpdated',
+ mock.MagicMock(return_value=True))
@mock.patch.object(
update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('===== BISECT JOB RESULTS =====\n'
- 'Status: Positive\n'
- 'Commit : a121212'),
- 'status': 'Completed',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
- def testFYI_Expected_Results_Mismatch_SendEmail(self):
- stored_object.Set(
- bisect_fyi._BISECT_FYI_CONFIGS_KEY,
- bisect_fyi_test.TEST_FYI_CONFIGS)
- test_config = bisect_fyi_test.TEST_FYI_CONFIGS['positive_culprit']
- bisect_config = test_config.get('bisect_config')
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf',
- job_name='positive_culprit',
- job_type='bisect-fyi',
- config=utils.BisectConfigPythonString(bisect_config)).put()
-
- global _TEST_RECEIVED_EMAIL
- _TEST_RECEIVED_EMAIL = None
-
- self.testapp.get('/update_bug_with_results')
- self.assertIn('<font color="red"><b>Bisect FYI Try Job Failed</b></font>',
- _TEST_RECEIVED_EMAIL.get('html'))
- self.assertIn('Bisect FYI Try Job Failed\n\n',
- _TEST_RECEIVED_EMAIL.get('body'))
- self.assertIn('auto-bisect-team@google.com',
- _TEST_RECEIVED_EMAIL.get('to'))
-
- @mock.patch(
- 'google.appengine.api.urlfetch.fetch',
- mock.MagicMock(side_effect=_MockFetch))
- @mock.patch.object(
- update_bug_with_results.rietveld_service.RietveldService, 'MakeRequest',
- mock.MagicMock(side_effect=_MockMakeRequest))
- @mock.patch(
- 'google.appengine.api.mail.send_mail',
- mock.MagicMock(side_effect=_MockSendMail))
- @mock.patch.object(
- update_bug_with_results.issue_tracker_service, 'IssueTrackerService',
- mock.MagicMock())
- @mock.patch.object(
- update_bug_with_results, '_GetBisectResults',
- mock.MagicMock(return_value={
- 'results': ('Failed to produce build.'),
- 'status': 'Failure',
- 'bisect_bot': 'bar',
- 'issue_url': 'bar',
- 'buildbot_log_url': 'bar',
- }))
def testFYI_Failed_Job_SendEmail(self):
stored_object.Set(
bisect_fyi._BISECT_FYI_CONFIGS_KEY,
bisect_fyi_test.TEST_FYI_CONFIGS)
test_config = bisect_fyi_test.TEST_FYI_CONFIGS['positive_culprit']
bisect_config = test_config.get('bisect_config')
- try_job.TryJob(
- bug_id=12345, rietveld_issue_id=200034, rietveld_patchset_id=1,
- status='started', bot='win_perf',
- job_name='positive_culprit',
- job_type='bisect-fyi',
- config=utils.BisectConfigPythonString(bisect_config)).put()
-
- global _TEST_RECEIVED_EMAIL
- _TEST_RECEIVED_EMAIL = None
+ sample_bisect_results = copy.deepcopy(_SAMPLE_BISECT_RESULTS_JSON)
+ sample_bisect_results['status'] = 'failed'
+ self._AddTryJob(12345, 'started', 'win_perf',
+ results_data=sample_bisect_results,
+ internal_only=True,
+ config=utils.BisectConfigPythonString(bisect_config),
+ job_type='bisect-fyi',
+ job_name='positive_culprit',
+ email='chris@email.com')
self.testapp.get('/update_bug_with_results')
- self.assertIn('<font color="red"><b>Bisect FYI Try Job Failed</b></font>',
- _TEST_RECEIVED_EMAIL.get('html'))
- self.assertIn('Bisect FYI Try Job Failed\n\n',
- _TEST_RECEIVED_EMAIL.get('body'))
- self.assertIn('auto-bisect-team@google.com',
- _TEST_RECEIVED_EMAIL.get('to'))
+ messages = self.mail_stub.get_sent_messages()
+ self.assertEqual(1, len(messages))
if __name__ == '__main__':
« no previous file with comments | « dashboard/dashboard/update_bug_with_results.py ('k') | dashboard/dashboard/utils.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698