Commit 885507eb authored by Wenbin Zhang's avatar Wenbin Zhang Committed by Commit Bot

[benchmarking] Avoid KeyError when no bot returned from swarming query

When making query to swarming for bots with dimension values, it is
possible that no bot is returned. Normally, the return JSON looks
like this:
{
  "death_timeout": "xxx",
  "items": ["list","of","bots"]
  "now": "xxx"
}
When there's no bot, the "items" key is gone:
{
  "death_timeout": "xxx",
  "now": "xxx"
}
In this case, we will see a KeyError in pre_run stage because we try to
read values using "items" key in perf_device_trigger.py:
  for bot in query_result['items']:
    ...

KeyError doesn't tell what is actually happening. To fix, we check this
key before using it. Then when no bot exists, we will see a message saying
there's not enough machines.


Bug: chromium:1027147
Change-Id: I38fe0e1a015e29d9b223515f49c527641bcebf60
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1929871Reviewed-by: default avatarCaleb Rouleau <crouleau@chromium.org>
Commit-Queue: Caleb Rouleau <crouleau@chromium.org>
Cr-Commit-Position: refs/heads/master@{#718356}
parent cab002d5
......@@ -131,7 +131,7 @@ class PerfDeviceTriggerer(base_test_triggerer.BaseTestTriggerer):
if verbose:
self._print_device_affinity_info({}, {},
self._eligible_bots_by_ids, trigger_count)
raise ValueError('Not enough available machines exist in in swarming'
raise ValueError('Not enough available machines exist in swarming '
'pool. Shards requested (%d) exceeds available bots '
'(%d).' % (
trigger_count, len(self._eligible_bots_by_ids)))
......@@ -227,6 +227,8 @@ class PerfDeviceTriggerer(base_test_triggerer.BaseTestTriggerer):
query_result = self.query_swarming(
'bots/list', values, True, server=self._swarming_server,
service_account=self._service_account)
if 'items' not in query_result:
return {}
perf_bots = {}
for bot in query_result['items']:
alive = (not bot['is_dead'] and not bot['quarantined'])
......
......@@ -133,6 +133,8 @@ class UnitTest(unittest.TestCase):
def generate_list_of_eligible_bots_query_response(
self, alive_bots, dead_bots):
if len(alive_bots) == 0 and len(dead_bots) == 0:
return {}
items = {'items': []}
for bot_id in alive_bots:
items['items'].append(
......@@ -176,7 +178,6 @@ class UnitTest(unittest.TestCase):
triggered_map[shard] = bot_id
return triggered_map
def test_all_healthy_shards(self):
triggerer = self.setup_and_trigger(
previous_task_assignment_map={0: 'build3', 1: 'build4', 2: 'build5'},
......@@ -192,6 +193,15 @@ class UnitTest(unittest.TestCase):
self.assertEquals(expected_task_assignment.get(1), 'build4')
self.assertEquals(expected_task_assignment.get(2), 'build5')
def test_no_bot_returned(self):
with self.assertRaises(ValueError) as context:
self.setup_and_trigger(
previous_task_assignment_map={0: 'build1'},
alive_bots=[],
dead_bots=[])
err_msg = 'Not enough available machines exist in swarming pool'
self.assertTrue(err_msg in context.exception.message)
def test_previously_healthy_now_dead(self):
# Test that it swaps out build1 and build2 that are dead
# for two healthy bots
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment