Merge "Record container action and event."

This commit is contained in:
Zuul 2018-02-03 07:32:54 +00:00 committed by Gerrit Code Review
commit 138281905e
7 changed files with 331 additions and 35 deletions

View File

@ -18,6 +18,7 @@
"""Utilities and helper functions.""" """Utilities and helper functions."""
import eventlet import eventlet
import functools import functools
import inspect
import mimetypes import mimetypes
from oslo_concurrency import lockutils from oslo_concurrency import lockutils
@ -36,6 +37,7 @@ from zun.common.i18n import _
from zun.common import privileged from zun.common import privileged
import zun.conf import zun.conf
from zun.network import neutron from zun.network import neutron
from zun import objects
CONF = zun.conf.CONF CONF = zun.conf.CONF
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
@ -506,3 +508,71 @@ def check_external_network_attach(context, nets):
if net.get('router:external') and not net.get('shared'): if net.get('router:external') and not net.get('shared'):
raise exception.ExternalNetworkAttachForbidden( raise exception.ExternalNetworkAttachForbidden(
network_uuid=net['network']) network_uuid=net['network'])
class EventReporter(object):
"""Context manager to report container action events."""
def __init__(self, context, event_name, *container_uuids):
self.context = context
self.event_name = event_name
self.container_uuids = container_uuids
def __enter__(self):
for uuid in self.container_uuids:
objects.ContainerActionEvent.event_start(
self.context, uuid, self.event_name, want_result=False)
return self
def __exit__(self, exc_type, exc_val, exc_tb):
for uuid in self.container_uuids:
objects.ContainerActionEvent.event_finish(
self.context, uuid, self.event_name, exc_val=exc_val,
exc_tb=exc_tb, want_result=False)
return False
def get_wrapped_function(function):
"""Get the method at the bottom of a stack of decorators."""
if not hasattr(function, '__closure__') or not function.__closure__:
return function
def _get_wrapped_function(function):
if not hasattr(function, '__closure__') or not function.__closure__:
return None
for closure in function.__closure__:
func = closure.cell_contents
deeper_func = _get_wrapped_function(func)
if deeper_func:
return deeper_func
elif hasattr(closure.cell_contents, '__call__'):
return closure.cell_contents
return function
return _get_wrapped_function(function)
def wrap_container_event(prefix):
"""Warps a method to log the event taken on the container, and result.
This decorator wraps a method to log the start and result of an event, as
part of an action taken on a container.
"""
def helper(function):
@functools.wraps(function)
def decorated_function(self, context, *args, **kwargs):
wrapped_func = get_wrapped_function(function)
keyed_args = inspect.getcallargs(wrapped_func, self, context,
*args, **kwargs)
container_uuid = keyed_args['container'].uuid
event_name = '{0}_{1}'.format(prefix, function.__name__)
with EventReporter(context, event_name, container_uuid):
return function(self, context, *args, **kwargs)
return decorated_function
return helper

View File

