#!/usr/bin/python
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

"""Unittests for lab status."""

from __future__ import print_function

import constants
from mock import Mock
import sys
import time
import urllib

sys.path.insert(0, constants.SOURCE_ROOT)
from chromite.cbuildbot import lab_status
from chromite.lib import cros_test_lib


class TestLabStatus(cros_test_lib.MockTestCase):
  """Class that tests GetLabStatus and CheckLabStatus."""

  def setUp(self):
    self.PatchObject(time, 'sleep')
    self.PatchObject(urllib, 'urlopen')

  def _LabStatusFile(self, message, general_state):
    """Returns a file-like object with the status message written in it."""
    my_response = Mock()
    my_response.json = '{"message": "%s", "general_state": "%s"}' % (
        message, general_state)
    return my_response

  def _TestGetLabStatusHelper(self, lab_message, general_state, expected_return,
                              max_attempts=5, failed_attempts=0):
    """Tests whether we get correct lab status.

    Args:
      lab_message: A message describing lab status and
                   disabled boards, e.g. "Lab is Up [stumpy, kiev]"
      general_state: Current lab state, e.g. 'open'.
      expected_return: The expected return of GetLabStatus,
                       e.g. {'lab_is_up': True, 'message': 'Lab is up'}.
      max_attempts: Max attempts GetLabStatus will make to get lab status.
      failed_attempts: Number of failed attempts we want to mock.
    """
    return_status = self._LabStatusFile(lab_message, general_state)
    urlopen_side_effect = [500 for _ in range(failed_attempts)]
    if failed_attempts < max_attempts:
      urlopen_side_effect.append(200)
      call_count = failed_attempts + 1
    else:
      call_count = max_attempts
    return_status.getcode.side_effect = urlopen_side_effect
    urllib.urlopen.return_value = return_status
    return_status.read.return_value = return_status.json
    self.assertEqual(lab_status.GetLabStatus(max_attempts), expected_return)
    # pylint: disable=no-member
    self.assertEqual(urllib.urlopen.call_count, call_count)

  def testGetLabStatusWithOneAttempt(self):
    """Tests that GetLabStatus succeeds with one attempt."""
    expected_return = {'lab_is_up': True, 'message': 'Lab is up'}
    self._TestGetLabStatusHelper('Lab is up', 'open', expected_return)

  def testGetLabStatusWithMultipleAttempts(self):
    """Tests that GetLabStatus succeeds after multiple tries."""
    expected_return = {'lab_is_up': True, 'message': 'Lab is up'}
    self._TestGetLabStatusHelper('Lab is up', 'open', expected_return,
                                 max_attempts=5, failed_attempts=3)

  def testGetLabStatusFailsWithMultipleAttempts(self):
    """Tests that GetLabStatus fails after multiple tries."""
    expected_return = {'lab_is_up': True, 'message': ''}
    self._TestGetLabStatusHelper('dummy_msg', 'dummy_state', expected_return,
                                 max_attempts=5, failed_attempts=5)

  def _BuildLabStatus(self, lab_is_up, disabled_boards=None):
    """Build a dictionary representing the lab status."""
    if lab_is_up:
      message = 'Lab is Open'
      if disabled_boards:
        message += '[%s]' % (', '.join(disabled_boards))
    else:
      message = 'Lab is Down (For some reason it is down.)'

    status = {'lab_is_up': lab_is_up, 'message': message}
    return status

  def _TestCheckLabStatusHelper(self, lab_is_up):
    """Tests CheckLabStatus runs properly."""
    self.PatchObject(lab_status, 'GetLabStatus')
    status = self._BuildLabStatus(lab_is_up)
    lab_status.GetLabStatus.return_value = status
    if lab_is_up:
      lab_status.CheckLabStatus()
    else:
      self.assertRaises(lab_status.LabIsDownException,
                        lab_status.CheckLabStatus)

  def testCheckLabStatusWhenLabUp(self):
    """Tests CheckLabStatus runs properly when lab is up."""
    self._TestCheckLabStatusHelper(True)

  def testCheckLabStatusWhenLabDown(self):
    """Tests CheckLabStatus runs properly when lab is down."""
    self._TestCheckLabStatusHelper(False)

  def testCheckLabStatusWhenBoardsDisabled(self):
    """Tests CheckLabStatus runs properly when some boards are disabled."""
    self.PatchObject(lab_status, 'GetLabStatus')
    status = self._BuildLabStatus(True, ['stumpy', 'kiev', 'x85-alex'])
    lab_status.GetLabStatus.return_value = status
    lab_status.CheckLabStatus('lumpy')
    self.assertRaises(lab_status.BoardIsDisabledException,
                      lab_status.CheckLabStatus,
                      'stumpy')


if __name__ == '__main__':
  cros_test_lib.main()
