#!/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 pexpect
import unittest

import dli

import rpm_controller

import common
from autotest_lib.site_utils.rpm_control_system import utils


class TestRPMControllerQueue(mox.MoxTestBase):
    """Test request can be queued and processed in controller.
    """

    def setUp(self):
        super(TestRPMControllerQueue, self).setUp()
        self.rpm = rpm_controller.SentryRPMController('chromeos-rack1-host8')
        self.powerunit_info = utils.PowerUnitInfo(
                device_hostname='chromos-rack1-host8',
                powerunit_hostname='chromeos-rack1-rpm1',
                powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
                outlet='.A100',
                hydra_hostname=None)


    def testQueueRequest(self):
        """Should create a new process to handle request."""
        new_state = 'ON'
        process = self.mox.CreateMockAnything()
        rpm_controller.multiprocessing.Process = self.mox.CreateMockAnything()
        rpm_controller.multiprocessing.Process(target=mox.IgnoreArg(),
                args=mox.IgnoreArg()).AndReturn(process)
        process.start()
        process.join()
        self.mox.ReplayAll()
        self.assertFalse(self.rpm.queue_request(self.powerunit_info, new_state))
        self.mox.VerifyAll()


class TestSentryRPMController(mox.MoxTestBase):
    """Test SentryRPMController."""


    def setUp(self):
        super(TestSentryRPMController, self).setUp()
        self.ssh = self.mox.CreateMockAnything()
        rpm_controller.pexpect.spawn = self.mox.CreateMockAnything()
        rpm_controller.pexpect.spawn(mox.IgnoreArg()).AndReturn(self.ssh)
        self.rpm = rpm_controller.SentryRPMController('chromeos-rack1-host8')
        self.powerunit_info = utils.PowerUnitInfo(
                device_hostname='chromos-rack1-host8',
                powerunit_hostname='chromeos-rack1-rpm1',
                powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
                outlet='.A100',
                hydra_hostname=None)


    def testSuccessfullyChangeOutlet(self):
        """Should return True if change was successful."""
        prompt = 'Switched CDU:'
        password = 'dummy_admin_password'
        new_state = 'ON'
        self.ssh.expect('Password:', timeout=60)
        self.ssh.sendline(password)
        self.ssh.expect(prompt, timeout=60)
        self.ssh.sendline('%s %s' % (new_state, self.powerunit_info.outlet))
        self.ssh.expect('Command successful', timeout=60)
        self.ssh.sendline('logout')
        self.ssh.close(force=True)
        self.mox.ReplayAll()
        self.assertTrue(self.rpm.set_power_state(
                self.powerunit_info, new_state))
        self.mox.VerifyAll()


    def testUnsuccessfullyChangeOutlet(self):
        """Should return False if change was unsuccessful."""
        prompt = 'Switched CDU:'
        password = 'dummy_admin_password'
        new_state = 'ON'
        self.ssh.expect('Password:', timeout=60)
        self.ssh.sendline(password)
        self.ssh.expect(prompt, timeout=60)
        self.ssh.sendline('%s %s' % (new_state, self.powerunit_info.outlet))
        self.ssh.expect('Command successful',
                        timeout=60).AndRaise(pexpect.TIMEOUT('Timed Out'))
        self.ssh.sendline('logout')
        self.ssh.close(force=True)
        self.mox.ReplayAll()
        self.assertFalse(self.rpm.set_power_state(self.powerunit_info, new_state))
        self.mox.VerifyAll()


class TestWebPoweredRPMController(mox.MoxTestBase):
    """Test WebPoweredRPMController."""


    def setUp(self):
        super(TestWebPoweredRPMController, self).setUp()
        self.dli_ps = self.mox.CreateMock(dli.powerswitch)
        hostname = 'chromeos-rack8a-rpm1'
        self.web_rpm = rpm_controller.WebPoweredRPMController(hostname,
                                                              self.dli_ps)
        outlet = 8
        dut = 'chromeos-rack8a-host8'
        # Outlet statuses are in the format "u'ON'"
        initial_state = 'u\'ON\''
        self.test_status_list_initial = [[outlet, dut, initial_state]]
        self.powerunit_info = utils.PowerUnitInfo(
                device_hostname=dut,
                powerunit_hostname=hostname,
                powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
                outlet=outlet,
                hydra_hostname=None)


    def testSuccessfullyChangeOutlet(self):
        """Should return True if change was successful."""
        test_status_list_final = [[8, 'chromeos-rack8a-host8','u\'OFF\'']]
        self.dli_ps.statuslist().AndReturn(self.test_status_list_initial)
        self.dli_ps.off(8)
        self.dli_ps.statuslist().AndReturn(test_status_list_final)
        self.mox.ReplayAll()
        self.assertTrue(self.web_rpm.set_power_state(
                self.powerunit_info, 'OFF'))
        self.mox.VerifyAll()


    def testUnsuccessfullyChangeOutlet(self):
        """Should return False if Outlet State does not change."""
        test_status_list_final = [[8, 'chromeos-rack8a-host8','u\'ON\'']]
        self.dli_ps.statuslist().AndReturn(self.test_status_list_initial)
        self.dli_ps.off(8)
        self.dli_ps.statuslist().AndReturn(test_status_list_final)
        self.mox.ReplayAll()
        self.assertFalse(self.web_rpm.set_power_state(
                self.powerunit_info, 'OFF'))
        self.mox.VerifyAll()


    def testNoOutlet(self):
        """Should return False if DUT hostname is not on the RPM device."""
        self.powerunit_info.outlet=None
        self.assertFalse(self.web_rpm.set_power_state(
                self.powerunit_info, 'OFF'))


