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