# Lint as: python2, python3
# 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.

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

from six.moves import range
import six
import json
import mox
import time
import unittest
from six.moves import urllib

import common
from autotest_lib.client.common_lib import global_config
from autotest_lib.server import site_utils

_DEADBUILD = 'deadboard-release/R33-4966.0.0'
_LIVEBUILD = 'liveboard-release/R32-4920.14.0'

_STATUS_TEMPLATE = '''
    {
      "username": "fizzbin@google.com",
      "date": "2013-11-16 00:25:23.511208",
      "message": "%s",
      "can_commit_freely": %s,
      "general_state": "%s"
    }
    '''


def _make_status(message, can_commit, state):
    return _STATUS_TEMPLATE % (message, can_commit, state)


def _make_open_status(message, state):
    return _make_status(message, 'true', state)


def _make_closed_status(message):
    return _make_status(message, 'false', 'closed')


def _make_deadbuild_status(message):
    return _make_status(message, 'false', 'open')


_OPEN_STATUS_VALUES = [
    _make_open_status('Lab is up (cross your fingers)', 'open'),
    _make_open_status('Lab is on fire', 'throttled'),
    _make_open_status('Lab is up despite deadboard', 'open'),
    _make_open_status('Lab is up despite .*/R33-4966.0.0', 'open'),
]

_CLOSED_STATUS_VALUES = [
    _make_closed_status('Lab is down for spite'),
    _make_closed_status('Lab is down even for [%s]' % _LIVEBUILD),
    _make_closed_status('Lab is down even for [%s]' % _DEADBUILD),
]

_DEADBUILD_STATUS_VALUES = [
    _make_deadbuild_status('Lab is up except for [deadboard-]'),
    _make_deadbuild_status('Lab is up except for [board- deadboard-]'),
    _make_deadbuild_status('Lab is up except for [.*/R33-]'),
    _make_deadbuild_status('Lab is up except for [deadboard-.*/R33-]'),
    _make_deadbuild_status('Lab is up except for [ deadboard-]'),
    _make_deadbuild_status('Lab is up except for [deadboard- ]'),
    _make_deadbuild_status('Lab is up [first .*/R33- last]'),
    _make_deadbuild_status('liveboard is good, but [deadboard-] is bad'),
    _make_deadbuild_status('Lab is up [deadboard- otherboard-]'),
    _make_deadbuild_status('Lab is up [otherboard- deadboard-]'),
]


_FAKE_URL = 'ignore://not.a.url'


class _FakeURLResponse(object):

    """Everything needed to pretend to be a response from urlopen().

    Creates a StringIO instance to handle the File operations.

    N.B.  StringIO is lame:  we can't inherit from it (super won't
    work), and it doesn't implement __getattr__(), either.  So, we
    have to manually forward calls to the StringIO object.  This
    forwards only what empirical testing says is required; YMMV.

    """

    def __init__(self, code, buffer):
        self._stringio = six.StringIO(buffer)
        self._code = code


    def read(self, size=-1):
        """Standard file-like read operation.

        @param size size for read operation.
        """
        return self._stringio.read(size)


    def getcode(self):
        """Get URL HTTP response code."""
        return self._code


