blob: dd6bb2fd8ce3b5ca4bafc4a372a9775a5462c7c6 [file] [log] [blame]
Scott Zawalski201d6be2012-09-21 15:56:25 -04001#!/usr/bin/python
Simran Basie6449322012-06-15 15:03:49 -07002# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
3# Use of this source code is governed by a BSD-style license that can be
4# found in the LICENSE file.
5
Simran Basie6449322012-06-15 15:03:49 -07006import mox
7import pexpect
Simran Basi7498d202012-07-10 15:21:28 -07008import unittest
Simran Basie6449322012-06-15 15:03:49 -07009
10import dli
11
12import rpm_controller
13
Fang Dengc30c4bf2014-08-13 17:21:21 -070014import common
15from autotest_lib.site_utils.rpm_control_system import utils
16
Simran Basie6449322012-06-15 15:03:49 -070017
Dan Shi6d46b562014-03-07 15:00:15 -080018class TestRPMControllerQueue(mox.MoxTestBase):
19 """Test request can be queued and processed in controller.
20 """
21
22 def setUp(self):
23 super(TestRPMControllerQueue, self).setUp()
24 self.rpm = rpm_controller.SentryRPMController('chromeos-rack1-host8')
Fang Dengc30c4bf2014-08-13 17:21:21 -070025 self.powerunit_info = utils.PowerUnitInfo(
26 device_hostname='chromos-rack1-host8',
27 powerunit_hostname='chromeos-rack1-rpm1',
28 powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
29 outlet='.A100',
30 hydra_hostname=None)
Dan Shi6d46b562014-03-07 15:00:15 -080031
32
33 def testQueueRequest(self):
34 """Should create a new process to handle request."""
Dan Shi6d46b562014-03-07 15:00:15 -080035 new_state = 'ON'
36 process = self.mox.CreateMockAnything()
37 rpm_controller.multiprocessing.Process = self.mox.CreateMockAnything()
38 rpm_controller.multiprocessing.Process(target=mox.IgnoreArg(),
39 args=mox.IgnoreArg()).AndReturn(process)
40 process.start()
41 process.join()
42 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -070043 self.assertFalse(self.rpm.queue_request(self.powerunit_info, new_state))
Dan Shi6d46b562014-03-07 15:00:15 -080044 self.mox.VerifyAll()
45
46
Simran Basie6449322012-06-15 15:03:49 -070047class TestSentryRPMController(mox.MoxTestBase):
Dan Shi6d46b562014-03-07 15:00:15 -080048 """Test SentryRPMController."""
Simran Basie6449322012-06-15 15:03:49 -070049
50
51 def setUp(self):
52 super(TestSentryRPMController, self).setUp()
Simran Basiaba8b532012-08-09 14:58:35 -070053 self.ssh = self.mox.CreateMockAnything()
54 rpm_controller.pexpect.spawn = self.mox.CreateMockAnything()
55 rpm_controller.pexpect.spawn(mox.IgnoreArg()).AndReturn(self.ssh)
56 self.rpm = rpm_controller.SentryRPMController('chromeos-rack1-host8')
Fang Dengc30c4bf2014-08-13 17:21:21 -070057 self.powerunit_info = utils.PowerUnitInfo(
58 device_hostname='chromos-rack1-host8',
59 powerunit_hostname='chromeos-rack1-rpm1',
60 powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
61 outlet='.A100',
62 hydra_hostname=None)
Simran Basie6449322012-06-15 15:03:49 -070063
64
65 def testSuccessfullyChangeOutlet(self):
66 """Should return True if change was successful."""
67 prompt = 'Switched CDU:'
Aviv Keshet4d7bbc82018-11-01 17:55:53 -070068 password = 'admn'
Simran Basie6449322012-06-15 15:03:49 -070069 new_state = 'ON'
70 self.ssh.expect('Password:', timeout=60)
71 self.ssh.sendline(password)
72 self.ssh.expect(prompt, timeout=60)
Fang Dengc30c4bf2014-08-13 17:21:21 -070073 self.ssh.sendline('%s %s' % (new_state, self.powerunit_info.outlet))
Simran Basie6449322012-06-15 15:03:49 -070074 self.ssh.expect('Command successful', timeout=60)
75 self.ssh.sendline('logout')
Fang Deng71c4b1f2013-05-20 09:55:04 -070076 self.ssh.close(force=True)
Simran Basie6449322012-06-15 15:03:49 -070077 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -070078 self.assertTrue(self.rpm.set_power_state(
79 self.powerunit_info, new_state))
Simran Basie6449322012-06-15 15:03:49 -070080 self.mox.VerifyAll()
81
82
83 def testUnsuccessfullyChangeOutlet(self):
84 """Should return False if change was unsuccessful."""
85 prompt = 'Switched CDU:'
Aviv Keshet4d7bbc82018-11-01 17:55:53 -070086 password = 'admn'
Simran Basie6449322012-06-15 15:03:49 -070087 new_state = 'ON'
88 self.ssh.expect('Password:', timeout=60)
89 self.ssh.sendline(password)
90 self.ssh.expect(prompt, timeout=60)
Fang Dengc30c4bf2014-08-13 17:21:21 -070091 self.ssh.sendline('%s %s' % (new_state, self.powerunit_info.outlet))
Simran Basie6449322012-06-15 15:03:49 -070092 self.ssh.expect('Command successful',
93 timeout=60).AndRaise(pexpect.TIMEOUT('Timed Out'))
94 self.ssh.sendline('logout')
Fang Deng71c4b1f2013-05-20 09:55:04 -070095 self.ssh.close(force=True)
Simran Basie6449322012-06-15 15:03:49 -070096 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -070097 self.assertFalse(self.rpm.set_power_state(self.powerunit_info, new_state))
Simran Basie6449322012-06-15 15:03:49 -070098 self.mox.VerifyAll()
99
100
101class TestWebPoweredRPMController(mox.MoxTestBase):
Dan Shi6d46b562014-03-07 15:00:15 -0800102 """Test WebPoweredRPMController."""
Simran Basie6449322012-06-15 15:03:49 -0700103
104
105 def setUp(self):
106 super(TestWebPoweredRPMController, self).setUp()
107 self.dli_ps = self.mox.CreateMock(dli.powerswitch)
108 hostname = 'chromeos-rack8a-rpm1'
109 self.web_rpm = rpm_controller.WebPoweredRPMController(hostname,
110 self.dli_ps)
111 outlet = 8
112 dut = 'chromeos-rack8a-host8'
113 # Outlet statuses are in the format "u'ON'"
114 initial_state = 'u\'ON\''
115 self.test_status_list_initial = [[outlet, dut, initial_state]]
Fang Dengc30c4bf2014-08-13 17:21:21 -0700116 self.powerunit_info = utils.PowerUnitInfo(
117 device_hostname=dut,
118 powerunit_hostname=hostname,
119 powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
120 outlet=outlet,
121 hydra_hostname=None)
Simran Basie6449322012-06-15 15:03:49 -0700122
123
124 def testSuccessfullyChangeOutlet(self):
125 """Should return True if change was successful."""
Fang Deng71c4b1f2013-05-20 09:55:04 -0700126 test_status_list_final = [[8, 'chromeos-rack8a-host8','u\'OFF\'']]
Simran Basie6449322012-06-15 15:03:49 -0700127 self.dli_ps.statuslist().AndReturn(self.test_status_list_initial)
128 self.dli_ps.off(8)
129 self.dli_ps.statuslist().AndReturn(test_status_list_final)
130 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -0700131 self.assertTrue(self.web_rpm.set_power_state(
132 self.powerunit_info, 'OFF'))
Simran Basie6449322012-06-15 15:03:49 -0700133 self.mox.VerifyAll()
134
135
136 def testUnsuccessfullyChangeOutlet(self):
137 """Should return False if Outlet State does not change."""
Fang Deng71c4b1f2013-05-20 09:55:04 -0700138 test_status_list_final = [[8, 'chromeos-rack8a-host8','u\'ON\'']]
Simran Basie6449322012-06-15 15:03:49 -0700139 self.dli_ps.statuslist().AndReturn(self.test_status_list_initial)
140 self.dli_ps.off(8)
141 self.dli_ps.statuslist().AndReturn(test_status_list_final)
142 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -0700143 self.assertFalse(self.web_rpm.set_power_state(
144 self.powerunit_info, 'OFF'))
Simran Basie6449322012-06-15 15:03:49 -0700145 self.mox.VerifyAll()
146
147
Fang Dengc30c4bf2014-08-13 17:21:21 -0700148 def testNoOutlet(self):
Simran Basie6449322012-06-15 15:03:49 -0700149 """Should return False if DUT hostname is not on the RPM device."""
Fang Dengc30c4bf2014-08-13 17:21:21 -0700150 self.powerunit_info.outlet=None
151 self.assertFalse(self.web_rpm.set_power_state(
152 self.powerunit_info, 'OFF'))
Simran Basie6449322012-06-15 15:03:49 -0700153
154
Fang Deng71c4b1f2013-05-20 09:55:04 -0700155class TestCiscoPOEController(mox.MoxTestBase):
156 """Test CiscoPOEController."""
157
158
159 STREAM_WELCOME = 'This is a POE switch.\n\nUser Name:'
160 STREAM_PWD = 'Password:'
161 STREAM_DEVICE = '\nchromeos2-poe-sw8#'
162 STREAM_CONFIG = 'chromeos2-poe-sw8(config)#'
163 STREAM_CONFIG_IF = 'chromeos2-poe-sw8(config-if)#'
164 STREAM_STATUS = ('\n '
165 'Flow Link Back Mdix\n'
166 'Port Type Duplex Speed Neg '
167 'ctrl State Pressure Mode\n'
168 '-------- ------------ ------ ----- -------- '
169 '---- ----------- -------- -------\n'
170 'fa32 100M-Copper Full 100 Enabled '
171 'Off Up Disabled Off\n')
172 SERVO = 'chromeos1-rack3-host12-servo'
173 SWITCH = 'chromeos2-poe-switch8'
174 PORT = 'fa32'
Fang Dengc30c4bf2014-08-13 17:21:21 -0700175 POWERUNIT_INFO = utils.PowerUnitInfo(
176 device_hostname=PORT,
177 powerunit_hostname=SERVO,
178 powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.POE,
179 outlet=PORT,
180 hydra_hostname=None)
Fang Deng71c4b1f2013-05-20 09:55:04 -0700181
182
183 def setUp(self):
184 super(TestCiscoPOEController, self).setUp()
185 self.mox.StubOutWithMock(pexpect.spawn, '_spawn')
186 self.mox.StubOutWithMock(pexpect.spawn, 'read_nonblocking')
187 self.mox.StubOutWithMock(pexpect.spawn, 'sendline')
Fang Dengc30c4bf2014-08-13 17:21:21 -0700188 self.poe = rpm_controller.CiscoPOEController(self.SWITCH)
Fang Deng71c4b1f2013-05-20 09:55:04 -0700189 pexpect.spawn._spawn(mox.IgnoreArg(), mox.IgnoreArg())
190 pexpect.spawn.read_nonblocking(
191 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_WELCOME)
192 pexpect.spawn.sendline(self.poe._username)
193 pexpect.spawn.read_nonblocking(
194 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_PWD)
195 pexpect.spawn.sendline(self.poe._password)
196 pexpect.spawn.read_nonblocking(
197 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_DEVICE)
198
199
200 def testLogin(self):
201 """Test we can log into the switch."""
202 self.mox.ReplayAll()
203 self.assertNotEqual(self.poe._login(), None)
204 self.mox.VerifyAll()
205
206
207 def _EnterConfigurationHelper(self, success=True):
208 """A helper function for testing entering configuration terminal.
209
210 @param success: True if we want the process to pass, False if we
211 want it to fail.
212 """
213 pexpect.spawn.sendline('configure terminal')
214 pexpect.spawn.read_nonblocking(
215 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_CONFIG)
216 pexpect.spawn.sendline('interface %s' % self.PORT)
217 if success:
218 pexpect.spawn.read_nonblocking(
219 mox.IgnoreArg(),
220 mox.IgnoreArg()).AndReturn(self.STREAM_CONFIG_IF)
221 else:
222 self.mox.StubOutWithMock(pexpect.spawn, '__str__')
223 exception = pexpect.TIMEOUT(
224 'Could not enter configuration terminal.')
225 pexpect.spawn.read_nonblocking(
226 mox.IgnoreArg(),
227 mox.IgnoreArg()).MultipleTimes().AndRaise(exception)
228 pexpect.spawn.__str__().AndReturn('A pexpect.spawn object.')
229 pexpect.spawn.sendline('end')
230
231
232 def testSuccessfullyChangeOutlet(self):
233 """Should return True if change was successful."""
234 self._EnterConfigurationHelper()
235 pexpect.spawn.sendline('power inline auto')
236 pexpect.spawn.sendline('end')
237 pexpect.spawn.read_nonblocking(
238 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_DEVICE)
239 pexpect.spawn.sendline('show interface status %s' % self.PORT)
240 pexpect.spawn.read_nonblocking(
241 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_STATUS)
242 pexpect.spawn.read_nonblocking(
243 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.STREAM_DEVICE)
244 pexpect.spawn.sendline('exit')
245 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -0700246 self.assertTrue(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
Fang Deng71c4b1f2013-05-20 09:55:04 -0700247 self.mox.VerifyAll()
248
249
250 def testUnableToEnterConfigurationTerminal(self):
251 """Should return False if unable to enter configuration terminal."""
252 self._EnterConfigurationHelper(success=False)
253 pexpect.spawn.sendline('exit')
254 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -0700255 self.assertFalse(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
Fang Deng71c4b1f2013-05-20 09:55:04 -0700256 self.mox.VerifyAll()
257
258
259 def testUnableToExitConfigurationTerminal(self):
260 """Should return False if unable to exit configuration terminal."""
261 self.mox.StubOutWithMock(pexpect.spawn, '__str__')
262 self.mox.StubOutWithMock(rpm_controller.CiscoPOEController,
263 '_enter_configuration_terminal')
264 self.poe._enter_configuration_terminal(
265 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
266 pexpect.spawn.sendline('power inline auto')
267 pexpect.spawn.sendline('end')
268 exception = pexpect.TIMEOUT('Could not exit configuration terminal.')
269 pexpect.spawn.read_nonblocking(
270 mox.IgnoreArg(),
271 mox.IgnoreArg()).MultipleTimes().AndRaise(exception)
272 pexpect.spawn.__str__().AndReturn('A pexpect.spawn object.')
273 pexpect.spawn.sendline('exit')
274 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -0700275 self.assertFalse(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
Fang Deng71c4b1f2013-05-20 09:55:04 -0700276 self.mox.VerifyAll()
277
278
279 def testUnableToVerifyState(self):
280 """Should return False if unable to verify current state."""
281 self.mox.StubOutWithMock(pexpect.spawn, '__str__')
282 self.mox.StubOutWithMock(rpm_controller.CiscoPOEController,
283 '_enter_configuration_terminal')
284 self.mox.StubOutWithMock(rpm_controller.CiscoPOEController,
285 '_exit_configuration_terminal')
286 self.poe._enter_configuration_terminal(
287 mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(True)
288 pexpect.spawn.sendline('power inline auto')
289 self.poe._exit_configuration_terminal(mox.IgnoreArg()).AndReturn(True)
290 pexpect.spawn.sendline('show interface status %s' % self.PORT)
291 exception = pexpect.TIMEOUT('Could not verify state.')
292 pexpect.spawn.read_nonblocking(
293 mox.IgnoreArg(),
294 mox.IgnoreArg()).MultipleTimes().AndRaise(exception)
295 pexpect.spawn.__str__().AndReturn('A pexpect.spawn object.')
296 pexpect.spawn.sendline('exit')
297 self.mox.ReplayAll()
Fang Dengc30c4bf2014-08-13 17:21:21 -0700298 self.assertFalse(self.poe.set_power_state(self.POWERUNIT_INFO, 'ON'))
Fang Deng71c4b1f2013-05-20 09:55:04 -0700299 self.mox.VerifyAll()
300
301
Simran Basie6449322012-06-15 15:03:49 -0700302if __name__ == "__main__":
303 unittest.main()