#!/usr/bin/python2
# Copyright (c) 2012 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.

import mox
import socket
import unittest

import common

from autotest_lib.site_utils.rpm_control_system import frontend_server
from autotest_lib.site_utils.rpm_control_system import utils
from autotest_lib.site_utils.rpm_control_system.rpm_infrastructure_exception import RPMInfrastructureException


FAKE_DISPATCHER_URI1 = 'http://fake_dispatcher:1'
FAKE_DISPATCHER_URI2 = 'http://fake_dispatcher:2'
UNREACHABLE_SERVER_MSG = 'Server Unreachable'
DUT_HOSTNAME = 'chromeos-rack8e-hostbs1'
POWERUNIT_HOSTNAME = 'chromeos-rack8e-rpm1'
OUTLET = '.A100'
NEW_STATE = 'ON'
FAKE_ERRNO = 1


class TestFrontendServer(mox.MoxTestBase):
    """Test frontend_server."""


    def setUp(self):
        super(TestFrontendServer, self).setUp()
        self.frontend = frontend_server.RPMFrontendServer()
        self.frontend._rpm_info[DUT_HOSTNAME] = utils.PowerUnitInfo(
                device_hostname=DUT_HOSTNAME,
                powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
                powerunit_hostname=POWERUNIT_HOSTNAME,
                outlet=OUTLET, hydra_hostname=None)
        self.xmlrpc_mock = self.mox.CreateMockAnything()
        frontend_server.xmlrpc_client.ServerProxy = self.mox.CreateMockAnything(
        )
        frontend_server.xmlrpc_client.ServerProxy(FAKE_DISPATCHER_URI1,
                                                  allow_none=True).AndReturn(
                                                          self.xmlrpc_mock)


    def testNoRegisteredDispatchers(self):
        """ Queue request with no dispatchers. Should fail. """
        self.mox.ResetAll()
        self.assertRaises(
                RPMInfrastructureException,
                self.frontend.set_power_via_rpm,
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        )


    def testSuccessfullyQueueRequest(self):
        """
        Queue request with at least one dispatcher.

        Expects the request to succeed.
        """
        self.xmlrpc_mock.queue_request(
                mox.IgnoreArg(), NEW_STATE).AndReturn(True)
        self.mox.ReplayAll()
        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
        self.assertTrue(self.frontend.set_power_via_rpm(
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        ))
        self.mox.VerifyAll()


    def testFailedQueueRequest(self):
        """
        Queue request with at least one dispatcher.

        Expects the request to fail.
        """
        self.xmlrpc_mock.queue_request(
                mox.IgnoreArg(), NEW_STATE).AndReturn(False)
        self.mox.ReplayAll()
        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
        self.assertFalse(self.frontend.set_power_via_rpm(
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        ))
        self.mox.VerifyAll()


    def testAllDispatchersUnregistered(self):
        """
        Queue request before and after a dispatcher unregisters.

        queue_request should return True then False.
        """
        self.xmlrpc_mock.queue_request(
                mox.IgnoreArg(), NEW_STATE).AndReturn(True)
        self.mox.ReplayAll()
        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
        self.assertTrue(self.frontend.set_power_via_rpm(
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        ))
        self.frontend.unregister_dispatcher(FAKE_DISPATCHER_URI1)
        self.assertRaises(
                RPMInfrastructureException,
                self.frontend.set_power_via_rpm,
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        )
        self.mox.VerifyAll()


    def testUnreachableDispatcherServer(self):
        """
        Make sure that if the dispatch server is unreachable and raises an error
        that we retry the call which will fail because there is no other servers
        available.

        The call to queue_request will raise a socket.error, and then it should
        return False as there is no other dispatch servers available.
        """
        self.xmlrpc_mock.queue_request(
                mox.IgnoreArg(), NEW_STATE).AndRaise(
                socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
        frontend_server.xmlrpc_client.ServerProxy(FAKE_DISPATCHER_URI1,
                                                  allow_none=True).AndReturn(
                                                          self.xmlrpc_mock)
        self.xmlrpc_mock.is_up().AndRaise(
                socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
        self.mox.ReplayAll()
        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
        self.assertRaises(
                RPMInfrastructureException,
                self.frontend.set_power_via_rpm,
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        )
        self.mox.VerifyAll()


    def testUnreachableDispatcherServerWithBackup(self):
        """
        Make sure that if the dispatch server is unreachable and raises an error
        that we retry the call with a different dispatch server (if it's
        available).

        The first call to queue_request will raise a socket.error, however it
        should make a second attempt that should be successful.
        """
        self.xmlrpc_mock.queue_request(
                mox.IgnoreArg(), NEW_STATE).AndRaise(
                socket.error(FAKE_ERRNO,UNREACHABLE_SERVER_MSG))
        frontend_server.xmlrpc_client.ServerProxy(
                mox.IgnoreArg(),
                allow_none=True).MultipleTimes(3).AndReturn(self.xmlrpc_mock)
        self.xmlrpc_mock.is_up().AndRaise(
                socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
        self.xmlrpc_mock.is_up().AndReturn(True)
        self.xmlrpc_mock.queue_request(
                mox.IgnoreArg(), NEW_STATE).AndReturn(True)
        self.mox.ReplayAll()
        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI2)
        self.assertTrue(self.frontend.set_power_via_rpm(
                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
        ))
        self.mox.VerifyAll()


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