class GetStatusTest(mox.MoxTestBase):

    """Test case for _get_lab_status().

    We mock out dependencies on urllib2 and time.sleep(), and
    confirm that the function returns the proper JSON representation
    for a pre-defined response.

    """

    def setUp(self):
        super(GetStatusTest, self).setUp()
        self.mox.StubOutWithMock(urllib.request, 'urlopen')
        self.mox.StubOutWithMock(time, 'sleep')


    def test_success(self):
        """Test that successful calls to urlopen() succeed."""
        json_string = _OPEN_STATUS_VALUES[0]
        json_value = json.loads(json_string)
        urllib.request.urlopen(mox.IgnoreArg()).AndReturn(
                _FakeURLResponse(200, json_string))
        self.mox.ReplayAll()
        result = site_utils._get_lab_status(_FAKE_URL)
        self.mox.VerifyAll()
        self.assertEqual(json_value, result)


    def test_retry_ioerror(self):
        """Test that an IOError retries at least once."""
        json_string = _OPEN_STATUS_VALUES[0]
        json_value = json.loads(json_string)
        urllib.request.urlopen(mox.IgnoreArg()).AndRaise(
                IOError('Fake I/O error for a fake URL'))
        time.sleep(mox.IgnoreArg()).AndReturn(None)
        urllib.request.urlopen(mox.IgnoreArg()).AndReturn(
                _FakeURLResponse(200, json_string))
        self.mox.ReplayAll()
        result = site_utils._get_lab_status(_FAKE_URL)
        self.mox.VerifyAll()
        self.assertEqual(json_value, result)


    def test_retry_http_internal_error(self):
        """Test that an HTTP error retries at least once."""
        json_string = _OPEN_STATUS_VALUES[0]
        json_value = json.loads(json_string)
        urllib.request.urlopen(mox.IgnoreArg()).AndReturn(
                _FakeURLResponse(500, ''))
        time.sleep(mox.IgnoreArg()).AndReturn(None)
        urllib.request.urlopen(mox.IgnoreArg()).AndReturn(
                _FakeURLResponse(200, json_string))
        self.mox.ReplayAll()
        result = site_utils._get_lab_status(_FAKE_URL)
        self.mox.VerifyAll()
        self.assertEqual(json_value, result)


    def test_failure_ioerror(self):
        """Test that there's a failure if urlopen() never succeeds."""
        json_string = _OPEN_STATUS_VALUES[0]
        json_value = json.loads(json_string)
        for _ in range(site_utils._MAX_LAB_STATUS_ATTEMPTS):
            urllib.request.urlopen(mox.IgnoreArg()).AndRaise(
                    IOError('Fake I/O error for a fake URL'))
            time.sleep(mox.IgnoreArg()).AndReturn(None)
        self.mox.ReplayAll()
        result = site_utils._get_lab_status(_FAKE_URL)
        self.mox.VerifyAll()
        self.assertEqual(None, result)


    def test_failure_http_internal_error(self):
        """Test that there's a failure for a permanent HTTP error."""
        json_string = _OPEN_STATUS_VALUES[0]
        json_value = json.loads(json_string)
        for _ in range(site_utils._MAX_LAB_STATUS_ATTEMPTS):
            urllib.request.urlopen(mox.IgnoreArg()).AndReturn(
                    _FakeURLResponse(404, 'Not here, never gonna be'))
            time.sleep(mox.IgnoreArg()).InAnyOrder().AndReturn(None)
        self.mox.ReplayAll()
        result = site_utils._get_lab_status(_FAKE_URL)
        self.mox.VerifyAll()
        self.assertEqual(None, result)


class DecodeStatusTest(unittest.TestCase):

    """Test case for _decode_lab_status().

    Testing covers three distinct possible states:
     1. Lab is up.  All calls to _decode_lab_status() will
        succeed without raising an exception.
     2. Lab is down.  All calls to _decode_lab_status() will
        fail with TestLabException.
     3. Build disabled.  Calls to _decode_lab_status() will
        succeed, except that board `_DEADBUILD` will raise
        TestLabException.

    """

    def _assert_lab_open(self, lab_status):
        """Test that open status values are handled properly.

        Test that _decode_lab_status() succeeds when the lab status
        is up.

        @param lab_status JSON value describing lab status.

        """
        site_utils._decode_lab_status(lab_status, _LIVEBUILD)
        site_utils._decode_lab_status(lab_status, _DEADBUILD)


    def _assert_lab_closed(self, lab_status):
        """Test that closed status values are handled properly.

        Test that _decode_lab_status() raises TestLabException
        when the lab status is down.

        @param lab_status JSON value describing lab status.

        """
        with self.assertRaises(site_utils.TestLabException):
            site_utils._decode_lab_status(lab_status, _LIVEBUILD)
        with self.assertRaises(site_utils.TestLabException):
            site_utils._decode_lab_status(lab_status, _DEADBUILD)


    def _assert_lab_deadbuild(self, lab_status):
        """Test that disabled builds are handled properly.

        Test that _decode_lab_status() raises TestLabException
        for build `_DEADBUILD` and succeeds otherwise.

        @param lab_status JSON value describing lab status.

        """
        site_utils._decode_lab_status(lab_status, _LIVEBUILD)
        with self.assertRaises(site_utils.TestLabException):
            site_utils._decode_lab_status(lab_status, _DEADBUILD)


    def _assert_lab_status(self, test_values, checker):
        """General purpose test for _decode_lab_status().

        Decode each JSON string in `test_values`, and call the
        `checker` function to test the corresponding status is
        correctly handled.

        @param test_values Array of JSON encoded strings representing
                           lab status.
        @param checker Function to be called against each of the lab
                       status values in the `test_values` array.

        """
        for s in test_values:
            lab_status = json.loads(s)
            checker(lab_status)


    def test_open_lab(self):
        """Test that open lab status values are handled correctly."""
        self._assert_lab_status(_OPEN_STATUS_VALUES,
                                self._assert_lab_open)


    def test_closed_lab(self):
        """Test that closed lab status values are handled correctly."""
        self._assert_lab_status(_CLOSED_STATUS_VALUES,
                                self._assert_lab_closed)


    def test_dead_build(self):
        """Test that disabled builds are handled correctly."""
        self._assert_lab_status(_DEADBUILD_STATUS_VALUES,
                                self._assert_lab_deadbuild)


