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

Side by Side Diff: tests/swarm_get_results_test.py

Issue 22980008: Merge all swarm_*.py scripts into swarming.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/tools/swarm_client
Patch Set: Created 7 years, 4 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
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 import json
7 import logging
8 import os
9 import StringIO
10 import sys
11 import threading
12 import unittest
13 import urllib2
14
15 import auto_stub
16
17 ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
18 sys.path.insert(0, ROOT_DIR)
19
20 import run_isolated
21 import swarm_get_results
22
23
24 TEST_CASE_SUCCESS = (
25 '[----------] 2 tests from StaticCookiePolicyTest\n'
26 '[ RUN ] StaticCookiePolicyTest.AllowAllCookiesTest\n'
27 '[ OK ] StaticCookiePolicyTest.AllowAllCookiesTest (0 ms)\n'
28 '[ RUN ] StaticCookiePolicyTest.BlockAllCookiesTest\n'
29 '[ OK ] StaticCookiePolicyTest.BlockAllCookiesTest (0 ms)\n'
30 '[----------] 2 tests from StaticCookiePolicyTest (0 ms total)\n'
31 '\n'
32 '[----------] 1 test from TCPListenSocketTest\n'
33 '[ RUN ] TCPListenSocketTest.ServerSend\n'
34 '[ OK ] TCPListenSocketTest.ServerSend (1 ms)\n'
35 '[----------] 1 test from TCPListenSocketTest (1 ms total)\n')
36
37
38 TEST_CASE_FAILURE = (
39 '[----------] 2 tests from StaticCookiePolicyTest\n'
40 '[ RUN ] StaticCookiePolicyTest.AllowAllCookiesTest\n'
41 '[ OK ] StaticCookiePolicyTest.AllowAllCookiesTest (0 ms)\n'
42 '[ RUN ] StaticCookiePolicyTest.BlockAllCookiesTest\n'
43 'C:\\win\\build\\src\\chrome\\test.cc: error: Value of: result()\n'
44 ' Actual: false\n'
45 'Expected: true\n'
46 '[ FAILED ] StaticCookiePolicyTest.BlockAllCookiesTest (0 ms)\n'
47 '[----------] 2 tests from StaticCookiePolicyTest (0 ms total)\n'
48 '\n'
49 '[----------] 1 test from TCPListenSocketTest\n'
50 '[ RUN ] TCPListenSocketTest.ServerSend\n'
51 '[ OK ] TCPListenSocketTest.ServerSend (1 ms)\n'
52 '[----------] 1 test from TCPListenSocketTest (1 ms total)\n')
53
54
55 SWARM_OUTPUT_SUCCESS = (
56 '[ RUN ] unittests.Run Test\n' +
57 TEST_CASE_SUCCESS +
58 '[ OK ] unittests.Run Test (2549 ms)\n'
59 '[ RUN ] unittests.Clean Up\n'
60 'No output!\n'
61 '[ OK ] unittests.Clean Up (6 ms)\n'
62 '\n'
63 '[----------] unittests summary\n'
64 '[==========] 2 tests ran. (2556 ms total)\n')
65
66
67 SWARM_OUTPUT_FAILURE = (
68 '[ RUN ] unittests.Run Test\n' +
69 TEST_CASE_FAILURE +
70 '[ OK ] unittests.Run Test (2549 ms)\n'
71 '[ RUN ] unittests.Clean Up\n'
72 'No output!\n'
73 '[ OK ] unittests.Clean Up (6 ms)\n'
74 '\n'
75 '[----------] unittests summary\n'
76 '[==========] 2 tests ran. (2556 ms total)\n')
77
78
79 SWARM_OUTPUT_WITH_NO_TEST_OUTPUT = (
80 '\n'
81 'Unable to connection to swarm machine.\n')
82
83
84 TEST_SHARD_1 = 'Note: This is test shard 1 of 3.'
85 TEST_SHARD_2 = 'Note: This is test shard 2 of 3.'
86 TEST_SHARD_3 = 'Note: This is test shard 3 of 3.'
87
88
89 SWARM_SHARD_OUTPUT = (
90 '[ RUN ] unittests.Run Test\n'
91 '%s\n'
92 '[ OK ] unittests.Run Test (2549 ms)\n'
93 '[ RUN ] unittests.Clean Up\n'
94 'No output!\n'
95 '[ OK ] unittests.Clean Up (6 ms)\n'
96 '\n'
97 '[----------] unittests summary\n'
98 '[==========] 2 tests ran. (2556 ms total)\n')
99
100
101 TEST_SHARD_OUTPUT_1 = SWARM_SHARD_OUTPUT % TEST_SHARD_1
102 TEST_SHARD_OUTPUT_2 = SWARM_SHARD_OUTPUT % TEST_SHARD_2
103 TEST_SHARD_OUTPUT_3 = SWARM_SHARD_OUTPUT % TEST_SHARD_3
104
105
106 def gen_data(index, shard_output, exit_codes):
107 return {
108 u'config_instance_index': index,
109 u'exit_codes': unicode(exit_codes),
110 u'machine_id': u'host',
111 u'machine_tag': u'localhost',
112 u'output': unicode(shard_output),
113 }
114
115
116 def gen_yielded_data(index, shard_output, exit_codes):
117 """Returns an entry as it would be yielded by yield_results()."""
118 return index, gen_data(index, shard_output, exit_codes)
119
120
121 def generate_url_response(index, shard_output, exit_codes):
122 url_response = urllib2.addinfourl(
123 StringIO.StringIO(json.dumps(gen_data(index, shard_output, exit_codes))),
124 'mock message',
125 'host')
126 url_response.code = 200
127 url_response.msg = 'OK'
128 return url_response
129
130
131 def get_swarm_results(keys):
132 """Simplifies the call to yield_results().
133
134 The timeout is hard-coded to 10 seconds.
135 """
136 return list(
137 swarm_get_results.yield_results(
138 'http://host:9001', keys, 10., None))
139
140
141 class TestCase(auto_stub.TestCase):
142 """Base class that defines the url_open mock."""
143 def setUp(self):
144 super(TestCase, self).setUp()
145 self._lock = threading.Lock()
146 self.requests = []
147 self.mock(
148 swarm_get_results.run_isolated, 'url_open',
149 self._url_open)
150
151 def tearDown(self):
152 try:
153 if not self.has_failed():
154 self.assertEqual([], self.requests)
155 finally:
156 super(TestCase, self).tearDown()
157
158 def _url_open(self, url, **kwargs):
159 logging.info('url_open(%s)', url)
160 with self._lock:
161 # Since the client is multi-threaded, requests can be processed out of
162 # order.
163 for index, r in enumerate(self.requests):
164 if r[0] == url and r[1] == kwargs:
165 _, _, returned = self.requests.pop(index)
166 break
167 else:
168 self.fail('Failed to find url %s' % url)
169 return returned
170
171
172 class TestGetTestKeys(TestCase):
173 def test_no_keys(self):
174 old_sleep = swarm_get_results.time.sleep
175 swarm_get_results.time.sleep = lambda x: x
176 try:
177 self.requests = [
178 (
179 'http://host:9001/get_matching_test_cases?name=my_test',
180 {'retry_404': True},
181 StringIO.StringIO('No matching Test Cases'),
182 ) for _ in range(run_isolated.URL_OPEN_MAX_ATTEMPTS)
183 ]
184 try:
185 swarm_get_results.get_test_keys('http://host:9001', 'my_test')
186 self.fail()
187 except swarm_get_results.Failure as e:
188 msg = (
189 'Error: Unable to find any tests with the name, my_test, on swarm '
190 'server')
191 self.assertEqual(msg, e.args[0])
192 finally:
193 swarm_get_results.time.sleep = old_sleep
194
195 def test_no_keys_on_first_attempt(self):
196 old_sleep = swarm_get_results.time.sleep
197 swarm_get_results.time.sleep = lambda x: x
198 try:
199 keys = ['key_1', 'key_2']
200 self.requests = [
201 (
202 'http://host:9001/get_matching_test_cases?name=my_test',
203 {'retry_404': True},
204 StringIO.StringIO('No matching Test Cases'),
205 ),
206 (
207 'http://host:9001/get_matching_test_cases?name=my_test',
208 {'retry_404': True},
209 StringIO.StringIO(json.dumps(keys)),
210 ),
211 ]
212 actual = swarm_get_results.get_test_keys('http://host:9001', 'my_test')
213 self.assertEqual(keys, actual)
214 finally:
215 swarm_get_results.time.sleep = old_sleep
216
217 def test_find_keys(self):
218 keys = ['key_1', 'key_2']
219 self.requests = [
220 (
221 'http://host:9001/get_matching_test_cases?name=my_test',
222 {'retry_404': True},
223 StringIO.StringIO(json.dumps(keys)),
224 ),
225 ]
226 actual = swarm_get_results.get_test_keys('http://host:9001', 'my_test')
227 self.assertEqual(keys, actual)
228
229
230 class TestGetSwarmResults(TestCase):
231 def test_success(self):
232 self.requests = [
233 (
234 'http://host:9001/get_result?r=key1',
235 {'retry_404': False, 'retry_50x': False},
236 generate_url_response(0, SWARM_OUTPUT_SUCCESS, '0, 0'),
237 ),
238 ]
239 expected = [gen_yielded_data(0, SWARM_OUTPUT_SUCCESS, '0, 0')]
240 actual = get_swarm_results(['key1'])
241 self.assertEqual(expected, actual)
242
243 def test_failure(self):
244 self.requests = [
245 (
246 'http://host:9001/get_result?r=key1',
247 {'retry_404': False, 'retry_50x': False},
248 generate_url_response(0, SWARM_OUTPUT_FAILURE, '0, 1'),
249 ),
250 ]
251 expected = [gen_yielded_data(0, SWARM_OUTPUT_FAILURE, '0, 1')]
252 actual = get_swarm_results(['key1'])
253 self.assertEqual(expected, actual)
254
255 def test_no_test_output(self):
256 self.requests = [
257 (
258 'http://host:9001/get_result?r=key1',
259 {'retry_404': False, 'retry_50x': False},
260 generate_url_response(0, SWARM_OUTPUT_WITH_NO_TEST_OUTPUT, '0, 0'),
261 ),
262 ]
263 expected = [gen_yielded_data(0, SWARM_OUTPUT_WITH_NO_TEST_OUTPUT, '0, 0')]
264 actual = get_swarm_results(['key1'])
265 self.assertEqual(expected, actual)
266
267 def test_no_keys(self):
268 actual = get_swarm_results([])
269 self.assertEqual([], actual)
270
271 def test_url_errors(self):
272 # NOTE: get_swarm_results() hardcodes timeout=10. range(12) is because of an
273 # additional time.time() call deep in run_isolated.url_open().
274 now = {}
275 lock = threading.Lock()
276 def get_now():
277 t = threading.current_thread()
278 with lock:
279 return now.setdefault(t, range(12)).pop(0)
280 self.mock(
281 swarm_get_results.run_isolated.HttpService,
282 'sleep_before_retry',
283 staticmethod(lambda _x, _y: None))
284 self.mock(swarm_get_results, 'now', get_now)
285 # The actual number of requests here depends on 'now' progressing to 10
286 # seconds. It's called twice per loop.
287 self.requests = [
288 (
289 'http://host:9001/get_result?r=key1',
290 {'retry_404': False, 'retry_50x': False},
291 None,
292 ),
293 (
294 'http://host:9001/get_result?r=key1',
295 {'retry_404': False, 'retry_50x': False},
296 None,
297 ),
298 (
299 'http://host:9001/get_result?r=key1',
300 {'retry_404': False, 'retry_50x': False},
301 None,
302 ),
303 (
304 'http://host:9001/get_result?r=key1',
305 {'retry_404': False, 'retry_50x': False},
306 None,
307 ),
308 (
309 'http://host:9001/get_result?r=key1',
310 {'retry_404': False, 'retry_50x': False},
311 None,
312 ),
313 ]
314 actual = get_swarm_results(['key1'])
315 self.assertEqual([], actual)
316 self.assertTrue(all(not v for v in now.itervalues()), now)
317
318 def test_shard_repeated(self):
319 self.requests = [
320 (
321 'http://host:9001/get_result?r=key1',
322 {'retry_404': False, 'retry_50x': False},
323 generate_url_response(0, SWARM_OUTPUT_SUCCESS, '0, 0'),
324 ),
325 (
326 'http://host:9001/get_result?r=key1-repeat',
327 {'retry_404': False, 'retry_50x': False},
328 generate_url_response(0, SWARM_OUTPUT_SUCCESS, '0, 0'),
329 ),
330 ]
331 expected = [gen_yielded_data(0, SWARM_OUTPUT_SUCCESS, '0, 0')]
332 actual = get_swarm_results(['key1', 'key1-repeat'])
333 self.assertEqual(expected, actual)
334
335 def test_one_shard_repeated(self):
336 """Have shard 1 repeated twice, then shard 2 and 3."""
337 self.requests = [
338 (
339 'http://host:9001/get_result?r=key1',
340 {'retry_404': False, 'retry_50x': False},
341 generate_url_response(0, TEST_SHARD_OUTPUT_1, '0, 0'),
342 ),
343 (
344 'http://host:9001/get_result?r=key1-repeat',
345 {'retry_404': False, 'retry_50x': False},
346 generate_url_response(0, TEST_SHARD_OUTPUT_1, '0, 0'),
347 ),
348 (
349 'http://host:9001/get_result?r=key2',
350 {'retry_404': False, 'retry_50x': False},
351 generate_url_response(1, TEST_SHARD_OUTPUT_2, '0, 0'),
352 ),
353 (
354 'http://host:9001/get_result?r=key3',
355 {'retry_404': False, 'retry_50x': False},
356 generate_url_response(2, TEST_SHARD_OUTPUT_3, '0, 0'),
357 ),
358 ]
359 expected = [
360 gen_yielded_data(0, TEST_SHARD_OUTPUT_1, '0, 0'),
361 gen_yielded_data(1, TEST_SHARD_OUTPUT_2, '0, 0'),
362 gen_yielded_data(2, TEST_SHARD_OUTPUT_3, '0, 0'),
363 ]
364 actual = get_swarm_results(['key1', 'key1-repeat', 'key2', 'key3'])
365 self.assertEqual(expected, sorted(actual))
366
367
368 if __name__ == '__main__':
369 logging.basicConfig(
370 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR)
371 if '-v' in sys.argv:
372 unittest.TestCase.maxDiff = None
373 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698