Add CastAsCall fixture

In Ia7f40718533e450f00cd3e7d753ac65755c70588 we made the EC2 integration
tests treat all RPC cast()s as call()s. The idea being that rather than
insert sleeps in the tests to ensure that a cast()ed operation is
completed before we continue, we instead just do the operation with
call() and thereby block until it is completed.

If we take a step back, the approach is questionable - if there's no way
for us to block on the completion of an async task in our unit tests,
what hope do users have?

But, it is a sweet little hack, and is better than sleeping in tests.

With oslo.messaging, it will be both harder to implement this hack and
seemingly needed more often. Encode the hack as a fixture so it can be
easily re-used.

blueprint: oslo-messaging
Change-Id: I5f9e74f46e347594103484460e81da46835eeb7e
This commit is contained in:
Mark McLoughlin 2013-08-16 20:59:05 +01:00
parent fbdb40ff4f
commit b5c622c46e
4 changed files with 55 additions and 21 deletions

View File

@ -4,6 +4,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -31,8 +32,8 @@ from nova.compute import utils as compute_utils
from nova import context
from nova import db
from nova import exception
from nova.openstack.common import rpc
from nova import test
from nova.tests import cast_as_call
from nova.tests import fake_network
from nova.tests import fake_utils
from nova.tests.image import fake
@ -142,9 +143,7 @@ class CinderCloudTestCase(test.TestCase):
self.volume_api = volume.API()
self.volume_api.reset_fake_api(self.context)
# NOTE(comstud): Make 'cast' behave like a 'call' which will
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
self.useFixture(cast_as_call.CastAsCall(self.stubs))
# make sure we can map ami-00000001/2 to a uuid in FakeImageService
db.s3_image_create(self.context,

View File

@ -4,6 +4,7 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
# All Rights Reserved.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -46,11 +47,11 @@ from nova.image import s3
from nova.network import api as network_api
from nova.network import neutronv2
from nova.openstack.common import log as logging
from nova.openstack.common import rpc
from nova.openstack.common import timeutils
from nova import test
from nova.tests.api.openstack.compute.contrib import (
test_neutron_security_groups as test_neutron)
from nova.tests import cast_as_call
from nova.tests import fake_network
from nova.tests import fake_utils
from nova.tests.image import fake
@ -165,9 +166,7 @@ class CloudTestCase(test.TestCase):
is_admin=True)
self.volume_api = volume.API()
# NOTE(comstud): Make 'cast' behave like a 'call' which will
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
self.useFixture(cast_as_call.CastAsCall(self.stubs))
# make sure we can map ami-00000001/2 to a uuid in FakeImageService
db.s3_image_create(self.context,
@ -1800,9 +1799,8 @@ class CloudTestCase(test.TestCase):
pass
self.stubs.Set(compute_utils, 'notify_about_instance_usage', dumb)
# NOTE(comstud): Make 'cast' behave like a 'call' which will
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
self.useFixture(cast_as_call.CastAsCall(self.stubs))
result = run_instances(self.context, **kwargs)
instance = result['instancesSet'][0]
@ -1829,9 +1827,8 @@ class CloudTestCase(test.TestCase):
'status': 'active'}
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
# NOTE(comstud): Make 'cast' behave like a 'call' which will
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
self.useFixture(cast_as_call.CastAsCall(self.stubs))
def fake_format(*args, **kwargs):
pass
@ -1886,9 +1883,8 @@ class CloudTestCase(test.TestCase):
pass
self.stubs.Set(compute_utils, 'notify_about_instance_usage', dumb)
# NOTE(comstud): Make 'cast' behave like a 'call' which will
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
self.useFixture(cast_as_call.CastAsCall(self.stubs))
kwargs['client_token'] = 'client-token-1'
result = run_instances(self.context, **kwargs)

View File

@ -3,6 +3,7 @@
# Copyright 2012 Cloudscaling, Inc.
# Author: Joe Gordon <jogo@cloudscaling.com>
# All Rights Reserved.
# Copyright 2013 Red Hat, Inc.
#
# 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
@ -26,9 +27,9 @@ from nova.compute import utils as compute_utils
from nova import context
from nova import db
from nova import exception
from nova.openstack.common import rpc
from nova.openstack.common import timeutils
from nova import test
from nova.tests import cast_as_call
from nova.tests import fake_network
from nova.tests.image import fake
@ -96,9 +97,7 @@ class EC2ValidateTestCase(test.TestCase):
self.stubs.Set(fake._FakeImageService, 'show', fake_show)
self.stubs.Set(fake._FakeImageService, 'detail', fake_detail)
# NOTE(comstud): Make 'cast' behave like a 'call' which will
# ensure that operations complete
self.stubs.Set(rpc, 'cast', rpc.call)
self.useFixture(cast_as_call.CastAsCall(self.stubs))
# make sure we can map ami-00000001/2 to a uuid in FakeImageService
db.s3_image_create(self.context,

View File

@ -0,0 +1,40 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2013 Red Hat, Inc.
#
# 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.
import fixtures
from nova.openstack.common import rpc
class CastAsCall(fixtures.Fixture):
"""Make RPC 'cast' behave like a 'call'.
This is a little hack for tests that need to know when a cast
operation has completed. The idea is that we wait for the RPC
endpoint method to complete and return before continuing on the
caller.
See Ia7f40718533e450f00cd3e7d753ac65755c70588 for more background.
"""
def __init__(self, stubs):
super(CastAsCall, self).__init__()
self.stubs = stubs
def setUp(self):
super(CastAsCall, self).setUp()
self.stubs.Set(rpc, 'cast', rpc.call)