OLD | NEW |
1 # Copyright 2017 The Chromium Authors. All rights reserved. | 1 # Copyright 2017 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 json | 5 import json |
6 | 6 |
7 import mock | 7 import mock |
8 import webapp2 | 8 import webapp2 |
9 import webtest | 9 import webtest |
10 | 10 |
11 from google.appengine.api import users | 11 from google.appengine.api import users |
12 | 12 |
13 from dashboard.api import api_auth | 13 from dashboard.api import api_auth |
14 from dashboard.common import namespaced_stored_object | 14 from dashboard.common import namespaced_stored_object |
15 from dashboard.common import testing_common | 15 from dashboard.common import testing_common |
16 from dashboard.common import utils | 16 from dashboard.common import utils |
17 from dashboard.services import gitiles_service | 17 from dashboard.services import gitiles_service |
18 from dashboard.pinpoint.handlers import new | 18 from dashboard.pinpoint.handlers import new |
19 from dashboard.pinpoint.models import job as job_module | 19 from dashboard.pinpoint.models import job as job_module |
20 | 20 |
21 AUTHORIZED_USER = users.User(email='authorized_person@chromium.org', | 21 |
22 _auth_domain='google.com') | 22 _AUTHORIZED_USER = users.User(email='authorized_person@chromium.org', |
23 UNAUTHORIZED_USER = users.User(email='foo@bar.com', _auth_domain='bar.com') | 23 _auth_domain='google.com') |
| 24 _UNAUTHORIZED_USER = users.User(email='foo@bar.com', _auth_domain='bar.com') |
| 25 |
| 26 |
| 27 _BASE_REQUEST = { |
| 28 'target': 'telemetry_perf_tests', |
| 29 'configuration': 'chromium-rel-mac11-pro', |
| 30 'benchmark': 'speedometer', |
| 31 'auto_explore': '1', |
| 32 'bug_id': '12345', |
| 33 'start_repository': 'src', |
| 34 'start_git_hash': '1', |
| 35 'end_repository': 'src', |
| 36 'end_git_hash': '3', |
| 37 } |
24 | 38 |
25 | 39 |
26 class NewTest(testing_common.TestCase): | 40 class NewTest(testing_common.TestCase): |
27 | 41 |
28 def setUp(self): | 42 def setUp(self): |
29 super(NewTest, self).setUp() | 43 super(NewTest, self).setUp() |
30 | 44 |
31 app = webapp2.WSGIApplication([ | 45 app = webapp2.WSGIApplication([ |
32 webapp2.Route(r'/api/new', new.New), | 46 webapp2.Route(r'/api/new', new.New), |
33 ]) | 47 ]) |
34 self.testapp = webtest.TestApp(app) | 48 self.testapp = webtest.TestApp(app) |
35 | 49 |
36 self.SetCurrentUser('internal@chromium.org', is_admin=True) | 50 self.SetCurrentUser('internal@chromium.org', is_admin=True) |
37 | 51 |
38 namespaced_stored_object.Set('repositories', { | 52 namespaced_stored_object.Set('repositories', { |
39 'catapult': {'repository_url': 'http://catapult'}, | 53 'catapult': {'repository_url': 'http://catapult'}, |
40 'src': {'repository_url': 'http://src'}, | 54 'src': {'repository_url': 'http://src'}, |
41 }) | 55 }) |
42 | 56 |
43 def _SetAuthorizedOAuth(self, mock_oauth): | 57 def _SetAuthorizedOAuth(self, mock_oauth): |
44 mock_oauth.get_current_user.return_value = AUTHORIZED_USER | 58 mock_oauth.get_current_user.return_value = _AUTHORIZED_USER |
45 mock_oauth.get_client_id.return_value = ( | 59 mock_oauth.get_client_id.return_value = ( |
46 api_auth.OAUTH_CLIENT_ID_WHITELIST[0]) | 60 api_auth.OAUTH_CLIENT_ID_WHITELIST[0]) |
47 | 61 |
48 @mock.patch.object(utils, 'IsGroupMember', mock.MagicMock(return_value=False)) | 62 @mock.patch.object(utils, 'IsGroupMember', mock.MagicMock(return_value=False)) |
49 @mock.patch.object(api_auth, 'oauth') | 63 @mock.patch.object(api_auth, 'oauth') |
50 def testPost_NoAccess_ShowsError(self, mock_oauth): | 64 def testPost_NoAccess_ShowsError(self, mock_oauth): |
51 self.SetCurrentUser('external@chromium.org') | 65 self.SetCurrentUser('external@chromium.org') |
52 mock_oauth.get_current_user.return_value = UNAUTHORIZED_USER | 66 mock_oauth.get_current_user.return_value = _UNAUTHORIZED_USER |
53 mock_oauth.get_client_id.return_value = ( | 67 mock_oauth.get_client_id.return_value = ( |
54 api_auth.OAUTH_CLIENT_ID_WHITELIST[0]) | 68 api_auth.OAUTH_CLIENT_ID_WHITELIST[0]) |
55 response = self.testapp.post('/api/new', status=200) | 69 response = self.testapp.post('/api/new', status=200) |
56 self.assertIn('error', json.loads(response.body)) | 70 self.assertIn('error', json.loads(response.body)) |
57 | 71 |
58 @mock.patch.object(api_auth, 'oauth') | 72 @mock.patch.object(api_auth, 'oauth') |
59 @mock.patch.object(api_auth, 'users') | 73 @mock.patch.object(api_auth, 'users') |
60 def testPost_NoOauthUser(self, mock_users, mock_oauth): | 74 def testPost_NoOauthUser(self, mock_users, mock_oauth): |
61 mock_users.get_current_user.return_value = None | 75 mock_users.get_current_user.return_value = None |
62 mock_oauth.get_current_user.return_value = None | 76 mock_oauth.get_current_user.return_value = None |
63 mock_oauth.get_client_id.return_value = ( | 77 mock_oauth.get_client_id.return_value = ( |
64 api_auth.OAUTH_CLIENT_ID_WHITELIST[0]) | 78 api_auth.OAUTH_CLIENT_ID_WHITELIST[0]) |
65 response = self.testapp.post('/api/new', status=200) | 79 response = self.testapp.post('/api/new', status=200) |
66 self.assertIn('error', json.loads(response.body)) | 80 self.assertIn('error', json.loads(response.body)) |
67 | 81 |
68 @mock.patch.object(api_auth, 'oauth') | 82 @mock.patch.object(api_auth, 'oauth') |
69 @mock.patch.object(api_auth, 'users') | 83 @mock.patch.object(api_auth, 'users') |
70 def testPost_BadOauthClientId(self, mock_users, mock_oauth): | 84 def testPost_BadOauthClientId(self, mock_users, mock_oauth): |
71 mock_users.get_current_user.return_value = None | 85 mock_users.get_current_user.return_value = None |
72 mock_oauth.get_current_user.return_value = AUTHORIZED_USER | 86 mock_oauth.get_current_user.return_value = _AUTHORIZED_USER |
73 mock_oauth.get_client_id.return_value = 'invalid' | 87 mock_oauth.get_client_id.return_value = 'invalid' |
74 response = self.testapp.post('/api/new', status=200) | 88 response = self.testapp.post('/api/new', status=200) |
75 self.assertIn('error', json.loads(response.body)) | 89 self.assertIn('error', json.loads(response.body)) |
76 | 90 |
77 @mock.patch( | 91 @mock.patch( |
78 'dashboard.services.issue_tracker_service.IssueTrackerService', | 92 'dashboard.services.issue_tracker_service.IssueTrackerService', |
79 mock.MagicMock()) | 93 mock.MagicMock()) |
80 @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock()) | 94 @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock()) |
81 @mock.patch.object(gitiles_service, 'CommitInfo', mock.MagicMock()) | 95 @mock.patch.object(gitiles_service, 'CommitInfo', mock.MagicMock()) |
82 @mock.patch.object(gitiles_service, 'CommitRange') | 96 @mock.patch.object(gitiles_service, 'CommitRange') |
83 def testPost(self, mock_commit_range): | 97 def testPost(self, mock_commit_range): |
84 mock_commit_range.return_value = [ | 98 mock_commit_range.return_value = [ |
85 {'commit': '1'}, | 99 {'commit': '1'}, |
86 {'commit': '2'}, | 100 {'commit': '2'}, |
87 {'commit': '3'}, | 101 {'commit': '3'}, |
88 ] | 102 ] |
89 params = { | 103 response = self.testapp.post('/api/new', _BASE_REQUEST, status=200) |
90 'configuration': 'chromium-rel-mac11-pro', | |
91 'test_suite': 'speedometer', | |
92 'test': '', | |
93 'metric': 'Total', | |
94 'auto_explore': '1', | |
95 'bug_id': 12345, | |
96 'start_repository': 'src', | |
97 'start_git_hash': '1', | |
98 'end_repository': 'src', | |
99 'end_git_hash': '3' | |
100 } | |
101 response = self.testapp.post('/api/new', params, status=200) | |
102 result = json.loads(response.body) | 104 result = json.loads(response.body) |
103 self.assertIn('jobId', result) | 105 self.assertIn('jobId', result) |
104 self.assertEqual( | 106 self.assertEqual( |
105 result['jobUrl'], | 107 result['jobUrl'], |
106 'https://testbed.example.com/job/%s' % result['jobId']) | 108 'https://testbed.example.com/job/%s' % result['jobId']) |
107 | 109 |
108 def testPost_MetricButNoTestSuite(self): | 110 def testPost_MissingTarget(self): |
109 params = { | 111 request = dict(_BASE_REQUEST) |
110 'configuration': 'chromium-rel-mac11-pro', | 112 del request['target'] |
111 'test_suite': '', | 113 response = self.testapp.post('/api/new', request, status=200) |
112 'test': '', | 114 self.assertIn('error', json.loads(response.body)) |
113 'metric': 'Total', | 115 |
114 'auto_explore': '1', | 116 def testPost_InvalidTestConfig(self): |
115 'bug_id': 12345, | 117 request = dict(_BASE_REQUEST) |
116 'start_repository': 'src', | 118 del request['configuration'] |
117 'start_git_hash': '1', | 119 response = self.testapp.post('/api/new', request, status=200) |
118 'end_repository': 'src', | 120 self.assertIn('error', json.loads(response.body)) |
119 'end_git_hash': '3' | |
120 } | |
121 response = self.testapp.post('/api/new', params, status=200) | |
122 self.assertEqual({'error': new._ERROR_METRIC_NO_TEST_SUITE}, | |
123 json.loads(response.body)) | |
124 | 121 |
125 @mock.patch.object( | 122 @mock.patch.object( |
126 gitiles_service, 'CommitInfo', | 123 gitiles_service, 'CommitInfo', |
127 mock.MagicMock(side_effect=gitiles_service.NotFoundError)) | 124 mock.MagicMock(side_effect=gitiles_service.NotFoundError('message'))) |
128 def testPost_InvalidChange(self): | 125 def testPost_InvalidChange(self): |
129 params = { | 126 response = self.testapp.post('/api/new', _BASE_REQUEST, status=200) |
130 'configuration': 'chromium-rel-mac11-pro', | 127 self.assertEqual({'error': 'message'}, json.loads(response.body)) |
131 'test_suite': 'speedometer', | |
132 'test': '', | |
133 'metric': 'Total', | |
134 'auto_explore': '1', | |
135 'bug_id': 12345, | |
136 'start_repository': 'src', | |
137 'start_git_hash': '1', | |
138 'end_repository': 'src', | |
139 'end_git_hash': '3' | |
140 } | |
141 response = self.testapp.post('/api/new', params, status=200) | |
142 self.assertEqual({'error': 'NotFoundError()'}, | |
143 json.loads(response.body)) | |
144 | 128 |
145 def testPost_InvalidBug(self): | 129 def testPost_InvalidBug(self): |
146 params = { | 130 request = dict(_BASE_REQUEST) |
147 'configuration': 'chromium-rel-mac11-pro', | 131 request['bug_id'] = 'not_an_int' |
148 'test_suite': 'speedometer', | 132 response = self.testapp.post('/api/new', request, status=200) |
149 'test': '', | |
150 'metric': 'Total', | |
151 'auto_explore': '1', | |
152 'bug_id': 'not_an_int', | |
153 'start_repository': 'src', | |
154 'start_git_hash': '1', | |
155 'end_repository': 'src', | |
156 'end_git_hash': '3' | |
157 } | |
158 response = self.testapp.post('/api/new', params, status=200) | |
159 self.assertEqual({'error': new._ERROR_BUG_ID}, | 133 self.assertEqual({'error': new._ERROR_BUG_ID}, |
160 json.loads(response.body)) | 134 json.loads(response.body)) |
161 | 135 |
162 @mock.patch( | 136 @mock.patch( |
163 'dashboard.services.issue_tracker_service.IssueTrackerService', | 137 'dashboard.services.issue_tracker_service.IssueTrackerService', |
164 mock.MagicMock()) | 138 mock.MagicMock()) |
165 @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock()) | 139 @mock.patch.object(utils, 'ServiceAccountHttp', mock.MagicMock()) |
166 @mock.patch.object(gitiles_service, 'CommitInfo', mock.MagicMock()) | 140 @mock.patch.object(gitiles_service, 'CommitInfo', mock.MagicMock()) |
167 @mock.patch.object(gitiles_service, 'CommitRange') | 141 @mock.patch.object(gitiles_service, 'CommitRange') |
168 def testPost_EmptyBug(self, mock_commit_range): | 142 def testPost_EmptyBug(self, mock_commit_range): |
169 mock_commit_range.return_value = [ | 143 mock_commit_range.return_value = [ |
170 {'commit': '1'}, | 144 {'commit': '1'}, |
171 {'commit': '2'}, | 145 {'commit': '2'}, |
172 {'commit': '3'}, | 146 {'commit': '3'}, |
173 ] | 147 ] |
174 params = { | 148 request = dict(_BASE_REQUEST) |
175 'configuration': 'chromium-rel-mac11-pro', | 149 request['bug_id'] = '' |
176 'test_suite': 'speedometer', | 150 response = self.testapp.post('/api/new', request, status=200) |
177 'test': '', | |
178 'metric': 'Total', | |
179 'auto_explore': '1', | |
180 'bug_id': '', | |
181 'start_repository': 'src', | |
182 'start_git_hash': '1', | |
183 'end_repository': 'src', | |
184 'end_git_hash': '3' | |
185 } | |
186 response = self.testapp.post('/api/new', params, status=200) | |
187 result = json.loads(response.body) | 151 result = json.loads(response.body) |
188 self.assertIn('jobId', result) | 152 self.assertIn('jobId', result) |
189 self.assertEqual( | 153 self.assertEqual( |
190 result['jobUrl'], | 154 result['jobUrl'], |
191 'https://testbed.example.com/job/%s' % result['jobId']) | 155 'https://testbed.example.com/job/%s' % result['jobId']) |
192 job = job_module.Job.query().get() | 156 job = job_module.Job.query().get() |
193 self.assertEqual(None, job.bug_id) | 157 self.assertEqual(None, job.bug_id) |
OLD | NEW |