Merge "Add support for container status"
This commit is contained in:
commit
3149306307
|
@ -85,6 +85,9 @@ class Container(base.APIBase):
|
|||
command = wtypes.text
|
||||
"""The command execute when container starts"""
|
||||
|
||||
status = wtypes.text
|
||||
"""The status of container"""
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.fields = []
|
||||
for field in objects.Container.fields:
|
||||
|
@ -98,7 +101,7 @@ class Container(base.APIBase):
|
|||
def _convert_with_links(container, url, expand=True):
|
||||
if not expand:
|
||||
container.unset_fields_except(['uuid', 'name', 'bay_uuid',
|
||||
'image_id', 'command'])
|
||||
'image_id', 'command', 'status'])
|
||||
|
||||
container.links = [link.Link.make_link('self', url,
|
||||
'containers', container.uuid),
|
||||
|
@ -120,6 +123,7 @@ class Container(base.APIBase):
|
|||
name='example',
|
||||
image_id='ubuntu',
|
||||
command='env',
|
||||
status='Running',
|
||||
bay_uuid="fff114da-3bfa-4a0f-a123-c0dffad9718e",
|
||||
created_at=datetime.datetime.utcnow(),
|
||||
updated_at=datetime.datetime.utcnow())
|
||||
|
@ -280,6 +284,8 @@ class ContainersController(rest.RestController):
|
|||
containers = objects.Container.list(pecan.request.context, limit,
|
||||
marker_obj, sort_key=sort_key,
|
||||
sort_dir=sort_dir)
|
||||
containers = [pecan.request.rpcapi.container_show(c.uuid)
|
||||
for c in containers]
|
||||
|
||||
return ContainerCollection.convert_with_links(containers, limit,
|
||||
url=resource_url,
|
||||
|
@ -299,7 +305,7 @@ class ContainersController(rest.RestController):
|
|||
:param sort_dir: direction to sort. "asc" or "desc". Default: asc.
|
||||
"""
|
||||
return self._get_containers_collection(marker, limit, sort_key,
|
||||
sort_dir)
|
||||
sort_dir)
|
||||
|
||||
@wsme_pecan.wsexpose(ContainerCollection, types.uuid,
|
||||
types.uuid, int, wtypes.text, wtypes.text)
|
||||
|
@ -335,7 +341,8 @@ class ContainersController(rest.RestController):
|
|||
|
||||
rpc_container = api_utils.get_rpc_resource('Container',
|
||||
container_ident)
|
||||
return Container.convert_with_links(rpc_container)
|
||||
res_container = pecan.request.rpcapi.container_show(rpc_container.uuid)
|
||||
return Container.convert_with_links(res_container)
|
||||
|
||||
@wsme_pecan.wsexpose(Container, body=Container, status_code=201)
|
||||
def post(self, container):
|
||||
|
|
|
@ -20,6 +20,7 @@ from magnum.common import exception
|
|||
from magnum.common import utils
|
||||
from magnum.conductor.handlers.common import docker_client
|
||||
from magnum import objects
|
||||
from magnum.objects import container as obj_container
|
||||
from magnum.openstack.common import log as logging
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
@ -102,10 +103,14 @@ class Handler(object):
|
|||
docker.create_container(image_id, name=name,
|
||||
hostname=container_uuid,
|
||||
command=container.command)
|
||||
container.status = obj_container.STOPPED
|
||||
return container
|
||||
except errors.APIError as api_error:
|
||||
container.status = obj_container.ERROR
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
finally:
|
||||
container.save()
|
||||
|
||||
def container_delete(self, context, container_uuid):
|
||||
LOG.debug("container_delete %s" % container_uuid)
|
||||
|
@ -122,63 +127,64 @@ class Handler(object):
|
|||
def container_show(self, context, container_uuid):
|
||||
LOG.debug("container_show %s" % container_uuid)
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
container = objects.Container.get_by_uuid(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
return docker.inspect_container(docker_id)
|
||||
result = docker.inspect_container(docker_id)
|
||||
status = result.get('State')
|
||||
if status:
|
||||
if status.get('Error') is True:
|
||||
container.status = obj_container.ERROR
|
||||
elif status.get('Running'):
|
||||
container.status = obj_container.RUNNING
|
||||
elif status.get('Paused'):
|
||||
container.status = obj_container.PAUSED
|
||||
else:
|
||||
container.status = obj_container.STOPPED
|
||||
container.save()
|
||||
return container
|
||||
except errors.APIError as api_error:
|
||||
error_message = str(api_error)
|
||||
if '404' in error_message:
|
||||
container.status = obj_container.ERROR
|
||||
container.save()
|
||||
return container
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % (error_message))
|
||||
|
||||
def _container_action(self, context, container_uuid, status, docker_func):
|
||||
LOG.debug("container_%s %s" % (status, container_uuid))
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
result = getattr(docker, docker_func)(docker_id)
|
||||
container = objects.Container.get_by_uuid(context, container_uuid)
|
||||
container.status = status
|
||||
container.save()
|
||||
return result
|
||||
except errors.APIError as api_error:
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
|
||||
def container_reboot(self, context, container_uuid):
|
||||
LOG.debug("container_reboot %s" % container_uuid)
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
return docker.restart(docker_id)
|
||||
except errors.APIError as api_error:
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
return self._container_action(context, container_uuid,
|
||||
obj_container.RUNNING, 'restart')
|
||||
|
||||
def container_stop(self, context, container_uuid):
|
||||
LOG.debug("container_stop %s" % container_uuid)
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
return docker.stop(docker_id)
|
||||
except errors.APIError as api_error:
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
return self._container_action(context, container_uuid,
|
||||
obj_container.STOPPED, 'stop')
|
||||
|
||||
def container_start(self, context, container_uuid):
|
||||
LOG.debug("Starting container %s" % container_uuid)
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
LOG.debug("Found Docker container %s" % docker_id)
|
||||
return docker.start(docker_id)
|
||||
except errors.APIError as api_error:
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
return self._container_action(context, container_uuid,
|
||||
obj_container.RUNNING, 'start')
|
||||
|
||||
def container_pause(self, context, container_uuid):
|
||||
LOG.debug("container_pause %s" % container_uuid)
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
return docker.pause(docker_id)
|
||||
except errors.APIError as api_error:
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
return self._container_action(context, container_uuid,
|
||||
obj_container.PAUSED, 'pause')
|
||||
|
||||
def container_unpause(self, context, container_uuid):
|
||||
LOG.debug("container_unpause %s" % container_uuid)
|
||||
docker = self.get_docker_client(context, container_uuid)
|
||||
try:
|
||||
docker_id = self._find_container_by_name(docker, container_uuid)
|
||||
return docker.unpause(docker_id)
|
||||
except errors.APIError as api_error:
|
||||
raise exception.ContainerException(
|
||||
"Docker API Error : %s" % str(api_error))
|
||||
return self._container_action(context, container_uuid,
|
||||
obj_container.RUNNING, 'unpause')
|
||||
|
||||
def container_logs(self, context, container_uuid):
|
||||
LOG.debug("container_logs %s" % container_uuid)
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
# 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.
|
||||
|
||||
"""add_container_status
|
||||
|
||||
Revision ID: 59e7664a8ba1
|
||||
Revises: 2b5f24dd95de
|
||||
Create Date: 2015-05-11 11:33:23.125790
|
||||
|
||||
"""
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision = '59e7664a8ba1'
|
||||
down_revision = '2b5f24dd95de'
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
def upgrade():
|
||||
op.add_column('container',
|
||||
sa.Column('status', sa.String(length=20),
|
||||
nullable=True))
|
|
@ -188,6 +188,7 @@ class Container(Base):
|
|||
image_id = Column(String(255))
|
||||
command = Column(String(255))
|
||||
bay_uuid = Column(String(36))
|
||||
status = Column(String(20))
|
||||
|
||||
|
||||
class Node(Base):
|
||||
|
|
|
@ -19,6 +19,13 @@ from magnum.db import api as dbapi
|
|||
from magnum.objects import base
|
||||
|
||||
|
||||
# possible status
|
||||
ERROR = 'Error'
|
||||
RUNNING = 'Running'
|
||||
STOPPED = 'Stopped'
|
||||
PAUSED = 'Paused'
|
||||
|
||||
|
||||
@base.MagnumObjectRegistry.register
|
||||
class Container(base.MagnumPersistentObject, base.MagnumObject,
|
||||
base.MagnumObjectDictCompat):
|
||||
|
@ -36,6 +43,7 @@ class Container(base.MagnumPersistentObject, base.MagnumObject,
|
|||
'image_id': fields.StringField(nullable=True),
|
||||
'command': fields.StringField(nullable=True),
|
||||
'bay_uuid': fields.StringField(nullable=True),
|
||||
'status': fields.StringField(nullable=True),
|
||||
}
|
||||
|
||||
@staticmethod
|
||||
|
|
|
@ -45,11 +45,13 @@ class TestContainerController(db_base.DbTestCase):
|
|||
self.assertEqual(response.status_int, 201)
|
||||
self.assertTrue(mock_container_create.called)
|
||||
|
||||
@patch('magnum.conductor.api.API.container_show')
|
||||
@patch('magnum.conductor.api.API.container_create')
|
||||
@patch('magnum.conductor.api.API.container_delete')
|
||||
def test_create_container_with_command(self,
|
||||
mock_container_delete,
|
||||
mock_container_create):
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
# Create a container with a command
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
|
@ -60,6 +62,9 @@ class TestContainerController(db_base.DbTestCase):
|
|||
content_type='application/json')
|
||||
self.assertEqual(response.status_int, 201)
|
||||
# get all containers
|
||||
container = objects.Container.list(self.context)[0]
|
||||
container.status = 'Stopped'
|
||||
mock_container_show.return_value = container
|
||||
response = self.app.get('/v1/containers')
|
||||
self.assertEqual(response.status_int, 200)
|
||||
self.assertEqual(1, len(response.json))
|
||||
|
@ -67,6 +72,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
self.assertIsNotNone(c.get('uuid'))
|
||||
self.assertEqual('My Docker', c.get('name'))
|
||||
self.assertEqual('env', c.get('command'))
|
||||
self.assertEqual('Stopped', c.get('status'))
|
||||
# Delete the container we created
|
||||
response = self.app.delete('/v1/containers/%s' % c.get('uuid'))
|
||||
self.assertEqual(response.status_int, 204)
|
||||
|
@ -77,11 +83,13 @@ class TestContainerController(db_base.DbTestCase):
|
|||
self.assertEqual(0, len(c))
|
||||
self.assertTrue(mock_container_create.called)
|
||||
|
||||
@patch('magnum.conductor.api.API.container_show')
|
||||
@patch('magnum.conductor.api.API.container_create')
|
||||
@patch('magnum.conductor.api.API.container_delete')
|
||||
def test_create_container_with_bay_uuid(self,
|
||||
mock_container_delete,
|
||||
mock_container_create):
|
||||
mock_container_delete,
|
||||
mock_container_create,
|
||||
mock_container_show):
|
||||
mock_container_create.side_effect = lambda x, y, z: z
|
||||
# Create a container with a command
|
||||
params = ('{"name": "My Docker", "image_id": "ubuntu",'
|
||||
|
@ -92,6 +100,9 @@ class TestContainerController(db_base.DbTestCase):
|
|||
content_type='application/json')
|
||||
self.assertEqual(response.status_int, 201)
|
||||
# get all containers
|
||||
container = objects.Container.list(self.context)[0]
|
||||
container.status = 'Stopped'
|
||||
mock_container_show.return_value = container
|
||||
response = self.app.get('/v1/containers')
|
||||
self.assertEqual(response.status_int, 200)
|
||||
self.assertEqual(1, len(response.json))
|
||||
|
@ -99,6 +110,7 @@ class TestContainerController(db_base.DbTestCase):
|
|||
self.assertIsNotNone(c.get('uuid'))
|
||||
self.assertEqual('My Docker', c.get('name'))
|
||||
self.assertEqual('env', c.get('command'))
|
||||
self.assertEqual('Stopped', c.get('status'))
|
||||
# Delete the container we created
|
||||
response = self.app.delete('/v1/containers/%s' % c.get('uuid'))
|
||||
self.assertEqual(response.status_int, 204)
|
||||
|
@ -128,11 +140,14 @@ class TestContainerController(db_base.DbTestCase):
|
|||
params=params, content_type='application/json')
|
||||
self.assertTrue(mock_container_create.not_called)
|
||||
|
||||
@patch('magnum.conductor.api.API.container_show')
|
||||
@patch('magnum.objects.Container.list')
|
||||
def test_get_all_containers(self, mock_container_list):
|
||||
def test_get_all_containers(self, mock_container_list,
|
||||
mock_container_show):
|
||||
test_container = utils.get_test_container()
|
||||
containers = [objects.Container(self.context, **test_container)]
|
||||
mock_container_list.return_value = containers
|
||||
mock_container_show.return_value = containers[0]
|
||||
|
||||
response = self.app.get('/v1/containers')
|
||||
|
||||
|
@ -145,11 +160,14 @@ class TestContainerController(db_base.DbTestCase):
|
|||
self.assertEqual(actual_containers[0].get('uuid'),
|
||||
test_container['uuid'])
|
||||
|
||||
@patch('magnum.conductor.api.API.container_show')
|
||||
@patch('magnum.objects.Container.get_by_uuid')
|
||||
def test_get_one_by_uuid(self, mock_container_get_by_uuid):
|
||||
def test_get_one_by_uuid(self, mock_container_get_by_uuid,
|
||||
mock_container_show):
|
||||
test_container = utils.get_test_container()
|
||||
test_container_obj = objects.Container(self.context, **test_container)
|
||||
mock_container_get_by_uuid.return_value = test_container_obj
|
||||
mock_container_show.return_value = test_container_obj
|
||||
|
||||
response = self.app.get('/v1/containers/%s' % test_container['uuid'])
|
||||
|
||||
|
@ -159,11 +177,14 @@ class TestContainerController(db_base.DbTestCase):
|
|||
self.assertEqual(response.json['uuid'],
|
||||
test_container['uuid'])
|
||||
|
||||
@patch('magnum.conductor.api.API.container_show')
|
||||
@patch('magnum.objects.Container.get_by_name')
|
||||
def test_get_one_by_name(self, mock_container_get_by_name):
|
||||
def test_get_one_by_name(self, mock_container_get_by_name,
|
||||
mock_container_show):
|
||||
test_container = utils.get_test_container()
|
||||
test_container_obj = objects.Container(self.context, **test_container)
|
||||
mock_container_get_by_name.return_value = test_container_obj
|
||||
mock_container_show.return_value = test_container_obj
|
||||
|
||||
response = self.app.get('/v1/containers/%s' % test_container['name'])
|
||||
|
||||
|
|
|
@ -17,6 +17,8 @@ from oslo_config import cfg
|
|||
|
||||
from magnum.common import exception
|
||||
from magnum.conductor.handlers import docker_conductor
|
||||
from magnum import objects
|
||||
from magnum.objects import container as obj_container
|
||||
from magnum.tests import base
|
||||
from mock import patch
|
||||
|
||||
|
@ -111,18 +113,19 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container.image_id = 'test_image:some_tag'
|
||||
mock_container.command = None
|
||||
|
||||
self.conductor.container_create(None, 'some-name', 'some-uuid',
|
||||
mock_container)
|
||||
container = self.conductor.container_create(None, 'some-name',
|
||||
'some-uuid', mock_container)
|
||||
|
||||
utf8_image_id = self.conductor._encode_utf8(mock_container.image_id)
|
||||
mock_docker.pull.assert_called_once_with('test_image',
|
||||
tag='some_tag')
|
||||
tag='some_tag')
|
||||
mock_docker.inspect_image.assert_called_once_with(utf8_image_id)
|
||||
mock_docker.create_container.assert_called_once_with(
|
||||
mock_container.image_id,
|
||||
name='some-name',
|
||||
hostname='some-uuid',
|
||||
command=None)
|
||||
self.assertEqual(obj_container.STOPPED, container.status)
|
||||
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_create_with_command(self, mock_get_docker_client):
|
||||
|
@ -133,8 +136,8 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container.image_id = 'test_image:some_tag'
|
||||
mock_container.command = 'env'
|
||||
|
||||
self.conductor.container_create(None, 'some-name', 'some-uuid',
|
||||
mock_container)
|
||||
container = self.conductor.container_create(None, 'some-name',
|
||||
'some-uuid', mock_container)
|
||||
|
||||
utf8_image_id = self.conductor._encode_utf8(mock_container.image_id)
|
||||
mock_docker.pull.assert_called_once_with('test_image',
|
||||
|
@ -145,6 +148,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
name='some-name',
|
||||
hostname='some-uuid',
|
||||
command='env')
|
||||
self.assertEqual(obj_container.STOPPED, container.status)
|
||||
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_create_with_failure(self, mock_get_docker_client):
|
||||
|
@ -165,8 +169,9 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
tag='some_tag')
|
||||
self.assertFalse(mock_docker.create_container.called)
|
||||
mock_init.assert_called_once_with()
|
||||
self.assertEqual(obj_container.ERROR, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_delete(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
|
@ -220,12 +225,32 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_action(self, mock_get_docker_client,
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
self.conductor._container_action(None, mock_container_uuid,
|
||||
'fake-status', 'fake-func')
|
||||
self.assertEqual('fake-status', mock_container.status)
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_reboot(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
|
@ -233,6 +258,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_docker.restart.assert_called_once_with(mock_docker_id)
|
||||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
self.assertEqual(obj_container.RUNNING, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
|
@ -257,12 +283,15 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_start(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
|
@ -270,6 +299,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_docker.start.assert_called_once_with(mock_docker_id)
|
||||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
self.assertEqual(obj_container.RUNNING, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
|
@ -294,12 +324,15 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_stop(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
|
@ -307,6 +340,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_docker.stop.assert_called_once_with(mock_docker_id)
|
||||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
self.assertEqual(obj_container.STOPPED, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
|
@ -330,12 +364,15 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_pause(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
|
@ -343,6 +380,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_docker.pause.assert_called_once_with(mock_docker_id)
|
||||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
self.assertEqual(obj_container.PAUSED, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
|
@ -366,12 +404,15 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_unpause(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
|
@ -379,6 +420,7 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_docker.unpause.assert_called_once_with(mock_docker_id)
|
||||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
self.assertEqual(obj_container.RUNNING, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
|
@ -403,12 +445,15 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container, mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
|
@ -418,13 +463,96 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@mock.patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show_with_running_state(self, mock_get_docker_client,
|
||||
mock_find_container,
|
||||
mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
mock_container_detail = {'State': {'Error': '',
|
||||
'Running': True,
|
||||
'Paused': False}}
|
||||
mock_docker.inspect_container.return_value = mock_container_detail
|
||||
self.conductor.container_show(None, mock_container_uuid)
|
||||
self.assertEqual(obj_container.RUNNING, mock_container.status)
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@mock.patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show_with_stop_state(self, mock_get_docker_client,
|
||||
mock_find_container,
|
||||
mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
mock_container_detail = {'State': {'Error': '',
|
||||
'Running': False,
|
||||
'Paused': False}}
|
||||
mock_docker.inspect_container.return_value = mock_container_detail
|
||||
self.conductor.container_show(None, mock_container_uuid)
|
||||
self.assertEqual(obj_container.STOPPED, mock_container.status)
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@mock.patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show_with_pause_state(self, mock_get_docker_client,
|
||||
mock_find_container,
|
||||
mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
mock_container_detail = {'State': {'Error': '',
|
||||
'Running': False,
|
||||
'Paused': True}}
|
||||
mock_docker.inspect_container.return_value = mock_container_detail
|
||||
self.conductor.container_show(None, mock_container_uuid)
|
||||
self.assertEqual(obj_container.PAUSED, mock_container.status)
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@mock.patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show_with_error_status(self, mock_get_docker_client,
|
||||
mock_find_container,
|
||||
mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
mock_container_detail = {'State': {'Error': True,
|
||||
'Running': False,
|
||||
'Paused': False}}
|
||||
mock_docker.inspect_container.return_value = mock_container_detail
|
||||
self.conductor.container_show(None, mock_container_uuid)
|
||||
self.assertEqual(obj_container.ERROR, mock_container.status)
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show_with_failure(self, mock_get_docker_client,
|
||||
mock_find_container):
|
||||
mock_find_container,
|
||||
mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-16b02ad20ca1'
|
||||
mock_get_by_uuid.return_value = mock.MagicMock()
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-1d6b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
with patch.object(errors.APIError, '__str__',
|
||||
|
@ -440,6 +568,31 @@ class TestDockerConductor(base.BaseTestCase):
|
|||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
|
||||
@mock.patch.object(objects.Container, 'get_by_uuid')
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_show_with_not_found(self, mock_get_docker_client,
|
||||
mock_find_container,
|
||||
mock_get_by_uuid):
|
||||
mock_docker = mock.MagicMock()
|
||||
mock_get_docker_client.return_value = mock_docker
|
||||
mock_container = mock.MagicMock()
|
||||
mock_get_by_uuid.return_value = mock_container
|
||||
mock_container_uuid = 'd545a92d-609a-428f-8edb-1d6b02ad20ca1'
|
||||
mock_docker_id = '2703ef2b705d'
|
||||
mock_find_container.return_value = mock_docker_id
|
||||
with patch.object(errors.APIError, '__str__',
|
||||
return_value='404 error') as mock_init:
|
||||
mock_docker.inspect_container = mock.Mock(side_effect=
|
||||
errors.APIError('Error', '', ''))
|
||||
self.conductor.container_show(None, mock_container_uuid)
|
||||
mock_docker.inspect_container.assert_called_once_with(
|
||||
mock_docker_id)
|
||||
mock_find_container.assert_called_once_with(mock_docker,
|
||||
mock_container_uuid)
|
||||
mock_init.assert_called_once_with()
|
||||
self.assertEqual(obj_container.ERROR, mock_container.status)
|
||||
|
||||
@patch.object(docker_conductor.Handler, '_find_container_by_name')
|
||||
@mock.patch.object(docker_conductor.Handler, 'get_docker_client')
|
||||
def test_container_execute(self, mock_get_docker_client,
|
||||
|
|
|
@ -186,6 +186,7 @@ def get_test_container(**kw):
|
|||
'updated_at': kw.get('updated_at'),
|
||||
'command': kw.get('command', 'fake_command'),
|
||||
'bay_uuid': kw.get('bay_uuid', 'fff114da-3bfa-4a0f-a123-c0dffad9718e'),
|
||||
'status': kw.get('state', 'Running'),
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue