Merge "Stop using global oslo_config"
This commit is contained in:
commit
764d0e255d
|
@ -69,19 +69,20 @@ def setup_commands():
|
|||
|
||||
|
||||
def main():
|
||||
CONF = conf.CONF
|
||||
config = cfg.ConfigOpts()
|
||||
conf.register_opts(config)
|
||||
command_opts = setup_commands()
|
||||
CONF.register_cli_opts(command_opts)
|
||||
CONF(sys.argv[1:], project='placement',
|
||||
version=version_info.version_string(),
|
||||
default_config_files=None)
|
||||
db_api.configure(CONF)
|
||||
config.register_cli_opts(command_opts)
|
||||
config(sys.argv[1:], project='placement',
|
||||
version=version_info.version_string(),
|
||||
default_config_files=None)
|
||||
db_api.configure(config)
|
||||
|
||||
try:
|
||||
func = CONF.command.func
|
||||
func = config.command.func
|
||||
return_code = func()
|
||||
# If return_code ends up None we assume 0.
|
||||
sys.exit(return_code or 0)
|
||||
except cfg.NoSuchOptError:
|
||||
CONF.print_help()
|
||||
config.print_help()
|
||||
sys.exit(1)
|
||||
|
|
|
@ -14,18 +14,19 @@
|
|||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from placement.conf import api
|
||||
from placement.conf import base
|
||||
from placement.conf import database
|
||||
from placement.conf import paths
|
||||
from placement.conf import placement
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
api.register_opts(CONF)
|
||||
base.register_opts(CONF)
|
||||
database.register_opts(CONF)
|
||||
paths.register_opts(CONF)
|
||||
placement.register_opts(CONF)
|
||||
# To avoid global config, we require an existing ConfigOpts is passed
|
||||
# to register_opts. Then the caller can have some assurance that the
|
||||
# config they are using will maintain some independence.
|
||||
def register_opts(conf):
|
||||
api.register_opts(conf)
|
||||
base.register_opts(conf)
|
||||
database.register_opts(conf)
|
||||
paths.register_opts(conf)
|
||||
placement.register_opts(conf)
|
||||
|
|
|
@ -20,6 +20,10 @@ from placement import policy
|
|||
@enginefacade.transaction_context_provider
|
||||
class RequestContext(context.RequestContext):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.config = None
|
||||
super(RequestContext, self).__init__(*args, **kwargs)
|
||||
|
||||
def can(self, action, target=None, fatal=True):
|
||||
"""Verifies that the given action is valid on the target in this
|
||||
context.
|
||||
|
|
|
@ -15,15 +15,14 @@ from __future__ import with_statement
|
|||
from logging.config import fileConfig
|
||||
|
||||
from alembic import context
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
|
||||
from placement import conf
|
||||
from placement.db.sqlalchemy import models
|
||||
from placement import db_api as placement_db
|
||||
|
||||
|
||||
CONF = conf.CONF
|
||||
|
||||
|
||||
# this is the Alembic Config object, which provides
|
||||
# access to the values within the .ini file in use.
|
||||
config = context.config
|
||||
|
@ -45,26 +44,6 @@ target_metadata = models.BASE.metadata
|
|||
# ... etc.
|
||||
|
||||
|
||||
def run_migrations_offline():
|
||||
"""Run migrations in 'offline' mode.
|
||||
|
||||
This configures the context with just a URL
|
||||
and not an Engine, though an Engine is acceptable
|
||||
here as well. By skipping the Engine creation
|
||||
we don't even need a DBAPI to be available.
|
||||
|
||||
Calls to context.execute() here emit the given string to the
|
||||
script output.
|
||||
|
||||
"""
|
||||
url = CONF.placement_database.connection
|
||||
context.configure(
|
||||
url=url, target_metadata=target_metadata, literal_binds=True)
|
||||
|
||||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
def run_migrations_online():
|
||||
"""Run migrations in 'online' mode.
|
||||
|
||||
|
@ -72,12 +51,17 @@ def run_migrations_online():
|
|||
and associate a connection with the context.
|
||||
|
||||
"""
|
||||
# If CONF and the database are not already configured, set them up. This
|
||||
# can happen when using the alembic command line tool.
|
||||
if not CONF.placement_database.connection:
|
||||
CONF([], project="placement", default_config_files=None)
|
||||
placement_db.configure(CONF)
|
||||
connectable = placement_db.get_placement_engine()
|
||||
try:
|
||||
connectable = placement_db.get_placement_engine()
|
||||
except db_exc.CantStartEngineError:
|
||||
# We are being called from a context where the database hasn't been
|
||||
# configured so we need to set up Config and config the database.
|
||||
# This is usually the alembic command line.
|
||||
config = cfg.ConfigOpts()
|
||||
conf.register_opts(config)
|
||||
config([], project="placement", default_config_files=None)
|
||||
placement_db.configure(config)
|
||||
connectable = placement_db.get_placement_engine()
|
||||
|
||||
with connectable.connect() as connection:
|
||||
context.configure(
|
||||
|
@ -87,7 +71,8 @@ def run_migrations_online():
|
|||
with context.begin_transaction():
|
||||
context.run_migrations()
|
||||
|
||||
|
||||
if context.is_offline_mode():
|
||||
run_migrations_offline()
|
||||
raise Exception('offline mode disabled')
|
||||
else:
|
||||
run_migrations_online()
|
||||
|
|
|
@ -57,7 +57,7 @@ def deploy(conf):
|
|||
fault_middleware = fault_wrap.FaultWrapper
|
||||
request_log = requestlog.RequestLog
|
||||
|
||||
application = handler.PlacementHandler()
|
||||
application = handler.PlacementHandler(config=conf)
|
||||
# configure microversion middleware in the old school way
|
||||
application = microversion_middleware(
|
||||
application, microversion.SERVICE_TYPE, microversion.VERSIONS,
|
||||
|
|
|
@ -192,10 +192,13 @@ class PlacementHandler(object):
|
|||
"""
|
||||
|
||||
def __init__(self, **local_config):
|
||||
# NOTE(cdent): Local config currently unused.
|
||||
self._map = make_map(ROUTE_DECLARATIONS)
|
||||
self.config = local_config['config']
|
||||
|
||||
def __call__(self, environ, start_response):
|
||||
# set a reference to the oslo.config ConfigOpts on the RequestContext
|
||||
context = environ['placement.context']
|
||||
context.config = self.config
|
||||
# Check that an incoming request with a content-length header
|
||||
# that is an integer > 0 and not empty, also has a content-type
|
||||
# header that is not empty. If not raise a 400.
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
# under the License.
|
||||
"""DB Utility methods for placement."""
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import webob
|
||||
|
||||
|
@ -23,7 +22,6 @@ from placement.objects import project as project_obj
|
|||
from placement.objects import user as user_obj
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -54,8 +52,8 @@ def ensure_consumer(ctx, consumer_uuid, project_id, user_id,
|
|||
created_new_consumer = False
|
||||
requires_consumer_generation = want_version.matches((1, 28))
|
||||
if project_id is None:
|
||||
project_id = CONF.placement.incomplete_consumer_project_id
|
||||
user_id = CONF.placement.incomplete_consumer_user_id
|
||||
project_id = ctx.config.placement.incomplete_consumer_project_id
|
||||
user_id = ctx.config.placement.incomplete_consumer_user_id
|
||||
try:
|
||||
proj = project_obj.Project.get_by_external_id(ctx, project_id)
|
||||
except exception.NotFound:
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_versionedobjects import base
|
||||
from oslo_versionedobjects import fields
|
||||
|
@ -20,7 +19,6 @@ from placement.db.sqlalchemy import models
|
|||
from placement import db_api
|
||||
from placement import exception
|
||||
|
||||
CONF = cfg.CONF
|
||||
PROJECT_TBL = models.Project.__table__
|
||||
|
||||
|
||||
|
@ -29,7 +27,7 @@ def ensure_incomplete_project(ctx):
|
|||
"""Ensures that a project record is created for the "incomplete consumer
|
||||
project". Returns the internal ID of that record.
|
||||
"""
|
||||
incomplete_id = CONF.placement.incomplete_consumer_project_id
|
||||
incomplete_id = ctx.config.placement.incomplete_consumer_project_id
|
||||
sel = sa.select([PROJECT_TBL.c.id]).where(
|
||||
PROJECT_TBL.c.external_id == incomplete_id)
|
||||
res = ctx.session.execute(sel).fetchone()
|
||||
|
|
|
@ -23,7 +23,6 @@ import random
|
|||
|
||||
import os_traits
|
||||
from oslo_concurrency import lockutils
|
||||
from oslo_config import cfg
|
||||
from oslo_db import api as oslo_db_api
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_log import log as logging
|
||||
|
@ -63,7 +62,6 @@ _RC_CACHE = None
|
|||
_TRAIT_LOCK = 'trait_sync'
|
||||
_TRAITS_SYNCED = False
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
|
@ -4014,9 +4012,9 @@ class AllocationCandidates(base.VersionedObject):
|
|||
"""Returns an AllocationCandidates object containing all resource
|
||||
providers matching a set of supplied resource constraints, with a set
|
||||
of allocation requests constructed from that list of resource
|
||||
providers. If CONF.placement.randomize_allocation_candidates is True
|
||||
(default is False) then the order of the allocation requests will
|
||||
be randomized.
|
||||
providers. If CONF.placement.randomize_allocation_candidates (on
|
||||
contex.config) is True (default is False) then the order of the
|
||||
allocation requests will be randomized.
|
||||
|
||||
:param context: Nova RequestContext.
|
||||
:param requests: Dict, keyed by suffix, of placement.lib.RequestGroup
|
||||
|
@ -4159,16 +4157,17 @@ class AllocationCandidates(base.VersionedObject):
|
|||
alloc_request_objs, summary_objs = _merge_candidates(
|
||||
candidates, group_policy=group_policy)
|
||||
|
||||
return cls._limit_results(alloc_request_objs, summary_objs, limit)
|
||||
return cls._limit_results(context, alloc_request_objs, summary_objs,
|
||||
limit)
|
||||
|
||||
@staticmethod
|
||||
def _limit_results(alloc_request_objs, summary_objs, limit):
|
||||
def _limit_results(context, alloc_request_objs, summary_objs, limit):
|
||||
# Limit the number of allocation request objects. We do this after
|
||||
# creating all of them so that we can do a random slice without
|
||||
# needing to mess with the complex sql above or add additional
|
||||
# columns to the DB.
|
||||
if limit and limit < len(alloc_request_objs):
|
||||
if CONF.placement.randomize_allocation_candidates:
|
||||
if context.config.placement.randomize_allocation_candidates:
|
||||
alloc_request_objs = random.sample(alloc_request_objs, limit)
|
||||
else:
|
||||
alloc_request_objs = alloc_request_objs[:limit]
|
||||
|
@ -4187,7 +4186,7 @@ class AllocationCandidates(base.VersionedObject):
|
|||
continue
|
||||
kept_summary_objs.append(summary)
|
||||
summary_objs = kept_summary_objs
|
||||
elif CONF.placement.randomize_allocation_candidates:
|
||||
elif context.config.placement.randomize_allocation_candidates:
|
||||
random.shuffle(alloc_request_objs)
|
||||
|
||||
return alloc_request_objs, summary_objs
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_versionedobjects import base
|
||||
from oslo_versionedobjects import fields
|
||||
|
@ -20,7 +19,6 @@ from placement.db.sqlalchemy import models
|
|||
from placement import db_api
|
||||
from placement import exception
|
||||
|
||||
CONF = cfg.CONF
|
||||
USER_TBL = models.User.__table__
|
||||
|
||||
|
||||
|
@ -29,7 +27,7 @@ def ensure_incomplete_user(ctx):
|
|||
"""Ensures that a user record is created for the "incomplete consumer
|
||||
user". Returns the internal ID of that record.
|
||||
"""
|
||||
incomplete_id = CONF.placement.incomplete_consumer_user_id
|
||||
incomplete_id = ctx.config.placement.incomplete_consumer_user_id
|
||||
sel = sa.select([USER_TBL.c.id]).where(
|
||||
USER_TBL.c.external_id == incomplete_id)
|
||||
res = ctx.session.execute(sel).fetchone()
|
||||
|
|
|
@ -20,7 +20,6 @@ from placement import exception
|
|||
from placement import policies
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
_ENFORCER_PLACEMENT = None
|
||||
|
||||
|
@ -33,7 +32,7 @@ def reset():
|
|||
_ENFORCER_PLACEMENT = None
|
||||
|
||||
|
||||
def init():
|
||||
def init(conf):
|
||||
"""Init an Enforcer class. Sets the _ENFORCER_PLACEMENT global."""
|
||||
global _ENFORCER_PLACEMENT
|
||||
if not _ENFORCER_PLACEMENT:
|
||||
|
@ -43,7 +42,7 @@ def init():
|
|||
# which is used by nova. In other words, to have separate policy files
|
||||
# for placement and nova, we have to use separate policy_file options.
|
||||
_ENFORCER_PLACEMENT = policy.Enforcer(
|
||||
CONF, policy_file=CONF.placement.policy_file)
|
||||
conf, policy_file=conf.placement.policy_file)
|
||||
_ENFORCER_PLACEMENT.register_defaults(policies.list_rules())
|
||||
_ENFORCER_PLACEMENT.load_rules()
|
||||
|
||||
|
@ -53,7 +52,7 @@ def get_enforcer():
|
|||
# files from overrides on disk and defaults in code. We can just pass an
|
||||
# empty list and let oslo do the config lifting for us.
|
||||
cfg.CONF([], project='placement')
|
||||
init()
|
||||
init(cfg.CONF)
|
||||
return _ENFORCER_PLACEMENT
|
||||
|
||||
|
||||
|
@ -74,7 +73,7 @@ def authorize(context, action, target, do_raise=True):
|
|||
:returns: non-False value (not necessarily "True") if authorized, and the
|
||||
exact value False if not authorized and do_raise is False.
|
||||
"""
|
||||
init()
|
||||
init(context.config)
|
||||
credentials = context.to_policy_values()
|
||||
try:
|
||||
# NOTE(mriedem): The "action" kwarg is for the PolicyNotAuthorized exc.
|
||||
|
|
|
@ -14,11 +14,14 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
"""Fixtures for Nova tests."""
|
||||
"""Fixtures for Placement tests."""
|
||||
from __future__ import absolute_import
|
||||
|
||||
import tempfile
|
||||
|
||||
import fixtures
|
||||
from oslo_concurrency.fixture import lockutils as lock_fixture
|
||||
from oslo_concurrency import lockutils
|
||||
from oslo_config import cfg
|
||||
|
||||
from placement.db.sqlalchemy import migration
|
||||
|
@ -27,16 +30,10 @@ from placement import deploy
|
|||
from placement.objects import resource_provider
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
session_configured = False
|
||||
|
||||
|
||||
def reset():
|
||||
"""Call this to allow the placement db fixture to be reconfigured
|
||||
in the same process.
|
||||
"""
|
||||
global session_configured
|
||||
session_configured = False
|
||||
placement_db.placement_context_manager.dispose_pool()
|
||||
# TODO(cdent): Future handling in sqlalchemy may allow doing this
|
||||
# in a less hacky way.
|
||||
|
@ -46,26 +43,25 @@ def reset():
|
|||
|
||||
|
||||
class Database(fixtures.Fixture):
|
||||
def __init__(self, set_config=False):
|
||||
def __init__(self, conf_fixture, set_config=False):
|
||||
"""Create a database fixture."""
|
||||
super(Database, self).__init__()
|
||||
global session_configured
|
||||
if not session_configured:
|
||||
if set_config:
|
||||
try:
|
||||
CONF.register_opt(cfg.StrOpt('connection'),
|
||||
group='placement_database')
|
||||
except cfg.DuplicateOptError:
|
||||
# already registered
|
||||
pass
|
||||
CONF.set_override('connection', 'sqlite://',
|
||||
group='placement_database')
|
||||
placement_db.configure(CONF)
|
||||
session_configured = True
|
||||
if set_config:
|
||||
try:
|
||||
conf_fixture.register_opt(
|
||||
cfg.StrOpt('connection'), group='placement_database')
|
||||
except cfg.DuplicateOptError:
|
||||
# already registered
|
||||
pass
|
||||
conf_fixture.config(connection='sqlite://',
|
||||
group='placement_database')
|
||||
self.conf_fixture = conf_fixture
|
||||
self.get_engine = placement_db.get_placement_engine
|
||||
|
||||
def setUp(self):
|
||||
super(Database, self).setUp()
|
||||
reset()
|
||||
placement_db.configure(self.conf_fixture.conf)
|
||||
migration.create_schema()
|
||||
resource_provider._TRAITS_SYNCED = False
|
||||
resource_provider._RC_CACHE = None
|
||||
|
@ -76,3 +72,15 @@ class Database(fixtures.Fixture):
|
|||
reset()
|
||||
resource_provider._TRAITS_SYNCED = False
|
||||
resource_provider._RC_CACHE = None
|
||||
|
||||
|
||||
class ExternalLockFixture(lock_fixture.LockFixture):
|
||||
"""Provide a predictable inter-process file-based lock that doesn't
|
||||
require oslo.config, by setting its own lock_path.
|
||||
|
||||
This is used to prevent live database test from conflicting with
|
||||
one another in a concurrent enviornment.
|
||||
"""
|
||||
def __init__(self, name):
|
||||
lock_path = tempfile.gettempdir()
|
||||
self.mgr = lockutils.lock(name, external=True, lock_path=lock_path)
|
||||
|
|
|
@ -16,15 +16,13 @@ from oslo_log.fixture import logging_error
|
|||
from oslotest import output
|
||||
import testtools
|
||||
|
||||
from placement import conf
|
||||
from placement import context
|
||||
from placement.tests import fixtures
|
||||
from placement.tests.functional.fixtures import capture
|
||||
from placement.tests.unit import policy_fixture
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class TestCase(testtools.TestCase):
|
||||
"""A base test case for placement functional tests.
|
||||
|
||||
|
@ -36,14 +34,14 @@ class TestCase(testtools.TestCase):
|
|||
super(TestCase, self).setUp()
|
||||
|
||||
# Manage required configuration
|
||||
conf_fixture = self.useFixture(config_fixture.Config(CONF))
|
||||
conf_fixture.config(
|
||||
group='placement_database',
|
||||
connection='sqlite://',
|
||||
sqlite_synchronous=False)
|
||||
CONF([], default_config_files=[])
|
||||
self.conf_fixture = self.useFixture(
|
||||
config_fixture.Config(cfg.ConfigOpts()))
|
||||
conf.register_opts(self.conf_fixture.conf)
|
||||
self.placement_db = self.useFixture(fixtures.Database(
|
||||
self.conf_fixture, set_config=True))
|
||||
self.conf_fixture.conf([], default_config_files=[])
|
||||
|
||||
self.useFixture(policy_fixture.PolicyFixture())
|
||||
self.useFixture(policy_fixture.PolicyFixture(self.conf_fixture))
|
||||
|
||||
self.useFixture(capture.Logging())
|
||||
self.useFixture(output.CaptureOutput())
|
||||
|
@ -51,5 +49,5 @@ class TestCase(testtools.TestCase):
|
|||
self.useFixture(capture.WarningsFixture())
|
||||
self.useFixture(logging_error.get_logging_handle_error_fixture())
|
||||
|
||||
self.placement_db = self.useFixture(fixtures.Database())
|
||||
self.context = context.RequestContext()
|
||||
self.context.config = self.conf_fixture.conf
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import os_traits
|
||||
from oslo_config import cfg
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
import six
|
||||
import sqlalchemy as sa
|
||||
|
@ -22,9 +21,6 @@ from placement import rc_fields as fields
|
|||
from placement.tests.functional.db import test_base as tb
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class ProviderDBHelperTestCase(tb.PlacementDbBaseTestCase):
|
||||
|
||||
def test_get_provider_ids_matching(self):
|
||||
|
@ -705,8 +701,8 @@ class AllocationCandidatesTestCase(tb.PlacementDbBaseTestCase):
|
|||
|
||||
# Do it again, with conf set to randomize. We can't confirm the
|
||||
# random-ness but we can be sure the code path doesn't explode.
|
||||
CONF.set_override('randomize_allocation_candidates', True,
|
||||
group='placement')
|
||||
self.conf_fixture.config(randomize_allocation_candidates=True,
|
||||
group='placement')
|
||||
|
||||
# Ask for two candidates.
|
||||
limit = 2
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
@ -25,7 +24,6 @@ from placement.tests.functional import base
|
|||
from placement.tests.functional.db import test_base as tb
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
CONSUMER_TBL = consumer_obj.CONSUMER_TBL
|
||||
PROJECT_TBL = project_obj.PROJECT_TBL
|
||||
USER_TBL = user_obj.USER_TBL
|
||||
|
@ -137,7 +135,8 @@ class CreateIncompleteConsumersTestCase(base.TestCase):
|
|||
|
||||
@db_api.placement_context_manager.reader
|
||||
def _check_incomplete_consumers(self, ctx):
|
||||
incomplete_project_id = CONF.placement.incomplete_consumer_project_id
|
||||
config = ctx.config
|
||||
incomplete_project_id = config.placement.incomplete_consumer_project_id
|
||||
|
||||
# Verify we have a record in projects for the missing sentinel
|
||||
sel = PROJECT_TBL.select(
|
||||
|
@ -147,7 +146,7 @@ class CreateIncompleteConsumersTestCase(base.TestCase):
|
|||
incomplete_proj_id = rec['id']
|
||||
|
||||
# Verify we have a record in users for the missing sentinel
|
||||
incomplete_user_id = CONF.placement.incomplete_consumer_user_id
|
||||
incomplete_user_id = config.placement.incomplete_consumer_user_id
|
||||
sel = user_obj.USER_TBL.select(
|
||||
USER_TBL.c.external_id == incomplete_user_id)
|
||||
rec = ctx.session.execute(sel).first()
|
||||
|
|
|
@ -25,11 +25,10 @@ the tests.
|
|||
|
||||
import contextlib
|
||||
import functools
|
||||
import tempfile
|
||||
|
||||
from alembic import script
|
||||
import mock
|
||||
from oslo_concurrency.fixture import lockutils as concurrency
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_db import exception as db_exc
|
||||
from oslo_db.sqlalchemy import enginefacade
|
||||
|
@ -46,7 +45,6 @@ from placement import db_api
|
|||
from placement.tests import fixtures as db_fixture
|
||||
|
||||
|
||||
CONF = conf.CONF
|
||||
DB_NAME = 'openstack_citest'
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
@ -64,8 +62,7 @@ def configure(conf_fixture, db_url):
|
|||
here, not done as a base class as the mess of mixins makes that
|
||||
inscrutable. So instead we create a nice simple function.
|
||||
"""
|
||||
conf_fixture.config(lock_path=tempfile.gettempdir(),
|
||||
group='oslo_concurrency')
|
||||
conf.register_opts(conf_fixture.conf)
|
||||
conf_fixture.config(group='placement_database', connection=db_url)
|
||||
# We need to retry at least once (and quickly) otherwise the connection
|
||||
# test routines in oslo_db do not run, and the exception handling for
|
||||
|
@ -192,11 +189,11 @@ class MigrationCheckersMixin(object):
|
|||
def setUp(self):
|
||||
self.addCleanup(db_fixture.reset)
|
||||
db_url = generate_url(self.DRIVER)
|
||||
conf_fixture = self.useFixture(config_fixture.Config(CONF))
|
||||
conf_fixture = self.useFixture(config_fixture.Config(cfg.ConfigOpts()))
|
||||
configure(conf_fixture, db_url)
|
||||
self.useFixture(concurrency.LockFixture('test_mig'))
|
||||
self.useFixture(db_fixture.ExternalLockFixture('test_mig'))
|
||||
db_fixture.reset()
|
||||
db_api.configure(CONF)
|
||||
db_api.configure(conf_fixture.conf)
|
||||
try:
|
||||
self.engine = db_api.get_placement_engine()
|
||||
except (db_exc.DBNonExistentDatabase, db_exc.DBConnectionError):
|
||||
|
@ -261,11 +258,11 @@ class TestMigrationsPostgresql(MigrationCheckersMixin,
|
|||
class ModelsMigrationSyncMixin(object):
|
||||
def setUp(self):
|
||||
url = generate_url(self.DRIVER)
|
||||
conf_fixture = self.useFixture(config_fixture.Config(CONF))
|
||||
conf_fixture = self.useFixture(config_fixture.Config(cfg.ConfigOpts()))
|
||||
configure(conf_fixture, url)
|
||||
self.useFixture(concurrency.LockFixture('test_mig'))
|
||||
self.useFixture(db_fixture.ExternalLockFixture('test_mig'))
|
||||
db_fixture.reset()
|
||||
db_api.configure(CONF)
|
||||
db_api.configure(conf_fixture.conf)
|
||||
super(ModelsMigrationSyncMixin, self).setUp()
|
||||
# This is required to prevent the global opportunistic db settings
|
||||
# leaking into other tests.
|
||||
|
|
|
@ -23,6 +23,7 @@ from oslo_utils.fixture import uuidsentinel as uuids
|
|||
from oslo_utils import uuidutils
|
||||
from oslotest import output
|
||||
|
||||
from placement import conf
|
||||
from placement import context
|
||||
from placement import deploy
|
||||
from placement.objects import project as project_obj
|
||||
|
@ -36,10 +37,14 @@ from placement.tests.functional.fixtures import capture
|
|||
from placement.tests.unit import policy_fixture
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
# This global conf is not a global olso_config.cfg.CONF. It's a global
|
||||
# used locally to work around a limitation in the way that gabbi instantiates
|
||||
# the WSGI application being tested.
|
||||
CONF = None
|
||||
|
||||
|
||||
def setup_app():
|
||||
global CONF
|
||||
return deploy.loadapp(CONF)
|
||||
|
||||
|
||||
|
@ -47,6 +52,7 @@ class APIFixture(fixture.GabbiFixture):
|
|||
"""Setup the required backend fixtures for a basic placement service."""
|
||||
|
||||
def start_fixture(self):
|
||||
global CONF
|
||||
# Set up stderr and stdout captures by directly driving the
|
||||
# existing nova fixtures that do that. This captures the
|
||||
# output that happens outside individual tests (for
|
||||
|
@ -62,31 +68,35 @@ class APIFixture(fixture.GabbiFixture):
|
|||
self.warnings_fixture = capture.WarningsFixture()
|
||||
self.warnings_fixture.setUp()
|
||||
|
||||
self.conf_fixture = config_fixture.Config(CONF)
|
||||
# Do not use global CONF
|
||||
self.conf_fixture = config_fixture.Config(cfg.ConfigOpts())
|
||||
self.conf_fixture.setUp()
|
||||
self.conf_fixture.config(
|
||||
group="placement_database",
|
||||
connection='sqlite://',
|
||||
sqlite_synchronous=False)
|
||||
conf.register_opts(self.conf_fixture.conf)
|
||||
self.conf_fixture.config(group='api', auth_strategy='noauth2')
|
||||
|
||||
self.placement_db_fixture = fixtures.Database(
|
||||
self.conf_fixture, set_config=True)
|
||||
self.placement_db_fixture.setUp()
|
||||
|
||||
self.context = context.RequestContext()
|
||||
|
||||
# Register CORS opts, but do not set config. This has the
|
||||
# effect of exercising the "don't use cors" path in
|
||||
# deploy.py. Without setting some config the group will not
|
||||
# be present.
|
||||
CONF.register_opts(cors.CORS_OPTS, 'cors')
|
||||
self.conf_fixture.register_opts(cors.CORS_OPTS, 'cors')
|
||||
# Set default policy opts, otherwise the deploy module can
|
||||
# NoSuchOptError.
|
||||
policy_opts.set_defaults(CONF)
|
||||
policy_opts.set_defaults(self.conf_fixture.conf)
|
||||
|
||||
# Make sure default_config_files is an empty list, not None.
|
||||
# If None /etc/nova/nova.conf is read and confuses results.
|
||||
CONF([], default_config_files=[])
|
||||
# If None /etc/placement/placement.conf is read and confuses results.
|
||||
self.conf_fixture.conf([], default_config_files=[])
|
||||
|
||||
self.placement_db_fixture = fixtures.Database()
|
||||
self.placement_db_fixture.setUp()
|
||||
# Turn on a policy fixture.
|
||||
self.policy_fixture = policy_fixture.PolicyFixture(
|
||||
self.conf_fixture)
|
||||
self.policy_fixture.setUp()
|
||||
|
||||
os.environ['RP_UUID'] = uuidutils.generate_uuid()
|
||||
os.environ['RP_NAME'] = uuidutils.generate_uuid()
|
||||
|
@ -100,14 +110,18 @@ class APIFixture(fixture.GabbiFixture):
|
|||
os.environ['CONSUMER_UUID'] = uuidutils.generate_uuid()
|
||||
os.environ['PARENT_PROVIDER_UUID'] = uuidutils.generate_uuid()
|
||||
os.environ['ALT_PARENT_PROVIDER_UUID'] = uuidutils.generate_uuid()
|
||||
CONF = self.conf_fixture.conf
|
||||
|
||||
def stop_fixture(self):
|
||||
global CONF
|
||||
self.placement_db_fixture.cleanUp()
|
||||
self.warnings_fixture.cleanUp()
|
||||
self.output_stream_fixture.cleanUp()
|
||||
self.standard_logging_fixture.cleanUp()
|
||||
self.logging_error_fixture.cleanUp()
|
||||
self.policy_fixture.cleanUp()
|
||||
self.conf_fixture.cleanUp()
|
||||
CONF = None
|
||||
|
||||
|
||||
class AllocationFixture(APIFixture):
|
||||
|
@ -476,8 +490,6 @@ class OpenPolicyFixture(APIFixture):
|
|||
|
||||
def start_fixture(self):
|
||||
super(OpenPolicyFixture, self).start_fixture()
|
||||
self.placement_policy_fixture = policy_fixture.PolicyFixture()
|
||||
self.placement_policy_fixture.setUp()
|
||||
# Get all of the registered rules and set them to '@' to allow any
|
||||
# user to have access. The nova policy "admin_or_owner" concept does
|
||||
# not really apply to most of placement resources since they do not
|
||||
|
@ -489,8 +501,7 @@ class OpenPolicyFixture(APIFixture):
|
|||
if name in ['placement', 'admin_api']:
|
||||
continue
|
||||
rules[name] = '@'
|
||||
self.placement_policy_fixture.set_rules(rules)
|
||||
self.policy_fixture.set_rules(rules)
|
||||
|
||||
def stop_fixture(self):
|
||||
super(OpenPolicyFixture, self).stop_fixture()
|
||||
self.placement_policy_fixture.cleanUp()
|
||||
|
|
|
@ -14,14 +14,14 @@ from __future__ import absolute_import
|
|||
import fixtures
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_policy import opts as policy_opts
|
||||
from oslo_utils import uuidutils
|
||||
from wsgi_intercept import interceptor
|
||||
|
||||
from placement import conf
|
||||
from placement import deploy
|
||||
from placement.tests import fixtures as db_fixture
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
from placement.tests.unit import policy_fixture
|
||||
|
||||
|
||||
class PlacementFixture(fixtures.Fixture):
|
||||
|
@ -34,22 +34,33 @@ class PlacementFixture(fixtures.Fixture):
|
|||
all calls would be passing this token.
|
||||
|
||||
This fixture takes care of starting a fixture for an in-RAM placement
|
||||
database, unless the db kwargs is False.
|
||||
database, unless the db kwarg is False.
|
||||
|
||||
Used by other services, including nova, for functional tests.
|
||||
"""
|
||||
def __init__(self, token='admin', db=True):
|
||||
def __init__(self, token='admin', conf_fixture=None, db=True):
|
||||
self.token = token
|
||||
self.db = db
|
||||
self.conf_fixture = conf_fixture
|
||||
|
||||
def setUp(self):
|
||||
super(PlacementFixture, self).setUp()
|
||||
if self.db:
|
||||
self.useFixture(db_fixture.Database(set_config=True))
|
||||
if not self.conf_fixture:
|
||||
config = cfg.ConfigOpts()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(config))
|
||||
conf.register_opts(self.conf_fixture.conf)
|
||||
|
||||
conf_fixture = config_fixture.Config(CONF)
|
||||
conf_fixture.config(group='api', auth_strategy='noauth2')
|
||||
loader = deploy.loadapp(CONF)
|
||||
if self.db:
|
||||
self.useFixture(db_fixture.Database(self.conf_fixture,
|
||||
set_config=True))
|
||||
policy_opts.set_defaults(self.conf_fixture.conf)
|
||||
self.conf_fixture.config(group='api', auth_strategy='noauth2')
|
||||
|
||||
self.conf_fixture.conf([], default_config_files=[])
|
||||
|
||||
self.useFixture(policy_fixture.PolicyFixture(self.conf_fixture))
|
||||
|
||||
loader = deploy.loadapp(self.conf_fixture.conf)
|
||||
app = lambda: loader
|
||||
self.endpoint = 'http://%s/placement' % uuidutils.generate_uuid()
|
||||
intercept = interceptor.RequestsInterceptor(app, url=self.endpoint)
|
||||
|
|
|
@ -11,26 +11,31 @@
|
|||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_policy import opts as policy_opts
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
|
||||
from placement import conf
|
||||
from placement import direct
|
||||
from placement.tests.functional import base
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class TestDirect(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestDirect, self).setUp()
|
||||
self.conf = cfg.ConfigOpts()
|
||||
conf.register_opts(self.conf)
|
||||
policy_opts.set_defaults(self.conf)
|
||||
|
||||
def test_direct_is_there(self):
|
||||
with direct.PlacementDirect(CONF) as client:
|
||||
with direct.PlacementDirect(self.conf) as client:
|
||||
resp = client.get('/')
|
||||
self.assertTrue(resp)
|
||||
data = resp.json()
|
||||
self.assertEqual('v1.0', data['versions'][0]['id'])
|
||||
|
||||
def test_get_resource_providers(self):
|
||||
with direct.PlacementDirect(CONF) as client:
|
||||
with direct.PlacementDirect(self.conf) as client:
|
||||
resp = client.get('/resource_providers')
|
||||
self.assertTrue(resp)
|
||||
data = resp.json()
|
||||
|
@ -38,7 +43,7 @@ class TestDirect(base.TestCase):
|
|||
|
||||
def test_create_resource_provider(self):
|
||||
data = {'name': 'fake'}
|
||||
with direct.PlacementDirect(CONF) as client:
|
||||
with direct.PlacementDirect(self.conf) as client:
|
||||
resp = client.post('/resource_providers', json=data)
|
||||
self.assertTrue(resp)
|
||||
resp = client.get('/resource_providers')
|
||||
|
@ -48,13 +53,13 @@ class TestDirect(base.TestCase):
|
|||
|
||||
def test_json_validation_happens(self):
|
||||
data = {'name': 'fake', 'cowsay': 'moo'}
|
||||
with direct.PlacementDirect(CONF) as client:
|
||||
with direct.PlacementDirect(self.conf) as client:
|
||||
resp = client.post('/resource_providers', json=data)
|
||||
self.assertFalse(resp)
|
||||
self.assertEqual(400, resp.status_code)
|
||||
|
||||
def test_microversion_handling(self):
|
||||
with direct.PlacementDirect(CONF) as client:
|
||||
with direct.PlacementDirect(self.conf) as client:
|
||||
# create parent
|
||||
parent_data = {'name': uuidsentinel.p_rp,
|
||||
'uuid': uuidsentinel.p_rp}
|
||||
|
|
|
@ -10,16 +10,11 @@
|
|||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
from placement import direct
|
||||
from placement import handler
|
||||
from placement.tests.functional import base
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class TestVerifyPolicy(base.TestCase):
|
||||
"""Verify that all defined placement routes have a policy."""
|
||||
|
||||
|
@ -42,7 +37,8 @@ class TestVerifyPolicy(base.TestCase):
|
|||
(method, route, response.status_code))
|
||||
|
||||
def test_verify_policy(self):
|
||||
with direct.PlacementDirect(CONF, latest_microversion=True) as client:
|
||||
conf = self.conf_fixture.conf
|
||||
with direct.PlacementDirect(conf, latest_microversion=True) as client:
|
||||
for route, methods in handler.ROUTE_DECLARATIONS.items():
|
||||
if route in self.EXCEPTIONS:
|
||||
continue
|
||||
|
|
|
@ -19,15 +19,17 @@ import six
|
|||
import testtools
|
||||
|
||||
from placement.cmd import manage
|
||||
from placement import conf
|
||||
|
||||
|
||||
class TestCommandParsers(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestCommandParsers, self).setUp()
|
||||
self.conf = cfg.CONF
|
||||
self.conf = cfg.ConfigOpts()
|
||||
conf_fixture = config_fixture.Config(self.conf)
|
||||
self.useFixture(conf_fixture)
|
||||
conf.register_opts(conf_fixture.conf)
|
||||
# Quiet output from argparse (used within oslo_config).
|
||||
# If you are debugging, commenting this out might be useful.
|
||||
self.output = self.useFixture(
|
||||
|
|
|
@ -14,12 +14,14 @@
|
|||
|
||||
import fixtures
|
||||
import microversion_parse
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
import testtools
|
||||
import webob
|
||||
|
||||
from placement import conf
|
||||
from placement import context
|
||||
from placement import exception
|
||||
from placement.handlers import util
|
||||
from placement import microversion
|
||||
|
@ -28,12 +30,12 @@ from placement.objects import project as project_obj
|
|||
from placement.objects import user as user_obj
|
||||
|
||||
|
||||
CONF = conf.CONF
|
||||
|
||||
|
||||
class TestEnsureConsumer(testtools.TestCase):
|
||||
def setUp(self):
|
||||
super(TestEnsureConsumer, self).setUp()
|
||||
self.conf = cfg.ConfigOpts()
|
||||
self.useFixture(config_fixture.Config(self.conf))
|
||||
conf.register_opts(self.conf)
|
||||
self.mock_project_get = self.useFixture(fixtures.MockPatch(
|
||||
'placement.objects.project.'
|
||||
'Project.get_by_external_id')).mock
|
||||
|
@ -52,7 +54,8 @@ class TestEnsureConsumer(testtools.TestCase):
|
|||
self.mock_consumer_create = self.useFixture(fixtures.MockPatch(
|
||||
'placement.objects.consumer.'
|
||||
'Consumer.create')).mock
|
||||
self.ctx = mock.sentinel.ctx
|
||||
self.ctx = context.RequestContext(user_id='fake', project_id='fake')
|
||||
self.ctx.config = self.conf
|
||||
self.consumer_id = uuidsentinel.consumer
|
||||
self.project_id = uuidsentinel.project
|
||||
self.user_id = uuidsentinel.user
|
||||
|
@ -144,9 +147,9 @@ class TestEnsureConsumer(testtools.TestCase):
|
|||
consumer_gen, self.before_version)
|
||||
|
||||
self.mock_project_get.assert_called_once_with(
|
||||
self.ctx, CONF.placement.incomplete_consumer_project_id)
|
||||
self.ctx, self.conf.placement.incomplete_consumer_project_id)
|
||||
self.mock_user_get.assert_called_once_with(
|
||||
self.ctx, CONF.placement.incomplete_consumer_user_id)
|
||||
self.ctx, self.conf.placement.incomplete_consumer_user_id)
|
||||
self.mock_consumer_get.assert_called_once_with(
|
||||
self.ctx, self.consumer_id)
|
||||
self.mock_project_create.assert_called_once()
|
||||
|
|
|
@ -11,11 +11,14 @@
|
|||
# under the License.
|
||||
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_utils.fixture import uuidsentinel as uuids
|
||||
from oslo_utils import timeutils
|
||||
import six
|
||||
import testtools
|
||||
|
||||
from placement import conf
|
||||
from placement import context
|
||||
from placement import exception
|
||||
from placement.objects import resource_provider
|
||||
|
@ -103,6 +106,10 @@ class _TestCase(testtools.TestCase):
|
|||
self.user_id = 'fake-user'
|
||||
self.project_id = 'fake-project'
|
||||
self.context = context.RequestContext(self.user_id, self.project_id)
|
||||
config = cfg.ConfigOpts()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(config))
|
||||
conf.register_opts(config)
|
||||
self.context.config = config
|
||||
|
||||
|
||||
class TestResourceProviderNoDB(_TestCase):
|
||||
|
@ -356,6 +363,6 @@ class TestAllocationCandidatesNoDB(_TestCase):
|
|||
sum6 = mock.Mock(resource_provider=mock.Mock(uuid=6))
|
||||
sum_in = [sum1, sum0, sum4, sum8, sum5, sum7, sum6]
|
||||
aro, sum = resource_provider.AllocationCandidates._limit_results(
|
||||
aro_in, sum_in, 2)
|
||||
self.context, aro_in, sum_in, 2)
|
||||
self.assertEqual(aro_in[:2], aro)
|
||||
self.assertEqual(set([sum1, sum0, sum4, sum8, sum5]), set(sum))
|
||||
|
|
|
@ -14,8 +14,6 @@
|
|||
|
||||
import fixtures
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_policy import policy as oslo_policy
|
||||
|
||||
from placement.conf import paths
|
||||
|
@ -23,15 +21,19 @@ from placement import policy as placement_policy
|
|||
|
||||
|
||||
class PolicyFixture(fixtures.Fixture):
|
||||
|
||||
def __init__(self, conf_fixture):
|
||||
self.conf_fixture = conf_fixture
|
||||
super(PolicyFixture, self).__init__()
|
||||
|
||||
"""Load the default placement policy for tests."""
|
||||
def setUp(self):
|
||||
super(PolicyFixture, self).setUp()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(cfg.CONF))
|
||||
policy_file = paths.state_path_def(
|
||||
'etc/placement/placement-policy.yaml')
|
||||
self.conf_fixture.config(group='placement', policy_file=policy_file)
|
||||
placement_policy.reset()
|
||||
placement_policy.init()
|
||||
placement_policy.init(self.conf_fixture.conf)
|
||||
self.addCleanup(placement_policy.reset)
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -17,17 +17,17 @@ import testtools
|
|||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
|
||||
from placement import conf
|
||||
from placement import db_api
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class DbApiTests(testtools.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(DbApiTests, self).setUp()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(CONF))
|
||||
config = cfg.ConfigOpts()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(config))
|
||||
conf.register_opts(self.conf_fixture.conf)
|
||||
db_api.configure.reset()
|
||||
|
||||
@mock.patch.object(db_api.placement_context_manager, "configure")
|
||||
|
|
|
@ -16,8 +16,7 @@ import testtools
|
|||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
from placement import conf
|
||||
|
||||
|
||||
class TestPlacementDBConf(testtools.TestCase):
|
||||
|
@ -25,7 +24,9 @@ class TestPlacementDBConf(testtools.TestCase):
|
|||
|
||||
def setUp(self):
|
||||
super(TestPlacementDBConf, self).setUp()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(CONF))
|
||||
config = cfg.ConfigOpts()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(config))
|
||||
conf.register_opts(config)
|
||||
|
||||
def test_missing_config_raises(self):
|
||||
"""Not setting [placement_database]/connection is an error."""
|
||||
|
|
|
@ -13,31 +13,39 @@
|
|||
# under the License.
|
||||
"""Unit tests for the deply function used to build the Placement service."""
|
||||
|
||||
from keystonemiddleware import auth_token
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_policy import opts as policy_opts
|
||||
import testtools
|
||||
import webob
|
||||
|
||||
from placement import conf
|
||||
from placement import deploy
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class DeployTest(testtools.TestCase):
|
||||
|
||||
def test_auth_middleware_factory(self):
|
||||
"""Make sure that configuration settings make their way to
|
||||
the keystone middleware correctly.
|
||||
"""
|
||||
config = cfg.ConfigOpts()
|
||||
conf_fixture = self.useFixture(config_fixture.Config(config))
|
||||
conf.register_opts(conf_fixture.conf)
|
||||
# NOTE(cdent): There appears to be no simple way to get the list of
|
||||
# options used by the auth_token middleware. So we pull from an
|
||||
# existing data structure.
|
||||
auth_token_opts = auth_token.AUTH_TOKEN_OPTS[0][1]
|
||||
conf_fixture.register_opts(auth_token_opts, group='keystone_authtoken')
|
||||
www_authenticate_uri = 'http://example.com/identity'
|
||||
CONF.set_override('www_authenticate_uri', www_authenticate_uri,
|
||||
conf_fixture.config(www_authenticate_uri=www_authenticate_uri,
|
||||
group='keystone_authtoken')
|
||||
# ensure that the auth_token middleware is chosen
|
||||
CONF.set_override('auth_strategy', 'keystone', group='api')
|
||||
conf_fixture.config(auth_strategy='keystone', group='api')
|
||||
# register and default policy opts (referenced by deploy)
|
||||
policy_opts.set_defaults(CONF)
|
||||
app = deploy.deploy(CONF)
|
||||
policy_opts.set_defaults(conf_fixture.conf)
|
||||
app = deploy.deploy(conf_fixture.conf)
|
||||
req = webob.Request.blank('/resource_providers', method="GET")
|
||||
|
||||
response = req.get_response(app)
|
||||
|
|
|
@ -128,10 +128,11 @@ class PlacementLoggingTest(testtools.TestCase):
|
|||
@mock.patch("placement.handler.LOG")
|
||||
def test_404_no_error_log(self, mocked_log):
|
||||
environ = _environ(path='/hello', method='GET')
|
||||
config = mock.MagicMock()
|
||||
context_mock = mock.Mock()
|
||||
context_mock.to_policy_values.return_value = {'roles': ['admin']}
|
||||
environ['placement.context'] = context_mock
|
||||
app = handler.PlacementHandler()
|
||||
app = handler.PlacementHandler(config=config)
|
||||
self.assertRaises(webob.exc.HTTPNotFound,
|
||||
app, environ, start_response)
|
||||
mocked_log.error.assert_not_called()
|
||||
|
@ -160,7 +161,9 @@ class ContentHeadersTest(testtools.TestCase):
|
|||
def setUp(self):
|
||||
super(ContentHeadersTest, self).setUp()
|
||||
self.environ = _environ(path='/')
|
||||
self.app = handler.PlacementHandler()
|
||||
config = mock.MagicMock()
|
||||
self.environ['placement.context'] = mock.MagicMock()
|
||||
self.app = handler.PlacementHandler(config=config)
|
||||
|
||||
def test_no_content_type(self):
|
||||
self.environ['CONTENT_LENGTH'] = '10'
|
||||
|
|
|
@ -12,32 +12,33 @@
|
|||
|
||||
import os
|
||||
|
||||
import fixtures
|
||||
from oslo_config import cfg
|
||||
from oslo_config import fixture as config_fixture
|
||||
from oslo_policy import policy as oslo_policy
|
||||
import testtools
|
||||
|
||||
from placement import conf
|
||||
from placement import context
|
||||
from placement import exception
|
||||
from placement import policy
|
||||
from placement.tests.unit import policy_fixture
|
||||
from placement import util
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class PlacementPolicyTestCase(testtools.TestCase):
|
||||
"""Tests interactions with placement policy."""
|
||||
def setUp(self):
|
||||
super(PlacementPolicyTestCase, self).setUp()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(CONF))
|
||||
config = cfg.ConfigOpts()
|
||||
self.conf_fixture = self.useFixture(config_fixture.Config(config))
|
||||
conf.register_opts(config)
|
||||
self.ctxt = context.RequestContext(user_id='fake', project_id='fake')
|
||||
self.target = {'user_id': 'fake', 'project_id': 'fake'}
|
||||
# A value is required in the database connection opt for CONF to
|
||||
# A value is required in the database connection opt for conf to
|
||||
# parse.
|
||||
CONF.set_default('connection', 'stub', group='placement_database')
|
||||
CONF([], default_config_files=[])
|
||||
self.conf_fixture.config(connection='stub', group='placement_database')
|
||||
config([], default_config_files=[])
|
||||
self.ctxt.config = config
|
||||
policy.reset()
|
||||
self.addCleanup(policy.reset)
|
||||
|
||||
|
@ -46,39 +47,40 @@ class PlacementPolicyTestCase(testtools.TestCase):
|
|||
authorizations against a fake rule between updates to the physical
|
||||
policy file.
|
||||
"""
|
||||
with util.tempdir() as tmpdir:
|
||||
tmpfilename = os.path.join(tmpdir, 'placement-policy.yaml')
|
||||
tempdir = self.useFixture(fixtures.TempDir())
|
||||
tmpfilename = os.path.join(tempdir.path, 'placement-policy.yaml')
|
||||
|
||||
self.conf_fixture.config(
|
||||
group='placement', policy_file=tmpfilename)
|
||||
self.conf_fixture.config(
|
||||
group='placement', policy_file=tmpfilename)
|
||||
|
||||
action = 'placement:test'
|
||||
# Expect PolicyNotRegistered since defaults are not yet loaded.
|
||||
self.assertRaises(oslo_policy.PolicyNotRegistered,
|
||||
policy.authorize, self.ctxt, action, self.target)
|
||||
action = 'placement:test'
|
||||
# Expect PolicyNotRegistered since defaults are not yet loaded.
|
||||
self.assertRaises(oslo_policy.PolicyNotRegistered,
|
||||
policy.authorize, self.ctxt, action, self.target)
|
||||
|
||||
# Load the default action and rule (defaults to "any").
|
||||
enforcer = policy.get_enforcer()
|
||||
rule = oslo_policy.RuleDefault(action, '')
|
||||
enforcer.register_default(rule)
|
||||
# Load the default action and rule (defaults to "any").
|
||||
enforcer = policy.get_enforcer()
|
||||
rule = oslo_policy.RuleDefault(action, '')
|
||||
enforcer.register_default(rule)
|
||||
|
||||
# Now auth should work because the action is registered and anyone
|
||||
# can perform the action.
|
||||
policy.authorize(self.ctxt, action, self.target)
|
||||
# Now auth should work because the action is registered and anyone
|
||||
# can perform the action.
|
||||
policy.authorize(self.ctxt, action, self.target)
|
||||
|
||||
# Now update the policy file and reload it to disable the action
|
||||
# from all users.
|
||||
with open(tmpfilename, "w") as policyfile:
|
||||
policyfile.write('"%s": "!"' % action)
|
||||
enforcer.load_rules(force_reload=True)
|
||||
self.assertRaises(exception.PolicyNotAuthorized, policy.authorize,
|
||||
self.ctxt, action, self.target)
|
||||
# Now update the policy file and reload it to disable the action
|
||||
# from all users.
|
||||
with open(tmpfilename, "w") as policyfile:
|
||||
policyfile.write('"%s": "!"' % action)
|
||||
enforcer.load_rules(force_reload=True)
|
||||
self.assertRaises(exception.PolicyNotAuthorized, policy.authorize,
|
||||
self.ctxt, action, self.target)
|
||||
|
||||
def test_authorize_do_raise_false(self):
|
||||
"""Tests that authorize does not raise an exception when the check
|
||||
fails.
|
||||
"""
|
||||
fixture = self.useFixture(policy_fixture.PolicyFixture())
|
||||
fixture = self.useFixture(
|
||||
policy_fixture.PolicyFixture(self.conf_fixture))
|
||||
fixture.set_rules({'placement': '!'})
|
||||
self.assertFalse(
|
||||
policy.authorize(
|
||||
|
|
|
@ -18,7 +18,6 @@ import datetime
|
|||
import fixtures
|
||||
import microversion_parse
|
||||
import mock
|
||||
from oslo_config import cfg
|
||||
from oslo_middleware import request_id
|
||||
from oslo_utils.fixture import uuidsentinel
|
||||
from oslo_utils import timeutils
|
||||
|
@ -33,9 +32,6 @@ from placement.objects import resource_provider as rp_obj
|
|||
from placement import util
|
||||
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class TestCheckAccept(testtools.TestCase):
|
||||
"""Confirm behavior of util.check_accept."""
|
||||
|
||||
|
|
|
@ -11,13 +11,9 @@
|
|||
# under the License.
|
||||
"""Utility methods for placement API."""
|
||||
|
||||
import contextlib
|
||||
import functools
|
||||
import shutil
|
||||
import tempfile
|
||||
|
||||
import jsonschema
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_middleware import request_id
|
||||
from oslo_serialization import jsonutils
|
||||
|
@ -31,7 +27,6 @@ from placement.i18n import _
|
|||
# microversion
|
||||
import placement.microversion
|
||||
|
||||
CONF = cfg.CONF
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
# Error code handling constants
|
||||
|
@ -398,21 +393,6 @@ def normalize_member_of_qs_param(value):
|
|||
return value
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def tempdir(**kwargs):
|
||||
argdict = kwargs.copy()
|
||||
if 'dir' not in argdict:
|
||||
argdict['dir'] = CONF.tempdir
|
||||
tmpdir = tempfile.mkdtemp(**argdict)
|
||||
try:
|
||||
yield tmpdir
|
||||
finally:
|
||||
try:
|
||||
shutil.rmtree(tmpdir)
|
||||
except OSError as e:
|
||||
LOG.error('Could not remove tmpdir: %s', e)
|
||||
|
||||
|
||||
def run_once(message, logger, cleanup=None):
|
||||
"""This is a utility function decorator to ensure a function
|
||||
is run once and only once in an interpreter instance.
|
||||
|
|
|
@ -18,6 +18,7 @@ import logging as py_logging
|
|||
import os
|
||||
import os.path
|
||||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
from oslo_middleware import cors
|
||||
from oslo_policy import opts as policy_opts
|
||||
|
@ -67,21 +68,23 @@ def _get_config_files(env=None):
|
|||
return None
|
||||
|
||||
|
||||
def _parse_args(argv, default_config_files):
|
||||
logging.register_options(conf.CONF)
|
||||
def _parse_args(config, argv, default_config_files):
|
||||
# register placement's config options
|
||||
conf.register_opts(config)
|
||||
logging.register_options(config)
|
||||
|
||||
if profiler:
|
||||
profiler.set_defaults(conf.CONF)
|
||||
profiler.set_defaults(config)
|
||||
|
||||
_set_middleware_defaults()
|
||||
|
||||
# This is needed so we can check [oslo_policy]/enforce_scope in the
|
||||
# deploy module.
|
||||
policy_opts.set_defaults(conf.CONF)
|
||||
policy_opts.set_defaults(config)
|
||||
|
||||
conf.CONF(argv[1:], project='placement',
|
||||
version=version_info.version_string(),
|
||||
default_config_files=default_config_files)
|
||||
config(argv[1:], project='placement',
|
||||
version=version_info.version_string(),
|
||||
default_config_files=default_config_files)
|
||||
|
||||
|
||||
def _set_middleware_defaults():
|
||||
|
@ -110,26 +113,25 @@ def init_application():
|
|||
# initialize the config system
|
||||
conffiles = _get_config_files()
|
||||
|
||||
# NOTE(lyarwood): Call reset to ensure the ConfigOpts object doesn't
|
||||
# already contain registered options if the app is reloaded.
|
||||
conf.CONF.reset()
|
||||
config = cfg.ConfigOpts()
|
||||
conf.register_opts(config)
|
||||
|
||||
# This will raise cfg.RequiredOptError when a required option is not set
|
||||
# (notably the database connection string). We want this to be a hard fail
|
||||
# that prevents the application from starting. The error will show up in
|
||||
# the wsgi server's logs.
|
||||
_parse_args([], default_config_files=conffiles)
|
||||
_parse_args(config, [], default_config_files=conffiles)
|
||||
# initialize the logging system
|
||||
setup_logging(conf.CONF)
|
||||
setup_logging(config)
|
||||
|
||||
# configure database
|
||||
db_api.configure(conf.CONF)
|
||||
db_api.configure(config)
|
||||
|
||||
# dump conf at debug if log_options
|
||||
if conf.CONF.log_options:
|
||||
conf.CONF.log_opt_values(
|
||||
if config.log_options:
|
||||
config.log_opt_values(
|
||||
logging.getLogger(__name__),
|
||||
logging.DEBUG)
|
||||
|
||||
# build and return our WSGI app
|
||||
return deploy.loadapp(conf.CONF)
|
||||
return deploy.loadapp(config)
|
||||
|
|
Loading…
Reference in New Issue