Split engine service into three services

This patch splits the engine into 3 services, conductor, engine and
health-manager.

The goal here is to make the engine more resilent by isolating the
pieces.

Before this patch each Engine worker could potentially be running many
thousands of threads and multiple thread groups, starving the process.
After this change each process would be limited to a single thread
group of 1000 threads, and more predictable and balanced workloads.

* Added two new services.
* Added workers opt to conductor and health manager.
* Merged Thread Group Manager into Engine Service code.

Change-Id: Id4a27ba934dc9777f7ae5b4d7d0a751318ea7877
This commit is contained in:
Erik Olof Gunnar Andersson 2019-10-15 11:47:59 -07:00
parent b0efef780b
commit 54997a14ea
52 changed files with 4484 additions and 4128 deletions

View File

@ -106,6 +106,7 @@ function configure_senlin {
iniset $SENLIN_CONF DEFAULT auth_encryption_key $(generate_hex_string 16)
iniset $SENLIN_CONF DEFAULT default_region_name "$REGION_NAME"
if [ "$USE_SYSTEMD" != "False" ]; then
setup_systemd_logging $SENLIN_CONF
fi
@ -256,6 +257,8 @@ function install_senlin {
# start_senlin() - Start running processes, including screen
function start_senlin {
run_process sl-eng "$SENLIN_BIN_DIR/senlin-engine --config-file=$SENLIN_CONF"
run_process sl-conductor "$SENLIN_BIN_DIR/senlin-conductor --config-file=$SENLIN_CONF"
run_process sl-health-manager "$SENLIN_BIN_DIR/senlin-health-manager --config-file=$SENLIN_CONF"
if [[ "$SENLIN_WSGI_MODE" == "uwsgi" ]]; then
run_process sl-api "$SENLIN_BIN_DIR/uwsgi --procname-prefix senlin-api --ini $SENLIN_UWSGI_CONF"
@ -275,6 +278,8 @@ function start_senlin {
function stop_senlin {
# Kill the screen windows
stop_process sl-eng
stop_process sl-conductor
stop_process sl-health-manager
if [[ "$SENLIN_WSGI_MODE" == "uwsgi" ]]; then
stop_process sl-api

View File

@ -3,4 +3,4 @@
# We have to add Senlin to enabled services for screen_it to work
# It consists of 2 parts: sl-api (API), sl-eng (Engine).
enable_service sl-api sl-eng
enable_service sl-api sl-eng sl-conductor sl-health-manager

View File

@ -234,7 +234,10 @@ Finalize installation
::
# systemctl enable openstack-senlin-api.service \
openstack-senlin-engine.service
openstack-senlin-conductor.service \
openstack-senlin-engine.service \
openstack-senlin-health-manager.service
# systemctl start openstack-senlin-api.service \
openstack-senlin-engine.service
openstack-senlin-conductor.service \
openstack-senlin-engine.service \
openstack-senlin-health-manager.service

View File

@ -115,13 +115,15 @@ update this script with the <DB PASSWORD> entered in step4.
$ cd /opt/stack/senlin/tools
$ ./senlin-db-recreate
6. Start senlin engine and api service.
6. Start the senlin api, conductor, engine and health-manager services.
You may need two consoles for the services i.e., one for each service.
You may need multiple consoles for the services i.e., one for each service.
::
$ senlin-conductor --config-file /etc/senlin/senlin.conf
$ senlin-engine --config-file /etc/senlin/senlin.conf
$ senlin-health-manager --config-file /etc/senlin/senlin.conf
$ senlin-api --config-file /etc/senlin/senlin.conf
Install Senlin Client

View File

@ -9,7 +9,9 @@ Senlin services
.. toctree::
:maxdepth: 1
senlin-conductor
senlin-engine
senlin-health-manager
senlin-api

View File

@ -0,0 +1,47 @@
================
senlin-conductor
================
.. program:: senlin-conductor
SYNOPSIS
~~~~~~~~
``senlin-conductor [options]``
DESCRIPTION
~~~~~~~~~~~
senlin-conductor provides an internal RPC interface for the senlin-api to
invoke.
INVENTORY
~~~~~~~~~
The senlin-conductor provides an internal RPC interface.
OPTIONS
~~~~~~~
.. cmdoption:: --config-file
Path to a config file to use. Multiple config files can be specified, with
values in later files taking precedence.
.. cmdoption:: --config-dir
Path to a config directory to pull .conf files from. This file set is
sorted, so as to provide a predictable parse order if individual options are
over-ridden. The set is parsed after the file(s), if any, specified via
--config-file, hence over-ridden options in the directory take precedence.
FILES
~~~~~
* /etc/senlin/senlin.conf
BUGS
~~~~
* Senlin issues are tracked in Launchpad so you can view or report bugs here
`OpenStack Senlin Bugs <https://bugs.launchpad.net/senlin>`__

View File

@ -13,16 +13,13 @@ DESCRIPTION
~~~~~~~~~~~
senlin-engine is the server that perform operations on objects such as
clusters, nodes, policies and profiles. It provides an internal RPC
interface for the senlin-api to invoke.
nodes, policies and profiles.
INVENTORY
~~~~~~~~~
The senlin-engine provides services to the callers so that requests on
various objects can be met by background operations. Senlin models most
operations as asynchronous actions, so most operations are not to be assumed
as completed when the calls return.
various objects can be met by background operations.
OPTIONS
~~~~~~~
@ -36,7 +33,7 @@ OPTIONS
Path to a config directory to pull .conf files from. This file set is
sorted, so as to provide a predictable parse order if individual options are
over-ridden. The set is parsed after the file(s), if any, specified via
over-ridden. The set is parsed after the file(s), if any, specified via
--config-file, hence over-ridden options in the directory take precedence.
FILES

View File

@ -0,0 +1,48 @@
=====================
senlin-health-manager
=====================
.. program:: senlin-health-manager
SYNOPSIS
~~~~~~~~
``senlin-health-manager [options]``
DESCRIPTION
~~~~~~~~~~~
senlin-health-manager is the server that is responsible for cluster health
related operations.
INVENTORY
~~~~~~~~~
The senlin-health-manager provides services to the callers so that various
cluster health related operations can be performed in the background.
OPTIONS
~~~~~~~
.. cmdoption:: --config-file
Path to a config file to use. Multiple config files can be specified, with
values in later files taking precedence.
.. cmdoption:: --config-dir
Path to a config directory to pull .conf files from. This file set is
sorted, so as to provide a predictable parse order if individual options are
over-ridden. The set is parsed after the file(s), if any, specified via
--config-file, hence over-ridden options in the directory take precedence.
FILES
~~~~~
* /etc/senlin/senlin.conf
BUGS
~~~~
* Senlin issues are tracked in Launchpad so you can view or report bugs here
`OpenStack Senlin Bugs <https://bugs.launchpad.net/senlin>`__

View File

@ -0,0 +1,30 @@
---
prelude: >
The Senlin-Engine was responsible for a large number of threaded
tasks. To help lower the number of potential threads per process and to
make the Engine more resilient, starting with OpenStack Ussuri, the Engine
service has been split into three services, ``senlin-conductor``,
``senlin-engine`` and ``senlin-health-manager``.
upgrade:
- |
Two new services has been introduced that will need to be started
after the upgrade, ``senlin-conductor`` and ``senlin-health-manager``.
With the introduction of these new services two new configuration options
were added to allow operators to change the number of proceses to spawn.
.. code-block:: ini
[conductor]
workers = 1
..
.. code-block:: ini
[health_manager]
workers = 1
..
The ``senlin-engine`` service still uses ``num_engine_workers`` to control
the number of processes to spawn.

48
senlin/cmd/conductor.py Normal file
View File

@ -0,0 +1,48 @@
#!/usr/bin/env python
#
# 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.
"""
Senlin Conductor.
"""
from oslo_config import cfg
from oslo_log import log as logging
from oslo_reports import guru_meditation_report as gmr
from oslo_service import service
from senlin.common import consts
from senlin.common import messaging
from senlin.common import profiler
from senlin import objects
from senlin import version
def main():
logging.register_options(cfg.CONF)
cfg.CONF(project='senlin', prog='senlin-conductor')
logging.setup(cfg.CONF, 'senlin-conductor')
logging.set_defaults()
gmr.TextGuruMeditation.setup_autorun(version)
objects.register_all()
messaging.setup()
from senlin.conductor import service as conductor
profiler.setup('senlin-conductor', cfg.CONF.host)
srv = conductor.ConductorService(cfg.CONF.host, consts.ENGINE_TOPIC)
launcher = service.launch(cfg.CONF, srv,
workers=cfg.CONF.conductor.workers,
restart_method='mutate')
# the following periodic tasks are intended serve as HA checking
# srv.create_periodic_tasks()
launcher.wait()

View File

@ -13,7 +13,7 @@
# under the License.
"""
Senlin Engine Server.
Senlin Engine.
"""
from oslo_config import cfg
from oslo_log import log as logging
@ -39,10 +39,9 @@ def main():
from senlin.engine import service as engine
profiler.setup('senlin-engine', cfg.CONF.host)
srv = engine.EngineService(cfg.CONF.host, consts.ENGINE_TOPIC)
srv = engine.EngineService(cfg.CONF.host,
consts.DISPATCHER_TOPIC)
launcher = service.launch(cfg.CONF, srv,
workers=cfg.CONF.num_engine_workers,
restart_method='mutate')
# the following periodic tasks are intended serve as HA checking
# srv.create_periodic_tasks()
launcher.wait()

View File

@ -0,0 +1,47 @@
#!/usr/bin/env python
#
# 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.
"""
Senlin Health-Manager.
"""
from oslo_config import cfg
from oslo_log import log as logging
from oslo_reports import guru_meditation_report as gmr
from oslo_service import service
from senlin.common import consts
from senlin.common import messaging
from senlin.common import profiler
from senlin import objects
from senlin import version
def main():
logging.register_options(cfg.CONF)
cfg.CONF(project='senlin', prog='senlin-health-manager')
logging.setup(cfg.CONF, 'senlin-health-manager')
logging.set_defaults()
gmr.TextGuruMeditation.setup_autorun(version)
objects.register_all()
messaging.setup()
from senlin.health_manager import service as health_manager
profiler.setup('senlin-health-manager', cfg.CONF.host)
srv = health_manager.HealthManagerService(cfg.CONF.host,
consts.HEALTH_MANAGER_TOPIC)
launcher = service.launch(cfg.CONF, srv,
workers=cfg.CONF.health_manager.workers,
restart_method='mutate')
launcher.wait()

View File

@ -112,7 +112,8 @@ engine_opts = [
'considered up.')),
cfg.IntOpt('scheduler_thread_pool_size',
default=1000,
help=_('Maximum number of threads to use for scheduler.')),
help=_('Maximum number of threads to use for the '
'conductor and engine.')),
cfg.IntOpt('health_manager_thread_pool_size',
default=1000,
help=_('Maximum number of threads to use for health manager.')),
@ -153,7 +154,8 @@ dispatcher_opts = [
choices=("critical", "error", "warning", "info", "debug"),
help=_("Lowest event priorities to be dispatched.")),
cfg.BoolOpt("exclude_derived_actions", default=True,
help=_("Exclude derived actions from events dumping."))]
help=_("Exclude derived actions from events dumping.")),
]
cfg.CONF.register_group(dispatcher_group)
cfg.CONF.register_opts(dispatcher_opts, group=dispatcher_group)
@ -177,6 +179,16 @@ authentication_opts = [
cfg.CONF.register_group(authentication_group)
cfg.CONF.register_opts(authentication_opts, group=authentication_group)
# Conductor group
conductor_group = cfg.OptGroup('conductor')
conductor_opts = [
cfg.IntOpt('workers',
default=1,
help=_('Number of senlin-conductor processes.')),
]
cfg.CONF.register_group(conductor_group)
cfg.CONF.register_opts(conductor_opts, group=conductor_group)
# Health Manager Group
healthmgr_group = cfg.OptGroup('health_manager')
healthmgr_opts = [
@ -186,6 +198,9 @@ healthmgr_opts = [
help=_("Exchange name for heat notifications.")),
cfg.MultiStrOpt("enabled_endpoints", default=['nova', 'heat'],
help=_("Notification endpoints to enable.")),
cfg.IntOpt('workers',
default=1,
help=_('Number of senlin-health-manager processes.')),
]
cfg.CONF.register_group(healthmgr_group)
cfg.CONF.register_opts(healthmgr_opts, group=healthmgr_group)
@ -283,6 +298,7 @@ def list_opts():
yield 'DEFAULT', service_opts
yield 'DEFAULT', event_opts
yield authentication_group.name, authentication_opts
yield conductor_group.name, conductor_opts
yield dispatcher_group.name, dispatcher_opts
yield healthmgr_group.name, healthmgr_opts
yield revision_group.name, revision_opts

42
senlin/common/service.py Normal file
View File

@ -0,0 +1,42 @@
# All Rights Reserved.
#
# 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_log import log as logging
from oslo_service import service
from senlin import version
LOG = logging.getLogger(__name__)
class Service(service.Service):
def __init__(self, name, host, topic, threads=None):
threads = threads or 1000
super(Service, self).__init__(threads)
self.name = name
self.host = host
self.topic = topic
def start(self):
LOG.info('Starting %(name)s service (version: %(version)s)',
{
'name': self.name,
'version': version.version_info.version_string()
})
super(Service, self).start()
def stop(self, graceful=True):
LOG.info('Stopping %(name)s service', {'name': self.name})
super(Service, self).stop(graceful)

2660
senlin/conductor/service.py Executable file

File diff suppressed because it is too large Load Diff

View File

@ -26,7 +26,6 @@ from senlin.engine import cluster as cluster_mod
from senlin.engine import dispatcher
from senlin.engine import node as node_mod
from senlin.engine.notifications import message as msg
from senlin.engine import scheduler
from senlin.engine import senlin_lock
from senlin.objects import action as ao
from senlin.objects import cluster as co
@ -110,7 +109,8 @@ class ClusterAction(base.Action):
return self.RES_LIFECYCLE_HOOK_TIMEOUT, reason
# Continue waiting (with reschedule)
scheduler.reschedule(self.id, 3)
LOG.debug('Action %s sleep for 3 seconds ', self.id)
self._sleep(3)
status = self.get_status()
dispatcher.start_action()

View File

@ -14,7 +14,6 @@ from oslo_config import cfg
from oslo_context import context as oslo_context
from oslo_log import log as logging
import oslo_messaging
from oslo_service import service
from senlin.common import consts
from senlin.common import messaging
@ -28,61 +27,6 @@ OPERATIONS = (
)
class Dispatcher(service.Service):
"""RPC server for dispatching actions.
Receive notification from engine services and schedule actions.
"""
def __init__(self, engine_service, topic, version, thread_group_mgr):
super(Dispatcher, self).__init__()
self.TG = thread_group_mgr
self.engine_id = engine_service.engine_id
self.topic = topic
self.version = version
def start(self):
"""Start the dispatcher.
Note that dispatcher is an engine-internal server, we are not using
versioned object for parameter passing.
"""
super(Dispatcher, self).start()
self.target = oslo_messaging.Target(server=self.engine_id,
topic=self.topic,
version=self.version)
server = messaging.get_rpc_server(self.target, self)
server.start()
def listening(self, ctxt):
"""Respond affirmatively to confirm that engine is still alive."""
return True
def start_action(self, ctxt, action_id=None):
self.TG.start_action(self.engine_id, action_id)
def cancel_action(self, ctxt, action_id):
"""Cancel an action."""
self.TG.cancel_action(action_id)
def suspend_action(self, ctxt, action_id):
"""Suspend an action."""
self.TG.suspend_action(action_id)
def resume_action(self, ctxt, action_id):
"""Resume an action."""
self.TG.resume_action(action_id)
def stop(self):
super(Dispatcher, self).stop()
# Wait for all action threads to be finished
LOG.info("Stopping all action threads of engine %s",
self.engine_id)
# Stop ThreadGroup gracefully
self.TG.stop(True)
LOG.info("All action threads have been finished")
def notify(method, engine_id=None, **kwargs):
"""Send notification to dispatcher.

View File

@ -16,15 +16,12 @@ Health Manager is responsible for monitoring the health of the clusters and
trigger corresponding actions to recover the clusters based on the pre-defined
health policies.
"""
from collections import defaultdict
from collections import namedtuple
import eventlet
from oslo_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_service import service
from oslo_service import threadgroup
from oslo_utils import timeutils
import re
import tenacity
@ -40,7 +37,7 @@ from senlin.rpc import client as rpc_client
LOG = logging.getLogger(__name__)
def _chase_up(start_time, interval, name='Poller'):
def chase_up(start_time, interval, name='Poller'):
"""Utility function to check if there are missed intervals.
:param start_time: A time object representing the starting time.
@ -463,13 +460,13 @@ class HealthCheck(object):
if not self.health_check_types:
LOG.error("No health check types found for cluster: %s",
self.cluster_id)
return _chase_up(start_time, self.interval)
return chase_up(start_time, self.interval)
cluster = objects.Cluster.get(self.ctx, self.cluster_id,
project_safe=False)
if not cluster:
LOG.warning("Cluster (%s) is not found.", self.cluster_id)
return _chase_up(start_time, self.interval)
return chase_up(start_time, self.interval)
ctx = context.get_service_context(user_id=cluster.user,
project_id=cluster.project)
@ -500,7 +497,7 @@ class HealthCheck(object):
LOG.warning("Error while performing health check: %s", ex)
finally:
return _chase_up(start_time, self.interval)
return chase_up(start_time, self.interval)
def _check_node_health(self, ctx, node, cluster):
node_is_healthy = True
@ -613,12 +610,11 @@ class HealthCheck(object):
class RuntimeHealthRegistry(object):
def __init__(self, ctx, engine_id, thread_group):
self.ctx = ctx
self.engine_id = engine_id
self.rt = {}
self.TG = thread_group
self.tg = thread_group
self.health_check_types = defaultdict(lambda: [])
@property
@ -736,7 +732,7 @@ class RuntimeHealthRegistry(object):
if entry.timer:
LOG.error("Health check for cluster %s already exists", cluster_id)
return None
timer = self.TG.add_dynamic_timer(entry.execute_health_check, None,
timer = self.tg.add_dynamic_timer(entry.execute_health_check, None,
None)
if timer:
entry.timer = timer
@ -764,7 +760,7 @@ class RuntimeHealthRegistry(object):
return
project = cluster.project
listener = self.TG.add_thread(ListenerProc, exchange, project,
listener = self.tg.add_thread(ListenerProc, exchange, project,
cluster_id, entry.recover_action)
if listener:
entry.listener = listener
@ -817,7 +813,7 @@ class RuntimeHealthRegistry(object):
try:
# tell threadgroup to remove timer
self.TG.timer_done(entry.timer)
self.tg.timer_done(entry.timer)
except ValueError:
pass
finally:
@ -825,7 +821,7 @@ class RuntimeHealthRegistry(object):
if entry.listener:
try:
self.TG.thread_done(entry.listener)
self.tg.thread_done(entry.listener)
entry.listener.stop()
except ValueError:
pass
@ -862,101 +858,6 @@ class RuntimeHealthRegistry(object):
self.add_health_check(self.registries[registry.cluster_id])
class HealthManager(service.Service):
def __init__(self, engine_service, topic, version):
super(HealthManager, self).__init__()
self.TG = threadgroup.ThreadGroup(
thread_pool_size=cfg.CONF.health_manager_thread_pool_size)
self.engine_id = engine_service.engine_id
self.topic = topic
self.version = version
self.ctx = context.get_admin_context()
self.rpc_client = rpc_client.EngineClient()
self.health_registry = RuntimeHealthRegistry(
ctx=self.ctx, engine_id=self.engine_id, thread_group=self.TG)
def task(self):
"""Task that is queued on the health manager thread group.
The task is here so that the service always has something to wait()
on, or else the process will exit.
"""
start_time = timeutils.utcnow(True)
try:
self.health_registry.load_runtime_registry()
except Exception as ex:
LOG.error("Failed when loading runtime for health manager: %s", ex)
return _chase_up(start_time, cfg.CONF.periodic_interval,
name='Health manager task')
def start(self):
"""Start the health manager RPC server.
Note that the health manager server uses JSON serializer for parameter
passing. We should be careful when changing this interface.
"""
super(HealthManager, self).start()
self.target = messaging.Target(server=self.engine_id, topic=self.topic,
version=self.version)
server = rpc.get_rpc_server(self.target, self)
server.start()
self.TG.add_dynamic_timer(self.task, None, cfg.CONF.periodic_interval)
def stop(self):
self.TG.stop_timers()
super(HealthManager, self).stop()
@property
def registries(self):
return self.health_registry.registries
def listening(self, ctx):
"""Respond to confirm that the rpc service is still alive."""
return True
def register_cluster(self, ctx, cluster_id, interval=None,
node_update_timeout=None, params=None,
enabled=True):
"""Register a cluster for health checking.
:param ctx: The context of notify request.
:param cluster_id: The ID of the cluster to be unregistered.
:param interval: Interval of the health check.
:param node_update_timeout: Time to wait before declairing a node
unhealthy.
:param params: Params to be passed to health check.
:param enabled: Set's if the health check is enabled or disabled.
:return: None
"""
LOG.info("Registering health check for cluster %s.", cluster_id)
self.health_registry.register_cluster(
cluster_id=cluster_id,
interval=interval,
node_update_timeout=node_update_timeout,
params=params,
enabled=enabled)
def unregister_cluster(self, ctx, cluster_id):
"""Unregister a cluster from health checking.
:param ctx: The context of notify request.
:param cluster_id: The ID of the cluster to be unregistered.
:return: None
"""
LOG.info("Unregistering health check for cluster %s.", cluster_id)
self.health_registry.unregister_cluster(cluster_id)
def enable_cluster(self, ctx, cluster_id, params=None):
self.health_registry.enable_cluster(cluster_id)
def disable_cluster(self, ctx, cluster_id, params=None):
self.health_registry.disable_cluster(cluster_id)
def notify(engine_id, method, **kwargs):
"""Send notification to health manager service.

View File

@ -1,201 +0,0 @@
# 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 time
import eventlet
from oslo_config import cfg
from oslo_context import context as oslo_context
from oslo_log import log as logging
from oslo_service import threadgroup
from osprofiler import profiler
from senlin.common import context
from senlin.engine.actions import base as action_mod
from senlin.objects import action as ao
LOG = logging.getLogger(__name__)
wallclock = time.time
class ThreadGroupManager(object):
"""Thread group manager."""
def __init__(self):
super(ThreadGroupManager, self).__init__()
self.group = threadgroup.ThreadGroup(
thread_pool_size=cfg.CONF.scheduler_thread_pool_size)
# Create dummy service task, because when there is nothing queued
# on self.tg the process exits
self.add_timer(cfg.CONF.periodic_interval, self._service_task)
# TODO(Yanyan Hu): Build a DB session with full privilege
# for DB accessing in scheduler module
self.db_session = context.RequestContext(is_admin=True)
def _service_task(self):
"""Dummy task which gets queued on the service.Service threadgroup.
Without this service.Service sees nothing running i.e has nothing to
wait() on, so the process exits..
This could also be used to trigger periodic non-cluster-specific
housekeeping tasks
(Yanyan)Not sure this is still necessary, just keep it temporarily.
"""
# TODO(Yanyan): have this task call dbapi purge events
pass
def _serialize_profile_info(self):
prof = profiler.get()
trace_info = None
if prof:
trace_info = {
"hmac_key": prof.hmac_key,
"base_id": prof.get_base_id(),
"parent_id": prof.get_id()
}
return trace_info
def _start_with_trace(self, cnxt, trace, func, *args, **kwargs):
if trace:
profiler.init(**trace)
if cnxt is not None:
cnxt.update_store()
return func(*args, **kwargs)
def start(self, func, *args, **kwargs):
"""Run the given method in a thread."""
req_cnxt = oslo_context.get_current()
self.group.add_thread(
self._start_with_trace, req_cnxt,
self._serialize_profile_info(),
func, *args, **kwargs)
def start_action(self, worker_id, action_id=None):
"""Run action(s) in sub-thread(s).
:param worker_id: ID of the worker thread; we fake workers using
senlin engines at the moment.
:param action_id: ID of the action to be executed. None means all
ready actions will be acquired and scheduled to run.
"""
actions_launched = 0
max_batch_size = cfg.CONF.max_actions_per_batch
batch_interval = cfg.CONF.batch_interval
if action_id is not None:
timestamp = wallclock()
action = ao.Action.acquire(self.db_session, action_id, worker_id,
timestamp)
if action:
self.start(action_mod.ActionProc, self.db_session, action.id)
actions_launched += 1
while True:
timestamp = wallclock()
action = ao.Action.acquire_first_ready(self.db_session, worker_id,
timestamp)
if not action:
break
if max_batch_size == 0 or 'NODE' not in action.action:
self.start(action_mod.ActionProc, self.db_session, action.id)
continue
if max_batch_size > actions_launched:
self.start(action_mod.ActionProc, self.db_session, action.id)
actions_launched += 1
continue
self.start(action_mod.ActionProc, self.db_session, action.id)
LOG.debug(
'Engine %(id)s has launched %(num)s node actions '
'consecutively, stop scheduling node action for '
'%(interval)s second...',
{
'id': worker_id,
'num': max_batch_size,
'interval': batch_interval
})
sleep(batch_interval)
actions_launched = 1
def cancel_action(self, action_id):
"""Cancel an action execution progress."""
action = action_mod.Action.load(self.db_session, action_id,
project_safe=False)
action.signal(action.SIG_CANCEL)
def suspend_action(self, action_id):
"""Suspend an action execution progress."""
action = action_mod.Action.load(self.db_session, action_id,
project_safe=False)
action.signal(action.SIG_SUSPEND)
def resume_action(self, action_id):
"""Resume an action execution progress."""
action = action_mod.Action.load(self.db_session, action_id,
project_safe=False)
action.signal(action.SIG_RESUME)
def add_timer(self, interval, func, *args, **kwargs):
"""Define a periodic task to be run in the thread group.
The task will be executed in a separate green thread.
Interval is from cfg.CONF.periodic_interval
"""
timer = self.group.add_timer(interval, func, None, *args, **kwargs)
return timer
def stop_timers(self):
self.group.stop_timers()
def stop(self, graceful=False):
"""Stop any active threads belong to this threadgroup."""
# Try to stop all threads gracefully
self.group.stop(graceful)
self.group.wait()
# Wait for link()ed functions (i.e. lock release)
threads = self.group.threads[:]
links_done = dict((th, False) for th in threads)
def mark_done(gt, th):
links_done[th] = True
for th in threads:
th.link(mark_done, th)
while not all(links_done.values()):
eventlet.sleep()
def reschedule(action_id, sleep_time=1):
"""Eventlet Sleep for the specified number of seconds.
:param action_id: the action to put into sleep.
:param sleep_time: seconds to sleep; if None, no sleep;
"""
if sleep_time is not None:
LOG.debug('Action %s sleep for %s seconds', action_id, sleep_time)
eventlet.sleep(sleep_time)
def sleep(sleep_time):
"""Interface for sleeping."""
eventlet.sleep(sleep_time)

File diff suppressed because it is too large Load Diff

View File

150
senlin/health_manager/service.py Executable file
View File

@ -0,0 +1,150 @@
# 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_config import cfg
from oslo_log import log as logging
import oslo_messaging as messaging
from oslo_utils import timeutils
from oslo_utils import uuidutils
from osprofiler import profiler
from senlin.common import consts
from senlin.common import context
from senlin.common import context as senlin_context
from senlin.common import messaging as rpc
from senlin.common import service
from senlin.engine import health_manager
from senlin.objects import service as service_obj
LOG = logging.getLogger(__name__)
CONF = cfg.CONF
@profiler.trace_cls("rpc")
class HealthManagerService(service.Service):
def __init__(self, host, topic):
super(HealthManagerService, self).__init__(
self.service_name, host, topic,
threads=cfg.CONF.health_manager_thread_pool_size
)
self.version = consts.RPC_API_VERSION
self.ctx = context.get_admin_context()
# The following are initialized here and will be assigned in start()
# which happens after the fork when spawning multiple worker processes
self.health_registry = None
self.server = None
self.service_id = None
self.target = None
@property
def service_name(self):
return 'senlin-health-manager'
def start(self):
super(HealthManagerService, self).start()
self.service_id = uuidutils.generate_uuid()
self.health_registry = health_manager.RuntimeHealthRegistry(
ctx=self.ctx, engine_id=self.service_id,
thread_group=self.tg
)
# create service record
ctx = senlin_context.get_admin_context()
service_obj.Service.create(ctx, self.service_id, self.host,
self.service_name,
self.topic)
self.tg.add_timer(CONF.periodic_interval, self.service_manage_report)
self.target = messaging.Target(server=self.service_id,
topic=self.topic,
version=self.version)
self.server = rpc.get_rpc_server(self.target, self)
self.server.start()
self.tg.add_dynamic_timer(self.task, None, cfg.CONF.periodic_interval)
def stop(self, graceful=True):
if self.server:
self.server.stop()
self.server.wait()
service_obj.Service.delete(self.service_id)
LOG.info('Health-manager %s deleted', self.service_id)
super(HealthManagerService, self).stop(graceful)
def service_manage_report(self):
try:
ctx = senlin_context.get_admin_context()
service_obj.Service.update(ctx, self.service_id)
except Exception as ex:
LOG.error('Error while updating health-manager service: %s', ex)
def task(self):
"""Task that is queued on the health manager thread group.
The task is here so that the service always has something to wait()
on, or else the process will exit.
"""
start_time = timeutils.utcnow(True)
try:
self.health_registry.load_runtime_registry()
except Exception as ex:
LOG.error("Failed when loading runtime for health manager: %s", ex)
return health_manager.chase_up(
start_time, cfg.CONF.periodic_interval, name='Health manager task'
)
def listening(self, ctx):
"""Respond to confirm that the rpc service is still alive."""
return True
def register_cluster(self, ctx, cluster_id, interval=None,
node_update_timeout=None, params=None,
enabled=True):
"""Register a cluster for health checking.
:param ctx: The context of notify request.
:param cluster_id: The ID of the cluster to be unregistered.
:param interval: Interval of the health check.
:param node_update_timeout: Time to wait before declairing a node
unhealthy.
:param params: Params to be passed to health check.
:param enabled: Set's if the health check is enabled or disabled.
:return: None
"""
LOG.info("Registering health check for cluster %s.", cluster_id)
self.health_registry.register_cluster(
cluster_id=cluster_id,
interval=interval,
node_update_timeout=node_update_timeout,
params=params,
enabled=enabled)
def unregister_cluster(self, ctx, cluster_id):
"""Unregister a cluster from health checking.
:param ctx: The context of notify request.
:param cluster_id: The ID of the cluster to be unregistered.
:return: None
"""
LOG.info("Unregistering health check for cluster %s.", cluster_id)
self.health_registry.unregister_cluster(cluster_id)
def enable_cluster(self, ctx, cluster_id, params=None):
self.health_registry.enable_cluster(cluster_id)
def disable_cluster(self, ctx, cluster_id, params=None):
self.health_registry.disable_cluster(cluster_id)

View File

@ -0,0 +1,58 @@
# 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 mock
from oslo_config import cfg
from senlin.cmd import conductor
from senlin.common import consts
from senlin.common import messaging
from senlin.common import profiler
from senlin.conductor import service
from senlin.tests.unit.common import base
CONF = cfg.CONF
class TestConductor(base.SenlinTestCase):
def setUp(self):
super(TestConductor, self).setUp()
@mock.patch('oslo_config.cfg.CONF')
@mock.patch('oslo_log.log.register_options')
@mock.patch('oslo_log.log.setup')
@mock.patch('oslo_log.log.set_defaults')
@mock.patch('oslo_service.service.launch')
@mock.patch.object(messaging, 'setup')
@mock.patch.object(profiler, 'setup')
@mock.patch.object(service, 'ConductorService')
def test_main(self, mock_service, mock_profiler_setup,
mock_messaging_setup, mock_launch,
mock_log_set_defaults, mock_log_setup,
mock_register_opts, mock_conf):
mock_conf.conductor.workers = 1
mock_conf.host = 'hostname'
conductor.main()
mock_register_opts.assert_called_once()
mock_log_setup.assert_called_once()
mock_log_set_defaults.assert_called_once()
mock_messaging_setup.assert_called_once()
mock_profiler_setup.assert_called_once()
mock_service.assert_called_once_with(
'hostname', consts.ENGINE_TOPIC
)
mock_launch.assert_called_once_with(
mock.ANY, mock.ANY, workers=1, restart_method='mutate'
)

View File

@ -0,0 +1,58 @@
# 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 mock
from oslo_config import cfg
from senlin.cmd import engine
from senlin.common import consts
from senlin.common import messaging
from senlin.common import profiler
from senlin.engine import service
from senlin.tests.unit.common import base
CONF = cfg.CONF
class TestEngine(base.SenlinTestCase):
def setUp(self):
super(TestEngine, self).setUp()
@mock.patch('oslo_config.cfg.CONF')
@mock.patch('oslo_log.log.register_options')
@mock.patch('oslo_log.log.setup')
@mock.patch('oslo_log.log.set_defaults')
@mock.patch('oslo_service.service.launch')
@mock.patch.object(messaging, 'setup')
@mock.patch.object(profiler, 'setup')
@mock.patch.object(service, 'EngineService')
def test_main(self, mock_service, mock_profiler_setup,
mock_messaging_setup, mock_launch,
mock_log_set_defaults, mock_log_setup,
mock_register_opts, mock_conf):
mock_conf.num_engine_workers = 1
mock_conf.host = 'hostname'
engine.main()
mock_register_opts.assert_called_once()
mock_log_setup.assert_called_once()
mock_log_set_defaults.assert_called_once()
mock_messaging_setup.assert_called_once()
mock_profiler_setup.assert_called_once()
mock_service.assert_called_once_with(
'hostname', consts.DISPATCHER_TOPIC
)
mock_launch.assert_called_once_with(
mock.ANY, mock.ANY, workers=1, restart_method='mutate'
)

View File

@ -0,0 +1,58 @@
# 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 mock
from oslo_config import cfg
from senlin.cmd import health_manager
from senlin.common import consts
from senlin.common import messaging
from senlin.common import profiler
from senlin.health_manager import service
from senlin.tests.unit.common import base
CONF = cfg.CONF
class TestHealthManager(base.SenlinTestCase):
def setUp(self):
super(TestHealthManager, self).setUp()
@mock.patch('oslo_config.cfg.CONF')
@mock.patch('oslo_log.log.register_options')
@mock.patch('oslo_log.log.setup')
@mock.patch('oslo_log.log.set_defaults')
@mock.patch('oslo_service.service.launch')
@mock.patch.object(messaging, 'setup')
@mock.patch.object(profiler, 'setup')
@mock.patch.object(service, 'HealthManagerService')
def test_main(self, mock_service, mock_profiler_setup,
mock_messaging_setup, mock_launch,
mock_log_set_defaults, mock_log_setup,
mock_register_opts, mock_conf):
mock_conf.health_manager.workers = 1
mock_conf.host = 'hostname'
health_manager.main()
mock_register_opts.assert_called_once()
mock_log_setup.assert_called_once()
mock_log_set_defaults.assert_called_once()
mock_messaging_setup.assert_called_once()
mock_profiler_setup.assert_called_once()
mock_service.assert_called_once_with(
'hostname', consts.HEALTH_MANAGER_TOPIC
)
mock_launch.assert_called_once_with(
mock.ANY, mock.ANY, workers=1, restart_method='mutate'
)

View File

@ -23,7 +23,7 @@ import testscenarios
import testtools
from senlin.common import messaging
from senlin.engine import scheduler
from senlin.engine import service
from senlin.tests.unit.common import utils
@ -63,13 +63,13 @@ class SenlinTestCase(testscenarios.WithScenarios,
def setUp(self):
super(SenlinTestCase, self).setUp()
self.setup_logging()
scheduler.ENABLE_SLEEP = False
service.ENABLE_SLEEP = False
self.useFixture(fixtures.MonkeyPatch(
'senlin.common.exception._FATAL_EXCEPTION_FORMAT_ERRORS',
True))
def enable_sleep():
scheduler.ENABLE_SLEEP = True
service.ENABLE_SLEEP = True
self.addCleanup(enable_sleep)
self.addCleanup(cfg.CONF.reset)
@ -88,8 +88,8 @@ class SenlinTestCase(testscenarios.WithScenarios,
self._wallclock += self.TIME_STEP
return self._wallclock
self.m.StubOutWithMock(scheduler, 'wallclock')
scheduler.wallclock = fake_wallclock
self.m.StubOutWithMock(service, 'wallclock')
service.wallclock = fake_wallclock
def patchobject(self, obj, attr, **kwargs):
mockfixture = self.useFixture(fixtures.MockPatchObject(obj, attr,

View File

View File

@ -16,8 +16,8 @@ import six
from senlin.common import consts
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine.actions import base as ab
from senlin.engine import service
from senlin.objects import action as ao
from senlin.objects import cluster as co
from senlin.objects.requests import actions as orao
@ -26,12 +26,10 @@ from senlin.tests.unit.common import utils
class ActionTest(base.SenlinTestCase):
def setUp(self):
super(ActionTest, self).setUp()
self.ctx = utils.dummy_context(project='action_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.eng.init_tgm()
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(ao.Action, 'get_all')
def test_action_list(self, mock_get):
@ -42,7 +40,7 @@ class ActionTest(base.SenlinTestCase):
mock_get.return_value = [x_1, x_2]
req = orao.ActionListRequest()
result = self.eng.action_list(self.ctx, req.obj_to_primitive())
result = self.svc.action_list(self.ctx, req.obj_to_primitive())
expected = [{'k': 'v1'}, {'k': 'v2'}]
self.assertEqual(expected, result)
@ -60,7 +58,7 @@ class ActionTest(base.SenlinTestCase):
limit=100,
sort='status',
project_safe=True)
result = self.eng.action_list(self.ctx, req.obj_to_primitive())
result = self.svc.action_list(self.ctx, req.obj_to_primitive())
expected = [{'status': 'READY'}, {'status': 'SUCCESS'}]
self.assertEqual(expected, result)
@ -75,7 +73,7 @@ class ActionTest(base.SenlinTestCase):
def test_action_list_with_bad_params(self):
req = orao.ActionListRequest(project_safe=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.action_list,
self.svc.action_list,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.Forbidden, ex.exc_info[0])
@ -84,7 +82,7 @@ class ActionTest(base.SenlinTestCase):
mock_get.return_value = []
req = orao.ActionListRequest(project_safe=True)
result = self.eng.action_list(self.ctx, req.obj_to_primitive())
result = self.svc.action_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@ -92,13 +90,13 @@ class ActionTest(base.SenlinTestCase):
mock_get.reset_mock()
req = orao.ActionListRequest(project_safe=True)
result = self.eng.action_list(self.ctx, req.obj_to_primitive())
result = self.svc.action_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
mock_get.reset_mock()
req = orao.ActionListRequest(project_safe=False)
result = self.eng.action_list(self.ctx, req.obj_to_primitive())
result = self.svc.action_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=False)
@ -111,7 +109,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionCreateRequestBody(name='a1', cluster_id='C1',
action='CLUSTER_CREATE')
result = self.eng.action_create(self.ctx, req.obj_to_primitive())
result = self.svc.action_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -130,7 +128,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionCreateRequestBody(name='NODE1',
cluster_id='C1')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.action_create,
self.svc.action_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -145,7 +143,7 @@ class ActionTest(base.SenlinTestCase):
x_obj.to_dict.return_value = {'k': 'v'}
req = orao.ActionGetRequest(identity='ACTION_ID')
result = self.eng.action_get(self.ctx, req.obj_to_primitive())
result = self.svc.action_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'k': 'v'}, result)
mock_find.assert_called_once_with(self.ctx, 'ACTION_ID')
@ -156,7 +154,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionGetRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.action_get,
self.svc.action_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
mock_find.assert_called_once_with(self.ctx, 'Bogus')
@ -170,7 +168,7 @@ class ActionTest(base.SenlinTestCase):
mock_delete.return_value = None
req = orao.ActionDeleteRequest(identity='ACTION_ID')
result = self.eng.action_delete(self.ctx, req.obj_to_primitive())
result = self.svc.action_delete(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_find.assert_called_once_with(self.ctx, 'ACTION_ID')
mock_delete.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -186,7 +184,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionDeleteRequest(identity='ACTION_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.action_delete,
self.svc.action_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceInUse, ex.exc_info[0])
@ -202,7 +200,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionDeleteRequest(identity='ACTION_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.action_delete,
self.svc.action_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -218,7 +216,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionUpdateRequest(identity='ACTION_ID',
status='CANCELLED', force=False)
result = self.eng.action_update(self.ctx, req.obj_to_primitive())
result = self.svc.action_update(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_load.assert_called_with(self.ctx, 'ACTION_ID', project_safe=False)
@ -233,7 +231,7 @@ class ActionTest(base.SenlinTestCase):
req = orao.ActionUpdateRequest(identity='ACTION_ID',
status='FOO')
ex = self.assertRaises(rpc.ExpectedException, self.eng.action_update,
ex = self.assertRaises(rpc.ExpectedException, self.svc.action_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])

View File

@ -16,10 +16,10 @@ import six
from senlin.common import consts
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine.actions import base as am
from senlin.engine import cluster as cm
from senlin.engine import dispatcher
from senlin.engine import service
from senlin.objects import cluster as co
from senlin.objects import node as no
from senlin.objects.requests import clusters as orco
@ -28,12 +28,11 @@ from senlin.tests.unit.common import utils
class ClusterOpTest(base.SenlinTestCase):
def setUp(self):
super(ClusterOpTest, self).setUp()
self.ctx = utils.dummy_context(project='cluster_op_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(am.Action, 'create')
@ -58,7 +57,7 @@ class ClusterOpTest(base.SenlinTestCase):
params=params,
filters=filters)
result = self.eng.cluster_op(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_op(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_CLUSTER')
@ -86,7 +85,7 @@ class ClusterOpTest(base.SenlinTestCase):
type='cluster', id='Bogus')
req = orco.ClusterOperationRequest(identity='Bogus', operation='dance')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_op,
self.svc.cluster_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -107,7 +106,7 @@ class ClusterOpTest(base.SenlinTestCase):
req = orco.ClusterOperationRequest(identity='node1', operation='swim')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_op,
self.svc.cluster_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -132,7 +131,7 @@ class ClusterOpTest(base.SenlinTestCase):
params={'style': 'tango'})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_op,
self.svc.cluster_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -162,7 +161,7 @@ class ClusterOpTest(base.SenlinTestCase):
operation='dance',
filters=filters)
result = self.eng.cluster_op(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_op(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_CLUSTER')
@ -203,7 +202,7 @@ class ClusterOpTest(base.SenlinTestCase):
req = orco.ClusterOperationRequest(identity='FAKE_CLUSTER',
operation='dance')
result = self.eng.cluster_op(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_op(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_CLUSTER')
@ -245,7 +244,7 @@ class ClusterOpTest(base.SenlinTestCase):
filters=filters)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_op,
self.svc.cluster_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -277,7 +276,7 @@ class ClusterOpTest(base.SenlinTestCase):
operation='dance', filters=filters)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_op,
self.svc.cluster_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])

View File

@ -16,9 +16,9 @@ import six
from senlin.common import consts
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine.actions import base as action_mod
from senlin.engine import dispatcher
from senlin.engine import service
from senlin.objects import cluster as co
from senlin.objects import cluster_policy as cpo
from senlin.objects import policy as po
@ -29,12 +29,10 @@ from senlin.tests.unit.common import utils
class ClusterPolicyTest(base.SenlinTestCase):
def setUp(self):
super(ClusterPolicyTest, self).setUp()
self.ctx = utils.dummy_context(project='cluster_policy_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.eng.init_tgm()
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(co.Cluster, 'find')
@mock.patch.object(cpo.ClusterPolicy, 'get_all')
@ -48,7 +46,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
mock_get.return_value = [b1, b2]
req = orcp.ClusterPolicyListRequest(identity='CLUSTER')
result = self.eng.cluster_policy_list(
result = self.svc.cluster_policy_list(
self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -72,7 +70,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orcp.ClusterPolicyListRequest(**params)
result = self.eng.cluster_policy_list(
result = self.svc.cluster_policy_list(
self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -95,7 +93,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
id='Bogus')
req = orcp.ClusterPolicyListRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_list,
self.svc.cluster_policy_list,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
self.assertEqual("The cluster 'Bogus' could not be found.",
@ -114,7 +112,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orcp.ClusterPolicyGetRequest(identity='C1',
policy_id='P1')
result = self.eng.cluster_policy_get(self.ctx,
result = self.svc.cluster_policy_get(self.ctx,
req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
@ -129,7 +127,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orcp.ClusterPolicyGetRequest(identity='cid',
policy_id='pid')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_get,
self.svc.cluster_policy_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
self.assertEqual("The cluster 'cid' could not be found.",
@ -145,7 +143,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orcp.ClusterPolicyGetRequest(identity='cid',
policy_id='pid')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_get,
self.svc.cluster_policy_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -166,7 +164,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orcp.ClusterPolicyGetRequest(identity='cid',
policy_id='pid')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_get,
self.svc.cluster_policy_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.PolicyBindingNotFound, ex.exc_info[0])
@ -185,7 +183,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orco.ClusterAttachPolicyRequest(identity='C1', policy_id='P1',
enabled=True)
res = self.eng.cluster_policy_attach(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_policy_attach(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_cluster.assert_called_once_with(self.ctx, 'C1')
@ -209,7 +207,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
policy_id='POLICY_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_attach,
self.svc.cluster_policy_attach,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -227,7 +225,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
policy_id='BOGUS')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_attach,
self.svc.cluster_policy_attach,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -249,7 +247,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
mock_cp.return_value = mock.Mock()
req = orco.ClusterDetachPolicyRequest(identity='C1', policy_id='P1')
res = self.eng.cluster_policy_detach(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_policy_detach(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_cluster.assert_called_once_with(self.ctx, 'C1')
@ -274,7 +272,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
policy_id='POLICY_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_detach,
self.svc.cluster_policy_detach,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -292,7 +290,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
policy_id='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_detach,
self.svc.cluster_policy_detach,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -312,7 +310,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orco.ClusterDetachPolicyRequest(identity='C1', policy_id='P1')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_detach,
self.svc.cluster_policy_detach,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -337,7 +335,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
req = orco.ClusterUpdatePolicyRequest(identity='C1', policy_id='P1',
enabled=False)
res = self.eng.cluster_policy_update(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_policy_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_cluster.assert_called_once_with(self.ctx, 'C1')
@ -362,7 +360,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
enabled=True)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_update,
self.svc.cluster_policy_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -380,7 +378,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
enabled=True)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_update,
self.svc.cluster_policy_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -401,7 +399,7 @@ class ClusterPolicyTest(base.SenlinTestCase):
enabled=True)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_policy_update,
self.svc.cluster_policy_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])

View File

@ -21,11 +21,11 @@ from senlin.common import exception as exc
from senlin.common.i18n import _
from senlin.common import scaleutils as su
from senlin.common import utils as common_utils
from senlin.conductor import service
from senlin.engine.actions import base as am
from senlin.engine.actions import cluster_action as ca
from senlin.engine import dispatcher
from senlin.engine import node as nm
from senlin.engine import service
from senlin.objects import action as ao
from senlin.objects import base as obj_base
from senlin.objects import cluster as co
@ -39,19 +39,18 @@ from senlin.tests.unit.common import utils
class ClusterTest(base.SenlinTestCase):
def setUp(self):
super(ClusterTest, self).setUp()
self.ctx = utils.dummy_context(project='cluster_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(co.Cluster, 'count_all')
def test_check_cluster_quota(self, mock_count):
mock_count.return_value = 10
cfg.CONF.set_override('max_clusters_per_project', 11)
res = self.eng.check_cluster_quota(self.ctx)
res = self.svc.check_cluster_quota(self.ctx)
self.assertIsNone(res)
mock_count.assert_called_once_with(self.ctx)
@ -62,7 +61,7 @@ class ClusterTest(base.SenlinTestCase):
cfg.CONF.set_override('max_clusters_per_project', 11)
ex = self.assertRaises(exc.OverQuota,
self.eng.check_cluster_quota, self.ctx)
self.svc.check_cluster_quota, self.ctx)
self.assertEqual("Quota exceeded for resources.",
six.text_type(ex))
@ -87,7 +86,7 @@ class ClusterTest(base.SenlinTestCase):
mock_get.return_value = [x_obj_1, x_obj_2]
req = orco.ClusterListRequest(project_safe=True)
result = self.eng.cluster_list(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@ -106,7 +105,7 @@ class ClusterTest(base.SenlinTestCase):
}
self._prepare_request(req)
result = self.eng.cluster_list(self.ctx, req)
result = self.svc.cluster_list(self.ctx, req)
self.assertEqual([], result)
mock_get.assert_called_once_with(
@ -114,7 +113,7 @@ class ClusterTest(base.SenlinTestCase):
filters={'name': ['test_cluster'], 'status': ['ACTIVE']},
project_safe=True)
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(service.ConductorService, 'check_cluster_quota')
@mock.patch.object(su, 'check_size_params')
@mock.patch.object(am.Action, 'create')
@mock.patch.object(co.Cluster, "create")
@ -134,7 +133,7 @@ class ClusterTest(base.SenlinTestCase):
desired_capacity=3)
# do it
result = self.eng.cluster_create(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_profile.assert_called_once_with(self.ctx, 'PROFILE')
@ -157,7 +156,7 @@ class ClusterTest(base.SenlinTestCase):
)
notify.assert_called_once_with()
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(service.ConductorService, 'check_cluster_quota')
@mock.patch.object(su, 'check_size_params')
@mock.patch.object(am.Action, 'create')
@mock.patch.object(co.Cluster, "create")
@ -179,7 +178,7 @@ class ClusterTest(base.SenlinTestCase):
config={'k1': 'v1'})
# do it
result = self.eng.cluster_create(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_profile.assert_called_once_with(self.ctx, 'PROFILE')
@ -202,14 +201,14 @@ class ClusterTest(base.SenlinTestCase):
)
notify.assert_called_once_with()
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(service.ConductorService, 'check_cluster_quota')
def test_cluster_create_exceeding_quota(self, mock_quota):
mock_quota.side_effect = exc.OverQuota()
req = {'profile_id': 'PROFILE', 'name': 'CLUSTER'}
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_create,
self.svc.cluster_create,
self.ctx, req)
self.assertEqual(exc.OverQuota, ex.exc_info[0])
@ -217,7 +216,7 @@ class ClusterTest(base.SenlinTestCase):
six.text_type(ex.exc_info[1]))
mock_quota.assert_called_once_with(self.ctx)
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(service.ConductorService, 'check_cluster_quota')
@mock.patch.object(co.Cluster, 'get_by_name')
def test_cluster_create_duplicate_name(self, mock_get, mock_quota):
cfg.CONF.set_override('name_unique', True)
@ -227,7 +226,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_create,
self.svc.cluster_create,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -235,7 +234,7 @@ class ClusterTest(base.SenlinTestCase):
six.text_type(ex.exc_info[1]))
mock_get.assert_called_once_with(self.ctx, 'CLUSTER')
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(service.ConductorService, 'check_cluster_quota')
@mock.patch.object(po.Profile, 'find')
def test_cluster_create_profile_not_found(self, mock_find, mock_quota):
mock_quota.return_value = None
@ -244,7 +243,7 @@ class ClusterTest(base.SenlinTestCase):
req = {'profile_id': 'Bogus', 'name': 'CLUSTER'}
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_create,
self.svc.cluster_create,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -252,7 +251,7 @@ class ClusterTest(base.SenlinTestCase):
"be found.", six.text_type(ex.exc_info[1]))
mock_find.assert_called_once_with(self.ctx, 'Bogus')
@mock.patch.object(service.EngineService, 'check_cluster_quota')
@mock.patch.object(service.ConductorService, 'check_cluster_quota')
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(su, 'check_size_params')
def test_cluster_create_failed_checking(self, mock_check, mock_find,
@ -264,7 +263,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_create,
self.svc.cluster_create,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -280,7 +279,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterGetRequest(identity='C1')
result = self.eng.cluster_get(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(
@ -294,7 +293,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_get,
self.svc.cluster_get,
self.ctx, req)
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -319,7 +318,7 @@ class ClusterTest(base.SenlinTestCase):
config={'k1': 'v1'})
# do it
result = self.eng.cluster_update(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -353,7 +352,7 @@ class ClusterTest(base.SenlinTestCase):
req = {'identity': 'Bogus', 'name': 'new-name'}
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.svc.cluster_update,
self.ctx, req)
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -366,7 +365,7 @@ class ClusterTest(base.SenlinTestCase):
self.assertEqual(consts.CS_ERROR, x_cluster.status)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.svc.cluster_update,
self.ctx, req)
self.assertEqual(exc.FeatureNotSupported, ex.exc_info[0])
@ -386,7 +385,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterUpdateRequest(identity='CLUSTER', profile_id='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.svc.cluster_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -411,7 +410,7 @@ class ClusterTest(base.SenlinTestCase):
profile_id='NEW_PROFILE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.svc.cluster_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -439,7 +438,7 @@ class ClusterTest(base.SenlinTestCase):
profile_id='NEW_PROFILE')
# do it
result = self.eng.cluster_update(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -474,7 +473,7 @@ class ClusterTest(base.SenlinTestCase):
metadata={'K': 'V'})
# do it
result = self.eng.cluster_update(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -506,7 +505,7 @@ class ClusterTest(base.SenlinTestCase):
timeout=10)
# do it
result = self.eng.cluster_update(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -538,7 +537,7 @@ class ClusterTest(base.SenlinTestCase):
timeout=100)
# do it
result = self.eng.cluster_update(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID', 'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -568,7 +567,7 @@ class ClusterTest(base.SenlinTestCase):
timeout=10)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.svc.cluster_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -581,7 +580,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterUpdateRequest(identity='CLUSTER')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_update,
self.svc.cluster_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -595,7 +594,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -625,7 +624,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterAddNodesRequest(identity='C1',
nodes=['NODE_A', 'NODE_B'])
result = self.eng.cluster_add_nodes(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_add_nodes(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -657,7 +656,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -681,7 +680,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -706,7 +705,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -734,7 +733,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -760,7 +759,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -793,7 +792,7 @@ class ClusterTest(base.SenlinTestCase):
self._prepare_request(req)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_add_nodes,
self.svc.cluster_add_nodes,
self.ctx, req)
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -827,7 +826,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterDelNodesRequest(identity='CLUSTER', nodes=['NODE1'])
result = self.eng.cluster_del_nodes(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_del_nodes(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -853,7 +852,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterDelNodesRequest(identity='Bogus', nodes=['NODE1'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -869,7 +868,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterDelNodesRequest(identity='CLUSTER', nodes=['NODE1'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -888,7 +887,7 @@ class ClusterTest(base.SenlinTestCase):
mock_node.return_value = node
req = orco.ClusterDelNodesRequest(identity='CLUSTER', nodes=['NODE1'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceInUse, ex.exc_info[0])
message = _("nodes ['NODE1'] are depended by other nodes, so can't be "
@ -904,7 +903,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterDelNodesRequest(identity='CLUSTER', nodes=['NODE2'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -923,7 +922,7 @@ class ClusterTest(base.SenlinTestCase):
nodes=['NODE1', 'NODE2'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -942,7 +941,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterDelNodesRequest(identity='CLUSTER', nodes=['NODE3'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -965,7 +964,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterDelNodesRequest(identity='CLUSTER', nodes=['NODE3'])
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_del_nodes,
self.svc.cluster_del_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -997,7 +996,7 @@ class ClusterTest(base.SenlinTestCase):
number=5
)
res = self.eng.cluster_resize(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_resize(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1041,7 +1040,7 @@ class ClusterTest(base.SenlinTestCase):
number=5
)
res = self.eng.cluster_resize(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_resize(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1086,7 +1085,7 @@ class ClusterTest(base.SenlinTestCase):
number=15.81
)
res = self.eng.cluster_resize(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_resize(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1117,7 +1116,7 @@ class ClusterTest(base.SenlinTestCase):
)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_resize,
self.svc.cluster_resize,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1131,7 +1130,7 @@ class ClusterTest(base.SenlinTestCase):
)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_resize,
self.svc.cluster_resize,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual("Missing adjustment_type "
@ -1146,7 +1145,7 @@ class ClusterTest(base.SenlinTestCase):
)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_resize,
self.svc.cluster_resize,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1165,7 +1164,7 @@ class ClusterTest(base.SenlinTestCase):
id='CLUSTER')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_resize,
self.svc.cluster_resize,
self.ctx, req.obj_to_primitive())
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1190,7 +1189,7 @@ class ClusterTest(base.SenlinTestCase):
)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_resize,
self.svc.cluster_resize,
self.ctx, req.obj_to_primitive())
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1212,7 +1211,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterScaleOutRequest(identity='CLUSTER', count=1)
result = self.eng.cluster_scale_out(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_scale_out(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1234,7 +1233,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterScaleOutRequest(identity='Bogus', count=1)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_scale_out,
self.svc.cluster_scale_out,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -1252,7 +1251,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterScaleOutRequest(identity='CLUSTER')
result = self.eng.cluster_scale_out(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_scale_out(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1272,7 +1271,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterScaleOutRequest(identity='CLUSTER', count=0)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_scale_out,
self.svc.cluster_scale_out,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1288,7 +1287,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterScaleOutRequest(identity='CLUSTER', count=2)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_scale_out,
self.svc.cluster_scale_out,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1309,7 +1308,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterScaleInRequest(identity='CLUSTER', count=2)
result = self.eng.cluster_scale_in(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_scale_in(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1331,7 +1330,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterScaleInRequest(identity='Bogus', count=2)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_scale_in,
self.svc.cluster_scale_in,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -1348,7 +1347,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterScaleInRequest(identity='CLUSTER')
result = self.eng.cluster_scale_in(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_scale_in(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER')
@ -1368,7 +1367,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterScaleInRequest(identity='CLUSTER', count=0)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_scale_in,
self.svc.cluster_scale_in,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1384,7 +1383,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterScaleInRequest(identity='FAKE_CLUSTER', count=2)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_scale_in,
self.svc.cluster_scale_in,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1402,7 +1401,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterCheckRequest(identity='C1', params={'foo': 'bar'})
res = self.eng.cluster_check(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_check(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -1428,7 +1427,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterCheckRequest(identity='C1',
params={'delete_check_action': True})
res = self.eng.cluster_check(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_check(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -1455,7 +1454,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterCheckRequest(identity='C1')
result = self.eng.cluster_check(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_check(self.ctx, req.obj_to_primitive())
self.assertIsNotNone(x_cluster.user)
self.assertEqual({'action': 'ACTION_ID'}, result)
@ -1480,7 +1479,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterCheckRequest(identity='C1')
result = self.eng.cluster_check(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_check(self.ctx, req.obj_to_primitive())
self.assertIsNotNone(x_cluster.user)
self.assertEqual({'action': 'ACTION_ID'}, result)
@ -1502,7 +1501,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterCheckRequest(identity='C1', params={'foo': 'bar'})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_check,
self.svc.cluster_check,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -1520,7 +1519,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterRecoverRequest(identity='C1',
params={'operation': 'RECREATE'})
result = self.eng.cluster_recover(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -1544,7 +1543,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterRecoverRequest(identity='C1',
params={'operation': 'REBUILD'})
result = self.eng.cluster_recover(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -1568,7 +1567,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterRecoverRequest(identity='C1',
params={'operation': 'REBOOT'})
result = self.eng.cluster_recover(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -1591,7 +1590,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterRecoverRequest(identity='C1')
result = self.eng.cluster_recover(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'C1')
@ -1612,7 +1611,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterRecoverRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_recover,
self.svc.cluster_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -1629,7 +1628,7 @@ class ClusterTest(base.SenlinTestCase):
params={'bad': 'fake'})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_recover,
self.svc.cluster_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1646,7 +1645,7 @@ class ClusterTest(base.SenlinTestCase):
params={'operation': 'fake'})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_recover,
self.svc.cluster_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1668,7 +1667,7 @@ class ClusterTest(base.SenlinTestCase):
)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_recover,
self.svc.cluster_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1687,7 +1686,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterRecoverRequest(identity='C1')
result = self.eng.cluster_recover(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_recover(self.ctx, req.obj_to_primitive())
self.assertIsNotNone(x_cluster.user)
self.assertEqual({'action': 'ACTION_ID'}, result)
@ -1714,7 +1713,7 @@ class ClusterTest(base.SenlinTestCase):
]
# do it
res = self.eng._validate_replace_nodes(self.ctx, cluster,
res = self.svc._validate_replace_nodes(self.ctx, cluster,
{'OLD_NODE': 'NEW_NODE'})
self.assertEqual({'OLD_ID': 'NEW_ID'}, res)
@ -1736,7 +1735,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD': 'NEW'})
self.assertIn("Original nodes not found: ['OLD']", six.text_type(ex))
@ -1754,7 +1753,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD': 'NEW'})
self.assertIn("Replacement nodes not found: ['NEW']",
@ -1776,7 +1775,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD': 'NEW'})
self.assertIn("The specified nodes ['OLD'] to be replaced are not "
@ -1798,7 +1797,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD': 'NEW'})
self.assertIn("Nodes ['NEW'] already member of a cluster.",
@ -1820,7 +1819,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD': 'NEW'})
self.assertIn("Nodes are not ACTIVE: ['NEW'].", six.text_type(ex))
@ -1841,7 +1840,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD1': 'NEW1'})
msg1 = _("Nodes ['NEW1'] already member of a cluster.")
@ -1870,7 +1869,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(exc.BadRequest,
self.eng._validate_replace_nodes,
self.svc._validate_replace_nodes,
self.ctx, c, {'OLD': 'NEW'})
self.assertIn("Profile type of nodes ['NEW'] do not match that of "
@ -1885,7 +1884,7 @@ class ClusterTest(base.SenlinTestCase):
])
@mock.patch.object(am.Action, 'create')
@mock.patch.object(service.EngineService, '_validate_replace_nodes')
@mock.patch.object(service.ConductorService, '_validate_replace_nodes')
@mock.patch.object(no.Node, 'find')
@mock.patch.object(po.Profile, 'find')
@mock.patch.object(co.Cluster, 'find')
@ -1906,7 +1905,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterReplaceNodesRequest(identity='CLUSTER', nodes=param)
# do it
res = self.eng.cluster_replace_nodes(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_replace_nodes(self.ctx, req.obj_to_primitive())
# verify
self.assertEqual({'action': 'ACTION_ID'}, res)
@ -1921,7 +1920,7 @@ class ClusterTest(base.SenlinTestCase):
inputs={'candidates': {'ORIGINAL': 'REPLACE'}})
notify.assert_called_once_with()
@mock.patch.object(service.EngineService, '_validate_replace_nodes')
@mock.patch.object(service.ConductorService, '_validate_replace_nodes')
@mock.patch.object(co.Cluster, 'find')
def test_cluster_replace_nodes_failed_validate(self, mock_find, mock_chk):
nodes = {'OLD': 'NEW'}
@ -1932,7 +1931,7 @@ class ClusterTest(base.SenlinTestCase):
# do it
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_replace_nodes,
self.svc.cluster_replace_nodes,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1959,7 +1958,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterCollectRequest(identity='CLUSTER_ID',
path='details.ip')
res = self.eng.cluster_collect(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_collect(self.ctx, req.obj_to_primitive())
self.assertIn('cluster_attributes', res)
self.assertIn({'id': 'NODE1', 'value': '1.2.3.4'},
@ -1984,7 +1983,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterCollectRequest(identity='CLUSTER_ID', path='foo.bar')
err = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_collect,
self.svc.cluster_collect,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, err.exc_info[0])
@ -1999,7 +1998,7 @@ class ClusterTest(base.SenlinTestCase):
req = orco.ClusterCollectRequest(identity=cid, path='foo.bar')
err = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_collect,
self.svc.cluster_collect,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, err.exc_info[0])
@ -2014,7 +2013,7 @@ class ClusterTest(base.SenlinTestCase):
mock_get.return_value = []
req = orco.ClusterCollectRequest(identity='CLUSTER_ID', path='barr')
res = self.eng.cluster_collect(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_collect(self.ctx, req.obj_to_primitive())
self.assertEqual({'cluster_attributes': []}, res)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER_ID')
@ -2032,7 +2031,7 @@ class ClusterTest(base.SenlinTestCase):
mock_get.return_value = [x_node_1, x_node_2]
req = orco.ClusterCollectRequest(identity='CLUSTER_ID', path='name')
res = self.eng.cluster_collect(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_collect(self.ctx, req.obj_to_primitive())
self.assertIn('cluster_attributes', res)
self.assertIn({'id': 'NODE1', 'value': 'node1'},
@ -2058,7 +2057,7 @@ class ClusterTest(base.SenlinTestCase):
mock_get.return_value = [x_node_1, x_node_2]
req = orco.ClusterCollectRequest(identity='CLUSTER_ID', path='bogus')
res = self.eng.cluster_collect(self.ctx, req.obj_to_primitive())
res = self.svc.cluster_collect(self.ctx, req.obj_to_primitive())
self.assertEqual({'cluster_attributes': []}, res)
mock_find.assert_called_once_with(self.ctx, 'CLUSTER_ID')
@ -2077,7 +2076,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterDeleteRequest(identity='IDENTITY', force=False)
result = self.eng.cluster_delete(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_delete(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'IDENTITY')
@ -2101,7 +2100,7 @@ class ClusterTest(base.SenlinTestCase):
force=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_delete,
self.svc.cluster_delete,
self.ctx, req.obj_to_primitive())
msg = _("The cluster 'FAKE_CLUSTER' cannot be deleted: still "
@ -2117,7 +2116,7 @@ class ClusterTest(base.SenlinTestCase):
force=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_delete,
self.svc.cluster_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -2134,7 +2133,7 @@ class ClusterTest(base.SenlinTestCase):
force=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.cluster_delete,
self.svc.cluster_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ActionInProgress, ex.exc_info[0])
@ -2159,7 +2158,7 @@ class ClusterTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orco.ClusterDeleteRequest(identity='IDENTITY', force=True)
result = self.eng.cluster_delete(self.ctx, req.obj_to_primitive())
result = self.svc.cluster_delete(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_with(self.ctx, 'IDENTITY')
@ -2181,7 +2180,7 @@ class ClusterTest(base.SenlinTestCase):
identity='CLUSTER', lifecycle_action_token='NODE_ACTION_ID')
# do it
res = self.eng.cluster_complete_lifecycle(self.ctx,
res = self.svc.cluster_complete_lifecycle(self.ctx,
req.obj_to_primitive())
# verify

View File

@ -12,7 +12,7 @@
import mock
from senlin.engine import service
from senlin.conductor import service
from senlin.objects import credential as co
from senlin.objects.requests import credentials as vorc
from senlin.tests.unit.common import base
@ -20,12 +20,11 @@ from senlin.tests.unit.common import utils
class CredentialTest(base.SenlinTestCase):
def setUp(self):
super(CredentialTest, self).setUp()
self.ctx = utils.dummy_context(user_id='fake_user_id',
project='fake_project_id')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(co.Credential, 'update_or_create')
def test_credential_create(self, mock_create):
@ -34,7 +33,7 @@ class CredentialTest(base.SenlinTestCase):
req = vorc.CredentialCreateRequest(cred=cred,
attrs={'k1': 'v1'})
result = self.eng.credential_create(self.ctx, req.obj_to_primitive())
result = self.svc.credential_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'cred': cred}, result)
mock_create.assert_called_once_with(
@ -59,7 +58,7 @@ class CredentialTest(base.SenlinTestCase):
project=self.ctx.project_id,
query={'k1': 'v1'})
result = self.eng.credential_get(self.ctx, req.obj_to_primitive())
result = self.svc.credential_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_get.assert_called_once_with(
@ -71,7 +70,7 @@ class CredentialTest(base.SenlinTestCase):
req = vorc.CredentialGetRequest(user=self.ctx.user_id,
project=self.ctx.project_id)
result = self.eng.credential_get(self.ctx, req.obj_to_primitive())
result = self.svc.credential_get(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_get.assert_called_once_with(
@ -84,7 +83,7 @@ class CredentialTest(base.SenlinTestCase):
req = vorc.CredentialGetRequest(user=self.ctx.user_id,
project=self.ctx.project_id)
result = self.eng.credential_get(self.ctx, req.obj_to_primitive())
result = self.svc.credential_get(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_get.assert_called_once_with(
@ -95,7 +94,7 @@ class CredentialTest(base.SenlinTestCase):
x_cred = 'fake_credential'
cred = {'openstack': {'trust': x_cred}}
req = vorc.CredentialUpdateRequest(cred=cred)
result = self.eng.credential_update(self.ctx, req.obj_to_primitive())
result = self.svc.credential_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'cred': cred}, result)
mock_update.assert_called_once_with(

View File

@ -16,7 +16,7 @@ from oslo_messaging.rpc import dispatcher as rpc
from senlin.common import consts
from senlin.common import exception as exc
from senlin.engine import service
from senlin.conductor import service
from senlin.objects import cluster as co
from senlin.objects import event as eo
from senlin.objects.requests import events as oreo
@ -25,11 +25,10 @@ from senlin.tests.unit.common import utils
class EventTest(base.SenlinTestCase):
def setUp(self):
super(EventTest, self).setUp()
self.ctx = utils.dummy_context(project='event_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(eo.Event, 'get_all')
def test_event_list(self, mock_load):
@ -41,7 +40,7 @@ class EventTest(base.SenlinTestCase):
mock_load.return_value = [obj_1, obj_2]
req = oreo.EventListRequest()
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
expected = [{'level': 'DEBUG'}, {'level': 'INFO'}]
self.assertEqual(expected, result)
@ -62,7 +61,7 @@ class EventTest(base.SenlinTestCase):
marker=marker_uuid,
sort=consts.EVENT_TIMESTAMP,
project_safe=True)
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
expected = [{'level': 'DEBUG'}, {'level': 'INFO'}]
self.assertEqual(expected, result)
@ -88,7 +87,7 @@ class EventTest(base.SenlinTestCase):
req = oreo.EventListRequest(cluster_id=['CLUSTERA', 'CLUSTER2'],
project_safe=True)
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
expected = [{'level': 'DEBUG'}, {'level': 'INFO'}]
self.assertEqual(expected, result)
@ -111,7 +110,7 @@ class EventTest(base.SenlinTestCase):
req = oreo.EventListRequest(cluster_id=['CLUSTERA', 'CLUSTER2'],
project_safe=True)
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
self.assertEqual(0, mock_load.call_count)
@ -123,7 +122,7 @@ class EventTest(base.SenlinTestCase):
def test_event_list_with_bad_params(self):
req = oreo.EventListRequest(project_safe=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.event_list,
self.svc.event_list,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.Forbidden, ex.exc_info[0])
@ -132,7 +131,7 @@ class EventTest(base.SenlinTestCase):
mock_load.return_value = []
req = oreo.EventListRequest(project_safe=True)
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_load.assert_called_once_with(self.ctx, project_safe=True)
@ -140,13 +139,13 @@ class EventTest(base.SenlinTestCase):
mock_load.reset_mock()
req = oreo.EventListRequest(project_safe=True)
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_load.assert_called_once_with(self.ctx, project_safe=True)
mock_load.reset_mock()
req = oreo.EventListRequest(project_safe=False)
result = self.eng.event_list(self.ctx, req.obj_to_primitive())
result = self.svc.event_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_load.assert_called_once_with(self.ctx, project_safe=False)
@ -157,7 +156,7 @@ class EventTest(base.SenlinTestCase):
mock_find.return_value = x_event
req = oreo.EventGetRequest(identity='EVENT_ID')
result = self.eng.event_get(self.ctx, req.obj_to_primitive())
result = self.svc.event_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'level': 'DEBUG'}, result)
mock_find.assert_called_once_with(self.ctx, 'EVENT_ID')
@ -167,7 +166,7 @@ class EventTest(base.SenlinTestCase):
mock_find.side_effect = exc.ResourceNotFound(type='event', id='BOGUS')
req = oreo.EventGetRequest(identity='BOGUS')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.event_get,
self.svc.event_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])

View File

@ -19,11 +19,11 @@ from senlin.common import consts
from senlin.common import exception as exc
from senlin.common.i18n import _
from senlin.common import utils as common_utils
from senlin.conductor import service
from senlin.engine.actions import base as action_mod
from senlin.engine import dispatcher
from senlin.engine import environment
from senlin.engine import node as node_mod
from senlin.engine import service
from senlin.objects import cluster as co
from senlin.objects import node as no
from senlin.objects import profile as po
@ -34,11 +34,10 @@ from senlin.tests.unit.common import utils
class NodeTest(base.SenlinTestCase):
def setUp(self):
super(NodeTest, self).setUp()
self.ctx = utils.dummy_context(project='node_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(no.Node, 'get_all')
def test_node_list(self, mock_get):
@ -49,7 +48,7 @@ class NodeTest(base.SenlinTestCase):
mock_get.return_value = [obj_1, obj_2]
req = orno.NodeListRequest()
result = self.eng.node_list(self.ctx, req.obj_to_primitive())
result = self.svc.node_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@ -66,7 +65,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeListRequest(cluster_id='MY_CLUSTER_NAME',
project_safe=True)
result = self.eng.node_list(self.ctx, req.obj_to_primitive())
result = self.svc.node_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_find.assert_called_once_with(self.ctx, 'MY_CLUSTER_NAME')
@ -85,7 +84,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeListRequest(status=['ACTIVE'], sort='status',
limit=123, marker=MARKER_UUID,
project_safe=True)
result = self.eng.node_list(self.ctx, req.obj_to_primitive())
result = self.svc.node_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_get.assert_called_once_with(self.ctx, sort='status', limit=123,
@ -100,7 +99,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeListRequest(cluster_id='BOGUS', project_safe=True)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_list,
self.svc.node_list,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -113,20 +112,20 @@ class NodeTest(base.SenlinTestCase):
mock_get.return_value = []
req = orno.NodeListRequest(project_safe=True)
result = self.eng.node_list(self.ctx, req.obj_to_primitive())
result = self.svc.node_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
mock_get.reset_mock()
req = orno.NodeListRequest(project_safe=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_list,
self.svc.node_list,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.Forbidden, ex.exc_info[0])
self.ctx.is_admin = True
req = orno.NodeListRequest(project_safe=False)
result = self.eng.node_list(self.ctx, req.obj_to_primitive())
result = self.svc.node_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=False)
mock_get.reset_mock()
@ -136,7 +135,7 @@ class NodeTest(base.SenlinTestCase):
mock_get.return_value = []
req = orno.NodeListRequest()
result = self.eng.node_list(self.ctx, req.obj_to_primitive())
result = self.svc.node_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@ -154,7 +153,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeCreateRequestBody(name='NODE1',
profile_id='PROFILE_NAME')
result = self.eng.node_create(self.ctx, req.obj_to_primitive())
result = self.svc.node_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar', 'action': 'ACTION_ID'}, result)
mock_profile.assert_called_once_with(self.ctx, 'PROFILE_NAME')
@ -211,7 +210,7 @@ class NodeTest(base.SenlinTestCase):
profile_id='PROFILE_NAME',
cluster_id='FAKE_CLUSTER')
result = self.eng.node_create(self.ctx, req.obj_to_primitive())
result = self.svc.node_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar', 'action': 'ACTION_ID'}, result)
mock_cluster.assert_called_once_with(self.ctx, 'FAKE_CLUSTER')
@ -272,7 +271,7 @@ class NodeTest(base.SenlinTestCase):
profile_id='PROFILE_NAME',
cluster_id='FAKE_CLUSTER')
result = self.eng.node_create(self.ctx, req.obj_to_primitive())
result = self.svc.node_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar', 'action': 'ACTION_ID'}, result)
mock_cluster.assert_called_once_with(self.ctx, 'FAKE_CLUSTER')
@ -317,7 +316,7 @@ class NodeTest(base.SenlinTestCase):
profile_id='PROFILE_NAME')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.svc.node_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -332,7 +331,7 @@ class NodeTest(base.SenlinTestCase):
profile_id='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.svc.node_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual("The specified profile 'Bogus' could not be "
@ -349,7 +348,7 @@ class NodeTest(base.SenlinTestCase):
cluster_id='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.svc.node_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -372,7 +371,7 @@ class NodeTest(base.SenlinTestCase):
cluster_id='FAKE_CLUSTER')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_create,
self.svc.node_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -392,7 +391,7 @@ class NodeTest(base.SenlinTestCase):
mock_find.return_value = x_obj
req = orno.NodeGetRequest(identity='NODE1', show_details=False)
result = self.eng.node_get(self.ctx, req.obj_to_primitive())
result = self.svc.node_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'NODE1')
@ -409,7 +408,7 @@ class NodeTest(base.SenlinTestCase):
mock_load.return_value = x_node
req = orno.NodeGetRequest(identity='NODE1', show_details=True)
result = self.eng.node_get(self.ctx, req.obj_to_primitive())
result = self.svc.node_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar', 'details': {'info': 'blahblah'}},
result)
@ -424,7 +423,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeGetRequest(identity='Bogus', show_details=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_get,
self.svc.node_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -439,7 +438,7 @@ class NodeTest(base.SenlinTestCase):
mock_find.return_value = x_obj
req = orno.NodeGetRequest(identity='NODE1', show_details=True)
result = self.eng.node_get(self.ctx, req.obj_to_primitive())
result = self.svc.node_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'NODE1')
@ -462,7 +461,7 @@ class NodeTest(base.SenlinTestCase):
metadata={'foo1': 'bar1'})
# all properties changed except profile id
result = self.eng.node_update(self.ctx, req.obj_to_primitive())
result = self.svc.node_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar', 'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -507,7 +506,7 @@ class NodeTest(base.SenlinTestCase):
role='ROLE1',
metadata={'KEY': 'VALUE'},
profile_id='NEW_PROFILE')
result = self.eng.node_update(self.ctx, req.obj_to_primitive())
result = self.svc.node_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar', 'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -532,7 +531,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeUpdateRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_update, self.ctx,
self.svc.node_update, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -550,7 +549,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeUpdateRequest(identity='FAKE_NODE',
profile_id='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_update,
self.svc.node_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -571,7 +570,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeUpdateRequest(identity='FAKE_NODE',
profile_id='NEW_PROFILE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_update,
self.svc.node_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -596,7 +595,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeUpdateRequest(identity='FAKE_NODE',
profile_id='OLD_PROFILE_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_update,
self.svc.node_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -617,7 +616,7 @@ class NodeTest(base.SenlinTestCase):
# no property has been specified for update
req = orno.NodeUpdateRequest(identity='FAKE_NODE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_update,
self.svc.node_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -635,7 +634,7 @@ class NodeTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orno.NodeDeleteRequest(identity='FAKE_NODE', force=False)
result = self.eng.node_delete(self.ctx, req.obj_to_primitive())
result = self.svc.node_delete(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -653,7 +652,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeDeleteRequest(identity='Bogus', force=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_delete, self.ctx,
self.svc.node_delete, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -669,7 +668,7 @@ class NodeTest(base.SenlinTestCase):
mock_find.return_value = fake_node
req = orno.NodeDeleteRequest(identity='BUSY', force=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_delete,
self.svc.node_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ActionInProgress, ex.exc_info[0])
@ -684,7 +683,7 @@ class NodeTest(base.SenlinTestCase):
mock_find.return_value = node
req = orno.NodeDeleteRequest(identity='node1', force=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_delete,
self.svc.node_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceInUse, ex.exc_info[0])
self.assertEqual("The node 'node1' cannot be deleted: still depended "
@ -705,7 +704,7 @@ class NodeTest(base.SenlinTestCase):
mock_action.return_value = 'ACTION_ID'
req = orno.NodeDeleteRequest(identity='FAKE_NODE', force=True)
result = self.eng.node_delete(self.ctx, req.obj_to_primitive())
result = self.svc.node_delete(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_with(self.ctx, 'FAKE_NODE')
@ -732,7 +731,7 @@ class NodeTest(base.SenlinTestCase):
mock_adopt.return_value = {'prop': 'value'}
mock_profile.return_value = FakeProfile
c, s = self.eng._node_adopt_preview(self.ctx, req)
c, s = self.svc._node_adopt_preview(self.ctx, req)
req.obj_set_defaults.assert_called_once_with()
mock_profile.assert_called_once_with("TestProfile-1.0")
@ -762,7 +761,7 @@ class NodeTest(base.SenlinTestCase):
)
ex = self.assertRaises(exc.BadRequest,
self.eng._node_adopt_preview,
self.svc._node_adopt_preview,
self.ctx, req)
req.obj_set_defaults.assert_called_once_with()
@ -787,7 +786,7 @@ class NodeTest(base.SenlinTestCase):
}
ex = self.assertRaises(exc.ProfileOperationFailed,
self.eng._node_adopt_preview,
self.svc._node_adopt_preview,
self.ctx, req)
req.obj_set_defaults.assert_called_once_with()
@ -798,28 +797,28 @@ class NodeTest(base.SenlinTestCase):
self.assertEqual('502: something is bad', six.text_type(ex))
@mock.patch.object(service.EngineService, '_node_adopt_preview')
@mock.patch.object(service.ConductorService, '_node_adopt_preview')
def test_node_adopt_preview(self, mock_preview):
spec = {'foo': 'bar'}
mock_preview.return_value = mock.Mock(), spec
req = orno.NodeAdoptPreviewRequest(identity='FAKE_ID',
type='FAKE_TYPE')
res = self.eng.node_adopt_preview(self.ctx, req.obj_to_primitive())
res = self.svc.node_adopt_preview(self.ctx, req.obj_to_primitive())
self.assertEqual({'node_preview': {'foo': 'bar'}}, res)
mock_preview.assert_called_once_with(self.ctx, mock.ANY)
self.assertIsInstance(mock_preview.call_args[0][1],
orno.NodeAdoptPreviewRequest)
@mock.patch.object(service.EngineService, '_node_adopt_preview')
@mock.patch.object(service.ConductorService, '_node_adopt_preview')
def test_node_adopt_preview_with_exception(self, mock_preview):
mock_preview.side_effect = exc.BadRequest(msg="boom")
req = orno.NodeAdoptPreviewRequest(identity='FAKE_ID',
type='FAKE_TYPE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_adopt_preview,
self.svc.node_adopt_preview,
self.ctx, req.obj_to_primitive())
mock_preview.assert_called_once_with(self.ctx, mock.ANY)
@ -829,7 +828,7 @@ class NodeTest(base.SenlinTestCase):
self.assertEqual('boom.', six.text_type(ex.exc_info[1]))
@mock.patch.object(no.Node, 'create')
@mock.patch.object(service.EngineService, '_node_adopt_preview')
@mock.patch.object(service.ConductorService, '_node_adopt_preview')
def test_node_adopt(self, mock_preview, mock_create):
class FakeProfile(object):
@ -845,7 +844,7 @@ class NodeTest(base.SenlinTestCase):
fake_node.to_dict = mock.Mock(return_value={'attr': 'value'})
mock_create.return_value = fake_node
res = self.eng.node_adopt(self.ctx, req.obj_to_primitive())
res = self.svc.node_adopt(self.ctx, req.obj_to_primitive())
self.assertEqual({'attr': 'value'}, res)
mock_preview.assert_called_once_with(self.ctx, mock.ANY)
@ -880,7 +879,7 @@ class NodeTest(base.SenlinTestCase):
mock_get.return_value = mock.Mock()
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_adopt,
self.svc.node_adopt,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -888,13 +887,13 @@ class NodeTest(base.SenlinTestCase):
six.text_type(ex.exc_info[1]))
@mock.patch.object(no.Node, 'create')
@mock.patch.object(service.EngineService, '_node_adopt_preview')
@mock.patch.object(service.ConductorService, '_node_adopt_preview')
def test_node_adopt_failed_preview(self, mock_preview, mock_create):
req = orno.NodeAdoptRequest(identity='FAKE_ID', type='FAKE_TYPE')
mock_preview.side_effect = exc.BadRequest(msg='boom')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_adopt,
self.svc.node_adopt,
self.ctx, req.obj_to_primitive())
mock_preview.assert_called_once_with(self.ctx, mock.ANY)
@ -914,7 +913,7 @@ class NodeTest(base.SenlinTestCase):
params = {'k1': 'v1'}
req = orno.NodeCheckRequest(identity='FAKE_NODE', params=params)
result = self.eng.node_check(self.ctx, req.obj_to_primitive())
result = self.svc.node_check(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -933,7 +932,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeCheckRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_check,
self.svc.node_check,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -951,7 +950,7 @@ class NodeTest(base.SenlinTestCase):
params = {'operation': 'REBOOT'}
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
result = self.eng.node_recover(self.ctx, req.obj_to_primitive())
result = self.svc.node_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -973,7 +972,7 @@ class NodeTest(base.SenlinTestCase):
params = {'check': True, 'operation': 'REBUILD'}
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
result = self.eng.node_recover(self.ctx, req.obj_to_primitive())
result = self.svc.node_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -996,7 +995,7 @@ class NodeTest(base.SenlinTestCase):
params = {'delete_timeout': 20, 'operation': 'RECREATE'}
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
result = self.eng.node_recover(self.ctx, req.obj_to_primitive())
result = self.svc.node_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -1022,7 +1021,7 @@ class NodeTest(base.SenlinTestCase):
params = {'force_recreate': True, 'operation': 'reboot',
'operation_params': {'type': 'soft'}}
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
result = self.eng.node_recover(self.ctx, req.obj_to_primitive())
result = self.svc.node_recover(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -1043,7 +1042,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeRecoverRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_recover,
self.svc.node_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -1060,7 +1059,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_recover,
self.svc.node_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1079,7 +1078,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_recover,
self.svc.node_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1100,7 +1099,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeRecoverRequest(identity='FAKE_NODE', params=params)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_recover,
self.svc.node_recover,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1128,7 +1127,7 @@ class NodeTest(base.SenlinTestCase):
operation='dance',
params=params)
result = self.eng.node_op(self.ctx, req.obj_to_primitive())
result = self.svc.node_op(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_NODE')
@ -1150,7 +1149,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeOperationRequest(identity='Bogus', operation='dance',
params={})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_op,
self.svc.node_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -1172,7 +1171,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeOperationRequest(identity='node1', operation='swim',
params={})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_op,
self.svc.node_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -1197,7 +1196,7 @@ class NodeTest(base.SenlinTestCase):
req = orno.NodeOperationRequest(identity='node1', operation='dance',
params={'style': 'tango'})
ex = self.assertRaises(rpc.ExpectedException,
self.eng.node_op,
self.svc.node_op,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])

View File

@ -19,8 +19,8 @@ import six
from senlin.common import exception as exc
from senlin.common.i18n import _
from senlin.conductor import service
from senlin.engine import environment
from senlin.engine import service
from senlin.objects import policy as po
from senlin.objects.requests import policies as orpo
from senlin.policies import base as pb
@ -30,11 +30,10 @@ from senlin.tests.unit import fakes
class PolicyTest(base.SenlinTestCase):
def setUp(self):
super(PolicyTest, self).setUp()
self.ctx = utils.dummy_context(project='policy_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
def _setup_fakes(self):
"""Set up fake policy for the purpose of testing.
@ -61,7 +60,7 @@ class PolicyTest(base.SenlinTestCase):
mock_get.return_value = [x_obj_1, x_obj_2]
req = orpo.PolicyListRequest(project_safe=True)
result = self.eng.policy_list(self.ctx, req.obj_to_primitive())
result = self.svc.policy_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@ -79,7 +78,7 @@ class PolicyTest(base.SenlinTestCase):
}
req = orpo.PolicyListRequest(**params)
result = self.eng.policy_list(self.ctx, req.obj_to_primitive())
result = self.svc.policy_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(
@ -92,7 +91,7 @@ class PolicyTest(base.SenlinTestCase):
self._setup_fakes()
req = orpo.PolicyCreateRequestBody(name='Fake', spec=self.spec)
result = self.eng.policy_create(self.ctx, req.obj_to_primitive())
result = self.svc.policy_create(self.ctx, req.obj_to_primitive())
self.assertEqual('Fake', result['name'])
self.assertEqual('TestPolicy-1.0', result['type'])
@ -115,7 +114,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyCreateRequestBody(name='FAKE_NAME', spec=spec)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_create,
self.svc.policy_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual("A policy named 'FAKE_NAME' already exists.",
@ -134,7 +133,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyCreateRequestBody(name='Fake', spec=spec)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_create,
self.svc.policy_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -151,7 +150,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyCreateRequestBody(name='Fake', spec=spec)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_create,
self.svc.policy_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ESchema, ex.exc_info[0])
self.assertEqual("Required spec item 'KEY2' not provided",
@ -168,7 +167,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyCreateRequestBody(name='Fake', spec=spec)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_create,
self.svc.policy_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
self.assertEqual("The specified KEY2 'value3' could not be "
@ -182,7 +181,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyCreateRequestBody(name='Fake', spec=self.spec)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_create,
self.svc.policy_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
self.assertEqual('BOOM', six.text_type(ex.exc_info[1]))
@ -211,7 +210,7 @@ class PolicyTest(base.SenlinTestCase):
body = orpo.PolicyValidateRequestBody(spec=self.spec)
resp = self.eng.policy_validate(self.ctx, body.obj_to_primitive())
resp = self.svc.policy_validate(self.ctx, body.obj_to_primitive())
self.assertEqual(expected_resp, resp)
def test_policy_validate_failed(self):
@ -222,7 +221,7 @@ class PolicyTest(base.SenlinTestCase):
body = orpo.PolicyValidateRequestBody(spec=self.spec)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_validate,
self.svc.policy_validate,
self.ctx, body.obj_to_primitive())
self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
self.assertEqual('BOOM',
@ -235,7 +234,7 @@ class PolicyTest(base.SenlinTestCase):
x_obj.to_dict.return_value = {'foo': 'bar'}
req = orpo.PolicyGetRequest(identity='FAKE_POLICY')
result = self.eng.policy_get(self.ctx, req.obj_to_primitive())
result = self.svc.policy_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_POLICY')
@ -247,7 +246,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyGetRequest(identity='POLICY')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_get,
self.svc.policy_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -269,7 +268,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyUpdateRequest(**request)
result = self.eng.policy_update(self.ctx, req.obj_to_primitive())
result = self.svc.policy_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'FAKE')
mock_load.assert_called_once_with(self.ctx, db_policy=x_obj)
@ -287,7 +286,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyUpdateRequest(**request)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_update,
self.svc.policy_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -313,7 +312,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyUpdateRequest(**request)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_update,
self.svc.policy_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -332,7 +331,7 @@ class PolicyTest(base.SenlinTestCase):
mock_delete.return_value = None
req = orpo.PolicyDeleteRequest(identity='POLICY_ID')
result = self.eng.policy_delete(self.ctx, req.obj_to_primitive())
result = self.svc.policy_delete(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
self.assertEqual('POLICY_ID', req.identity)
@ -346,7 +345,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyDeleteRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_delete, self.ctx,
self.svc.policy_delete, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -365,7 +364,7 @@ class PolicyTest(base.SenlinTestCase):
req = orpo.PolicyDeleteRequest(identity='POLICY_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_delete, self.ctx,
self.svc.policy_delete, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceInUse, ex.exc_info[0])

View File

@ -15,19 +15,18 @@ from oslo_messaging.rpc import dispatcher as rpc
import six
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine import environment
from senlin.engine import service
from senlin.objects.requests import policy_type as orpt
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class PolicyTypeTest(base.SenlinTestCase):
def setUp(self):
super(PolicyTypeTest, self).setUp()
self.ctx = utils.dummy_context(project='policy_type_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(environment, 'global_env')
def test_policy_type_list(self, mock_env):
@ -36,7 +35,7 @@ class PolicyTypeTest(base.SenlinTestCase):
mock_env.return_value = x_env
req = orpt.PolicyTypeListRequest()
types = self.eng.policy_type_list(self.ctx, req.obj_to_primitive())
types = self.svc.policy_type_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'foo': 'bar'}], types)
mock_env.assert_called_once_with()
@ -53,7 +52,7 @@ class PolicyTypeTest(base.SenlinTestCase):
mock_env.return_value = x_env
req = orpt.PolicyTypeGetRequest(type_name='FAKE_TYPE')
result = self.eng.policy_type_get(self.ctx, req.obj_to_primitive())
result = self.svc.policy_type_get(self.ctx, req.obj_to_primitive())
self.assertEqual(
{
@ -76,7 +75,7 @@ class PolicyTypeTest(base.SenlinTestCase):
req = orpt.PolicyTypeGetRequest(type_name='FAKE_TYPE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.policy_type_get,
self.svc.policy_type_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])

View File

@ -15,19 +15,18 @@ from oslo_messaging.rpc import dispatcher as rpc
import six
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine import environment
from senlin.engine import service
from senlin.objects.requests import profile_type as vorp
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class ProfileTypeTest(base.SenlinTestCase):
def setUp(self):
super(ProfileTypeTest, self).setUp()
self.ctx = utils.dummy_context(project='profile_type_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(environment, 'global_env')
def test_profile_type_list(self, mock_env):
@ -36,7 +35,7 @@ class ProfileTypeTest(base.SenlinTestCase):
mock_env.return_value = x_env
req = vorp.ProfileTypeListRequest()
types = self.eng.profile_type_list(self.ctx, req.obj_to_primitive())
types = self.svc.profile_type_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'foo': 'bar'}], types)
mock_env.assert_called_once_with()
@ -53,7 +52,7 @@ class ProfileTypeTest(base.SenlinTestCase):
mock_env.return_value = x_env
req = vorp.ProfileTypeGetRequest(type_name='FAKE_TYPE')
result = self.eng.profile_type_get(self.ctx, req.obj_to_primitive())
result = self.svc.profile_type_get(self.ctx, req.obj_to_primitive())
self.assertEqual(
{
@ -76,7 +75,7 @@ class ProfileTypeTest(base.SenlinTestCase):
req = vorp.ProfileTypeGetRequest(type_name='FAKE_TYPE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_type_get,
self.svc.profile_type_get,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -94,7 +93,7 @@ class ProfileTypeTest(base.SenlinTestCase):
mock_env.return_value = x_env
req = vorp.ProfileTypeOpListRequest(type_name='FAKE_TYPE')
ops = self.eng.profile_type_ops(self.ctx, req.obj_to_primitive())
ops = self.svc.profile_type_ops(self.ctx, req.obj_to_primitive())
self.assertEqual({'operations': {'foo': 'bar'}}, ops)
mock_env.assert_called_once_with()
@ -110,7 +109,7 @@ class ProfileTypeTest(base.SenlinTestCase):
req = vorp.ProfileTypeOpListRequest(type_name='FAKE_TYPE')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_type_ops,
self.svc.profile_type_ops,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])

View File

@ -19,8 +19,8 @@ from oslo_utils import uuidutils
import six
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine import environment
from senlin.engine import service
from senlin.objects import profile as po
from senlin.objects.requests import profiles as vorp
from senlin.profiles import base as pb
@ -30,11 +30,10 @@ from senlin.tests.unit import fakes
class ProfileTest(base.SenlinTestCase):
def setUp(self):
super(ProfileTest, self).setUp()
self.ctx = utils.dummy_context(project='profile_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
def _setup_fakes(self):
"""Set up fake profile for the purpose of testing.
@ -64,7 +63,7 @@ class ProfileTest(base.SenlinTestCase):
mock_get.return_value = [x_obj_1, x_obj_2]
req = vorp.ProfileListRequest(project_safe=True)
result = self.eng.profile_list(self.ctx, req.obj_to_primitive())
result = self.svc.profile_list(self.ctx, req.obj_to_primitive())
self.assertEqual([{'k': 'v1'}, {'k': 'v2'}], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
@ -83,7 +82,7 @@ class ProfileTest(base.SenlinTestCase):
}
req = vorp.ProfileListRequest(**params)
result = self.eng.profile_list(self.ctx, req.obj_to_primitive())
result = self.svc.profile_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, limit=10, marker=marker,
@ -102,7 +101,7 @@ class ProfileTest(base.SenlinTestCase):
metadata={'foo': 'bar'})
req = vorp.ProfileCreateRequest(profile=body)
result = self.eng.profile_create(self.ctx, req.obj_to_primitive())
result = self.svc.profile_create(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
@ -123,7 +122,7 @@ class ProfileTest(base.SenlinTestCase):
body = vorp.ProfileCreateRequestBody(name='FAKE_NAME', spec=spec)
req = vorp.ProfileCreateRequest(profile=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_create,
self.svc.profile_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual("A profile named 'FAKE_NAME' already exists.",
@ -139,7 +138,7 @@ class ProfileTest(base.SenlinTestCase):
req = vorp.ProfileCreateRequest(profile=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_create,
self.svc.profile_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -153,7 +152,7 @@ class ProfileTest(base.SenlinTestCase):
body = vorp.ProfileCreateRequestBody(name='foo', spec=self.spec)
req = vorp.ProfileCreateRequest(profile=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_create,
self.svc.profile_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
@ -187,7 +186,7 @@ class ProfileTest(base.SenlinTestCase):
body = vorp.ProfileValidateRequestBody(spec=self.spec)
request = vorp.ProfileValidateRequest(profile=body)
resp = self.eng.profile_validate(self.ctx, request.obj_to_primitive())
resp = self.svc.profile_validate(self.ctx, request.obj_to_primitive())
self.assertEqual(expected_resp, resp)
@ -201,7 +200,7 @@ class ProfileTest(base.SenlinTestCase):
request = vorp.ProfileValidateRequest(profile=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_validate,
self.svc.profile_validate,
self.ctx, request.obj_to_primitive())
self.assertEqual(exc.InvalidSpec, ex.exc_info[0])
self.assertEqual('BOOM',
@ -215,7 +214,7 @@ class ProfileTest(base.SenlinTestCase):
req = vorp.ProfileGetRequest(identity='FAKE_PROFILE')
project_safe = not self.ctx.is_admin
result = self.eng.profile_get(self.ctx, req.obj_to_primitive())
result = self.svc.profile_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(
@ -227,7 +226,7 @@ class ProfileTest(base.SenlinTestCase):
id='Bogus')
req = vorp.ProfileGetRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_get, self.ctx,
self.svc.profile_get, self.ctx,
req.obj_to_primitive())
project_safe = not self.ctx.is_admin
@ -252,7 +251,7 @@ class ProfileTest(base.SenlinTestCase):
req_body = vorp.ProfileUpdateRequestBody(**params)
req = vorp.ProfileUpdateRequest(identity='PID', profile=req_body)
result = self.eng.profile_update(self.ctx, req.obj_to_primitive())
result = self.svc.profile_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'PID')
mock_load.assert_called_once_with(self.ctx, profile=x_obj)
@ -274,7 +273,7 @@ class ProfileTest(base.SenlinTestCase):
req_body = vorp.ProfileUpdateRequestBody(**params)
req = vorp.ProfileUpdateRequest(identity='PID', profile=req_body)
result = self.eng.profile_update(self.ctx, req.obj_to_primitive())
result = self.svc.profile_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'PID')
mock_load.assert_called_once_with(self.ctx, profile=x_obj)
@ -292,7 +291,7 @@ class ProfileTest(base.SenlinTestCase):
req = vorp.ProfileUpdateRequest(identity='Bogus', profile=req_body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_update,
self.svc.profile_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -314,7 +313,7 @@ class ProfileTest(base.SenlinTestCase):
req = vorp.ProfileUpdateRequest(identity='PID', profile=req_body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_update,
self.svc.profile_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -334,7 +333,7 @@ class ProfileTest(base.SenlinTestCase):
mock_delete.return_value = None
req = vorp.ProfileDeleteRequest(identity='PROFILE_ID')
result = self.eng.profile_delete(self.ctx, req.obj_to_primitive())
result = self.svc.profile_delete(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_find.assert_called_once_with(self.ctx, 'PROFILE_ID')
@ -347,7 +346,7 @@ class ProfileTest(base.SenlinTestCase):
req = vorp.ProfileDeleteRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_delete, self.ctx,
self.svc.profile_delete, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -366,7 +365,7 @@ class ProfileTest(base.SenlinTestCase):
req = vorp.ProfileDeleteRequest(identity='PROFILE_ID')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.profile_delete,
self.svc.profile_delete,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceInUse, ex.exc_info[0])

View File

@ -17,8 +17,8 @@ import six
from senlin.common import consts
from senlin.common import exception as exc
from senlin.conductor import service
from senlin.engine.receivers import base as rb
from senlin.engine import service
from senlin.objects import cluster as co
from senlin.objects import receiver as ro
from senlin.objects.requests import receivers as orro
@ -27,11 +27,10 @@ from senlin.tests.unit.common import utils
class ReceiverTest(base.SenlinTestCase):
def setUp(self):
super(ReceiverTest, self).setUp()
self.ctx = utils.dummy_context(project='receiver_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(ro.Receiver, 'get_all')
def test_receiver_list(self, mock_get):
@ -40,7 +39,7 @@ class ReceiverTest(base.SenlinTestCase):
mock_get.return_value = [fake_obj]
req = orro.ReceiverListRequest()
result = self.eng.receiver_list(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_list(self.ctx, req.obj_to_primitive())
self.assertIsInstance(result, list)
self.assertEqual([{'FOO': 'BAR'}], result)
@ -58,7 +57,7 @@ class ReceiverTest(base.SenlinTestCase):
action=['CLUSTER_RESIZE'],
cluster_id=['123abc'],
user=['user123'])
result = self.eng.receiver_list(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_list(self.ctx, req.obj_to_primitive())
self.assertIsInstance(result, list)
self.assertEqual([{'FOO': 'BAR'}], result)
@ -76,19 +75,19 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverListRequest(project_safe=False)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_list,
self.svc.receiver_list,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.Forbidden, ex.exc_info[0])
self.ctx.is_admin = True
result = self.eng.receiver_list(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=False)
mock_get.reset_mock()
req = orro.ReceiverListRequest(project_safe=True)
result = self.eng.receiver_list(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_list(self.ctx, req.obj_to_primitive())
self.assertEqual([], result)
mock_get.assert_called_once_with(self.ctx, project_safe=True)
mock_get.reset_mock()
@ -110,7 +109,7 @@ class ReceiverTest(base.SenlinTestCase):
name='r1', type=consts.RECEIVER_WEBHOOK, cluster_id='C1',
action=consts.CLUSTER_RESIZE)
result = self.eng.receiver_create(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_create(self.ctx, req.obj_to_primitive())
self.assertIsInstance(result, dict)
self.assertEqual('FAKE_RECEIVER', result['id'])
@ -126,7 +125,7 @@ class ReceiverTest(base.SenlinTestCase):
name='r1', type=consts.RECEIVER_WEBHOOK, cluster_id='C1',
action=consts.CLUSTER_RESIZE, params={'FOO': 'BAR'})
self.eng.receiver_create(self.ctx, req.obj_to_primitive())
self.svc.receiver_create(self.ctx, req.obj_to_primitive())
mock_create.assert_called_once_with(
self.ctx, 'webhook', fake_cluster, consts.CLUSTER_RESIZE,
name='r1', user=self.ctx.user_id, project=self.ctx.project_id,
@ -141,7 +140,7 @@ class ReceiverTest(base.SenlinTestCase):
name='r1', type=consts.RECEIVER_MESSAGE)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.svc.receiver_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -156,7 +155,7 @@ class ReceiverTest(base.SenlinTestCase):
action=consts.CLUSTER_RESIZE)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.svc.receiver_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -173,7 +172,7 @@ class ReceiverTest(base.SenlinTestCase):
action=consts.CLUSTER_CREATE)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.svc.receiver_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -191,7 +190,7 @@ class ReceiverTest(base.SenlinTestCase):
action=consts.CLUSTER_RESIZE)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.svc.receiver_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.Forbidden, ex.exc_info[0])
@ -204,7 +203,7 @@ class ReceiverTest(base.SenlinTestCase):
# an admin can do this
self.ctx.is_admin = True
result = self.eng.receiver_create(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_create(self.ctx, req.obj_to_primitive())
self.assertIsInstance(result, dict)
@mock.patch.object(co.Cluster, 'find')
@ -220,7 +219,7 @@ class ReceiverTest(base.SenlinTestCase):
for req in [req1, req2]:
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.svc.receiver_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual("Cluster identity is required for creating "
@ -239,7 +238,7 @@ class ReceiverTest(base.SenlinTestCase):
for req in [req1, req2]:
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_create,
self.svc.receiver_create,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
self.assertEqual("Action name is required for creating webhook "
@ -255,7 +254,7 @@ class ReceiverTest(base.SenlinTestCase):
mock_create.return_value = fake_receiver
req = orro.ReceiverCreateRequestBody(name='r1', type='message')
result = self.eng.receiver_create(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_create(self.ctx, req.obj_to_primitive())
self.assertIsInstance(result, dict)
self.assertEqual('FAKE_RECEIVER', result['id'])
@ -270,7 +269,7 @@ class ReceiverTest(base.SenlinTestCase):
fake_obj.to_dict.return_value = {'FOO': 'BAR'}
req = orro.ReceiverGetRequest(identity='FAKE_ID')
res = self.eng.receiver_get(self.ctx, req.obj_to_primitive())
res = self.svc.receiver_get(self.ctx, req.obj_to_primitive())
self.assertEqual({'FOO': 'BAR'}, res)
mock_find.assert_called_once_with(self.ctx, 'FAKE_ID')
@ -281,7 +280,7 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverGetRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_get, self.ctx,
self.svc.receiver_get, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -301,7 +300,7 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverUpdateRequest(**params)
result = self.eng.receiver_update(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_update(self.ctx, req.obj_to_primitive())
self.assertEqual({'foo': 'bar'}, result)
mock_find.assert_called_once_with(self.ctx, 'PID')
mock_load.assert_called_once_with(self.ctx, receiver_obj=x_obj)
@ -318,7 +317,7 @@ class ReceiverTest(base.SenlinTestCase):
kwargs = {'identity': 'Bogus', 'name': 'NEW_NAME'}
req = orro.ReceiverUpdateRequest(**kwargs)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_update,
self.svc.receiver_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -339,7 +338,7 @@ class ReceiverTest(base.SenlinTestCase):
kwargs = {'name': 'OLD_NAME', 'identity': 'PID'}
req = orro.ReceiverUpdateRequest(**kwargs)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_update,
self.svc.receiver_update,
self.ctx, req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])
@ -358,7 +357,7 @@ class ReceiverTest(base.SenlinTestCase):
mock_find.return_value = fake_obj
req = orro.ReceiverDeleteRequest(identity='FAKE_RECEIVER')
result = self.eng.receiver_delete(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_delete(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_RECEIVER')
@ -370,7 +369,7 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverDeleteRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_delete, self.ctx,
self.svc.receiver_delete, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -386,7 +385,7 @@ class ReceiverTest(base.SenlinTestCase):
mock_load.return_value = fake_receiver
req = orro.ReceiverNotifyRequest(identity='FAKE_RECEIVER')
result = self.eng.receiver_notify(self.ctx, req.obj_to_primitive())
result = self.svc.receiver_notify(self.ctx, req.obj_to_primitive())
self.assertIsNone(result)
mock_find.assert_called_once_with(self.ctx, 'FAKE_RECEIVER')
@ -400,7 +399,7 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverNotifyRequest(identity='Bogus')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_notify, self.ctx,
self.svc.receiver_notify, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.ResourceNotFound, ex.exc_info[0])
@ -413,7 +412,7 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverNotifyRequest(identity='FAKE_RECEIVER')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_notify, self.ctx,
self.svc.receiver_notify, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.Forbidden, ex.exc_info[0])
@ -427,6 +426,6 @@ class ReceiverTest(base.SenlinTestCase):
req = orro.ReceiverNotifyRequest(identity='FAKE_RECEIVER')
ex = self.assertRaises(rpc.ExpectedException,
self.eng.receiver_notify, self.ctx,
self.svc.receiver_notify, self.ctx,
req.obj_to_primitive())
self.assertEqual(exc.BadRequest, ex.exc_info[0])

View File

@ -16,9 +16,9 @@ import six
from senlin.common import consts
from senlin.common import exception
from senlin.conductor import service
from senlin.engine.actions import base as action_mod
from senlin.engine import dispatcher
from senlin.engine import service
from senlin.objects import cluster as co
from senlin.objects import receiver as ro
from senlin.objects.requests import webhooks as vorw
@ -27,11 +27,10 @@ from senlin.tests.unit.common import utils
class WebhookTest(base.SenlinTestCase):
def setUp(self):
super(WebhookTest, self).setUp()
self.ctx = utils.dummy_context(project='webhook_test_project')
self.eng = service.EngineService('host-a', 'topic-a')
self.svc = service.ConductorService('host-a', 'topic-a')
@mock.patch.object(dispatcher, 'start_action')
@mock.patch.object(action_mod.Action, 'create')
@ -49,7 +48,7 @@ class WebhookTest(base.SenlinTestCase):
body = {'kee': 'vee'}
req = vorw.WebhookTriggerRequestParamsInBody(identity='FAKE_RECEIVER',
body=body)
res = self.eng.webhook_trigger(self.ctx, req.obj_to_primitive())
res = self.svc.webhook_trigger(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
@ -81,7 +80,7 @@ class WebhookTest(base.SenlinTestCase):
body = {}
req = vorw.WebhookTriggerRequestParamsInBody(identity='FAKE_RECEIVER',
body=body)
res = self.eng.webhook_trigger(self.ctx, req.obj_to_primitive())
res = self.svc.webhook_trigger(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
@ -105,7 +104,7 @@ class WebhookTest(base.SenlinTestCase):
body = None
req = vorw.WebhookTriggerRequestParamsInBody(identity='RRR', body=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.webhook_trigger, self.ctx,
self.svc.webhook_trigger, self.ctx,
req.obj_to_primitive())
self.assertEqual(exception.ResourceNotFound, ex.exc_info[0])
@ -125,7 +124,7 @@ class WebhookTest(base.SenlinTestCase):
body = None
req = vorw.WebhookTriggerRequestParamsInBody(identity='RRR', body=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.webhook_trigger, self.ctx,
self.svc.webhook_trigger, self.ctx,
req.obj_to_primitive())
self.assertEqual(exception.BadRequest, ex.exc_info[0])
@ -150,7 +149,7 @@ class WebhookTest(base.SenlinTestCase):
body = vorw.WebhookTriggerRequestBody(params={'kee': 'vee'})
req = vorw.WebhookTriggerRequest(identity='FAKE_RECEIVER',
body=body)
res = self.eng.webhook_trigger(self.ctx, req.obj_to_primitive())
res = self.svc.webhook_trigger(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
@ -182,7 +181,7 @@ class WebhookTest(base.SenlinTestCase):
body = vorw.WebhookTriggerRequestBody(params={})
req = vorw.WebhookTriggerRequest(identity='FAKE_RECEIVER',
body=body)
res = self.eng.webhook_trigger(self.ctx, req.obj_to_primitive())
res = self.svc.webhook_trigger(self.ctx, req.obj_to_primitive())
self.assertEqual({'action': 'ACTION_ID'}, res)
@ -205,7 +204,7 @@ class WebhookTest(base.SenlinTestCase):
body = vorw.WebhookTriggerRequestBody(params=None)
req = vorw.WebhookTriggerRequest(identity='RRR', body=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.webhook_trigger, self.ctx,
self.svc.webhook_trigger, self.ctx,
req.obj_to_primitive())
self.assertEqual(exception.ResourceNotFound, ex.exc_info[0])
@ -224,7 +223,7 @@ class WebhookTest(base.SenlinTestCase):
body = vorw.WebhookTriggerRequestBody(params=None)
req = vorw.WebhookTriggerRequest(identity='RRR', body=body)
ex = self.assertRaises(rpc.ExpectedException,
self.eng.webhook_trigger, self.ctx,
self.svc.webhook_trigger, self.ctx,
req.obj_to_primitive())
self.assertEqual(exception.BadRequest, ex.exc_info[0])

View File

@ -0,0 +1,168 @@
# 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 datetime
import eventlet
import mock
from oslo_config import cfg
import oslo_messaging
from oslo_utils import timeutils
from oslo_utils import uuidutils
from senlin.common import consts
from senlin.conductor import service
from senlin.objects.requests import build_info as vorb
from senlin.objects import service as service_obj
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class ConductorTest(base.SenlinTestCase):
def setUp(self):
super(ConductorTest, self).setUp()
self.context = utils.dummy_context()
self.service_id = '4db0a14c-dc10-4131-8ed6-7573987ce9b0'
self.tg = mock.Mock()
self.topic = consts.HEALTH_MANAGER_TOPIC
self.svc = service.ConductorService('HOST', self.topic)
self.svc.service_id = self.service_id
self.svc.tg = self.tg
def test_init(self):
self.assertEqual(self.service_id, self.svc.service_id)
self.assertEqual(self.tg, self.svc.tg)
self.assertEqual(self.topic, self.svc.topic)
@mock.patch.object(uuidutils, 'generate_uuid')
@mock.patch.object(oslo_messaging, 'get_rpc_server')
@mock.patch.object(service_obj.Service, 'create')
def test_service_start(self, mock_service_create, mock_rpc_server,
mock_uuid):
service_uuid = '4db0a14c-dc10-4131-8ed6-7573987ce9b1'
mock_uuid.return_value = service_uuid
self.svc.start()
mock_uuid.assert_called_once()
mock_service_create.assert_called_once()
self.svc.server.start.assert_called_once()
self.assertEqual(service_uuid, self.svc.service_id)
@mock.patch.object(service_obj.Service, 'delete')
def test_service_stop(self, mock_delete):
self.svc.server = mock.Mock()
self.svc.stop()
self.svc.server.stop.assert_called_once()
self.svc.server.wait.assert_called_once()
mock_delete.assert_called_once_with(self.service_id)
@mock.patch.object(service_obj.Service, 'delete')
def test_service_stop_not_yet_started(self, mock_delete):
self.svc.server = None
self.svc.stop()
mock_delete.assert_called_once_with(self.svc.service_id)
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_update(self, mock_update):
mock_update.return_value = mock.Mock()
self.svc.service_manage_report()
mock_update.assert_called_once_with(mock.ANY,
self.svc.service_id)
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_with_exception(self, mock_update):
mock_update.side_effect = Exception('blah')
self.svc.service_manage_report()
self.assertEqual(mock_update.call_count, 1)
def test_get_revision(self):
self.assertEqual(
cfg.CONF.revision['senlin_engine_revision'],
self.svc.get_revision(
self.context, vorb.GetRevisionRequest().obj_to_primitive()
)
)
class ConductorCleanupTest(base.SenlinTestCase):
def setUp(self):
super(ConductorCleanupTest, self).setUp()
self.service_id = '4db0a14c-dc10-4131-8ed6-7573987ce9b0'
self.topic = consts.HEALTH_MANAGER_TOPIC
self.svc = service.ConductorService('HOST', self.topic)
self.svc.service_id = self.service_id
@mock.patch.object(service_obj.Service, 'update')
def test_conductor_manage_report(self, mock_update):
cfg.CONF.set_override('periodic_interval', 0.1)
# start engine and verify that update is being called more than once
self.svc.start()
eventlet.sleep(0.6)
self.assertGreater(mock_update.call_count, 1)
self.svc.stop()
@mock.patch.object(service_obj.Service, 'update')
def test_conductor_manage_report_with_exception(self, mock_update):
cfg.CONF.set_override('periodic_interval', 0.1)
# start engine and verify that update is being called more than once
# even with the exception being thrown
mock_update.side_effect = Exception('blah')
self.svc.start()
eventlet.sleep(0.6)
self.assertGreater(mock_update.call_count, 1)
self.svc.stop()
@mock.patch.object(service_obj.Service, 'gc_by_engine')
@mock.patch.object(service_obj.Service, 'get_all')
@mock.patch.object(service_obj.Service, 'delete')
def test_service_manage_cleanup(self, mock_delete, mock_get_all, mock_gc):
delta = datetime.timedelta(seconds=2 * cfg.CONF.periodic_interval)
ages_a_go = timeutils.utcnow(True) - delta
mock_get_all.return_value = [{'id': 'foo', 'updated_at': ages_a_go}]
self.svc._service_manage_cleanup()
mock_delete.assert_called_once_with('foo')
mock_gc.assert_called_once_with('foo')
@mock.patch.object(service_obj.Service, 'get_all')
def test_service_manage_cleanup_without_exception(self, mock_get_all):
cfg.CONF.set_override('periodic_interval', 0.1)
# start engine and verify that get_all is being called more than once
self.svc.start()
eventlet.sleep(0.6)
self.assertGreater(mock_get_all.call_count, 1)
self.svc.stop()
@mock.patch.object(service_obj.Service, 'get_all')
def test_service_manage_cleanup_with_exception(self, mock_get_all):
cfg.CONF.set_override('periodic_interval', 0.1)
# start engine and verify that get_all is being called more than once
# even with the exception being thrown
mock_get_all.side_effect = Exception('blah')
self.svc.start()
eventlet.sleep(0.6)
self.assertGreater(mock_get_all.call_count, 1)
self.svc.stop()

View File

@ -9,13 +9,12 @@
# 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 eventlet
import mock
from senlin.engine.actions import base as ab
from senlin.engine.actions import cluster_action as ca
from senlin.engine import cluster as cm
from senlin.engine import scheduler
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
@ -77,7 +76,7 @@ class ClusterActionWaitTest(base.SenlinTestCase):
self.ctx = utils.dummy_context()
@mock.patch.object(cm.Cluster, 'load')
@mock.patch.object(scheduler, 'reschedule')
@mock.patch.object(eventlet, 'sleep')
def test_wait_dependents(self, mock_reschedule, mock_load):
action = ca.ClusterAction('ID', 'ACTION', self.ctx)
action.id = 'FAKE_ID'

View File

@ -1,163 +0,0 @@
# 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 mock
from oslo_config import cfg
from oslo_context import context
import oslo_messaging
from senlin.common import consts
from senlin.common import messaging
from senlin.engine import dispatcher
from senlin.engine import scheduler
from senlin.engine import service
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class TestDispatcher(base.SenlinTestCase):
def setUp(self):
super(TestDispatcher, self).setUp()
self.context = utils.dummy_context()
self.thm = scheduler.ThreadGroupManager()
self.svc = service.EngineService('HOST', 'TOPIC')
self.svc.engine_id = '1234'
def test_init(self):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
self.assertEqual(self.thm, disp.TG)
self.assertEqual('1234', disp.engine_id)
self.assertEqual('TOPIC', disp.topic)
self.assertEqual('1', disp.version)
@mock.patch.object(messaging, 'get_rpc_server')
@mock.patch.object(oslo_messaging, 'Target')
def test_start(self, mock_target, mock_server):
mock_server.return_value = mock.Mock()
mock_target.return_value = mock.Mock()
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
disp.start()
mock_target.assert_called_once_with(server='1234', topic='TOPIC',
version='1')
the_target = mock_target.return_value
mock_server.assert_called_once_with(the_target, disp)
the_server = mock_server.return_value
the_server.start.assert_called_once_with()
def test_listening(self):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
result = disp.listening(self.context)
self.assertTrue(result)
@mock.patch.object(scheduler.ThreadGroupManager, 'start_action')
def test_start_action(self, mock_start):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
disp.start_action(self.context, action_id='FOO')
mock_start.assert_called_once_with('1234', 'FOO')
mock_start.reset_mock()
disp.start_action(self.context)
mock_start.assert_called_once_with('1234', None)
@mock.patch.object(scheduler.ThreadGroupManager, 'cancel_action')
def test_cancel_action(self, mock_cancel):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
disp.cancel_action(self.context, action_id='FOO')
mock_cancel.assert_called_once_with('FOO')
@mock.patch.object(scheduler.ThreadGroupManager, 'suspend_action')
def test_suspend_action(self, mock_suspend):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
disp.suspend_action(self.context, action_id='FOO')
mock_suspend.assert_called_once_with('FOO')
@mock.patch.object(scheduler.ThreadGroupManager, 'resume_action')
def test_resume_action(self, mock_resume):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
disp.resume_action(self.context, action_id='FOO')
mock_resume.assert_called_once_with('FOO')
@mock.patch.object(scheduler.ThreadGroupManager, 'stop')
def test_stop(self, mock_stop):
disp = dispatcher.Dispatcher(self.svc, 'TOPIC', '1', self.thm)
disp.stop()
mock_stop.assert_called_once_with(True)
@mock.patch.object(context, 'get_current')
@mock.patch.object(messaging, 'get_rpc_client')
def test_notify_broadcast(self, mock_rpc, mock_get_current):
cfg.CONF.set_override('host', 'HOSTNAME')
fake_ctx = mock.Mock()
mock_get_current.return_value = fake_ctx
mock_rpc.return_value = mock.Mock()
dispatcher.notify('METHOD')
mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME')
mock_client = mock_rpc.return_value
mock_client.prepare.assert_called_once_with(fanout=True)
mock_context = mock_client.prepare.return_value
mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
@mock.patch.object(context, 'get_current')
@mock.patch.object(messaging, 'get_rpc_client')
def test_notify_single_server(self, mock_rpc, mock_get_current):
cfg.CONF.set_override('host', 'HOSTNAME')
fake_ctx = mock.Mock()
mock_get_current.return_value = fake_ctx
mock_rpc.return_value = mock.Mock()
result = dispatcher.notify('METHOD', 'FAKE_ENGINE')
self.assertTrue(result)
mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME')
mock_client = mock_rpc.return_value
mock_client.prepare.assert_called_once_with(server='FAKE_ENGINE')
mock_context = mock_client.prepare.return_value
mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
@mock.patch.object(messaging, 'get_rpc_client')
def test_notify_timeout(self, mock_rpc):
cfg.CONF.set_override('host', 'HOSTNAME')
mock_rpc.return_value = mock.Mock()
mock_client = mock_rpc.return_value
mock_context = mock_client.prepare.return_value
mock_context.cast.side_effect = oslo_messaging.MessagingTimeout
result = dispatcher.notify('METHOD')
self.assertFalse(result)
mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME')
mock_client.prepare.assert_called_once_with(fanout=True)
mock_context.cast.assert_called_once_with(mock.ANY, 'METHOD')
@mock.patch.object(dispatcher, 'notify')
def test_start_action_function(self, mock_notify):
dispatcher.start_action(engine_id='FAKE_ENGINE')
mock_notify.assert_called_once_with(dispatcher.START_ACTION,
'FAKE_ENGINE')

View File

@ -1,211 +0,0 @@
# 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 datetime
import eventlet
import mock
from oslo_config import cfg
from oslo_utils import timeutils
from oslo_utils import uuidutils
from senlin.common import consts
from senlin.common import context
from senlin.common import messaging as rpc_messaging
from senlin.engine import service
from senlin.objects import service as service_obj
from senlin.tests.unit.common import base
@mock.patch('senlin.engine.dispatcher.Dispatcher')
@mock.patch('senlin.engine.health_manager.HealthManager')
@mock.patch('oslo_messaging.Target')
class EngineBasicTest(base.SenlinTestCase):
def setUp(self):
super(EngineBasicTest, self).setUp()
self.eng = service.EngineService('host-a', 'topic-a')
self.fake_id = '4db0a14c-dc10-4131-8ed6-7573987ce9b0'
self.gen_id = self.patchobject(uuidutils, 'generate_uuid',
return_value=self.fake_id)
self.fake_rpc_server = mock.Mock()
self.get_rpc = self.patchobject(rpc_messaging, 'get_rpc_server',
return_value=self.fake_rpc_server)
# TODO(Yanyan Hu): Remove this decorator after DB session related
# work is done.
@mock.patch.object(context, 'RequestContext')
def test_engine_start(self, mock_context, mock_msg_cls, mock_hm_cls,
mock_disp_cls):
mock_disp = mock_disp_cls.return_value
mock_hm = mock_hm_cls.return_value
mock_target = mock_msg_cls.return_value
self.eng.start()
self.gen_id.assert_called_once_with()
self.assertEqual(self.fake_id, self.eng.engine_id)
self.assertIsNotNone(self.eng.TG)
mock_disp_cls.assert_called_once_with(self.eng,
self.eng.dispatcher_topic,
consts.RPC_API_VERSION,
self.eng.TG)
self.assertEqual(mock_disp, self.eng.dispatcher)
mock_disp.start.assert_called_once_with()
mock_hm_cls.assert_called_once_with(self.eng,
self.eng.health_mgr_topic,
consts.RPC_API_VERSION)
self.assertEqual(mock_hm, self.eng.health_mgr)
mock_hm.start.assert_called_once_with()
mock_msg_cls.assert_called_once_with(version=consts.RPC_API_VERSION,
server=self.eng.host,
topic=self.eng.topic)
self.get_rpc.assert_called_once_with(mock_target, self.eng,
serializer=mock.ANY)
self.assertEqual(self.fake_rpc_server, self.eng._rpc_server)
self.fake_rpc_server.start.assert_called_once_with()
@mock.patch.object(service_obj.Service, 'delete')
def test_engine_stop(self, mock_delete, mock_msg_cls, mock_hm_cls,
mock_disp_cls):
mock_disp = mock_disp_cls.return_value
mock_hm = mock_hm_cls.return_value
self.eng.start()
self.eng.stop()
self.fake_rpc_server.stop.assert_called_once_with()
self.fake_rpc_server.wait.assert_called_once_with()
mock_disp.stop.assert_called_once_with()
mock_hm.stop.assert_called_once_with()
mock_delete.assert_called_once_with(self.fake_id)
def test_engine_stop_with_exception(self, mock_msg_cls, mock_hm_cls,
mock_disp_cls):
mock_disp = mock_disp_cls.return_value
mock_hm = mock_hm_cls.return_value
self.fake_rpc_server.wait.side_effect = Exception('blah')
self.eng.start()
self.eng.stop()
# on exception, both methods are still invoked
self.fake_rpc_server.stop.assert_called_once_with()
self.fake_rpc_server.wait.assert_called_once_with()
mock_disp.stop.assert_called_once_with()
mock_hm.stop.assert_called_once_with()
class EngineStatusTest(base.SenlinTestCase):
def setUp(self):
super(EngineStatusTest, self).setUp()
self.eng = service.EngineService('host-a', 'topic-a')
fake_id = '4db0a14c-dc10-4131-8ed6-7573987ce9b0'
self.gen_id = self.patchobject(uuidutils, 'generate_uuid',
return_value=fake_id)
self.fake_rpc_server = mock.Mock()
self.get_rpc = self.patchobject(rpc_messaging, 'get_rpc_server',
return_value=self.fake_rpc_server)
@mock.patch('senlin.engine.dispatcher.Dispatcher')
@mock.patch('senlin.engine.health_manager.HealthManager')
@mock.patch('oslo_messaging.Target')
@mock.patch.object(service_obj.Service, 'update')
def test_engine_manage_report(self, mock_update, mock_msg_cls, mock_hm_cls,
mock_disp_cls):
cfg.CONF.set_override('periodic_interval', 1)
# start engine and verify that update is being called more than once
self.eng.start()
eventlet.sleep(6)
self.assertGreater(mock_update.call_count, 1)
self.eng.stop()
@mock.patch('senlin.engine.dispatcher.Dispatcher')
@mock.patch('senlin.engine.health_manager.HealthManager')
@mock.patch('oslo_messaging.Target')
@mock.patch.object(service_obj.Service, 'update')
def test_engine_manage_report_with_exception(self, mock_update,
mock_msg_cls, mock_hm_cls,
mock_disp_cls):
cfg.CONF.set_override('periodic_interval', 1)
# start engine and verify that update is being called more than once
# even with the exception being thrown
mock_update.side_effect = Exception('blah')
self.eng.start()
eventlet.sleep(6)
self.assertGreater(mock_update.call_count, 1)
self.eng.stop()
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_update(self, mock_update):
mock_update.return_value = mock.Mock()
self.eng.service_manage_report()
mock_update.assert_called_once_with(mock.ANY, self.eng.engine_id)
@mock.patch.object(service_obj.Service, 'gc_by_engine')
@mock.patch.object(service_obj.Service, 'get_all')
@mock.patch.object(service_obj.Service, 'delete')
def test_service_manage_cleanup(self, mock_delete, mock_get_all, mock_gc):
delta = datetime.timedelta(seconds=2 * cfg.CONF.periodic_interval)
ages_a_go = timeutils.utcnow(True) - delta
mock_get_all.return_value = [{'id': 'foo', 'updated_at': ages_a_go}]
self.eng._service_manage_cleanup()
mock_delete.assert_called_once_with('foo')
mock_gc.assert_called_once_with('foo')
@mock.patch('senlin.engine.dispatcher.Dispatcher')
@mock.patch('senlin.engine.health_manager.HealthManager')
@mock.patch('oslo_messaging.Target')
@mock.patch.object(service_obj.Service, 'get_all')
def test_service_manage_cleanup_without_exception(self, mock_get_all,
mock_msg_cls,
mock_hm_cls,
mock_disp_cls):
cfg.CONF.set_override('periodic_interval', 1)
# start engine and verify that get_all is being called more than once
self.eng.start()
eventlet.sleep(6)
self.assertGreater(mock_get_all.call_count, 1)
self.eng.stop()
@mock.patch('senlin.engine.dispatcher.Dispatcher')
@mock.patch('senlin.engine.health_manager.HealthManager')
@mock.patch('oslo_messaging.Target')
@mock.patch.object(service_obj.Service, 'get_all')
def test_service_manage_cleanup_with_exception(self, mock_get_all,
mock_msg_cls, mock_hm_cls,
mock_disp_cls):
cfg.CONF.set_override('periodic_interval', 1)
# start engine and verify that get_all is being called more than once
# even with the exception being thrown
mock_get_all.side_effect = Exception('blah')
self.eng.start()
eventlet.sleep(6)
self.assertGreater(mock_get_all.call_count, 1)
self.eng.stop()

View File

@ -20,13 +20,11 @@ from oslo_utils import timeutils as tu
from senlin.common import consts
from senlin.common import context
from senlin.common import exception as exc
from senlin.common import messaging
from senlin.common import utils
from senlin.engine import health_manager as hm
from senlin.engine import node as node_mod
from senlin import objects
from senlin.objects import cluster as obj_cluster
from senlin.objects import health_registry as hr
from senlin.objects import node as obj_node
from senlin.objects import profile as obj_profile
from senlin.rpc import client as rpc_client
@ -38,7 +36,7 @@ class TestChaseUp(base.SenlinTestCase):
def test_less_than_one_interval(self):
start = tu.utcnow(True)
# we assume that the delay before next line is < 5 seconds
res = hm._chase_up(start, 5)
res = hm.chase_up(start, 5)
self.assertLessEqual(res, 5)
@ -47,7 +45,7 @@ class TestChaseUp(base.SenlinTestCase):
time.sleep(2)
# we assume that the delay before next line is < 5 seconds
res = hm._chase_up(start, 1)
res = hm.chase_up(start, 1)
self.assertLessEqual(res, 1)
@ -1720,106 +1718,3 @@ class TestRuntimeHealthRegistry(base.SenlinTestCase):
self.mock_tg.timer_done.assert_not_called()
self.mock_tg.thread_done.assert_called_once_with(fake_listener)
self.assertIsNone(mock_entry.listener)
class TestHealthManager(base.SenlinTestCase):
def setUp(self):
super(TestHealthManager, self).setUp()
mock_eng = mock.Mock()
mock_eng.engine_id = 'ENGINE_ID'
topic = consts.HEALTH_MANAGER_TOPIC
version = consts.RPC_API_VERSION
self.hm = hm.HealthManager(mock_eng, topic, version)
def test_init(self):
self.assertEqual('ENGINE_ID', self.hm.engine_id)
self.assertIsNotNone(self.hm.TG)
self.assertIsNotNone(self.hm.rpc_client)
self.assertEqual(consts.HEALTH_MANAGER_TOPIC, self.hm.topic)
self.assertEqual(consts.RPC_API_VERSION, self.hm.version)
self.assertEqual(0, len(self.hm.registries))
def test_task(self):
self.hm.health_registry = mock.Mock()
self.hm.task()
self.hm.health_registry.load_runtime_registry.assert_called_once_with()
@mock.patch('oslo_messaging.Target')
def test_start(self, mock_target):
self.hm.TG = mock.Mock()
target = mock.Mock()
mock_target.return_value = target
x_rpc_server = mock.Mock()
mock_get_rpc = self.patchobject(messaging, 'get_rpc_server',
return_value=x_rpc_server)
x_timer = mock.Mock()
mock_add_timer = self.patchobject(self.hm.TG, 'add_dynamic_timer',
return_value=x_timer)
# do it
self.hm.start()
# assert
mock_target.assert_called_once_with(server='ENGINE_ID',
topic='engine-health-mgr',
version=consts.RPC_API_VERSION)
mock_get_rpc.assert_called_once_with(target, self.hm)
x_rpc_server.start.assert_called_once_with()
mock_add_timer.assert_called_once_with(
self.hm.task, None, cfg.CONF.periodic_interval)
def test_stop(self):
self.hm.TG = mock.Mock()
self.hm.stop()
self.hm.TG.stop_timers.assert_called_once_with()
def test_register_cluster(self):
self.hm.health_registry = mock.Mock()
ctx = mock.Mock()
self.hm.register_cluster(ctx, 'CID', 60, 160, {}, True)
self.hm.health_registry.register_cluster.assert_called_once_with(
cluster_id='CID',
enabled=True,
interval=60,
node_update_timeout=160,
params={})
def test_unregister_cluster(self):
self.hm.health_registry = mock.Mock()
ctx = mock.Mock()
self.hm.unregister_cluster(ctx, 'CID')
self.hm.health_registry.unregister_cluster.assert_called_once_with(
'CID')
@mock.patch.object(context, 'get_admin_context')
@mock.patch.object(hr.HealthRegistry, 'get')
def test_get_manager_engine(self, mock_get, mock_ctx):
ctx = mock.Mock()
mock_ctx.return_value = ctx
registry = mock.Mock(engine_id='fake')
mock_get.return_value = registry
result = hm.get_manager_engine('CID')
self.assertEqual(result, 'fake')
mock_get.assert_called_once_with(ctx, 'CID')
self.assertTrue(mock_ctx.called)
@mock.patch.object(context, 'get_admin_context')
@mock.patch.object(hr.HealthRegistry, 'get')
def test_get_manager_engine_none(self, mock_get, mock_ctx):
ctx = mock.Mock()
mock_ctx.return_value = ctx
mock_get.return_value = None
result = hm.get_manager_engine('CID')
self.assertIsNone(result)
mock_get.assert_called_once_with(ctx, 'CID')
self.assertTrue(mock_ctx.called)

View File

@ -1,289 +0,0 @@
# 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 eventlet
import mock
from oslo_config import cfg
from oslo_context import context as oslo_context
from oslo_service import threadgroup
from senlin.db import api as db_api
from senlin.engine.actions import base as actionm
from senlin.engine import scheduler
from senlin.tests.unit.common import base
class DummyThread(object):
def __init__(self, function, *args, **kwargs):
self.function = function
def link(self, callback, *args):
callback(self, *args)
class DummyThreadGroup(object):
def __init__(self):
self.threads = []
def add_timer(self, interval, callback, initial_delay=None,
*args, **kwargs):
self.threads.append(callback)
def stop_timers(self):
pass
def add_thread(self, callback, cnxt, trace, func, *args, **kwargs):
# callback here is _start_with_trace, func is the 'real' callback
self.threads.append(func)
return DummyThread(func)
def stop(self, graceful=False):
pass
def wait(self):
pass
class SchedulerTest(base.SenlinTestCase):
def setUp(self):
super(SchedulerTest, self).setUp()
self.fake_tg = DummyThreadGroup()
self.mock_tg = self.patchobject(threadgroup, 'ThreadGroup')
self.mock_tg.return_value = self.fake_tg
def test_create(self):
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
mock_group.add_timer.assert_called_once_with(
cfg.CONF.periodic_interval,
tgm._service_task,
None)
def test_start(self):
def f():
pass
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
tgm.start(f)
mock_group.add_thread.assert_called_once_with(
tgm._start_with_trace,
oslo_context.get_current(),
None, f)
@mock.patch.object(db_api, 'action_acquire_first_ready')
@mock.patch.object(db_api, 'action_acquire')
def test_start_action(self, mock_action_acquire,
mock_action_acquire_1st):
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
action = mock.Mock()
action.id = '0123'
mock_action_acquire.return_value = action
mock_action_acquire_1st.return_value = None
tgm = scheduler.ThreadGroupManager()
tgm.start_action('4567', '0123')
mock_group.add_thread.assert_called_once_with(
tgm._start_with_trace,
oslo_context.get_current(),
None, actionm.ActionProc,
tgm.db_session, '0123')
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_no_action_id(self, mock_acquire_action):
mock_action = mock.Mock()
mock_action.id = '0123'
mock_action.action = 'CLUSTER_CREATE'
mock_acquire_action.side_effect = [mock_action, None]
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
tgm.start_action('4567')
mock_group.add_thread.assert_called_once_with(
tgm._start_with_trace,
oslo_context.get_current(),
None, actionm.ActionProc,
tgm.db_session, '0123')
@mock.patch.object(scheduler, 'sleep')
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_batch_control(self, mock_acquire_action, mock_sleep):
mock_action1 = mock.Mock()
mock_action1.id = 'ID1'
mock_action1.action = 'NODE_CREATE'
mock_action2 = mock.Mock()
mock_action2.id = 'ID2'
mock_action2.action = 'CLUSTER_CREATE'
mock_action3 = mock.Mock()
mock_action3.id = 'ID3'
mock_action3.action = 'NODE_DELETE'
mock_acquire_action.side_effect = [mock_action1, mock_action2,
mock_action3, None]
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
cfg.CONF.set_override('max_actions_per_batch', 1)
cfg.CONF.set_override('batch_interval', 2)
tgm = scheduler.ThreadGroupManager()
tgm.start_action('4567')
mock_sleep.assert_called_once_with(2)
self.assertEqual(mock_group.add_thread.call_count, 3)
@mock.patch.object(scheduler, 'sleep')
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_multiple_batches(self, mock_acquire_action,
mock_sleep):
action_types = ['NODE_CREATE', 'NODE_DELETE']
actions = []
for index in range(10):
mock_action = mock.Mock()
mock_action.id = 'ID%d' % (index + 1)
mock_action.action = action_types[index % 2]
actions.append(mock_action)
# Add a None at the end to end the process.
actions.insert(len(actions), None)
mock_acquire_action.side_effect = actions
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
cfg.CONF.set_override('max_actions_per_batch', 3)
cfg.CONF.set_override('batch_interval', 5)
tgm = scheduler.ThreadGroupManager()
tgm.start_action(worker_id='4567')
self.assertEqual(mock_sleep.call_count, 3)
self.assertEqual(mock_group.add_thread.call_count, 10)
@mock.patch.object(db_api, 'action_acquire_first_ready')
@mock.patch.object(db_api, 'action_acquire')
def test_start_action_failed_locking_action(self, mock_acquire_action,
mock_acquire_action_1st):
mock_acquire_action.return_value = None
mock_acquire_action_1st.return_value = None
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
res = tgm.start_action('4567', '0123')
self.assertIsNone(res)
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_no_action_ready(self, mock_acquire_action):
mock_acquire_action.return_value = None
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
res = tgm.start_action('4567')
self.assertIsNone(res)
def test_cancel_action(self):
mock_action = mock.Mock()
mock_load = self.patchobject(actionm.Action, 'load',
return_value=mock_action)
tgm = scheduler.ThreadGroupManager()
tgm.cancel_action('action0123')
mock_load.assert_called_once_with(tgm.db_session, 'action0123',
project_safe=False)
mock_action.signal.assert_called_once_with(mock_action.SIG_CANCEL)
def test_suspend_action(self):
mock_action = mock.Mock()
mock_load = self.patchobject(actionm.Action, 'load',
return_value=mock_action)
tgm = scheduler.ThreadGroupManager()
tgm.suspend_action('action0123')
mock_load.assert_called_once_with(tgm.db_session, 'action0123',
project_safe=False)
mock_action.signal.assert_called_once_with(mock_action.SIG_SUSPEND)
def test_resume_action(self):
mock_action = mock.Mock()
mock_load = self.patchobject(actionm.Action, 'load',
return_value=mock_action)
tgm = scheduler.ThreadGroupManager()
tgm.resume_action('action0123')
mock_load.assert_called_once_with(tgm.db_session, 'action0123',
project_safe=False)
mock_action.signal.assert_called_once_with(mock_action.SIG_RESUME)
def test_add_timer(self):
def f():
pass
tgm = scheduler.ThreadGroupManager()
tgm.add_timer(10, f)
# The first element is the '_service_task'
self.assertEqual(2, len(self.fake_tg.threads))
self.assertEqual(f, self.fake_tg.threads[1])
def test_stop_timer(self):
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
tgm.stop_timers()
mock_group.stop_timers.assert_called_once_with()
def test_stop(self):
def f():
pass
mock_group = mock.Mock()
self.mock_tg.return_value = mock_group
tgm = scheduler.ThreadGroupManager()
mock_group.threads = [
DummyThread(tgm._service_task),
DummyThread(f)
]
tgm.start(f)
tgm.stop()
mock_group.stop.assert_called_once_with(False)
mock_group.wait.assert_called_once_with()
def test_reschedule(self):
action = mock.Mock()
action.id = '0123'
mock_sleep = self.patchobject(eventlet, 'sleep')
scheduler.reschedule(action.id)
mock_sleep.assert_called_once_with(1)
mock_sleep.reset_mock()
scheduler.reschedule(action.id, None)
self.assertEqual(0, mock_sleep.call_count)
def test_sleep(self):
mock_sleep = self.patchobject(eventlet, 'sleep')
scheduler.sleep(1)
mock_sleep.assert_called_once_with(1)

View File

@ -0,0 +1,373 @@
# 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 eventlet
import mock
from oslo_config import cfg
from oslo_context import context as oslo_context
import oslo_messaging
from oslo_service import threadgroup
from oslo_utils import uuidutils
from osprofiler import profiler
from senlin.common import consts
from senlin.common import messaging
from senlin.db import api as db_api
from senlin.engine.actions import base as actionm
from senlin.engine import dispatcher
from senlin.engine import service
from senlin.objects import service as service_obj
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class DummyThread(object):
def __init__(self, function, *args, **kwargs):
self.function = function
class DummyThreadGroup(object):
def __init__(self):
self.threads = []
def add_timer(self, interval, callback, initial_delay=None,
*args, **kwargs):
self.threads.append(callback)
def stop_timers(self):
pass
def add_thread(self, callback, cnxt, trace, func, *args, **kwargs):
# callback here is _start_with_trace, func is the 'real' callback
self.threads.append(func)
return DummyThread(func)
def stop(self, graceful=False):
pass
def wait(self):
pass
class TestEngine(base.SenlinTestCase):
def setUp(self):
super(TestEngine, self).setUp()
self.context = utils.dummy_context()
self.service_id = '4db0a14c-dc10-4131-8ed6-7573987ce9b0'
self.tg = mock.Mock()
self.topic = consts.DISPATCHER_TOPIC
self.tg = mock.Mock()
self.svc = service.EngineService('HOST', self.topic)
self.svc.service_id = self.service_id
self.svc.tg = self.tg
def test_init(self):
self.assertEqual(self.service_id, self.svc.service_id)
self.assertEqual(self.tg, self.svc.tg)
self.assertEqual(self.topic, self.svc.topic)
@mock.patch.object(uuidutils, 'generate_uuid')
@mock.patch.object(oslo_messaging, 'get_rpc_server')
@mock.patch.object(service_obj.Service, 'create')
def test_service_start(self, mock_service_create, mock_rpc_server,
mock_uuid):
service_uuid = '4db0a14c-dc10-4131-8ed6-7573987ce9b1'
mock_uuid.return_value = service_uuid
self.svc.start()
mock_uuid.assert_called_once()
mock_service_create.assert_called_once()
self.svc.server.start.assert_called_once()
self.assertEqual(service_uuid, self.svc.service_id)
@mock.patch.object(service_obj.Service, 'delete')
def test_service_stop(self, mock_delete):
self.svc.server = mock.Mock()
self.svc.stop()
self.svc.server.stop.assert_called_once()
self.svc.server.wait.assert_called_once()
mock_delete.assert_called_once_with(self.svc.service_id)
@mock.patch.object(service_obj.Service, 'delete')
def test_service_stop_not_yet_started(self, mock_delete):
self.svc.server = None
self.svc.stop()
mock_delete.assert_called_once_with(self.svc.service_id)
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_update(self, mock_update):
mock_update.return_value = mock.Mock()
self.svc.service_manage_report()
mock_update.assert_called_once_with(mock.ANY,
self.svc.service_id)
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_with_exception(self, mock_update):
mock_update.side_effect = Exception('blah')
self.svc.service_manage_report()
self.assertEqual(mock_update.call_count, 1)
def test_listening(self):
self.assertTrue(self.svc.listening(self.context))
@mock.patch.object(oslo_context, 'get_current')
@mock.patch.object(messaging, 'get_rpc_client')
def test_notify_broadcast(self, mock_rpc, mock_get_current):
cfg.CONF.set_override('host', 'HOSTNAME')
fake_ctx = mock.Mock()
mock_get_current.return_value = fake_ctx
mock_rpc.return_value = mock.Mock()
dispatcher.notify('METHOD')
mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME')
mock_client = mock_rpc.return_value
mock_client.prepare.assert_called_once_with(fanout=True)
mock_context = mock_client.prepare.return_value
mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
@mock.patch.object(oslo_context, 'get_current')
@mock.patch.object(messaging, 'get_rpc_client')
def test_notify_single_server(self, mock_rpc, mock_get_current):
cfg.CONF.set_override('host', 'HOSTNAME')
fake_ctx = mock.Mock()
mock_get_current.return_value = fake_ctx
mock_rpc.return_value = mock.Mock()
result = dispatcher.notify('METHOD', 'FAKE_ENGINE')
self.assertTrue(result)
mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME')
mock_client = mock_rpc.return_value
mock_client.prepare.assert_called_once_with(server='FAKE_ENGINE')
mock_context = mock_client.prepare.return_value
mock_context.cast.assert_called_once_with(fake_ctx, 'METHOD')
@mock.patch.object(messaging, 'get_rpc_client')
def test_notify_timeout(self, mock_rpc):
cfg.CONF.set_override('host', 'HOSTNAME')
mock_rpc.return_value = mock.Mock()
mock_client = mock_rpc.return_value
mock_context = mock_client.prepare.return_value
mock_context.cast.side_effect = oslo_messaging.MessagingTimeout
result = dispatcher.notify('METHOD')
self.assertFalse(result)
mock_rpc.assert_called_once_with(consts.DISPATCHER_TOPIC, 'HOSTNAME')
mock_client.prepare.assert_called_once_with(fanout=True)
mock_context.cast.assert_called_once_with(mock.ANY, 'METHOD')
@mock.patch.object(profiler, 'get')
def test_serialize_profile_info(self, mock_profiler_get):
mock_profiler_get.return_value = None
self.assertIsNone(self.svc._serialize_profile_info())
@mock.patch.object(profiler, 'get')
def test_serialize_profile_info_with_profile(self, mock_profiler_get):
mock_result = mock.Mock()
mock_result.hmac_key = 'hmac_key'
mock_result.get_base_id.return_value = 'get_base_id'
mock_result.get_id.return_value = 'get_id'
mock_profiler_get.return_value = mock_result
result = self.svc._serialize_profile_info()
self.assertEqual(
{
'base_id': 'get_base_id',
'hmac_key': 'hmac_key',
'parent_id': 'get_id'
},
result
)
@mock.patch.object(profiler, 'init')
def test_start_with_trace(self, mock_profiler_init):
self.assertIsNotNone(
self.svc._start_with_trace(
self.context, {'hmac_key': mock.Mock()}, mock.Mock()
)
)
class DispatcherActionTest(base.SenlinTestCase):
def setUp(self):
super(DispatcherActionTest, self).setUp()
self.context = utils.dummy_context()
self.fake_tg = DummyThreadGroup()
self.mock_tg = self.patchobject(threadgroup, 'ThreadGroup')
self.mock_tg.return_value = self.fake_tg
@mock.patch.object(db_api, 'action_acquire_first_ready')
@mock.patch.object(db_api, 'action_acquire')
def test_start_action(self, mock_action_acquire,
mock_action_acquire_1st):
action = mock.Mock()
action.id = '0123'
mock_action_acquire.return_value = action
mock_action_acquire_1st.return_value = None
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.start_action('4567', '0123')
self.mock_tg.add_thread.assert_called_once_with(
svc._start_with_trace,
oslo_context.get_current(),
None, actionm.ActionProc,
svc.db_session, '0123'
)
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_no_action_id(self, mock_acquire_action):
mock_action = mock.Mock()
mock_action.id = '0123'
mock_action.action = 'CLUSTER_CREATE'
mock_acquire_action.side_effect = [mock_action, None]
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.start_action('4567')
self.mock_tg.add_thread.assert_called_once_with(
svc._start_with_trace,
oslo_context.get_current(),
None, actionm.ActionProc,
svc.db_session, '0123'
)
@mock.patch.object(service, 'sleep')
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_batch_control(self, mock_acquire_action, mock_sleep):
mock_action1 = mock.Mock()
mock_action1.id = 'ID1'
mock_action1.action = 'NODE_CREATE'
mock_action2 = mock.Mock()
mock_action2.id = 'ID2'
mock_action2.action = 'CLUSTER_CREATE'
mock_action3 = mock.Mock()
mock_action3.id = 'ID3'
mock_action3.action = 'NODE_DELETE'
mock_acquire_action.side_effect = [mock_action1, mock_action2,
mock_action3, None]
cfg.CONF.set_override('max_actions_per_batch', 1)
cfg.CONF.set_override('batch_interval', 2)
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.start_action('4567')
mock_sleep.assert_called_once_with(2)
self.assertEqual(self.mock_tg.add_thread.call_count, 3)
@mock.patch.object(service, 'sleep')
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_multiple_batches(self, mock_acquire_action,
mock_sleep):
action_types = ['NODE_CREATE', 'NODE_DELETE']
actions = []
for index in range(10):
mock_action = mock.Mock()
mock_action.id = 'ID%d' % (index + 1)
mock_action.action = action_types[index % 2]
actions.append(mock_action)
# Add a None at the end to end the process.
actions.insert(len(actions), None)
mock_acquire_action.side_effect = actions
cfg.CONF.set_override('max_actions_per_batch', 3)
cfg.CONF.set_override('batch_interval', 5)
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.start_action(self.context)
self.assertEqual(mock_sleep.call_count, 3)
self.assertEqual(self.mock_tg.add_thread.call_count, 10)
@mock.patch.object(db_api, 'action_acquire_first_ready')
@mock.patch.object(db_api, 'action_acquire')
def test_start_action_failed_locking_action(self, mock_acquire_action,
mock_acquire_action_1st):
mock_acquire_action.return_value = None
mock_acquire_action_1st.return_value = None
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
res = svc.start_action(self.context, '0123')
self.assertIsNone(res)
@mock.patch.object(db_api, 'action_acquire_first_ready')
def test_start_action_no_action_ready(self, mock_acquire_action):
mock_acquire_action.return_value = None
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
res = svc.start_action('4567')
self.assertIsNone(res)
def test_cancel_action(self):
mock_action = mock.Mock()
mock_load = self.patchobject(actionm.Action, 'load',
return_value=mock_action)
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.cancel_action(self.context, 'action0123')
mock_load.assert_called_once_with(svc.db_session, 'action0123',
project_safe=False)
mock_action.signal.assert_called_once_with(mock_action.SIG_CANCEL)
def test_suspend_action(self):
mock_action = mock.Mock()
mock_load = self.patchobject(actionm.Action, 'load',
return_value=mock_action)
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.suspend_action(self.context, 'action0123')
mock_load.assert_called_once_with(svc.db_session, 'action0123',
project_safe=False)
mock_action.signal.assert_called_once_with(mock_action.SIG_SUSPEND)
def test_resume_action(self):
mock_action = mock.Mock()
mock_load = self.patchobject(actionm.Action, 'load',
return_value=mock_action)
svc = service.EngineService('HOST', 'TOPIC')
svc.tg = self.mock_tg
svc.resume_action(self.context, 'action0123')
mock_load.assert_called_once_with(svc.db_session, 'action0123',
project_safe=False)
mock_action.signal.assert_called_once_with(mock_action.SIG_RESUME)
def test_sleep(self):
mock_sleep = self.patchobject(eventlet, 'sleep')
service.sleep(1)
mock_sleep.assert_called_once_with(1)

View File

@ -0,0 +1,172 @@
# 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 mock
import oslo_messaging
from oslo_utils import uuidutils
from senlin.common import consts
from senlin.common import context
from senlin.engine import health_manager as hm
from senlin.health_manager import service
from senlin.objects import health_registry as hr
from senlin.objects import service as obj_service
from senlin.objects import service as service_obj
from senlin.tests.unit.common import base
from senlin.tests.unit.common import utils
class TestHealthManager(base.SenlinTestCase):
def setUp(self):
super(TestHealthManager, self).setUp()
self.context = utils.dummy_context()
self.service_id = '4db0a14c-dc10-4131-8ed6-7573987ce9b0'
self.tg = mock.Mock()
self.topic = consts.HEALTH_MANAGER_TOPIC
self.svc = service.HealthManagerService('HOST', self.topic)
self.svc.service_id = self.service_id
self.svc.tg = self.tg
def test_init(self):
self.assertEqual(self.service_id, self.svc.service_id)
self.assertEqual(self.tg, self.svc.tg)
self.assertEqual(self.topic, self.svc.topic)
self.assertEqual(consts.RPC_API_VERSION, self.svc.version)
@mock.patch.object(uuidutils, 'generate_uuid')
@mock.patch.object(oslo_messaging, 'get_rpc_server')
@mock.patch.object(obj_service.Service, 'create')
def test_service_start(self, mock_service_create, mock_rpc_server,
mock_uuid):
service_uuid = '4db0a14c-dc10-4131-8ed6-7573987ce9b1'
mock_uuid.return_value = service_uuid
self.svc.start()
mock_uuid.assert_called_once()
mock_service_create.assert_called_once()
self.svc.server.start.assert_called_once()
self.assertEqual(service_uuid, self.svc.service_id)
@mock.patch.object(service_obj.Service, 'delete')
def test_service_stop(self, mock_delete):
self.svc.server = mock.Mock()
self.svc.stop()
self.svc.server.stop.assert_called_once()
self.svc.server.wait.assert_called_once()
mock_delete.assert_called_once_with(self.svc.service_id)
@mock.patch.object(service_obj.Service, 'delete')
def test_service_stop_not_yet_started(self, mock_delete):
self.svc.server = None
self.svc.stop()
mock_delete.assert_called_once_with(self.svc.service_id)
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_update(self, mock_update):
mock_update.return_value = mock.Mock()
self.svc.service_manage_report()
mock_update.assert_called_once_with(mock.ANY,
self.svc.service_id)
@mock.patch.object(service_obj.Service, 'update')
def test_service_manage_report_with_exception(self, mock_update):
mock_update.side_effect = Exception('blah')
self.svc.service_manage_report()
self.assertEqual(mock_update.call_count, 1)
def test_listening(self):
self.assertTrue(self.svc.listening(self.context))
def test_task(self):
self.svc.health_registry = mock.Mock()
self.svc.task()
self.svc.health_registry.load_runtime_registry.assert_called_once_with(
)
def test_task_with_exception(self):
self.svc.health_registry = mock.Mock()
self.svc.health_registry.load_runtime_registry.side_effect = Exception(
'blah'
)
self.svc.task()
self.svc.health_registry.load_runtime_registry.assert_called_once_with(
)
def test_enable_cluster(self):
self.svc.health_registry = mock.Mock()
self.svc.enable_cluster(self.context, 'CID')
self.svc.health_registry.enable_cluster.assert_called_once_with(
'CID')
def test_disable_cluster(self):
self.svc.health_registry = mock.Mock()
self.svc.disable_cluster(self.context, 'CID')
self.svc.health_registry.disable_cluster.assert_called_once_with(
'CID')
def test_register_cluster(self):
self.svc.health_registry = mock.Mock()
self.svc.register_cluster(self.context, 'CID', 60, 160, {}, True)
self.svc.health_registry.register_cluster.assert_called_once_with(
cluster_id='CID',
enabled=True,
interval=60,
node_update_timeout=160,
params={})
def test_unregister_cluster(self):
self.svc.health_registry = mock.Mock()
self.svc.unregister_cluster(self.context, 'CID')
self.svc.health_registry.unregister_cluster.assert_called_once_with(
'CID')
@mock.patch.object(context, 'get_admin_context')
@mock.patch.object(hr.HealthRegistry, 'get')
def test_get_manager_engine(self, mock_get, mock_ctx):
ctx = mock.Mock()
mock_ctx.return_value = ctx
registry = mock.Mock(engine_id='fake')
mock_get.return_value = registry
result = hm.get_manager_engine('CID')
self.assertEqual(result, 'fake')
mock_get.assert_called_once_with(ctx, 'CID')
self.assertTrue(mock_ctx.called)
@mock.patch.object(context, 'get_admin_context')
@mock.patch.object(hr.HealthRegistry, 'get')
def test_get_manager_engine_none(self, mock_get, mock_ctx):
ctx = mock.Mock()
mock_ctx.return_value = ctx
mock_get.return_value = None
result = hm.get_manager_engine('CID')
self.assertIsNone(result)
mock_get.assert_called_once_with(ctx, 'CID')
self.assertTrue(mock_ctx.called)

View File

@ -29,7 +29,9 @@ data_files =
[entry_points]
console_scripts =
senlin-api = senlin.cmd.api:main
senlin-conductor = senlin.cmd.conductor:main
senlin-engine = senlin.cmd.engine:main
senlin-health-manager = senlin.cmd.health_manager:main
senlin-manage = senlin.cmd.manage:main
senlin-status = senlin.cmd.status:main