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 3# found in the LICENSE file. 4 5import json 6import re 7import unittest 8 9import mock 10import webapp2 11import webtest 12 13from dashboard import buildbucket_job_status 14from dashboard import testing_common 15 16 17SAMPLE_RESPONSE = r"""{ 18 "build": { 19 "status": "COMPLETED", 20 "created_ts": "1430771172999340", 21 "url": "http://build.chromium.org/p/tryserver.chromium.perf/builders\ 22/linux_perf_bisector/builds/32", 23 "bucket": "master.tryserver.chromium.perf", 24 "result_details_json": "{\"properties\": {\ 25\"got_nacl_revision\": \"660eb1e1c91349b53f0d60bbf9a92e31f4cf4e1d\", \ 26\"got_swarming_client_revision\": \ 27\"f222001cc23c7cdb574bf4cfb447f65c94bc6da3\", \ 28\"got_revision\": \"d558f46c34085abfc9f59824fdc3466f45c40152\", \ 29\"build_url\": \"gs://chrome-perf/Linux Bisector\", \ 30\"recipe\": \"bisect\", \ 31\"got_webrtc_revision_cp\": \"refs/heads/master@{#9128}\", \ 32\"got_webkit_revision_git\": \"44bf01091874592828070dc26cbb5189da9b959b\", \ 33\"append_deps_patch_sha\": true, \ 34\"project\": \"\", \ 35\"got_webkit_revision\": 194864, \ 36\"slavename\": \"build74-m4\", \ 37\"got_revision_cp\": \"refs/heads/master@{#328178}\", \ 38\"blamelist\": [], \ 39\"branch\": \"\", \ 40\"revision\": \"\", \ 41\"workdir\": \"/b/build/slave/linux_perf_bisector\", \ 42\"repository\": \"\", \ 43\"buildername\": \"linux_perf_bisector\", \ 44\"got_webrtc_revision\": \"0d778c6af22767e9bcc92a278da08b5f82885977\", \ 45\"mastername\": \"tryserver.chromium.perf\", \ 46\"got_v8_revision\": \"a06f1b4e013812cc7ad1d52a0ea49206cafa7b67\", \ 47\"got_v8_revision_cp\": \"refs/heads/4.4.50@{#1}\", \ 48\"buildbotURL\": \"http://build.chromium.org/p/tryserver.chromium.perf/\", \ 49\"bisect_config\": {\"good_revision\": \"328111\", \ 50\"builder_host\": null, \ 51\"metric\": \"record_time/record_time\", \ 52\"max_time_minutes\": \"20\", \ 53\"builder_port\": null, \ 54\"bug_id\": null, \ 55\"command\": \"src/tools/perf/run_benchmark -v --browser=release \ 56rasterize_and_record_micro.key_mobile_sites_smooth\", \ 57\"repeat_count\": \"20\", \ 58\"test_type\": \"perf\", \ 59\"gs_bucket\": \"chrome-perf\", \ 60\"bad_revision\": \"328115\"}, \ 61\"got_webkit_revision_cp\": \"refs/heads/master@{#194864}\", \ 62\"buildnumber\": 32, \ 63\"requestedAt\": 1430771180}}", 64 "status_changed_ts": "1430771433288620", 65 "created_by": "user:425761728072-pa1bs18esuhp2cp2qfa1u9vb6p1v6kfu\ 66@developer.gserviceaccount.com", 67 "failure_reason": "BUILD_FAILURE", 68 "result": "FAILURE", 69 "utcnow_ts": "1430863009872910", 70 "id": "9046721402459257808", 71 "parameters_json": "{\"builder_name\": \"linux_perf_bisector\", \ 72\"properties\": {\"bisect_config\": {\"bad_revision\": \"328115\", \ 73\"bug_id\": null, \ 74\"builder_host\": null, \ 75\"builder_port\": null, \ 76\"command\": \"src/tools/perf/run_benchmark -v --browser=release \ 77rasterize_and_record_micro.key_mobile_sites_smooth\", \ 78\"good_revision\": \"328111\", \ 79\"gs_bucket\": \"chrome-perf\", \ 80\"max_time_minutes\": \"20\", \ 81\"metric\": \"record_time/record_time\", \ 82\"repeat_count\": \"20\", \ 83\"test_type\": \"perf\"}}}", 84 "completed_ts": "1430771433288680", 85 "updated_ts": "1430771433288850" 86 }, 87 "kind": "buildbucket#resourcesItem", 88 "etag": "\"mWAxLWqIHM8gXvavjiTVUApk92U/AaU08KGmhFQcdRWOCVgNYJBBlgI\"" 89}""".replace('\\\n', '') 90 91SAMPLE_RESPONSE_NOT_FOUND = r"""{ 92 "error": { 93 "message": "", 94 "reason": "BUILD_NOT_FOUND" 95 }, 96 "kind": "buildbucket#resourcesItem", 97 "etag": "\"mWAxLWqIHM8gXvavjiTVUApk92U/vcsTyxWNZoEnszG8qWqlQLOhpl8\"" 98}""" 99 100 101class BuildbucketJobStatusTest(testing_common.TestCase): 102 103 def setUp(self): 104 super(BuildbucketJobStatusTest, self).setUp() 105 app = webapp2.WSGIApplication( 106 [(r'/buildbucket_job_status/(\d+)', 107 buildbucket_job_status.BuildbucketJobStatusHandler)]) 108 self.testapp = webtest.TestApp(app) 109 110 @mock.patch.object( 111 buildbucket_job_status.buildbucket_service, 'GetJobStatus', 112 mock.MagicMock(return_value=json.loads(SAMPLE_RESPONSE))) 113 def testGet_ExistingJob(self): 114 response = self.testapp.get('/buildbucket_job_status/9046721402459257808') 115 # Verify that a human-readable creation time is presented. We check for the 116 # minute:second string to avoid localization from breaking this test. 117 self.assertIn('26:12', response.body) 118 # Verify that both the good and bad revisions are displayed somewhere. 119 self.assertIn('328115', response.body) 120 self.assertIn('328111', response.body) 121 # Verify that a link to buildbot is provided somewhere. 122 self.assertTrue( 123 re.search('href\\s*=\\s*[\'"]http://build.chromium.org/p/tryserver', 124 response.body, re.IGNORECASE)) 125 126 @mock.patch.object( 127 buildbucket_job_status.buildbucket_service, 'GetJobStatus', 128 mock.MagicMock(return_value=json.loads(SAMPLE_RESPONSE_NOT_FOUND))) 129 def testGet_JobNotFound(self): 130 response = self.testapp.get('/buildbucket_job_status/9046721402459257808') 131 # If the error code is shown somewhere in the page and no exception is 132 # raised, that's good enough. 133 self.assertIn('BUILD_NOT_FOUND', response) 134 135 136if __name__ == '__main__': 137 unittest.main() 138