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'}})