| OLD | NEW |
| (Empty) |
| 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 | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import urllib | |
| 6 | |
| 7 from testing_utils import testing | |
| 8 | |
| 9 from common import retry_http_client | |
| 10 | |
| 11 | |
| 12 class DummyHttpClient(retry_http_client.RetryHttpClient): | |
| 13 def __init__(self, simulated_failures, failure_status): | |
| 14 super(DummyHttpClient, self).__init__() | |
| 15 self.requests = [] | |
| 16 self.request_count = 0 | |
| 17 self.simulated_failures = simulated_failures | |
| 18 self.failure_status = failure_status | |
| 19 | |
| 20 def GetBackoff(self, *_): | |
| 21 return 0 | |
| 22 | |
| 23 def _Get(self, url, timeout_seconds, headers=None): | |
| 24 self.requests.append({ | |
| 25 'url': url, | |
| 26 'timeout_seconds': timeout_seconds, | |
| 27 }) | |
| 28 self.request_count += 1 | |
| 29 if self.request_count > self.simulated_failures: | |
| 30 return 200, 'success - GET' | |
| 31 else: | |
| 32 return self.failure_status, 'failure - GET' | |
| 33 | |
| 34 def _Post(self, url, data, timeout_seconds, headers=None): | |
| 35 self.requests.append({ | |
| 36 'url': url, | |
| 37 'timeout_seconds': timeout_seconds, | |
| 38 }) | |
| 39 self.request_count += 1 | |
| 40 if self.request_count > self.simulated_failures: | |
| 41 return 200, 'success - POST' | |
| 42 else: | |
| 43 return self.failure_status, 'failure - POST' | |
| 44 | |
| 45 def _Put(self, url, data, timeout_seconds, headers=None): | |
| 46 self.requests.append({ | |
| 47 'url': url, | |
| 48 'timeout_seconds': timeout_seconds, | |
| 49 }) | |
| 50 self.request_count += 1 | |
| 51 if self.request_count > self.simulated_failures: | |
| 52 return 200, 'success - PUT' | |
| 53 else: | |
| 54 return self.failure_status, 'failure - PUT' | |
| 55 | |
| 56 class HttpClientTest(testing.AppengineTestCase): | |
| 57 def testRequestWithTimeout(self): | |
| 58 url = 'http://test' | |
| 59 timeout_seconds = 70 | |
| 60 dummy_http_client = DummyHttpClient(0, 404) | |
| 61 status_code, content = dummy_http_client.Get( | |
| 62 url, timeout_seconds=timeout_seconds) | |
| 63 self.assertEquals(200, status_code) | |
| 64 self.assertEquals('success - GET', content) | |
| 65 self.assertEquals(1, dummy_http_client.request_count) | |
| 66 self.assertEquals(url, dummy_http_client.requests[0]['url']) | |
| 67 self.assertEquals(timeout_seconds, | |
| 68 dummy_http_client.requests[0]['timeout_seconds']) | |
| 69 | |
| 70 def testRequestWithParameters(self): | |
| 71 url = 'http://test' | |
| 72 params = {'a': 1, 'b': 'b&b'} | |
| 73 dummy_http_client = DummyHttpClient(0, 404) | |
| 74 status_code, content = dummy_http_client.Get( | |
| 75 url, params=params) | |
| 76 self.assertEquals(200, status_code) | |
| 77 self.assertEquals('success - GET', content) | |
| 78 self.assertEquals(1, dummy_http_client.request_count) | |
| 79 target_url, query_str = urllib.splitquery( | |
| 80 dummy_http_client.requests[0]['url']) | |
| 81 self.assertEquals(url, target_url) | |
| 82 for query in query_str.split('&'): | |
| 83 name, value = urllib.splitvalue(query) | |
| 84 self.assertIn(name, params) | |
| 85 self.assertEqual(urllib.quote(str(params[name])), value) | |
| 86 | |
| 87 def testGetBackoff(self): | |
| 88 cases = [ | |
| 89 # (retry_backoff, tries, expected_backoff) | |
| 90 (1, 1, 1), | |
| 91 (1, 2, 1), | |
| 92 (2, 1, 2), | |
| 93 (2, 2, 4) | |
| 94 ] | |
| 95 for retry_backoff, tries, expected_backoff in cases: | |
| 96 http_client = retry_http_client.RetryHttpClient() | |
| 97 self.assertLessEqual(expected_backoff, | |
| 98 http_client.GetBackoff(retry_backoff, tries)) | |
| 99 | |
| 100 def testRequestWithRetry(self): | |
| 101 simulated_failures = 2 | |
| 102 | |
| 103 self.mock_sleep() | |
| 104 | |
| 105 dummy_http_client = DummyHttpClient(simulated_failures, 503) | |
| 106 | |
| 107 status_code, content = dummy_http_client.Get( | |
| 108 'http://test', max_retries=simulated_failures + 2, | |
| 109 retry_backoff=1) | |
| 110 self.assertEquals(200, status_code) | |
| 111 self.assertEquals('success - GET', content) | |
| 112 self.assertEquals(simulated_failures + 1, | |
| 113 dummy_http_client.request_count) | |
| 114 | |
| 115 def testFailedRequest(self): | |
| 116 dummy_http_client = DummyHttpClient(5, 503) | |
| 117 status_code, content = dummy_http_client.Get( | |
| 118 'http://test', max_retries=2, retry_backoff=0.01) | |
| 119 self.assertEquals(2, dummy_http_client.request_count) | |
| 120 self.assertEquals(503, status_code) | |
| 121 self.assertEquals('failure - GET', content) | |
| 122 | |
| 123 def testNoRetryForSpecificHttpStatusCode(self): | |
| 124 for expected_status_code in (302, 401, 403, 404, 501): | |
| 125 dummy_http_client = DummyHttpClient(20000000, expected_status_code) | |
| 126 | |
| 127 status_code, content = dummy_http_client.Get( | |
| 128 'http://test', max_retries=2000, retry_backoff=0.1) | |
| 129 self.assertEquals(1, dummy_http_client.request_count) | |
| 130 self.assertEquals(expected_status_code, status_code) | |
| 131 self.assertEquals('failure - GET', content) | |
| 132 | |
| 133 def testPostFailure(self): | |
| 134 dummy_http_client = DummyHttpClient(1, 404) | |
| 135 status_code, content = dummy_http_client.Post('http://test', {'data': 0}) | |
| 136 self.assertEquals(404, status_code) | |
| 137 self.assertEquals('failure - POST', content) | |
| 138 | |
| 139 def testPostSuccess(self): | |
| 140 dummy_http_client = DummyHttpClient(0, 404) | |
| 141 status_code, content = dummy_http_client.Post('http://test', {'data': 0}) | |
| 142 self.assertEquals(200, status_code) | |
| 143 self.assertEquals('success - POST', content) | |
| 144 | |
| 145 def testNoRetryForSpecificHttpStatusCodePost(self): | |
| 146 for expected_status_code in (302, 401, 403, 404, 501): | |
| 147 dummy_http_client = DummyHttpClient(20000000, expected_status_code) | |
| 148 | |
| 149 status_code, content = dummy_http_client.Post('http://test', {'data': 0}) | |
| 150 self.assertEquals(1, dummy_http_client.request_count) | |
| 151 self.assertEquals(expected_status_code, status_code) | |
| 152 self.assertEquals('failure - POST', content) | |
| 153 | |
| 154 def testRetryForPost(self): | |
| 155 dummy_http_client = DummyHttpClient(5, 503) | |
| 156 status_code, content = dummy_http_client.Post('http://test', {'data': 0}, | |
| 157 max_retries=3) | |
| 158 self.assertEquals(3, dummy_http_client.request_count) | |
| 159 self.assertEquals(503, status_code) | |
| 160 self.assertEquals('failure - POST', content) | |
| 161 | |
| 162 def testPutFailure(self): | |
| 163 dummy_http_client = DummyHttpClient(1, 404) | |
| 164 status_code, content = dummy_http_client.Put('http://test', {'data': 0}) | |
| 165 self.assertEquals(404, status_code) | |
| 166 self.assertEquals('failure - PUT', content) | |
| 167 | |
| 168 def testPutSuccess(self): | |
| 169 dummy_http_client = DummyHttpClient(0, 404) | |
| 170 status_code, content = dummy_http_client.Put('http://test', {'data': 0}) | |
| 171 self.assertEquals(200, status_code) | |
| 172 self.assertEquals('success - PUT', content) | |
| 173 | |
| 174 def testNoRetryForSpecificHttpStatusCodePut(self): | |
| 175 for expected_status_code in (302, 401, 403, 404, 501): | |
| 176 dummy_http_client = DummyHttpClient(20000000, expected_status_code) | |
| 177 | |
| 178 status_code, content = dummy_http_client.Put('http://test', {'data': 0}) | |
| 179 self.assertEquals(1, dummy_http_client.request_count) | |
| 180 self.assertEquals(expected_status_code, status_code) | |
| 181 self.assertEquals('failure - PUT', content) | |
| 182 | |
| 183 def testRetryForPut(self): | |
| 184 dummy_http_client = DummyHttpClient(5, 503) | |
| 185 status_code, content = dummy_http_client.Put('http://test', {'data': 0}, | |
| 186 max_retries=3) | |
| 187 self.assertEquals(3, dummy_http_client.request_count) | |
| 188 self.assertEquals(503, status_code) | |
| 189 self.assertEquals('failure - PUT', content) | |
| OLD | NEW |