OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright 2013 The LUCI Authors. All rights reserved. | 2 # Copyright 2013 The LUCI Authors. All rights reserved. |
3 # Use of this source code is governed under the Apache License, Version 2.0 | 3 # Use of this source code is governed under the Apache License, Version 2.0 |
4 # that can be found in the LICENSE file. | 4 # that can be found in the LICENSE file. |
5 | 5 |
6 import json | 6 import json |
7 import logging | 7 import logging |
8 import os | 8 import os |
9 import shutil | |
10 import sys | 9 import sys |
11 import tempfile | 10 import tempfile |
12 import threading | 11 import threading |
13 import time | 12 import time |
14 import unittest | 13 import unittest |
15 import zipfile | 14 import zipfile |
16 | 15 |
17 import test_env_bot_code | 16 import test_env_bot_code |
18 test_env_bot_code.setup_test_env() | 17 test_env_bot_code.setup_test_env() |
19 | 18 |
20 # Creates a server mock for functions in net.py. | 19 # Creates a server mock for functions in net.py. |
21 import net_utils | 20 import net_utils |
22 | 21 |
23 import bot_main | 22 import bot_main |
| 23 import remote_client |
24 from api import bot | 24 from api import bot |
25 from api import os_utilities | 25 from api import os_utilities |
26 from depot_tools import fix_encoding | 26 from depot_tools import fix_encoding |
27 from utils import file_path | 27 from utils import file_path |
28 from utils import logging_utils | 28 from utils import logging_utils |
29 from utils import net | 29 from utils import net |
30 from utils import subprocess42 | 30 from utils import subprocess42 |
31 from utils import zip_package | 31 from utils import zip_package |
32 | 32 |
33 | 33 |
(...skipping 18 matching lines...) Expand all Loading... |
52 'id': ['localhost'], | 52 'id': ['localhost'], |
53 'pool': ['default'], | 53 'pool': ['default'], |
54 }, | 54 }, |
55 'state': { | 55 'state': { |
56 'cost_usd_hour': 3600., | 56 'cost_usd_hour': 3600., |
57 'sleep_streak': 0, | 57 'sleep_streak': 0, |
58 }, | 58 }, |
59 'version': '123', | 59 'version': '123', |
60 } | 60 } |
61 self.mock(zip_package, 'generate_version', lambda: '123') | 61 self.mock(zip_package, 'generate_version', lambda: '123') |
62 self.bot = bot.Bot( | 62 self.bot = self.make_bot() |
63 self.attributes, 'https://localhost:1', 'version1', self.root_dir, | |
64 self.fail) | |
65 self.mock(self.bot, 'post_error', self.fail) | 63 self.mock(self.bot, 'post_error', self.fail) |
66 self.mock(self.bot, 'restart', self.fail) | 64 self.mock(self.bot, 'restart', self.fail) |
67 self.mock(subprocess42, 'call', self.fail) | 65 self.mock(subprocess42, 'call', self.fail) |
68 self.mock(time, 'time', lambda: 100.) | 66 self.mock(time, 'time', lambda: 100.) |
69 config_path = os.path.join( | 67 config_path = os.path.join( |
70 test_env_bot_code.BOT_DIR, 'config', 'config.json') | 68 test_env_bot_code.BOT_DIR, 'config', 'config.json') |
71 with open(config_path, 'rb') as f: | 69 with open(config_path, 'rb') as f: |
72 config = json.load(f) | 70 config = json.load(f) |
73 self.mock(bot_main, 'get_config', lambda: config) | 71 self.mock(bot_main, 'get_config', lambda: config) |
74 self.mock( | 72 self.mock( |
75 bot_main, 'THIS_FILE', | 73 bot_main, 'THIS_FILE', |
76 os.path.join(test_env_bot_code.BOT_DIR, 'swarming_bot.zip')) | 74 os.path.join(test_env_bot_code.BOT_DIR, 'swarming_bot.zip')) |
77 | 75 |
78 def tearDown(self): | 76 def tearDown(self): |
79 os.environ.pop('SWARMING_BOT_ID', None) | 77 os.environ.pop('SWARMING_BOT_ID', None) |
80 os.chdir(self.old_cwd) | 78 os.chdir(self.old_cwd) |
81 file_path.rmtree(self.root_dir) | 79 file_path.rmtree(self.root_dir) |
82 super(TestBotMain, self).tearDown() | 80 super(TestBotMain, self).tearDown() |
83 | 81 |
| 82 def make_bot(self, auth_headers_cb=None): |
| 83 return bot.Bot( |
| 84 remote_client.RemoteClient('https://localhost:1', auth_headers_cb), |
| 85 self.attributes, 'https://localhost:1', 'version1', |
| 86 self.root_dir, self.fail) |
| 87 |
84 def test_get_dimensions(self): | 88 def test_get_dimensions(self): |
85 dimensions = set(bot_main.get_dimensions(None)) | 89 dimensions = set(bot_main.get_dimensions(None)) |
86 dimensions.discard('hidpi') | 90 dimensions.discard('hidpi') |
87 dimensions.discard('zone') # Only set on GCE bots. | 91 dimensions.discard('zone') # Only set on GCE bots. |
88 expected = {'cores', 'cpu', 'gpu', 'id', 'machine_type', 'os', 'pool'} | 92 expected = {'cores', 'cpu', 'gpu', 'id', 'machine_type', 'os', 'pool'} |
89 if sys.platform == 'darwin': | 93 if sys.platform == 'darwin': |
90 expected.add('xcode_version') | 94 expected.add('xcode_version') |
91 self.assertEqual(expected, dimensions) | 95 self.assertEqual(expected, dimensions) |
92 | 96 |
93 def test_get_dimensions_load_test(self): | 97 def test_get_dimensions_load_test(self): |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 self.expected_requests( | 160 self.expected_requests( |
157 [ | 161 [ |
158 ( | 162 ( |
159 'https://localhost:1/swarming/api/v1/bot/task_error/23', | 163 'https://localhost:1/swarming/api/v1/bot/task_error/23', |
160 { | 164 { |
161 'data': { | 165 'data': { |
162 'id': expected_attribs['dimensions']['id'][0], | 166 'id': expected_attribs['dimensions']['id'][0], |
163 'message': 'error', | 167 'message': 'error', |
164 'task_id': 23, | 168 'task_id': 23, |
165 }, | 169 }, |
| 170 'follow_redirects': False, |
| 171 'headers': {}, |
| 172 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
166 }, | 173 }, |
167 {'resp': 1}, | 174 {'resp': 1}, |
168 ), | 175 ), |
169 ]) | 176 ]) |
170 botobj = bot_main.get_bot() | 177 botobj = bot_main.get_bot() |
171 self.assertEqual({'resp': 1}, bot_main.post_error_task(botobj, 'error', 23)) | 178 self.assertEqual({'resp': 1}, bot_main.post_error_task(botobj, 'error', 23)) |
172 | 179 |
173 def test_run_bot(self): | 180 def test_run_bot(self): |
174 # Test the run_bot() loop. Does not use self.bot. | 181 # Test the run_bot() loop. Does not use self.bot. |
175 self.mock(time, 'time', lambda: 126.0) | 182 self.mock(time, 'time', lambda: 126.0) |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 self.mock(subprocess42, 'Popen', Popen) | 227 self.mock(subprocess42, 'Popen', Popen) |
221 | 228 |
222 self.expected_requests( | 229 self.expected_requests( |
223 [ | 230 [ |
224 ( | 231 ( |
225 'https://localhost:1/swarming/api/v1/bot/server_ping', | 232 'https://localhost:1/swarming/api/v1/bot/server_ping', |
226 {}, 'foo', None, | 233 {}, 'foo', None, |
227 ), | 234 ), |
228 ( | 235 ( |
229 'https://localhost:1/swarming/api/v1/bot/handshake', | 236 'https://localhost:1/swarming/api/v1/bot/handshake', |
230 {'data': self.attributes}, | 237 { |
| 238 'data': self.attributes, |
| 239 'follow_redirects': False, |
| 240 'headers': {}, |
| 241 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
| 242 }, |
231 {'bot_version': '123', 'server': self.url, 'server_version': 1}, | 243 {'bot_version': '123', 'server': self.url, 'server_version': 1}, |
232 ), | 244 ), |
233 ]) | 245 ]) |
234 | 246 |
235 with self.assertRaises(Foo): | 247 with self.assertRaises(Foo): |
236 bot_main.run_bot(None) | 248 bot_main.run_bot(None) |
237 self.assertEqual( | 249 self.assertEqual( |
238 self.attributes['dimensions']['id'][0], os.environ['SWARMING_BOT_ID']) | 250 self.attributes['dimensions']['id'][0], os.environ['SWARMING_BOT_ID']) |
239 | 251 |
240 def test_poll_server_sleep(self): | 252 def test_poll_server_sleep(self): |
241 slept = [] | 253 slept = [] |
242 bit = threading.Event() | 254 bit = threading.Event() |
243 self.mock(bit, 'wait', slept.append) | 255 self.mock(bit, 'wait', slept.append) |
244 self.mock(bot_main, 'run_manifest', self.fail) | 256 self.mock(bot_main, 'run_manifest', self.fail) |
245 self.mock(bot_main, 'update_bot', self.fail) | 257 self.mock(bot_main, 'update_bot', self.fail) |
246 | 258 |
247 self.expected_requests( | 259 self.expected_requests( |
248 [ | 260 [ |
249 ( | 261 ( |
250 'https://localhost:1/swarming/api/v1/bot/poll', | 262 'https://localhost:1/swarming/api/v1/bot/poll', |
251 {'data': self.attributes}, | 263 { |
| 264 'data': self.attributes, |
| 265 'follow_redirects': False, |
| 266 'headers': {}, |
| 267 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
| 268 }, |
252 { | 269 { |
253 'cmd': 'sleep', | 270 'cmd': 'sleep', |
254 'duration': 1.24, | 271 'duration': 1.24, |
| 272 }, |
| 273 ), |
| 274 ]) |
| 275 self.assertFalse(bot_main.poll_server(self.bot, bit)) |
| 276 self.assertEqual([1.24], slept) |
| 277 |
| 278 def test_poll_server_sleep_with_auth(self): |
| 279 slept = [] |
| 280 bit = threading.Event() |
| 281 self.mock(bit, 'wait', slept.append) |
| 282 self.mock(bot_main, 'run_manifest', self.fail) |
| 283 self.mock(bot_main, 'update_bot', self.fail) |
| 284 |
| 285 self.bot = self.make_bot(lambda: ({'A': 'a'}, time.time() + 3600)) |
| 286 |
| 287 self.expected_requests( |
| 288 [ |
| 289 ( |
| 290 'https://localhost:1/swarming/api/v1/bot/poll', |
| 291 { |
| 292 'data': self.attributes, |
| 293 'follow_redirects': False, |
| 294 'headers': {'A': 'a'}, |
| 295 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
| 296 }, |
| 297 { |
| 298 'cmd': 'sleep', |
| 299 'duration': 1.24, |
255 }, | 300 }, |
256 ), | 301 ), |
257 ]) | 302 ]) |
258 self.assertFalse(bot_main.poll_server(self.bot, bit)) | 303 self.assertFalse(bot_main.poll_server(self.bot, bit)) |
259 self.assertEqual([1.24], slept) | 304 self.assertEqual([1.24], slept) |
260 | 305 |
261 def test_poll_server_run(self): | 306 def test_poll_server_run(self): |
262 manifest = [] | 307 manifest = [] |
263 clean = [] | 308 clean = [] |
264 bit = threading.Event() | 309 bit = threading.Event() |
265 self.mock(bit, 'wait', self.fail) | 310 self.mock(bit, 'wait', self.fail) |
266 self.mock(bot_main, 'run_manifest', lambda *args: manifest.append(args)) | 311 self.mock(bot_main, 'run_manifest', lambda *args: manifest.append(args)) |
267 self.mock(bot_main, 'clean_isolated_cache', | 312 self.mock(bot_main, 'clean_isolated_cache', |
268 lambda *args: clean.append(args)) | 313 lambda *args: clean.append(args)) |
269 self.mock(bot_main, 'update_bot', self.fail) | 314 self.mock(bot_main, 'update_bot', self.fail) |
270 | 315 |
271 self.expected_requests( | 316 self.expected_requests( |
272 [ | 317 [ |
273 ( | 318 ( |
274 'https://localhost:1/swarming/api/v1/bot/poll', | 319 'https://localhost:1/swarming/api/v1/bot/poll', |
275 {'data': self.bot._attributes}, | 320 { |
| 321 'data': self.bot._attributes, |
| 322 'follow_redirects': False, |
| 323 'headers': {}, |
| 324 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
| 325 }, |
276 { | 326 { |
277 'cmd': 'run', | 327 'cmd': 'run', |
278 'manifest': {'foo': 'bar'}, | 328 'manifest': {'foo': 'bar'}, |
279 }, | 329 }, |
280 ), | 330 ), |
281 ]) | 331 ]) |
282 self.assertTrue(bot_main.poll_server(self.bot, bit)) | 332 self.assertTrue(bot_main.poll_server(self.bot, bit)) |
283 expected = [(self.bot, {'foo': 'bar'}, time.time())] | 333 expected = [(self.bot, {'foo': 'bar'}, time.time())] |
284 self.assertEqual(expected, manifest) | 334 self.assertEqual(expected, manifest) |
285 expected = [(self.bot,)] | 335 expected = [(self.bot,)] |
286 self.assertEqual(expected, clean) | 336 self.assertEqual(expected, clean) |
287 | 337 |
288 def test_poll_server_update(self): | 338 def test_poll_server_update(self): |
289 update = [] | 339 update = [] |
290 bit = threading.Event() | 340 bit = threading.Event() |
291 self.mock(bit, 'wait', self.fail) | 341 self.mock(bit, 'wait', self.fail) |
292 self.mock(bot_main, 'run_manifest', self.fail) | 342 self.mock(bot_main, 'run_manifest', self.fail) |
293 self.mock(bot_main, 'update_bot', lambda *args: update.append(args)) | 343 self.mock(bot_main, 'update_bot', lambda *args: update.append(args)) |
294 | 344 |
295 self.expected_requests( | 345 self.expected_requests( |
296 [ | 346 [ |
297 ( | 347 ( |
298 'https://localhost:1/swarming/api/v1/bot/poll', | 348 'https://localhost:1/swarming/api/v1/bot/poll', |
299 {'data': self.attributes}, | 349 { |
| 350 'data': self.attributes, |
| 351 'follow_redirects': False, |
| 352 'headers': {}, |
| 353 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
| 354 }, |
300 { | 355 { |
301 'cmd': 'update', | 356 'cmd': 'update', |
302 'version': '123', | 357 'version': '123', |
303 }, | 358 }, |
304 ), | 359 ), |
305 ]) | 360 ]) |
306 self.assertTrue(bot_main.poll_server(self.bot, bit)) | 361 self.assertTrue(bot_main.poll_server(self.bot, bit)) |
307 self.assertEqual([(self.bot, '123')], update) | 362 self.assertEqual([(self.bot, '123')], update) |
308 | 363 |
309 def test_poll_server_restart(self): | 364 def test_poll_server_restart(self): |
310 restart = [] | 365 restart = [] |
311 bit = threading.Event() | 366 bit = threading.Event() |
312 self.mock(bit, 'wait', self.fail) | 367 self.mock(bit, 'wait', self.fail) |
313 self.mock(bot_main, 'run_manifest', self.fail) | 368 self.mock(bot_main, 'run_manifest', self.fail) |
314 self.mock(bot_main, 'update_bot', self.fail) | 369 self.mock(bot_main, 'update_bot', self.fail) |
315 self.mock(self.bot, 'restart', lambda *args: restart.append(args)) | 370 self.mock(self.bot, 'restart', lambda *args: restart.append(args)) |
316 | 371 |
317 self.expected_requests( | 372 self.expected_requests( |
318 [ | 373 [ |
319 ( | 374 ( |
320 'https://localhost:1/swarming/api/v1/bot/poll', | 375 'https://localhost:1/swarming/api/v1/bot/poll', |
321 {'data': self.attributes}, | 376 { |
| 377 'data': self.attributes, |
| 378 'follow_redirects': False, |
| 379 'headers': {}, |
| 380 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
| 381 }, |
322 { | 382 { |
323 'cmd': 'restart', | 383 'cmd': 'restart', |
324 'message': 'Please die now', | 384 'message': 'Please die now', |
325 }, | 385 }, |
326 ), | 386 ), |
327 ]) | 387 ]) |
328 self.assertTrue(bot_main.poll_server(self.bot, bit)) | 388 self.assertTrue(bot_main.poll_server(self.bot, bit)) |
329 self.assertEqual([('Please die now',)], restart) | 389 self.assertEqual([('Please die now',)], restart) |
330 | 390 |
331 def test_poll_server_restart_load_test(self): | 391 def test_poll_server_restart_load_test(self): |
332 os.environ['SWARMING_LOAD_TEST'] = '1' | 392 os.environ['SWARMING_LOAD_TEST'] = '1' |
333 bit = threading.Event() | 393 bit = threading.Event() |
334 self.mock(bit, 'wait', self.fail) | 394 self.mock(bit, 'wait', self.fail) |
335 self.mock(bot_main, 'run_manifest', self.fail) | 395 self.mock(bot_main, 'run_manifest', self.fail) |
336 self.mock(bot_main, 'update_bot', self.fail) | 396 self.mock(bot_main, 'update_bot', self.fail) |
337 self.mock(self.bot, 'restart', self.fail) | 397 self.mock(self.bot, 'restart', self.fail) |
338 | 398 |
339 self.expected_requests( | 399 self.expected_requests( |
340 [ | 400 [ |
341 ( | 401 ( |
342 'https://localhost:1/swarming/api/v1/bot/poll', | 402 'https://localhost:1/swarming/api/v1/bot/poll', |
343 { | 403 { |
344 'data': self.attributes, | 404 'data': self.attributes, |
| 405 'follow_redirects': False, |
| 406 'headers': {}, |
| 407 'timeout': remote_client.NET_CONNECTION_TIMEOUT_SEC, |
345 }, | 408 }, |
346 { | 409 { |
347 'cmd': 'restart', | 410 'cmd': 'restart', |
348 'message': 'Please die now', | 411 'message': 'Please die now', |
349 }, | 412 }, |
350 ), | 413 ), |
351 ]) | 414 ]) |
352 self.assertTrue(bot_main.poll_server(self.bot, bit)) | 415 self.assertTrue(bot_main.poll_server(self.bot, bit)) |
353 | 416 |
354 def _mock_popen(self, returncode=0, exit_code=0, url='https://localhost:1'): | 417 def _mock_popen( |
| 418 self, returncode=0, exit_code=0, url='https://localhost:1', |
| 419 auth_params_json=None): |
355 result = { | 420 result = { |
356 'exit_code': exit_code, | 421 'exit_code': exit_code, |
357 'must_signal_internal_failure': None, | 422 'must_signal_internal_failure': None, |
358 'version': 3, | 423 'version': 3, |
359 } | 424 } |
360 # Method should have "self" as first argument - pylint: disable=E0213 | 425 # Method should have "self" as first argument - pylint: disable=E0213 |
361 class Popen(object): | 426 class Popen(object): |
362 def __init__( | 427 def __init__( |
363 self2, cmd, detached, cwd, env, stdout, stderr, stdin, close_fds): | 428 self2, cmd, detached, cwd, env, stdout, stderr, stdin, close_fds): |
364 self2.returncode = None | 429 self2.returncode = None |
(...skipping 12 matching lines...) Expand all Loading... |
377 1024 * 1024)), | 442 1024 * 1024)), |
378 ] | 443 ] |
379 self.assertEqual(expected, cmd) | 444 self.assertEqual(expected, cmd) |
380 self.assertEqual(True, detached) | 445 self.assertEqual(True, detached) |
381 self.assertEqual(self.bot.base_dir, cwd) | 446 self.assertEqual(self.bot.base_dir, cwd) |
382 self.assertEqual('24', env['SWARMING_TASK_ID']) | 447 self.assertEqual('24', env['SWARMING_TASK_ID']) |
383 self.assertTrue(stdout) | 448 self.assertTrue(stdout) |
384 self.assertEqual(subprocess42.STDOUT, stderr) | 449 self.assertEqual(subprocess42.STDOUT, stderr) |
385 self.assertEqual(subprocess42.PIPE, stdin) | 450 self.assertEqual(subprocess42.PIPE, stdin) |
386 self.assertEqual(sys.platform != 'win32', close_fds) | 451 self.assertEqual(sys.platform != 'win32', close_fds) |
| 452 if auth_params_json is not None: |
| 453 auth_params_file = os.path.join( |
| 454 self.root_dir, 'work', 'bot_auth_params.json') |
| 455 self.assertEqual(auth_params_file, env.get('SWARMING_AUTH_PARAMS')) |
| 456 with open(auth_params_file, 'rb') as f: |
| 457 actual_auth_params = json.load(f) |
| 458 self.assertEqual(auth_params_json, actual_auth_params) |
387 | 459 |
388 def wait(self2, timeout=None): # pylint: disable=unused-argument | 460 def wait(self2, timeout=None): # pylint: disable=unused-argument |
389 self2.returncode = returncode | 461 self2.returncode = returncode |
390 with open(self2._out_file, 'wb') as f: | 462 with open(self2._out_file, 'wb') as f: |
391 json.dump(result, f) | 463 json.dump(result, f) |
392 return 0 | 464 return 0 |
393 | 465 |
394 self.mock(subprocess42, 'Popen', Popen) | 466 self.mock(subprocess42, 'Popen', Popen) |
395 return result | 467 return result |
396 | 468 |
(...skipping 14 matching lines...) Expand all Loading... |
411 'command': ['echo', 'hi'], | 483 'command': ['echo', 'hi'], |
412 'dimensions': {'os': 'Amiga', 'pool': 'default'}, | 484 'dimensions': {'os': 'Amiga', 'pool': 'default'}, |
413 'grace_period': 30, | 485 'grace_period': 30, |
414 'hard_timeout': 60, | 486 'hard_timeout': 60, |
415 'host': 'https://localhost:3', | 487 'host': 'https://localhost:3', |
416 'task_id': '24', | 488 'task_id': '24', |
417 } | 489 } |
418 self.assertEqual(self.root_dir, self.bot.base_dir) | 490 self.assertEqual(self.root_dir, self.bot.base_dir) |
419 bot_main.run_manifest(self.bot, manifest, time.time()) | 491 bot_main.run_manifest(self.bot, manifest, time.time()) |
420 | 492 |
| 493 def test_run_manifest_with_auth(self): |
| 494 self.bot = self.make_bot( |
| 495 auth_headers_cb=lambda: ({'A': 'a'}, time.time() + 3600)) |
| 496 |
| 497 self.mock(bot_main, 'post_error_task', lambda *args: self.fail(args)) |
| 498 def call_hook(botobj, name, *args): |
| 499 if name == 'on_after_task': |
| 500 failure, internal_failure, dimensions, summary = args |
| 501 self.assertEqual(self.attributes['dimensions'], botobj.dimensions) |
| 502 self.assertEqual(False, failure) |
| 503 self.assertEqual(False, internal_failure) |
| 504 self.assertEqual({'os': 'Amiga', 'pool': 'default'}, dimensions) |
| 505 self.assertEqual(result, summary) |
| 506 self.mock(bot_main, 'call_hook', call_hook) |
| 507 result = self._mock_popen( |
| 508 url='https://localhost:3', |
| 509 auth_params_json={'swarming_http_headers': {'A': 'a'}}) |
| 510 |
| 511 manifest = { |
| 512 'command': ['echo', 'hi'], |
| 513 'dimensions': {'os': 'Amiga', 'pool': 'default'}, |
| 514 'grace_period': 30, |
| 515 'hard_timeout': 60, |
| 516 'host': 'https://localhost:3', |
| 517 'task_id': '24', |
| 518 } |
| 519 self.assertEqual(self.root_dir, self.bot.base_dir) |
| 520 bot_main.run_manifest(self.bot, manifest, time.time()) |
| 521 |
421 def test_run_manifest_task_failure(self): | 522 def test_run_manifest_task_failure(self): |
422 self.mock(bot_main, 'post_error_task', lambda *args: self.fail(args)) | 523 self.mock(bot_main, 'post_error_task', lambda *args: self.fail(args)) |
423 def call_hook(_botobj, name, *args): | 524 def call_hook(_botobj, name, *args): |
424 if name == 'on_after_task': | 525 if name == 'on_after_task': |
425 failure, internal_failure, dimensions, summary = args | 526 failure, internal_failure, dimensions, summary = args |
426 self.assertEqual(True, failure) | 527 self.assertEqual(True, failure) |
427 self.assertEqual(False, internal_failure) | 528 self.assertEqual(False, internal_failure) |
428 self.assertEqual({'pool': 'default'}, dimensions) | 529 self.assertEqual({'pool': 'default'}, dimensions) |
429 self.assertEqual(result, summary) | 530 self.assertEqual(result, summary) |
430 self.mock(bot_main, 'call_hook', call_hook) | 531 self.mock(bot_main, 'call_hook', call_hook) |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
498 # Under the test however forever-blocking calls finish, and post_error is | 599 # Under the test however forever-blocking calls finish, and post_error is |
499 # called. | 600 # called. |
500 self.mock(self.bot, 'post_error', lambda *_: None) | 601 self.mock(self.bot, 'post_error', lambda *_: None) |
501 # Mock the file to download in the temporary directory. | 602 # Mock the file to download in the temporary directory. |
502 self.mock( | 603 self.mock( |
503 bot_main, 'THIS_FILE', | 604 bot_main, 'THIS_FILE', |
504 os.path.join(self.root_dir, 'swarming_bot.1.zip')) | 605 os.path.join(self.root_dir, 'swarming_bot.1.zip')) |
505 new_zip = os.path.join(self.root_dir, 'swarming_bot.2.zip') | 606 new_zip = os.path.join(self.root_dir, 'swarming_bot.2.zip') |
506 # This is necessary otherwise zipfile will crash. | 607 # This is necessary otherwise zipfile will crash. |
507 self.mock(time, 'time', lambda: 1400000000) | 608 self.mock(time, 'time', lambda: 1400000000) |
508 def url_retrieve(f, url): | 609 def url_retrieve(f, url, headers=None, timeout=None): |
509 self.assertEqual( | 610 self.assertEqual( |
510 'https://localhost:1/swarming/api/v1/bot/bot_code/123', url) | 611 'https://localhost:1/swarming/api/v1/bot/bot_code/123', url) |
511 self.assertEqual(new_zip, f) | 612 self.assertEqual(new_zip, f) |
| 613 self.assertEqual({}, headers) |
| 614 self.assertEqual(remote_client.NET_CONNECTION_TIMEOUT_SEC, timeout) |
512 # Create a valid zip that runs properly. | 615 # Create a valid zip that runs properly. |
513 with zipfile.ZipFile(f, 'w') as z: | 616 with zipfile.ZipFile(f, 'w') as z: |
514 z.writestr('__main__.py', 'print("hi")') | 617 z.writestr('__main__.py', 'print("hi")') |
515 return True | 618 return True |
516 self.mock(net, 'url_retrieve', url_retrieve) | 619 self.mock(net, 'url_retrieve', url_retrieve) |
517 | 620 |
518 calls = [] | 621 calls = [] |
519 def exec_python(args): | 622 def exec_python(args): |
520 calls.append(args) | 623 calls.append(args) |
521 return 23 | 624 return 23 |
(...skipping 26 matching lines...) Expand all Loading... |
548 self.assertEqual(0, bot_main.main([])) | 651 self.assertEqual(0, bot_main.main([])) |
549 | 652 |
550 | 653 |
551 if __name__ == '__main__': | 654 if __name__ == '__main__': |
552 fix_encoding.fix_encoding() | 655 fix_encoding.fix_encoding() |
553 if '-v' in sys.argv: | 656 if '-v' in sys.argv: |
554 TestBotMain.maxDiff = None | 657 TestBotMain.maxDiff = None |
555 logging.basicConfig( | 658 logging.basicConfig( |
556 level=logging.DEBUG if '-v' in sys.argv else logging.CRITICAL) | 659 level=logging.DEBUG if '-v' in sys.argv else logging.CRITICAL) |
557 unittest.main() | 660 unittest.main() |
OLD | NEW |