From f21e7e33298a359f54e4eb5c7089a6a4f13537ee Mon Sep 17 00:00:00 2001 From: Chris Dent Date: Thu, 22 Sep 2016 14:40:45 +0000 Subject: [PATCH] [placement] Allow both /placement and /placement/ to work When mounted under a prefix (such as /placement) the service was only returning the home document at /placement/ not /placement. In the context of having a prefix, we'd generally like the latter to work and for '/' to work when there is no prefix. This allows both. Note that this doesn't make /placement/resource_providers/ work, and we don't want that. Change-Id: I0ac92bf9982227d5f4915175182e5230aeb039b4 Closes-Bug: #1626490 --- nova/api/openstack/placement/handler.py | 8 ++++++++ .../api/openstack/placement/test_handler.py | 18 ++++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/nova/api/openstack/placement/handler.py b/nova/api/openstack/placement/handler.py index 5d5377f4c835..f769c58fa1d3 100644 --- a/nova/api/openstack/placement/handler.py +++ b/nova/api/openstack/placement/handler.py @@ -48,6 +48,14 @@ ROUTE_DECLARATIONS = { '/': { 'GET': root.home, }, + # NOTE(cdent): This allows '/placement/' and '/placement' to + # both work as the root of the service, which we probably want + # for those situations where the service is mounted under a + # prefix (as it is in devstack). While weird, an empty string is + # a legit key in a dictionary and matches as desired in Routes. + '': { + 'GET': root.home, + }, '/resource_providers': { 'GET': resource_provider.list_resource_providers, 'POST': resource_provider.create_resource_provider diff --git a/nova/tests/unit/api/openstack/placement/test_handler.py b/nova/tests/unit/api/openstack/placement/test_handler.py index b0a81e15efcd..e59e80fed726 100644 --- a/nova/tests/unit/api/openstack/placement/test_handler.py +++ b/nova/tests/unit/api/openstack/placement/test_handler.py @@ -18,6 +18,7 @@ import routes import webob from nova.api.openstack.placement import handler +from nova.api.openstack.placement.handlers import root from nova import test from nova.tests import uuidsentinel @@ -112,3 +113,20 @@ class PlacementLoggingTest(test.NoDBTestCase): app, environ, start_response) mocked_log.error.assert_not_called() mocked_log.exception.assert_not_called() + + +class DeclarationsTest(test.NoDBTestCase): + + def setUp(self): + super(DeclarationsTest, self).setUp() + self.mapper = handler.make_map(handler.ROUTE_DECLARATIONS) + + def test_root_slash_match(self): + environ = _environ(path='/') + result = self.mapper.match(environ=environ) + self.assertEqual(root.home, result['action']) + + def test_root_empty_match(self): + environ = _environ(path='') + result = self.mapper.match(environ=environ) + self.assertEqual(root.home, result['action'])