class CheckStatusTest(mox.MoxTestBase):

    """Test case for `check_lab_status()`.

    We mock out dependencies on `global_config.global_config()`,
    `_get_lab_status()` and confirm that the function succeeds or
    fails as expected.

    N.B.  We don't mock `_decode_lab_status()`; if DecodeStatusTest
    is failing, this test may fail, too.

    """

    def setUp(self):
        super(CheckStatusTest, self).setUp()
        self.mox.StubOutWithMock(global_config.global_config,
                                 'get_config_value')
        self.mox.StubOutWithMock(site_utils, '_get_lab_status')


    def _setup_not_cautotest(self):
        """Set up to mock the "we're not on cautotest" case."""
        global_config.global_config.get_config_value(
                'SERVER', 'hostname').AndReturn('not-cautotest')


    def _setup_no_status(self):
        """Set up to mock lab status as unavailable."""
        global_config.global_config.get_config_value(
                'SERVER', 'hostname').AndReturn('cautotest')
        global_config.global_config.get_config_value(
                'CROS', 'lab_status_url').AndReturn(_FAKE_URL)
        site_utils._get_lab_status(_FAKE_URL).AndReturn(None)


    def _setup_lab_status(self, json_string):
        """Set up to mock a given lab status.

        @param json_string JSON string for the JSON object to return
                           from `_get_lab_status()`.

        """
        global_config.global_config.get_config_value(
                'SERVER', 'hostname').AndReturn('cautotest')
        global_config.global_config.get_config_value(
                'CROS', 'lab_status_url').AndReturn(_FAKE_URL)
        json_value = json.loads(json_string)
        site_utils._get_lab_status(_FAKE_URL).AndReturn(json_value)


    def _try_check_status(self, build):
        """Test calling check_lab_status() with `build`."""
        try:
            self.mox.ReplayAll()
            site_utils.check_lab_status(build)
        finally:
            self.mox.VerifyAll()


    def test_non_cautotest(self):
        """Test a call with a build when the host isn't cautotest."""
        self._setup_not_cautotest()
        self._try_check_status(_LIVEBUILD)


    def test_no_lab_status(self):
        """Test with a build when `_get_lab_status()` returns `None`."""
        self._setup_no_status()
        self._try_check_status(_LIVEBUILD)


    def test_lab_up_live_build(self):
        """Test lab open with a build specified."""
        self._setup_lab_status(_OPEN_STATUS_VALUES[0])
        self._try_check_status(_LIVEBUILD)


    def test_lab_down_live_build(self):
        """Test lab closed with a build specified."""
        self._setup_lab_status(_CLOSED_STATUS_VALUES[0])
        with self.assertRaises(site_utils.TestLabException):
            self._try_check_status(_LIVEBUILD)


    def test_build_disabled_live_build(self):
        """Test build disabled with a live build specified."""
        self._setup_lab_status(_DEADBUILD_STATUS_VALUES[0])
        self._try_check_status(_LIVEBUILD)


    def test_build_disabled_dead_build(self):
        """Test build disabled with the disabled build specified."""
        self._setup_lab_status(_DEADBUILD_STATUS_VALUES[0])
        with self.assertRaises(site_utils.TestLabException):
            self._try_check_status(_DEADBUILD)


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