zun/zun/tests/unit/common/test_utils.py

265 lines
12 KiB
Python

# Copyright 2016 IBM, Corp.
#
# 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 mock import patch
import pecan
from zun.common import exception
from zun.common import utils
from zun.common.utils import check_container_id
from zun.common.utils import translate_exception
import zun.conf
from zun import objects
from zun.objects.container import Container
from zun.tests import base
from zun.tests.unit.db import utils as db_utils
from zun.tests.unit.objects import utils as obj_utils
CONF = zun.conf.CONF
class TestUtils(base.TestCase):
"""Test cases for zun.common.utils"""
def test_check_container_id(self):
@check_container_id
def foo(self, context, container):
pass
fake_container = mock.MagicMock()
fake_container.container_id = None
self.assertRaises(exception.Invalid, foo,
self, self.context, fake_container)
def test_translate_exception(self):
@translate_exception
def foo(self, context):
raise TypeError()
self.assertRaises(exception.ZunException, foo,
self, mock.MagicMock())
def test_parse_image_name(self):
self.assertEqual(('test', 'latest'),
utils.parse_image_name('test:latest'))
self.assertEqual(('test', 'latest'),
utils.parse_image_name('test'))
self.assertEqual(('test', 'test'),
utils.parse_image_name('test:test'))
self.assertEqual(('test-test', 'test'),
utils.parse_image_name('test-test:test'))
def test_parse_image_name_with_default_registry(self):
CONF.set_override('default_registry', 'test.io', group='docker')
self.assertEqual(('test.io/test', 'latest'),
utils.parse_image_name('test'))
self.assertEqual(('test.io/test/test', 'latest'),
utils.parse_image_name('test/test'))
self.assertEqual(('other.com/test/test', 'latest'),
utils.parse_image_name('other.com/test/test'))
def test_parse_image_name_with_custom_registry(self):
registry = obj_utils.get_test_registry(self.context, domain='test.io')
self.assertEqual(('test.io/test', 'latest'),
utils.parse_image_name('test', registry=registry))
self.assertEqual(('test.io/test/test', 'latest'),
utils.parse_image_name('test/test',
registry=registry))
self.assertEqual(('other.com/test/test', 'latest'),
utils.parse_image_name('other.com/test/test',
registry=registry))
def test_get_image_pull_policy(self):
self.assertEqual('always',
utils.get_image_pull_policy('always',
'latest'))
self.assertEqual('always',
utils.get_image_pull_policy(None,
'latest'))
self.assertEqual('ifnotpresent',
utils.get_image_pull_policy(None,
'2.0'))
def test_should_pull_image(self):
self.assertFalse(utils.should_pull_image('never', True))
self.assertFalse(utils.should_pull_image('never', False))
self.assertTrue(utils.should_pull_image('always', True))
self.assertTrue(utils.should_pull_image('always', False))
self.assertTrue(utils.should_pull_image('ifnotpresent', False))
self.assertFalse(utils.should_pull_image('ifnotpresent', True))
def test_validate_container_state(self):
container = Container(self.context, **db_utils.get_test_container())
container.status = 'Stopped'
with self.assertRaisesRegex(exception.InvalidStateException,
"%s" % container.uuid):
utils.validate_container_state(container, 'stop')
with self.assertRaisesRegex(exception.InvalidStateException,
"%s" % container.uuid):
utils.validate_container_state(container, 'pause')
container.status = 'Running'
with self.assertRaisesRegex(exception.InvalidStateException,
"%s" % container.uuid):
utils.validate_container_state(container, 'start')
with self.assertRaisesRegex(exception.InvalidStateException,
"%s" % container.uuid):
utils.validate_container_state(container, 'unpause')
with self.assertRaisesRegex(exception.InvalidStateException,
"%s" % container.uuid):
utils.validate_container_state(container, 'delete')
self.assertIsNone(utils.validate_container_state(
container, 'reboot'))
container.status = 'Stopped'
self.assertIsNone(utils.validate_container_state(
container, 'reboot'))
container.status = 'Running'
self.assertIsNone(utils.validate_container_state(
container, 'execute'))
@mock.patch('zun.common.clients.OpenStackClients.neutron')
def test_get_security_group_ids(self, mock_neutron_client):
security_groups = None
self.assertIsNone(utils.get_security_group_ids(self.context,
security_groups))
security_groups = ['test_security_group_name']
neutron_client_instance = mock.MagicMock()
neutron_client_instance.list_security_groups.return_value = \
{'security_groups': [{'id': 'test_security_group_id',
'name': 'test_security_group_name'}]}
mock_neutron_client.return_value = neutron_client_instance
security_group_ids = utils.get_security_group_ids(self.context,
security_groups)
self.assertEqual(['test_security_group_id'], security_group_ids)
security_groups = ["not_attached_security_group_name"]
self.assertRaises(exception.ZunException, utils.get_security_group_ids,
self.context, security_groups)
def test_capsule_get_container_spec(self):
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate,
"Capsule need to have one container at least"):
params = ({"containers": []})
utils.capsule_get_container_spec(params)
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate, "Container "
"image is needed"):
params = ({"containers": [{"labels": {"app": "web"}}]})
utils.capsule_get_container_spec(params)
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate, "Container image is needed"):
params = ({"containers": [
{"image": "test1"},
{"environment": {"ROOT_PASSWORD": "foo0"}}]})
utils.capsule_get_container_spec(params)
params = ({"containers": [
{"image": "test1", "env": {"ROOT_PASSWORD": "foo0"}}]})
utils.capsule_get_container_spec(params)
self.assertEqual(params.get("containers")[0].get("environment"),
{"ROOT_PASSWORD": "foo0"})
self.assertNotIn("env", params.get("containers"))
def test_capsule_get_volume_spec(self):
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate,
"Volume name is needed"):
params = ({"volumes": [{"foo": "bar"}]})
utils.capsule_get_volume_spec(params)
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate, "Volume size is needed"):
params = ({"volumes": [{"name": "test",
"cinder": {"foo": "bar"}}]})
utils.capsule_get_volume_spec(params)
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate, "Volume size and uuid "
"could not be set at "
"the same time"):
params = ({"volumes": [{"name": "test",
"cinder": {"size": 3,
"volumeID": "fakevolid"}}]})
utils.capsule_get_volume_spec(params)
with self.assertRaisesRegex(
exception.InvalidCapsuleTemplate, "Zun now Only support "
"Cinder volume driver"):
params = ({"volumes": [{"name": "test", "other": {}}]})
utils.capsule_get_volume_spec(params)
@patch('zun.objects.Image.get_by_uuid')
def test_get_image(self, mock_image_get_by_uuid):
test_image = db_utils.get_test_image()
test_image_obj = objects.Image(self.context, **test_image)
mock_image_get_by_uuid.return_value = test_image_obj
with mock.patch.object(pecan, 'request'):
image = utils.get_image(test_image['uuid'])
mock_image_get_by_uuid.assert_called_once_with(
mock.ANY,
test_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_container_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)