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

Unified Diff: appengine/swarming/server/task_scheduler_test.py

Issue 2914803004: Fix non-idempotent task that /poll reaped but returned HTTP 500. (Closed)
Patch Set: Rebase on 2927053002 to reduce delta 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 side-by-side diff with in-line comments
Download patch
Index: appengine/swarming/server/task_scheduler_test.py
diff --git a/appengine/swarming/server/task_scheduler_test.py b/appengine/swarming/server/task_scheduler_test.py
index 9a97ee0999da0fc306b54e789d92636a3822f580..de3cb54d74519466a8a6ae3e182f61dd0fd3d0aa 100755
--- a/appengine/swarming/server/task_scheduler_test.py
+++ b/appengine/swarming/server/task_scheduler_test.py
@@ -1608,6 +1608,169 @@ class TaskSchedulerApiTest(test_env_handlers.AppTestBase):
self.assertEqual(0, self.execute_tasks())
self.assertEqual(4, len(pub_sub_calls)) # RUNNING -> COMPLETED
+ def test_cron_handle_bot_died_no_update_not_idempotent(self):
+ pub_sub_calls = self.mock_pub_sub()
+
+ # Test first retry, then success.
+ now = utils.utcnow()
+ request = self._gen_request(
+ properties={
+ 'dimensions': {u'os': u'Windows-3.1.1', u'pool': u'default'},
+ },
+ created_ts=now,
+ expiration_ts=now+datetime.timedelta(seconds=600),
+ pubsub_topic='projects/abc/topics/def')
+ task_request.init_new_request(request, True, None)
+ _result_summary = task_scheduler.schedule_request(request, None)
+ self.assertEqual(1, self.execute_tasks())
+ self.assertEqual(0, len(pub_sub_calls))
+ bot_dimensions = {
+ u'foo': [u'bar'],
+ u'id': [u'localhost'],
+ u'os': [u'Windows', u'Windows-3.1.1'],
+ u'pool': [u'default'],
+ }
+ self._register_bot(bot_dimensions, nb_task=0)
+ request, _, run_result = task_scheduler.bot_reap_task(
+ bot_dimensions, 'abc', None)
+ self.assertEqual(
+ task_result.State.RUNNING, run_result.result_summary_key.get().state)
+ self.assertEqual(1, self.execute_tasks())
+ self.assertEqual(1, len(pub_sub_calls)) # PENDING -> RUNNING
+ self.assertEqual(1, run_result.try_number)
+ self.assertEqual(task_result.State.RUNNING, run_result.state)
+ now_1 = self.mock_now(self.now + task_result.BOT_PING_TOLERANCE, 1)
+ self.assertEqual(([], 1, 0), task_scheduler.cron_handle_bot_died('f.local'))
+ self.assertEqual(1, self.execute_tasks())
+ self.assertEqual(2, len(pub_sub_calls)) # RUNNING -> PENDING
+
+ # Refresh and compare:
+ expected = {
+ 'abandoned_ts': now_1,
+ 'bot_dimensions': bot_dimensions,
+ 'bot_id': u'localhost',
+ 'bot_version': u'abc',
+ 'cipd_pins': None,
+ 'children_task_ids': [],
+ 'completed_ts': None,
+ 'cost_usd': 0.,
+ 'duration': None,
+ 'exit_code': None,
+ 'failure': False,
+ 'id': '1d69b9f088008911',
+ 'internal_failure': True,
+ 'modified_ts': now_1,
+ 'outputs_ref': None,
+ 'server_versions': [u'v1a'],
+ 'started_ts': self.now,
+ 'state': task_result.State.BOT_DIED,
+ 'try_number': 1,
+ }
+ self.assertEqual(expected, run_result.key.get().to_dict())
+ expected = {
+ 'abandoned_ts': None,
+ 'bot_dimensions': bot_dimensions,
+ 'bot_id': u'localhost',
+ 'bot_version': u'abc',
+ 'cipd_pins': None,
+ 'children_task_ids': [],
+ 'completed_ts': None,
+ 'costs_usd': [0.],
+ 'cost_saved_usd': None,
+ 'created_ts': self.now,
+ 'deduped_from': None,
+ 'duration': None,
+ 'exit_code': None,
+ 'failure': False,
+ 'id': '1d69b9f088008910',
+ 'internal_failure': False,
+ 'modified_ts': now_1,
+ 'name': u'Request name',
+ 'outputs_ref': None,
+ 'properties_hash': None,
+ 'server_versions': [u'v1a'],
+ 'started_ts': None,
+ 'state': task_result.State.PENDING,
+ 'tags': [
+ u'os:Windows-3.1.1',
+ u'pool:default',
+ u'priority:50',
+ u'service_account:none',
+ u'tag:1',
+ u'user:Jesus',
+ ],
+ 'try_number': 1,
+ 'user': u'Jesus',
+ }
+ self.assertEqual(expected, run_result.result_summary_key.get().to_dict())
+
+ # Task was retried.
+ now_2 = self.mock_now(self.now + task_result.BOT_PING_TOLERANCE, 2)
+ bot_dimensions_second = bot_dimensions.copy()
+ bot_dimensions_second[u'id'] = [u'localhost-second']
+ self._register_bot(bot_dimensions_second, nb_task=0)
+ _request, _, run_result = task_scheduler.bot_reap_task(
+ bot_dimensions_second, 'abc', None)
+ self.assertEqual(1, self.execute_tasks())
+ self.assertEqual(3, len(pub_sub_calls)) # PENDING -> RUNNING
+ logging.info('%s', [t.to_dict() for t in task_to_run.TaskToRun.query()])
+ self.assertEqual(2, run_result.try_number)
+ self.assertEqual(
+ task_result.State.COMPLETED,
+ task_scheduler.bot_update_task(
+ run_result_key=run_result.key,
+ bot_id='localhost-second',
+ cipd_pins=None,
+ output='Foo1',
+ output_chunk_start=0,
+ exit_code=0,
+ duration=0.1,
+ hard_timeout=False,
+ io_timeout=False,
+ cost_usd=0.1,
+ outputs_ref=None,
+ performance_stats=None))
+ expected = {
+ 'abandoned_ts': None,
+ 'bot_dimensions': bot_dimensions_second,
+ 'bot_id': u'localhost-second',
+ 'bot_version': u'abc',
+ 'cipd_pins': None,
+ 'children_task_ids': [],
+ 'completed_ts': now_2,
+ 'costs_usd': [0., 0.1],
+ 'cost_saved_usd': None,
+ 'created_ts': self.now,
+ 'deduped_from': None,
+ 'duration': 0.1,
+ 'exit_code': 0,
+ 'failure': False,
+ 'id': '1d69b9f088008910',
+ 'internal_failure': False,
+ 'modified_ts': now_2,
+ 'name': u'Request name',
+ 'outputs_ref': None,
+ 'properties_hash': None,
+ 'server_versions': [u'v1a'],
+ 'started_ts': now_2,
+ 'state': task_result.State.COMPLETED,
+ 'tags': [
+ u'os:Windows-3.1.1',
+ u'pool:default',
+ u'priority:50',
+ u'service_account:none',
+ u'tag:1',
+ u'user:Jesus',
+ ],
+ 'try_number': 2,
+ 'user': u'Jesus',
+ }
+ self.assertEqual(expected, run_result.result_summary_key.get().to_dict())
+ self.assertEqual(0.1, run_result.key.get().cost_usd)
+
+ self.assertEqual(0, self.execute_tasks())
+ self.assertEqual(4, len(pub_sub_calls)) # RUNNING -> COMPLETED
+
def test_cron_handle_bot_died_same_bot_denied(self):
# Test first retry, then success.
now = utils.utcnow()
« appengine/swarming/server/task_scheduler.py ('K') | « appengine/swarming/server/task_scheduler.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698