Merge "Ensure to store context in thread local after spawn/spawn_n"

This commit is contained in:
Jenkins 2015-06-15 19:49:59 +00:00 committed by Gerrit Code Review
commit 4ad4c07d6f
5 changed files with 44 additions and 13 deletions

View File

@ -1047,6 +1047,7 @@ class SpawnNTestCase(test.NoDBTestCase):
def setUp(self):
super(SpawnNTestCase, self).setUp()
self.useFixture(context_fixture.ClearRequestContext())
self.spawn_name = 'spawn_n'
def test_spawn_n_no_context(self):
self.assertIsNone(common_context.get_current())
@ -1059,8 +1060,8 @@ class SpawnNTestCase(test.NoDBTestCase):
def fake(arg):
pass
with mock.patch.object(eventlet, 'spawn_n', _fake_spawn):
utils.spawn_n(fake, 'test')
with mock.patch.object(eventlet, self.spawn_name, _fake_spawn):
getattr(utils, self.spawn_name)(fake, 'test')
self.assertIsNone(common_context.get_current())
def test_spawn_n_context(self):
@ -1076,8 +1077,8 @@ class SpawnNTestCase(test.NoDBTestCase):
def fake(context, kwarg1=None):
pass
with mock.patch.object(eventlet, 'spawn_n', _fake_spawn):
utils.spawn_n(fake, ctxt, kwarg1='test')
with mock.patch.object(eventlet, self.spawn_name, _fake_spawn):
getattr(utils, self.spawn_name)(fake, ctxt, kwarg1='test')
self.assertEqual(ctxt, common_context.get_current())
def test_spawn_n_context_different_from_passed(self):
@ -1096,6 +1097,12 @@ class SpawnNTestCase(test.NoDBTestCase):
def fake(context, kwarg1=None):
pass
with mock.patch.object(eventlet, 'spawn_n', _fake_spawn):
utils.spawn_n(fake, ctxt_passed, kwarg1='test')
with mock.patch.object(eventlet, self.spawn_name, _fake_spawn):
getattr(utils, self.spawn_name)(fake, ctxt_passed, kwarg1='test')
self.assertEqual(ctxt, common_context.get_current())
class SpawnTestCase(SpawnNTestCase):
def setUp(self):
super(SpawnTestCase, self).setUp()
self.spawn_name = 'spawn'

View File

@ -6283,7 +6283,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
self._test_live_migration_monitoring(domain_info_records, False)
@mock.patch.object(greenthread, "spawn")
@mock.patch.object(utils, "spawn")
@mock.patch.object(libvirt_driver.LibvirtDriver, "_live_migration_monitor")
@mock.patch.object(host.Host, "get_domain")
@mock.patch.object(fakelibvirt.Connection, "_mark_running")
@ -11013,7 +11013,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
dstfile, "qcow2")
mock_define.assert_called_once_with(xmldoc)
@mock.patch.object(greenthread, "spawn")
@mock.patch.object(utils, "spawn")
def test_live_migration_hostname_valid(self, mock_spawn):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)
drvr.live_migration(self.context, self.test_instance,
@ -11022,7 +11022,7 @@ class LibvirtConnTestCase(test.NoDBTestCase):
lambda x: x)
self.assertEqual(1, mock_spawn.call_count)
@mock.patch.object(greenthread, "spawn")
@mock.patch.object(utils, "spawn")
@mock.patch.object(fake_libvirt_utils, "is_valid_hostname")
def test_live_migration_hostname_invalid(self, mock_hostname, mock_spawn):
drvr = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), False)

View File

@ -975,6 +975,29 @@ def validate_integer(value, name, min_value=None, max_value=None):
return value
def spawn(func, *args, **kwargs):
"""Passthrough method for eventlet.spawn.
This utility exists so that it can be stubbed for testing without
interfering with the service spawns.
It will also grab the context from the threadlocal store and add it to
the store on the new thread. This allows for continuity in logging the
context when using this method to spawn a new thread.
"""
_context = common_context.get_current()
@functools.wraps(func)
def context_wrapper(*args, **kwargs):
# NOTE: If update_store is not called after spawn it won't be
# available for the logger to pull from threadlocal storage.
if _context is not None:
_context.update_store()
return func(*args, **kwargs)
return eventlet.spawn(context_wrapper, *args, **kwargs)
def spawn_n(func, *args, **kwargs):
"""Passthrough method for eventlet.spawn_n.

View File

@ -5331,7 +5331,7 @@ class LibvirtDriver(driver.ComputeDriver):
if not libvirt_utils.is_valid_hostname(dest):
raise exception.InvalidHostname(hostname=dest)
greenthread.spawn(self._live_migration, context, instance, dest,
utils.spawn(self._live_migration, context, instance, dest,
post_method, recover_method, block_migration,
migrate_data)
@ -5729,7 +5729,7 @@ class LibvirtDriver(driver.ComputeDriver):
# We should be able to remove dom at the end.
dom = guest._domain
opthread = greenthread.spawn(self._live_migration_operation,
opthread = utils.spawn(self._live_migration_operation,
context, instance, dest,
block_migration,
migrate_data, dom)

View File

@ -27,6 +27,7 @@ from oslo_log import log as logging
from nova import exception
from nova.i18n import _, _LE
from nova import image
from nova import utils
LOG = logging.getLogger(__name__)
IMAGE_API = image.API()
@ -138,7 +139,7 @@ class GlanceWriteThread(object):
self.stop()
self.done.send_exception(exc)
greenthread.spawn(_inner)
utils.spawn(_inner)
return self.done
def stop(self):
@ -183,7 +184,7 @@ class IOThread(object):
LOG.exception(_LE('Read/Write data failed'))
self.done.send_exception(exc)
greenthread.spawn(_inner)
utils.spawn(_inner)
return self.done
def stop(self):