Chromium Code Reviews| Index: appengine/swarming/handlers_endpoints_test.py |
| diff --git a/appengine/swarming/handlers_endpoints_test.py b/appengine/swarming/handlers_endpoints_test.py |
| index 5c913d139d6a6caaa96b8315a18df8ed9214b144..15aa1983ae64e88ac309b0c33cd0e788e1da4738 100755 |
| --- a/appengine/swarming/handlers_endpoints_test.py |
| +++ b/appengine/swarming/handlers_endpoints_test.py |
| @@ -625,6 +625,107 @@ class TasksApiTest(BaseTest): |
| expected, |
| self.call_api('requests', body=message_to_dict(request)).json) |
| + def test_new_ok_deduped_by_transaction_id(self): |
| + """Asserts that new returns task result for deduped.""" |
| + # Run a task to completion. |
| + self.mock(random, 'getrandbits', lambda _: 0x88) |
| + now = self.mock_now(datetime.datetime(2010, 1, 2, 3, 4, 5)) |
| + str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) |
| + new_req, _, task_id = self.client_create_task_raw( |
| + name='task', tags=['project:yay', 'commit:post'], |
| + properties=dict(idempotent=True), |
| + transaction_id='txn') |
| + self.set_as_bot() |
| + self.bot_run_task() |
| + |
| + self.mock(random, 'getrandbits', lambda _: 0x66) |
| + self.set_as_user() |
| + |
| + expected = { |
| + u'request': { |
| + u'authenticated': u'user:user@example.com', |
| + u'created_ts': str_now, |
| + u'expiration_secs': u'86400', |
| + u'name': u'task', |
| + u'priority': u'100', |
| + u'properties': { |
| + u'cipd_input': { |
| + u'client_package': { |
| + u'package_name': u'infra/tools/cipd/${platform}', |
| + u'version': u'git_revision:deadbeef', |
| + }, |
| + u'packages': [{ |
| + u'package_name': u'rm', |
| + u'path': u'bin', |
| + u'version': u'git_revision:deadbeef', |
| + }], |
| + u'server': u'https://chrome-infra-packages.appspot.com', |
| + }, |
| + u'command': [u'python', u'run_test.py'], |
| + u'dimensions': [ |
| + {u'key': u'os', u'value': u'Amiga'}, |
| + {u'key': u'pool', u'value': u'default'}, |
| + ], |
| + u'execution_timeout_secs': u'3600', |
| + u'grace_period_secs': u'30', |
| + u'idempotent': True, |
| + u'io_timeout_secs': u'1200', |
| + u'outputs': [u'foo', u'path/to/foobar'], |
| + }, |
| + u'service_account': u'none', |
| + u'tags': [ |
| + u'commit:post', |
| + u'os:Amiga', |
| + u'pool:default', |
| + u'priority:100', |
| + u'project:yay', |
| + u'service_account:none', |
| + u'user:joe@localhost', |
| + ], |
| + u'user': u'joe@localhost', |
| + }, |
| + u'task_id': unicode(task_id), |
| + u'task_result': { |
| + u'bot_dimensions': [ |
| + {u'key': u'id', u'value': [u'bot1']}, |
| + {u'key': u'os', u'value': [u'Amiga']}, |
| + {u'key': u'pool', u'value': [u'default']}, |
| + ], |
| + u'bot_id': u'bot1', |
| + u'bot_version': self.bot_version, |
| + u'completed_ts': str_now, |
| + u'costs_usd': [0.1], |
| + u'created_ts': str_now, |
| + u'duration': 0.1, |
| + u'exit_code': u'0', |
| + u'failure': False, |
| + u'internal_failure': False, |
| + u'modified_ts': str_now, |
| + u'name': u'task', |
| + u'properties_hash': ( |
| + u'd35fe05074cbd9a2356c77c9983c71476f3a5f9415c5c5b1f3e2cdf7826b7261' |
| + ), |
| + u'run_id': u'5cee488008811', |
| + u'server_versions': [u'v1a'], |
| + u'started_ts': str_now, |
| + u'state': u'COMPLETED', |
| + u'tags': [ |
| + u'commit:post', |
| + u'os:Amiga', |
| + u'pool:default', |
| + u'priority:100', |
| + u'project:yay', |
| + u'service_account:none', |
| + u'user:joe@localhost', |
| + ], |
| + u'task_id': unicode(task_id), |
| + u'try_number': u'1', |
| + u'user': u'joe@localhost', |
| + }, |
| + } |
| + response = self.call_api('new', body=message_to_dict(new_req)) |
| + self.assertEqual(expected, response.json) |
| + |
| def test_new_ok_isolated(self): |
| """Asserts that new generates appropriate metadata.""" |
| self.mock(random, 'getrandbits', lambda _: 0x88) |
| @@ -880,8 +981,6 @@ class TasksApiTest(BaseTest): |
| response = self.call_api('cancel', body={u'tags': [u'os:Win']}) |
| self.assertEqual(expected, response.json) |
| - |
| - |
| def test_list_ok(self): |
| """Asserts that list requests all TaskResultSummaries.""" |
| first, second, str_now_120, start, end = self._gen_two_tasks() |
| @@ -1066,7 +1165,7 @@ class TasksApiTest(BaseTest): |
| str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) |
| self.mock_now(now) |
| self.mock(random, 'getrandbits', lambda _: 0x66) |
| - _, first_id = self.client_create_task_raw( |
| + _, _, first_id = self.client_create_task_raw( |
| name='first', tags=['project:yay', 'commit:post', 'os:Win'], |
| properties=dict(idempotent=True)) |
| self.set_as_bot() |
| @@ -1193,7 +1292,7 @@ class TasksApiTest(BaseTest): |
| now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| self.mock_now(now) |
| self.mock(random, 'getrandbits', lambda _: 0x66) |
| - _, first_id = self.client_create_task_raw( |
| + _, _, first_id = self.client_create_task_raw( |
| name='first', tags=['project:yay', 'commit:abcd', 'os:Win'], |
| pubsub_topic='projects/abc/topics/def', |
| pubsub_userdata='1234', |
| @@ -1201,7 +1300,7 @@ class TasksApiTest(BaseTest): |
| now_60 = self.mock_now(now, 60) |
| self.mock(random, 'getrandbits', lambda _: 0x88) |
| - _, second_id = self.client_create_task_raw( |
| + _, _, second_id = self.client_create_task_raw( |
| name='second', user='jack@localhost', |
| pubsub_topic='projects/abc/topics/def', |
| pubsub_userdata='5678', |
| @@ -1209,7 +1308,7 @@ class TasksApiTest(BaseTest): |
| properties=dict(idempotent=True)) |
| now_120 = self.mock_now(now, 120) |
| - _, third_id = self.client_create_task_raw( |
| + _, _, third_id = self.client_create_task_raw( |
| name='third', user='jack@localhost', |
| pubsub_topic='projects/abc/topics/def', |
| pubsub_userdata='9000', |
| @@ -1230,12 +1329,18 @@ class TaskApiTest(BaseTest): |
| def test_cancel_ok(self): |
| """Asserts that task cancellation goes smoothly.""" |
| # catch PubSub notification |
| + notifies = [] |
| + def enqueue_task_mock(**kwargs): |
| + notifies.append(kwargs) |
| + return True |
| + self.mock(utils, 'enqueue_task', enqueue_task_mock) |
|
M-A Ruel
2017/05/03 01:33:20
enqueue_task is already mocked above, this is not
nodir
2017/05/05 18:11:38
Done
this code was copied from test_cancel_forbid
|
| + |
| # Create and cancel a task as a non-privileged user. |
| self.mock(random, 'getrandbits', lambda _: 0x88) |
| now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| self.mock_now(now) |
| str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) |
| - _, task_id = self.client_create_task_raw( |
| + _, _, task_id = self.client_create_task_raw( |
| pubsub_topic='projects/abc/topics/def', |
| pubsub_userdata='blah') |
| expected = {u'ok': True, u'was_running': False} |
| @@ -1274,6 +1379,7 @@ class TaskApiTest(BaseTest): |
| 'url': '/internal/taskqueue/pubsub/5cee488008810', |
| }, |
| ] |
| + self.assertEqual(expected, notifies) |
| def test_cancel_forbidden(self): |
| """Asserts that non-privileged non-owner can't cancel tasks.""" |
| @@ -1289,7 +1395,7 @@ class TaskApiTest(BaseTest): |
| now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| self.mock_now(now) |
| self.set_as_admin() |
| - _, task_id = self.client_create_task_raw( |
| + _, _, task_id = self.client_create_task_raw( |
| pubsub_topic='projects/abc/topics/def', |
| pubsub_userdata='blah') |
| @@ -1297,12 +1403,94 @@ class TaskApiTest(BaseTest): |
| self.set_as_user() |
| self.call_api('cancel', body={'task_id': task_id}, status=403) |
| + self.assertEqual([], notifies) |
| + |
| + def test_cancel_by_transaction_id_ok(self): |
| + """Asserts that task cancellation goes smoothly.""" |
| + # catch PubSub notification |
| + notifies = [] |
| + def enqueue_task_mock(**kwargs): |
| + notifies.append(kwargs) |
| + return True |
| + self.mock(utils, 'enqueue_task', enqueue_task_mock) |
|
M-A Ruel
2017/05/03 01:33:20
same
nodir
2017/05/05 18:11:38
Done.
|
| + |
| + # Create and cancel a task as a non-privileged user. |
| + self.mock(random, 'getrandbits', lambda _: 0x88) |
| + now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| + self.mock_now(now) |
| + str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) |
| + _, _, task_id = self.client_create_task_raw( |
| + pubsub_topic='projects/abc/topics/def', |
| + pubsub_userdata='blah', |
| + transaction_id='txn') |
| + expected = {u'ok': True, u'was_running': False} |
| + response = self.call_api('cancel', body={'transaction_id': 'txn'}) |
| + self.assertEqual(expected, response.json) |
| + |
| + # determine that the task's state updates correctly |
| + expected = { |
| + u'abandoned_ts': str_now, |
| + u'created_ts': str_now, |
| + u'failure': False, |
| + u'internal_failure': False, |
| + u'modified_ts': str_now, |
| + u'name': u'hi', |
| + u'state': u'CANCELED', |
| + u'tags': [ |
| + u'os:Amiga', |
| + u'pool:default', |
| + u'priority:100', |
| + u'service_account:none', |
| + u'user:joe@localhost', |
| + ], |
| + u'task_id': task_id, |
| + u'user': u'joe@localhost', |
| + } |
| + response = self.call_api('result', body={'task_id': task_id}) |
| + self.assertEqual(expected, response.json) |
| + |
| + expected = [ |
| + { |
| + 'payload': '{"auth_token":null,"task_id":"5cee488008810",' |
| + '"topic":"projects/abc/topics/def","userdata":"blah"}', |
| + 'queue_name': 'pubsub', |
| + 'transactional': True, |
| + 'url': '/internal/taskqueue/pubsub/5cee488008810', |
| + }, |
| + ] |
| + self.assertEqual(expected, notifies) |
| + |
| + def test_cancel_by_transaction_id_forbidden(self): |
| + """Asserts that non-privileged non-owner can't cancel tasks.""" |
| + # catch PubSub notification |
| + notifies = [] |
| + def enqueue_task_mock(**kwargs): |
| + notifies.append(kwargs) |
| + return True |
| + self.mock(utils, 'enqueue_task', enqueue_task_mock) |
|
M-A Ruel
2017/05/03 01:33:20
same
nodir
2017/05/05 18:11:38
Done.
|
| + |
| + # Create a task as an admin. |
| + self.mock(random, 'getrandbits', lambda _: 0x88) |
| + now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| + self.mock_now(now) |
| + self.set_as_admin() |
| + self.client_create_task_raw( |
| + pubsub_topic='projects/abc/topics/def', |
| + pubsub_userdata='blah', |
| + transaction_id='txn') |
| + |
| + # Attempt to cancel as non-privileged user -> HTTP 403. |
| + self.set_as_user() |
| + self.call_api('cancel', body={'transaction_id': 'txn'}, status=403) |
| + |
| + self.assertEqual([], notifies) |
| + |
| def test_task_canceled(self): |
| self.mock(random, 'getrandbits', lambda _: 0x88) |
| now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| self.mock_now(now) |
| str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) |
| - _, task_id = self.client_create_task_raw( |
| + _, _, task_id = self.client_create_task_raw( |
| properties=dict(command=['python', 'runtest.py'])) |
| self.set_as_bot() |
| @@ -1387,7 +1575,7 @@ class TaskApiTest(BaseTest): |
| now = datetime.datetime(2010, 1, 2, 3, 4, 5) |
| self.mock_now(now) |
| str_now = unicode(now.strftime(self.DATETIME_NO_MICRO)) |
| - _, task_id = self.client_create_task_raw() |
| + _, _, task_id = self.client_create_task_raw() |
| response = self.call_api('result', body={'task_id': task_id}) |
| expected = { |
| u'created_ts': str_now, |
| @@ -1519,7 +1707,7 @@ class TaskApiTest(BaseTest): |
| def test_stdout_empty(self): |
| """Asserts that incipient tasks produce no output.""" |
| - _, task_id = self.client_create_task_raw() |
| + _, _, task_id = self.client_create_task_raw() |
| response = self.call_api('stdout', body={'task_id': task_id}) |
| self.assertEqual({}, response.json) |
| @@ -1528,13 +1716,13 @@ class TaskApiTest(BaseTest): |
| def test_result_run_not_found(self): |
| """Asserts that getting results from incipient tasks raises 404.""" |
| - _, task_id = self.client_create_task_raw() |
| + _, _, task_id = self.client_create_task_raw() |
| run_id = task_id[:-1] + '1' |
| self.call_api('stdout', body={'task_id': run_id}, status=404) |
| def test_task_deduped(self): |
| """Asserts that task deduplication works as expected.""" |
| - _, task_id_1 = self.client_create_task_raw(properties=dict(idempotent=True)) |
| + _, _, task_id_1 = self.client_create_task_raw(properties=dict(idempotent=True)) |
| self.set_as_bot() |
| task_id_bot = self.bot_run_task() |
| @@ -1543,7 +1731,7 @@ class TaskApiTest(BaseTest): |
| # second task; this one's results should be returned immediately |
| self.set_as_user() |
| - _, task_id_2 = self.client_create_task_raw( |
| + _, _, task_id_2 = self.client_create_task_raw( |
| name='second', user='jack@localhost', properties=dict(idempotent=True)) |
| self.set_as_bot() |
| @@ -1564,7 +1752,7 @@ class TaskApiTest(BaseTest): |
| """Asserts that request produces a task request.""" |
| now = datetime.datetime(2010, 1, 2, 3, 4, 5, 6) |
| self.mock_now(now) |
| - _, task_id = self.client_create_task_raw() |
| + _, _, task_id = self.client_create_task_raw() |
| response = self.call_api('request', body={'task_id': task_id}) |
| expected = { |
| u'authenticated': u'user:user@example.com', |