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:
parent
b0efef780b
commit
54997a14ea
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -9,7 +9,9 @@ Senlin services
|
|||
.. toctree::
|
||||
:maxdepth: 1
|
||||
|
||||
senlin-conductor
|
||||
senlin-engine
|
||||
senlin-health-manager
|
||||
senlin-api
|
||||
|
||||
|
||||
|
|
|
@ -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>`__
|
|
@ -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
|
||||
|
|
|
@ -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>`__
|
|
@ -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.
|
|
@ -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()
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
|
@ -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
|
||||
|
|
|
@ -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)
|
File diff suppressed because it is too large
Load Diff
|
@ -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()
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
@ -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)
|
|
@ -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'
|
||||
)
|
|
@ -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'
|
||||
)
|
|
@ -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'
|
||||
)
|
|
@ -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,
|
||||
|
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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
|
|
@ -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(
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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])
|
|
@ -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()
|
|
@ -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'
|
||||
|
|
|
@ -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')
|
|
@ -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()
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
|
@ -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)
|
|
@ -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)
|
|
@ -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
|
||||
|
||||
|
|
Loading…
Reference in New Issue