1#!/usr/bin/python2
2# 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
6import mox
7import socket
8import unittest
9
10import frontend_server
11from rpm_infrastructure_exception import RPMInfrastructureException
12
13import common
14from autotest_lib.site_utils.rpm_control_system import utils
15
16
17FAKE_DISPATCHER_URI1 = 'http://fake_dispatcher:1'
18FAKE_DISPATCHER_URI2 = 'http://fake_dispatcher:2'
19UNREACHABLE_SERVER_MSG = 'Server Unreachable'
20DUT_HOSTNAME = 'chromeos-rack8e-hostbs1'
21POWERUNIT_HOSTNAME = 'chromeos-rack8e-rpm1'
22OUTLET = '.A100'
23NEW_STATE = 'ON'
24FAKE_ERRNO = 1
25
26
27class TestFrontendServer(mox.MoxTestBase):
28    """Test frontend_server."""
29
30
31    def setUp(self):
32        super(TestFrontendServer, self).setUp()
33        self.frontend = frontend_server.RPMFrontendServer()
34        self.frontend._rpm_info[DUT_HOSTNAME] = utils.PowerUnitInfo(
35                device_hostname=DUT_HOSTNAME,
36                powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
37                powerunit_hostname=POWERUNIT_HOSTNAME,
38                outlet=OUTLET, hydra_hostname=None)
39        self.xmlrpc_mock = self.mox.CreateMockAnything()
40        frontend_server.xmlrpclib.ServerProxy = self.mox.CreateMockAnything()
41        frontend_server.xmlrpclib.ServerProxy(FAKE_DISPATCHER_URI1,
42                allow_none=True).AndReturn(self.xmlrpc_mock)
43
44
45    def testNoRegisteredDispatchers(self):
46        """ Queue request with no dispatchers. Should fail. """
47        self.mox.ResetAll()
48        self.assertRaises(
49                RPMInfrastructureException,
50                self.frontend.set_power_via_rpm,
51                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
52        )
53
54
55    def testSuccessfullyQueueRequest(self):
56        """
57        Queue request with at least one dispatcher.
58
59        Expects the request to succeed.
60        """
61        self.xmlrpc_mock.queue_request(
62                mox.IgnoreArg(), NEW_STATE).AndReturn(True)
63        self.mox.ReplayAll()
64        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
65        self.assertTrue(self.frontend.set_power_via_rpm(
66                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
67        ))
68        self.mox.VerifyAll()
69
70
71    def testFailedQueueRequest(self):
72        """
73        Queue request with at least one dispatcher.
74
75        Expects the request to fail.
76        """
77        self.xmlrpc_mock.queue_request(
78                mox.IgnoreArg(), NEW_STATE).AndReturn(False)
79        self.mox.ReplayAll()
80        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
81        self.assertFalse(self.frontend.set_power_via_rpm(
82                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
83        ))
84        self.mox.VerifyAll()
85
86
87    def testAllDispatchersUnregistered(self):
88        """
89        Queue request before and after a dispatcher unregisters.
90
91        queue_request should return True then False.
92        """
93        self.xmlrpc_mock.queue_request(
94                mox.IgnoreArg(), NEW_STATE).AndReturn(True)
95        self.mox.ReplayAll()
96        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
97        self.assertTrue(self.frontend.set_power_via_rpm(
98                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
99        ))
100        self.frontend.unregister_dispatcher(FAKE_DISPATCHER_URI1)
101        self.assertRaises(
102                RPMInfrastructureException,
103                self.frontend.set_power_via_rpm,
104                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
105        )
106        self.mox.VerifyAll()
107
108
109    def testUnreachableDispatcherServer(self):
110        """
111        Make sure that if the dispatch server is unreachable and raises an error
112        that we retry the call which will fail because there is no other servers
113        available.
114
115        The call to queue_request will raise a socket.error, and then it should
116        return False as there is no other dispatch servers available.
117        """
118        self.xmlrpc_mock.queue_request(
119                mox.IgnoreArg(), NEW_STATE).AndRaise(
120                socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
121        frontend_server.xmlrpclib.ServerProxy(
122                FAKE_DISPATCHER_URI1,
123                allow_none=True).AndReturn(
124                self.xmlrpc_mock)
125        self.xmlrpc_mock.is_up().AndRaise(
126                socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
127        self.mox.ReplayAll()
128        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
129        self.assertRaises(
130                RPMInfrastructureException,
131                self.frontend.set_power_via_rpm,
132                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
133        )
134        self.mox.VerifyAll()
135
136
137    def testUnreachableDispatcherServerWithBackup(self):
138        """
139        Make sure that if the dispatch server is unreachable and raises an error
140        that we retry the call with a different dispatch server (if it's
141        available).
142
143        The first call to queue_request will raise a socket.error, however it
144        should make a second attempt that should be successful.
145        """
146        self.xmlrpc_mock.queue_request(
147                mox.IgnoreArg(), NEW_STATE).AndRaise(
148                socket.error(FAKE_ERRNO,UNREACHABLE_SERVER_MSG))
149        frontend_server.xmlrpclib.ServerProxy(
150                mox.IgnoreArg(), allow_none=True).MultipleTimes(3).AndReturn(
151                        self.xmlrpc_mock)
152        self.xmlrpc_mock.is_up().AndRaise(
153                socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
154        self.xmlrpc_mock.is_up().AndReturn(True)
155        self.xmlrpc_mock.queue_request(
156                mox.IgnoreArg(), NEW_STATE).AndReturn(True)
157        self.mox.ReplayAll()
158        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
159        self.frontend.register_dispatcher(FAKE_DISPATCHER_URI2)
160        self.assertTrue(self.frontend.set_power_via_rpm(
161                DUT_HOSTNAME, POWERUNIT_HOSTNAME, OUTLET, '', NEW_STATE,
162        ))
163        self.mox.VerifyAll()
164
165
166if __name__ == '__main__':
167    unittest.main()
168