[autotest] rpm frontend server retrieves rpm/outlet/hydra from afe

This is the 2nd CL to make rpm infra read rpm/outlet/hydra info from
afe.

The major change of this cl is to add a new method
    _get_powerunit_info(...)
For chromeos duts, it first looks up in its local lru cache for
rpm/outlet/hydra information for the dut. If not found in
local cache, retrieve the information from afe.

For servos, it loads the poe/outlet/hydra info from a local file.

The method returns an instance of PowerUnitInfo instance, which
will be passed to rpm_dispatcher.

CQ-DEPEND=CL:212349
BUG=chromium:392548
TEST=unittest.
Integration test with other cls in this series, set up
rpm server locally and change host states.

Change-Id: I63326f8b58083ebf807105d94c919bf5fd5f7cea
Reviewed-on: https://chromium-review.googlesource.com/212346
Reviewed-by: Simran Basi <sbasi@chromium.org>
Reviewed-by: Dan Shi <dshi@chromium.org>
Tested-by: Fang Deng <fdeng@chromium.org>
Commit-Queue: Fang Deng <fdeng@chromium.org>
diff --git a/site_utils/rpm_control_system/frontend_server_unittest.py b/site_utils/rpm_control_system/frontend_server_unittest.py
index 3d70ce0..e67b287 100755
--- a/site_utils/rpm_control_system/frontend_server_unittest.py
+++ b/site_utils/rpm_control_system/frontend_server_unittest.py
@@ -10,24 +10,36 @@
 import frontend_server
 from rpm_infrastructure_exception import RPMInfrastructureException
 
+import common
+from autotest_lib.site_utils.rpm_control_system import utils
+
+
 FAKE_DISPATCHER_URI1 = 'http://fake_dispatcher:1'
 FAKE_DISPATCHER_URI2 = 'http://fake_dispatcher:2'
 UNREACHABLE_SERVER_MSG = 'Server Unreachable'
 DUT_HOSTNAME = 'chromeos-rack8e-hostbs1'
+POWERUNIT_HOSTNAME = 'chromeos-rack8e-rpm1'
+OUTLET = '.A100'
 NEW_STATE = 'ON'
 FAKE_ERRNO = 1
 
 
 class TestFrontendServer(mox.MoxTestBase):
+    """Test frontend_server."""
 
 
     def setUp(self):
         super(TestFrontendServer, self).setUp()
         self.frontend = frontend_server.RPMFrontendServer()
+        self.frontend._rpm_info[DUT_HOSTNAME] = utils.PowerUnitInfo(
+                device_hostname=DUT_HOSTNAME,
+                powerunit_type=utils.PowerUnitInfo.POWERUNIT_TYPES.RPM,
+                powerunit_hostname=POWERUNIT_HOSTNAME,
+                outlet=OUTLET, hydra_hostname=None)
         self.xmlrpc_mock = self.mox.CreateMockAnything()
         frontend_server.xmlrpclib.ServerProxy = self.mox.CreateMockAnything()
-        frontend_server.xmlrpclib.ServerProxy(FAKE_DISPATCHER_URI1).AndReturn(
-                self.xmlrpc_mock)
+        frontend_server.xmlrpclib.ServerProxy(FAKE_DISPATCHER_URI1,
+                allow_none=True).AndReturn(self.xmlrpc_mock)
 
 
     def testNoRegisteredDispatchers(self):
@@ -43,7 +55,9 @@
 
         Expects the request to succeed.
         """
-        self.xmlrpc_mock.queue_request(DUT_HOSTNAME, NEW_STATE).AndReturn(True)
+        self.xmlrpc_mock.queue_request(
+                self.frontend._rpm_info[DUT_HOSTNAME],
+                NEW_STATE).AndReturn(True)
         self.mox.ReplayAll()
         self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
         self.assertTrue(self.frontend.queue_request(DUT_HOSTNAME, NEW_STATE))
@@ -56,7 +70,9 @@
 
         Expects the request to fail.
         """
-        self.xmlrpc_mock.queue_request(DUT_HOSTNAME, NEW_STATE).AndReturn(False)
+        self.xmlrpc_mock.queue_request(
+                self.frontend._rpm_info[DUT_HOSTNAME],
+                NEW_STATE).AndReturn(False)
         self.mox.ReplayAll()
         self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
         self.assertFalse(self.frontend.queue_request(DUT_HOSTNAME, NEW_STATE))
@@ -69,7 +85,9 @@
 
         queue_request should return True then False.
         """
-        self.xmlrpc_mock.queue_request(DUT_HOSTNAME, NEW_STATE).AndReturn(True)
+        self.xmlrpc_mock.queue_request(
+                self.frontend._rpm_info[DUT_HOSTNAME],
+                NEW_STATE).AndReturn(True)
         self.mox.ReplayAll()
         self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
         self.assertTrue(self.frontend.queue_request(DUT_HOSTNAME, NEW_STATE))
@@ -88,9 +106,12 @@
         The call to queue_request will raise a socket.error, and then it should
         return False as there is no other dispatch servers available.
         """
-        self.xmlrpc_mock.queue_request(DUT_HOSTNAME, NEW_STATE).AndRaise(
+        self.xmlrpc_mock.queue_request(
+                self.frontend._rpm_info[DUT_HOSTNAME], NEW_STATE).AndRaise(
                 socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
-        frontend_server.xmlrpclib.ServerProxy(FAKE_DISPATCHER_URI1).AndReturn(
+        frontend_server.xmlrpclib.ServerProxy(
+                FAKE_DISPATCHER_URI1,
+                allow_none=True).AndReturn(
                 self.xmlrpc_mock)
         self.xmlrpc_mock.is_up().AndRaise(
                 socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
@@ -110,14 +131,17 @@
         The first call to queue_request will raise a socket.error, however it
         should make a second attempt that should be successful.
         """
-        self.xmlrpc_mock.queue_request(DUT_HOSTNAME, NEW_STATE).AndRaise(
+        self.xmlrpc_mock.queue_request(
+                self.frontend._rpm_info[DUT_HOSTNAME], NEW_STATE).AndRaise(
                 socket.error(FAKE_ERRNO,UNREACHABLE_SERVER_MSG))
         frontend_server.xmlrpclib.ServerProxy(
-                mox.IgnoreArg()).MultipleTimes(3).AndReturn(self.xmlrpc_mock)
+                mox.IgnoreArg(), allow_none=True).MultipleTimes(3).AndReturn(
+                        self.xmlrpc_mock)
         self.xmlrpc_mock.is_up().AndRaise(
                 socket.error(FAKE_ERRNO, UNREACHABLE_SERVER_MSG))
         self.xmlrpc_mock.is_up().AndReturn(True)
-        self.xmlrpc_mock.queue_request(DUT_HOSTNAME, NEW_STATE).AndReturn(True)
+        self.xmlrpc_mock.queue_request(
+                self.frontend._rpm_info[DUT_HOSTNAME], NEW_STATE).AndReturn(True)
         self.mox.ReplayAll()
         self.frontend.register_dispatcher(FAKE_DISPATCHER_URI1)
         self.frontend.register_dispatcher(FAKE_DISPATCHER_URI2)