#!/usr/bin/python
# 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 frontend_server
from rpm_infrastructure_exception import RPMInfrastructureException

import common
from autotest_lib.site_utils.rpm_control_system import utils


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.xmlrpclib.ServerProxy = self.mox.CreateMockAnything()
        frontend_server.xmlrpclib.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.xmlrpclib.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.xmlrpclib.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()
