diff options
| author | Rick Harris <rconradharris@gmail.com> | 2011-09-21 16:00:53 -0500 |
|---|---|---|
| committer | Rick Harris <rconradharris@gmail.com> | 2011-09-21 16:00:53 -0500 |
| commit | 4fb602fcbc2a7b0681e79454fe7c3f01110b1f0e (patch) | |
| tree | 1c5c5f7ded02c886f48d5e2fa008881c7f0ebdc1 | |
| parent | 748b056209947032735c71212b8be21a16f2cadf (diff) | |
| parent | 9cf7352fbd26fe8db4205c385b92778603af7797 (diff) | |
| download | nova-4fb602fcbc2a7b0681e79454fe7c3f01110b1f0e.tar.gz nova-4fb602fcbc2a7b0681e79454fe7c3f01110b1f0e.tar.xz nova-4fb602fcbc2a7b0681e79454fe7c3f01110b1f0e.zip | |
Renumbering instance progress migration
| -rw-r--r-- | nova/api/openstack/servers.py | 41 | ||||
| -rw-r--r-- | nova/api/openstack/zones.py | 2 | ||||
| -rw-r--r-- | nova/compute/api.py | 6 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py | 35 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/migrate_repo/versions/049_add_instances_progress.py (renamed from nova/db/sqlalchemy/migrate_repo/versions/048_add_instances_progress.py) | 0 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/models.py | 1 | ||||
| -rw-r--r-- | nova/rpc/impl_kombu.py | 1 | ||||
| -rw-r--r-- | nova/scheduler/abstract_scheduler.py | 3 | ||||
| -rw-r--r-- | nova/scheduler/api.py | 58 | ||||
| -rw-r--r-- | nova/scheduler/zone_manager.py | 17 | ||||
| -rw-r--r-- | nova/tests/scheduler/test_scheduler.py | 68 | ||||
| -rw-r--r-- | nova/tests/test_zones.py | 29 | ||||
| -rw-r--r-- | tools/pip-requires | 2 |
13 files changed, 192 insertions, 71 deletions
diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index 0e7c37486..1a4703069 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -17,6 +17,7 @@ import base64 import os import traceback +from novaclient import exceptions as novaclient_exceptions from lxml import etree from webob import exc import webob @@ -45,6 +46,27 @@ LOG = logging.getLogger('nova.api.openstack.servers') FLAGS = flags.FLAGS +class ConvertedException(exc.WSGIHTTPException): + def __init__(self, code, title, explanation): + self.code = code + self.title = title + self.explanation = explanation + super(ConvertedException, self).__init__() + + +def novaclient_exception_converter(f): + """Convert novaclient ClientException HTTP codes to webob exceptions. + Has to be the outer-most decorator. + """ + def new_f(*args, **kwargs): + try: + ret = f(*args, **kwargs) + return ret + except novaclient_exceptions.ClientException, e: + raise ConvertedException(e.code, e.message, e.details) + return new_f + + class Controller(object): """ The Server API base controller class for the OpenStack API """ @@ -135,6 +157,7 @@ class Controller(object): return dict(servers=servers) + @novaclient_exception_converter @scheduler_api.redirect_handler def show(self, req, id): """ Returns server details by server id """ @@ -210,6 +233,7 @@ class Controller(object): def _update(self, context, req, id, inst_dict): return exc.HTTPNotImplemented() + @novaclient_exception_converter @scheduler_api.redirect_handler def action(self, req, id, body): """Multi-purpose method used to take actions on a server""" @@ -348,6 +372,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def lock(self, req, id): """ @@ -364,6 +389,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def unlock(self, req, id): """ @@ -380,6 +406,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def get_lock(self, req, id): """ @@ -395,6 +422,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def reset_network(self, req, id): """ @@ -410,6 +438,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def inject_network_info(self, req, id): """ @@ -425,6 +454,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def pause(self, req, id): """ Permit Admins to Pause the server. """ @@ -437,6 +467,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def unpause(self, req, id): """ Permit Admins to Unpause the server. """ @@ -449,6 +480,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def suspend(self, req, id): """permit admins to suspend the server""" @@ -461,6 +493,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def resume(self, req, id): """permit admins to resume the server from suspend""" @@ -473,6 +506,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def migrate(self, req, id): try: @@ -482,6 +516,7 @@ class Controller(object): raise exc.HTTPBadRequest() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def rescue(self, req, id, body={}): """Permit users to rescue the server.""" @@ -500,6 +535,7 @@ class Controller(object): return {'adminPass': password} + @novaclient_exception_converter @scheduler_api.redirect_handler def unrescue(self, req, id): """Permit users to unrescue the server.""" @@ -512,6 +548,7 @@ class Controller(object): raise exc.HTTPUnprocessableEntity() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def get_ajax_console(self, req, id): """Returns a url to an instance's ajaxterm console.""" @@ -522,6 +559,7 @@ class Controller(object): raise exc.HTTPNotFound() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def get_vnc_console(self, req, id): """Returns a url to an instance's ajaxterm console.""" @@ -532,6 +570,7 @@ class Controller(object): raise exc.HTTPNotFound() return webob.Response(status_int=202) + @novaclient_exception_converter @scheduler_api.redirect_handler def diagnostics(self, req, id): """Permit Admins to retrieve server diagnostics.""" @@ -574,6 +613,7 @@ class Controller(object): class ControllerV10(Controller): """v1.0 OpenStack API controller""" + @novaclient_exception_converter @scheduler_api.redirect_handler def delete(self, req, id): """ Destroys a server """ @@ -652,6 +692,7 @@ class ControllerV10(Controller): class ControllerV11(Controller): """v1.1 OpenStack API controller""" + @novaclient_exception_converter @scheduler_api.redirect_handler def delete(self, req, id): """ Destroys a server """ diff --git a/nova/api/openstack/zones.py b/nova/api/openstack/zones.py index a2bf267ed..998498e82 100644 --- a/nova/api/openstack/zones.py +++ b/nova/api/openstack/zones.py @@ -46,7 +46,7 @@ def _filter_keys(item, keys): def _exclude_keys(item, keys): - return dict((k, v) for k, v in item.iteritems() if k not in keys) + return dict((k, v) for k, v in item.iteritems() if k and (k not in keys)) def _scrub_zone(zone): diff --git a/nova/compute/api.py b/nova/compute/api.py index 76b0596e7..cedbd747a 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -995,10 +995,8 @@ class API(base.Base): if not recurse_zones: return instances - # Recurse zones. Need admin context for this. Send along - # the un-modified search options we received.. - admin_context = context.elevated() - children = scheduler_api.call_zone_method(admin_context, + # Recurse zones. Send along the un-modified search options we received. + children = scheduler_api.call_zone_method(context, "list", errors_to_ignore=[novaclient.exceptions.NotFound], novaclient_collection_name="servers", diff --git a/nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py b/nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py new file mode 100644 index 000000000..3198e48a9 --- /dev/null +++ b/nova/db/sqlalchemy/migrate_repo/versions/048_add_zone_name.py @@ -0,0 +1,35 @@ +# Copyright 2011 OpenStack LLC. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +from sqlalchemy import Column, Integer, MetaData, String, Table + +meta = MetaData() + +zones = Table('zones', meta, + Column('id', Integer(), primary_key=True, nullable=False), + ) + +name = Column('name', String(255)) + + +def upgrade(migrate_engine): + meta.bind = migrate_engine + + zones.create_column(name) + + +def downgrade(migrate_engine): + meta.bind = migrate_engine + + zones.drop_column(name) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/048_add_instances_progress.py b/nova/db/sqlalchemy/migrate_repo/versions/049_add_instances_progress.py index d23d52e80..d23d52e80 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/048_add_instances_progress.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/049_add_instances_progress.py diff --git a/nova/db/sqlalchemy/models.py b/nova/db/sqlalchemy/models.py index b7a35f881..2261a1d09 100644 --- a/nova/db/sqlalchemy/models.py +++ b/nova/db/sqlalchemy/models.py @@ -839,6 +839,7 @@ class Zone(BASE, NovaBase): """Represents a child zone of this zone.""" __tablename__ = 'zones' id = Column(Integer, primary_key=True) + name = Column(String(255)) api_url = Column(String(255)) username = Column(String(255)) password = Column(String(255)) diff --git a/nova/rpc/impl_kombu.py b/nova/rpc/impl_kombu.py index b994a6a10..e7fc491ea 100644 --- a/nova/rpc/impl_kombu.py +++ b/nova/rpc/impl_kombu.py @@ -728,7 +728,6 @@ def multicall(context, topic, msg): wait_msg = MulticallWaiter(conn) conn.declare_direct_consumer(msg_id, wait_msg) conn.topic_send(topic, msg) - return wait_msg diff --git a/nova/scheduler/abstract_scheduler.py b/nova/scheduler/abstract_scheduler.py index 6e8c7d715..b121444f2 100644 --- a/nova/scheduler/abstract_scheduler.py +++ b/nova/scheduler/abstract_scheduler.py @@ -118,7 +118,8 @@ class AbstractScheduler(driver.Scheduler): ". ReservationID=%(reservation_id)s") % locals()) nova = None try: - nova = novaclient.Client(zone.username, zone.password, None, url) + nova = novaclient.Client(zone.username, zone.password, None, url, + token=context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: raise exception.NotAuthorized(_("Bad credentials attempting " diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index 719437b73..44e01aa0c 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -17,6 +17,8 @@ Handles all requests relating to schedulers. """ +import functools + from novaclient import v1_1 as novaclient from novaclient import exceptions as novaclient_exceptions @@ -117,13 +119,16 @@ def call_zone_method(context, method_name, errors_to_ignore=None, zones = db.zone_get_all(context) for zone in zones: try: + # Do this on behalf of the user ... nova = novaclient.Client(zone.username, zone.password, None, - zone.api_url) + zone.api_url, region_name=zone.name, + token=context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: url = zone.api_url - LOG.warn(_("Failed request to zone; URL=%(url)s: %(e)s") - % locals()) + name = zone.name + LOG.warn(_("Authentication failed to zone " + "'%(name)s' URL=%(url)s: %(e)s") % locals()) #TODO (dabo) - add logic for failure counts per zone, # with escalation after a given number of failures. continue @@ -144,25 +149,20 @@ def call_zone_method(context, method_name, errors_to_ignore=None, return [(zone.id, res.wait()) for zone, res in results] -def child_zone_helper(zone_list, func): +def child_zone_helper(context, zone_list, func): """Fire off a command to each zone in the list. The return is [novaclient return objects] from each child zone. For example, if you are calling server.pause(), the list will be whatever the response from server.pause() is. One entry per child zone called.""" - def _wrap_method(function, arg1): - """Wrap method to supply an argument.""" - def _wrap(*args, **kwargs): - return function(arg1, *args, **kwargs) - return _wrap - - def _process(func, zone): + def _process(func, context, zone): """Worker stub for green thread pool. Give the worker an authenticated nova client and zone info.""" try: nova = novaclient.Client(zone.username, zone.password, None, - zone.api_url) + zone.api_url, region_name=zone.name, + token=context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: url = zone.api_url @@ -174,11 +174,15 @@ def child_zone_helper(zone_list, func): # there if no other zones had a response. return exception.ZoneRequestError() else: - return func(nova, zone) + try: + answer = func(nova, zone) + return answer + except Exception, e: + return e green_pool = greenpool.GreenPool() return [result for result in green_pool.imap( - _wrap_method(_process, func), zone_list)] + functools.partial(_process, func, context), zone_list)] def _issue_novaclient_command(nova, zone, collection, @@ -211,11 +215,11 @@ def _issue_novaclient_command(nova, zone, collection, item = args.pop(0) try: result = manager.get(item) - except novaclient_exceptions.NotFound: + except novaclient_exceptions.NotFound, e: url = zone.api_url LOG.debug(_("%(collection)s '%(item)s' not found on '%(url)s'" % locals())) - return None + raise e if method_name.lower() != 'get': # if we're doing something other than 'get', call it passing args. @@ -278,7 +282,7 @@ class reroute_compute(object): # Ask the children to provide an answer ... LOG.debug(_("Asking child zones ...")) - result = self._call_child_zones(zones, + result = self._call_child_zones(context, zones, wrap_novaclient_function(_issue_novaclient_command, collection, self.method_name, item_uuid)) # Scrub the results and raise another exception @@ -318,10 +322,10 @@ class reroute_compute(object): return wrapped_f - def _call_child_zones(self, zones, function): + def _call_child_zones(self, context, zones, function): """Ask the child zones to perform this operation. Broken out for testing.""" - return child_zone_helper(zones, function) + return child_zone_helper(context, zones, function) def get_collection_context_and_id(self, args, kwargs): """Returns a tuple of (novaclient collection name, security @@ -369,11 +373,19 @@ class reroute_compute(object): del server[k] reduced_response.append(dict(server=server)) + + # Boil the responses down to a single response. + # + # If we get a happy response use that, ignore all the + # complaint repsonses ... if reduced_response: return reduced_response[0] # first for now. elif found_exception: - raise found_exception - raise exception.InstanceNotFound(instance_id=self.item_uuid) + return found_exception + + # Some operations, like delete(), don't send back any results + # on success. We'll do the same. + return None def redirect_handler(f): @@ -381,5 +393,9 @@ def redirect_handler(f): try: return f(*args, **kwargs) except RedirectResult, e: + # Remember: exceptions are returned, not thrown, in the decorator. + # At this point it's safe to throw it. + if isinstance(e.results, BaseException): + raise e.results return e.results return new_f diff --git a/nova/scheduler/zone_manager.py b/nova/scheduler/zone_manager.py index 9d05ea42e..c61ff7b77 100644 --- a/nova/scheduler/zone_manager.py +++ b/nova/scheduler/zone_manager.py @@ -51,16 +51,18 @@ class ZoneState(object): def update_credentials(self, zone): """Update zone credentials from db""" self.zone_id = zone.id + self.name = zone.name self.api_url = zone.api_url self.username = zone.username self.password = zone.password + self.weight_offset = zone.weight_offset + self.weight_scale = zone.weight_scale def update_metadata(self, zone_metadata): """Update zone metadata after successful communications with child zone.""" self.last_seen = utils.utcnow() self.attempt = 0 - self.name = zone_metadata.get("name", "n/a") self.capabilities = ", ".join(["%s=%s" % (k, v) for k, v in zone_metadata.iteritems() if k != 'name']) self.is_active = True @@ -68,7 +70,8 @@ class ZoneState(object): def to_dict(self): return dict(name=self.name, capabilities=self.capabilities, is_active=self.is_active, api_url=self.api_url, - id=self.zone_id) + id=self.zone_id, weight_scale=self.weight_scale, + weight_offset=self.weight_offset) def log_error(self, exception): """Something went wrong. Check to see if zone should be @@ -89,15 +92,19 @@ class ZoneState(object): def _call_novaclient(zone): - """Call novaclient. Broken out for testing purposes.""" + """Call novaclient. Broken out for testing purposes. Note that + we have to use the admin credentials for this since there is no + available context.""" client = novaclient.Client(zone.username, zone.password, None, - zone.api_url) + zone.api_url, region_name=zone.name) return client.zones.info()._info def _poll_zone(zone): """Eventlet worker to poll a zone.""" - logging.debug(_("Polling zone: %s") % zone.api_url) + name = zone.name + url = zone.api_url + logging.debug(_("Polling zone: %(name)s @ %(url)s") % locals()) try: zone.update_metadata(_call_novaclient(zone)) except Exception, e: diff --git a/nova/tests/scheduler/test_scheduler.py b/nova/tests/scheduler/test_scheduler.py index 890348192..0b51792a0 100644 --- a/nova/tests/scheduler/test_scheduler.py +++ b/nova/tests/scheduler/test_scheduler.py @@ -53,6 +53,10 @@ FAKE_UUID_NOT_FOUND = 'ffffffff-ffff-ffff-ffff-ffffffffffff' FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' +class FakeContext(object): + auth_token = None + + class TestDriver(driver.Scheduler): """Scheduler Driver for Tests""" def schedule(context, topic, *args, **kwargs): @@ -956,11 +960,12 @@ class MultiDriverTestCase(SimpleDriverTestCase): class FakeZone(object): - def __init__(self, id, api_url, username, password): + def __init__(self, id, api_url, username, password, name='child'): self.id = id self.api_url = api_url self.username = username self.password = password + self.name = name ZONE_API_URL1 = "http://1.example.com" @@ -986,7 +991,7 @@ class FakeRerouteCompute(api.reroute_compute): super(FakeRerouteCompute, self).__init__(method_name) self.id_to_return = id_to_return - def _call_child_zones(self, zones, function): + def _call_child_zones(self, context, zones, function): return [] def get_collection_context_and_id(self, args, kwargs): @@ -1071,8 +1076,8 @@ class ZoneRedirectTest(test.TestCase): def test_unmarshal_single_server(self): decorator = api.reroute_compute("foo") decorator.item_uuid = 'fake_uuid' - self.assertRaises(exception.InstanceNotFound, - decorator.unmarshall_result, []) + result = decorator.unmarshall_result([]) + self.assertEquals(decorator.unmarshall_result([]), None) self.assertEquals(decorator.unmarshall_result( [FakeResource(dict(a=1, b=2)), ]), dict(server=dict(a=1, b=2))) @@ -1092,7 +1097,8 @@ class ZoneRedirectTest(test.TestCase): return None class FakeNovaClientWithFailure(object): - def __init__(self, username, password, method, api_url): + def __init__(self, username, password, method, api_url, + token=None, region_name=None): self.api_url = api_url def authenticate(self): @@ -1107,8 +1113,11 @@ class ZoneRedirectTest(test.TestCase): def do_get(self, context, uuid): pass - self.assertRaises(exception.ZoneRequestError, - do_get, None, {}, FAKE_UUID) + try: + do_get(None, FakeContext(), FAKE_UUID) + self.fail("Should have got redirect exception.") + except api.RedirectResult, e: + self.assertTrue(isinstance(e.results, exception.ZoneRequestError)) def test_one_zone_down_got_instance(self): @@ -1120,7 +1129,8 @@ class ZoneRedirectTest(test.TestCase): return FakeServer() class FakeNovaClientWithFailure(object): - def __init__(self, username, password, method, api_url): + def __init__(self, username, password, method, api_url, + token=None, region_name=None): self.api_url = api_url def authenticate(self): @@ -1136,14 +1146,14 @@ class ZoneRedirectTest(test.TestCase): pass try: - do_get(None, {}, FAKE_UUID) + do_get(None, FakeContext(), FAKE_UUID) except api.RedirectResult, e: results = e.results self.assertIn('server', results) self.assertEqual(results['server']['id'], FAKE_UUID) self.assertEqual(results['server']['test'], '1234') except Exception, e: - self.fail(_("RedirectResult should have been raised")) + self.fail(_("RedirectResult should have been raised: %s" % e)) else: self.fail(_("RedirectResult should have been raised")) @@ -1153,7 +1163,8 @@ class ZoneRedirectTest(test.TestCase): return None class FakeNovaClientNoFailure(object): - def __init__(self, username, password, method, api_url): + def __init__(self, username, password, method, api_url, + token=None, region_name=None): pass def authenticate(self): @@ -1167,8 +1178,11 @@ class ZoneRedirectTest(test.TestCase): def do_get(self, context, uuid): pass - self.assertRaises(exception.InstanceNotFound, - do_get, None, {}, FAKE_UUID) + try: + do_get(None, FakeContext(), FAKE_UUID) + self.fail("Expected redirect exception") + except api.RedirectResult, e: + self.assertEquals(e.results, None) class FakeServerCollection(object): @@ -1209,17 +1223,19 @@ class DynamicNovaClientTest(test.TestCase): def test_issue_novaclient_command_not_found(self): zone = FakeZone(1, 'http://example.com', 'bob', 'xxx') - self.assertEquals(api._issue_novaclient_command( - FakeNovaClient(FakeEmptyServerCollection()), - zone, "servers", "get", 100), None) - - self.assertEquals(api._issue_novaclient_command( - FakeNovaClient(FakeEmptyServerCollection()), - zone, "servers", "find", name="test"), None) + try: + api._issue_novaclient_command(FakeNovaClient( + FakeEmptyServerCollection()), zone, "servers", "get", 100) + self.fail("Expected NotFound exception") + except novaclient_exceptions.NotFound, e: + pass - self.assertEquals(api._issue_novaclient_command( - FakeNovaClient(FakeEmptyServerCollection()), - zone, "servers", "any", "name"), None) + try: + api._issue_novaclient_command(FakeNovaClient( + FakeEmptyServerCollection()), zone, "servers", "any", "name") + self.fail("Expected NotFound exception") + except novaclient_exceptions.NotFound, e: + pass class FakeZonesProxy(object): @@ -1250,7 +1266,7 @@ class CallZoneMethodTest(test.TestCase): super(CallZoneMethodTest, self).tearDown() def test_call_zone_method(self): - context = {} + context = FakeContext() method = 'do_something' results = api.call_zone_method(context, method) self.assertEqual(len(results), 2) @@ -1258,12 +1274,12 @@ class CallZoneMethodTest(test.TestCase): self.assertIn((2, 42), results) def test_call_zone_method_not_present(self): - context = {} + context = FakeContext() method = 'not_present' self.assertRaises(AttributeError, api.call_zone_method, context, method) def test_call_zone_method_generates_exception(self): - context = {} + context = FakeContext() method = 'raises_exception' self.assertRaises(Exception, api.call_zone_method, context, method) diff --git a/nova/tests/test_zones.py b/nova/tests/test_zones.py index 9efa23015..9b5b9b24a 100644 --- a/nova/tests/test_zones.py +++ b/nova/tests/test_zones.py @@ -63,7 +63,8 @@ class ZoneManagerTestCase(test.TestCase): self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=1, api_url='http://foo.com', username='user1', - password='pass1'), + password='pass1', name='child', weight_offset=0.0, + weight_scale=1.0), ]) self.assertEquals(len(zm.zone_states), 0) @@ -107,13 +108,15 @@ class ZoneManagerTestCase(test.TestCase): zm = zone_manager.ZoneManager() zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', - username='user1', password='pass1')) + username='user1', password='pass1', name='child', + weight_offset=0.0, weight_scale=1.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=1, api_url='http://foo.com', username='user2', - password='pass2'), + password='pass2', name='child', + weight_offset=0.0, weight_scale=1.0), ]) self.assertEquals(len(zm.zone_states), 1) @@ -129,7 +132,8 @@ class ZoneManagerTestCase(test.TestCase): zm = zone_manager.ZoneManager() zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', - username='user1', password='pass1')) + username='user1', password='pass1', name='child', + weight_offset=0.0, weight_scale=1.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') @@ -147,14 +151,16 @@ class ZoneManagerTestCase(test.TestCase): zm = zone_manager.ZoneManager() zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=1, api_url='http://foo.com', - username='user1', password='pass1')) + username='user1', password='pass1', name='child', + weight_offset=2.0, weight_scale=3.0)) zm.zone_states[1] = zone_state self.mox.StubOutWithMock(db, 'zone_get_all') db.zone_get_all(mox.IgnoreArg()).AndReturn([ FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2'), + password='pass2', name='child', weight_offset=2.0, + weight_scale=3.0), ]) self.assertEquals(len(zm.zone_states), 1) @@ -168,19 +174,20 @@ class ZoneManagerTestCase(test.TestCase): def test_poll_zone(self): self.mox.StubOutWithMock(zone_manager, '_call_novaclient') zone_manager._call_novaclient(mox.IgnoreArg()).AndReturn( - dict(name='zohan', capabilities='hairdresser')) + dict(name='child', capabilities='hairdresser')) zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2')) + password='pass2', name='child', + weight_offset=0.0, weight_scale=1.0)) zone_state.attempt = 1 self.mox.ReplayAll() zone_manager._poll_zone(zone_state) self.mox.VerifyAll() self.assertEquals(zone_state.attempt, 0) - self.assertEquals(zone_state.name, 'zohan') + self.assertEquals(zone_state.name, 'child') def test_poll_zone_fails(self): self.stubs.Set(zone_manager, "_call_novaclient", exploding_novaclient) @@ -188,7 +195,8 @@ class ZoneManagerTestCase(test.TestCase): zone_state = zone_manager.ZoneState() zone_state.update_credentials(FakeZone(id=2, api_url='http://foo.com', username='user2', - password='pass2')) + password='pass2', name='child', + weight_offset=0.0, weight_scale=1.0)) zone_state.attempt = FLAGS.zone_failures_to_offline - 1 self.mox.ReplayAll() @@ -196,7 +204,6 @@ class ZoneManagerTestCase(test.TestCase): self.mox.VerifyAll() self.assertEquals(zone_state.attempt, 3) self.assertFalse(zone_state.is_active) - self.assertEquals(zone_state.name, None) def test_host_service_caps_stale_no_stale_service(self): zm = zone_manager.ZoneManager() diff --git a/tools/pip-requires b/tools/pip-requires index a4af326dc..f47d6130c 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -11,7 +11,7 @@ eventlet kombu lockfile==0.8 lxml==2.3 -python-novaclient==2.6.0 +python-novaclient==2.6.5 python-daemon==1.5.5 python-gflags==1.3 redis==2.0.0 |