class TestCiscoPOEController(mox.MoxTestBase):
    """Test CiscoPOEController."""


    STREAM_WELCOME = 'This is a POE switch.\n\nUser Name:'
    STREAM_PWD = 'Password:'
    STREAM_DEVICE = '\nchromeos2-poe-sw8#'
    STREAM_CONFIG = 'chromeos2-poe-sw8(config)#'
    STREAM_CONFIG_IF = 'chromeos2-poe-sw8(config-if)#'
    STREAM_STATUS = ('\n                                             '
                     'Flow Link          Back   Mdix\n'
                     'Port     Type         Duplex  Speed Neg      '
                     'ctrl State       Pressure Mode\n'
                     '-------- ------------ ------  ----- -------- '
                     '---- ----------- -------- -------\n'
                     'fa32     100M-Copper  Full    100   Enabled  '
                     'Off  Up          Disabled Off\n')
    SERVO = 'chromeos1-rack3-host12-servo'
    SWITCH = 'chromeos2-poe-switch8'
    PORT = 'fa32'
    POWERUNIT_INFO = utils.PowerUnitInfo(
            device_hostname=PORT,
            powerunit_hostname=SERVO,
            powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.POE,
            outlet=PORT,
            hydra_hostname=None)


    def setUp(self):
        super(TestCiscoPOEController, self).setUp()
        self.mox.StubOutWithMock(pexpect.spawn, '_spawn')
        self.mox.StubOutWithMock(pexpect.spawn, 'read_nonblocking')
        self.mox.StubOutWithMock(pexpect.spawn, 'sendline')
        self.poe = rpm_controller.CiscoPOEController(self.SWITCH)
        pexpect.spawn._spawn(mox.IgnoreArg(), mox.IgnoreArg())
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_WELCOME)
        pexpect.spawn.sendline(self.poe._username)
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_PWD)
        pexpect.spawn.sendline(self.poe._password)
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_DEVICE)


    def testLogin(self):
        """Test we can log into the switch."""
        self.mox.ReplayAll()
        self.assertNotEqual(self.poe._login(), None)
        self.mox.VerifyAll()


    def _EnterConfigurationHelper(self, success=True):
        """A helper function for testing entering configuration terminal.

        @param success: True if we want the process to pass, False if we
                        want it to fail.
        """
        pexpect.spawn.sendline('configure terminal')
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_CONFIG)
        pexpect.spawn.sendline('interface %s' % self.PORT)
        if success:
            pexpect.spawn.read_nonblocking(
                    mox.IgnoreArg(),
                    mox.IgnoreArg()).AndReturn(self.STREAM_CONFIG_IF)
        else:
            self.mox.StubOutWithMock(pexpect.spawn, '__str__')
            exception = pexpect.TIMEOUT(
                    'Could not enter configuration terminal.')
            pexpect.spawn.read_nonblocking(
                    mox.IgnoreArg(),
                    mox.IgnoreArg()).MultipleTimes().AndRaise(exception)
            pexpect.spawn.__str__().AndReturn('A pexpect.spawn object.')
            pexpect.spawn.sendline('end')


    def testSuccessfullyChangeOutlet(self):
        """Should return True if change was successful."""
        self._EnterConfigurationHelper()
        pexpect.spawn.sendline('power inline auto')
        pexpect.spawn.sendline('end')
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_DEVICE)
        pexpect.spawn.sendline('show interface status %s' % self.PORT)
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_STATUS)
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_DEVICE)
        pexpect.spawn.sendline('exit')
        self.mox.ReplayAll()
        self.assertTrue(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
        self.mox.VerifyAll()


    def testUnableToEnterConfigurationTerminal(self):
        """Should return False if unable to enter configuration terminal."""
        self._EnterConfigurationHelper(success=False)
        pexpect.spawn.sendline('exit')
        self.mox.ReplayAll()
        self.assertFalse(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
        self.mox.VerifyAll()


    def testUnableToExitConfigurationTerminal(self):
        """Should return False if unable to exit configuration terminal."""
        self.mox.StubOutWithMock(pexpect.spawn, '__str__')
        self.mox.StubOutWithMock(rpm_controller.CiscoPOEController,
                                 '_enter_configuration_terminal')
        self.poe._enter_configuration_terminal(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
        pexpect.spawn.sendline('power inline auto')
        pexpect.spawn.sendline('end')
        exception = pexpect.TIMEOUT('Could not exit configuration terminal.')
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(),
                mox.IgnoreArg()).MultipleTimes().AndRaise(exception)
        pexpect.spawn.__str__().AndReturn('A pexpect.spawn object.')
        pexpect.spawn.sendline('exit')
        self.mox.ReplayAll()
        self.assertFalse(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
        self.mox.VerifyAll()


    def testUnableToVerifyState(self):
        """Should return False if unable to verify current state."""
        self.mox.StubOutWithMock(pexpect.spawn, '__str__')
        self.mox.StubOutWithMock(rpm_controller.CiscoPOEController,
                                 '_enter_configuration_terminal')
        self.mox.StubOutWithMock(rpm_controller.CiscoPOEController,
                                 '_exit_configuration_terminal')
        self.poe._enter_configuration_terminal(
                mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
        pexpect.spawn.sendline('power inline auto')
        self.poe._exit_configuration_terminal(mox.IgnoreArg()).AndReturn(True)
        pexpect.spawn.sendline('show interface status %s' % self.PORT)
        exception = pexpect.TIMEOUT('Could not verify state.')
        pexpect.spawn.read_nonblocking(
                mox.IgnoreArg(),
                mox.IgnoreArg()).MultipleTimes().AndRaise(exception)
        pexpect.spawn.__str__().AndReturn('A pexpect.spawn object.')
        pexpect.spawn.sendline('exit')
        self.mox.ReplayAll()
        self.assertFalse(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
        self.mox.VerifyAll()


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