python-openstackclient/openstackclient/tests/unit/image/v2/test_image.py

1482 lines
46 KiB
Python

# Copyright 2013 Nebula Inc.
#
# 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 copy
from glanceclient.v2 import schemas
import mock
from osc_lib import exceptions
from osc_lib import utils as common_utils
import warlock
from openstackclient.image.v2 import image
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
from openstackclient.tests.unit.image.v2 import fakes as image_fakes
class TestImage(image_fakes.TestImagev2):
def setUp(self):
super(TestImage, self).setUp()
# Get shortcuts to the Mocks in image client
self.images_mock = self.app.client_manager.image.images
self.images_mock.reset_mock()
self.image_members_mock = self.app.client_manager.image.image_members
self.image_members_mock.reset_mock()
self.image_tags_mock = self.app.client_manager.image.image_tags
self.image_tags_mock.reset_mock()
# Get shortcut to the Mocks in identity client
self.project_mock = self.app.client_manager.identity.projects
self.project_mock.reset_mock()
self.domain_mock = self.app.client_manager.identity.domains
self.domain_mock.reset_mock()
def setup_images_mock(self, count):
images = image_fakes.FakeImage.create_images(count=count)
self.images_mock.get = image_fakes.FakeImage.get_images(
images,
0)
return images
class TestImageCreate(TestImage):
project = identity_fakes.FakeProject.create_one_project()
domain = identity_fakes.FakeDomain.create_one_domain()
def setUp(self):
super(TestImageCreate, self).setUp()
self.new_image = image_fakes.FakeImage.create_one_image()
self.images_mock.create.return_value = self.new_image
self.project_mock.get.return_value = self.project
self.domain_mock.get.return_value = self.domain
# This is the return value for utils.find_resource()
self.images_mock.get.return_value = copy.deepcopy(
self.new_image
)
self.images_mock.update.return_value = self.new_image
# Get the command object to test
self.cmd = image.CreateImage(self.app, None)
def test_image_reserve_no_options(self):
mock_exception = {
'find.side_effect': exceptions.CommandError('x'),
}
self.images_mock.configure_mock(**mock_exception)
arglist = [
self.new_image.name
]
verifylist = [
('container_format', image.DEFAULT_CONTAINER_FORMAT),
('disk_format', image.DEFAULT_DISK_FORMAT),
('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
name=self.new_image.name,
container_format=image.DEFAULT_CONTAINER_FORMAT,
disk_format=image.DEFAULT_DISK_FORMAT,
)
# Verify update() was not called, if it was show the args
self.assertEqual(self.images_mock.update.call_args_list, [])
self.images_mock.upload.assert_called_with(
mock.ANY, mock.ANY,
)
self.assertEqual(
image_fakes.FakeImage.get_image_columns(self.new_image),
columns)
self.assertEqual(
image_fakes.FakeImage.get_image_data(self.new_image),
data)
@mock.patch('glanceclient.common.utils.get_data_file', name='Open')
def test_image_reserve_options(self, mock_open):
mock_file = mock.MagicMock(name='File')
mock_open.return_value = mock_file
mock_open.read.return_value = None
mock_exception = {
'find.side_effect': exceptions.CommandError('x'),
}
self.images_mock.configure_mock(**mock_exception)
arglist = [
'--container-format', 'ovf',
'--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
('--protected'
if self.new_image.protected else '--unprotected'),
('--private'
if self.new_image.visibility == 'private' else '--public'),
'--project', self.new_image.owner,
'--project-domain', self.domain.id,
self.new_image.name,
]
verifylist = [
('container_format', 'ovf'),
('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('protected', self.new_image.protected),
('unprotected', not self.new_image.protected),
('public', self.new_image.visibility == 'public'),
('private', self.new_image.visibility == 'private'),
('project', self.new_image.owner),
('project_domain', self.domain.id),
('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
name=self.new_image.name,
container_format='ovf',
disk_format='ami',
min_disk=10,
min_ram=4,
owner=self.project.id,
protected=self.new_image.protected,
visibility=self.new_image.visibility,
)
# Verify update() was not called, if it was show the args
self.assertEqual(self.images_mock.update.call_args_list, [])
self.images_mock.upload.assert_called_with(
mock.ANY, mock.ANY,
)
self.assertEqual(
image_fakes.FakeImage.get_image_columns(self.new_image),
columns)
self.assertEqual(
image_fakes.FakeImage.get_image_data(self.new_image),
data)
def test_image_create_with_unexist_owner(self):
self.project_mock.get.side_effect = exceptions.NotFound(None)
self.project_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
'--container-format', 'ovf',
'--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
'--owner', 'unexist_owner',
'--protected',
'--private',
image_fakes.image_name,
]
verifylist = [
('container_format', 'ovf'),
('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('owner', 'unexist_owner'),
('protected', True),
('unprotected', False),
('public', False),
('private', True),
('name', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError,
self.cmd.take_action,
parsed_args,
)
def test_image_create_with_unexist_project(self):
self.project_mock.get.side_effect = exceptions.NotFound(None)
self.project_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
'--container-format', 'ovf',
'--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
'--protected',
'--private',
'--project', 'unexist_owner',
image_fakes.image_name,
]
verifylist = [
('container_format', 'ovf'),
('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('protected', True),
('unprotected', False),
('public', False),
('private', True),
('project', 'unexist_owner'),
('name', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError,
self.cmd.take_action,
parsed_args,
)
@mock.patch('glanceclient.common.utils.get_data_file', name='Open')
def test_image_create_file(self, mock_open):
mock_file = mock.MagicMock(name='File')
mock_open.return_value = mock_file
mock_open.read.return_value = (
image_fakes.FakeImage.get_image_data(self.new_image))
mock_exception = {
'find.side_effect': exceptions.CommandError('x'),
}
self.images_mock.configure_mock(**mock_exception)
arglist = [
'--file', 'filer',
('--unprotected'
if not self.new_image.protected else '--protected'),
('--public'
if self.new_image.visibility == 'public' else '--private'),
'--property', 'Alpha=1',
'--property', 'Beta=2',
'--tag', self.new_image.tags[0],
'--tag', self.new_image.tags[1],
self.new_image.name,
]
verifylist = [
('file', 'filer'),
('protected', self.new_image.protected),
('unprotected', not self.new_image.protected),
('public', self.new_image.visibility == 'public'),
('private', self.new_image.visibility == 'private'),
('properties', {'Alpha': '1', 'Beta': '2'}),
('tags', self.new_image.tags),
('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
# ImageManager.create(name=, **)
self.images_mock.create.assert_called_with(
name=self.new_image.name,
container_format=image.DEFAULT_CONTAINER_FORMAT,
disk_format=image.DEFAULT_DISK_FORMAT,
protected=self.new_image.protected,
visibility=self.new_image.visibility,
Alpha='1',
Beta='2',
tags=self.new_image.tags,
)
# Verify update() was not called, if it was show the args
self.assertEqual(self.images_mock.update.call_args_list, [])
self.images_mock.upload.assert_called_with(
mock.ANY, mock.ANY,
)
self.assertEqual(
image_fakes.FakeImage.get_image_columns(self.new_image),
columns)
self.assertEqual(
image_fakes.FakeImage.get_image_data(self.new_image),
data)
def test_image_create_dead_options(self):
arglist = [
'--store', 'somewhere',
self.new_image.name,
]
verifylist = [
('name', self.new_image.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError,
self.cmd.take_action, parsed_args)
class TestAddProjectToImage(TestImage):
project = identity_fakes.FakeProject.create_one_project()
domain = identity_fakes.FakeDomain.create_one_domain()
_image = image_fakes.FakeImage.create_one_image()
new_member = image_fakes.FakeImage.create_one_image_member(
attrs={'image_id': _image.id,
'member_id': project.id}
)
columns = (
'image_id',
'member_id',
'status',
)
datalist = (
_image.id,
new_member.member_id,
new_member.status,
)
def setUp(self):
super(TestAddProjectToImage, self).setUp()
# This is the return value for utils.find_resource()
self.images_mock.get.return_value = self._image
# Update the image_id in the MEMBER dict
self.image_members_mock.create.return_value = self.new_member
self.project_mock.get.return_value = self.project
self.domain_mock.get.return_value = self.domain
# Get the command object to test
self.cmd = image.AddProjectToImage(self.app, None)
def test_add_project_to_image_no_option(self):
arglist = [
self._image.id,
self.project.id,
]
verifylist = [
('image', self._image.id),
('project', self.project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
self.image_members_mock.create.assert_called_with(
self._image.id,
self.project.id
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
def test_add_project_to_image_with_option(self):
arglist = [
self._image.id,
self.project.id,
'--project-domain', self.domain.id,
]
verifylist = [
('image', self._image.id),
('project', self.project.id),
('project_domain', self.domain.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
self.image_members_mock.create.assert_called_with(
self._image.id,
self.project.id
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
class TestImageDelete(TestImage):
def setUp(self):
super(TestImageDelete, self).setUp()
self.images_mock.delete.return_value = None
# Get the command object to test
self.cmd = image.DeleteImage(self.app, None)
def test_image_delete_no_options(self):
images = self.setup_images_mock(count=1)
arglist = [
images[0].id,
]
verifylist = [
('images', [images[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.images_mock.delete.assert_called_with(images[0].id)
self.assertIsNone(result)
def test_image_delete_multi_images(self):
images = self.setup_images_mock(count=3)
arglist = [i.id for i in images]
verifylist = [
('images', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
calls = [mock.call(i.id) for i in images]
self.images_mock.delete.assert_has_calls(calls)
self.assertIsNone(result)
def test_image_delete_multi_images_exception(self):
images = image_fakes.FakeImage.create_images(count=2)
arglist = [
images[0].id,
images[1].id,
'x-y-x',
]
verifylist = [
('images', arglist)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# Fake exception in utils.find_resource()
# In image v2, we use utils.find_resource() to find a network.
# It calls get() several times, but find() only one time. So we
# choose to fake get() always raise exception, then pass through.
# And fake find() to find the real network or not.
ret_find = [
images[0],
images[1],
exceptions.NotFound('404'),
]
self.images_mock.get = Exception()
self.images_mock.find.side_effect = ret_find
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
calls = [mock.call(i.id) for i in images]
self.images_mock.delete.assert_has_calls(calls)
class TestImageList(TestImage):
_image = image_fakes.FakeImage.create_one_image()
columns = (
'ID',
'Name',
'Status',
)
datalist = (
_image.id,
_image.name,
'',
),
def setUp(self):
super(TestImageList, self).setUp()
self.api_mock = mock.Mock()
self.api_mock.image_list.side_effect = [
[self._image], [],
]
self.app.client_manager.image.api = self.api_mock
# Get the command object to test
self.cmd = image.ListImage(self.app, None)
def test_image_list_no_options(self):
arglist = []
verifylist = [
('public', False),
('private', False),
('shared', False),
('long', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
marker=self._image.id,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_image_list_public_option(self):
arglist = [
'--public',
]
verifylist = [
('public', True),
('private', False),
('shared', False),
('long', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
public=True,
marker=self._image.id,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_image_list_private_option(self):
arglist = [
'--private',
]
verifylist = [
('public', False),
('private', True),
('shared', False),
('long', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
private=True,
marker=self._image.id,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_image_list_shared_option(self):
arglist = [
'--shared',
]
verifylist = [
('public', False),
('private', False),
('shared', True),
('long', False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
shared=True,
marker=self._image.id,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_image_list_long_option(self):
arglist = [
'--long',
]
verifylist = [
('long', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
marker=self._image.id,
)
collist = (
'ID',
'Name',
'Disk Format',
'Container Format',
'Size',
'Checksum',
'Status',
'Visibility',
'Protected',
'Project',
'Tags',
)
self.assertEqual(collist, columns)
datalist = ((
self._image.id,
self._image.name,
'',
'',
'',
'',
'',
self._image.visibility,
self._image.protected,
self._image.owner,
common_utils.format_list(self._image.tags),
), )
self.assertEqual(datalist, tuple(data))
@mock.patch('openstackclient.api.utils.simple_filter')
def test_image_list_property_option(self, sf_mock):
sf_mock.return_value = [copy.deepcopy(self._image)]
arglist = [
'--property', 'a=1',
]
verifylist = [
('property', {'a': '1'}),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
marker=self._image.id,
)
sf_mock.assert_called_with(
[self._image],
attr='a',
value='1',
property_field='properties',
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
@mock.patch('osc_lib.utils.sort_items')
def test_image_list_sort_option(self, si_mock):
si_mock.return_value = [copy.deepcopy(self._image)]
arglist = ['--sort', 'name:asc']
verifylist = [('sort', 'name:asc')]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
# returns a tuple containing the column names and an iterable
# containing the data to be listed.
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
marker=self._image.id,
)
si_mock.assert_called_with(
[self._image],
'name:asc'
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, tuple(data))
def test_image_list_limit_option(self):
arglist = [
'--limit', str(1),
]
verifylist = [
('limit', 1),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
limit=1, marker=self._image.id
)
self.assertEqual(self.columns, columns)
self.assertEqual(len(self.datalist), len(tuple(data)))
@mock.patch('osc_lib.utils.find_resource')
def test_image_list_marker_option(self, fr_mock):
# tangchen: Since image_fakes.IMAGE is a dict, it cannot offer a .id
# operation. Will fix this by using FakeImage class instead
# of IMAGE dict.
fr_mock.return_value = mock.Mock()
fr_mock.return_value.id = image_fakes.image_id
arglist = [
'--marker', image_fakes.image_name,
]
verifylist = [
('marker', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
marker=image_fakes.image_id,
)
def test_image_list_name_option(self):
arglist = [
'--name', 'abc',
]
verifylist = [
('name', 'abc'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
name='abc', marker=self._image.id
)
def test_image_list_status_option(self):
arglist = [
'--status', 'active',
]
verifylist = [
('status', 'active'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.api_mock.image_list.assert_called_with(
status='active', marker=self._image.id
)
class TestRemoveProjectImage(TestImage):
project = identity_fakes.FakeProject.create_one_project()
domain = identity_fakes.FakeDomain.create_one_domain()
def setUp(self):
super(TestRemoveProjectImage, self).setUp()
self._image = image_fakes.FakeImage.create_one_image()
# This is the return value for utils.find_resource()
self.images_mock.get.return_value = self._image
self.project_mock.get.return_value = self.project
self.domain_mock.get.return_value = self.domain
self.image_members_mock.delete.return_value = None
# Get the command object to test
self.cmd = image.RemoveProjectImage(self.app, None)
def test_remove_project_image_no_options(self):
arglist = [
self._image.id,
self.project.id,
]
verifylist = [
('image', self._image.id),
('project', self.project.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.image_members_mock.delete.assert_called_with(
self._image.id,
self.project.id,
)
self.assertIsNone(result)
def test_remove_project_image_with_options(self):
arglist = [
self._image.id,
self.project.id,
'--project-domain', self.domain.id,
]
verifylist = [
('image', self._image.id),
('project', self.project.id),
('project_domain', self.domain.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.image_members_mock.delete.assert_called_with(
self._image.id,
self.project.id,
)
self.assertIsNone(result)
class TestImageSet(TestImage):
project = identity_fakes.FakeProject.create_one_project()
domain = identity_fakes.FakeDomain.create_one_domain()
def setUp(self):
super(TestImageSet, self).setUp()
# Set up the schema
self.model = warlock.model_factory(
image_fakes.IMAGE_schema,
schemas.SchemaBasedModel,
)
self.project_mock.get.return_value = self.project
self.domain_mock.get.return_value = self.domain
self.images_mock.get.return_value = self.model(**image_fakes.IMAGE)
self.images_mock.update.return_value = self.model(**image_fakes.IMAGE)
self.app.client_manager.auth_ref = mock.Mock(
project_id=self.project.id,
)
# Get the command object to test
self.cmd = image.SetImage(self.app, None)
def test_image_set_no_options(self):
arglist = [
image_fakes.image_id,
]
verifylist = [
('image', image_fakes.image_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.assertIsNone(result)
self.image_members_mock.update.assert_not_called()
def test_image_set_membership_option_accept(self):
membership = image_fakes.FakeImage.create_one_image_member(
attrs={'image_id': image_fakes.image_id,
'member_id': self.project.id}
)
self.image_members_mock.update.return_value = membership
arglist = [
'--accept',
image_fakes.image_id,
]
verifylist = [
('accept', True),
('reject', False),
('pending', False),
('image', image_fakes.image_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.image_members_mock.update.assert_called_once_with(
image_fakes.image_id,
self.app.client_manager.auth_ref.project_id,
'accepted',
)
# Assert that the 'update image" route is also called, in addition to
# the 'update membership' route.
self.images_mock.update.assert_called_with(image_fakes.image_id)
def test_image_set_membership_option_reject(self):
membership = image_fakes.FakeImage.create_one_image_member(
attrs={'image_id': image_fakes.image_id,
'member_id': self.project.id}
)
self.image_members_mock.update.return_value = membership
arglist = [
'--reject',
image_fakes.image_id,
]
verifylist = [
('accept', False),
('reject', True),
('pending', False),
('image', image_fakes.image_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.image_members_mock.update.assert_called_once_with(
image_fakes.image_id,
self.app.client_manager.auth_ref.project_id,
'rejected',
)
# Assert that the 'update image" route is also called, in addition to
# the 'update membership' route.
self.images_mock.update.assert_called_with(image_fakes.image_id)
def test_image_set_membership_option_pending(self):
membership = image_fakes.FakeImage.create_one_image_member(
attrs={'image_id': image_fakes.image_id,
'member_id': self.project.id}
)
self.image_members_mock.update.return_value = membership
arglist = [
'--pending',
image_fakes.image_id,
]
verifylist = [
('accept', False),
('reject', False),
('pending', True),
('image', image_fakes.image_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.cmd.take_action(parsed_args)
self.image_members_mock.update.assert_called_once_with(
image_fakes.image_id,
self.app.client_manager.auth_ref.project_id,
'pending',
)
# Assert that the 'update image" route is also called, in addition to
# the 'update membership' route.
self.images_mock.update.assert_called_with(image_fakes.image_id)
def test_image_set_options(self):
arglist = [
'--name', 'new-name',
'--min-disk', '2',
'--min-ram', '4',
'--container-format', 'ovf',
'--disk-format', 'vmdk',
'--project', self.project.name,
'--project-domain', self.domain.id,
image_fakes.image_id,
]
verifylist = [
('name', 'new-name'),
('min_disk', 2),
('min_ram', 4),
('container_format', 'ovf'),
('disk_format', 'vmdk'),
('project', self.project.name),
('project_domain', self.domain.id),
('image', image_fakes.image_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'name': 'new-name',
'owner': self.project.id,
'min_disk': 2,
'min_ram': 4,
'container_format': 'ovf',
'disk_format': 'vmdk',
}
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id, **kwargs)
self.assertIsNone(result)
def test_image_set_with_unexist_owner(self):
self.project_mock.get.side_effect = exceptions.NotFound(None)
self.project_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
'--owner', 'unexist_owner',
image_fakes.image_id,
]
verifylist = [
('owner', 'unexist_owner'),
('image', image_fakes.image_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError,
self.cmd.take_action, parsed_args)
def test_image_set_with_unexist_project(self):
self.project_mock.get.side_effect = exceptions.NotFound(None)
self.project_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
'--project', 'unexist_owner',
image_fakes.image_id,
]
verifylist = [
('project', 'unexist_owner'),
('image', image_fakes.image_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError,
self.cmd.take_action, parsed_args)
def test_image_set_bools1(self):
arglist = [
'--protected',
'--private',
image_fakes.image_name,
]
verifylist = [
('protected', True),
('unprotected', False),
('public', False),
('private', True),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'protected': True,
'visibility': 'private',
}
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_bools2(self):
arglist = [
'--unprotected',
'--public',
image_fakes.image_name,
]
verifylist = [
('protected', False),
('unprotected', True),
('public', True),
('private', False),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'protected': False,
'visibility': 'public',
}
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_properties(self):
arglist = [
'--property', 'Alpha=1',
'--property', 'Beta=2',
image_fakes.image_name,
]
verifylist = [
('properties', {'Alpha': '1', 'Beta': '2'}),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'Alpha': '1',
'Beta': '2',
}
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_fake_properties(self):
arglist = [
'--architecture', 'z80',
'--instance-id', '12345',
'--kernel-id', '67890',
'--os-distro', 'cpm',
'--os-version', '2.2H',
'--ramdisk-id', 'xyzpdq',
image_fakes.image_name,
]
verifylist = [
('architecture', 'z80'),
('instance_id', '12345'),
('kernel_id', '67890'),
('os_distro', 'cpm'),
('os_version', '2.2H'),
('ramdisk_id', 'xyzpdq'),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'architecture': 'z80',
'instance_id': '12345',
'kernel_id': '67890',
'os_distro': 'cpm',
'os_version': '2.2H',
'ramdisk_id': 'xyzpdq',
}
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_tag(self):
arglist = [
'--tag', 'test-tag',
image_fakes.image_name,
]
verifylist = [
('tags', ['test-tag']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['test-tag'],
}
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_activate(self):
arglist = [
'--tag', 'test-tag',
'--activate',
image_fakes.image_name,
]
verifylist = [
('tags', ['test-tag']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['test-tag'],
}
self.images_mock.reactivate.assert_called_with(
image_fakes.image_id,
)
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_deactivate(self):
arglist = [
'--tag', 'test-tag',
'--deactivate',
image_fakes.image_name,
]
verifylist = [
('tags', ['test-tag']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['test-tag'],
}
self.images_mock.deactivate.assert_called_with(
image_fakes.image_id,
)
# ImageManager.update(image, **kwargs)
self.images_mock.update.assert_called_with(
image_fakes.image_id,
**kwargs
)
self.assertIsNone(result)
def test_image_set_tag_merge(self):
old_image = copy.copy(image_fakes.IMAGE)
old_image['tags'] = ['old1', 'new2']
self.images_mock.get.return_value = self.model(**old_image)
arglist = [
'--tag', 'test-tag',
image_fakes.image_name,
]
verifylist = [
('tags', ['test-tag']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['old1', 'new2', 'test-tag'],
}
# ImageManager.update(image, **kwargs)
a, k = self.images_mock.update.call_args
self.assertEqual(image_fakes.image_id, a[0])
self.assertIn('tags', k)
self.assertEqual(set(kwargs['tags']), set(k['tags']))
self.assertIsNone(result)
def test_image_set_tag_merge_dupe(self):
old_image = copy.copy(image_fakes.IMAGE)
old_image['tags'] = ['old1', 'new2']
self.images_mock.get.return_value = self.model(**old_image)
arglist = [
'--tag', 'old1',
image_fakes.image_name,
]
verifylist = [
('tags', ['old1']),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {
'tags': ['new2', 'old1'],
}
# ImageManager.update(image, **kwargs)
a, k = self.images_mock.update.call_args
self.assertEqual(image_fakes.image_id, a[0])
self.assertIn('tags', k)
self.assertEqual(set(kwargs['tags']), set(k['tags']))
self.assertIsNone(result)
def test_image_set_dead_options(self):
arglist = [
'--visibility', '1-mile',
image_fakes.image_name,
]
verifylist = [
('visibility', '1-mile'),
('image', image_fakes.image_name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(
exceptions.CommandError,
self.cmd.take_action, parsed_args)
class TestImageShow(TestImage):
new_image = image_fakes.FakeImage.create_one_image(
attrs={'size': 1000})
def setUp(self):
super(TestImageShow, self).setUp()
# Set up the schema
self.model = warlock.model_factory(
image_fakes.IMAGE_schema,
schemas.SchemaBasedModel,
)
self.images_mock.get.return_value = self.model(**image_fakes.IMAGE)
# Get the command object to test
self.cmd = image.ShowImage(self.app, None)
def test_image_show(self):
arglist = [
image_fakes.image_id,
]
verifylist = [
('image', image_fakes.image_id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
self.images_mock.get.assert_called_with(
image_fakes.image_id,
)
self.assertEqual(image_fakes.IMAGE_columns, columns)
self.assertEqual(image_fakes.IMAGE_SHOW_data, data)
def test_image_show_human_readable(self):
self.images_mock.get.return_value = self.new_image
arglist = [
'--human-readable',
self.new_image.id,
]
verifylist = [
('human_readable', True),
('image', self.new_image.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class ShowOne in cliff, abstract method take_action()
# returns a two-part tuple with a tuple of column names and a tuple of
# data to be shown.
columns, data = self.cmd.take_action(parsed_args)
self.images_mock.get.assert_called_with(
self.new_image.id,
)
size_index = columns.index('size')
self.assertEqual(data[size_index], '1K')
class TestImageUnset(TestImage):
attrs = {}
attrs['tags'] = ['test']
attrs['prop'] = 'test'
image = image_fakes.FakeImage.create_one_image(attrs)
def setUp(self):
super(TestImageUnset, self).setUp()
# Set up the schema
self.model = warlock.model_factory(
image_fakes.IMAGE_schema,
schemas.SchemaBasedModel,
)
self.images_mock.get.return_value = self.image
self.image_tags_mock.delete.return_value = self.image
# Get the command object to test
self.cmd = image.UnsetImage(self.app, None)
def test_image_unset_no_options(self):
arglist = [
image_fakes.image_id,
]
verifylist = [
('image', image_fakes.image_id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.assertIsNone(result)
def test_image_unset_tag_option(self):
arglist = [
'--tag', 'test',
self.image.id,
]
verifylist = [
('tags', ['test']),
('image', self.image.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.image_tags_mock.delete.assert_called_with(
self.image.id, 'test'
)
self.assertIsNone(result)
def test_image_unset_property_option(self):
arglist = [
'--property', 'prop',
self.image.id,
]
verifylist = [
('properties', ['prop']),
('image', self.image.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {}
self.images_mock.update.assert_called_with(
self.image.id,
parsed_args.properties,
**kwargs)
self.assertIsNone(result)
def test_image_unset_mixed_option(self):
arglist = [
'--tag', 'test',
'--property', 'prop',
self.image.id,
]
verifylist = [
('tags', ['test']),
('properties', ['prop']),
('image', self.image.id)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
kwargs = {}
self.images_mock.update.assert_called_with(
self.image.id,
parsed_args.properties,
**kwargs)
self.image_tags_mock.delete.assert_called_with(
self.image.id, 'test'
)
self.assertIsNone(result)