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 |