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

Side by Side Diff: appengine/swarming/server/task_request_test.py

Issue 2926713004: Add support for repeated keys in TaskRequest. (Closed)
Patch Set: rebase Created 3 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 # Copyright 2014 The LUCI Authors. All rights reserved. 2 # Copyright 2014 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 datetime 6 import datetime
7 import logging 7 import logging
8 import random 8 import random
9 import sys 9 import sys
10 import unittest 10 import unittest
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
68 }) 68 })
69 69
70 inputs_ref = properties.pop('inputs_ref', { 70 inputs_ref = properties.pop('inputs_ref', {
71 'isolatedserver': 'https://isolateserver.appspot.com', 71 'isolatedserver': 'https://isolateserver.appspot.com',
72 'namespace': 'default-gzip', 72 'namespace': 'default-gzip',
73 }) 73 })
74 74
75 properties = merge(properties, { 75 properties = merge(properties, {
76 'cipd_input': cipd_input, 76 'cipd_input': cipd_input,
77 'command': [u'command1', u'arg1'], 77 'command': [u'command1', u'arg1'],
78 'dimensions': { 78 'dimensions_flat': [
79 u'OS': u'Windows-3.1.1', 79 u'hostname:localhost',
80 u'hostname': u'localhost', 80 u'os:Windows-3.1.1',
81 u'pool': u'default', 81 # Test repeated keys. In this case, the bot has to be in both pools.
82 }, 82 u'pool:default',
83 u'pool:testing',
84 ],
83 'env': {u'foo': u'bar', u'joe': u'2'}, 85 'env': {u'foo': u'bar', u'joe': u'2'},
84 'execution_timeout_secs': 30, 86 'execution_timeout_secs': 30,
85 'grace_period_secs': 30, 87 'grace_period_secs': 30,
86 'idempotent': False, 88 'idempotent': False,
87 'inputs_ref': inputs_ref, 89 'inputs_ref': inputs_ref,
88 'io_timeout_secs': None, 90 'io_timeout_secs': None,
89 'has_secret_bytes': 'secret_bytes' in kwargs, 91 'has_secret_bytes': 'secret_bytes' in kwargs,
90 }) 92 })
91 properties['dimensions_dict'] = properties.pop('dimensions')
92 now = utils.utcnow() 93 now = utils.utcnow()
93 args = { 94 args = {
94 'created_ts': now, 95 'created_ts': now,
95 'name': 'Request name', 96 'name': 'Request name',
96 'priority': 50, 97 'priority': 50,
97 'properties': properties, 98 'properties': properties,
98 'expiration_ts': now + datetime.timedelta(seconds=30), 99 'expiration_ts': now + datetime.timedelta(seconds=30),
99 'tags': [u'tag:1'], 100 'tags': [u'tag:1'],
100 'user': 'Jesus', 101 'user': 'Jesus',
101 } 102 }
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
235 'version': u'git_revision:deadbeef', 236 'version': u'git_revision:deadbeef',
236 }, 237 },
237 'packages': [{ 238 'packages': [{
238 'package_name': u'rm', 239 'package_name': u'rm',
239 'path': u'bin', 240 'path': u'bin',
240 'version': u'git_revision:deadbeef', 241 'version': u'git_revision:deadbeef',
241 }], 242 }],
242 'server': u'https://chrome-infra-packages.appspot.com' 243 'server': u'https://chrome-infra-packages.appspot.com'
243 }, 244 },
244 'command': [u'command1', u'arg1'], 245 'command': [u'command1', u'arg1'],
245 'dimensions': { 246 'dimensions': [
246 u'OS': u'Windows-3.1.1', 247 (u'hostname', u'localhost'),
247 u'hostname': u'localhost', 248 (u'os', u'Windows-3.1.1'),
248 u'pool': u'default', 249 (u'pool', u'default'),
249 }, 250 (u'pool', u'testing'),
251 ],
250 'env': {u'foo': u'bar', u'joe': u'2'}, 252 'env': {u'foo': u'bar', u'joe': u'2'},
251 'extra_args': [], 253 'extra_args': [],
252 'execution_timeout_secs': 30, 254 'execution_timeout_secs': 30,
253 'grace_period_secs': 30, 255 'grace_period_secs': 30,
254 'idempotent': True, 256 'idempotent': True,
255 'inputs_ref': { 257 'inputs_ref': {
256 'isolated': None, 258 'isolated': None,
257 'isolatedserver': u'https://isolateserver.appspot.com', 259 'isolatedserver': u'https://isolateserver.appspot.com',
258 'namespace': u'default-gzip', 260 'namespace': u'default-gzip',
259 }, 261 },
260 'io_timeout_secs': None, 262 'io_timeout_secs': None,
261 'outputs': [], 263 'outputs': [],
262 'has_secret_bytes': True, 264 'has_secret_bytes': True,
263 } 265 }
264 expected_request = { 266 expected_request = {
265 'authenticated': auth_testing.DEFAULT_MOCKED_IDENTITY, 267 'authenticated': auth_testing.DEFAULT_MOCKED_IDENTITY,
266 'name': u'Request name', 268 'name': u'Request name',
267 'parent_task_id': unicode(parent_id), 269 'parent_task_id': unicode(parent_id),
268 'priority': 49, 270 'priority': 49,
269 'properties': expected_properties, 271 'properties': expected_properties,
270 # Intentionally hard code the hash value since it has to be deterministic. 272 # Intentionally hard code the hash value since it has to be deterministic.
271 # Other unit tests should use the calculated value. 273 # Other unit tests should use the calculated value.
272 'properties_hash': 274 'properties_hash':
273 '258e0894f2589a7bc2b46bd563d01f64300ae08938fb14b3d750baff94ba714e', 275 '40635327d825d2e12ba704b7db72be55dc1dcf195ff881eff558c1be2a9f7ef6',
274 'pubsub_topic': None, 276 'pubsub_topic': None,
275 'pubsub_userdata': None, 277 'pubsub_userdata': None,
276 'service_account': u'none', 278 'service_account': u'none',
277 'tags': [ 279 'tags': [
278 u'OS:Windows-3.1.1',
279 u'hostname:localhost', 280 u'hostname:localhost',
281 u'os:Windows-3.1.1',
280 u'pool:default', 282 u'pool:default',
283 u'pool:testing',
281 u'priority:49', 284 u'priority:49',
282 u'service_account:none', 285 u'service_account:none',
283 u'tag:1', 286 u'tag:1',
284 u'user:Jesus', 287 u'user:Jesus',
285 ], 288 ],
286 'user': u'Jesus', 289 'user': u'Jesus',
287 } 290 }
288 actual = request.to_dict() 291 actual = request.to_dict()
289 actual.pop('created_ts') 292 actual.pop('created_ts')
290 actual.pop('expiration_ts') 293 actual.pop('expiration_ts')
(...skipping 23 matching lines...) Expand all
314 'version': u'git_revision:deadbeef', 317 'version': u'git_revision:deadbeef',
315 }, 318 },
316 'packages': [{ 319 'packages': [{
317 'package_name': u'rm', 320 'package_name': u'rm',
318 'path': u'bin', 321 'path': u'bin',
319 'version': u'git_revision:deadbeef', 322 'version': u'git_revision:deadbeef',
320 }], 323 }],
321 'server': u'https://chrome-infra-packages.appspot.com' 324 'server': u'https://chrome-infra-packages.appspot.com'
322 }, 325 },
323 'command': [u'command1', u'arg1'], 326 'command': [u'command1', u'arg1'],
324 'dimensions': { 327 'dimensions': [
325 u'OS': u'Windows-3.1.1', 328 (u'hostname', u'localhost'),
326 u'hostname': u'localhost', 329 (u'os', u'Windows-3.1.1'),
327 u'pool': u'default', 330 (u'pool', u'default'),
328 }, 331 (u'pool', u'testing'),
332 ],
329 'env': {u'foo': u'bar', u'joe': u'2'}, 333 'env': {u'foo': u'bar', u'joe': u'2'},
330 'extra_args': [], 334 'extra_args': [],
331 'execution_timeout_secs': 30, 335 'execution_timeout_secs': 30,
332 'grace_period_secs': 30, 336 'grace_period_secs': 30,
333 'idempotent': True, 337 'idempotent': True,
334 'inputs_ref': { 338 'inputs_ref': {
335 'isolated': None, 339 'isolated': None,
336 'isolatedserver': u'https://isolateserver.appspot.com', 340 'isolatedserver': u'https://isolateserver.appspot.com',
337 'namespace': u'default-gzip', 341 'namespace': u'default-gzip',
338 }, 342 },
339 'io_timeout_secs': None, 343 'io_timeout_secs': None,
340 'outputs': [], 344 'outputs': [],
341 'has_secret_bytes': True, 345 'has_secret_bytes': True,
342 } 346 }
343 expected_request = { 347 expected_request = {
344 'authenticated': auth_testing.DEFAULT_MOCKED_IDENTITY, 348 'authenticated': auth_testing.DEFAULT_MOCKED_IDENTITY,
345 'name': u'Request name', 349 'name': u'Request name',
346 'parent_task_id': unicode(parent_id), 350 'parent_task_id': unicode(parent_id),
347 'priority': 49, 351 'priority': 49,
348 'properties': expected_properties, 352 'properties': expected_properties,
349 # Intentionally hard code the hash value since it has to be deterministic. 353 # Intentionally hard code the hash value since it has to be deterministic.
350 # Other unit tests should use the calculated value. 354 # Other unit tests should use the calculated value.
351 'properties_hash': 355 'properties_hash':
352 '693715e9539552e2ece434e25a665d437cfe4685504a3c7bad6356f9feffee2a', 356 'cbbf1b58e73a27c15bae48019cd6678a47a4bfb637c63b47af7231e11d82109e',
353 'pubsub_topic': None, 357 'pubsub_topic': None,
354 'pubsub_userdata': None, 358 'pubsub_userdata': None,
355 'service_account': u'none', 359 'service_account': u'none',
356 'tags': [ 360 'tags': [
357 u'OS:Windows-3.1.1',
358 u'hostname:localhost', 361 u'hostname:localhost',
362 u'os:Windows-3.1.1',
359 u'pool:default', 363 u'pool:default',
364 u'pool:testing',
360 u'priority:49', 365 u'priority:49',
361 u'service_account:none', 366 u'service_account:none',
362 u'tag:1', 367 u'tag:1',
363 u'user:Jesus', 368 u'user:Jesus',
364 ], 369 ],
365 'user': u'Jesus', 370 'user': u'Jesus',
366 } 371 }
367 actual = request.to_dict() 372 actual = request.to_dict()
368 # expiration_ts - created_ts == scheduling_expiration_secs. 373 # expiration_ts - created_ts == scheduling_expiration_secs.
369 actual.pop('created_ts') 374 actual.pop('created_ts')
(...skipping 14 matching lines...) Expand all
384 _gen_request(parent_task_id='1d69b9f088008810') 389 _gen_request(parent_task_id='1d69b9f088008810')
385 390
386 def test_init_new_request_idempotent(self): 391 def test_init_new_request_idempotent(self):
387 request = mkreq(_gen_request(properties=dict(idempotent=True))) 392 request = mkreq(_gen_request(properties=dict(idempotent=True)))
388 as_dict = request.to_dict() 393 as_dict = request.to_dict()
389 self.assertEqual(True, as_dict['properties']['idempotent']) 394 self.assertEqual(True, as_dict['properties']['idempotent'])
390 # Intentionally hard code the hash value since it has to be deterministic. 395 # Intentionally hard code the hash value since it has to be deterministic.
391 # Other unit tests should use the calculated value. 396 # Other unit tests should use the calculated value.
392 # Ensure the algorithm is deterministic. 397 # Ensure the algorithm is deterministic.
393 self.assertEqual( 398 self.assertEqual(
394 'c7445927612637c589b72dd47c4657b166a53ac6ecdfd08c167539331a7890d3', 399 'b4ee0e7018e5fdb414ede87d0da2bc1479211191c5cd6a7af552916d4aa40d25',
395 as_dict['properties_hash']) 400 as_dict['properties_hash'])
396 401
397 def test_init_new_request_bot_service_account(self): 402 def test_init_new_request_bot_service_account(self):
398 request = mkreq(_gen_request(service_account_token='bot')) 403 request = mkreq(_gen_request(service_account_token='bot'))
399 as_dict = request.to_dict() 404 as_dict = request.to_dict()
400 self.assertEqual('bot', as_dict['service_account']) 405 self.assertEqual('bot', as_dict['service_account'])
401 self.assertIn(u'service_account:bot', as_dict['tags']) 406 self.assertIn(u'service_account:bot', as_dict['tags'])
402 407
403 def test_duped(self): 408 def test_duped(self):
404 # Two TestRequest with the same properties. 409 # Two TestRequest with the same properties.
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
539 caches=[dict(name='git_chromium', path='git_cache')], 544 caches=[dict(name='git_chromium', path='git_cache')],
540 cipd_input=dict(packages=[ 545 cipd_input=dict(packages=[
541 dict(package_name='foo', path='git_cache', version='latest')])))) 546 dict(package_name='foo', path='git_cache', version='latest')]))))
542 mkcachereq() 547 mkcachereq()
543 mkcachereq(dict(name='git_chromium', path='git_cache')) 548 mkcachereq(dict(name='git_chromium', path='git_cache'))
544 mkcachereq( 549 mkcachereq(
545 dict(name='git_chromium', path='git_cache'), 550 dict(name='git_chromium', path='git_cache'),
546 dict(name='build_chromium', path='out')) 551 dict(name='build_chromium', path='out'))
547 552
548 # Dimensions. 553 # Dimensions.
549 with self.assertRaises(TypeError):
550 mkreq(_gen_request(properties=dict(dimensions=[])))
551 with self.assertRaises(datastore_errors.BadValueError): 554 with self.assertRaises(datastore_errors.BadValueError):
552 mkreq(_gen_request(properties=dict(dimensions={}))) 555 mkreq(_gen_request(properties=dict(dimensions_flat={})))
556 with self.assertRaises(datastore_errors.BadValueError):
557 mkreq(_gen_request(properties=dict(dimensions_flat=[])))
558 with self.assertRaises(datastore_errors.BadValueError):
559 mkreq(_gen_request(properties=dict(dimensions_dict={u'id': u'b'})))
553 with self.assertRaises(datastore_errors.BadValueError): 560 with self.assertRaises(datastore_errors.BadValueError):
554 mkreq(_gen_request( 561 mkreq(_gen_request(
555 properties=dict(dimensions={u'id': u'b', u'a:': u'b'}))) 562 properties=dict(dimensions_flat=[u'id:b', u'a :b'])))
563 with self.assertRaises(datastore_errors.BadValueError):
564 mkreq(_gen_request(
565 properties=dict(dimensions_flat=[u'id:b', u'a.:b'])))
556 mkreq(_gen_request( 566 mkreq(_gen_request(
557 properties=dict(dimensions={u'id': u'b', u'a.': u'b'}))) 567 properties=dict(dimensions_flat=[u'a.:b', u'id:b'])))
558 568
559 # Environment. 569 # Environment.
560 with self.assertRaises(TypeError): 570 with self.assertRaises(TypeError):
561 mkreq(_gen_request(properties=dict(env=[]))) 571 mkreq(_gen_request(properties=dict(env=[])))
562 with self.assertRaises(TypeError): 572 with self.assertRaises(TypeError):
563 mkreq(_gen_request(properties=dict(env={u'a': 1}))) 573 mkreq(_gen_request(properties=dict(env={u'a': 1})))
564 mkreq(_gen_request(properties=dict(env={}))) 574 mkreq(_gen_request(properties=dict(env={})))
565 575
566 # Priority. 576 # Priority.
567 with self.assertRaises(datastore_errors.BadValueError): 577 with self.assertRaises(datastore_errors.BadValueError):
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
644 'version': u'git_revision:deadbeef', 654 'version': u'git_revision:deadbeef',
645 }, 655 },
646 'packages': [{ 656 'packages': [{
647 'package_name': u'rm', 657 'package_name': u'rm',
648 'path': u'bin', 658 'path': u'bin',
649 'version': u'git_revision:deadbeef', 659 'version': u'git_revision:deadbeef',
650 }], 660 }],
651 'server': u'https://chrome-infra-packages.appspot.com' 661 'server': u'https://chrome-infra-packages.appspot.com'
652 }, 662 },
653 'command': [u'command1', u'arg1'], 663 'command': [u'command1', u'arg1'],
654 'dimensions': { 664 'dimensions': [
655 u'OS': u'Windows-3.1.1', 665 (u'hostname', u'localhost'),
656 u'hostname': u'localhost', 666 (u'os', u'Windows-3.1.1'),
657 u'pool': u'default', 667 (u'pool', u'default'),
658 }, 668 (u'pool', u'testing'),
669 ],
659 'env': {u'foo': u'bar', u'joe': u'2'}, 670 'env': {u'foo': u'bar', u'joe': u'2'},
660 'execution_timeout_secs': 30, 671 'execution_timeout_secs': 30,
661 'extra_args': [], 672 'extra_args': [],
662 'grace_period_secs': 30, 673 'grace_period_secs': 30,
663 'idempotent': False, 674 'idempotent': False,
664 'inputs_ref': { 675 'inputs_ref': {
665 'isolated': None, 676 'isolated': None,
666 'isolatedserver': u'https://isolateserver.appspot.com', 677 'isolatedserver': u'https://isolateserver.appspot.com',
667 'namespace': u'default-gzip', 678 'namespace': u'default-gzip',
668 }, 679 },
669 'io_timeout_secs': None, 680 'io_timeout_secs': None,
670 'outputs': [], 681 'outputs': [],
671 'has_secret_bytes': False, 682 'has_secret_bytes': False,
672 } 683 }
673 # Differences from new_request() are: 684 # Differences from new_request() are:
674 # - parent_task_id was reset to None. 685 # - parent_task_id was reset to None.
675 # - tag 'user:' was replaced 686 # - tag 'user:' was replaced
676 # - user was replaced. 687 # - user was replaced.
677 expected_request = { 688 expected_request = {
678 'authenticated': auth_testing.DEFAULT_MOCKED_IDENTITY, 689 'authenticated': auth_testing.DEFAULT_MOCKED_IDENTITY,
679 'name': u'Request name (Retry #1)', 690 'name': u'Request name (Retry #1)',
680 'parent_task_id': None, 691 'parent_task_id': None,
681 'priority': 49, 692 'priority': 49,
682 'properties': expected_properties, 693 'properties': expected_properties,
683 'properties_hash': None, 694 'properties_hash': None,
684 'pubsub_topic': None, 695 'pubsub_topic': None,
685 'pubsub_userdata': None, 696 'pubsub_userdata': None,
686 'service_account': u'none', 697 'service_account': u'none',
687 'tags': [ 698 'tags': [
688 u'OS:Windows-3.1.1',
689 u'hostname:localhost', 699 u'hostname:localhost',
700 u'os:Windows-3.1.1',
690 u'pool:default', 701 u'pool:default',
702 u'pool:testing',
691 u'priority:49', 703 u'priority:49',
692 u'service_account:none', 704 u'service_account:none',
693 u'tag:1', 705 u'tag:1',
694 u'user:mocked@example.com', 706 u'user:mocked@example.com',
695 ], 707 ],
696 'user': u'mocked@example.com', 708 'user': u'mocked@example.com',
697 } 709 }
698 actual = request.to_dict() 710 actual = request.to_dict()
699 # expiration_ts - created_ts == deadline_to_run. 711 # expiration_ts - created_ts == deadline_to_run.
700 actual.pop('created_ts') 712 actual.pop('created_ts')
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
743 with self.assertRaises(datastore_errors.BadValueError): 755 with self.assertRaises(datastore_errors.BadValueError):
744 task_request.SecretBytes(secret_bytes='a'*(20*1024+1)).put() 756 task_request.SecretBytes(secret_bytes='a'*(20*1024+1)).put()
745 757
746 758
747 if __name__ == '__main__': 759 if __name__ == '__main__':
748 if '-v' in sys.argv: 760 if '-v' in sys.argv:
749 unittest.TestCase.maxDiff = None 761 unittest.TestCase.maxDiff = None
750 logging.basicConfig( 762 logging.basicConfig(
751 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR) 763 level=logging.DEBUG if '-v' in sys.argv else logging.ERROR)
752 unittest.main() 764 unittest.main()
OLDNEW
« no previous file with comments | « appengine/swarming/server/task_request.py ('k') | appengine/swarming/server/task_result_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698