| OLD | NEW |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 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 | 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 collections | 5 import collections |
| 6 import json | 6 import json |
| 7 import os | 7 import os |
| 8 import urllib | 8 import urllib |
| 9 import zlib | 9 import zlib |
| 10 | 10 |
| 11 from testing_utils import testing | |
| 12 | |
| 13 from common.retry_http_client import RetryHttpClient | 11 from common.retry_http_client import RetryHttpClient |
| 12 from model.wf_config import FinditConfig |
| 14 from model.wf_step import WfStep | 13 from model.wf_step import WfStep |
| 15 from waterfall import swarming_util | 14 from waterfall import swarming_util |
| 16 from waterfall import waterfall_config | 15 from waterfall import waterfall_config |
| 17 from waterfall.swarming_task_request import SwarmingTaskRequest | 16 from waterfall.swarming_task_request import SwarmingTaskRequest |
| 18 | 17 from waterfall.test import wf_configured_test_case |
| 19 | |
| 20 _MOCK_SWARMING_SETTINGS = { | |
| 21 'task_timeout_hours': 23, | |
| 22 'server_query_interval_seconds': 60, | |
| 23 'iterations_to_rerun': 10, | |
| 24 'server_host': 'chromium-swarm.appspot.com', | |
| 25 'default_request_priority': 150, | |
| 26 'isolated_storage_url': 'isolateserver.storage.googleapis.com', | |
| 27 'isolated_server': 'https://isolateserver.appspot.com', | |
| 28 'request_expiration_hours': 20 | |
| 29 } | |
| 30 | 18 |
| 31 | 19 |
| 32 class SwarmingHttpClient(RetryHttpClient): | 20 class SwarmingHttpClient(RetryHttpClient): |
| 33 | 21 |
| 34 def __init__(self): | 22 def __init__(self): |
| 35 self.get_responses = dict() | 23 self.get_responses = dict() |
| 36 self.post_responses = dict() | 24 self.post_responses = dict() |
| 37 | 25 |
| 38 def _GetData(self, data_type, file_name=None): | 26 def _GetData(self, data_type, file_name=None): |
| 39 file_name_map = { | 27 file_name_map = { |
| (...skipping 11 matching lines...) Expand all Loading... |
| 51 def _SetResponseForGetRequestIsolated(self, url, file_hash): | 39 def _SetResponseForGetRequestIsolated(self, url, file_hash): |
| 52 self.get_responses[url] = self._GetData('isolated', file_hash) | 40 self.get_responses[url] = self._GetData('isolated', file_hash) |
| 53 | 41 |
| 54 def _SetResponseForGetRequestSwarmingList( | 42 def _SetResponseForGetRequestSwarmingList( |
| 55 self, master_name, builder_name, build_number, step_name=None): | 43 self, master_name, builder_name, build_number, step_name=None): |
| 56 if builder_name == 'download_failed': | 44 if builder_name == 'download_failed': |
| 57 return | 45 return |
| 58 | 46 |
| 59 url = ('https://%s/_ah/api/swarming/v1/tasks/' | 47 url = ('https://%s/_ah/api/swarming/v1/tasks/' |
| 60 'list?tags=%s&tags=%s&tags=%s') % ( | 48 'list?tags=%s&tags=%s&tags=%s') % ( |
| 61 _MOCK_SWARMING_SETTINGS.get('server_host'), | 49 FinditConfig().Get().swarming_settings.get('server_host'), |
| 62 urllib.quote('master:%s' % master_name), | 50 urllib.quote('master:%s' % master_name), |
| 63 urllib.quote('buildername:%s' % builder_name), | 51 urllib.quote('buildername:%s' % builder_name), |
| 64 urllib.quote('buildnumber:%d' % build_number)) | 52 urllib.quote('buildnumber:%d' % build_number)) |
| 65 | 53 |
| 66 if step_name: | 54 if step_name: |
| 67 url += '&tags=%s' % urllib.quote('stepname:%s' % step_name) | 55 url += '&tags=%s' % urllib.quote('stepname:%s' % step_name) |
| 68 response = self._GetData('step') | 56 response = self._GetData('step') |
| 69 else: | 57 else: |
| 70 response = self._GetData('build') | 58 response = self._GetData('build') |
| 71 | 59 |
| 72 cursor_swarming_data = { | 60 cursor_swarming_data = { |
| 73 'cursor': None, | 61 'cursor': None, |
| 74 'items': [], | 62 'items': [], |
| 75 'state': 'all', | 63 'state': 'all', |
| 76 'limit': 100, | 64 'limit': 100, |
| 77 'sort': 'created_ts' | 65 'sort': 'created_ts' |
| 78 } | 66 } |
| 79 cursor_url = ('%s&cursor=thisisacursor') % url | 67 cursor_url = ('%s&cursor=thisisacursor') % url |
| 80 | 68 |
| 81 self.get_responses[url] = response | 69 self.get_responses[url] = response |
| 82 self.get_responses[cursor_url] = json.dumps(cursor_swarming_data) | 70 self.get_responses[cursor_url] = json.dumps(cursor_swarming_data) |
| 83 | 71 |
| 84 def _SetResponseForGetRequestSwarmingResult(self, task_id): | 72 def _SetResponseForGetRequestSwarmingResult(self, task_id): |
| 85 url = ('https://%s/_ah/api/swarming/v1/task/%s/result') % ( | 73 url = ('https://%s/_ah/api/swarming/v1/task/%s/result') % ( |
| 86 _MOCK_SWARMING_SETTINGS.get('server_host'), task_id) | 74 FinditConfig().Get().swarming_settings.get('server_host'), task_id) |
| 87 | 75 |
| 88 response = self._GetData('task') | 76 response = self._GetData('task') |
| 89 self.get_responses[url] = response | 77 self.get_responses[url] = response |
| 90 | 78 |
| 91 def _SetResponseForPostRequest(self, isolated_hash): | 79 def _SetResponseForPostRequest(self, isolated_hash): |
| 92 if isolated_hash == 'not found': | 80 if isolated_hash == 'not found': |
| 93 response = '{"content":"eJyrrgUAAXUA+Q=="}' | 81 response = '{"content":"eJyrrgUAAXUA+Q=="}' |
| 94 else: | 82 else: |
| 95 response = self._GetData('isolated', isolated_hash) | 83 response = self._GetData('isolated', isolated_hash) |
| 96 | 84 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 def _Put(self, *_): # pragma: no cover | 116 def _Put(self, *_): # pragma: no cover |
| 129 pass | 117 pass |
| 130 | 118 |
| 131 def SetResponse(self, method, url, content=None, status_code=200): | 119 def SetResponse(self, method, url, content=None, status_code=200): |
| 132 self.responses[method][url] = (status_code, content) | 120 self.responses[method][url] = (status_code, content) |
| 133 | 121 |
| 134 def GetRequest(self, url): | 122 def GetRequest(self, url): |
| 135 return self.requests.get(url) | 123 return self.requests.get(url) |
| 136 | 124 |
| 137 | 125 |
| 138 class SwarmingUtilTest(testing.AppengineTestCase): | 126 class SwarmingUtilTest(wf_configured_test_case.WaterfallConfiguredTestCase): |
| 139 | 127 |
| 140 def setUp(self): | 128 def setUp(self): |
| 141 super(SwarmingUtilTest, self).setUp() | 129 super(SwarmingUtilTest, self).setUp() |
| 142 self.http_client = SwarmingHttpClient() | 130 self.http_client = SwarmingHttpClient() |
| 143 self.logged_http_client = _LoggedHttpClient() | 131 self.logged_http_client = _LoggedHttpClient() |
| 144 | 132 |
| 145 def _MockGetSwarmingSettings(): | |
| 146 return _MOCK_SWARMING_SETTINGS | |
| 147 | |
| 148 self.mock(waterfall_config, 'GetSwarmingSettings', _MockGetSwarmingSettings) | |
| 149 | |
| 150 def testGetSwarmingTaskRequest(self): | 133 def testGetSwarmingTaskRequest(self): |
| 151 task_request_json = { | 134 task_request_json = { |
| 152 'expiration_secs': 2, | 135 'expiration_secs': 2, |
| 153 'name': 'name', | 136 'name': 'name', |
| 154 'parent_task_id': 'pti', | 137 'parent_task_id': 'pti', |
| 155 'priority': 1, | 138 'priority': 1, |
| 156 'properties': { | 139 'properties': { |
| 157 'command': 'cmd', | 140 'command': 'cmd', |
| 158 'dimensions': [{'key': 'd', 'value': 'dv'}], | 141 'dimensions': [{'key': 'd', 'value': 'dv'}], |
| 159 'env': [{'key': 'e', 'value': 'ev'}], | 142 'env': [{'key': 'e', 'value': 'ev'}], |
| (...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 363 self.assertEqual(expected_data, data) | 346 self.assertEqual(expected_data, data) |
| 364 | 347 |
| 365 def testGetIsolatedDataForStepFailed(self): | 348 def testGetIsolatedDataForStepFailed(self): |
| 366 master_name = 'm' | 349 master_name = 'm' |
| 367 builder_name = 'download_failed' | 350 builder_name = 'download_failed' |
| 368 build_number = 223 | 351 build_number = 223 |
| 369 step_name = 's1' | 352 step_name = 's1' |
| 370 | 353 |
| 371 self.http_client._SetResponseForGetRequestSwarmingList( | 354 self.http_client._SetResponseForGetRequestSwarmingList( |
| 372 master_name, builder_name, build_number, step_name) | 355 master_name, builder_name, build_number, step_name) |
| 356 |
| 373 task_ids = swarming_util.GetIsolatedDataForStep( | 357 task_ids = swarming_util.GetIsolatedDataForStep( |
| 374 master_name, builder_name, build_number, step_name, | 358 master_name, builder_name, build_number, step_name, |
| 375 self.http_client) | 359 self.http_client) |
| 376 expected_task_ids = [] | 360 expected_task_ids = [] |
| 377 | 361 |
| 378 self.assertEqual(expected_task_ids, task_ids) | 362 self.assertEqual(expected_task_ids, task_ids) |
| 379 | 363 |
| 380 def testDownloadTestResults(self): | 364 def testDownloadTestResults(self): |
| 381 isolated_data = { | 365 isolated_data = { |
| 382 'digest': 'shard1_isolated', | 366 'digest': 'shard1_isolated', |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 585 expected_failure_log = { | 569 expected_failure_log = { |
| 586 'failures': ['Test1'], | 570 'failures': ['Test1'], |
| 587 'valid': True | 571 'valid': True |
| 588 } | 572 } |
| 589 | 573 |
| 590 self.assertEqual(expected_failure_log, failure_log) | 574 self.assertEqual(expected_failure_log, failure_log) |
| 591 | 575 |
| 592 def testGetTagValueInvalidTag(self): | 576 def testGetTagValueInvalidTag(self): |
| 593 tags = ['a:1', 'b:2'] | 577 tags = ['a:1', 'b:2'] |
| 594 self.assertIsNone(swarming_util.GetTagValue(tags, 'c')) | 578 self.assertIsNone(swarming_util.GetTagValue(tags, 'c')) |
| OLD | NEW |