Add unit tests for check_lab_status() internals
This refactors check_lab_status for testability, and adds unit tests
to cover all of the function's code paths.
BUG=None
TEST=run the unit tests
Change-Id: I7cbeb41314af541aea17405c0f50ea54ae2bbc50
Reviewed-on: https://chromium-review.googlesource.com/178307
Tested-by: Richard Barnette <jrbarnette@chromium.org>
Reviewed-by: Simran Basi <sbasi@chromium.org>
Commit-Queue: Richard Barnette <jrbarnette@chromium.org>
diff --git a/server/site_utils.py b/server/site_utils.py
index 65e1643..daa0a6b 100644
--- a/server/site_utils.py
+++ b/server/site_utils.py
@@ -155,43 +155,35 @@
base_utils.run(wget_cmd)
-def get_lab_status():
+_MAX_LAB_STATUS_ATTEMPTS = 5
+def _get_lab_status(status_url):
"""Grabs the current lab status and message.
- @returns a dict with keys 'lab_is_up' and 'message'. lab_is_up points
- to a boolean and message points to a string.
+ @returns The JSON object obtained from the given URL.
+
"""
- result = {'lab_is_up' : True, 'message' : ''}
- status_url = global_config.global_config.get_config_value('CROS',
- 'lab_status_url')
- max_attempts = 5
retry_waittime = 1
- for _ in range(max_attempts):
+ for _ in range(_MAX_LAB_STATUS_ATTEMPTS):
try:
response = urllib2.urlopen(status_url)
except IOError as e:
- logging.debug('Error occured when grabbing the lab status: %s.',
+ logging.debug('Error occurred when grabbing the lab status: %s.',
e)
time.sleep(retry_waittime)
continue
# Check for successful response code.
if response.getcode() == 200:
- data = json.load(response)
- result['lab_is_up'] = data['general_state'] in LAB_GOOD_STATES
- result['message'] = data['message']
- return result
+ return json.load(response)
time.sleep(retry_waittime)
- # We go ahead and say the lab is open if we can't get the status.
- logging.warn('Could not get a status from %s', status_url)
- return result
+ return None
-def check_lab_status(board=None):
- """Check if the lab is up and if we can schedule suites to run.
+def _decode_lab_status(lab_status, board):
+ """Decode lab status, and report exceptions as needed.
- Also checks if the lab is disabled for that particular board, and if so
- will raise an error to prevent new suites from being scheduled for that
- board.
+ Takes a deserialized JSON object from the lab status page, and
+ interprets it to determine the actual lab status. Raises
+ exceptions as required to report when the lab is down.
@param board: board name that we want to check the status of.
@@ -199,16 +191,10 @@
@raises BoardIsDisabledException if the desired board is currently
disabled.
"""
- # Ensure we are trying to schedule on the actual lab.
- if not (global_config.global_config.get_config_value('SERVER',
- 'hostname').startswith('cautotest')):
- return
-
# First check if the lab is up.
- lab_status = get_lab_status()
- if not lab_status['lab_is_up']:
+ if not lab_status['general_state'] in LAB_GOOD_STATES:
raise LabIsDownException('Chromium OS Lab is currently not up: '
- '%s.' % lab_status['message'])
+ '%s.' % lab_status['message'])
# Check if the board we wish to use is disabled.
# Lab messages should be in the format of:
@@ -222,3 +208,34 @@
'currently not allowing suites to be scheduled on board '
'%s: %s' % (board, lab_status['message']))
return
+
+
+def check_lab_status(board=None):
+ """Check if the lab status allows us to schedule suites.
+
+ Also checks if the lab is disabled for that particular board, and if so
+ will raise an error to prevent new suites from being scheduled for that
+ board.
+
+ @param board: board name that we want to check the status of.
+
+ @raises LabIsDownException if the lab is not up.
+ @raises BoardIsDisabledException if the desired board is currently
+ disabled.
+
+ """
+ # Ensure we are trying to schedule on the actual lab.
+ test_server_name = global_config.global_config.get_config_value(
+ 'SERVER', 'hostname')
+ if not test_server_name.startswith('cautotest'):
+ return
+
+ # Download the lab status from its home on the web.
+ status_url = global_config.global_config.get_config_value(
+ 'CROS', 'lab_status_url')
+ json_status = _get_lab_status(status_url)
+ if json_status is None:
+ # We go ahead and say the lab is open if we can't get the status.
+ logging.warn('Could not get a status from %s', status_url)
+ return
+ _decode_lab_status(json_status, board)