From d218f0df65729e2818a63a22f9eb476d376e168e Mon Sep 17 00:00:00 2001 From: melanie witt Date: Mon, 26 Sep 2016 20:08:33 +0000 Subject: [PATCH] Stop overwriting thread local context in ClientRouter In commit 4df0869, a ClientRouter was added to cache client connections to cell message queues. The periodic task for removing stale clients is called with an empty RequestContext, but this overwrites the copy in thread local storage unless overwrite=False is specified. This adds overwrite=False to the empty RequestContext to prevent it from overwriting the thread local context. All of the other periodic tasks use get_admin_context() which also creates a RequestContext with overwrite=False. Closes-Bug: #1627838 Change-Id: I48024952865fe017e0cb786567b5b445b05e7659 --- nova/rpc.py | 3 +- .../regressions/test_bug_1627838.py | 32 +++++++++++++++++++ 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 nova/tests/functional/regressions/test_bug_1627838.py diff --git a/nova/rpc.py b/nova/rpc.py index 1320e50cde30..72be15772b20 100644 --- a/nova/rpc.py +++ b/nova/rpc.py @@ -380,7 +380,8 @@ class ClientRouter(periodic_task.PeriodicTasks): # NOTE(melwitt): Cells v1 does its own serialization and won't # have a serializer available on the client object. self.serializer = getattr(default_client, 'serializer', None) - self.run_periodic_tasks(nova.context.RequestContext()) + # Prevent this empty context from overwriting the thread local copy + self.run_periodic_tasks(nova.context.RequestContext(overwrite=False)) def _client(self, context, cell_mapping=None): if cell_mapping: diff --git a/nova/tests/functional/regressions/test_bug_1627838.py b/nova/tests/functional/regressions/test_bug_1627838.py new file mode 100644 index 000000000000..af9be8c26d13 --- /dev/null +++ b/nova/tests/functional/regressions/test_bug_1627838.py @@ -0,0 +1,32 @@ +# 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 oslo_context import context as common_context +from oslo_context import fixture as context_fixture + +from nova import context +from nova import test + + +class TestThreadLocalContext(test.TestCase): + def setUp(self): + super(TestThreadLocalContext, self).setUp() + self.useFixture(context_fixture.ClearRequestContext()) + # This will set the thread local copy of the context + self.context = context.RequestContext('user', 'project') + # Start the compute service to initialize compute RPC + self.start_service('compute') + + def test_context_not_overwritten_by_periodic_tasks(self): + # None of the periodic tasks should have overwritten the + # thread local copy of the context + self.assertEqual(self.context, common_context.get_current())