@ -16,8 +16,10 @@ networking and storage of containers, and compute hosts on which they run)."""
from zun.common import consts from zun.common import consts
from zun.common import exception from zun.common import exception
from zun.common import profiler from zun.common import profiler
from zun.compute import container_actions
from zun.compute import rpcapi from zun.compute import rpcapi
import zun.conf import zun.conf
from zun import objects
from zun.scheduler import client as scheduler_client from zun.scheduler import client as scheduler_client
CONF = zun.conf.CONF CONF = zun.conf.CONF
@ -32,6 +34,10 @@ class API(object):
self.scheduler_client = scheduler_client.SchedulerClient() self.scheduler_client = scheduler_client.SchedulerClient()
super(API, self).__init__() super(API, self).__init__()
def _record_action_start(self, context, container, action):
objects.ContainerAction.action_start(context, container.uuid,
action, want_result=False)
def container_create(self, context, new_container, extra_spec, def container_create(self, context, new_container, extra_spec,
requested_networks, requested_volumes, run, requested_networks, requested_volumes, run,
pci_requests=None): pci_requests=None):
@ -55,6 +61,8 @@ class API(object):
if not images: if not images:
raise exception.ImageNotFound(image=new_container.image) raise exception.ImageNotFound(image=new_container.image)
self._record_action_start(context, new_container,
container_actions.CREATE)
self.rpcapi.container_create(context, host_state['host'], self.rpcapi.container_create(context, host_state['host'],
new_container, host_state['limits'], new_container, host_state['limits'],
requested_networks, requested_volumes, requested_networks, requested_volumes,
@ -67,24 +75,31 @@ class API(object):
return dests[0] return dests[0]
def container_delete(self, context, container, *args): def container_delete(self, context, container, *args):
self._record_action_start(context, container, container_actions.DELETE)
return self.rpcapi.container_delete(context, container, *args) return self.rpcapi.container_delete(context, container, *args)
def container_show(self, context, container, *args): def container_show(self, context, container, *args):
return self.rpcapi.container_show(context, container, *args) return self.rpcapi.container_show(context, container, *args)
def container_reboot(self, context, container, *args): def container_reboot(self, context, container, *args):
self._record_action_start(context, container, container_actions.REBOOT)
return self.rpcapi.container_reboot(context, container, *args) return self.rpcapi.container_reboot(context, container, *args)
def container_stop(self, context, container, *args): def container_stop(self, context, container, *args):
self._record_action_start(context, container, container_actions.STOP)
return self.rpcapi.container_stop(context, container, *args) return self.rpcapi.container_stop(context, container, *args)
def container_start(self, context, container): def container_start(self, context, container):
self._record_action_start(context, container, container_actions.START)
return self.rpcapi.container_start(context, container) return self.rpcapi.container_start(context, container)
def container_pause(self, context, container): def container_pause(self, context, container):
self._record_action_start(context, container, container_actions.PAUSE)
return self.rpcapi.container_pause(context, container) return self.rpcapi.container_pause(context, container)
def container_unpause(self, context, container): def container_unpause(self, context, container):
self._record_action_start(context, container,
container_actions.UNPAUSE)
return self.rpcapi.container_unpause(context, container) return self.rpcapi.container_unpause(context, container)
def container_logs(self, context, container, stdout, stderr, def container_logs(self, context, container, stdout, stderr,
@ -99,6 +114,7 @@ class API(object):
return self.rpcapi.container_exec_resize(context, container, *args) return self.rpcapi.container_exec_resize(context, container, *args)
def container_kill(self, context, container, *args): def container_kill(self, context, container, *args):
self._record_action_start(context, container, container_actions.KILL)
return self.rpcapi.container_kill(context, container, *args) return self.rpcapi.container_kill(context, container, *args)
def container_update(self, context, container, *args): def container_update(self, context, container, *args):
@ -117,9 +133,13 @@ class API(object):
return self.rpcapi.container_get_archive(context, container, *args) return self.rpcapi.container_get_archive(context, container, *args)
def add_security_group(self, context, container, *args): def add_security_group(self, context, container, *args):
self._record_action_start(context, container,
container_actions.ADD_SECURITY_GROUP)
return self.rpcapi.add_security_group(context, container, *args) return self.rpcapi.add_security_group(context, container, *args)
def remove_security_group(self, context, container, *args): def remove_security_group(self, context, container, *args):
self._record_action_start(context, container,
container_actions.REMOVE_SECURITY_GROUP)
return self.rpcapi.remove_security_group(context, container, *args) return self.rpcapi.remove_security_group(context, container, *args)
def container_put_archive(self, context, container, *args): def container_put_archive(self, context, container, *args):
@ -129,6 +149,7 @@ class API(object):
return self.rpcapi.container_stats(context, container) return self.rpcapi.container_stats(context, container)
def container_commit(self, context, container, *args): def container_commit(self, context, container, *args):
self._record_action_start(context, container, container_actions.COMMIT)
return self.rpcapi.container_commit(context, container, *args) return self.rpcapi.container_commit(context, container, *args)
def image_pull(self, context, image): def image_pull(self, context, image):
@ -157,7 +178,11 @@ class API(object):
return self.rpcapi.capsule_delete(context, capsule, *args) return self.rpcapi.capsule_delete(context, capsule, *args)
def network_detach(self, context, container, *args): def network_detach(self, context, container, *args):
self._record_action_start(context, container,
container_actions.NETWORK_DETACH)
return self.rpcapi.network_detach(context, container, *args) return self.rpcapi.network_detach(context, container, *args)
def network_attach(self, context, container, *args): def network_attach(self, context, container, *args):
self._record_action_start(context, container,
container_actions.NETWORK_ATTACH)
return self.rpcapi.network_attach(context, container, *args) return self.rpcapi.network_attach(context, container, *args)

View File

@ -0,0 +1,40 @@
# 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.
"""Possible actions on an container.
Action should probably match a user intention at the API level. Because they
can be user visible that should help to avoid confusion. For that reason they
tent to maintain the casing sent to the API.
Maintaining a list of actions here should protect against inconsistencies when
they are used.
"""
CREATE = 'create'
DELETE = 'delete'
REBOOT = 'reboot'
STOP = 'stop'
START = 'start'
PAUSE = 'pause'
UNPAUSE = 'unpause'
EXEC_CMD = 'exec_cmd'
KILL = 'kill'
UPDATE = 'update'
CONTAINER_ATTACH = 'container_attach'
RESIZE = 'resize'
ADD_SECURITY_GROUP = 'add_security_group'
REMOVE_SECURITY_GROUP = 'remove_security_group'
PUT_ARCHIVE = 'put_archive'
COMMIT = 'commit'
NETWORK_DETACH = 'network_detach'
NETWORK_ATTACH = 'network_attach'

View File

@ -25,6 +25,7 @@ from zun.common import exception
from zun.common.i18n import _ from zun.common.i18n import _
from zun.common import utils from zun.common import utils
from zun.common.utils import translate_exception from zun.common.utils import translate_exception
from zun.common.utils import wrap_container_event
from zun.compute import compute_node_tracker from zun.compute import compute_node_tracker
import zun.conf import zun.conf
from zun.container import driver from zun.container import driver
@ -262,6 +263,7 @@ class Manager(periodic_task.PeriodicTasks):
unset_host=True) unset_host=True)
return return
@wrap_container_event(prefix='compute')
def _do_container_create(self, context, container, requested_networks, def _do_container_create(self, context, container, requested_networks,
requested_volumes, pci_requests=None, requested_volumes, pci_requests=None,
limits=None, reraise=False): limits=None, reraise=False):
@ -378,6 +380,7 @@ class Manager(periodic_task.PeriodicTasks):
six.text_type(e)) six.text_type(e))
self._fail_container(context, container, six.text_type(e)) self._fail_container(context, container, six.text_type(e))
@wrap_container_event(prefix='compute')
def _do_container_start(self, context, container, reraise=False): def _do_container_start(self, context, container, reraise=False):
LOG.debug('Starting container: %s', container.uuid) LOG.debug('Starting container: %s', container.uuid)
self._update_task_state(context, container, consts.CONTAINER_STARTING) self._update_task_state(context, container, consts.CONTAINER_STARTING)
@ -451,6 +454,7 @@ class Manager(periodic_task.PeriodicTasks):
utils.spawn_n(do_add_security_group) utils.spawn_n(do_add_security_group)
@wrap_container_event(prefix='compute')
def _add_security_group(self, context, container, security_group): def _add_security_group(self, context, container, security_group):
LOG.debug('Adding security_group to container: %s', container.uuid) LOG.debug('Adding security_group to container: %s', container.uuid)
try: try:
@ -468,6 +472,7 @@ class Manager(periodic_task.PeriodicTasks):
utils.spawn_n(do_remove_security_group) utils.spawn_n(do_remove_security_group)
@wrap_container_event(prefix='compute')
def _remove_security_group(self, context, container, security_group): def _remove_security_group(self, context, container, security_group):
LOG.debug('Removing security_group from container: %s', container.uuid) LOG.debug('Removing security_group from container: %s', container.uuid)
try: try:
@ -510,6 +515,7 @@ class Manager(periodic_task.PeriodicTasks):
LOG.exception("Unexpected exception: %s", six.text_type(e)) LOG.exception("Unexpected exception: %s", six.text_type(e))
raise raise
@wrap_container_event(prefix='compute')
def _do_container_reboot(self, context, container, timeout, reraise=False): def _do_container_reboot(self, context, container, timeout, reraise=False):
LOG.debug('Rebooting container: %s', container.uuid) LOG.debug('Rebooting container: %s', container.uuid)
self._update_task_state(context, container, consts.CONTAINER_REBOOTING) self._update_task_state(context, container, consts.CONTAINER_REBOOTING)
@ -535,6 +541,7 @@ class Manager(periodic_task.PeriodicTasks):
utils.spawn_n(do_container_reboot) utils.spawn_n(do_container_reboot)
@wrap_container_event(prefix='compute')
def _do_container_stop(self, context, container, timeout, reraise=False): def _do_container_stop(self, context, container, timeout, reraise=False):
LOG.debug('Stopping container: %s', container.uuid) LOG.debug('Stopping container: %s', container.uuid)
self._update_task_state(context, container, consts.CONTAINER_STOPPING) self._update_task_state(context, container, consts.CONTAINER_STOPPING)
@ -567,6 +574,7 @@ class Manager(periodic_task.PeriodicTasks):
utils.spawn_n(do_container_start) utils.spawn_n(do_container_start)
@wrap_container_event(prefix='compute')
def _do_container_pause(self, context, container, reraise=False): def _do_container_pause(self, context, container, reraise=False):
LOG.debug('Pausing container: %s', container.uuid) LOG.debug('Pausing container: %s', container.uuid)
try: try:
@ -591,6 +599,7 @@ class Manager(periodic_task.PeriodicTasks):
utils.spawn_n(do_container_pause) utils.spawn_n(do_container_pause)
@wrap_container_event(prefix='compute')
def _do_container_unpause(self, context, container, reraise=False): def _do_container_unpause(self, context, container, reraise=False):
LOG.debug('Unpausing container: %s', container.uuid) LOG.debug('Unpausing container: %s', container.uuid)
try: try:
@ -667,6 +676,7 @@ class Manager(periodic_task.PeriodicTasks):
LOG.exception("Unexpected exception: %s", six.text_type(e)) LOG.exception("Unexpected exception: %s", six.text_type(e))
raise raise
@wrap_container_event(prefix='compute')
def _do_container_kill(self, context, container, signal, reraise=False): def _do_container_kill(self, context, container, signal, reraise=False):
LOG.debug('Killing a container: %s', container.uuid) LOG.debug('Killing a container: %s', container.uuid)
try: try:
@ -824,6 +834,7 @@ class Manager(periodic_task.PeriodicTasks):
self.driver.delete_image(container_image_id) self.driver.delete_image(container_image_id)
raise raise
@wrap_container_event(prefix='compute')
def _do_container_commit(self, context, snapshot_image, container, def _do_container_commit(self, context, snapshot_image, container,
repository, tag=None): repository, tag=None):
container_image_id = None container_image_id = None
@ -1034,6 +1045,7 @@ class Manager(periodic_task.PeriodicTasks):
capsule.save(context) capsule.save(context)
capsule.destroy(context) capsule.destroy(context)
@wrap_container_event(prefix='compute')
def network_detach(self, context, container, network): def network_detach(self, context, container, network):
LOG.debug('Detach network: %(network)s from container: %(container)s.', LOG.debug('Detach network: %(network)s from container: %(container)s.',
{'container': container, 'network': network}) {'container': container, 'network': network})
@ -1043,6 +1055,7 @@ class Manager(periodic_task.PeriodicTasks):
with excutils.save_and_reraise_exception(reraise=False): with excutils.save_and_reraise_exception(reraise=False):
LOG.exception("Unexpected exception: %s", six.text_type(e)) LOG.exception("Unexpected exception: %s", six.text_type(e))
@wrap_container_event(prefix='compute')
def network_attach(self, context, container, network): def network_attach(self, context, container, network):
LOG.debug('Attach network: %(network)s to container: %(container)s.', LOG.debug('Attach network: %(network)s to container: %(container)s.',
{'container': container, 'network': network}) {'container': container, 'network': network})

View File

@ -40,6 +40,8 @@ class ContainerAction(base.ZunPersistentObject, base.ZunObject):
'start_time': fields.DateTimeField(nullable=True), 'start_time': fields.DateTimeField(nullable=True),
'finish_time': fields.DateTimeField(nullable=True), 'finish_time': fields.DateTimeField(nullable=True),
'message': fields.StringField(nullable=True), 'message': fields.StringField(nullable=True),
# NOTE: By now, this field is only used for etcd. If using sql,
# this field will be None.
'uuid': fields.StringField(nullable=True), 'uuid': fields.StringField(nullable=True),
} }

View File

@ -215,3 +215,49 @@ class TestUtils(base.TestCase):
mock.ANY, mock.ANY,
test_image['uuid']) test_image['uuid'])
self.assertEqual(test_image['uuid'], image.uuid) self.assertEqual(test_image['uuid'], image.uuid)
@mock.patch.object(objects.ContainerActionEvent, 'event_start')
@mock.patch.object(objects.ContainerActionEvent, 'event_finish')
def test_wart_container_event(self, mock_finish, mock_start):
container = Container(self.context, **db_utils.get_test_container())
@utils.wrap_container_event(prefix='compute')
def fake_event(self, context, container):
pass
fake_event(self, self.context, container=container)
self.assertTrue(mock_start.called)
self.assertTrue(mock_finish.called)
@mock.patch.object(objects.ContainerActionEvent, 'event_start')
@mock.patch.object(objects.ContainerActionEvent, 'event_finish')
def test_wrap_container_event_return(self, mock_finish, mock_start):
container = Container(self.context, **db_utils.get_test_container())
@utils.wrap_container_event(prefix='compute')
def fake_event(self, context, container):
return True
retval = fake_event(self, self.context, container=container)
self.assertTrue(retval)
self.assertTrue(mock_start.called)
self.assertTrue(mock_finish.called)
@mock.patch.object(objects.ContainerActionEvent, 'event_start')
@mock.patch.object(objects.ContainerActionEvent, 'event_finish')
def test_wrap_conatiner_event_log_exception(self, mock_finish, mock_start):
container = Container(self.context, **db_utils.get_test_container())
@utils.wrap_container_event(prefix='compute')
def fake_event(self, context, container):
raise exception.ZunException()
self.assertRaises(exception.ZunException, fake_event,
self, self.context, container=container)
self.assertTrue(mock_start.called)
self.assertTrue(mock_finish.called)
args, kwargs = mock_finish.call_args
self.assertIsInstance(kwargs['exc_val'], exception.ZunException)

View File

@ -22,6 +22,7 @@ from zun.compute import claims
from zun.compute import manager from zun.compute import manager
import zun.conf import zun.conf
from zun.objects.container import Container from zun.objects.container import Container
from zun.objects.container_action import ContainerActionEvent
from zun.objects.image import Image from zun.objects.image import Image
from zun.objects.volume_mapping import VolumeMapping from zun.objects.volume_mapping import VolumeMapping
from zun.tests import base from zun.tests import base
@ -183,10 +184,13 @@ class TestManager(base.TestCase):
self.assertEqual("Creation Failed", container.status_reason) self.assertEqual("Creation Failed", container.status_reason)
self.assertIsNone(container.task_state) self.assertIsNone(container.task_state)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch('zun.image.driver.pull_image') @mock.patch('zun.image.driver.pull_image')
@mock.patch.object(fake_driver, 'create') @mock.patch.object(fake_driver, 'create')
def test_container_create(self, mock_create, mock_pull, mock_save): def test_container_create(self, mock_create, mock_pull, mock_save,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance'} image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance'}
mock_pull.return_value = image, False mock_pull.return_value = image, False
@ -201,11 +205,14 @@ class TestManager(base.TestCase):
mock_create.assert_called_once_with(self.context, container, image, mock_create.assert_called_once_with(self.context, container, image,
networks, volumes) networks, volumes)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch('zun.image.driver.pull_image') @mock.patch('zun.image.driver.pull_image')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
def test_container_create_pull_image_failed_docker_error( def test_container_create_pull_image_failed_docker_error(
self, mock_fail, mock_pull, mock_save): self, mock_fail, mock_pull, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_pull.side_effect = exception.DockerError("Pull Failed") mock_pull.side_effect = exception.DockerError("Pull Failed")
networks = [] networks = []
@ -215,11 +222,14 @@ class TestManager(base.TestCase):
mock_fail.assert_called_once_with(self.context, mock_fail.assert_called_once_with(self.context,
container, "Pull Failed") container, "Pull Failed")
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch('zun.image.driver.pull_image') @mock.patch('zun.image.driver.pull_image')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
def test_container_create_pull_image_failed_image_not_found( def test_container_create_pull_image_failed_image_not_found(
self, mock_fail, mock_pull, mock_save): self, mock_fail, mock_pull, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_pull.side_effect = exception.ImageNotFound("Image Not Found") mock_pull.side_effect = exception.ImageNotFound("Image Not Found")
networks = [] networks = []
@ -229,11 +239,14 @@ class TestManager(base.TestCase):
mock_fail.assert_called_once_with(self.context, mock_fail.assert_called_once_with(self.context,
container, "Image Not Found") container, "Image Not Found")
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch('zun.image.driver.pull_image') @mock.patch('zun.image.driver.pull_image')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
def test_container_create_pull_image_failed_zun_exception( def test_container_create_pull_image_failed_zun_exception(
self, mock_fail, mock_pull, mock_save): self, mock_fail, mock_pull, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_pull.side_effect = exception.ZunException( mock_pull.side_effect = exception.ZunException(
message="Image Not Found") message="Image Not Found")
@ -244,13 +257,15 @@ class TestManager(base.TestCase):
mock_fail.assert_called_once_with(self.context, mock_fail.assert_called_once_with(self.context,
container, "Image Not Found") container, "Image Not Found")
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch('zun.image.driver.pull_image') @mock.patch('zun.image.driver.pull_image')
@mock.patch.object(fake_driver, 'create') @mock.patch.object(fake_driver, 'create')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
def test_container_create_docker_create_failed(self, mock_fail, def test_container_create_docker_create_failed(
mock_create, mock_pull, self, mock_fail, mock_create, mock_pull, mock_save,
mock_save): mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance', image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance',
'repo': 'test', 'tag': 'testtag'} 'repo': 'test', 'tag': 'testtag'}
@ -264,6 +279,8 @@ class TestManager(base.TestCase):
mock_fail.assert_called_once_with( mock_fail.assert_called_once_with(
self.context, container, "Creation Failed", unset_host=True) self.context, container, "Creation Failed", unset_host=True)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.common.utils.spawn_n') @mock.patch('zun.common.utils.spawn_n')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(VolumeMapping, 'list_by_container', @mock.patch.object(VolumeMapping, 'list_by_container',
@ -278,7 +295,7 @@ class TestManager(base.TestCase):
self, mock_start, mock_create, self, mock_start, mock_create,
mock_is_volume_available, mock_attach_volume, mock_is_volume_available, mock_attach_volume,
mock_detach_volume, mock_pull, mock_list_by_container, mock_save, mock_detach_volume, mock_pull, mock_list_by_container, mock_save,
mock_spawn_n): mock_spawn_n, mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance'} image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance'}
mock_create.return_value = container mock_create.return_value = container
@ -305,6 +322,8 @@ class TestManager(base.TestCase):
mock_is_volume_available.assert_called_once() mock_is_volume_available.assert_called_once()
self.assertEqual(1, len(FakeVolumeMapping.volumes)) self.assertEqual(1, len(FakeVolumeMapping.volumes))
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.common.utils.spawn_n') @mock.patch('zun.common.utils.spawn_n')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(VolumeMapping, 'list_by_container', @mock.patch.object(VolumeMapping, 'list_by_container',
@ -319,7 +338,7 @@ class TestManager(base.TestCase):
self, mock_start, mock_create, self, mock_start, mock_create,
mock_is_volume_available, mock_attach_volume, mock_is_volume_available, mock_attach_volume,
mock_detach_volume, mock_pull, mock_list_by_container, mock_save, mock_detach_volume, mock_pull, mock_list_by_container, mock_save,
mock_spawn_n): mock_spawn_n, mock_event_finish, mock_event_start):
mock_is_volume_available.return_value = True mock_is_volume_available.return_value = True
mock_attach_volume.side_effect = [None, base.TestingException("fake")] mock_attach_volume.side_effect = [None, base.TestingException("fake")]
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
@ -349,6 +368,8 @@ class TestManager(base.TestCase):
mock.call(mock.ANY, vol)]) mock.call(mock.ANY, vol)])
self.assertEqual(0, len(FakeVolumeMapping.volumes)) self.assertEqual(0, len(FakeVolumeMapping.volumes))
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.common.utils.spawn_n') @mock.patch('zun.common.utils.spawn_n')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(VolumeMapping, 'list_by_container', @mock.patch.object(VolumeMapping, 'list_by_container',
@ -360,7 +381,8 @@ class TestManager(base.TestCase):
def test_container_run_image_not_found( def test_container_run_image_not_found(
self, mock_pull, mock_is_volume_available, self, mock_pull, mock_is_volume_available,
mock_attach_volume, mock_detach_volume, mock_attach_volume, mock_detach_volume,
mock_list_by_container, mock_save, mock_spawn_n): mock_list_by_container, mock_save, mock_spawn_n, mock_event_finish,
mock_event_start):
container_dict = utils.get_test_container( container_dict = utils.get_test_container(
image='test:latest', image_driver='docker', image='test:latest', image_driver='docker',
image_pull_policy='ifnotpresent') image_pull_policy='ifnotpresent')
@ -386,6 +408,8 @@ class TestManager(base.TestCase):
mock_is_volume_available.assert_called_once() mock_is_volume_available.assert_called_once()
self.assertEqual(0, len(FakeVolumeMapping.volumes)) self.assertEqual(0, len(FakeVolumeMapping.volumes))
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.common.utils.spawn_n') @mock.patch('zun.common.utils.spawn_n')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(VolumeMapping, 'list_by_container', @mock.patch.object(VolumeMapping, 'list_by_container',
@ -397,7 +421,8 @@ class TestManager(base.TestCase):
def test_container_run_image_pull_exception_raised( def test_container_run_image_pull_exception_raised(
self, mock_pull, mock_is_volume_available, self, mock_pull, mock_is_volume_available,
mock_attach_volume, mock_detach_volume, mock_attach_volume, mock_detach_volume,
mock_list_by_container, mock_save, mock_spawn_n): mock_list_by_container, mock_save, mock_spawn_n, mock_event_finish,
mock_event_start):
container_dict = utils.get_test_container( container_dict = utils.get_test_container(
image='test:latest', image_driver='docker', image='test:latest', image_driver='docker',
image_pull_policy='ifnotpresent') image_pull_policy='ifnotpresent')
@ -423,6 +448,8 @@ class TestManager(base.TestCase):
mock_is_volume_available.assert_called_once() mock_is_volume_available.assert_called_once()
self.assertEqual(0, len(FakeVolumeMapping.volumes)) self.assertEqual(0, len(FakeVolumeMapping.volumes))
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.common.utils.spawn_n') @mock.patch('zun.common.utils.spawn_n')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(VolumeMapping, 'list_by_container', @mock.patch.object(VolumeMapping, 'list_by_container',
@ -434,7 +461,8 @@ class TestManager(base.TestCase):
def test_container_run_image_pull_docker_error( def test_container_run_image_pull_docker_error(
self, mock_pull, mock_is_volume_available, self, mock_pull, mock_is_volume_available,
mock_attach_volume, mock_detach_volume, mock_attach_volume, mock_detach_volume,
mock_list_by_container, mock_save, mock_spawn_n): mock_list_by_container, mock_save, mock_spawn_n, mock_event_finish,
mock_event_start):
container_dict = utils.get_test_container( container_dict = utils.get_test_container(
image='test:latest', image_driver='docker', image='test:latest', image_driver='docker',
image_pull_policy='ifnotpresent') image_pull_policy='ifnotpresent')
@ -460,6 +488,8 @@ class TestManager(base.TestCase):
mock_is_volume_available.assert_called_once() mock_is_volume_available.assert_called_once()
self.assertEqual(0, len(FakeVolumeMapping.volumes)) self.assertEqual(0, len(FakeVolumeMapping.volumes))
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.common.utils.spawn_n') @mock.patch('zun.common.utils.spawn_n')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(VolumeMapping, 'list_by_container', @mock.patch.object(VolumeMapping, 'list_by_container',
@ -472,7 +502,8 @@ class TestManager(base.TestCase):
def test_container_run_create_raises_docker_error( def test_container_run_create_raises_docker_error(
self, mock_create, mock_pull, mock_is_volume_available, self, mock_create, mock_pull, mock_is_volume_available,
mock_attach_volume, mock_detach_volume, mock_attach_volume, mock_detach_volume,
mock_list_by_container, mock_save, mock_spawn_n): mock_list_by_container, mock_save, mock_spawn_n,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance', image = {'image': 'repo', 'path': 'out_path', 'driver': 'glance',
'repo': 'test', 'tag': 'testtag'} 'repo': 'test', 'tag': 'testtag'}
@ -501,6 +532,8 @@ class TestManager(base.TestCase):
mock_is_volume_available.assert_called_once() mock_is_volume_available.assert_called_once()
self.assertEqual(0, len(FakeVolumeMapping.volumes)) self.assertEqual(0, len(FakeVolumeMapping.volumes))
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(FakeResourceTracker, @mock.patch.object(FakeResourceTracker,
'remove_usage_from_container') 'remove_usage_from_container')
@mock.patch.object(Container, 'destroy') @mock.patch.object(Container, 'destroy')
@ -509,7 +542,8 @@ class TestManager(base.TestCase):
@mock.patch.object(fake_driver, 'delete') @mock.patch.object(fake_driver, 'delete')
def test_container_delete( def test_container_delete(
self, mock_delete, mock_list_by_container, mock_save, self, mock_delete, mock_list_by_container, mock_save,
mock_cnt_destroy, mock_remove_usage): mock_cnt_destroy, mock_remove_usage, mock_event_finish,
mock_event_start):
mock_list_by_container.return_value = [] mock_list_by_container.return_value = []
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_delete(self. context, container, self.compute_manager._do_container_delete(self. context, container,
@ -520,6 +554,8 @@ class TestManager(base.TestCase):
mock_remove_usage.assert_called_once_with(self.context, container, mock_remove_usage.assert_called_once_with(self.context, container,
True) True)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(FakeResourceTracker, @mock.patch.object(FakeResourceTracker,
'remove_usage_from_container') 'remove_usage_from_container')
@mock.patch.object(Container, 'destroy') @mock.patch.object(Container, 'destroy')
@ -528,7 +564,8 @@ class TestManager(base.TestCase):
@mock.patch.object(fake_driver, 'delete') @mock.patch.object(fake_driver, 'delete')
def test_container_delete_failed(self, mock_delete, mock_save, def test_container_delete_failed(self, mock_delete, mock_save,
mock_fail, mock_destroy, mock_fail, mock_destroy,
mock_remove_usage): mock_remove_usage, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_delete.side_effect = exception.DockerError( mock_delete.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -541,6 +578,8 @@ class TestManager(base.TestCase):
mock_destroy.assert_not_called() mock_destroy.assert_not_called()
mock_remove_usage.assert_not_called() mock_remove_usage.assert_not_called()
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(FakeResourceTracker, @mock.patch.object(FakeResourceTracker,
'remove_usage_from_container') 'remove_usage_from_container')
@mock.patch.object(Container, 'destroy') @mock.patch.object(Container, 'destroy')
@ -552,7 +591,9 @@ class TestManager(base.TestCase):
mock_list_by_container, mock_list_by_container,
mock_save, mock_save,
mock_fail, mock_destroy, mock_fail, mock_destroy,
mock_remove_usage): mock_remove_usage,
mock_event_finish,
mock_event_start):
mock_list_by_container.return_value = [] mock_list_by_container.return_value = []
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_delete.side_effect = exception.DockerError( mock_delete.side_effect = exception.DockerError(
@ -566,6 +607,8 @@ class TestManager(base.TestCase):
mock_remove_usage.assert_called_once_with(self.context, container, mock_remove_usage.assert_called_once_with(self.context, container,
True) True)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(FakeResourceTracker, @mock.patch.object(FakeResourceTracker,
'remove_usage_from_container') 'remove_usage_from_container')
@mock.patch.object(Container, 'destroy') @mock.patch.object(Container, 'destroy')
@ -576,7 +619,9 @@ class TestManager(base.TestCase):
def test_container_delete_sandbox_failed(self, mock_delete, mock_save, def test_container_delete_sandbox_failed(self, mock_delete, mock_save,
mock_delete_sandbox, mock_delete_sandbox,
mock_fail, mock_destroy, mock_fail, mock_destroy,
mock_remove_usage): mock_remove_usage,
mock_event_finish,
mock_event_start):
self.compute_manager.use_sandbox = True self.compute_manager.use_sandbox = True
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
container.set_sandbox_id("sandbox_id") container.set_sandbox_id("sandbox_id")
@ -591,6 +636,8 @@ class TestManager(base.TestCase):
mock_destroy.assert_not_called() mock_destroy.assert_not_called()
mock_remove_usage.assert_not_called() mock_remove_usage.assert_not_called()
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(FakeResourceTracker, @mock.patch.object(FakeResourceTracker,
'remove_usage_from_container') 'remove_usage_from_container')
@mock.patch.object(Container, 'destroy') @mock.patch.object(Container, 'destroy')
@ -604,7 +651,9 @@ class TestManager(base.TestCase):
mock_save, mock_save,
mock_delete_sandbox, mock_delete_sandbox,
mock_fail, mock_destroy, mock_fail, mock_destroy,
mock_remove_usage): mock_remove_usage,
mock_event_finish,
mock_event_start):
mock_list_by_container.return_value = [] mock_list_by_container.return_value = []
self.compute_manager.use_sandbox = True self.compute_manager.use_sandbox = True
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
@ -643,19 +692,25 @@ class TestManager(base.TestCase):
self.compute_manager.container_show, self.compute_manager.container_show,
self.context, container) self.context, container)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(fake_driver, 'reboot') @mock.patch.object(fake_driver, 'reboot')
def test_container_reboot(self, mock_reboot, mock_save): def test_container_reboot(self, mock_reboot, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_reboot(self.context, container, 10) self.compute_manager._do_container_reboot(self.context, container, 10)
mock_save.assert_called_with(self.context) mock_save.assert_called_with(self.context)
mock_reboot.assert_called_once_with(self.context, container, 10) mock_reboot.assert_called_once_with(self.context, container, 10)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(fake_driver, 'reboot') @mock.patch.object(fake_driver, 'reboot')
def test_container_reboot_failed(self, mock_reboot, mock_save, def test_container_reboot_failed(self, mock_reboot, mock_save,
mock_fail): mock_fail, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_reboot.side_effect = exception.DockerError( mock_reboot.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -666,18 +721,24 @@ class TestManager(base.TestCase):
mock_fail.assert_called_with(self.context, mock_fail.assert_called_with(self.context,
container, 'Docker Error occurred') container, 'Docker Error occurred')
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(fake_driver, 'stop') @mock.patch.object(fake_driver, 'stop')
def test_container_stop(self, mock_stop, mock_save): def test_container_stop(self, mock_stop, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_stop(self.context, container, 10) self.compute_manager._do_container_stop(self.context, container, 10)
mock_save.assert_called_with(self.context) mock_save.assert_called_with(self.context)
mock_stop.assert_called_once_with(self.context, container, 10) mock_stop.assert_called_once_with(self.context, container, 10)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(fake_driver, 'stop') @mock.patch.object(fake_driver, 'stop')
def test_container_stop_failed(self, mock_stop, mock_save, mock_fail): def test_container_stop_failed(self, mock_stop, mock_save, mock_fail,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_stop.side_effect = exception.DockerError( mock_stop.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -688,19 +749,25 @@ class TestManager(base.TestCase):
mock_fail.assert_called_with(self.context, mock_fail.assert_called_with(self.context,
container, 'Docker Error occurred') container, 'Docker Error occurred')
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(fake_driver, 'start') @mock.patch.object(fake_driver, 'start')
def test_container_start(self, mock_start, mock_save): def test_container_start(self, mock_start, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_start(self.context, container) self.compute_manager._do_container_start(self.context, container)
mock_save.assert_called_with(self.context) mock_save.assert_called_with(self.context)
mock_start.assert_called_once_with(self.context, container) mock_start.assert_called_once_with(self.context, container)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(Container, 'save') @mock.patch.object(Container, 'save')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
@mock.patch.object(fake_driver, 'start') @mock.patch.object(fake_driver, 'start')
def test_container_start_failed(self, mock_start, def test_container_start_failed(self, mock_start,
mock_fail, mock_save): mock_fail, mock_save, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_start.side_effect = exception.DockerError( mock_start.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -711,15 +778,21 @@ class TestManager(base.TestCase):
mock_fail.assert_called_with(self.context, mock_fail.assert_called_with(self.context,
container, 'Docker Error occurred') container, 'Docker Error occurred')
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(fake_driver, 'pause') @mock.patch.object(fake_driver, 'pause')
def test_container_pause(self, mock_pause): def test_container_pause(self, mock_pause, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_pause(self.context, container) self.compute_manager._do_container_pause(self.context, container)
mock_pause.assert_called_once_with(self.context, container) mock_pause.assert_called_once_with(self.context, container)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
@mock.patch.object(fake_driver, 'pause') @mock.patch.object(fake_driver, 'pause')
def test_container_pause_failed(self, mock_pause, mock_fail): def test_container_pause_failed(self, mock_pause, mock_fail,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_pause.side_effect = exception.DockerError( mock_pause.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -729,15 +802,21 @@ class TestManager(base.TestCase):
mock_fail.assert_called_with(self.context, mock_fail.assert_called_with(self.context,
container, 'Docker Error occurred') container, 'Docker Error occurred')
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(fake_driver, 'unpause') @mock.patch.object(fake_driver, 'unpause')
def test_container_unpause(self, mock_unpause): def test_container_unpause(self, mock_unpause, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_unpause(self.context, container) self.compute_manager._do_container_unpause(self.context, container)
mock_unpause.assert_called_once_with(self.context, container) mock_unpause.assert_called_once_with(self.context, container)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
@mock.patch.object(fake_driver, 'unpause') @mock.patch.object(fake_driver, 'unpause')
def test_container_unpause_failed(self, mock_unpause, mock_fail): def test_container_unpause_failed(self, mock_unpause, mock_fail,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_unpause.side_effect = exception.DockerError( mock_unpause.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -785,15 +864,21 @@ class TestManager(base.TestCase):
self.compute_manager.container_exec, self.compute_manager.container_exec,
self.context, container, 'fake_cmd', True, False) self.context, container, 'fake_cmd', True, False)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(fake_driver, 'kill') @mock.patch.object(fake_driver, 'kill')
def test_container_kill(self, mock_kill): def test_container_kill(self, mock_kill, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager._do_container_kill(self.context, container, None) self.compute_manager._do_container_kill(self.context, container, None)
mock_kill.assert_called_once_with(self.context, container, None) mock_kill.assert_called_once_with(self.context, container, None)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(manager.Manager, '_fail_container') @mock.patch.object(manager.Manager, '_fail_container')
@mock.patch.object(fake_driver, 'kill') @mock.patch.object(fake_driver, 'kill')
def test_container_kill_failed(self, mock_kill, mock_fail): def test_container_kill_failed(self, mock_kill, mock_fail,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_kill.side_effect = exception.DockerError( mock_kill.side_effect = exception.DockerError(
message="Docker Error occurred") message="Docker Error occurred")
@ -897,11 +982,14 @@ class TestManager(base.TestCase):
self.compute_manager.container_exec_resize, self.compute_manager.container_exec_resize,
self.context, 'fake_exec_id', "100", "100") self.context, 'fake_exec_id', "100", "100")
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.image.driver.upload_image_data') @mock.patch('zun.image.driver.upload_image_data')
@mock.patch.object(fake_driver, 'get_image') @mock.patch.object(fake_driver, 'get_image')
@mock.patch.object(fake_driver, 'commit') @mock.patch.object(fake_driver, 'commit')
def test_container_commit(self, mock_commit, def test_container_commit(self, mock_commit,
mock_get_image, mock_upload_image_data): mock_get_image, mock_upload_image_data,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_get_image_response = mock.MagicMock() mock_get_image_response = mock.MagicMock()
mock_get_image_response.data = StringIO().read() mock_get_image_response.data = StringIO().read()
@ -914,24 +1002,36 @@ class TestManager(base.TestCase):
mock_commit.assert_called_once_with( mock_commit.assert_called_once_with(
self.context, container, 'repo', 'tag') self.context, container, 'repo', 'tag')
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch('zun.image.driver.delete_image') @mock.patch('zun.image.driver.delete_image')
@mock.patch.object(fake_driver, 'commit') @mock.patch.object(fake_driver, 'commit')
def test_container_commit_failed(self, mock_commit, mock_delete): def test_container_commit_failed(self, mock_commit, mock_delete,
mock_event_finish, mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
mock_get_image_response = mock.MagicMock()
mock_get_image_response.data = StringIO().read()
mock_commit.side_effect = exception.DockerError mock_commit.side_effect = exception.DockerError
self.assertRaises(exception.DockerError, self.assertRaises(exception.DockerError,
self.compute_manager._do_container_commit, self.compute_manager._do_container_commit,
self.context, container, 'repo', 'tag') self.context, mock_get_image_response, container,
'repo', 'tag')
self.assertTrue(mock_delete.called) self.assertTrue(mock_delete.called)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(fake_driver, 'network_detach') @mock.patch.object(fake_driver, 'network_detach')
def test_container_network_detach(self, mock_detach): def test_container_network_detach(self, mock_detach, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager.network_detach(self.context, container, 'network') self.compute_manager.network_detach(self.context, container, 'network')
mock_detach.assert_called_once_with(self.context, container, mock.ANY) mock_detach.assert_called_once_with(self.context, container, mock.ANY)
@mock.patch.object(ContainerActionEvent, 'event_start')
@mock.patch.object(ContainerActionEvent, 'event_finish')
@mock.patch.object(fake_driver, 'network_attach') @mock.patch.object(fake_driver, 'network_attach')
def test_container_network_attach(self, mock_attach): def test_container_network_attach(self, mock_attach, mock_event_finish,
mock_event_start):
container = Container(self.context, **utils.get_test_container()) container = Container(self.context, **utils.get_test_container())
self.compute_manager.network_attach(self.context, container, 'network') self.compute_manager.network_attach(self.context, container, 'network')