Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(79)

Side by Side Diff: tests/net_test.py

Issue 23657003: Move url_open with dependencies to utils.net module. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/swarm_client
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import json
7 import logging 6 import logging
8 import math 7 import math
9 import os 8 import os
10 import shutil
11 import StringIO 9 import StringIO
12 import sys 10 import sys
13 import tempfile
14 import time
15 import unittest 11 import unittest
16 import urllib2 12 import urllib2
17 13
18 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) 14 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
19 sys.path.insert(0, ROOT_DIR) 15 sys.path.insert(0, ROOT_DIR)
20 16
21 import auto_stub 17 import auto_stub
22 import run_isolated 18 from utils import net
23 19
24 # Number of times self._now() is called per loop in HttpService._retry_loop(). 20 # Number of times self._now() is called per loop in HttpService._retry_loop().
25 NOW_CALLS_PER_OPEN = 2 21 NOW_CALLS_PER_OPEN = 2
26 22
27 23
28 class RemoteTest(run_isolated.Remote):
29 def get_file_handler(self, _): # pylint: disable=R0201
30 def upload_file(item, _dest):
31 if type(item) == type(Exception) and issubclass(item, Exception):
32 raise item()
33 elif isinstance(item, int):
34 time.sleep(int(item) / 100)
35 return upload_file
36
37
38 def fake_http_response(content, url):
39 """Returns run_isolated.HttpResponse with predefined content."""
40 stream = StringIO.StringIO(content)
41 stream.headers = {'content-length': len(content)}
42 return run_isolated.HttpResponse(stream, url)
43
44
45 class RunIsolatedTest(auto_stub.TestCase):
46 def setUp(self):
47 super(RunIsolatedTest, self).setUp()
48 self.tempdir = tempfile.mkdtemp(prefix='run_isolated')
49 os.chdir(self.tempdir)
50
51 def tearDown(self):
52 os.chdir(ROOT_DIR)
53 shutil.rmtree(self.tempdir)
54 super(RunIsolatedTest, self).tearDown()
55
56 def test_load_isolated_empty(self):
57 m = run_isolated.load_isolated('{}')
58 self.assertEqual({}, m)
59
60 def test_load_isolated_good(self):
61 data = {
62 u'command': [u'foo', u'bar'],
63 u'files': {
64 u'a': {
65 u'l': u'somewhere',
66 u'm': 123,
67 },
68 u'b': {
69 u'm': 123,
70 u'h': u'0123456789abcdef0123456789abcdef01234567'
71 }
72 },
73 u'includes': [u'0123456789abcdef0123456789abcdef01234567'],
74 u'os': run_isolated.get_flavor(),
75 u'read_only': False,
76 u'relative_cwd': u'somewhere_else'
77 }
78 m = run_isolated.load_isolated(json.dumps(data))
79 self.assertEqual(data, m)
80
81 def test_load_isolated_bad(self):
82 data = {
83 u'files': {
84 u'a': {
85 u'l': u'somewhere',
86 u'h': u'0123456789abcdef0123456789abcdef01234567'
87 }
88 },
89 }
90 try:
91 run_isolated.load_isolated(json.dumps(data))
92 self.fail()
93 except run_isolated.ConfigError:
94 pass
95
96 def test_load_isolated_os_only(self):
97 data = {
98 u'os': run_isolated.get_flavor(),
99 }
100 m = run_isolated.load_isolated(json.dumps(data))
101 self.assertEqual(data, m)
102
103 def test_load_isolated_os_bad(self):
104 data = {
105 u'os': 'foo',
106 }
107 try:
108 run_isolated.load_isolated(json.dumps(data))
109 self.fail()
110 except run_isolated.ConfigError:
111 pass
112
113 def test_remote_no_errors(self):
114 files_to_handle = 50
115 remote = RemoteTest('')
116
117 for i in range(files_to_handle):
118 remote.add_item(
119 run_isolated.Remote.MED,
120 'obj%d' % i,
121 'dest%d' % i,
122 run_isolated.UNKNOWN_FILE_SIZE)
123
124 items = sorted(remote.join())
125 expected = sorted('obj%d' % i for i in range(files_to_handle))
126 self.assertEqual(expected, items)
127
128 def test_remote_with_errors(self):
129 remote = RemoteTest('')
130
131 def RaiseIOError(*_):
132 raise IOError()
133 remote._do_item = RaiseIOError
134 remote.add_item(run_isolated.Remote.MED, 'ignored', '',
135 run_isolated.UNKNOWN_FILE_SIZE)
136 self.assertRaises(IOError, remote.join)
137 self.assertEqual([], remote.join())
138
139 def test_zip_header_error(self):
140 self.mock(run_isolated, 'url_open',
141 lambda url, **_kwargs: fake_http_response('111', url))
142 self.mock(run_isolated.time, 'sleep', lambda _x: None)
143
144 remote = run_isolated.Remote('https://fake-CAD.com/')
145
146 # Both files will fail to be unzipped due to incorrect headers,
147 # ensure that we don't accept the files (even if the size is unknown)}.
148 remote.add_item(run_isolated.Remote.MED, 'zipped_A', 'A',
149 run_isolated.UNKNOWN_FILE_SIZE)
150 remote.add_item(run_isolated.Remote.MED, 'zipped_B', 'B', 5)
151 self.assertRaises(IOError, remote.get_one_result)
152 self.assertRaises(IOError, remote.get_one_result)
153 # Need to use join here, since get_one_result will hang.
154 self.assertEqual([], remote.join())
155
156
157
158 class HttpServiceTest(auto_stub.TestCase): 24 class HttpServiceTest(auto_stub.TestCase):
159 25
160 # HttpService that doesn't sleep in retries and doesn't write cookie files. 26 # HttpService that doesn't sleep in retries and doesn't write cookie files.
161 class HttpServiceNoSideEffects(run_isolated.HttpService): 27 class HttpServiceNoSideEffects(net.HttpService):
162 def __init__(self, *args, **kwargs): 28 def __init__(self, *args, **kwargs):
163 super(HttpServiceTest.HttpServiceNoSideEffects, self).__init__( 29 super(HttpServiceTest.HttpServiceNoSideEffects, self).__init__(
164 *args, **kwargs) 30 *args, **kwargs)
165 self.sleeps = [] 31 self.sleeps = []
166 self._count = 0. 32 self._count = 0.
167 33
168 def _now(self): # pylint: disable=W0221 34 def _now(self): # pylint: disable=W0221
169 x = self._count 35 x = self._count
170 self._count += 1 36 self._count += 1
171 return x 37 return x
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return StringIO.StringIO(response) 78 return StringIO.StringIO(response)
213 79
214 service = self.mocked_http_service(url=service_url, _url_open=mock_url_open) 80 service = self.mocked_http_service(url=service_url, _url_open=mock_url_open)
215 self.assertEqual(service.request(request_url, data={}).read(), response) 81 self.assertEqual(service.request(request_url, data={}).read(), response)
216 self.assertEqual([], service.sleeps) 82 self.assertEqual([], service.sleeps)
217 83
218 def test_request_success_after_failure(self): 84 def test_request_success_after_failure(self):
219 response = 'True' 85 response = 'True'
220 86
221 def mock_url_open(request, **_kwargs): 87 def mock_url_open(request, **_kwargs):
222 if run_isolated.COUNT_KEY + '=1' not in request.get_data(): 88 if net.COUNT_KEY + '=1' not in request.get_data():
223 raise urllib2.URLError('url') 89 raise urllib2.URLError('url')
224 return StringIO.StringIO(response) 90 return StringIO.StringIO(response)
225 91
226 service = self.mocked_http_service(_url_open=mock_url_open) 92 service = self.mocked_http_service(_url_open=mock_url_open)
227 self.assertEqual(service.request('/', data={}).read(), response) 93 self.assertEqual(service.request('/', data={}).read(), response)
228 self.assertEqual( 94 self.assertEqual(
229 [(0, run_isolated.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN)], 95 [(0, net.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN)],
230 service.sleeps) 96 service.sleeps)
231 97
232 def test_request_failure_max_attempts_default(self): 98 def test_request_failure_max_attempts_default(self):
233 def mock_url_open(_request, **_kwargs): 99 def mock_url_open(_request, **_kwargs):
234 raise urllib2.URLError('url') 100 raise urllib2.URLError('url')
235 service = self.mocked_http_service(_url_open=mock_url_open) 101 service = self.mocked_http_service(_url_open=mock_url_open)
236 self.assertEqual(service.request('/'), None) 102 self.assertEqual(service.request('/'), None)
237 retries = [ 103 retries = [
238 (i, run_isolated.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN * (i + 1)) 104 (i, net.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN * (i + 1))
239 for i in xrange(run_isolated.URL_OPEN_MAX_ATTEMPTS) 105 for i in xrange(net.URL_OPEN_MAX_ATTEMPTS)
240 ] 106 ]
241 self.assertEqual(retries, service.sleeps) 107 self.assertEqual(retries, service.sleeps)
242 108
243 def test_request_failure_max_attempts(self): 109 def test_request_failure_max_attempts(self):
244 def mock_url_open(_request, **_kwargs): 110 def mock_url_open(_request, **_kwargs):
245 raise urllib2.URLError('url') 111 raise urllib2.URLError('url')
246 service = self.mocked_http_service(_url_open=mock_url_open) 112 service = self.mocked_http_service(_url_open=mock_url_open)
247 self.assertEqual(service.request('/', max_attempts=23), None) 113 self.assertEqual(service.request('/', max_attempts=23), None)
248 retries = [ 114 retries = [
249 (i, run_isolated.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN * (i + 1)) 115 (i, net.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN * (i + 1))
250 for i in xrange(23) 116 for i in xrange(23)
251 ] 117 ]
252 self.assertEqual(retries, service.sleeps) 118 self.assertEqual(retries, service.sleeps)
253 119
254 def test_request_failure_timeout(self): 120 def test_request_failure_timeout(self):
255 def mock_url_open(_request, **_kwargs): 121 def mock_url_open(_request, **_kwargs):
256 raise urllib2.URLError('url') 122 raise urllib2.URLError('url')
257 service = self.mocked_http_service(_url_open=mock_url_open) 123 service = self.mocked_http_service(_url_open=mock_url_open)
258 self.assertEqual(service.request('/', max_attempts=10000), None) 124 self.assertEqual(service.request('/', max_attempts=10000), None)
259 retries = [ 125 retries = [
260 (i, run_isolated.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN * (i + 1)) 126 (i, net.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN * (i + 1))
261 # Currently 179 for timeout == 360. 127 # Currently 179 for timeout == 360.
262 for i in xrange( 128 for i in xrange(
263 int(run_isolated.URL_OPEN_TIMEOUT) / NOW_CALLS_PER_OPEN - 1) 129 int(net.URL_OPEN_TIMEOUT) / NOW_CALLS_PER_OPEN - 1)
264 ] 130 ]
265 self.assertEqual(retries, service.sleeps) 131 self.assertEqual(retries, service.sleeps)
266 132
267 def test_request_failure_timeout_default(self): 133 def test_request_failure_timeout_default(self):
268 def mock_url_open(_request, **_kwargs): 134 def mock_url_open(_request, **_kwargs):
269 raise urllib2.URLError('url') 135 raise urllib2.URLError('url')
270 service = self.mocked_http_service(_url_open=mock_url_open) 136 service = self.mocked_http_service(_url_open=mock_url_open)
271 self.assertEqual(service.request('/', timeout=10.), None) 137 self.assertEqual(service.request('/', timeout=10.), None)
272 retries = [(i, 8. - (NOW_CALLS_PER_OPEN * i)) for i in xrange(4)] 138 retries = [(i, 8. - (NOW_CALLS_PER_OPEN * i)) for i in xrange(4)]
273 self.assertEqual(retries, service.sleeps) 139 self.assertEqual(retries, service.sleeps)
274 140
275 def test_request_HTTP_error_no_retry(self): 141 def test_request_HTTP_error_no_retry(self):
276 count = [] 142 count = []
277 def mock_url_open(request, **_kwargs): 143 def mock_url_open(request, **_kwargs):
278 count.append(request) 144 count.append(request)
279 raise urllib2.HTTPError( 145 raise urllib2.HTTPError(
280 'url', 400, 'error message', None, StringIO.StringIO()) 146 'url', 400, 'error message', None, StringIO.StringIO())
281 147
282 service = self.mocked_http_service(_url_open=mock_url_open) 148 service = self.mocked_http_service(_url_open=mock_url_open)
283 self.assertEqual(service.request('/', data={}), None) 149 self.assertEqual(service.request('/', data={}), None)
284 self.assertEqual(1, len(count)) 150 self.assertEqual(1, len(count))
285 self.assertEqual([], service.sleeps) 151 self.assertEqual([], service.sleeps)
286 152
287 def test_request_HTTP_error_retry_404(self): 153 def test_request_HTTP_error_retry_404(self):
288 response = 'data' 154 response = 'data'
289 def mock_url_open(request, **_kwargs): 155 def mock_url_open(request, **_kwargs):
290 if run_isolated.COUNT_KEY + '=1' in request.get_data(): 156 if net.COUNT_KEY + '=1' in request.get_data():
291 return StringIO.StringIO(response) 157 return StringIO.StringIO(response)
292 raise urllib2.HTTPError( 158 raise urllib2.HTTPError(
293 'url', 404, 'error message', None, StringIO.StringIO()) 159 'url', 404, 'error message', None, StringIO.StringIO())
294 160
295 service = self.mocked_http_service(_url_open=mock_url_open) 161 service = self.mocked_http_service(_url_open=mock_url_open)
296 result = service.request('/', data={}, retry_404=True) 162 result = service.request('/', data={}, retry_404=True)
297 self.assertEqual(result.read(), response) 163 self.assertEqual(result.read(), response)
298 self.assertEqual( 164 self.assertEqual(
299 [(0, run_isolated.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN)], 165 [(0, net.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN)],
300 service.sleeps) 166 service.sleeps)
301 167
302 def test_request_HTTP_error_with_retry(self): 168 def test_request_HTTP_error_with_retry(self):
303 response = 'response' 169 response = 'response'
304 170
305 def mock_url_open(request, **_kwargs): 171 def mock_url_open(request, **_kwargs):
306 if run_isolated.COUNT_KEY + '=1' not in request.get_data(): 172 if net.COUNT_KEY + '=1' not in request.get_data():
307 raise urllib2.HTTPError( 173 raise urllib2.HTTPError(
308 'url', 500, 'error message', None, StringIO.StringIO()) 174 'url', 500, 'error message', None, StringIO.StringIO())
309 return StringIO.StringIO(response) 175 return StringIO.StringIO(response)
310 176
311 service = self.mocked_http_service(_url_open=mock_url_open) 177 service = self.mocked_http_service(_url_open=mock_url_open)
312 self.assertTrue(service.request('/', data={}).read(), response) 178 self.assertTrue(service.request('/', data={}).read(), response)
313 self.assertEqual( 179 self.assertEqual(
314 [(0, run_isolated.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN)], 180 [(0, net.URL_OPEN_TIMEOUT - NOW_CALLS_PER_OPEN)],
315 service.sleeps) 181 service.sleeps)
316 182
317 def test_count_key_in_data_failure(self): 183 def test_count_key_in_data_failure(self):
318 data = {run_isolated.COUNT_KEY: 1} 184 data = {net.COUNT_KEY: 1}
319 service = self.mocked_http_service() 185 service = self.mocked_http_service()
320 self.assertEqual(service.request('/', data=data), None) 186 self.assertEqual(service.request('/', data=data), None)
321 self.assertEqual([], service.sleeps) 187 self.assertEqual([], service.sleeps)
322 188
323 def test_auth_success(self): 189 def test_auth_success(self):
324 count = [] 190 count = []
325 response = 'response' 191 response = 'response'
326 def mock_url_open(_request, **_kwargs): 192 def mock_url_open(_request, **_kwargs):
327 if not count: 193 if not count:
328 raise urllib2.HTTPError( 194 raise urllib2.HTTPError(
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 service = self.mocked_http_service(_url_open=mock_url_open, 230 service = self.mocked_http_service(_url_open=mock_url_open,
365 authenticate=mock_authenticate) 231 authenticate=mock_authenticate)
366 self.assertEqual(service.request('/'), None) 232 self.assertEqual(service.request('/'), None)
367 self.assertEqual(calls, ['url_open', 'authenticate']) 233 self.assertEqual(calls, ['url_open', 'authenticate'])
368 self.assertEqual([], service.sleeps) 234 self.assertEqual([], service.sleeps)
369 235
370 def test_sleep_before_retry(self): 236 def test_sleep_before_retry(self):
371 # Verifies bounds. Because it's using a pseudo-random number generator and 237 # Verifies bounds. Because it's using a pseudo-random number generator and
372 # not a read random source, it's basically guaranteed to never return the 238 # not a read random source, it's basically guaranteed to never return the
373 # same value twice consecutively. 239 # same value twice consecutively.
374 a = run_isolated.HttpService.calculate_sleep_before_retry(0, 0) 240 a = net.HttpService.calculate_sleep_before_retry(0, 0)
375 b = run_isolated.HttpService.calculate_sleep_before_retry(0, 0) 241 b = net.HttpService.calculate_sleep_before_retry(0, 0)
376 self.assertTrue(a >= math.pow(1.5, -1), a) 242 self.assertTrue(a >= math.pow(1.5, -1), a)
377 self.assertTrue(b >= math.pow(1.5, -1), b) 243 self.assertTrue(b >= math.pow(1.5, -1), b)
378 self.assertTrue(a < 1.5 + math.pow(1.5, -1), a) 244 self.assertTrue(a < 1.5 + math.pow(1.5, -1), a)
379 self.assertTrue(b < 1.5 + math.pow(1.5, -1), b) 245 self.assertTrue(b < 1.5 + math.pow(1.5, -1), b)
380 self.assertNotEqual(a, b) 246 self.assertNotEqual(a, b)
381 247
382 def test_url_read(self): 248 def test_url_read(self):
383 # Successfully reads the data. 249 # Successfully reads the data.
384 self.mock(run_isolated, 'url_open', 250 self.mock(net, 'url_open',
385 lambda url, **_kwargs: fake_http_response('111', url)) 251 lambda url, **_kwargs: net.HttpResponse.get_fake_response('111', url))
386 self.assertEqual(run_isolated.url_read('https://fake_url.com/test'), '111') 252 self.assertEqual(net.url_read('https://fake_url.com/test'), '111')
387 253
388 # Respects url_open connection errors. 254 # Respects url_open connection errors.
389 self.mock(run_isolated, 'url_open', lambda _url, **_kwargs: None) 255 self.mock(net, 'url_open', lambda _url, **_kwargs: None)
390 self.assertIsNone(run_isolated.url_read('https://fake_url.com/test')) 256 self.assertIsNone(net.url_read('https://fake_url.com/test'))
391 257
392 # Respects read timeout errors. 258 # Respects read timeout errors.
393 def timeouting_http_response(url): 259 def timeouting_http_response(url):
394 def read_mock(_size=None): 260 def read_mock(_size=None):
395 raise run_isolated.TimeoutError() 261 raise net.TimeoutError()
396 stream = StringIO.StringIO('') 262 response = net.HttpResponse(StringIO.StringIO(''),
397 stream.headers = {'content-length': 0} 263 url, {'content-length': 0})
398 response = run_isolated.HttpResponse(stream, url) 264 self.mock(response, 'read', read_mock)
399 response.read = read_mock
400 return response 265 return response
401 266
402 self.mock(run_isolated, 'url_open', 267 self.mock(net, 'url_open',
403 lambda url, **_kwargs: timeouting_http_response(url)) 268 lambda url, **_kwargs: timeouting_http_response(url))
404 self.assertIsNone(run_isolated.url_read('https://fake_url.com/test')) 269 self.assertIsNone(net.url_read('https://fake_url.com/test'))
405 270
406 271
407 if __name__ == '__main__': 272 if __name__ == '__main__':
408 logging.basicConfig( 273 logging.basicConfig(
409 level=(logging.DEBUG if '-v' in sys.argv else logging.FATAL)) 274 level=(logging.DEBUG if '-v' in sys.argv else logging.FATAL))
410 if '-v' in sys.argv: 275 if '-v' in sys.argv:
411 unittest.TestCase.maxDiff = None 276 unittest.TestCase.maxDiff = None
412 unittest.main() 277 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698