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

Side by Side Diff: appengine/swarming/handlers_endpoints_test.py

Issue 2856733002: swarming: add transaction_id to tasks.new request
Patch Set: nits Created 3 years, 7 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 2015 The LUCI Authors. All rights reserved. 3 # Copyright 2015 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 datetime 8 import datetime
9 import json 9 import json
10 import logging 10 import logging
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
56 webapp2.WSGIApplication(handlers_bot.get_routes(), debug=True), 56 webapp2.WSGIApplication(handlers_bot.get_routes(), debug=True),
57 extra_environ={ 57 extra_environ={
58 'REMOTE_ADDR': self.source_ip, 58 'REMOTE_ADDR': self.source_ip,
59 'SERVER_SOFTWARE': os.environ['SERVER_SOFTWARE'], 59 'SERVER_SOFTWARE': os.environ['SERVER_SOFTWARE'],
60 }) 60 })
61 self.mock( 61 self.mock(
62 ereporter2, 'log_request', 62 ereporter2, 'log_request',
63 lambda *args, **kwargs: self.fail('%s, %s' % (args, kwargs))) 63 lambda *args, **kwargs: self.fail('%s, %s' % (args, kwargs)))
64 # Client API test cases run by default as user. 64 # Client API test cases run by default as user.
65 self.set_as_user() 65 self.set_as_user()
66 self.pubsub_tasks = []
66 self.mock(utils, 'enqueue_task', self._enqueue_task) 67 self.mock(utils, 'enqueue_task', self._enqueue_task)
67 68
68 @ndb.non_transactional 69 @ndb.non_transactional
69 def _enqueue_task(self, url, queue_name, **kwargs): 70 def _enqueue_task(self, url, queue_name, **kwargs):
70 if queue_name == 'task-dimensions': 71 if queue_name == 'task-dimensions':
71 # Call directly into it, ignores any current transaction. 72 # Call directly into it, ignores any current transaction.
72 handlers_backend.TaskDimensionsHandler.tidy_stale(kwargs['payload']) 73 handlers_backend.TaskDimensionsHandler.tidy_stale(kwargs['payload'])
73 return True 74 return True
74 if queue_name == 'pubsub': 75 if queue_name == 'pubsub':
76 task = {'url': url, 'queue_name': queue_name}
77 task.update(kwargs)
78 self.pubsub_tasks.append(task)
75 return True 79 return True
76 self.fail(url) 80 self.fail(url)
77 81
78 82
79 class ServerApiTest(BaseTest): 83 class ServerApiTest(BaseTest):
80 api_service_cls = handlers_endpoints.SwarmingServerService 84 api_service_cls = handlers_endpoints.SwarmingServerService
81 85
82 def test_details(self): 86 def test_details(self):
83 """Asserts that server_details returns the correct version.""" 87 """Asserts that server_details returns the correct version."""
84 self.mock(config.config, 'config_service_hostname', lambda: 'a.server') 88 self.mock(config.config, 'config_service_hostname', lambda: 'a.server')
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after
618 ], 622 ],
619 u'user': u'joe@localhost', 623 u'user': u'joe@localhost',
620 }, 624 },
621 ], 625 ],
622 u'now': str_now_30, 626 u'now': str_now_30,
623 } 627 }
624 self.assertEqual( 628 self.assertEqual(
625 expected, 629 expected,
626 self.call_api('requests', body=message_to_dict(request)).json) 630 self.call_api('requests', body=message_to_dict(request)).json)
627 631
632 def test_new_ok_deduped_by_transaction_id(self):
633 """Asserts that new returns task result for deduped."""
634 # Run a task to completion.
635 self.mock(random, 'getrandbits', lambda _: 0x88)
636 now = self.mock_now(datetime.datetime(2010, 1, 2, 3, 4, 5))
637 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO))
638 new_req, _, task_id = self.client_create_task_raw(
639 name='task', tags=['project:yay', 'commit:post'],
640 properties=dict(idempotent=True),
641 transaction_id='txn')
642 self.set_as_bot()
643 self.bot_run_task()
644
645 self.mock(random, 'getrandbits', lambda _: 0x66)
646 self.set_as_user()
647
648 expected = {
649 u'request': {
650 u'authenticated': u'user:user@example.com',
651 u'created_ts': str_now,
652 u'expiration_secs': u'86400',
653 u'name': u'task',
654 u'priority': u'100',
655 u'properties': {
656 u'cipd_input': {
657 u'client_package': {
658 u'package_name': u'infra/tools/cipd/${platform}',
659 u'version': u'git_revision:deadbeef',
660 },
661 u'packages': [{
662 u'package_name': u'rm',
663 u'path': u'bin',
664 u'version': u'git_revision:deadbeef',
665 }],
666 u'server': u'https://chrome-infra-packages.appspot.com',
667 },
668 u'command': [u'python', u'run_test.py'],
669 u'dimensions': [
670 {u'key': u'os', u'value': u'Amiga'},
671 {u'key': u'pool', u'value': u'default'},
672 ],
673 u'execution_timeout_secs': u'3600',
674 u'grace_period_secs': u'30',
675 u'idempotent': True,
676 u'io_timeout_secs': u'1200',
677 u'outputs': [u'foo', u'path/to/foobar'],
678 },
679 u'service_account': u'none',
680 u'tags': [
681 u'commit:post',
682 u'os:Amiga',
683 u'pool:default',
684 u'priority:100',
685 u'project:yay',
686 u'service_account:none',
687 u'user:joe@localhost',
688 ],
689 u'user': u'joe@localhost',
690 },
691 u'task_id': unicode(task_id),
692 u'task_result': {
693 u'bot_dimensions': [
694 {u'key': u'id', u'value': [u'bot1']},
695 {u'key': u'os', u'value': [u'Amiga']},
696 {u'key': u'pool', u'value': [u'default']},
697 ],
698 u'bot_id': u'bot1',
699 u'bot_version': self.bot_version,
700 u'completed_ts': str_now,
701 u'costs_usd': [0.1],
702 u'created_ts': str_now,
703 u'duration': 0.1,
704 u'exit_code': u'0',
705 u'failure': False,
706 u'internal_failure': False,
707 u'modified_ts': str_now,
708 u'name': u'task',
709 u'properties_hash': (
710 u'd35fe05074cbd9a2356c77c9983c71476f3a5f9415c5c5b1f3e2cdf7826b7261'
711 ),
712 u'run_id': u'5cee488008811',
713 u'server_versions': [u'v1a'],
714 u'started_ts': str_now,
715 u'state': u'COMPLETED',
716 u'tags': [
717 u'commit:post',
718 u'os:Amiga',
719 u'pool:default',
720 u'priority:100',
721 u'project:yay',
722 u'service_account:none',
723 u'user:joe@localhost',
724 ],
725 u'task_id': unicode(task_id),
726 u'try_number': u'1',
727 u'user': u'joe@localhost',
728 },
729 }
730 response = self.call_api('new', body=message_to_dict(new_req))
731 self.assertEqual(expected, response.json)
732
628 def test_new_ok_isolated(self): 733 def test_new_ok_isolated(self):
629 """Asserts that new generates appropriate metadata.""" 734 """Asserts that new generates appropriate metadata."""
630 self.mock(random, 'getrandbits', lambda _: 0x88) 735 self.mock(random, 'getrandbits', lambda _: 0x88)
631 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 736 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
632 self.mock_now(now) 737 self.mock_now(now)
633 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) 738 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO))
634 request = swarming_rpcs.NewTaskRequest( 739 request = swarming_rpcs.NewTaskRequest(
635 expiration_secs=30, 740 expiration_secs=30,
636 name='job1', 741 name='job1',
637 priority=200, 742 priority=200,
(...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after
843 u'user:joe@localhost', 948 u'user:joe@localhost',
844 ], 949 ],
845 u'user': u'joe@localhost', 950 u'user': u'joe@localhost',
846 }, 951 },
847 u'task_id': u'5cee488008810', 952 u'task_id': u'5cee488008810',
848 } 953 }
849 response = self.call_api('new', body=message_to_dict(request)) 954 response = self.call_api('new', body=message_to_dict(request))
850 self.assertEqual(expected, response.json) 955 self.assertEqual(expected, response.json)
851 956
852 def test_mass_cancel(self): 957 def test_mass_cancel(self):
853 notifies = []
854 def enqueue_task_mock(**kwargs):
855 notifies.append(kwargs)
856 return True
857 self.mock(utils, 'enqueue_task', enqueue_task_mock)
858
859 # Create two tasks. 958 # Create two tasks.
860 self.mock(random, 'getrandbits', lambda _: 0x88) 959 self.mock(random, 'getrandbits', lambda _: 0x88)
861 first, second, _, _, _, now_120 = self._gen_three_pending_tasks() 960 first, second, _, _, _, now_120 = self._gen_three_pending_tasks()
862 now_120_str = unicode(now_120.strftime(self.DATETIME_NO_MICRO)) 961 now_120_str = unicode(now_120.strftime(self.DATETIME_NO_MICRO))
863 962
864 expected = { 963 expected = {
865 u'matched': u'2', 964 u'matched': u'2',
866 u'now': now_120_str, 965 u'now': now_120_str,
867 } 966 }
868 self.set_as_admin() 967 self.set_as_admin()
869 968
870 def enqueue_task(*args, **kwargs): 969 def enqueue_task(*args, **kwargs):
871 self.assertEqual('%s,%s' % (second, first), 970 self.assertEqual('%s,%s' % (second, first),
872 kwargs.get('payload', '')) 971 kwargs.get('payload', ''))
873 # check URL 972 # check URL
874 self.assertEqual('/internal/taskqueue/cancel-tasks', args[0]) 973 self.assertEqual('/internal/taskqueue/cancel-tasks', args[0])
875 # check task queue 974 # check task queue
876 self.assertEqual('cancel-tasks', args[1]) 975 self.assertEqual('cancel-tasks', args[1])
877 return True 976 return True
878 self.mock(utils, 'enqueue_task', enqueue_task) 977 self.mock(utils, 'enqueue_task', enqueue_task)
879 978
880 response = self.call_api('cancel', body={u'tags': [u'os:Win']}) 979 response = self.call_api('cancel', body={u'tags': [u'os:Win']})
881 self.assertEqual(expected, response.json) 980 self.assertEqual(expected, response.json)
882 981
982 def test_cancel_by_transaction_id_ok(self):
983 """Asserts that task cancellation goes smoothly."""
984 # Create and cancel a task as a non-privileged user.
985 self.mock(random, 'getrandbits', lambda _: 0x88)
986 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
987 self.mock_now(now)
988 _, _, task_id = self.client_create_task_raw(
989 pubsub_topic='projects/abc/topics/def',
990 pubsub_userdata='blah',
991 transaction_id='txn')
992 expected = {
993 u'task_id': task_id,
994 u'ok': True,
995 u'was_running': False
996 }
997 response = self.call_api(
998 'cancel_by_transaction_id', body={'transaction_id': 'txn'})
999 self.assertEqual(expected, response.json)
883 1000
1001 _, result = handlers_endpoints.get_request_and_result(task_id)
1002 self.assertEqual(result.state, task_result.State.CANCELED)
1003
1004 expected = [
1005 {
1006 'payload': '{"auth_token":null,"task_id":"5cee488008810",'
1007 '"topic":"projects/abc/topics/def","userdata":"blah"}',
1008 'queue_name': 'pubsub',
1009 'transactional': True,
1010 'url': '/internal/taskqueue/pubsub/5cee488008810',
1011 },
1012 ]
1013 self.assertEqual(expected, self.pubsub_tasks)
1014
1015 def test_cancel_by_transaction_id_forbidden(self):
1016 """Asserts that non-privileged non-owner can't cancel tasks."""
1017 # Create a task as an admin.
1018 self.mock(random, 'getrandbits', lambda _: 0x88)
1019 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1020 self.mock_now(now)
1021 self.set_as_admin()
1022 self.client_create_task_raw(
1023 pubsub_topic='projects/abc/topics/def',
1024 pubsub_userdata='blah',
1025 transaction_id='txn')
1026
1027 # Attempt to cancel as non-privileged user -> HTTP 403.
1028 self.set_as_user()
1029 self.call_api(
1030 'cancel_by_transaction_id', body={'transaction_id': 'txn'}, status=403)
1031
1032 self.assertEqual([], self.pubsub_tasks)
884 1033
885 def test_list_ok(self): 1034 def test_list_ok(self):
886 """Asserts that list requests all TaskResultSummaries.""" 1035 """Asserts that list requests all TaskResultSummaries."""
887 first, second, str_now_120, start, end = self._gen_two_tasks() 1036 first, second, str_now_120, start, end = self._gen_two_tasks()
888 first_no_perf = first.copy() 1037 first_no_perf = first.copy()
889 first_no_perf.pop('performance_stats') 1038 first_no_perf.pop('performance_stats')
890 # Basic request. 1039 # Basic request.
891 request = swarming_rpcs.TasksRequest( 1040 request = swarming_rpcs.TasksRequest(
892 end=end, start=start, include_performance_stats=True) 1041 end=end, start=start, include_performance_stats=True)
893 expected = {u'now': str_now_120, u'items': [second, first]} 1042 expected = {u'now': str_now_120, u'items': [second, first]}
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 u'ts': unicode(now.strftime(self.DATETIME_FORMAT)), 1208 u'ts': unicode(now.strftime(self.DATETIME_FORMAT)),
1060 } 1209 }
1061 self.assertEqual(expected, self.call_api('tags', body={}).json) 1210 self.assertEqual(expected, self.call_api('tags', body={}).json)
1062 1211
1063 def _gen_two_tasks(self): 1212 def _gen_two_tasks(self):
1064 # first request 1213 # first request
1065 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 1214 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1066 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) 1215 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO))
1067 self.mock_now(now) 1216 self.mock_now(now)
1068 self.mock(random, 'getrandbits', lambda _: 0x66) 1217 self.mock(random, 'getrandbits', lambda _: 0x66)
1069 _, first_id = self.client_create_task_raw( 1218 _, _, first_id = self.client_create_task_raw(
1070 name='first', tags=['project:yay', 'commit:post', 'os:Win'], 1219 name='first', tags=['project:yay', 'commit:post', 'os:Win'],
1071 properties=dict(idempotent=True)) 1220 properties=dict(idempotent=True))
1072 self.set_as_bot() 1221 self.set_as_bot()
1073 self.bot_run_task() 1222 self.bot_run_task()
1074 1223
1075 # second request 1224 # second request
1076 self.set_as_user() 1225 self.set_as_user()
1077 self.mock(random, 'getrandbits', lambda _: 0x88) 1226 self.mock(random, 'getrandbits', lambda _: 0x88)
1078 now_60 = self.mock_now(now, 60) 1227 now_60 = self.mock_now(now, 60)
1079 str_now_60 = unicode(now_60.strftime(self.DATETIME_NO_MICRO)) 1228 str_now_60 = unicode(now_60.strftime(self.DATETIME_NO_MICRO))
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1186 utils.datetime_to_timestamp(now + datetime.timedelta(days=1)) / 1335 utils.datetime_to_timestamp(now + datetime.timedelta(days=1)) /
1187 1000000.) 1336 1000000.)
1188 self.set_as_privileged_user() 1337 self.set_as_privileged_user()
1189 return first, second, str_now_120, start, end 1338 return first, second, str_now_120, start, end
1190 1339
1191 def _gen_three_pending_tasks(self): 1340 def _gen_three_pending_tasks(self):
1192 # Creates three pending tasks, spaced 1 minute apart 1341 # Creates three pending tasks, spaced 1 minute apart
1193 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 1342 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1194 self.mock_now(now) 1343 self.mock_now(now)
1195 self.mock(random, 'getrandbits', lambda _: 0x66) 1344 self.mock(random, 'getrandbits', lambda _: 0x66)
1196 _, first_id = self.client_create_task_raw( 1345 _, _, first_id = self.client_create_task_raw(
1197 name='first', tags=['project:yay', 'commit:abcd', 'os:Win'], 1346 name='first', tags=['project:yay', 'commit:abcd', 'os:Win'],
1198 pubsub_topic='projects/abc/topics/def', 1347 pubsub_topic='projects/abc/topics/def',
1199 pubsub_userdata='1234', 1348 pubsub_userdata='1234',
1200 properties=dict(idempotent=True)) 1349 properties=dict(idempotent=True))
1201 1350
1202 now_60 = self.mock_now(now, 60) 1351 now_60 = self.mock_now(now, 60)
1203 self.mock(random, 'getrandbits', lambda _: 0x88) 1352 self.mock(random, 'getrandbits', lambda _: 0x88)
1204 _, second_id = self.client_create_task_raw( 1353 _, _, second_id = self.client_create_task_raw(
1205 name='second', user='jack@localhost', 1354 name='second', user='jack@localhost',
1206 pubsub_topic='projects/abc/topics/def', 1355 pubsub_topic='projects/abc/topics/def',
1207 pubsub_userdata='5678', 1356 pubsub_userdata='5678',
1208 tags=['project:yay', 'commit:efgh', 'os:Win'], 1357 tags=['project:yay', 'commit:efgh', 'os:Win'],
1209 properties=dict(idempotent=True)) 1358 properties=dict(idempotent=True))
1210 1359
1211 now_120 = self.mock_now(now, 120) 1360 now_120 = self.mock_now(now, 120)
1212 _, third_id = self.client_create_task_raw( 1361 _, _, third_id = self.client_create_task_raw(
1213 name='third', user='jack@localhost', 1362 name='third', user='jack@localhost',
1214 pubsub_topic='projects/abc/topics/def', 1363 pubsub_topic='projects/abc/topics/def',
1215 pubsub_userdata='9000', 1364 pubsub_userdata='9000',
1216 tags=['project:yay', 'commit:ijkhl', 'os:Linux'], 1365 tags=['project:yay', 'commit:ijkhl', 'os:Linux'],
1217 properties=dict(idempotent=True)) 1366 properties=dict(idempotent=True))
1218 1367
1219 return first_id, second_id, third_id, now, now_60, now_120 1368 return first_id, second_id, third_id, now, now_60, now_120
1220 1369
1221 1370
1222 class TaskApiTest(BaseTest): 1371 class TaskApiTest(BaseTest):
1223 api_service_cls = handlers_endpoints.SwarmingTaskService 1372 api_service_cls = handlers_endpoints.SwarmingTaskService
1224 1373
1225 def setUp(self): 1374 def setUp(self):
1226 super(TaskApiTest, self).setUp() 1375 super(TaskApiTest, self).setUp()
1227 self.tasks_api = test_case.Endpoints( 1376 self.tasks_api = test_case.Endpoints(
1228 handlers_endpoints.SwarmingTasksService) 1377 handlers_endpoints.SwarmingTasksService)
1229 1378
1230 def test_cancel_ok(self): 1379 def test_cancel_ok(self):
1231 """Asserts that task cancellation goes smoothly.""" 1380 """Asserts that task cancellation goes smoothly."""
1232 # catch PubSub notification
1233 # Create and cancel a task as a non-privileged user. 1381 # Create and cancel a task as a non-privileged user.
1234 self.mock(random, 'getrandbits', lambda _: 0x88) 1382 self.mock(random, 'getrandbits', lambda _: 0x88)
1235 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 1383 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1236 self.mock_now(now) 1384 self.mock_now(now)
1237 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) 1385 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO))
1238 _, task_id = self.client_create_task_raw( 1386 _, _, task_id = self.client_create_task_raw(
1239 pubsub_topic='projects/abc/topics/def', 1387 pubsub_topic='projects/abc/topics/def',
1240 pubsub_userdata='blah') 1388 pubsub_userdata='blah')
1241 expected = {u'ok': True, u'was_running': False} 1389 expected = {u'ok': True, u'was_running': False}
1242 response = self.call_api('cancel', body={'task_id': task_id}) 1390 response = self.call_api('cancel', body={'task_id': task_id})
1243 self.assertEqual(expected, response.json) 1391 self.assertEqual(expected, response.json)
1244 1392
1245 # determine that the task's state updates correctly 1393 # determine that the task's state updates correctly
1246 expected = { 1394 expected = {
1247 u'abandoned_ts': str_now, 1395 u'abandoned_ts': str_now,
1248 u'created_ts': str_now, 1396 u'created_ts': str_now,
(...skipping 18 matching lines...) Expand all
1267 # notification has been sent. 1415 # notification has been sent.
1268 expected = [ 1416 expected = [
1269 { 1417 {
1270 'payload': '{"auth_token":null,"task_id":"5cee488008810",' 1418 'payload': '{"auth_token":null,"task_id":"5cee488008810",'
1271 '"topic":"projects/abc/topics/def","userdata":"blah"}', 1419 '"topic":"projects/abc/topics/def","userdata":"blah"}',
1272 'queue_name': 'pubsub', 1420 'queue_name': 'pubsub',
1273 'transactional': True, 1421 'transactional': True,
1274 'url': '/internal/taskqueue/pubsub/5cee488008810', 1422 'url': '/internal/taskqueue/pubsub/5cee488008810',
1275 }, 1423 },
1276 ] 1424 ]
1425 self.assertEqual(expected, self.pubsub_tasks)
1277 1426
1278 def test_cancel_forbidden(self): 1427 def test_cancel_forbidden(self):
1279 """Asserts that non-privileged non-owner can't cancel tasks.""" 1428 """Asserts that non-privileged non-owner can't cancel tasks."""
1280 # catch PubSub notification
1281 notifies = []
1282 def enqueue_task_mock(**kwargs):
1283 notifies.append(kwargs)
1284 return True
1285 self.mock(utils, 'enqueue_task', enqueue_task_mock)
1286
1287 # Create a task as an admin. 1429 # Create a task as an admin.
1288 self.mock(random, 'getrandbits', lambda _: 0x88) 1430 self.mock(random, 'getrandbits', lambda _: 0x88)
1289 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 1431 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1290 self.mock_now(now) 1432 self.mock_now(now)
1291 self.set_as_admin() 1433 self.set_as_admin()
1292 _, task_id = self.client_create_task_raw( 1434 _, _, task_id = self.client_create_task_raw(
1293 pubsub_topic='projects/abc/topics/def', 1435 pubsub_topic='projects/abc/topics/def',
1294 pubsub_userdata='blah') 1436 pubsub_userdata='blah')
1295 1437
1296 # Attempt to cancel as non-privileged user -> HTTP 403. 1438 # Attempt to cancel as non-privileged user -> HTTP 403.
1297 self.set_as_user() 1439 self.set_as_user()
1298 self.call_api('cancel', body={'task_id': task_id}, status=403) 1440 self.call_api('cancel', body={'task_id': task_id}, status=403)
1299 1441
1442 self.assertEqual([], self.pubsub_tasks)
1443
1300 def test_task_canceled(self): 1444 def test_task_canceled(self):
1301 self.mock(random, 'getrandbits', lambda _: 0x88) 1445 self.mock(random, 'getrandbits', lambda _: 0x88)
1302 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 1446 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1303 self.mock_now(now) 1447 self.mock_now(now)
1304 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) 1448 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO))
1305 _, task_id = self.client_create_task_raw( 1449 _, _, task_id = self.client_create_task_raw(
1306 properties=dict(command=['python', 'runtest.py'])) 1450 properties=dict(command=['python', 'runtest.py']))
1307 1451
1308 self.set_as_bot() 1452 self.set_as_bot()
1309 params = self.do_handshake() 1453 params = self.do_handshake()
1310 data = self.post_json('/swarming/api/v1/bot/poll', params) 1454 data = self.post_json('/swarming/api/v1/bot/poll', params)
1311 run_id = data['manifest']['task_id'] 1455 run_id = data['manifest']['task_id']
1312 def _params(**kwargs): 1456 def _params(**kwargs):
1313 out = { 1457 out = {
1314 'cost_usd': 0.1, 1458 'cost_usd': 0.1,
1315 'duration': None, 1459 'duration': None,
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1380 self.call_api('result', body={'task_id': '12310'}, status=404) 1524 self.call_api('result', body={'task_id': '12310'}, status=404)
1381 1525
1382 def test_result_ok(self): 1526 def test_result_ok(self):
1383 """Asserts that result produces a result entity.""" 1527 """Asserts that result produces a result entity."""
1384 self.mock(random, 'getrandbits', lambda _: 0x88) 1528 self.mock(random, 'getrandbits', lambda _: 0x88)
1385 1529
1386 # pending task 1530 # pending task
1387 now = datetime.datetime(2010, 1, 2, 3, 4, 5) 1531 now = datetime.datetime(2010, 1, 2, 3, 4, 5)
1388 self.mock_now(now) 1532 self.mock_now(now)
1389 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) 1533 str_now = unicode(now.strftime(self.DATETIME_NO_MICRO))
1390 _, task_id = self.client_create_task_raw() 1534 _, _, task_id = self.client_create_task_raw()
1391 response = self.call_api('result', body={'task_id': task_id}) 1535 response = self.call_api('result', body={'task_id': task_id})
1392 expected = { 1536 expected = {
1393 u'created_ts': str_now, 1537 u'created_ts': str_now,
1394 u'failure': False, 1538 u'failure': False,
1395 u'internal_failure': False, 1539 u'internal_failure': False,
1396 u'modified_ts': str_now, 1540 u'modified_ts': str_now,
1397 u'name': u'hi', 1541 u'name': u'hi',
1398 u'state': u'PENDING', 1542 u'state': u'PENDING',
1399 u'tags': [ 1543 u'tags': [
1400 u'os:Amiga', 1544 u'os:Amiga',
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1512 1656
1513 self.set_as_privileged_user() 1657 self.set_as_privileged_user()
1514 run_id = task_id[:-1] + '1' 1658 run_id = task_id[:-1] + '1'
1515 expected = {u'output': u'rÉsult string'} 1659 expected = {u'output': u'rÉsult string'}
1516 for i in (task_id, run_id): 1660 for i in (task_id, run_id):
1517 response = self.call_api('stdout', body={'task_id': i}) 1661 response = self.call_api('stdout', body={'task_id': i})
1518 self.assertEqual(expected, response.json) 1662 self.assertEqual(expected, response.json)
1519 1663
1520 def test_stdout_empty(self): 1664 def test_stdout_empty(self):
1521 """Asserts that incipient tasks produce no output.""" 1665 """Asserts that incipient tasks produce no output."""
1522 _, task_id = self.client_create_task_raw() 1666 _, _, task_id = self.client_create_task_raw()
1523 response = self.call_api('stdout', body={'task_id': task_id}) 1667 response = self.call_api('stdout', body={'task_id': task_id})
1524 self.assertEqual({}, response.json) 1668 self.assertEqual({}, response.json)
1525 1669
1526 run_id = task_id[:-1] + '1' 1670 run_id = task_id[:-1] + '1'
1527 self.call_api('stdout', body={'task_id': run_id}, status=404) 1671 self.call_api('stdout', body={'task_id': run_id}, status=404)
1528 1672
1529 def test_result_run_not_found(self): 1673 def test_result_run_not_found(self):
1530 """Asserts that getting results from incipient tasks raises 404.""" 1674 """Asserts that getting results from incipient tasks raises 404."""
1531 _, task_id = self.client_create_task_raw() 1675 _, _, task_id = self.client_create_task_raw()
1532 run_id = task_id[:-1] + '1' 1676 run_id = task_id[:-1] + '1'
1533 self.call_api('stdout', body={'task_id': run_id}, status=404) 1677 self.call_api('stdout', body={'task_id': run_id}, status=404)
1534 1678
1535 def test_task_deduped(self): 1679 def test_task_deduped(self):
1536 """Asserts that task deduplication works as expected.""" 1680 """Asserts that task deduplication works as expected."""
1537 _, task_id_1 = self.client_create_task_raw(properties=dict(idempotent=True)) 1681 _, _, task_id_1 = self.client_create_task_raw(
1682 properties=dict(idempotent=True))
1538 1683
1539 self.set_as_bot() 1684 self.set_as_bot()
1540 task_id_bot = self.bot_run_task() 1685 task_id_bot = self.bot_run_task()
1541 self.assertEqual(task_id_1, task_id_bot[:-1] + '0') 1686 self.assertEqual(task_id_1, task_id_bot[:-1] + '0')
1542 self.assertEqual('1', task_id_bot[-1:]) 1687 self.assertEqual('1', task_id_bot[-1:])
1543 1688
1544 # second task; this one's results should be returned immediately 1689 # second task; this one's results should be returned immediately
1545 self.set_as_user() 1690 self.set_as_user()
1546 _, task_id_2 = self.client_create_task_raw( 1691 _, _, task_id_2 = self.client_create_task_raw(
1547 name='second', user='jack@localhost', properties=dict(idempotent=True)) 1692 name='second', user='jack@localhost', properties=dict(idempotent=True))
1548 1693
1549 self.set_as_bot() 1694 self.set_as_bot()
1550 resp = self.bot_poll() 1695 resp = self.bot_poll()
1551 self.assertEqual('sleep', resp['cmd']) 1696 self.assertEqual('sleep', resp['cmd'])
1552 1697
1553 self.set_as_user() 1698 self.set_as_user()
1554 1699
1555 # results shouldn't change, even if the second task wasn't executed 1700 # results shouldn't change, even if the second task wasn't executed
1556 response = self.call_api('stdout', body={'task_id': task_id_2}) 1701 response = self.call_api('stdout', body={'task_id': task_id_2})
1557 self.assertEqual({'output': u'rÉsult string'}, response.json) 1702 self.assertEqual({'output': u'rÉsult string'}, response.json)
1558 1703
1559 def test_request_unknown(self): 1704 def test_request_unknown(self):
1560 """Asserts that 404 is raised for unknown tasks.""" 1705 """Asserts that 404 is raised for unknown tasks."""
1561 self.call_api('request', body={'task_id': '12310'}, status=404) 1706 self.call_api('request', body={'task_id': '12310'}, status=404)
1562 1707
1563 def test_request_ok(self): 1708 def test_request_ok(self):
1564 """Asserts that request produces a task request.""" 1709 """Asserts that request produces a task request."""
1565 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6) 1710 now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6)
1566 self.mock_now(now) 1711 self.mock_now(now)
1567 _, task_id = self.client_create_task_raw() 1712 _, _, task_id = self.client_create_task_raw()
1568 response = self.call_api('request', body={'task_id': task_id}) 1713 response = self.call_api('request', body={'task_id': task_id})
1569 expected = { 1714 expected = {
1570 u'authenticated': u'user:user@example.com', 1715 u'authenticated': u'user:user@example.com',
1571 u'created_ts': unicode(now.strftime(self.DATETIME_FORMAT)), 1716 u'created_ts': unicode(now.strftime(self.DATETIME_FORMAT)),
1572 u'expiration_secs': unicode(24 * 60 * 60), 1717 u'expiration_secs': unicode(24 * 60 * 60),
1573 u'name': u'hi', 1718 u'name': u'hi',
1574 u'priority': u'100', 1719 u'priority': u'100',
1575 u'properties': { 1720 u'properties': {
1576 u'cipd_input': { 1721 u'cipd_input': {
1577 u'client_package': { 1722 u'client_package': {
(...skipping 613 matching lines...) Expand 10 before | Expand all | Expand 10 after
2191 self.call_api('terminate', body={'bot_id': 'bot1'}, status=403) 2336 self.call_api('terminate', body={'bot_id': 'bot1'}, status=403)
2192 2337
2193 2338
2194 if __name__ == '__main__': 2339 if __name__ == '__main__':
2195 if '-v' in sys.argv: 2340 if '-v' in sys.argv:
2196 unittest.TestCase.maxDiff = None 2341 unittest.TestCase.maxDiff = None
2197 logging.basicConfig(level=logging.DEBUG) 2342 logging.basicConfig(level=logging.DEBUG)
2198 else: 2343 else:
2199 logging.basicConfig(level=logging.CRITICAL) 2344 logging.basicConfig(level=logging.CRITICAL)
2200 unittest.main() 2345 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698