Blob Blame History Raw
From d0b32e693eadf6fdc9e885dbe09656a69d5e3662 Mon Sep 17 00:00:00 2001
From: Chris Behrens <cbehrens@codestud.com>
Date: Mon, 9 Apr 2012 19:23:03 +0000
Subject: [PATCH] Create compute.api.BaseAPI for compute APIs to use

Fixes bug 960226 where compute.api.HostAPI called non-existent methods

Regression was introduced here:
https://review.openstack.org/#change,5252

Added tests for HostAPI

Change-Id: Id17927bc608ff638ea9b0b5509f0f0bb14503f85
---
 nova/compute/api.py        |   36 ++++++++++++++++++--------------
 nova/tests/test_compute.py |   48 +++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 67 insertions(+), 17 deletions(-)

diff --git a/nova/compute/api.py b/nova/compute/api.py
index 6edfefd..92adea1 100644
--- a/nova/compute/api.py
+++ b/nova/compute/api.py
@@ -106,17 +106,10 @@ def check_policy(context, action, target):
     nova.policy.enforce(context, _action, target)
 
 
-class API(base.Base):
-    """API for interacting with the compute manager."""
-
-    def __init__(self, image_service=None, network_api=None, volume_api=None,
-                 **kwargs):
-        self.image_service = (image_service or
-                              nova.image.get_default_image_service())
-
-        self.network_api = network_api or network.API()
-        self.volume_api = volume_api or volume.API()
-        super(API, self).__init__(**kwargs)
+class BaseAPI(base.Base):
+    """Base API class."""
+    def __init__(self, **kwargs):
+        super(BaseAPI, self).__init__(**kwargs)
 
     def _cast_or_call_compute_message(self, rpc_method, compute_method,
             context, instance=None, host=None, params=None):
@@ -157,10 +150,24 @@ class API(base.Base):
         """Generic handler for RPC calls to compute."""
         return self._cast_or_call_compute_message(rpc.call, *args, **kwargs)
 
-    def _cast_scheduler_message(self, context, args):
+    @staticmethod
+    def _cast_scheduler_message(context, args):
         """Generic handler for RPC calls to the scheduler."""
         rpc.cast(context, FLAGS.scheduler_topic, args)
 
+
+class API(BaseAPI):
+    """API for interacting with the compute manager."""
+
+    def __init__(self, image_service=None, network_api=None, volume_api=None,
+                 **kwargs):
+        self.image_service = (image_service or
+                              nova.image.get_default_image_service())
+
+        self.network_api = network_api or network.API()
+        self.volume_api = volume_api or volume.API()
+        super(API, self).__init__(**kwargs)
+
     def _check_injected_file_quota(self, context, injected_files):
         """Enforce quota limits on injected files.
 
@@ -1677,11 +1684,8 @@ class API(base.Base):
         return self.db.instance_fault_get_by_instance_uuids(context, uuids)
 
 
-class HostAPI(base.Base):
+class HostAPI(BaseAPI):
     """Sub-set of the Compute Manager API for managing host operations."""
-    def __init__(self, **kwargs):
-        super(HostAPI, self).__init__(**kwargs)
-
     def set_host_enabled(self, context, host, enabled):
         """Sets the specified host's ability to accept new instances."""
         # NOTE(comstud): No instance_uuid argument to this compute manager
diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py
index 305282c..2e7e7de 100644
--- a/nova/tests/test_compute.py
+++ b/nova/tests/test_compute.py
@@ -24,7 +24,6 @@ import sys
 import time
 
 import mox
-import webob.exc
 
 import nova
 import nova.common.policy
@@ -3643,3 +3642,50 @@ class ComputePolicyTestCase(BaseTestCase):
         self.assertRaises(exception.PolicyNotAuthorized,
                           self.compute_api.get_instance_faults,
                           self.context, instances)
+
+
+class ComputeHostAPITestCase(BaseTestCase):
+    def setUp(self):
+        super(ComputeHostAPITestCase, self).setUp()
+        self.host_api = compute_api.HostAPI()
+
+    def _rpc_call_stub(self, call_info):
+        def fake_rpc_call(context, topic, msg):
+            call_info['context'] = context
+            call_info['topic'] = topic
+            call_info['msg'] = msg
+        self.stubs.Set(rpc, 'call', fake_rpc_call)
+
+    def test_set_host_enabled(self):
+        ctxt = context.RequestContext('fake', 'fake')
+        call_info = {}
+        self._rpc_call_stub(call_info)
+
+        self.host_api.set_host_enabled(ctxt, 'fake_host', 'fake_enabled')
+        self.assertEqual(call_info['context'], ctxt)
+        self.assertEqual(call_info['topic'], 'compute.fake_host')
+        self.assertEqual(call_info['msg'],
+                {'method': 'set_host_enabled',
+                 'args': {'enabled': 'fake_enabled'}})
+
+    def test_host_power_action(self):
+        ctxt = context.RequestContext('fake', 'fake')
+        call_info = {}
+        self._rpc_call_stub(call_info)
+        self.host_api.host_power_action(ctxt, 'fake_host', 'fake_action')
+        self.assertEqual(call_info['context'], ctxt)
+        self.assertEqual(call_info['topic'], 'compute.fake_host')
+        self.assertEqual(call_info['msg'],
+                {'method': 'host_power_action',
+                 'args': {'action': 'fake_action'}})
+
+    def test_set_host_maintenance(self):
+        ctxt = context.RequestContext('fake', 'fake')
+        call_info = {}
+        self._rpc_call_stub(call_info)
+        self.host_api.set_host_maintenance(ctxt, 'fake_host', 'fake_mode')
+        self.assertEqual(call_info['context'], ctxt)
+        self.assertEqual(call_info['topic'], 'compute.fake_host')
+        self.assertEqual(call_info['msg'],
+                {'method': 'host_maintenance_mode',
+                 'args': {'host': 'fake_host', 'mode': 'fake_mode'}})