python-openstackclient/openstackclient/tests/unit/compute/v2/test_flavor.py
Reedip 6a3c7c2a68 Overwrite/Clear Flavor property
This patch adds support to overwrite/clear the flavor's
property using the new ``--no-property`` option in the
``flavor set`` command.

Change-Id: I873c96fcf223bbd638a19b908766d904a84e8431
Implements: blueprint allow-overwrite-set-options
Co-Authored By: zhiyong.dai@easystack.cn
2017-02-13 15:16:09 +00:00

842 lines
26 KiB
Python

# Copyright 2015 Symantec Corporation
#
# 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 call
from osc_lib import exceptions
from osc_lib import utils
from openstackclient.compute.v2 import flavor
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
from openstackclient.tests.unit import utils as tests_utils
class TestFlavor(compute_fakes.TestComputev2):
def setUp(self):
super(TestFlavor, self).setUp()
# Get a shortcut to the FlavorManager Mock
self.flavors_mock = self.app.client_manager.compute.flavors
self.flavors_mock.reset_mock()
# Get a shortcut to the FlavorAccessManager Mock
self.flavor_access_mock = self.app.client_manager.compute.flavor_access
self.flavor_access_mock.reset_mock()
self.projects_mock = self.app.client_manager.identity.projects
self.projects_mock.reset_mock()
class TestFlavorCreate(TestFlavor):
flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={'links': 'flavor-links'})
project = identity_fakes.FakeProject.create_one_project()
columns = (
'OS-FLV-DISABLED:disabled',
'OS-FLV-EXT-DATA:ephemeral',
'disk',
'id',
'name',
'os-flavor-access:is_public',
'properties',
'ram',
'rxtx_factor',
'swap',
'vcpus',
)
data = (
flavor.disabled,
flavor.ephemeral,
flavor.disk,
flavor.id,
flavor.name,
flavor.is_public,
utils.format_dict(flavor.properties),
flavor.ram,
flavor.rxtx_factor,
flavor.swap,
flavor.vcpus,
)
def setUp(self):
super(TestFlavorCreate, self).setUp()
# Return a project
self.projects_mock.get.return_value = self.project
self.flavors_mock.create.return_value = self.flavor
self.cmd = flavor.CreateFlavor(self.app, None)
def test_flavor_create_default_options(self):
arglist = [
self.flavor.name
]
verifylist = [
('name', self.flavor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
default_args = (
self.flavor.name,
256,
1,
0,
'auto',
0,
0,
1.0,
True
)
columns, data = self.cmd.take_action(parsed_args)
self.flavors_mock.create.assert_called_once_with(*default_args)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
def test_flavor_create_all_options(self):
arglist = [
'--id', self.flavor.id,
'--ram', str(self.flavor.ram),
'--disk', str(self.flavor.disk),
'--ephemeral', str(self.flavor.ephemeral),
'--swap', str(self.flavor.swap),
'--vcpus', str(self.flavor.vcpus),
'--rxtx-factor', str(self.flavor.rxtx_factor),
'--public',
'--property', 'property=value',
self.flavor.name,
]
verifylist = [
('id', self.flavor.id),
('ram', self.flavor.ram),
('disk', self.flavor.disk),
('ephemeral', self.flavor.ephemeral),
('swap', self.flavor.swap),
('vcpus', self.flavor.vcpus),
('rxtx_factor', self.flavor.rxtx_factor),
('public', True),
('property', {'property': 'value'}),
('name', self.flavor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
args = (
self.flavor.name,
self.flavor.ram,
self.flavor.vcpus,
self.flavor.disk,
self.flavor.id,
self.flavor.ephemeral,
self.flavor.swap,
self.flavor.rxtx_factor,
self.flavor.is_public,
)
columns, data = self.cmd.take_action(parsed_args)
self.flavors_mock.create.assert_called_once_with(*args)
self.flavor.set_keys.assert_called_once_with({'property': 'value'})
self.flavor.get_keys.assert_called_once_with()
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
def test_flavor_create_other_options(self):
self.flavor.is_public = False
arglist = [
'--id', 'auto',
'--ram', str(self.flavor.ram),
'--disk', str(self.flavor.disk),
'--ephemeral', str(self.flavor.ephemeral),
'--swap', str(self.flavor.swap),
'--vcpus', str(self.flavor.vcpus),
'--rxtx-factor', str(self.flavor.rxtx_factor),
'--private',
'--project', self.project.id,
'--property', 'key1=value1',
'--property', 'key2=value2',
self.flavor.name,
]
verifylist = [
('ram', self.flavor.ram),
('disk', self.flavor.disk),
('ephemeral', self.flavor.ephemeral),
('swap', self.flavor.swap),
('vcpus', self.flavor.vcpus),
('rxtx_factor', self.flavor.rxtx_factor),
('public', False),
('project', self.project.id),
('property', {'key1': 'value1', 'key2': 'value2'}),
('name', self.flavor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
args = (
self.flavor.name,
self.flavor.ram,
self.flavor.vcpus,
self.flavor.disk,
'auto',
self.flavor.ephemeral,
self.flavor.swap,
self.flavor.rxtx_factor,
self.flavor.is_public,
)
columns, data = self.cmd.take_action(parsed_args)
self.flavors_mock.create.assert_called_once_with(*args)
self.flavor_access_mock.add_tenant_access.assert_called_with(
self.flavor.id,
self.project.id,
)
self.flavor.set_keys.assert_called_with(
{'key1': 'value1', 'key2': 'value2'})
self.flavor.get_keys.assert_called_with()
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
def test_public_flavor_create_with_project(self):
arglist = [
'--project', self.project.id,
self.flavor.name,
]
verifylist = [
('project', self.project.id),
('name', self.flavor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError,
self.cmd.take_action,
parsed_args)
def test_flavor_create_no_options(self):
arglist = []
verifylist = None
self.assertRaises(tests_utils.ParserException,
self.check_parser,
self.cmd,
arglist,
verifylist)
class TestFlavorDelete(TestFlavor):
flavors = compute_fakes.FakeFlavor.create_flavors(count=2)
def setUp(self):
super(TestFlavorDelete, self).setUp()
self.flavors_mock.get = (
compute_fakes.FakeFlavor.get_flavors(self.flavors))
self.flavors_mock.delete.return_value = None
self.cmd = flavor.DeleteFlavor(self.app, None)
def test_flavor_delete(self):
arglist = [
self.flavors[0].id
]
verifylist = [
('flavor', [self.flavors[0].id]),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.flavors_mock.delete.assert_called_with(self.flavors[0].id)
self.assertIsNone(result)
def test_delete_multiple_flavors(self):
arglist = []
for f in self.flavors:
arglist.append(f.id)
verifylist = [
('flavor', arglist),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
calls = []
for f in self.flavors:
calls.append(call(f.id))
self.flavors_mock.delete.assert_has_calls(calls)
self.assertIsNone(result)
def test_multi_flavors_delete_with_exception(self):
arglist = [
self.flavors[0].id,
'unexist_flavor',
]
verifylist = [
('flavor', [self.flavors[0].id, 'unexist_flavor'])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
find_mock_result = [self.flavors[0], exceptions.CommandError]
self.flavors_mock.get = (
mock.Mock(side_effect=find_mock_result)
)
self.flavors_mock.find.side_effect = exceptions.NotFound(None)
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 flavors failed to delete.', str(e))
self.flavors_mock.get.assert_any_call(self.flavors[0].id)
self.flavors_mock.get.assert_any_call('unexist_flavor')
self.flavors_mock.delete.assert_called_once_with(self.flavors[0].id)
class TestFlavorList(TestFlavor):
# Return value of self.flavors_mock.list().
flavors = compute_fakes.FakeFlavor.create_flavors(count=1)
columns = (
'ID',
'Name',
'RAM',
'Disk',
'Ephemeral',
'VCPUs',
'Is Public',
)
columns_long = columns + (
'Swap',
'RXTX Factor',
'Properties'
)
data = ((
flavors[0].id,
flavors[0].name,
flavors[0].ram,
flavors[0].disk,
flavors[0].ephemeral,
flavors[0].vcpus,
flavors[0].is_public,
), )
data_long = (data[0] + (
flavors[0].swap,
flavors[0].rxtx_factor,
u'property=\'value\''
), )
def setUp(self):
super(TestFlavorList, self).setUp()
self.flavors_mock.list.return_value = self.flavors
# Get the command object to test
self.cmd = flavor.ListFlavor(self.app, None)
def test_flavor_list_no_options(self):
arglist = []
verifylist = [
('public', True),
('all', 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)
# Set expected values
kwargs = {
'is_public': True,
'limit': None,
'marker': None
}
self.flavors_mock.list.assert_called_with(
**kwargs
)
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
def test_flavor_list_all_flavors(self):
arglist = [
'--all',
]
verifylist = [
('all', 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)
# Set expected values
kwargs = {
'is_public': None,
'limit': None,
'marker': None
}
self.flavors_mock.list.assert_called_with(
**kwargs
)
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
def test_flavor_list_private_flavors(self):
arglist = [
'--private',
]
verifylist = [
('public', 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)
# Set expected values
kwargs = {
'is_public': False,
'limit': None,
'marker': None
}
self.flavors_mock.list.assert_called_with(
**kwargs
)
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
def test_flavor_list_public_flavors(self):
arglist = [
'--public',
]
verifylist = [
('public', 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)
# Set expected values
kwargs = {
'is_public': True,
'limit': None,
'marker': None
}
self.flavors_mock.list.assert_called_with(
**kwargs
)
self.assertEqual(self.columns, columns)
self.assertEqual(tuple(self.data), tuple(data))
def test_flavor_list_long(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)
# Set expected values
kwargs = {
'is_public': True,
'limit': None,
'marker': None
}
self.flavors_mock.list.assert_called_with(
**kwargs
)
self.assertEqual(self.columns_long, columns)
self.assertEqual(tuple(self.data_long), tuple(data))
class TestFlavorSet(TestFlavor):
# Return value of self.flavors_mock.find().
flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={'os-flavor-access:is_public': False})
project = identity_fakes.FakeProject.create_one_project()
def setUp(self):
super(TestFlavorSet, self).setUp()
self.flavors_mock.find.return_value = self.flavor
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
# Return a project
self.projects_mock.get.return_value = self.project
self.cmd = flavor.SetFlavor(self.app, None)
def test_flavor_set_property(self):
arglist = [
'--property', 'FOO="B A R"',
'baremetal'
]
verifylist = [
('property', {'FOO': '"B A R"'}),
('flavor', 'baremetal')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name=parsed_args.flavor,
is_public=None)
self.flavor.set_keys.assert_called_with({'FOO': '"B A R"'})
self.assertIsNone(result)
def test_flavor_set_no_property(self):
arglist = [
'--no-property',
'baremetal'
]
verifylist = [
('no_property', True),
('flavor', 'baremetal')
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name=parsed_args.flavor,
is_public=None)
self.flavor.unset_keys.assert_called_with(['property'])
self.assertIsNone(result)
def test_flavor_set_project(self):
arglist = [
'--project', self.project.id,
self.flavor.id,
]
verifylist = [
('project', self.project.id),
('flavor', self.flavor.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name=parsed_args.flavor,
is_public=None)
self.flavor_access_mock.add_tenant_access.assert_called_with(
self.flavor.id,
self.project.id,
)
self.flavor.set_keys.assert_not_called()
self.assertIsNone(result)
def test_flavor_set_no_project(self):
arglist = [
'--project',
self.flavor.id,
]
verifylist = [
('project', None),
('flavor', self.flavor.id),
]
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
def test_flavor_set_no_flavor(self):
arglist = [
'--project', self.project.id,
]
verifylist = [
('project', self.project.id),
]
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
def test_flavor_set_with_unexist_flavor(self):
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
self.flavors_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
'--project', self.project.id,
'unexist_flavor',
]
verifylist = [
('project', self.project.id),
('flavor', 'unexist_flavor'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError,
self.cmd.take_action,
parsed_args)
def test_flavor_set_nothing(self):
arglist = [
self.flavor.id,
]
verifylist = [
('flavor', self.flavor.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name=parsed_args.flavor,
is_public=None)
self.flavor_access_mock.add_tenant_access.assert_not_called()
self.assertIsNone(result)
class TestFlavorShow(TestFlavor):
# Return value of self.flavors_mock.find().
flavor_access = compute_fakes.FakeFlavorAccess.create_one_flavor_access()
flavor = compute_fakes.FakeFlavor.create_one_flavor()
columns = (
'OS-FLV-DISABLED:disabled',
'OS-FLV-EXT-DATA:ephemeral',
'access_project_ids',
'disk',
'id',
'name',
'os-flavor-access:is_public',
'properties',
'ram',
'rxtx_factor',
'swap',
'vcpus',
)
data = (
flavor.disabled,
flavor.ephemeral,
None,
flavor.disk,
flavor.id,
flavor.name,
flavor.is_public,
utils.format_dict(flavor.get_keys()),
flavor.ram,
flavor.rxtx_factor,
flavor.swap,
flavor.vcpus,
)
def setUp(self):
super(TestFlavorShow, self).setUp()
# Return value of _find_resource()
self.flavors_mock.find.return_value = self.flavor
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
self.flavor_access_mock.list.return_value = [self.flavor_access]
self.cmd = flavor.ShowFlavor(self.app, None)
def test_show_no_options(self):
arglist = []
verifylist = []
# Missing required args should boil here
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
def test_public_flavor_show(self):
arglist = [
self.flavor.name,
]
verifylist = [
('flavor', self.flavor.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
def test_private_flavor_show(self):
private_flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={
'os-flavor-access:is_public': False,
}
)
self.flavors_mock.find.return_value = private_flavor
arglist = [
private_flavor.name,
]
verifylist = [
('flavor', private_flavor.name),
]
data_with_project = (
private_flavor.disabled,
private_flavor.ephemeral,
self.flavor_access.tenant_id,
private_flavor.disk,
private_flavor.id,
private_flavor.name,
private_flavor.is_public,
utils.format_dict(private_flavor.get_keys()),
private_flavor.ram,
private_flavor.rxtx_factor,
private_flavor.swap,
private_flavor.vcpus,
)
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.flavor_access_mock.list.assert_called_with(
flavor=private_flavor.id)
self.assertEqual(self.columns, columns)
self.assertEqual(data_with_project, data)
class TestFlavorUnset(TestFlavor):
# Return value of self.flavors_mock.find().
flavor = compute_fakes.FakeFlavor.create_one_flavor(
attrs={'os-flavor-access:is_public': False})
project = identity_fakes.FakeProject.create_one_project()
def setUp(self):
super(TestFlavorUnset, self).setUp()
self.flavors_mock.find.return_value = self.flavor
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
# Return a project
self.projects_mock.get.return_value = self.project
self.cmd = flavor.UnsetFlavor(self.app, None)
def test_flavor_unset_property(self):
arglist = [
'--property', 'property',
'baremetal'
]
verifylist = [
('property', ['property']),
('flavor', 'baremetal'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.flavors_mock.find.assert_called_with(name=parsed_args.flavor,
is_public=None)
self.flavor.unset_keys.assert_called_with(['property'])
self.flavor_access_mock.remove_tenant_access.assert_not_called()
self.assertIsNone(result)
def test_flavor_unset_project(self):
arglist = [
'--project', self.project.id,
self.flavor.id,
]
verifylist = [
('project', self.project.id),
('flavor', self.flavor.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.assertIsNone(result)
self.flavors_mock.find.assert_called_with(name=parsed_args.flavor,
is_public=None)
self.flavor_access_mock.remove_tenant_access.assert_called_with(
self.flavor.id,
self.project.id,
)
self.flavor.unset_keys.assert_not_called()
self.assertIsNone(result)
def test_flavor_unset_no_project(self):
arglist = [
'--project',
self.flavor.id,
]
verifylist = [
('project', None),
('flavor', self.flavor.id),
]
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
def test_flavor_unset_no_flavor(self):
arglist = [
'--project', self.project.id,
]
verifylist = [
('project', self.project.id),
]
self.assertRaises(tests_utils.ParserException, self.check_parser,
self.cmd, arglist, verifylist)
def test_flavor_unset_with_unexist_flavor(self):
self.flavors_mock.get.side_effect = exceptions.NotFound(None)
self.flavors_mock.find.side_effect = exceptions.NotFound(None)
arglist = [
'--project', self.project.id,
'unexist_flavor',
]
verifylist = [
('project', self.project.id),
('flavor', 'unexist_flavor'),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError, self.cmd.take_action,
parsed_args)
def test_flavor_unset_nothing(self):
arglist = [
self.flavor.id,
]
verifylist = [
('flavor', self.flavor.id),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
self.assertIsNone(result)
self.flavor_access_mock.remove_tenant_access.assert_not_called()