普通文本  |  304行  |  12.27 KB

#!/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 = 'admn'
        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 = 'admn'
        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()