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

Side by Side Diff: appengine/swarming/swarming_bot/bot_code/task_runner_test.py

Issue 2024313003: Send authorization headers when calling Swarming backend. (Closed) Base URL: https://chromium.googlesource.com/external/github.com/luci/luci-py@master
Patch Set: rebase Created 4 years, 6 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
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # coding=utf-8 2 # coding=utf-8
3 # Copyright 2013 The LUCI Authors. All rights reserved. 3 # Copyright 2013 The LUCI Authors. All rights reserved.
4 # Use of this source code is governed under the Apache License, Version 2.0 4 # Use of this source code is governed under the Apache License, Version 2.0
5 # that can be found in the LICENSE file. 5 # that can be found in the LICENSE file.
6 6
7 import base64 7 import base64
8 import json 8 import json
9 import logging 9 import logging
10 import os 10 import os
11 import re 11 import re
12 import signal 12 import signal
13 import sys 13 import sys
14 import tempfile 14 import tempfile
15 import time 15 import time
16 import unittest 16 import unittest
17 17
18 import test_env_bot_code 18 import test_env_bot_code
19 test_env_bot_code.setup_test_env() 19 test_env_bot_code.setup_test_env()
20 20
21 # Creates a server mock for functions in net.py. 21 # Creates a server mock for functions in net.py.
22 import net_utils 22 import net_utils
23 23
24 from api import os_utilities
25 from depot_tools import fix_encoding 24 from depot_tools import fix_encoding
26 from utils import file_path 25 from utils import file_path
27 from utils import large 26 from utils import large
28 from utils import logging_utils 27 from utils import logging_utils
29 from utils import subprocess42 28 from utils import subprocess42
30 from utils import tools
31 import fake_swarming 29 import fake_swarming
32 import task_runner 30 import task_runner
33 31
34 CLIENT_DIR = os.path.normpath( 32 CLIENT_DIR = os.path.normpath(
35 os.path.join(test_env_bot_code.BOT_DIR, '..', '..', '..', 'client')) 33 os.path.join(test_env_bot_code.BOT_DIR, '..', '..', '..', 'client'))
36 34
37 sys.path.insert(0, os.path.join(CLIENT_DIR, 'tests')) 35 sys.path.insert(0, os.path.join(CLIENT_DIR, 'tests'))
38 import isolateserver_mock 36 import isolateserver_mock
39 37
40 38
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 file_path.rmtree(self.root_dir) 75 file_path.rmtree(self.root_dir)
78 except OSError: 76 except OSError:
79 print >> sys.stderr, 'Failed to delete %s' % self.root_dir 77 print >> sys.stderr, 'Failed to delete %s' % self.root_dir
80 finally: 78 finally:
81 super(TestTaskRunnerBase, self).tearDown() 79 super(TestTaskRunnerBase, self).tearDown()
82 80
83 @classmethod 81 @classmethod
84 def get_task_details(cls, *args, **kwargs): 82 def get_task_details(cls, *args, **kwargs):
85 return task_runner.TaskDetails(get_manifest(*args, **kwargs)) 83 return task_runner.TaskDetails(get_manifest(*args, **kwargs))
86 84
87 def gen_requests(self, cost_usd=0., **kwargs): 85 def gen_requests(self, cost_usd=0., auth_headers=None, **kwargs):
88 return [ 86 return [
89 ( 87 (
90 'https://localhost:1/swarming/api/v1/bot/task_update/23', 88 'https://localhost:1/swarming/api/v1/bot/task_update/23',
91 self.get_check_first(cost_usd), 89 self.get_check_first(cost_usd, auth_headers=auth_headers),
92 {'ok': True}, 90 {'ok': True},
93 ), 91 ),
94 ( 92 (
95 'https://localhost:1/swarming/api/v1/bot/task_update/23', 93 'https://localhost:1/swarming/api/v1/bot/task_update/23',
96 self.get_check_final(**kwargs), 94 self.get_check_final(auth_headers=auth_headers, **kwargs),
97 {'ok': True}, 95 {'ok': True},
98 ), 96 ),
99 ] 97 ]
100 98
101 def requests(self, **kwargs): 99 def requests(self, **kwargs):
102 """Generates the expected HTTP requests for a task run.""" 100 """Generates the expected HTTP requests for a task run."""
103 self.expected_requests(self.gen_requests(**kwargs)) 101 self.expected_requests(self.gen_requests(**kwargs))
104 102
105 def get_check_first(self, cost_usd): 103 def get_check_first(self, cost_usd, auth_headers=None):
106 def check_first(kwargs): 104 def check_first(kwargs):
107 self.assertLessEqual(cost_usd, kwargs['data'].pop('cost_usd')) 105 self.assertLessEqual(cost_usd, kwargs['data'].pop('cost_usd'))
108 self.assertEqual( 106 self.assertEqual(
109 { 107 {
110 'data': { 108 'data': {
111 'id': 'localhost', 109 'id': 'localhost',
112 'task_id': 23, 110 'task_id': 23,
113 }, 111 },
112 'follow_redirects': False,
113 'headers': auth_headers or {},
114 }, 114 },
115 kwargs) 115 kwargs)
116 return check_first 116 return check_first
117 117
118 118
119 class TestTaskRunner(TestTaskRunnerBase): 119 class TestTaskRunner(TestTaskRunnerBase):
120 def setUp(self): 120 def setUp(self):
121 super(TestTaskRunner, self).setUp() 121 super(TestTaskRunner, self).setUp()
122 self.mock(time, 'time', lambda: 1000000000.) 122 self.mock(time, 'time', lambda: 1000000000.)
123 123
124 def get_check_final(self, exit_code=0, output_re=r'^hi\n$', outputs_ref=None): 124 def get_check_final(
125 self, exit_code=0, output_re=r'^hi\n$', outputs_ref=None,
126 auth_headers=None):
125 def check_final(kwargs): 127 def check_final(kwargs):
126 # Ignore these values. 128 # Ignore these values.
127 kwargs['data'].pop('bot_overhead', None) 129 kwargs['data'].pop('bot_overhead', None)
128 kwargs['data'].pop('duration', None) 130 kwargs['data'].pop('duration', None)
129 131
130 output = '' 132 output = ''
131 if 'output' in kwargs['data']: 133 if 'output' in kwargs['data']:
132 output = base64.b64decode(kwargs['data'].pop('output')) 134 output = base64.b64decode(kwargs['data'].pop('output'))
133 self.assertTrue(re.match(output_re, output)) 135 self.assertTrue(re.match(output_re, output))
134 136
135 expected = { 137 expected = {
136 'data': { 138 'data': {
137 'cost_usd': 10., 139 'cost_usd': 10.,
138 'exit_code': exit_code, 140 'exit_code': exit_code,
139 'hard_timeout': False, 141 'hard_timeout': False,
140 'id': 'localhost', 142 'id': 'localhost',
141 'io_timeout': False, 143 'io_timeout': False,
142 'output_chunk_start': 0, 144 'output_chunk_start': 0,
143 'task_id': 23, 145 'task_id': 23,
144 }, 146 },
147 'follow_redirects': False,
148 'headers': auth_headers or {},
145 } 149 }
146 if outputs_ref: 150 if outputs_ref:
147 expected['data']['outputs_ref'] = outputs_ref 151 expected['data']['outputs_ref'] = outputs_ref
148 self.assertEqual(expected, kwargs) 152 self.assertEqual(expected, kwargs)
149 return check_final 153 return check_final
150 154
151 def _run_command(self, task_details): 155 def _run_command(self, task_details, auth_headers_file=None):
152 start = time.time() 156 start = time.time()
153 self.mock(time, 'time', lambda: start + 10) 157 self.mock(time, 'time', lambda: start + 10)
154 server = 'https://localhost:1' 158 server = 'https://localhost:1'
155 return task_runner.run_command( 159 return task_runner.run_command(
156 server, task_details, self.work_dir, 3600., start, 1) 160 server, task_details, self.work_dir, auth_headers_file, 3600., start, 1)
157 161
158 def test_load_and_run_raw(self): 162 def test_load_and_run_raw(self):
159 server = 'https://localhost:1' 163 server = 'https://localhost:1'
160 164
161 def run_command( 165 def run_command(
162 swarming_server, task_details, work_dir, cost_usd_hour, start, 166 swarming_server, task_details, work_dir, auth_headers_file,
163 min_free_space): 167 cost_usd_hour, start, min_free_space):
164 self.assertEqual(server, swarming_server) 168 self.assertEqual(server, swarming_server)
169 self.assertTrue(isinstance(task_details, task_runner.TaskDetails))
165 # Necessary for OSX. 170 # Necessary for OSX.
166 self.assertEqual( 171 self.assertEqual(
167 os.path.realpath(self.work_dir), os.path.realpath(work_dir)) 172 os.path.realpath(self.work_dir), os.path.realpath(work_dir))
168 self.assertTrue(isinstance(task_details, task_runner.TaskDetails)) 173 self.assertEqual(None, auth_headers_file)
169 self.assertEqual(3600., cost_usd_hour) 174 self.assertEqual(3600., cost_usd_hour)
170 self.assertEqual(time.time(), start) 175 self.assertEqual(time.time(), start)
171 self.assertEqual(1, min_free_space) 176 self.assertEqual(1, min_free_space)
172 return { 177 return {
173 u'exit_code': 1, 178 u'exit_code': 1,
174 u'hard_timeout': False, 179 u'hard_timeout': False,
175 u'io_timeout': False, 180 u'io_timeout': False,
176 u'must_signal_internal_failure': None, 181 u'must_signal_internal_failure': None,
177 u'version': task_runner.OUT_VERSION, 182 u'version': task_runner.OUT_VERSION,
178 } 183 }
179 self.mock(task_runner, 'run_command', run_command) 184 self.mock(task_runner, 'run_command', run_command)
180 185
181 manifest = os.path.join(self.root_dir, 'manifest') 186 manifest = os.path.join(self.root_dir, 'manifest')
182 with open(manifest, 'wb') as f: 187 with open(manifest, 'wb') as f:
183 data = { 188 data = {
184 'bot_id': 'localhost', 189 'bot_id': 'localhost',
185 'command': ['a'], 190 'command': ['a'],
186 'env': {'d': 'e'}, 191 'env': {'d': 'e'},
187 'extra_args': [], 192 'extra_args': [],
188 'grace_period': 30., 193 'grace_period': 30.,
189 'hard_timeout': 10, 194 'hard_timeout': 10,
190 'io_timeout': 11, 195 'io_timeout': 11,
191 'isolated': None, 196 'isolated': None,
192 'task_id': 23, 197 'task_id': 23,
193 } 198 }
194 json.dump(data, f) 199 json.dump(data, f)
195 200
196 out_file = os.path.join(self.root_dir, 'work', 'task_runner_out.json') 201 out_file = os.path.join(self.root_dir, 'work', 'task_runner_out.json')
197 task_runner.load_and_run(manifest, server, 3600., time.time(), out_file, 1) 202 task_runner.load_and_run(
203 manifest, server, None, 3600., time.time(), out_file, 1)
198 expected = { 204 expected = {
199 u'exit_code': 1, 205 u'exit_code': 1,
200 u'hard_timeout': False, 206 u'hard_timeout': False,
201 u'io_timeout': False, 207 u'io_timeout': False,
202 u'must_signal_internal_failure': None, 208 u'must_signal_internal_failure': None,
203 u'version': task_runner.OUT_VERSION, 209 u'version': task_runner.OUT_VERSION,
204 } 210 }
205 with open(out_file, 'rb') as f: 211 with open(out_file, 'rb') as f:
206 self.assertEqual(expected, json.load(f)) 212 self.assertEqual(expected, json.load(f))
207 213
208 def test_load_and_run_isolated(self): 214 def test_load_and_run_isolated(self):
209 self.expected_requests([]) 215 self.expected_requests([])
210 server = 'https://localhost:1' 216 server = 'https://localhost:1'
211 217
212 def run_command( 218 def run_command(
213 swarming_server, task_details, work_dir, cost_usd_hour, start, 219 swarming_server, task_details, work_dir, auth_headers_file,
214 min_free_space): 220 cost_usd_hour, start, min_free_space):
215 self.assertEqual(server, swarming_server) 221 self.assertEqual(server, swarming_server)
222 self.assertTrue(isinstance(task_details, task_runner.TaskDetails))
216 # Necessary for OSX. 223 # Necessary for OSX.
217 self.assertEqual( 224 self.assertEqual(
218 os.path.realpath(self.work_dir), os.path.realpath(work_dir)) 225 os.path.realpath(self.work_dir), os.path.realpath(work_dir))
219 self.assertTrue(isinstance(task_details, task_runner.TaskDetails)) 226 self.assertEqual(None, auth_headers_file)
220 self.assertEqual(3600., cost_usd_hour) 227 self.assertEqual(3600., cost_usd_hour)
221 self.assertEqual(time.time(), start) 228 self.assertEqual(time.time(), start)
222 self.assertEqual(1, min_free_space) 229 self.assertEqual(1, min_free_space)
223 return { 230 return {
224 u'exit_code': 0, 231 u'exit_code': 0,
225 u'hard_timeout': False, 232 u'hard_timeout': False,
226 u'io_timeout': False, 233 u'io_timeout': False,
227 u'must_signal_internal_failure': None, 234 u'must_signal_internal_failure': None,
228 u'version': task_runner.OUT_VERSION, 235 u'version': task_runner.OUT_VERSION,
229 } 236 }
(...skipping 12 matching lines...) Expand all
242 'isolated': { 249 'isolated': {
243 'input': '123', 250 'input': '123',
244 'server': 'http://localhost:1', 251 'server': 'http://localhost:1',
245 'namespace': 'default-gzip', 252 'namespace': 'default-gzip',
246 }, 253 },
247 'task_id': 23, 254 'task_id': 23,
248 } 255 }
249 json.dump(data, f) 256 json.dump(data, f)
250 257
251 out_file = os.path.join(self.root_dir, 'work', 'task_runner_out.json') 258 out_file = os.path.join(self.root_dir, 'work', 'task_runner_out.json')
252 task_runner.load_and_run(manifest, server, 3600., time.time(), out_file, 1) 259 task_runner.load_and_run(
260 manifest, server, None, 3600., time.time(), out_file, 1)
253 expected = { 261 expected = {
254 u'exit_code': 0, 262 u'exit_code': 0,
255 u'hard_timeout': False, 263 u'hard_timeout': False,
256 u'io_timeout': False, 264 u'io_timeout': False,
257 u'must_signal_internal_failure': None, 265 u'must_signal_internal_failure': None,
258 u'version': task_runner.OUT_VERSION, 266 u'version': task_runner.OUT_VERSION,
259 } 267 }
260 with open(out_file, 'rb') as f: 268 with open(out_file, 'rb') as f:
261 self.assertEqual(expected, json.load(f)) 269 self.assertEqual(expected, json.load(f))
262 270
263 def test_run_command_raw(self): 271 def test_run_command_raw(self):
264 # This runs the command for real. 272 # This runs the command for real.
265 self.requests(cost_usd=1, exit_code=0) 273 self.requests(cost_usd=1, exit_code=0)
266 task_details = self.get_task_details('print(\'hi\')') 274 task_details = self.get_task_details('print(\'hi\')')
267 expected = { 275 expected = {
268 u'exit_code': 0, 276 u'exit_code': 0,
269 u'hard_timeout': False, 277 u'hard_timeout': False,
270 u'io_timeout': False, 278 u'io_timeout': False,
271 u'must_signal_internal_failure': None, 279 u'must_signal_internal_failure': None,
272 u'version': task_runner.OUT_VERSION, 280 u'version': task_runner.OUT_VERSION,
273 } 281 }
274 self.assertEqual(expected, self._run_command(task_details)) 282 self.assertEqual(expected, self._run_command(task_details))
275 283
284 def test_run_command_raw_with_auth(self):
285 headers_file = os.path.join(self.root_dir, 'header.json')
286 with open(headers_file, 'wb') as f:
287 json.dump({'A': 'a'}, f)
288
289 # This runs the command for real.
290 self.requests(cost_usd=1, exit_code=0, auth_headers={'A': 'a'})
291 task_details = self.get_task_details('print(\'hi\')')
292 expected = {
293 u'exit_code': 0,
294 u'hard_timeout': False,
295 u'io_timeout': False,
296 u'must_signal_internal_failure': None,
297 u'version': task_runner.OUT_VERSION,
298 }
299 self.assertEqual(
300 expected, self._run_command(
301 task_details, auth_headers_file=headers_file))
302
276 def test_run_command_isolated(self): 303 def test_run_command_isolated(self):
277 # This runs the command for real. 304 # This runs the command for real.
278 self.requests( 305 self.requests(
279 cost_usd=1, exit_code=0, 306 cost_usd=1, exit_code=0,
280 outputs_ref={ 307 outputs_ref={
281 u'isolated': u'123', 308 u'isolated': u'123',
282 u'isolatedserver': u'http://localhost:1', 309 u'isolatedserver': u'http://localhost:1',
283 u'namespace': u'default-gzip', 310 u'namespace': u'default-gzip',
284 }) 311 })
285 task_details = self.get_task_details(isolated={ 312 task_details = self.get_task_details(isolated={
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
409 'cost_usd': 10., 436 'cost_usd': 10.,
410 'duration': 0., 437 'duration': 0.,
411 'exit_code': 0, 438 'exit_code': 0,
412 'hard_timeout': False, 439 'hard_timeout': False,
413 'id': 'localhost', 440 'id': 'localhost',
414 'io_timeout': False, 441 'io_timeout': False,
415 'output': base64.b64encode('hi!\n'), 442 'output': base64.b64encode('hi!\n'),
416 'output_chunk_start': 100002*4, 443 'output_chunk_start': 100002*4,
417 'task_id': 23, 444 'task_id': 23,
418 }, 445 },
446 'follow_redirects': False,
447 'headers': {},
419 }, 448 },
420 kwargs) 449 kwargs)
421 450
422 requests = [ 451 requests = [
423 ( 452 (
424 'https://localhost:1/swarming/api/v1/bot/task_update/23', 453 'https://localhost:1/swarming/api/v1/bot/task_update/23',
425 { 454 {
426 'data': { 455 'data': {
427 'cost_usd': 10., 456 'cost_usd': 10.,
428 'id': 'localhost', 457 'id': 'localhost',
429 'task_id': 23, 458 'task_id': 23,
430 }, 459 },
460 'follow_redirects': False,
461 'headers': {},
431 }, 462 },
432 {'ok': True}, 463 {'ok': True},
433 ), 464 ),
434 ( 465 (
435 'https://localhost:1/swarming/api/v1/bot/task_update/23', 466 'https://localhost:1/swarming/api/v1/bot/task_update/23',
436 { 467 {
437 'data': { 468 'data': {
438 'cost_usd': 10., 469 'cost_usd': 10.,
439 'id': 'localhost', 470 'id': 'localhost',
440 'output': base64.b64encode('hi!\n' * 100002), 471 'output': base64.b64encode('hi!\n' * 100002),
441 'output_chunk_start': 0, 472 'output_chunk_start': 0,
442 'task_id': 23, 473 'task_id': 23,
443 }, 474 },
475 'follow_redirects': False,
476 'headers': {},
444 }, 477 },
445 {'ok': True}, 478 {'ok': True},
446 ), 479 ),
447 ( 480 (
448 'https://localhost:1/swarming/api/v1/bot/task_update/23', 481 'https://localhost:1/swarming/api/v1/bot/task_update/23',
449 check_final, 482 check_final,
450 {'ok': True}, 483 {'ok': True},
451 ), 484 ),
452 ] 485 ]
453 self.expected_requests(requests) 486 self.expected_requests(requests)
(...skipping 13 matching lines...) Expand all
467 u'exit_code': 0, 500 u'exit_code': 0,
468 u'hard_timeout': False, 501 u'hard_timeout': False,
469 u'io_timeout': False, 502 u'io_timeout': False,
470 u'must_signal_internal_failure': None, 503 u'must_signal_internal_failure': None,
471 u'version': task_runner.OUT_VERSION, 504 u'version': task_runner.OUT_VERSION,
472 } 505 }
473 self.assertEqual(expected, self._run_command(task_details)) 506 self.assertEqual(expected, self._run_command(task_details))
474 507
475 def test_main(self): 508 def test_main(self):
476 def load_and_run( 509 def load_and_run(
477 manifest, swarming_server, cost_usd_hour, start, json_file, 510 manifest, swarming_server, auth_headers_file, cost_usd_hour, start,
478 min_free_space): 511 json_file, min_free_space):
479 self.assertEqual('foo', manifest) 512 self.assertEqual('foo', manifest)
480 self.assertEqual('http://localhost', swarming_server) 513 self.assertEqual('http://localhost', swarming_server)
514 self.assertEqual(None, auth_headers_file)
481 self.assertEqual(3600., cost_usd_hour) 515 self.assertEqual(3600., cost_usd_hour)
482 self.assertEqual(time.time(), start) 516 self.assertEqual(time.time(), start)
483 self.assertEqual('task_summary.json', json_file) 517 self.assertEqual('task_summary.json', json_file)
484 self.assertEqual(1, min_free_space) 518 self.assertEqual(1, min_free_space)
485 519
486 self.mock(task_runner, 'load_and_run', load_and_run) 520 self.mock(task_runner, 'load_and_run', load_and_run)
487 cmd = [ 521 cmd = [
488 '--swarming-server', 'http://localhost', 522 '--swarming-server', 'http://localhost',
489 '--in-file', 'foo', 523 '--in-file', 'foo',
490 '--out-file', 'task_summary.json', 524 '--out-file', 'task_summary.json',
491 '--cost-usd-hour', '3600', 525 '--cost-usd-hour', '3600',
492 '--start', str(time.time()), 526 '--start', str(time.time()),
493 '--min-free-space', '1', 527 '--min-free-space', '1',
494 ] 528 ]
495 self.assertEqual(0, task_runner.main(cmd)) 529 self.assertEqual(0, task_runner.main(cmd))
496 530
497 def test_main_reboot(self): 531 def test_main_reboot(self):
498 def load_and_run( 532 def load_and_run(
499 manifest, swarming_server, cost_usd_hour, start, json_file, 533 manifest, swarming_server, auth_headers_file, cost_usd_hour, start,
500 min_free_space): 534 json_file, min_free_space):
501 self.assertEqual('foo', manifest) 535 self.assertEqual('foo', manifest)
502 self.assertEqual('http://localhost', swarming_server) 536 self.assertEqual('http://localhost', swarming_server)
537 self.assertEqual(None, auth_headers_file)
503 self.assertEqual(3600., cost_usd_hour) 538 self.assertEqual(3600., cost_usd_hour)
504 self.assertEqual(time.time(), start) 539 self.assertEqual(time.time(), start)
505 self.assertEqual('task_summary.json', json_file) 540 self.assertEqual('task_summary.json', json_file)
506 self.assertEqual(1, min_free_space) 541 self.assertEqual(1, min_free_space)
507 542
508 self.mock(task_runner, 'load_and_run', load_and_run) 543 self.mock(task_runner, 'load_and_run', load_and_run)
509 cmd = [ 544 cmd = [
510 '--swarming-server', 'http://localhost', 545 '--swarming-server', 'http://localhost',
511 '--in-file', 'foo', 546 '--in-file', 'foo',
512 '--out-file', 'task_summary.json', 547 '--out-file', 'task_summary.json',
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
561 ' except IOError:\n' 596 ' except IOError:\n'
562 ' pass;\n' 597 ' pass;\n'
563 'print(\'bye\');\n' 598 'print(\'bye\');\n'
564 'time.sleep(100)') % ( 599 'time.sleep(100)') % (
565 'signal.SIGBREAK' if sys.platform == 'win32' else 'signal.SIGTERM') 600 'signal.SIGBREAK' if sys.platform == 'win32' else 'signal.SIGTERM')
566 601
567 SCRIPT_HANG = 'import time; print(\'hi\'); time.sleep(100)' 602 SCRIPT_HANG = 'import time; print(\'hi\'); time.sleep(100)'
568 603
569 def get_check_final( 604 def get_check_final(
570 self, hard_timeout=False, io_timeout=False, exit_code=None, 605 self, hard_timeout=False, io_timeout=False, exit_code=None,
571 output_re='^hi\n$'): 606 output_re='^hi\n$', auth_headers=None):
572 def check_final(kwargs): 607 def check_final(kwargs):
573 kwargs['data'].pop('bot_overhead', None) 608 kwargs['data'].pop('bot_overhead', None)
574 if hard_timeout or io_timeout: 609 if hard_timeout or io_timeout:
575 self.assertLess(self.SHORT_TIME_OUT, kwargs['data'].pop('cost_usd')) 610 self.assertLess(self.SHORT_TIME_OUT, kwargs['data'].pop('cost_usd'))
576 self.assertLess(self.SHORT_TIME_OUT, kwargs['data'].pop('duration')) 611 self.assertLess(self.SHORT_TIME_OUT, kwargs['data'].pop('duration'))
577 else: 612 else:
578 self.assertLess(0., kwargs['data'].pop('cost_usd')) 613 self.assertLess(0., kwargs['data'].pop('cost_usd'))
579 self.assertLess(0., kwargs['data'].pop('duration')) 614 self.assertLess(0., kwargs['data'].pop('duration'))
580 615
581 output = '' 616 output = ''
582 if 'output' in kwargs['data']: 617 if 'output' in kwargs['data']:
583 output = base64.b64decode(kwargs['data'].pop('output')) 618 output = base64.b64decode(kwargs['data'].pop('output'))
584 self.assertTrue(re.match(output_re, output)) 619 self.assertTrue(re.match(output_re, output))
585 620
586 self.assertEqual( 621 self.assertEqual(
587 { 622 {
588 'data': { 623 'data': {
589 'exit_code': exit_code, 624 'exit_code': exit_code,
590 'hard_timeout': hard_timeout, 625 'hard_timeout': hard_timeout,
591 'id': 'localhost', 626 'id': 'localhost',
592 'io_timeout': io_timeout, 627 'io_timeout': io_timeout,
593 'output_chunk_start': 0, 628 'output_chunk_start': 0,
594 'task_id': 23, 629 'task_id': 23,
595 }, 630 },
631 'follow_redirects': False,
632 'headers': auth_headers or {},
596 }, 633 },
597 kwargs) 634 kwargs)
598 return check_final 635 return check_final
599 636
600 def _load_and_run(self, manifest): 637 def _load_and_run(self, manifest):
601 # Dot not mock time since this test class is testing timeouts. 638 # Dot not mock time since this test class is testing timeouts.
602 server = 'https://localhost:1' 639 server = 'https://localhost:1'
603 in_file = os.path.join(self.work_dir, 'task_runner_in.json') 640 in_file = os.path.join(self.work_dir, 'task_runner_in.json')
604 with open(in_file, 'wb') as f: 641 with open(in_file, 'wb') as f:
605 json.dump(manifest, f) 642 json.dump(manifest, f)
606 out_file = os.path.join(self.work_dir, 'task_runner_out.json') 643 out_file = os.path.join(self.work_dir, 'task_runner_out.json')
607 task_runner.load_and_run(in_file, server, 3600., time.time(), out_file, 1) 644 task_runner.load_and_run(
645 in_file, server, None, 3600., time.time(), out_file, 1)
608 with open(out_file, 'rb') as f: 646 with open(out_file, 'rb') as f:
609 return json.load(f) 647 return json.load(f)
610 648
611 def _run_command(self, task_details): 649 def _run_command(self, task_details):
612 # Dot not mock time since this test class is testing timeouts. 650 # Dot not mock time since this test class is testing timeouts.
613 server = 'https://localhost:1' 651 server = 'https://localhost:1'
614 return task_runner.run_command( 652 return task_runner.run_command(
615 server, task_details, self.work_dir, 3600., time.time(), 1) 653 server, task_details, self.work_dir, None, 3600., time.time(), 1)
616 654
617 def test_hard(self): 655 def test_hard(self):
618 # Actually 0xc000013a 656 # Actually 0xc000013a
619 sig = -1073741510 if sys.platform == 'win32' else -signal.SIGTERM 657 sig = -1073741510 if sys.platform == 'win32' else -signal.SIGTERM
620 self.requests(hard_timeout=True, exit_code=sig) 658 self.requests(hard_timeout=True, exit_code=sig)
621 task_details = self.get_task_details( 659 task_details = self.get_task_details(
622 self.SCRIPT_HANG, hard_timeout=self.SHORT_TIME_OUT) 660 self.SCRIPT_HANG, hard_timeout=self.SHORT_TIME_OUT)
623 expected = { 661 expected = {
624 u'exit_code': sig, 662 u'exit_code': sig,
625 u'hard_timeout': True, 663 u'hard_timeout': True,
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
794 }, 832 },
795 u'upload': { 833 u'upload': {
796 u'items_cold': [], 834 u'items_cold': [],
797 u'items_hot': [], 835 u'items_hot': [],
798 }, 836 },
799 }, 837 },
800 'output': 'hi\n', 838 'output': 'hi\n',
801 'output_chunk_start': 0, 839 'output_chunk_start': 0,
802 'task_id': 23, 840 'task_id': 23,
803 }, 841 },
842 'follow_redirects': False,
843 'headers': {},
804 }, 844 },
805 kwargs) 845 kwargs)
806 requests = [ 846 requests = [
807 ( 847 (
808 'https://localhost:1/swarming/api/v1/bot/task_update/23', 848 'https://localhost:1/swarming/api/v1/bot/task_update/23',
809 self.get_check_first(0.), 849 self.get_check_first(0.),
810 {'ok': True}, 850 {'ok': True},
811 ), 851 ),
812 ( 852 (
813 'https://localhost:1/swarming/api/v1/bot/task_update/23', 853 'https://localhost:1/swarming/api/v1/bot/task_update/23',
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
913 u'items_hot': [], 953 u'items_hot': [],
914 }, 954 },
915 u'upload': { 955 u'upload': {
916 u'items_cold': [], 956 u'items_cold': [],
917 u'items_hot': [], 957 u'items_hot': [],
918 }, 958 },
919 }, 959 },
920 'output_chunk_start': 0, 960 'output_chunk_start': 0,
921 'task_id': 23, 961 'task_id': 23,
922 }, 962 },
963 'follow_redirects': False,
964 'headers': {},
923 }, 965 },
924 kwargs) 966 kwargs)
925 requests = [ 967 requests = [
926 ( 968 (
927 'https://localhost:1/swarming/api/v1/bot/task_update/23', 969 'https://localhost:1/swarming/api/v1/bot/task_update/23',
928 self.get_check_first(0.), 970 self.get_check_first(0.),
929 {'ok': True}, 971 {'ok': True},
930 ), 972 ),
931 ( 973 (
932 'https://localhost:1/swarming/api/v1/bot/task_update/23', 974 'https://localhost:1/swarming/api/v1/bot/task_update/23',
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
1096 fix_encoding.fix_encoding() 1138 fix_encoding.fix_encoding()
1097 if '-v' in sys.argv: 1139 if '-v' in sys.argv:
1098 unittest.TestCase.maxDiff = None 1140 unittest.TestCase.maxDiff = None
1099 logging_utils.prepare_logging(None) 1141 logging_utils.prepare_logging(None)
1100 logging_utils.set_console_level( 1142 logging_utils.set_console_level(
1101 logging.DEBUG if '-v' in sys.argv else logging.CRITICAL+1) 1143 logging.DEBUG if '-v' in sys.argv else logging.CRITICAL+1)
1102 # Fix litteral text expectation. 1144 # Fix litteral text expectation.
1103 os.environ['LANG'] = 'en_US.UTF-8' 1145 os.environ['LANG'] = 'en_US.UTF-8'
1104 os.environ['LANGUAGE'] = 'en_US.UTF-8' 1146 os.environ['LANGUAGE'] = 'en_US.UTF-8'
1105 unittest.main() 1147 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698