diff options
Diffstat (limited to 'openstackclient/tests')
33 files changed, 3568 insertions, 956 deletions
diff --git a/openstackclient/tests/common/test_command.py b/openstackclient/tests/common/test_command.py index 7467d9eb..722a4c06 100644 --- a/openstackclient/tests/common/test_command.py +++ b/openstackclient/tests/common/test_command.py @@ -15,6 +15,8 @@ import mock from openstackclient.common import command +from openstackclient.common import exceptions +from openstackclient.tests import fakes as test_fakes from openstackclient.tests import utils as test_utils @@ -31,3 +33,16 @@ class TestCommand(test_utils.TestCase): self.assertTrue(hasattr(cmd, 'log')) self.assertEqual('openstackclient.tests.common.test_command.' 'FakeCommand', cmd.log.name) + + def test_validate_os_beta_command_enabled(self): + cmd = FakeCommand(mock.Mock(), mock.Mock()) + cmd.app = mock.Mock() + cmd.app.options = test_fakes.FakeOptions() + + # No exception is raised when enabled. + cmd.app.options.os_beta_command = True + cmd.validate_os_beta_command_enabled() + + cmd.app.options.os_beta_command = False + self.assertRaises(exceptions.CommandError, + cmd.validate_os_beta_command_enabled) diff --git a/openstackclient/tests/common/test_quota.py b/openstackclient/tests/common/test_quota.py index ba7ee469..c9ec5599 100644 --- a/openstackclient/tests/common/test_quota.py +++ b/openstackclient/tests/common/test_quota.py @@ -97,6 +97,9 @@ class TestQuotaSet(TestQuota): loaded=True, ) + self.network_mock = self.app.client_manager.network + self.network_mock.update_quota = mock.Mock() + self.cmd = quota.SetQuota(self.app, None) def test_quota_set(self): @@ -132,6 +135,7 @@ class TestQuotaSet(TestQuota): ('project', identity_fakes.project_name), ] + self.app.client_manager.network_endpoint_enabled = False parsed_args = self.check_parser(self.cmd, arglist, verifylist) self.cmd.take_action(parsed_args) @@ -185,6 +189,61 @@ class TestQuotaSet(TestQuota): **kwargs ) + def test_quota_set_network(self): + arglist = [ + '--subnets', str(network_fakes.QUOTA['subnet']), + '--networks', str(network_fakes.QUOTA['network']), + '--floating-ips', str(network_fakes.QUOTA['floatingip']), + '--subnetpools', str(network_fakes.QUOTA['subnetpool']), + '--secgroup-rules', + str(network_fakes.QUOTA['security_group_rule']), + '--secgroups', str(network_fakes.QUOTA['security_group']), + '--routers', str(network_fakes.QUOTA['router']), + '--rbac-policies', str(network_fakes.QUOTA['rbac_policy']), + '--ports', str(network_fakes.QUOTA['port']), + '--vips', str(network_fakes.QUOTA['vip']), + '--members', str(network_fakes.QUOTA['member']), + '--health-monitors', str(network_fakes.QUOTA['health_monitor']), + identity_fakes.project_name, + ] + verifylist = [ + ('subnet', network_fakes.QUOTA['subnet']), + ('network', network_fakes.QUOTA['network']), + ('floatingip', network_fakes.QUOTA['floatingip']), + ('subnetpool', network_fakes.QUOTA['subnetpool']), + ('security_group_rule', + network_fakes.QUOTA['security_group_rule']), + ('security_group', network_fakes.QUOTA['security_group']), + ('router', network_fakes.QUOTA['router']), + ('rbac_policy', network_fakes.QUOTA['rbac_policy']), + ('port', network_fakes.QUOTA['port']), + ('vip', network_fakes.QUOTA['vip']), + ('member', network_fakes.QUOTA['member']), + ('health_monitor', network_fakes.QUOTA['health_monitor']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.cmd.take_action(parsed_args) + kwargs = { + 'subnet': network_fakes.QUOTA['subnet'], + 'network': network_fakes.QUOTA['network'], + 'floatingip': network_fakes.QUOTA['floatingip'], + 'subnetpool': network_fakes.QUOTA['subnetpool'], + 'security_group_rule': + network_fakes.QUOTA['security_group_rule'], + 'security_group': network_fakes.QUOTA['security_group'], + 'router': network_fakes.QUOTA['router'], + 'rbac_policy': network_fakes.QUOTA['rbac_policy'], + 'port': network_fakes.QUOTA['port'], + 'vip': network_fakes.QUOTA['vip'], + 'member': network_fakes.QUOTA['member'], + 'health_monitor': network_fakes.QUOTA['health_monitor'], + } + self.network_mock.update_quota.assert_called_with( + identity_fakes.project_id, + **kwargs + ) + class TestQuotaShow(TestQuota): diff --git a/openstackclient/tests/compute/v2/fakes.py b/openstackclient/tests/compute/v2/fakes.py index 948d9e97..c9e2025d 100644 --- a/openstackclient/tests/compute/v2/fakes.py +++ b/openstackclient/tests/compute/v2/fakes.py @@ -76,17 +76,6 @@ QUOTA = { QUOTA_columns = tuple(sorted(QUOTA)) QUOTA_data = tuple(QUOTA[x] for x in sorted(QUOTA)) -service_host = 'host_test' -service_binary = 'compute_test' -service_status = 'enabled' -service_disabled_reason = 'earthquake' -SERVICE = { - 'host': service_host, - 'binary': service_binary, - 'status': service_status, - 'disabled_reason': service_disabled_reason, -} - class FakeAggregate(object): """Fake one aggregate.""" @@ -122,6 +111,9 @@ class FakeAggregate(object): class FakeComputev2Client(object): def __init__(self, **kwargs): + self.agents = mock.Mock() + self.agents.resource_class = fakes.FakeResource(None, {}) + self.aggregates = mock.Mock() self.aggregates.resource_class = fakes.FakeResource(None, {}) @@ -143,6 +135,9 @@ class FakeComputev2Client(object): self.flavors = mock.Mock() self.flavors.resource_class = fakes.FakeResource(None, {}) + self.flavor_access = mock.Mock() + self.flavor_access.resource_class = fakes.FakeResource(None, {}) + self.quotas = mock.Mock() self.quotas.resource_class = fakes.FakeResource(None, {}) @@ -215,6 +210,55 @@ class TestComputev2(utils.TestCommand): ) +class FakeAgent(object): + """Fake one or more agent.""" + + @staticmethod + def create_one_agent(attrs=None): + """Create a fake agent. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object, with agent_id, os, and so on + """ + + attrs = attrs or {} + + # set default attributes. + agent_info = { + 'agent_id': 'agent-id-' + uuid.uuid4().hex, + 'os': 'agent-os-' + uuid.uuid4().hex, + 'architecture': 'agent-architecture', + 'version': '8.0', + 'url': 'http://127.0.0.1', + 'md5hash': 'agent-md5hash', + 'hypervisor': 'hypervisor', + } + agent_info.update(attrs) + + agent = fakes.FakeResource(info=copy.deepcopy(agent_info), + loaded=True) + return agent + + @staticmethod + def create_agents(attrs=None, count=2): + """Create multiple fake agents. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of agents to fake + :return: + A list of FakeResource objects faking the agents + """ + agents = [] + for i in range(0, count): + agents.append(FakeAgent.create_one_agent(attrs)) + + return agents + + class FakeHypervisor(object): """Fake one or more hypervisor.""" @@ -472,7 +516,8 @@ class FakeServer(object): }, 'flavor': { 'id': 'flavor-id-' + uuid.uuid4().hex, - } + }, + 'OS-EXT-STS:power_state': 1, } # Overwrite default attributes. @@ -522,6 +567,54 @@ class FakeServer(object): return mock.MagicMock(side_effect=servers) +class FakeService(object): + """Fake one or more services.""" + + @staticmethod + def create_one_service(attrs=None): + """Create a fake service. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object, with id, name, ram, vcpus, properties + """ + attrs = attrs or {} + + # Set default attributes. + service_info = { + 'host': 'host-' + uuid.uuid4().hex, + 'binary': 'binary-' + uuid.uuid4().hex, + 'status': 'enabled', + 'disabled_reason': 'earthquake', + } + + # Overwrite default attributes. + service_info.update(attrs) + + service = fakes.FakeResource(info=copy.deepcopy(service_info), + loaded=True) + + return service + + @staticmethod + def create_services(attrs=None, count=2): + """Create multiple fake services. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of services to fake + :return: + A list of FakeResource objects faking the services + """ + services = [] + for i in range(0, count): + services.append(FakeService.create_one_service(attrs)) + + return services + + class FakeFlavor(object): """Fake one or more flavors.""" @@ -543,8 +636,8 @@ class FakeFlavor(object): 'ram': 8192, 'vcpus': 4, 'disk': 128, - 'swap': '', - 'rxtx_factor': '1.0', + 'swap': 0, + 'rxtx_factor': 1.0, 'OS-FLV-DISABLED:disabled': False, 'os-flavor-access:is_public': True, 'OS-FLV-EXT-DATA:ephemeral': 0, @@ -858,6 +951,25 @@ class FakeNetwork(object): return networks + @staticmethod + def get_networks(networks=None, count=2): + """Get an iterable MagicMock object with a list of faked networks. + + If networks list is provided, then initialize the Mock object with the + list. Otherwise create one. + + :param List networks: + A list of FakeResource objects faking networks + :param int count: + The number of networks to fake + :return: + An iterable Mock object with side_effect set to a list of faked + networks + """ + if networks is None: + networks = FakeNetwork.create_networks(count=count) + return mock.Mock(side_effect=networks) + class FakeHost(object): """Fake one host.""" diff --git a/openstackclient/tests/compute/v2/test_agent.py b/openstackclient/tests/compute/v2/test_agent.py new file mode 100644 index 00000000..bdff8c5e --- /dev/null +++ b/openstackclient/tests/compute/v2/test_agent.py @@ -0,0 +1,203 @@ +# Copyright 2016 Easystack. All rights reserved. +# +# 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. +# + +from openstackclient.compute.v2 import agent +from openstackclient.tests.compute.v2 import fakes as compute_fakes + + +class TestAgent(compute_fakes.TestComputev2): + + fake_agent = compute_fakes.FakeAgent.create_one_agent() + + columns = ( + 'agent_id', + 'architecture', + 'hypervisor', + 'md5hash', + 'os', + 'url', + 'version', + ) + + data = ( + fake_agent.agent_id, + fake_agent.architecture, + fake_agent.hypervisor, + fake_agent.md5hash, + fake_agent.os, + fake_agent.url, + fake_agent.version, + ) + + def setUp(self): + super(TestAgent, self).setUp() + + self.agents_mock = self.app.client_manager.compute.agents + self.agents_mock.reset_mock() + + +class TestAgentCreate(TestAgent): + + def setUp(self): + super(TestAgentCreate, self).setUp() + + self.agents_mock.create.return_value = self.fake_agent + self.cmd = agent.CreateAgent(self.app, None) + + def test_agent_create(self): + arglist = [ + self.fake_agent.os, + self.fake_agent.architecture, + self.fake_agent.version, + self.fake_agent.url, + self.fake_agent.md5hash, + self.fake_agent.hypervisor, + ] + + verifylist = [ + ('os', self.fake_agent.os), + ('architecture', self.fake_agent.architecture), + ('version', self.fake_agent.version), + ('url', self.fake_agent.url), + ('md5hash', self.fake_agent.md5hash), + ('hypervisor', self.fake_agent.hypervisor), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + self.agents_mock.create.assert_called_with(parsed_args.os, + parsed_args.architecture, + parsed_args.version, + parsed_args.url, + parsed_args.md5hash, + parsed_args.hypervisor) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + +class TestAgentDelete(TestAgent): + + def setUp(self): + super(TestAgentDelete, self).setUp() + + self.agents_mock.get.return_value = self.fake_agent + self.cmd = agent.DeleteAgent(self.app, None) + + def test_one_agent_delete(self): + arglist = [ + 'test' + ] + + verifylist = [ + ('id', 'test'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self.agents_mock.delete.assert_called_with(parsed_args.id) + self.assertIsNone(result) + + +class TestAgentList(TestAgent): + + agents = compute_fakes.FakeAgent.create_agents(count=3) + list_columns = ( + "Agent ID", + "Hypervisor", + "OS", + "Architecture", + "Version", + "Md5Hash", + "URL", + ) + + list_data = [] + for _agent in agents: + list_data.append(( + _agent.agent_id, + _agent.hypervisor, + _agent.os, + _agent.architecture, + _agent.version, + _agent.md5hash, + _agent.url, + )) + + def setUp(self): + + super(TestAgentList, self).setUp() + + self.agents_mock.list.return_value = self.agents + self.cmd = agent.ListAgent(self.app, None) + + def test_agent_list(self): + + arglist = [] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.assertEqual(self.list_columns, columns) + self.assertEqual(self.list_data, list(data)) + + def test_agent_list_with_hypervisor(self): + + arglist = [ + '--hypervisor', + 'hypervisor', + ] + verifylist = [ + ('hypervisor', 'hypervisor'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.assertEqual(self.list_columns, columns) + self.assertEqual(self.list_data, list(data)) + + +class TestAgentSet(TestAgent): + + def setUp(self): + super(TestAgentSet, self).setUp() + + self.agents_mock.update.return_value = self.fake_agent + self.cmd = agent.SetAgent(self.app, None) + + def test_agent_set(self): + arglist = [ + 'id', + 'new-version', + 'new-url', + 'new-md5hash', + ] + + verifylist = [ + ('id', 'id'), + ('version', 'new-version'), + ('url', 'new-url'), + ('md5hash', 'new-md5hash'), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + + self.agents_mock.update.assert_called_with(parsed_args.id, + parsed_args.version, + parsed_args.url, + parsed_args.md5hash) + self.assertIsNone(result) diff --git a/openstackclient/tests/compute/v2/test_flavor.py b/openstackclient/tests/compute/v2/test_flavor.py index fa29111b..434d5f92 100644 --- a/openstackclient/tests/compute/v2/test_flavor.py +++ b/openstackclient/tests/compute/v2/test_flavor.py @@ -13,10 +13,14 @@ # under the License. # +import copy + from openstackclient.common import exceptions from openstackclient.common import utils from openstackclient.compute.v2 import flavor from openstackclient.tests.compute.v2 import fakes as compute_fakes +from openstackclient.tests import fakes +from openstackclient.tests.identity.v3 import fakes as identity_fakes from openstackclient.tests import utils as tests_utils @@ -29,6 +33,173 @@ class TestFlavor(compute_fakes.TestComputev2): 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'}) + + columns = ( + 'OS-FLV-DISABLED:disabled', + 'OS-FLV-EXT-DATA:ephemeral', + 'disk', + 'id', + 'name', + 'os-flavor-access:is_public', + 'ram', + 'rxtx_factor', + 'swap', + 'vcpus', + ) + data = ( + flavor.disabled, + flavor.ephemeral, + flavor.disk, + flavor.id, + flavor.name, + flavor.is_public, + flavor.ram, + flavor.rxtx_factor, + flavor.swap, + flavor.vcpus, + ) + + def setUp(self): + super(TestFlavorCreate, self).setUp() + + 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 = [ + self.flavor.name, + '--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', + ] + verifylist = [ + ('name', self.flavor.name), + ('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), + ] + 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.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_flavor_create_other_options(self): + + self.flavor.is_public = False + arglist = [ + self.flavor.name, + '--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), + '--private', + ] + verifylist = [ + ('name', self.flavor.name), + ('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', False), + ] + 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.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + 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): @@ -267,16 +438,23 @@ class TestFlavorList(TestFlavor): class TestFlavorSet(TestFlavor): # Return value of self.flavors_mock.find(). - flavor = compute_fakes.FakeFlavor.create_one_flavor() + flavor = compute_fakes.FakeFlavor.create_one_flavor( + attrs={'os-flavor-access:is_public': False}) 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 = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.PROJECT), + loaded=True, + ) self.cmd = flavor.SetFlavor(self.app, None) - def test_flavor_set(self): + def test_flavor_set_property(self): arglist = [ '--property', 'FOO="B A R"', 'baremetal' @@ -288,12 +466,85 @@ class TestFlavorSet(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - try: - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor) - except Exception: - self.flavors_mock.get.assert_called_with(parsed_args.flavor) + self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, + is_public=None) + self.assertIsNone(result) + + def test_flavor_set_project(self): + arglist = [ + '--project', identity_fakes.project_id, + self.flavor.id, + ] + verifylist = [ + ('project', identity_fakes.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.flavor_access_mock.add_tenant_access.assert_called_with( + self.flavor.id, + identity_fakes.project_id, + ) + + def test_flavor_set_no_project(self): + arglist = [ + '--project', + self.flavor.id, + ] + verifylist = [ + ('project', ''), + ('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', identity_fakes.project_id, + ] + verifylist = [ + ('project', identity_fakes.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', identity_fakes.project_id, + 'unexist_flavor', + ] + verifylist = [ + ('project', identity_fakes.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) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + class TestFlavorShow(TestFlavor): @@ -331,9 +582,9 @@ class TestFlavorShow(TestFlavor): def setUp(self): super(TestFlavorShow, self).setUp() - # Return value of utils.find_resource() - self.flavors_mock.get.return_value = self.flavor - + # Return value of _find_resource() + self.flavors_mock.find.return_value = self.flavor + self.flavors_mock.get.side_effect = exceptions.NotFound(None) self.cmd = flavor.ShowFlavor(self.app, None) def test_show_no_options(self): @@ -363,16 +614,23 @@ class TestFlavorShow(TestFlavor): class TestFlavorUnset(TestFlavor): # Return value of self.flavors_mock.find(). - flavor = compute_fakes.FakeFlavor.create_one_flavor() + flavor = compute_fakes.FakeFlavor.create_one_flavor( + attrs={'os-flavor-access:is_public': False}) 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 = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes.PROJECT), + loaded=True, + ) self.cmd = flavor.UnsetFlavor(self.app, None) - def test_flavor_unset(self): + def test_flavor_unset_property(self): arglist = [ '--property', 'property', 'baremetal' @@ -384,8 +642,83 @@ class TestFlavorUnset(TestFlavor): parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - try: - self.flavors_mock.find.assert_called_with(name=parsed_args.flavor) - except Exception: - self.flavors_mock.get.assert_called_with(parsed_args.flavor) + self.flavors_mock.find.assert_called_with(name=parsed_args.flavor, + is_public=None) + self.assertIsNone(result) + + def test_flavor_unset_project(self): + arglist = [ + '--project', identity_fakes.project_id, + self.flavor.id, + ] + verifylist = [ + ('project', identity_fakes.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.flavor_access_mock.remove_tenant_access.assert_called_with( + self.flavor.id, + identity_fakes.project_id, + ) + + def test_flavor_unset_no_project(self): + arglist = [ + '--project', '', + self.flavor.id, + ] + verifylist = [ + ('project', ''), + ('flavor', self.flavor.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_flavor_unset_no_flavor(self): + arglist = [ + '--project', identity_fakes.project_id, + ] + verifylist = [ + ('project', identity_fakes.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', identity_fakes.project_id, + 'unexist_flavor', + ] + verifylist = [ + ('project', identity_fakes.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) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) diff --git a/openstackclient/tests/compute/v2/test_server.py b/openstackclient/tests/compute/v2/test_server.py index 17681672..2dfdb68a 100644 --- a/openstackclient/tests/compute/v2/test_server.py +++ b/openstackclient/tests/compute/v2/test_server.py @@ -89,6 +89,7 @@ class TestServer(compute_fakes.TestComputev2): class TestServerCreate(TestServer): columns = ( + 'OS-EXT-STS:power_state', 'addresses', 'flavor', 'id', @@ -100,6 +101,8 @@ class TestServerCreate(TestServer): def datalist(self): datalist = ( + server._format_servers_list_power_state( + getattr(self.new_server, 'OS-EXT-STS:power_state')), '', self.flavor.name + ' (' + self.new_server.flavor.get('id') + ')', self.new_server.id, @@ -146,7 +149,6 @@ class TestServerCreate(TestServer): ('server_name', self.new_server.name), ] - # Missing required args should bail here self.assertRaises(utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -1211,6 +1213,67 @@ class TestServerResume(TestServer): self.run_method_with_servers('resume', 3) +class TestServerSet(TestServer): + + def setUp(self): + super(TestServerSet, self).setUp() + + self.methods = { + 'update': None, + 'reset_state': None, + 'change_password': None, + } + + self.fake_servers = self.setup_servers_mock(2) + + # Get the command object to test + self.cmd = server.SetServer(self.app, None) + + def test_server_set_no_option(self): + arglist = [ + 'foo_vm' + ] + verifylist = [ + ('server', 'foo_vm') + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self.assertNotCalled(self.fake_servers[0].update) + self.assertNotCalled(self.fake_servers[0].reset_state) + self.assertNotCalled(self.fake_servers[0].change_password) + self.assertNotCalled(self.servers_mock.set_meta) + self.assertIsNone(result) + + def test_server_set_with_state(self): + for index, state in enumerate(['active', 'error']): + arglist = [ + '--state', state, + 'foo_vm', + ] + verifylist = [ + ('state', state), + ('server', 'foo_vm'), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + self.fake_servers[index].reset_state.assert_called_once_with( + state=state) + self.assertIsNone(result) + + def test_server_set_with_invalid_state(self): + arglist = [ + '--state', 'foo_state', + 'foo_vm', + ] + verifylist = [ + ('state', 'foo_state'), + ('server', 'foo_vm'), + ] + self.assertRaises(utils.ParserException, + self.check_parser, + self.cmd, arglist, verifylist) + + class TestServerShelve(TestServer): def setUp(self): @@ -1231,6 +1294,101 @@ class TestServerShelve(TestServer): self.run_method_with_servers('shelve', 3) +class TestServerShow(TestServer): + + def setUp(self): + super(TestServerShow, self).setUp() + + self.image = image_fakes.FakeImage.create_one_image() + self.flavor = compute_fakes.FakeFlavor.create_one_flavor() + server_info = { + 'image': {'id': self.image.id}, + 'flavor': {'id': self.flavor.id}, + 'tenant_id': 'tenant-id-xxx', + 'networks': {'public': ['10.20.30.40', '2001:db8::f']}, + } + # Fake the server.diagnostics() method. The return value contains http + # response and data. The data is a dict. Sincce this method itself is + # faked, we don't need to fake everything of the return value exactly. + resp = mock.Mock() + resp.status_code = 200 + server_method = { + 'diagnostics': (resp, {'test': 'test'}), + } + self.server = compute_fakes.FakeServer.create_one_server( + attrs=server_info, methods=server_method) + + # This is the return value for utils.find_resource() + self.servers_mock.get.return_value = self.server + self.cimages_mock.get.return_value = self.image + self.flavors_mock.get.return_value = self.flavor + + # Get the command object to test + self.cmd = server.ShowServer(self.app, None) + + self.columns = ( + 'OS-EXT-STS:power_state', + 'addresses', + 'flavor', + 'id', + 'image', + 'name', + 'networks', + 'project_id', + 'properties', + ) + + self.data = ( + 'Running', + 'public=10.20.30.40, 2001:db8::f', + self.flavor.name + " (" + self.flavor.id + ")", + self.server.id, + self.image.name + " (" + self.image.id + ")", + self.server.name, + {'public': ['10.20.30.40', '2001:db8::f']}, + 'tenant-id-xxx', + '', + ) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + self.assertRaises(utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_show(self): + arglist = [ + self.server.name, + ] + verifylist = [ + ('diagnostics', False), + ('server', self.server.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_show_diagnostics(self): + arglist = [ + '--diagnostics', + self.server.name, + ] + verifylist = [ + ('diagnostics', True), + ('server', self.server.name), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.assertEqual(('test',), columns) + self.assertEqual(('test',), data) + + class TestServerStart(TestServer): def setUp(self): @@ -1449,14 +1607,12 @@ class TestServerGeneral(TestServer): @mock.patch('openstackclient.common.utils.find_resource') def test_prep_server_detail(self, find_resource): # Setup mock method return value. utils.find_resource() will be called - # twice in _prep_server_detail(): - # - The first time, return image info. - # - The second time, return flavor info. + # three times in _prep_server_detail(): + # - The first time, return server info. + # - The second time, return image info. + # - The third time, return flavor info. _image = image_fakes.FakeImage.create_one_image() _flavor = compute_fakes.FakeFlavor.create_one_flavor() - find_resource.side_effect = [_image, _flavor] - - # compute_client.servers.get() will be called once, return server info. server_info = { 'image': {u'id': _image.id}, 'flavor': {u'id': _flavor.id}, @@ -1465,7 +1621,7 @@ class TestServerGeneral(TestServer): 'links': u'http://xxx.yyy.com', } _server = compute_fakes.FakeServer.create_one_server(attrs=server_info) - self.servers_mock.get.return_value = _server + find_resource.side_effect = [_server, _image, _flavor] # Prepare result data. info = { @@ -1476,6 +1632,8 @@ class TestServerGeneral(TestServer): 'image': u'%s (%s)' % (_image.name, _image.id), 'project_id': u'tenant-id-xxx', 'properties': '', + 'OS-EXT-STS:power_state': server._format_servers_list_power_state( + getattr(_server, 'OS-EXT-STS:power_state')), } # Call _prep_server_detail(). diff --git a/openstackclient/tests/compute/v2/test_server_backup.py b/openstackclient/tests/compute/v2/test_server_backup.py new file mode 100644 index 00000000..b35f9f52 --- /dev/null +++ b/openstackclient/tests/compute/v2/test_server_backup.py @@ -0,0 +1,270 @@ +# 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 openstackclient.common import exceptions +from openstackclient.common import utils as common_utils +from openstackclient.compute.v2 import server_backup +from openstackclient.tests.compute.v2 import fakes as compute_fakes +from openstackclient.tests.image.v2 import fakes as image_fakes + + +class TestServerBackup(compute_fakes.TestComputev2): + + def setUp(self): + super(TestServerBackup, self).setUp() + + # Get a shortcut to the compute client ServerManager Mock + self.servers_mock = self.app.client_manager.compute.servers + self.servers_mock.reset_mock() + + # Get a shortcut to the image client ImageManager Mock + self.images_mock = self.app.client_manager.image.images + self.images_mock.reset_mock() + + # Set object attributes to be tested. Could be overwriten in subclass. + self.attrs = {} + + # Set object methods to be tested. Could be overwriten in subclass. + self.methods = {} + + def setup_servers_mock(self, count): + servers = compute_fakes.FakeServer.create_servers( + attrs=self.attrs, + methods=self.methods, + count=count, + ) + + # This is the return value for utils.find_resource() + self.servers_mock.get = compute_fakes.FakeServer.get_servers( + servers, + 0, + ) + return servers + + +class TestServerBackupCreate(TestServerBackup): + + # Just return whatever Image is testing with these days + def image_columns(self, image): + columnlist = tuple(sorted(image.keys())) + return columnlist + + def image_data(self, image): + datalist = ( + image['id'], + image['name'], + image['owner'], + image['protected'], + 'active', + common_utils.format_list(image.get('tags')), + image['visibility'], + ) + return datalist + + def setUp(self): + super(TestServerBackupCreate, self).setUp() + + # Get the command object to test + self.cmd = server_backup.CreateServerBackup(self.app, None) + + self.methods = { + 'backup': None, + } + + def setup_images_mock(self, count, servers=None): + if servers: + images = image_fakes.FakeImage.create_images( + attrs={ + 'name': servers[0].name, + 'status': 'active', + }, + count=count, + ) + else: + images = image_fakes.FakeImage.create_images( + attrs={ + 'status': 'active', + }, + count=count, + ) + + self.images_mock.get = mock.MagicMock(side_effect=images) + return images + + def test_server_backup_defaults(self): + servers = self.setup_servers_mock(count=1) + images = self.setup_images_mock(count=1, servers=servers) + + arglist = [ + servers[0].id, + ] + verifylist = [ + ('name', None), + ('type', None), + ('rotate', None), + ('wait', False), + ('server', servers[0].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) + + # ServerManager.backup(server, backup_name, backup_type, rotation) + self.servers_mock.backup.assert_called_with( + servers[0].id, + servers[0].name, + '', + 1, + ) + + self.assertEqual(self.image_columns(images[0]), columns) + self.assertEqual(self.image_data(images[0]), data) + + def test_server_backup_create_options(self): + servers = self.setup_servers_mock(count=1) + images = self.setup_images_mock(count=1, servers=servers) + + arglist = [ + '--name', 'image', + '--type', 'daily', + '--rotate', '2', + servers[0].id, + ] + verifylist = [ + ('name', 'image'), + ('type', 'daily'), + ('rotate', 2), + ('server', servers[0].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) + + # ServerManager.backup(server, backup_name, backup_type, rotation) + self.servers_mock.backup.assert_called_with( + servers[0].id, + 'image', + 'daily', + 2, + ) + + self.assertEqual(self.image_columns(images[0]), columns) + self.assertEqual(self.image_data(images[0]), data) + + @mock.patch.object(common_utils, 'wait_for_status', return_value=False) + def test_server_backup_wait_fail(self, mock_wait_for_status): + servers = self.setup_servers_mock(count=1) + images = image_fakes.FakeImage.create_images( + attrs={ + 'name': servers[0].name, + 'status': 'active', + }, + count=5, + ) + + self.images_mock.get = mock.MagicMock( + side_effect=images, + ) + + arglist = [ + '--name', 'image', + '--type', 'daily', + '--wait', + servers[0].id, + ] + verifylist = [ + ('name', 'image'), + ('type', 'daily'), + ('wait', True), + ('server', servers[0].id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + self.assertRaises( + exceptions.CommandError, + self.cmd.take_action, + parsed_args, + ) + + # ServerManager.backup(server, backup_name, backup_type, rotation) + self.servers_mock.backup.assert_called_with( + servers[0].id, + 'image', + 'daily', + 1, + ) + + mock_wait_for_status.assert_called_once_with( + self.images_mock.get, + images[0].id, + callback=mock.ANY + ) + + @mock.patch.object(common_utils, 'wait_for_status', return_value=True) + def test_server_backup_wait_ok(self, mock_wait_for_status): + servers = self.setup_servers_mock(count=1) + images = image_fakes.FakeImage.create_images( + attrs={ + 'name': servers[0].name, + 'status': 'active', + }, + count=5, + ) + + self.images_mock.get = mock.MagicMock( + side_effect=images, + ) + + arglist = [ + '--name', 'image', + '--type', 'daily', + '--wait', + servers[0].id, + ] + verifylist = [ + ('name', 'image'), + ('type', 'daily'), + ('wait', True), + ('server', servers[0].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) + + # ServerManager.backup(server, backup_name, backup_type, rotation) + self.servers_mock.backup.assert_called_with( + servers[0].id, + 'image', + 'daily', + 1, + ) + + mock_wait_for_status.assert_called_once_with( + self.images_mock.get, + images[0].id, + callback=mock.ANY + ) + + self.assertEqual(self.image_columns(images[0]), columns) + self.assertEqual(self.image_data(images[0]), data) diff --git a/openstackclient/tests/compute/v2/test_service.py b/openstackclient/tests/compute/v2/test_service.py index db097204..7a5a840f 100644 --- a/openstackclient/tests/compute/v2/test_service.py +++ b/openstackclient/tests/compute/v2/test_service.py @@ -13,12 +13,10 @@ # under the License. # -import copy import mock from openstackclient.compute.v2 import service from openstackclient.tests.compute.v2 import fakes as compute_fakes -from openstackclient.tests import fakes class TestService(compute_fakes.TestComputev2): @@ -36,6 +34,8 @@ class TestServiceDelete(TestService): def setUp(self): super(TestServiceDelete, self).setUp() + self.service = compute_fakes.FakeService.create_one_service() + self.service_mock.delete.return_value = None # Get the command object to test @@ -43,17 +43,17 @@ class TestServiceDelete(TestService): def test_service_delete_no_options(self): arglist = [ - compute_fakes.service_binary, + self.service.binary, ] verifylist = [ - ('service', compute_fakes.service_binary), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.service_mock.delete.assert_called_with( - compute_fakes.service_binary, + self.service.binary, ) self.assertIsNone(result) @@ -63,23 +63,21 @@ class TestServiceList(TestService): def setUp(self): super(TestServiceList, self).setUp() - self.service_mock.list.return_value = [fakes.FakeResource( - None, - copy.deepcopy(compute_fakes.SERVICE), - loaded=True, - )] + self.service = compute_fakes.FakeService.create_one_service() + + self.service_mock.list.return_value = [self.service] # Get the command object to test self.cmd = service.ListService(self.app, None) def test_service_list(self): arglist = [ - '--host', compute_fakes.service_host, - '--service', compute_fakes.service_binary, + '--host', self.service.host, + '--service', self.service.binary, ] verifylist = [ - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -89,22 +87,22 @@ class TestServiceList(TestService): columns, data = self.cmd.take_action(parsed_args) self.service_mock.list.assert_called_with( - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, ) self.assertNotIn("Disabled Reason", columns) - self.assertNotIn(compute_fakes.service_disabled_reason, list(data)[0]) + self.assertNotIn(self.service.disabled_reason, list(data)[0]) def test_service_list_with_long_option(self): arglist = [ - '--host', compute_fakes.service_host, - '--service', compute_fakes.service_binary, + '--host', self.service.host, + '--service', self.service.binary, '--long' ] verifylist = [ - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ('long', True) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -115,7 +113,7 @@ class TestServiceList(TestService): columns, data = self.cmd.take_action(parsed_args) self.assertIn("Disabled Reason", columns) - self.assertIn(compute_fakes.service_disabled_reason, list(data)[0]) + self.assertIn(self.service.disabled_reason, list(data)[0]) class TestServiceSet(TestService): @@ -123,59 +121,52 @@ class TestServiceSet(TestService): def setUp(self): super(TestServiceSet, self).setUp() - self.service_mock.enable.return_value = [fakes.FakeResource( - None, - copy.deepcopy(compute_fakes.SERVICE), - loaded=True, - )] + self.service = compute_fakes.FakeService.create_one_service() - self.service_mock.disable.return_value = [fakes.FakeResource( - None, - copy.deepcopy(compute_fakes.SERVICE), - loaded=True, - )] + self.service_mock.enable.return_value = self.service + self.service_mock.disable.return_value = self.service self.cmd = service.SetService(self.app, None) def test_service_set_enable(self): arglist = [ '--enable', - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, ] verifylist = [ ('enabled', True), - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.service_mock.enable.assert_called_with( - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary ) self.assertIsNone(result) def test_service_set_disable(self): arglist = [ '--disable', - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, ] verifylist = [ ('enabled', False), - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.service_mock.disable.assert_called_with( - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary ) self.assertIsNone(result) @@ -184,22 +175,22 @@ class TestServiceSet(TestService): arglist = [ '--disable', '--disable-reason', reason, - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, ] verifylist = [ ('enabled', False), ('disable_reason', reason), - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.service_mock.disable_log_reason.assert_called_with( - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, reason ) self.assertIsNone(result) @@ -208,14 +199,14 @@ class TestServiceSet(TestService): reason = 'earthquake' arglist = [ '--disable-reason', reason, - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, ] verifylist = [ ('enabled', True), ('disable_reason', reason), - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -226,8 +217,8 @@ class TestServiceSet(TestService): mock_log.assert_called_once_with(msg) self.service_mock.enable.assert_called_with( - compute_fakes.service_host, - compute_fakes.service_binary + self.service.host, + self.service.binary ) self.assertIsNone(result) @@ -236,14 +227,14 @@ class TestServiceSet(TestService): arglist = [ '--enable', '--disable-reason', reason, - compute_fakes.service_host, - compute_fakes.service_binary, + self.service.host, + self.service.binary, ] verifylist = [ ('enabled', True), ('disable_reason', reason), - ('host', compute_fakes.service_host), - ('service', compute_fakes.service_binary), + ('host', self.service.host), + ('service', self.service.binary), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -254,7 +245,7 @@ class TestServiceSet(TestService): mock_log.assert_called_once_with(msg) self.service_mock.enable.assert_called_with( - compute_fakes.service_host, - compute_fakes.service_binary + self.service.host, + self.service.binary ) self.assertIsNone(result) diff --git a/openstackclient/tests/fakes.py b/openstackclient/tests/fakes.py index 46f983dc..ad4705a4 100644 --- a/openstackclient/tests/fakes.py +++ b/openstackclient/tests/fakes.py @@ -97,6 +97,11 @@ class FakeApp(object): self.log = _log +class FakeOptions(object): + def __init__(self, **kwargs): + self.os_beta_command = False + + class FakeClient(object): def __init__(self, **kwargs): @@ -105,6 +110,9 @@ class FakeClient(object): class FakeClientManager(object): + _api_version = { + 'image': '2', + } def __init__(self): self.compute = None @@ -189,6 +197,10 @@ class FakeResource(object): def keys(self): return self._info.keys() + @property + def info(self): + return self._info + class FakeResponse(requests.Response): diff --git a/openstackclient/tests/identity/v2_0/test_catalog.py b/openstackclient/tests/identity/v2_0/test_catalog.py index 1e27bb3c..d9ae6a80 100644 --- a/openstackclient/tests/identity/v2_0/test_catalog.py +++ b/openstackclient/tests/identity/v2_0/test_catalog.py @@ -36,6 +36,12 @@ class TestCatalog(utils.TestCommand): 'internalURL': 'https://internal.two.example.com', 'adminURL': 'https://admin.two.example.com', }, + { + 'region': None, + 'publicURL': 'https://public.none.example.com', + 'internalURL': 'https://internal.none.example.com', + 'adminURL': 'https://admin.none.example.com', + }, ], } @@ -87,7 +93,10 @@ class TestCatalogList(TestCatalog): 'adminURL: https://admin.one.example.com\n' 'two\n publicURL: https://public.two.example.com\n ' 'internalURL: https://internal.two.example.com\n ' - 'adminURL: https://admin.two.example.com\n', + 'adminURL: https://admin.two.example.com\n' + '<none>\n publicURL: https://public.none.example.com\n ' + 'internalURL: https://internal.none.example.com\n ' + 'adminURL: https://admin.none.example.com\n', ), ) self.assertEqual(datalist, tuple(data)) @@ -164,7 +173,10 @@ class TestCatalogShow(TestCatalog): 'adminURL: https://admin.one.example.com\n' 'two\n publicURL: https://public.two.example.com\n ' 'internalURL: https://internal.two.example.com\n ' - 'adminURL: https://admin.two.example.com\n', + 'adminURL: https://admin.two.example.com\n' + '<none>\n publicURL: https://public.none.example.com\n ' + 'internalURL: https://internal.none.example.com\n ' + 'adminURL: https://admin.none.example.com\n', 'qwertyuiop', 'supernova', 'compute', diff --git a/openstackclient/tests/identity/v3/test_catalog.py b/openstackclient/tests/identity/v3/test_catalog.py index a03c9d3e..1b8fa085 100644 --- a/openstackclient/tests/identity/v3/test_catalog.py +++ b/openstackclient/tests/identity/v3/test_catalog.py @@ -38,6 +38,11 @@ class TestCatalog(utils.TestCommand): 'url': 'https://internal.example.com', 'interface': 'internal', }, + { + 'region': None, + 'url': 'https://none.example.com', + 'interface': 'none', + }, ], } @@ -81,7 +86,8 @@ class TestCatalogList(TestCatalog): 'compute', 'onlyone\n public: https://public.example.com\n' 'onlyone\n admin: https://admin.example.com\n' - '<none>\n internal: https://internal.example.com\n', + '<none>\n internal: https://internal.example.com\n' + '<none>\n none: https://none.example.com\n', ), ) self.assertEqual(datalist, tuple(data)) @@ -114,7 +120,8 @@ class TestCatalogShow(TestCatalog): datalist = ( 'onlyone\n public: https://public.example.com\nonlyone\n' ' admin: https://admin.example.com\n' - '<none>\n internal: https://internal.example.com\n', + '<none>\n internal: https://internal.example.com\n' + '<none>\n none: https://none.example.com\n', 'qwertyuiop', 'supernova', 'compute', diff --git a/openstackclient/tests/identity/v3/test_identity_provider.py b/openstackclient/tests/identity/v3/test_identity_provider.py index 465e79ba..3ff79812 100644 --- a/openstackclient/tests/identity/v3/test_identity_provider.py +++ b/openstackclient/tests/identity/v3/test_identity_provider.py @@ -616,6 +616,7 @@ class TestIdentityProviderShow(TestIdentityProvider): self.identity_providers_mock.get.assert_called_with( identity_fakes.idp_id, + id='test_idp' ) collist = ('description', 'enabled', 'id', 'remote_ids') diff --git a/openstackclient/tests/identity/v3/test_service_provider.py b/openstackclient/tests/identity/v3/test_service_provider.py index 80d60c5a..99ea1f75 100644 --- a/openstackclient/tests/identity/v3/test_service_provider.py +++ b/openstackclient/tests/identity/v3/test_service_provider.py @@ -408,6 +408,7 @@ class TestServiceProviderShow(TestServiceProvider): self.service_providers_mock.get.assert_called_with( service_fakes.sp_id, + id='BETA' ) collist = ('auth_url', 'description', 'enabled', 'id', 'sp_url') diff --git a/openstackclient/tests/image/v2/fakes.py b/openstackclient/tests/image/v2/fakes.py index f90d846d..24aaec51 100644 --- a/openstackclient/tests/image/v2/fakes.py +++ b/openstackclient/tests/image/v2/fakes.py @@ -18,6 +18,9 @@ import mock import random import uuid +from glanceclient.v2 import schemas +import warlock + from openstackclient.common import utils as common_utils from openstackclient.tests import fakes from openstackclient.tests import utils @@ -154,6 +157,8 @@ class FakeImagev2Client(object): self.images.resource_class = fakes.FakeResource(None, {}) self.image_members = mock.Mock() self.image_members.resource_class = fakes.FakeResource(None, {}) + self.image_tags = mock.Mock() + self.image_tags.resource_class = fakes.FakeResource(None, {}) self.auth_token = kwargs['token'] self.management_url = kwargs['endpoint'] @@ -194,7 +199,7 @@ class FakeImage(object): # Set default attribute image_info = { - 'id': 'image-id' + uuid.uuid4().hex, + 'id': str(uuid.uuid4()), 'name': 'image-name' + uuid.uuid4().hex, 'owner': 'image-owner' + uuid.uuid4().hex, 'protected': bool(random.choice([0, 1])), @@ -205,11 +210,13 @@ class FakeImage(object): # Overwrite default attributes if there are some attributes set image_info.update(attrs) - image = fakes.FakeResource( - None, - image_info, - loaded=True) - return image + # Set up the schema + model = warlock.model_factory( + IMAGE_schema, + schemas.SchemaBasedModel, + ) + + return model(**image_info) @staticmethod def create_images(attrs=None, count=2): @@ -249,27 +256,6 @@ class FakeImage(object): return mock.MagicMock(side_effect=images) @staticmethod - def get_image_info(image=None): - """Get the image info from a faked image object. - - :param image: - A FakeResource objects faking image - :return - A dictionary which includes the faked image info as follows: - { - 'id': image_id, - 'name': image_name, - 'owner': image_owner, - 'protected': image_protected, - 'visibility': image_visibility, - 'tags': image_tags - } - """ - if image is not None: - return image._info - return {} - - @staticmethod def get_image_columns(image=None): """Get the image columns from a faked image object. @@ -280,9 +266,8 @@ class FakeImage(object): ('id', 'name', 'owner', 'protected', 'visibility', 'tags') """ if image is not None: - return tuple(k for k in sorted( - FakeImage.get_image_info(image).keys())) - return tuple([]) + return tuple(sorted(image)) + return IMAGE_columns @staticmethod def get_image_data(image=None): @@ -296,7 +281,7 @@ class FakeImage(object): """ data_list = [] if image is not None: - for x in sorted(FakeImage.get_image_info(image).keys()): + for x in sorted(image.keys()): if x == 'tags': # The 'tags' should be format_list data_list.append( diff --git a/openstackclient/tests/image/v2/test_image.py b/openstackclient/tests/image/v2/test_image.py index 0248f30b..ca20d83d 100644 --- a/openstackclient/tests/image/v2/test_image.py +++ b/openstackclient/tests/image/v2/test_image.py @@ -20,6 +20,7 @@ import warlock from glanceclient.v2 import schemas from openstackclient.common import exceptions +from openstackclient.common import utils as common_utils from openstackclient.image.v2 import image from openstackclient.tests import fakes from openstackclient.tests.identity.v3 import fakes as identity_fakes @@ -36,6 +37,8 @@ class TestImage(image_fakes.TestImagev2): 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 @@ -74,7 +77,8 @@ class TestImageCreate(TestImage): # This is the return value for utils.find_resource() self.images_mock.get.return_value = copy.deepcopy( - image_fakes.FakeImage.get_image_info(self.new_image)) + self.new_image + ) self.images_mock.update.return_value = self.new_image # Get the command object to test @@ -341,28 +345,31 @@ class TestImageCreate(TestImage): class TestAddProjectToImage(TestImage): + _image = image_fakes.FakeImage.create_one_image() + columns = ( 'image_id', 'member_id', 'status', ) + datalist = ( - image_fakes.image_id, + _image.id, identity_fakes.project_id, - image_fakes.member_status, + image_fakes.member_status ) def setUp(self): super(TestAddProjectToImage, self).setUp() # This is the return value for utils.find_resource() - self.images_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(image_fakes.IMAGE), - loaded=True, - ) + self.images_mock.get.return_value = self._image + + # Update the image_id in the MEMBER dict + self.new_member = copy.deepcopy(image_fakes.MEMBER) + self.new_member['image_id'] = self._image.id self.image_members_mock.create.return_value = fakes.FakeModel( - copy.deepcopy(image_fakes.MEMBER), + self.new_member, ) self.project_mock.get.return_value = fakes.FakeResource( None, @@ -379,11 +386,11 @@ class TestAddProjectToImage(TestImage): def test_add_project_to_image_no_option(self): arglist = [ - image_fakes.image_id, + self._image.id, identity_fakes.project_id, ] verifylist = [ - ('image', image_fakes.image_id), + ('image', self._image.id), ('project', identity_fakes.project_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -393,20 +400,21 @@ class TestAddProjectToImage(TestImage): # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.image_members_mock.create.assert_called_with( - image_fakes.image_id, + self._image.id, identity_fakes.project_id ) + self.assertEqual(self.columns, columns) self.assertEqual(self.datalist, data) def test_add_project_to_image_with_option(self): arglist = [ - image_fakes.image_id, + self._image.id, identity_fakes.project_id, '--project-domain', identity_fakes.domain_id, ] verifylist = [ - ('image', image_fakes.image_id), + ('image', self._image.id), ('project', identity_fakes.project_id), ('project_domain', identity_fakes.domain_id), ] @@ -417,7 +425,7 @@ class TestAddProjectToImage(TestImage): # data to be shown. columns, data = self.cmd.take_action(parsed_args) self.image_members_mock.create.assert_called_with( - image_fakes.image_id, + self._image.id, identity_fakes.project_id ) self.assertEqual(self.columns, columns) @@ -468,25 +476,26 @@ class TestImageDelete(TestImage): class TestImageList(TestImage): + _image = image_fakes.FakeImage.create_one_image() + columns = ( 'ID', 'Name', 'Status', ) + datalist = ( - ( - image_fakes.image_id, - image_fakes.image_name, - '', - ), - ) + _image.id, + _image.name, + '', + ), def setUp(self): super(TestImageList, self).setUp() self.api_mock = mock.Mock() self.api_mock.image_list.side_effect = [ - [copy.deepcopy(image_fakes.IMAGE)], [], + [self._image], [], ] self.app.client_manager.image.api = self.api_mock @@ -611,24 +620,22 @@ class TestImageList(TestImage): self.assertEqual(collist, columns) datalist = (( - image_fakes.image_id, - image_fakes.image_name, - '', + self._image.id, + self._image.name, '', '', '', - 'public', - False, - image_fakes.image_owner, '', + 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(image_fakes.IMAGE), - ] + sf_mock.return_value = [copy.deepcopy(self._image)] arglist = [ '--property', 'a=1', @@ -644,7 +651,7 @@ class TestImageList(TestImage): columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with() sf_mock.assert_called_with( - [image_fakes.IMAGE], + [self._image], attr='a', value='1', property_field='properties', @@ -655,9 +662,7 @@ class TestImageList(TestImage): @mock.patch('openstackclient.common.utils.sort_items') def test_image_list_sort_option(self, si_mock): - si_mock.return_value = [ - copy.deepcopy(image_fakes.IMAGE) - ] + si_mock.return_value = [copy.deepcopy(self._image)] arglist = ['--sort', 'name:asc'] verifylist = [('sort', 'name:asc')] @@ -669,10 +674,9 @@ class TestImageList(TestImage): columns, data = self.cmd.take_action(parsed_args) self.api_mock.image_list.assert_called_with() si_mock.assert_called_with( - [image_fakes.IMAGE], + [self._image], 'name:asc' ) - self.assertEqual(self.columns, columns) self.assertEqual(self.datalist, tuple(data)) @@ -720,12 +724,10 @@ class TestRemoveProjectImage(TestImage): 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 = fakes.FakeResource( - None, - copy.deepcopy(image_fakes.IMAGE), - loaded=True, - ) + self.images_mock.get.return_value = self._image + self.project_mock.get.return_value = fakes.FakeResource( None, copy.deepcopy(identity_fakes.PROJECT), @@ -742,11 +744,11 @@ class TestRemoveProjectImage(TestImage): def test_remove_project_image_no_options(self): arglist = [ - image_fakes.image_id, + self._image.id, identity_fakes.project_id, ] verifylist = [ - ('image', image_fakes.image_id), + ('image', self._image.id), ('project', identity_fakes.project_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -754,19 +756,19 @@ class TestRemoveProjectImage(TestImage): result = self.cmd.take_action(parsed_args) self.image_members_mock.delete.assert_called_with( - image_fakes.image_id, + self._image.id, identity_fakes.project_id, ) self.assertIsNone(result) def test_remove_project_image_with_options(self): arglist = [ - image_fakes.image_id, + self._image.id, identity_fakes.project_id, '--project-domain', identity_fakes.domain_id, ] verifylist = [ - ('image', image_fakes.image_id), + ('image', self._image.id), ('project', identity_fakes.project_id), ('project_domain', identity_fakes.domain_id), ] @@ -775,7 +777,7 @@ class TestRemoveProjectImage(TestImage): result = self.cmd.take_action(parsed_args) self.image_members_mock.delete.assert_called_with( - image_fakes.image_id, + self._image.id, identity_fakes.project_id, ) self.assertIsNone(result) @@ -1184,3 +1186,94 @@ class TestImageShow(TestImage): self.assertEqual(image_fakes.IMAGE_columns, columns) self.assertEqual(image_fakes.IMAGE_SHOW_data, data) + + +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_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) diff --git a/openstackclient/tests/network/v2/fakes.py b/openstackclient/tests/network/v2/fakes.py index 1989b515..587fdc1a 100644 --- a/openstackclient/tests/network/v2/fakes.py +++ b/openstackclient/tests/network/v2/fakes.py @@ -36,6 +36,9 @@ QUOTA = { "router": 10, "rbac_policy": -1, "port": 50, + "vip": 10, + "member": 10, + "health_monitor": 10, } @@ -106,6 +109,43 @@ class FakeAddressScope(object): return address_scope + @staticmethod + def create_address_scopes(attrs=None, count=2): + """Create multiple fake address scopes. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of address scopes to fake + :return: + A list of FakeResource objects faking the address scopes + """ + address_scopes = [] + for i in range(0, count): + address_scopes.append( + FakeAddressScope.create_one_address_scope(attrs)) + + return address_scopes + + @staticmethod + def get_address_scopes(address_scopes=None, count=2): + """Get an iterable MagicMock object with a list of faked address scopes. + + If address scopes list is provided, then initialize the Mock object + with the list. Otherwise create one. + + :param List address scopes: + A list of FakeResource objects faking address scopes + :param int count: + The number of address scopes to fake + :return: + An iterable Mock object with side_effect set to a list of faked + address scopes + """ + if address_scopes is None: + address_scopes = FakeAddressScope.create_address_scopes(count) + return mock.MagicMock(side_effect=address_scopes) + class FakeAvailabilityZone(object): """Fake one or more network availability zones (AZs).""" @@ -166,8 +206,7 @@ class FakeNetwork(object): :param Dictionary attrs: A dictionary with all attributes :return: - A FakeResource object, with id, name, admin_state_up, - router_external, status, subnets, tenant_id + A FakeResource object, with id, name, etc. """ attrs = attrs or {} @@ -181,7 +220,7 @@ class FakeNetwork(object): 'shared': False, 'subnets': ['a', 'b'], 'provider_network_type': 'vlan', - 'router_external': True, + 'router:external': True, 'availability_zones': [], 'availability_zone_hints': [], 'is_default': False, @@ -195,6 +234,7 @@ class FakeNetwork(object): # Set attributes with special mapping in OpenStack SDK. network.project_id = network_attrs['tenant_id'] + network.is_router_external = network_attrs['router:external'] return network @@ -235,6 +275,58 @@ class FakeNetwork(object): return mock.MagicMock(side_effect=networks) +class FakeNetworkSegment(object): + """Fake one or more network segments.""" + + @staticmethod + def create_one_network_segment(attrs=None): + """Create a fake network segment. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object faking the network segment + """ + attrs = attrs or {} + + # Set default attributes. + network_segment_attrs = { + 'id': 'segment-id-' + uuid.uuid4().hex, + 'network_id': 'network-id-' + uuid.uuid4().hex, + 'network_type': 'vlan', + 'physical_network': 'physical-network-name-' + uuid.uuid4().hex, + 'segmentation_id': 1024, + } + + # Overwrite default attributes. + network_segment_attrs.update(attrs) + + network_segment = fakes.FakeResource( + info=copy.deepcopy(network_segment_attrs), + loaded=True + ) + + return network_segment + + @staticmethod + def create_network_segments(attrs=None, count=2): + """Create multiple fake network segments. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of network segments to fake + :return: + A list of FakeResource objects faking the network segments + """ + network_segments = [] + for i in range(0, count): + network_segments.append( + FakeNetworkSegment.create_one_network_segment(attrs) + ) + return network_segments + + class FakePort(object): """Fake one or more ports.""" @@ -478,8 +570,8 @@ class FakeSecurityGroupRule(object): 'direction': 'ingress', 'ethertype': 'IPv4', 'id': 'security-group-rule-id-' + uuid.uuid4().hex, - 'port_range_max': 0, - 'port_range_min': 0, + 'port_range_max': None, + 'port_range_min': None, 'protocol': 'tcp', 'remote_group_id': None, 'remote_ip_prefix': '0.0.0.0/0', diff --git a/openstackclient/tests/network/v2/test_address_scope.py b/openstackclient/tests/network/v2/test_address_scope.py new file mode 100644 index 00000000..b4f4fa88 --- /dev/null +++ b/openstackclient/tests/network/v2/test_address_scope.py @@ -0,0 +1,411 @@ +# 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 +import mock + +from mock import call +from openstackclient.common import exceptions +from openstackclient.network.v2 import address_scope +from openstackclient.tests import fakes +from openstackclient.tests.identity.v3 import fakes as identity_fakes_v3 +from openstackclient.tests.network.v2 import fakes as network_fakes +from openstackclient.tests import utils as tests_utils + + +class TestAddressScope(network_fakes.TestNetworkV2): + + def setUp(self): + super(TestAddressScope, self).setUp() + + # Get a shortcut to the network client + self.network = self.app.client_manager.network + + +class TestCreateAddressScope(TestAddressScope): + + # The new address scope created. + new_address_scope = ( + network_fakes.FakeAddressScope.create_one_address_scope( + attrs={ + 'tenant_id': identity_fakes_v3.project_id, + } + )) + columns = ( + 'id', + 'ip_version', + 'name', + 'project_id', + 'shared' + ) + data = ( + new_address_scope.id, + new_address_scope.ip_version, + new_address_scope.name, + new_address_scope.project_id, + new_address_scope.shared, + ) + + def setUp(self): + super(TestCreateAddressScope, self).setUp() + self.network.create_address_scope = mock.Mock( + return_value=self.new_address_scope) + + # Get the command object to test + self.cmd = address_scope.CreateAddressScope(self.app, self.namespace) + + # Set identity client v3. And get a shortcut to Identity client. + identity_client = identity_fakes_v3.FakeIdentityv3Client( + endpoint=fakes.AUTH_URL, + token=fakes.AUTH_TOKEN, + ) + self.app.client_manager.identity = identity_client + self.identity = self.app.client_manager.identity + + # Get a shortcut to the ProjectManager Mock + self.projects_mock = self.identity.projects + self.projects_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes_v3.PROJECT), + loaded=True, + ) + + # Get a shortcut to the DomainManager Mock + self.domains_mock = self.identity.domains + self.domains_mock.get.return_value = fakes.FakeResource( + None, + copy.deepcopy(identity_fakes_v3.DOMAIN), + loaded=True, + ) + + def test_create_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_create_default_options(self): + arglist = [ + self.new_address_scope.name, + ] + verifylist = [ + ('project', None), + ('ip_version', self.new_address_scope.ip_version), + ('name', self.new_address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_address_scope.assert_called_once_with(**{ + 'ip_version': self.new_address_scope.ip_version, + 'name': self.new_address_scope.name, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_all_options(self): + arglist = [ + '--ip-version', str(self.new_address_scope.ip_version), + '--share', + '--project', identity_fakes_v3.project_name, + '--project-domain', identity_fakes_v3.domain_name, + self.new_address_scope.name, + ] + verifylist = [ + ('ip_version', self.new_address_scope.ip_version), + ('share', True), + ('project', identity_fakes_v3.project_name), + ('project_domain', identity_fakes_v3.domain_name), + ('name', self.new_address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = (self.cmd.take_action(parsed_args)) + + self.network.create_address_scope.assert_called_once_with(**{ + 'ip_version': self.new_address_scope.ip_version, + 'shared': True, + 'tenant_id': identity_fakes_v3.project_id, + 'name': self.new_address_scope.name, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + def test_create_no_share(self): + arglist = [ + '--no-share', + self.new_address_scope.name, + ] + verifylist = [ + ('no_share', True), + ('name', self.new_address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.create_address_scope.assert_called_once_with(**{ + 'ip_version': self.new_address_scope.ip_version, + 'shared': False, + 'name': self.new_address_scope.name, + }) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) + + +class TestDeleteAddressScope(TestAddressScope): + + # The address scope to delete. + _address_scopes = ( + network_fakes.FakeAddressScope.create_address_scopes(count=2)) + + def setUp(self): + super(TestDeleteAddressScope, self).setUp() + self.network.delete_address_scope = mock.Mock(return_value=None) + self.network.find_address_scope = ( + network_fakes.FakeAddressScope.get_address_scopes( + address_scopes=self._address_scopes) + ) + + # Get the command object to test + self.cmd = address_scope.DeleteAddressScope(self.app, self.namespace) + + def test_address_scope_delete(self): + arglist = [ + self._address_scopes[0].name, + ] + verifylist = [ + ('address_scope', [self._address_scopes[0].name]), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.network.find_address_scope.assert_called_once_with( + self._address_scopes[0].name, ignore_missing=False) + self.network.delete_address_scope.assert_called_once_with( + self._address_scopes[0]) + self.assertIsNone(result) + + def test_multi_address_scopes_delete(self): + arglist = [] + verifylist = [] + + for a in self._address_scopes: + arglist.append(a.name) + verifylist = [ + ('address_scope', arglist), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + calls = [] + for a in self._address_scopes: + calls.append(call(a)) + self.network.delete_address_scope.assert_has_calls(calls) + self.assertIsNone(result) + + def test_multi_address_scopes_delete_with_exception(self): + arglist = [ + self._address_scopes[0].name, + 'unexist_address_scope', + ] + verifylist = [ + ('address_scope', + [self._address_scopes[0].name, 'unexist_address_scope']), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + find_mock_result = [self._address_scopes[0], exceptions.CommandError] + self.network.find_address_scope = ( + mock.MagicMock(side_effect=find_mock_result) + ) + + try: + self.cmd.take_action(parsed_args) + self.fail('CommandError should be raised.') + except exceptions.CommandError as e: + self.assertEqual('1 of 2 address scopes failed to delete.', str(e)) + + self.network.find_address_scope.assert_any_call( + self._address_scopes[0].name, ignore_missing=False) + self.network.find_address_scope.assert_any_call( + 'unexist_address_scope', ignore_missing=False) + self.network.delete_address_scope.assert_called_once_with( + self._address_scopes[0] + ) + + +class TestListAddressScope(TestAddressScope): + + # The address scopes to list up. + address_scopes = ( + network_fakes.FakeAddressScope.create_address_scopes(count=3)) + columns = ( + 'ID', + 'Name', + 'IP Version', + 'Shared', + 'Project', + ) + data = [] + for scope in address_scopes: + data.append(( + scope.id, + scope.name, + scope.ip_version, + scope.shared, + scope.project_id, + )) + + def setUp(self): + super(TestListAddressScope, self).setUp() + self.network.address_scopes = mock.Mock( + return_value=self.address_scopes) + + # Get the command object to test + self.cmd = address_scope.ListAddressScope(self.app, self.namespace) + + def test_address_scope_list(self): + arglist = [] + verifylist = [] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.address_scopes.assert_called_once_with(**{}) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + +class TestSetAddressScope(TestAddressScope): + + # The address scope to set. + _address_scope = network_fakes.FakeAddressScope.create_one_address_scope() + + def setUp(self): + super(TestSetAddressScope, self).setUp() + self.network.update_address_scope = mock.Mock(return_value=None) + self.network.find_address_scope = mock.Mock( + return_value=self._address_scope) + + # Get the command object to test + self.cmd = address_scope.SetAddressScope(self.app, self.namespace) + + def test_set_nothing(self): + arglist = [self._address_scope.name, ] + verifylist = [ + ('address_scope', self._address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_set_name_and_share(self): + arglist = [ + '--name', 'new_address_scope', + '--share', + self._address_scope.name, + ] + verifylist = [ + ('name', 'new_address_scope'), + ('share', True), + ('address_scope', self._address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + attrs = { + 'name': "new_address_scope", + 'shared': True, + } + self.network.update_address_scope.assert_called_with( + self._address_scope, **attrs) + self.assertIsNone(result) + + def test_set_no_share(self): + arglist = [ + '--no-share', + self._address_scope.name, + ] + verifylist = [ + ('no_share', True), + ('address_scope', self._address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) + attrs = { + 'shared': False, + } + self.network.update_address_scope.assert_called_with( + self._address_scope, **attrs) + self.assertIsNone(result) + + +class TestShowAddressScope(TestAddressScope): + + # The address scope to show. + _address_scope = ( + network_fakes.FakeAddressScope.create_one_address_scope()) + columns = ( + 'id', + 'ip_version', + 'name', + 'project_id', + 'shared', + ) + data = ( + _address_scope.id, + _address_scope.ip_version, + _address_scope.name, + _address_scope.project_id, + _address_scope.shared, + ) + + def setUp(self): + super(TestShowAddressScope, self).setUp() + self.network.find_address_scope = mock.Mock( + return_value=self._address_scope) + + # Get the command object to test + self.cmd = address_scope.ShowAddressScope(self.app, self.namespace) + + def test_show_no_options(self): + arglist = [] + verifylist = [] + + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_show_all_options(self): + arglist = [ + self._address_scope.name, + ] + verifylist = [ + ('address_scope', self._address_scope.name), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_address_scope.assert_called_once_with( + self._address_scope.name, ignore_missing=False) + self.assertEqual(self.columns, columns) + self.assertEqual(list(self.data), list(data)) diff --git a/openstackclient/tests/network/v2/test_floating_ip.py b/openstackclient/tests/network/v2/test_floating_ip.py index 3e261fb5..f9ccfe1c 100644 --- a/openstackclient/tests/network/v2/test_floating_ip.py +++ b/openstackclient/tests/network/v2/test_floating_ip.py @@ -88,7 +88,6 @@ class TestCreateFloatingIPNetwork(TestFloatingIPNetwork): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -314,7 +313,6 @@ class TestCreateFloatingIPCompute(TestFloatingIPCompute): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/network/v2/test_network.py b/openstackclient/tests/network/v2/test_network.py index a1b0aec9..ba810f16 100644 --- a/openstackclient/tests/network/v2/test_network.py +++ b/openstackclient/tests/network/v2/test_network.py @@ -14,6 +14,7 @@ import copy import mock +from mock import call from openstackclient.common import exceptions from openstackclient.common import utils from openstackclient.network.v2 import network @@ -55,7 +56,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'name', 'project_id', 'provider_network_type', - 'router_external', + 'router:external', 'shared', 'status', 'subnets', @@ -70,7 +71,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): _network.name, _network.project_id, _network.provider_network_type, - network._format_router_external(_network.router_external), + network._format_router_external(_network.is_router_external), _network.shared, _network.status, utils.format_list(_network.subnets), @@ -112,7 +113,6 @@ class TestCreateNetworkIdentityV3(TestNetwork): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -149,6 +149,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): "--provider-network-type", "vlan", "--provider-physical-network", "physnet1", "--provider-segment", "400", + "--transparent-vlan", self._network.name, ] verifylist = [ @@ -162,6 +163,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): ('provider_network_type', 'vlan'), ('physical_network', 'physnet1'), ('segmentation_id', '400'), + ('transparent_vlan', True), ('name', self._network.name), ] @@ -179,6 +181,7 @@ class TestCreateNetworkIdentityV3(TestNetwork): 'provider:network_type': 'vlan', 'provider:physical_network': 'physnet1', 'provider:segmentation_id': '400', + 'vlan_transparent': True, }) self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -224,7 +227,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): 'name', 'project_id', 'provider_network_type', - 'router_external', + 'router:external', 'shared', 'status', 'subnets', @@ -239,7 +242,7 @@ class TestCreateNetworkIdentityV2(TestNetwork): _network.name, _network.project_id, _network.provider_network_type, - network._format_router_external(_network.router_external), + network._format_router_external(_network.is_router_external), _network.shared, _network.status, utils.format_list(_network.subnets), @@ -321,33 +324,88 @@ class TestCreateNetworkIdentityV2(TestNetwork): class TestDeleteNetwork(TestNetwork): - # The network to delete. - _network = network_fakes.FakeNetwork.create_one_network() - def setUp(self): super(TestDeleteNetwork, self).setUp() + # The networks to delete + self._networks = network_fakes.FakeNetwork.create_networks(count=3) + self.network.delete_network = mock.Mock(return_value=None) - self.network.find_network = mock.Mock(return_value=self._network) + self.network.find_network = network_fakes.FakeNetwork.get_networks( + networks=self._networks) # Get the command object to test self.cmd = network.DeleteNetwork(self.app, self.namespace) - def test_delete(self): + def test_delete_one_network(self): arglist = [ - self._network.name, + self._networks[0].name, ] verifylist = [ - ('network', [self._network.name]), + ('network', [self._networks[0].name]), ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.network.delete_network.assert_called_once_with(self._networks[0]) + self.assertIsNone(result) + + def test_delete_multiple_networks(self): + arglist = [] + for n in self._networks: + arglist.append(n.id) + verifylist = [ + ('network', arglist), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) - self.network.delete_network.assert_called_once_with(self._network) + calls = [] + for n in self._networks: + calls.append(call(n)) + self.network.delete_network.assert_has_calls(calls) self.assertIsNone(result) + def test_delete_multiple_networks_exception(self): + arglist = [ + self._networks[0].id, + 'xxxx-yyyy-zzzz', + self._networks[1].id, + ] + verifylist = [ + ('network', arglist), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # Fake exception in find_network() + ret_find = [ + self._networks[0], + exceptions.NotFound('404'), + self._networks[1], + ] + self.network.find_network = mock.Mock(side_effect=ret_find) + + # Fake exception in delete_network() + ret_delete = [ + None, + exceptions.NotFound('404'), + ] + self.network.delete_network = mock.Mock(side_effect=ret_delete) + + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + # The second call of find_network() should fail. So delete_network() + # was only called twice. + calls = [ + call(self._networks[0]), + call(self._networks[1]), + ] + self.network.delete_network.assert_has_calls(calls) + class TestListNetwork(TestNetwork): @@ -391,7 +449,7 @@ class TestListNetwork(TestNetwork): net.shared, utils.format_list(net.subnets), net.provider_network_type, - network._format_router_external(net.router_external), + network._format_router_external(net.is_router_external), utils.format_list(net.availability_zones), )) @@ -487,6 +545,7 @@ class TestSetNetwork(TestNetwork): '--provider-network-type', 'vlan', '--provider-physical-network', 'physnet1', '--provider-segment', '400', + '--no-transparent-vlan', ] verifylist = [ ('network', self._network.name), @@ -498,6 +557,7 @@ class TestSetNetwork(TestNetwork): ('provider_network_type', 'vlan'), ('physical_network', 'physnet1'), ('segmentation_id', '400'), + ('no_transparent_vlan', True), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -512,6 +572,7 @@ class TestSetNetwork(TestNetwork): 'provider:network_type': 'vlan', 'provider:physical_network': 'physnet1', 'provider:segmentation_id': '400', + 'vlan_transparent': False, } self.network.update_network.assert_called_once_with( self._network, **attrs) @@ -566,7 +627,7 @@ class TestShowNetwork(TestNetwork): 'name', 'project_id', 'provider_network_type', - 'router_external', + 'router:external', 'shared', 'status', 'subnets', @@ -581,7 +642,7 @@ class TestShowNetwork(TestNetwork): _network.name, _network.project_id, _network.provider_network_type, - network._format_router_external(_network.router_external), + network._format_router_external(_network.is_router_external), _network.shared, _network.status, utils.format_list(_network.subnets), @@ -599,7 +660,6 @@ class TestShowNetwork(TestNetwork): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -617,8 +677,8 @@ class TestShowNetwork(TestNetwork): self.network.find_network.assert_called_once_with( self._network.name, ignore_missing=False) - self.assertEqual(tuple(self.columns), columns) - self.assertEqual(list(self.data), list(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) # Tests for Nova network @@ -748,36 +808,97 @@ class TestCreateNetworkCompute(TestNetworkCompute): class TestDeleteNetworkCompute(TestNetworkCompute): - # The network to delete. - _network = compute_fakes.FakeNetwork.create_one_network() - def setUp(self): super(TestDeleteNetworkCompute, self).setUp() self.app.client_manager.network_endpoint_enabled = False + # The networks to delete + self._networks = compute_fakes.FakeNetwork.create_networks(count=3) + self.compute.networks.delete.return_value = None # Return value of utils.find_resource() - self.compute.networks.get.return_value = self._network + self.compute.networks.get = \ + compute_fakes.FakeNetwork.get_networks(networks=self._networks) # Get the command object to test self.cmd = network.DeleteNetwork(self.app, None) - def test_network_delete(self): + def test_delete_one_network(self): arglist = [ - self._network.label, + self._networks[0].label, ] verifylist = [ - ('network', [self._network.label]), + ('network', [self._networks[0].label]), ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + self.compute.networks.delete.assert_called_once_with( + self._networks[0].id) + self.assertIsNone(result) + + def test_delete_multiple_networks(self): + arglist = [] + for n in self._networks: + arglist.append(n.label) + verifylist = [ + ('network', arglist), + ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) + result = self.cmd.take_action(parsed_args) - self.compute.networks.delete.assert_called_once_with(self._network.id) + calls = [] + for n in self._networks: + calls.append(call(n.id)) + self.compute.networks.delete.assert_has_calls(calls) self.assertIsNone(result) + def test_delete_multiple_networks_exception(self): + arglist = [ + self._networks[0].id, + 'xxxx-yyyy-zzzz', + self._networks[1].id, + ] + verifylist = [ + ('network', arglist), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + # Fake exception in utils.find_resource() + # In compute 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. + self.compute.networks.get.side_effect = Exception() + ret_find = [ + self._networks[0], + Exception(), + self._networks[1], + ] + self.compute.networks.find.side_effect = ret_find + + # Fake exception in delete() + ret_delete = [ + None, + Exception(), + ] + self.compute.networks.delete = mock.Mock(side_effect=ret_delete) + + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + # The second call of utils.find_resource() should fail. So delete() + # was only called twice. + calls = [ + call(self._networks[0].id), + call(self._networks[1].id), + ] + self.compute.networks.delete.assert_has_calls(calls) + class TestListNetworkCompute(TestNetworkCompute): @@ -916,7 +1037,6 @@ class TestShowNetworkCompute(TestNetworkCompute): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -931,5 +1051,5 @@ class TestShowNetworkCompute(TestNetworkCompute): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.assertEqual(self.columns, tuple(columns)) + self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_network_segment.py b/openstackclient/tests/network/v2/test_network_segment.py new file mode 100644 index 00000000..0a99eced --- /dev/null +++ b/openstackclient/tests/network/v2/test_network_segment.py @@ -0,0 +1,199 @@ +# 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 openstackclient.common import exceptions +from openstackclient.network.v2 import network_segment +from openstackclient.tests.network.v2 import fakes as network_fakes +from openstackclient.tests import utils as tests_utils + + +class TestNetworkSegment(network_fakes.TestNetworkV2): + + def setUp(self): + super(TestNetworkSegment, self).setUp() + + # Enable beta commands. + self.app.options.os_beta_command = True + + # Get a shortcut to the network client + self.network = self.app.client_manager.network + + +class TestListNetworkSegment(TestNetworkSegment): + _network = network_fakes.FakeNetwork.create_one_network() + _network_segments = \ + network_fakes.FakeNetworkSegment.create_network_segments(count=3) + + columns = ( + 'ID', + 'Network', + 'Network Type', + 'Segment', + ) + columns_long = columns + ( + 'Physical Network', + ) + + data = [] + for _network_segment in _network_segments: + data.append(( + _network_segment.id, + _network_segment.network_id, + _network_segment.network_type, + _network_segment.segmentation_id, + )) + + data_long = [] + for _network_segment in _network_segments: + data_long.append(( + _network_segment.id, + _network_segment.network_id, + _network_segment.network_type, + _network_segment.segmentation_id, + _network_segment.physical_network, + )) + + def setUp(self): + super(TestListNetworkSegment, self).setUp() + + # Get the command object to test + self.cmd = network_segment.ListNetworkSegment(self.app, self.namespace) + + self.network.find_network = mock.Mock(return_value=self._network) + self.network.segments = mock.Mock(return_value=self._network_segments) + + def test_list_no_option(self): + arglist = [] + verifylist = [ + ('long', False), + ('network', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.segments.assert_called_once_with() + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + def test_list_no_beta_commands(self): + self.app.options.os_beta_command = False + parsed_args = self.check_parser(self.cmd, [], []) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_list_long(self): + arglist = [ + '--long', + ] + verifylist = [ + ('long', True), + ('network', None), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.segments.assert_called_once_with() + self.assertEqual(self.columns_long, columns) + self.assertEqual(self.data_long, list(data)) + + def test_list_network(self): + arglist = [ + '--network', + self._network.id, + ] + verifylist = [ + ('long', False), + ('network', self._network.id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.segments.assert_called_once_with( + **{'network_id': self._network.id} + ) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + + +class TestShowNetworkSegment(TestNetworkSegment): + + # The network segment to show. + _network_segment = \ + network_fakes.FakeNetworkSegment.create_one_network_segment() + + columns = ( + 'id', + 'network_id', + 'network_type', + 'physical_network', + 'segmentation_id', + ) + + data = ( + _network_segment.id, + _network_segment.network_id, + _network_segment.network_type, + _network_segment.physical_network, + _network_segment.segmentation_id, + ) + + def setUp(self): + super(TestShowNetworkSegment, self).setUp() + + self.network.find_segment = mock.Mock( + return_value=self._network_segment + ) + + # Get the command object to test + self.cmd = network_segment.ShowNetworkSegment(self.app, self.namespace) + + def test_show_no_options(self): + # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, [], []) + + def test_show_no_beta_commands(self): + arglist = [ + self._network_segment.id, + ] + verifylist = [ + ('network_segment', self._network_segment.id), + ] + self.app.options.os_beta_command = False + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_show_all_options(self): + arglist = [ + self._network_segment.id, + ] + verifylist = [ + ('network_segment', self._network_segment.id), + ] + + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + columns, data = self.cmd.take_action(parsed_args) + + self.network.find_segment.assert_called_once_with( + self._network_segment.id, + ignore_missing=False + ) + + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_port.py b/openstackclient/tests/network/v2/test_port.py index f2aa26cf..c3f175bf 100644 --- a/openstackclient/tests/network/v2/test_port.py +++ b/openstackclient/tests/network/v2/test_port.py @@ -283,6 +283,7 @@ class TestSetPort(TestPort): ] verifylist = [ ('fixed_ip', [{'ip-address': '10.0.0.11'}]), + ('port', self._port.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -304,6 +305,7 @@ class TestSetPort(TestPort): ] verifylist = [ ('fixed_ip', [{'ip-address': '10.0.0.12'}]), + ('port', _testport.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) @@ -325,6 +327,7 @@ class TestSetPort(TestPort): ('disable', True), ('no_binding_profile', True), ('no_fixed_ip', True), + ('port', self._port.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -352,7 +355,8 @@ class TestSetPort(TestPort): ('vnic_type', 'macvtap'), ('binding_profile', {'foo': 'bar'}), ('host', 'binding-host-id-xxxx'), - ('name', 'newName') + ('name', 'newName'), + ('port', self._port.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/network/v2/test_router.py b/openstackclient/tests/network/v2/test_router.py index e8041498..99b41d2d 100644 --- a/openstackclient/tests/network/v2/test_router.py +++ b/openstackclient/tests/network/v2/test_router.py @@ -47,7 +47,6 @@ class TestAddPortToRouter(TestRouter): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -88,7 +87,6 @@ class TestAddSubnetToRouter(TestRouter): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -138,7 +136,7 @@ class TestCreateRouter(TestRouter): new_router.id, new_router.name, new_router.tenant_id, - new_router.routes, + router._format_routes(new_router.routes), new_router.status, ) @@ -154,7 +152,6 @@ class TestCreateRouter(TestRouter): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -268,7 +265,7 @@ class TestListRouter(TestRouter): r = routers[i] data_long.append( data[i] + ( - r.routes, + router._format_routes(r.routes), router._format_external_gateway_info(r.external_gateway_info), osc_utils.format_list(r.availability_zones), ) @@ -335,7 +332,6 @@ class TestRemovePortFromRouter(TestRouter): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -375,7 +371,6 @@ class TestRemoveSubnetFromRouter(TestRouter): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -399,7 +394,10 @@ class TestRemoveSubnetFromRouter(TestRouter): class TestSetRouter(TestRouter): # The router to set. - _router = network_fakes.FakeRouter.create_one_router() + _default_route = {'destination': '10.20.20.0/24', 'nexthop': '10.20.30.1'} + _router = network_fakes.FakeRouter.create_one_router( + attrs={'routes': [_default_route]} + ) def setUp(self): super(TestSetRouter, self).setUp() @@ -472,7 +470,6 @@ class TestSetRouter(TestRouter): ('distributed', False), ] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -491,13 +488,49 @@ class TestSetRouter(TestRouter): result = self.cmd.take_action(parsed_args) attrs = { - 'routes': [{'destination': '10.20.30.0/24', - 'gateway': '10.20.30.1'}], + 'routes': self._router.routes + [{'destination': '10.20.30.0/24', + 'nexthop': '10.20.30.1'}], + } + self.network.update_router.assert_called_once_with( + self._router, **attrs) + self.assertIsNone(result) + + def test_set_no_route(self): + arglist = [ + self._router.name, + '--no-route', + ] + verifylist = [ + ('router', self._router.name), + ('no_route', True), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + attrs = { + 'routes': [], } self.network.update_router.assert_called_once_with( self._router, **attrs) self.assertIsNone(result) + def test_set_route_no_route(self): + arglist = [ + self._router.name, + '--route', 'destination=10.20.30.0/24,gateway=10.20.30.1', + '--no-route', + ] + verifylist = [ + ('router', self._router.name), + ('routes', [{'destination': '10.20.30.0/24', + 'gateway': '10.20.30.1'}]), + ('no_route', True), + ] + + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + def test_set_clear_routes(self): arglist = [ self._router.name, @@ -531,7 +564,6 @@ class TestSetRouter(TestRouter): ('clear_routes', True), ] - # Argument parse failing should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -572,7 +604,7 @@ class TestShowRouter(TestRouter): _router.id, _router.name, _router.tenant_id, - _router.routes, + router._format_routes(_router.routes), _router.status, ) @@ -588,7 +620,6 @@ class TestShowRouter(TestRouter): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -605,5 +636,5 @@ class TestShowRouter(TestRouter): self.network.find_router.assert_called_once_with( self._router.name, ignore_missing=False) - self.assertEqual(tuple(self.columns), columns) + self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_security_group.py b/openstackclient/tests/network/v2/test_security_group.py index dd6a3d41..213367a4 100644 --- a/openstackclient/tests/network/v2/test_security_group.py +++ b/openstackclient/tests/network/v2/test_security_group.py @@ -114,7 +114,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork): 'description': self._security_group.name, 'name': self._security_group.name, }) - self.assertEqual(tuple(self.columns), columns) + self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) def test_create_all_options(self): @@ -139,7 +139,7 @@ class TestCreateSecurityGroupNetwork(TestSecurityGroupNetwork): 'name': self._security_group.name, 'tenant_id': identity_fakes.project_id, }) - self.assertEqual(tuple(self.columns), columns) + self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) @@ -296,28 +296,30 @@ class TestDeleteSecurityGroupCompute(TestSecurityGroupCompute): class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): # The security group to be listed. - _security_group = \ - network_fakes.FakeSecurityGroup.create_one_security_group() + _security_groups = \ + network_fakes.FakeSecurityGroup.create_security_groups(count=3) - expected_columns = ( + columns = ( 'ID', 'Name', 'Description', 'Project', ) - expected_data = (( - _security_group.id, - _security_group.name, - _security_group.description, - _security_group.tenant_id, - ),) + data = [] + for grp in _security_groups: + data.append(( + grp.id, + grp.name, + grp.description, + grp.tenant_id, + )) def setUp(self): super(TestListSecurityGroupNetwork, self).setUp() self.network.security_groups = mock.Mock( - return_value=[self._security_group]) + return_value=self._security_groups) # Get the command object to test self.cmd = security_group.ListSecurityGroup(self.app, self.namespace) @@ -332,8 +334,8 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): columns, data = self.cmd.take_action(parsed_args) self.network.security_groups.assert_called_once_with() - self.assertEqual(self.expected_columns, columns) - self.assertEqual(self.expected_data, tuple(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) def test_security_group_list_all_projects(self): arglist = [ @@ -347,45 +349,49 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork): columns, data = self.cmd.take_action(parsed_args) self.network.security_groups.assert_called_once_with() - self.assertEqual(self.expected_columns, columns) - self.assertEqual(self.expected_data, tuple(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) class TestListSecurityGroupCompute(TestSecurityGroupCompute): # The security group to be listed. - _security_group = \ - compute_fakes.FakeSecurityGroup.create_one_security_group() + _security_groups = \ + compute_fakes.FakeSecurityGroup.create_security_groups(count=3) - expected_columns = ( + columns = ( 'ID', 'Name', 'Description', ) - expected_columns_all_projects = ( + columns_all_projects = ( 'ID', 'Name', 'Description', 'Project', ) - expected_data = (( - _security_group.id, - _security_group.name, - _security_group.description, - ),) - expected_data_all_projects = (( - _security_group.id, - _security_group.name, - _security_group.description, - _security_group.tenant_id, - ),) + data = [] + for grp in _security_groups: + data.append(( + grp.id, + grp.name, + grp.description, + )) + data_all_projects = [] + for grp in _security_groups: + data_all_projects.append(( + grp.id, + grp.name, + grp.description, + grp.tenant_id, + )) def setUp(self): super(TestListSecurityGroupCompute, self).setUp() self.app.client_manager.network_endpoint_enabled = False - self.compute.security_groups.list.return_value = [self._security_group] + self.compute.security_groups.list.return_value = self._security_groups # Get the command object to test self.cmd = security_group.ListSecurityGroup(self.app, None) @@ -401,8 +407,8 @@ class TestListSecurityGroupCompute(TestSecurityGroupCompute): kwargs = {'search_opts': {'all_tenants': False}} self.compute.security_groups.list.assert_called_once_with(**kwargs) - self.assertEqual(self.expected_columns, columns) - self.assertEqual(self.expected_data, tuple(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) def test_security_group_list_all_projects(self): arglist = [ @@ -417,8 +423,8 @@ class TestListSecurityGroupCompute(TestSecurityGroupCompute): kwargs = {'search_opts': {'all_tenants': True}} self.compute.security_groups.list.assert_called_once_with(**kwargs) - self.assertEqual(self.expected_columns_all_projects, columns) - self.assertEqual(self.expected_data_all_projects, tuple(data)) + self.assertEqual(self.columns_all_projects, columns) + self.assertEqual(self.data_all_projects, list(data)) class TestSetSecurityGroupNetwork(TestSecurityGroupNetwork): diff --git a/openstackclient/tests/network/v2/test_security_group_rule.py b/openstackclient/tests/network/v2/test_security_group_rule.py index df7414aa..2a64b884 100644 --- a/openstackclient/tests/network/v2/test_security_group_rule.py +++ b/openstackclient/tests/network/v2/test_security_group_rule.py @@ -14,6 +14,7 @@ import copy import mock +from openstackclient.common import exceptions from openstackclient.network import utils as network_utils from openstackclient.network.v2 import security_group_rule from openstackclient.tests.compute.v2 import fakes as compute_fakes @@ -131,22 +132,40 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, []) - def test_create_bad_protocol(self): + def test_create_bad_ethertype(self): arglist = [ - '--protocol', 'foo', + '--ethertype', 'foo', self._security_group.id, ] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, []) - def test_create_bad_ethertype(self): + def test_create_all_protocol_options(self): arglist = [ - '--ethertype', 'foo', + '--protocol', 'tcp', + '--proto', 'tcp', self._security_group.id, ] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, []) + def test_create_all_port_range_options(self): + arglist = [ + '--dst-port', '80:80', + '--icmp-type', '3', + '--icmp-code', '1', + self._security_group.id, + ] + verifylist = [ + ('dst_port', (80, 80)), + ('icmp_type', 3), + ('icmp_code', 1), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + def test_create_default_rule(self): self._setup_security_group_rule({ 'port_range_max': 443, @@ -174,7 +193,37 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix, 'security_group_id': self._security_group.id, }) - self.assertEqual(tuple(self.expected_columns), columns) + self.assertEqual(self.expected_columns, columns) + self.assertEqual(self.expected_data, data) + + def test_create_proto_option(self): + self._setup_security_group_rule({ + 'protocol': 'icmp', + 'remote_ip_prefix': '10.0.2.0/24', + }) + arglist = [ + '--proto', self._security_group_rule.protocol, + '--src-ip', self._security_group_rule.remote_ip_prefix, + self._security_group.id, + ] + verifylist = [ + ('proto', self._security_group_rule.protocol), + ('protocol', None), + ('src_ip', self._security_group_rule.remote_ip_prefix), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.create_security_group_rule.assert_called_once_with(**{ + 'direction': self._security_group_rule.direction, + 'ethertype': self._security_group_rule.ethertype, + 'protocol': self._security_group_rule.protocol, + 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix, + 'security_group_id': self._security_group.id, + }) + self.assertEqual(self.expected_columns, columns) self.assertEqual(self.expected_data, data) def test_create_source_group(self): @@ -209,23 +258,21 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): 'remote_group_id': self._security_group_rule.remote_group_id, 'security_group_id': self._security_group.id, }) - self.assertEqual(tuple(self.expected_columns), columns) + self.assertEqual(self.expected_columns, columns) self.assertEqual(self.expected_data, data) def test_create_source_ip(self): self._setup_security_group_rule({ 'protocol': 'icmp', - 'port_range_max': -1, - 'port_range_min': -1, 'remote_ip_prefix': '10.0.2.0/24', }) arglist = [ - '--proto', self._security_group_rule.protocol, + '--protocol', self._security_group_rule.protocol, '--src-ip', self._security_group_rule.remote_ip_prefix, self._security_group.id, ] verifylist = [ - ('proto', self._security_group_rule.protocol), + ('protocol', self._security_group_rule.protocol), ('src_ip', self._security_group_rule.remote_ip_prefix), ('group', self._security_group.id), ] @@ -240,7 +287,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix, 'security_group_id': self._security_group.id, }) - self.assertEqual(tuple(self.expected_columns), columns) + self.assertEqual(self.expected_columns, columns) self.assertEqual(self.expected_data, data) def test_create_network_options(self): @@ -249,6 +296,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): 'ethertype': 'IPv6', 'port_range_max': 443, 'port_range_min': 443, + 'protocol': '6', 'remote_group_id': None, 'remote_ip_prefix': None, }) @@ -258,6 +306,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): '--ethertype', self._security_group_rule.ethertype, '--project', identity_fakes.project_name, '--project-domain', identity_fakes.domain_name, + '--protocol', self._security_group_rule.protocol, self._security_group.id, ] verifylist = [ @@ -267,6 +316,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): ('ethertype', self._security_group_rule.ethertype), ('project', identity_fakes.project_name), ('project_domain', identity_fakes.domain_name), + ('protocol', self._security_group_rule.protocol), ('group', self._security_group.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -282,7 +332,137 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): 'security_group_id': self._security_group.id, 'tenant_id': identity_fakes.project_id, }) - self.assertEqual(tuple(self.expected_columns), columns) + self.assertEqual(self.expected_columns, columns) + self.assertEqual(self.expected_data, data) + + def test_create_tcp_with_icmp_type(self): + arglist = [ + '--protocol', 'tcp', + '--icmp-type', '15', + self._security_group.id, + ] + verifylist = [ + ('protocol', 'tcp'), + ('icmp_type', 15), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_create_icmp_code(self): + arglist = [ + '--protocol', '1', + '--icmp-code', '1', + self._security_group.id, + ] + verifylist = [ + ('protocol', '1'), + ('icmp_code', 1), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + self.assertRaises(exceptions.CommandError, self.cmd.take_action, + parsed_args) + + def test_create_icmp_type(self): + self._setup_security_group_rule({ + 'port_range_min': 15, + 'protocol': 'icmp', + 'remote_ip_prefix': '0.0.0.0/0', + }) + arglist = [ + '--icmp-type', str(self._security_group_rule.port_range_min), + '--protocol', self._security_group_rule.protocol, + self._security_group.id, + ] + verifylist = [ + ('dst_port', None), + ('icmp_type', self._security_group_rule.port_range_min), + ('icmp_code', None), + ('protocol', self._security_group_rule.protocol), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.create_security_group_rule.assert_called_once_with(**{ + 'direction': self._security_group_rule.direction, + 'ethertype': self._security_group_rule.ethertype, + 'port_range_min': self._security_group_rule.port_range_min, + 'protocol': self._security_group_rule.protocol, + 'remote_ip_prefix': self._security_group_rule.remote_ip_prefix, + 'security_group_id': self._security_group.id, + }) + self.assertEqual(self.expected_columns, columns) + self.assertEqual(self.expected_data, data) + + def test_create_ipv6_icmp_type_code(self): + self._setup_security_group_rule({ + 'ethertype': 'IPv6', + 'port_range_min': 139, + 'port_range_max': 2, + 'protocol': 'ipv6-icmp', + }) + arglist = [ + '--icmp-type', str(self._security_group_rule.port_range_min), + '--icmp-code', str(self._security_group_rule.port_range_max), + '--protocol', self._security_group_rule.protocol, + self._security_group.id, + ] + verifylist = [ + ('dst_port', None), + ('icmp_type', self._security_group_rule.port_range_min), + ('icmp_code', self._security_group_rule.port_range_max), + ('protocol', self._security_group_rule.protocol), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.create_security_group_rule.assert_called_once_with(**{ + 'direction': self._security_group_rule.direction, + 'ethertype': self._security_group_rule.ethertype, + 'port_range_min': self._security_group_rule.port_range_min, + 'port_range_max': self._security_group_rule.port_range_max, + 'protocol': self._security_group_rule.protocol, + 'security_group_id': self._security_group.id, + }) + self.assertEqual(self.expected_columns, columns) + self.assertEqual(self.expected_data, data) + + def test_create_icmpv6_type(self): + self._setup_security_group_rule({ + 'ethertype': 'IPv6', + 'port_range_min': 139, + 'protocol': 'icmpv6', + }) + arglist = [ + '--icmp-type', str(self._security_group_rule.port_range_min), + '--protocol', self._security_group_rule.protocol, + self._security_group.id, + ] + verifylist = [ + ('dst_port', None), + ('icmp_type', self._security_group_rule.port_range_min), + ('icmp_code', None), + ('protocol', self._security_group_rule.protocol), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.network.create_security_group_rule.assert_called_once_with(**{ + 'direction': self._security_group_rule.direction, + 'ethertype': self._security_group_rule.ethertype, + 'port_range_min': self._security_group_rule.port_range_min, + 'protocol': self._security_group_rule.protocol, + 'security_group_id': self._security_group.id, + }) + self.assertEqual(self.expected_columns, columns) self.assertEqual(self.expected_data, data) @@ -337,10 +517,21 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, []) + def test_create_all_protocol_options(self): + arglist = [ + '--protocol', 'tcp', + '--proto', 'tcp', + self._security_group.id, + ] + self.assertRaises(tests_utils.ParserException, + self.check_parser, self.cmd, arglist, []) + def test_create_network_options(self): arglist = [ '--ingress', '--ethertype', 'IPv4', + '--icmp-type', '3', + '--icmp-code', '11', '--project', identity_fakes.project_name, '--project-domain', identity_fakes.domain_name, self._security_group.id, @@ -416,12 +607,45 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute): 'ip_range': {'cidr': '10.0.2.0/24'}, }) arglist = [ + '--protocol', self._security_group_rule.ip_protocol, + '--src-ip', self._security_group_rule.ip_range['cidr'], + self._security_group.id, + ] + verifylist = [ + ('protocol', self._security_group_rule.ip_protocol), + ('src_ip', self._security_group_rule.ip_range['cidr']), + ('group', self._security_group.id), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + + self.compute.security_group_rules.create.assert_called_once_with( + self._security_group.id, + self._security_group_rule.ip_protocol, + self._security_group_rule.from_port, + self._security_group_rule.to_port, + self._security_group_rule.ip_range['cidr'], + None, + ) + self.assertEqual(expected_columns, columns) + self.assertEqual(expected_data, data) + + def test_create_proto_option(self): + expected_columns, expected_data = self._setup_security_group_rule({ + 'ip_protocol': 'icmp', + 'from_port': -1, + 'to_port': -1, + 'ip_range': {'cidr': '10.0.2.0/24'}, + }) + arglist = [ '--proto', self._security_group_rule.ip_protocol, '--src-ip', self._security_group_rule.ip_range['cidr'], self._security_group.id, ] verifylist = [ ('proto', self._security_group_rule.ip_protocol), + ('protocol', None), ('src_ip', self._security_group_rule.ip_range['cidr']), ('group', self._security_group.id), ] @@ -522,8 +746,6 @@ class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): _security_group_rule_icmp = \ network_fakes.FakeSecurityGroupRule.create_one_security_group_rule({ 'protocol': 'icmp', - 'port_range_max': -1, - 'port_range_min': -1, 'remote_ip_prefix': '10.0.2.0/24', 'security_group_id': _security_group.id, }) @@ -816,7 +1038,7 @@ class TestShowSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork): self.network.find_security_group_rule.assert_called_once_with( self._security_group_rule.id, ignore_missing=False) - self.assertEqual(tuple(self.columns), columns) + self.assertEqual(self.columns, columns) self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_subnet.py b/openstackclient/tests/network/v2/test_subnet.py index ede37416..22c288f9 100644 --- a/openstackclient/tests/network/v2/test_subnet.py +++ b/openstackclient/tests/network/v2/test_subnet.py @@ -469,6 +469,22 @@ class TestListSubnet(TestSubnet): self.assertEqual(self.columns_long, columns) self.assertEqual(self.data_long, list(data)) + def test_subnet_list_ip_version(self): + arglist = [ + '--ip-version', str(4), + ] + verifylist = [ + ('ip_version', 4), + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + columns, data = self.cmd.take_action(parsed_args) + filters = {'ip_version': 4} + + self.network.subnets.assert_called_once_with(**filters) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) + class TestSetSubnet(TestSubnet): @@ -627,4 +643,4 @@ class TestShowSubnet(TestSubnet): self._subnet.name, ignore_missing=False) self.assertEqual(self.columns, columns) - self.assertEqual(list(self.data), list(data)) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/network/v2/test_subnet_pool.py b/openstackclient/tests/network/v2/test_subnet_pool.py index 369a8b11..de12c9e9 100644 --- a/openstackclient/tests/network/v2/test_subnet_pool.py +++ b/openstackclient/tests/network/v2/test_subnet_pool.py @@ -109,7 +109,17 @@ class TestCreateSubnetPool(TestSubnetPool): arglist = [] verifylist = [] - # Missing required args should bail here + self.assertRaises(tests_utils.ParserException, self.check_parser, + self.cmd, arglist, verifylist) + + def test_create_no_pool_prefix(self): + """Make sure --pool-prefix is a required argument""" + arglist = [ + self._subnet_pool.name, + ] + verifylist = [ + ('name', self._subnet_pool.name), + ] self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) @@ -138,23 +148,26 @@ class TestCreateSubnetPool(TestSubnetPool): '--default-prefix-length', self._subnet_pool.default_prefixlen, '--max-prefix-length', self._subnet_pool.max_prefixlen, '--min-prefix-length', self._subnet_pool.min_prefixlen, + '--pool-prefix', '10.0.10.0/24', self._subnet_pool.name, ] verifylist = [ - ('default_prefix_length', self._subnet_pool.default_prefixlen), - ('max_prefix_length', self._subnet_pool.max_prefixlen), - ('min_prefix_length', self._subnet_pool.min_prefixlen), + ('default_prefix_length', + int(self._subnet_pool.default_prefixlen)), + ('max_prefix_length', int(self._subnet_pool.max_prefixlen)), + ('min_prefix_length', int(self._subnet_pool.min_prefixlen)), ('name', self._subnet_pool.name), + ('prefixes', ['10.0.10.0/24']), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = (self.cmd.take_action(parsed_args)) self.network.create_subnet_pool.assert_called_once_with(**{ - 'default_prefixlen': self._subnet_pool.default_prefixlen, - 'max_prefixlen': self._subnet_pool.max_prefixlen, - 'min_prefixlen': self._subnet_pool.min_prefixlen, - 'prefixes': [], + 'default_prefixlen': int(self._subnet_pool.default_prefixlen), + 'max_prefixlen': int(self._subnet_pool.max_prefixlen), + 'min_prefixlen': int(self._subnet_pool.min_prefixlen), + 'prefixes': ['10.0.10.0/24'], 'name': self._subnet_pool.name, }) self.assertEqual(self.columns, columns) @@ -384,8 +397,8 @@ class TestSetSubnetPool(TestSubnetPool): ] verifylist = [ ('name', 'noob'), - ('default_prefix_length', '8'), - ('min_prefix_length', '8'), + ('default_prefix_length', 8), + ('min_prefix_length', 8), ('subnet_pool', self._subnet_pool.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -394,8 +407,8 @@ class TestSetSubnetPool(TestSubnetPool): attrs = { 'name': 'noob', - 'default_prefixlen': '8', - 'min_prefixlen': '8', + 'default_prefixlen': 8, + 'min_prefixlen': 8, } self.network.update_subnet_pool.assert_called_once_with( self._subnet_pool, **attrs) @@ -410,7 +423,7 @@ class TestSetSubnetPool(TestSubnetPool): ] verifylist = [ ('prefixes', ['10.0.1.0/24', '10.0.2.0/24']), - ('max_prefix_length', '16'), + ('max_prefix_length', 16), ('subnet_pool', self._subnet_pool.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -421,7 +434,7 @@ class TestSetSubnetPool(TestSubnetPool): prefixes.extend(self._subnet_pool.prefixes) attrs = { 'prefixes': prefixes, - 'max_prefixlen': '16', + 'max_prefixlen': 16, } self.network.update_subnet_pool.assert_called_once_with( self._subnet_pool, **attrs) @@ -610,7 +623,6 @@ class TestShowSubnetPool(TestSubnetPool): arglist = [] verifylist = [] - # Missing required args should bail here self.assertRaises(tests_utils.ParserException, self.check_parser, self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/utils.py b/openstackclient/tests/utils.py index 319c1c11..8dead718 100644 --- a/openstackclient/tests/utils.py +++ b/openstackclient/tests/utils.py @@ -60,6 +60,7 @@ class TestCommand(TestCase): self.fake_log = fakes.FakeLog() self.app = fakes.FakeApp(self.fake_stdout, self.fake_log) self.app.client_manager = fakes.FakeClientManager() + self.app.options = fakes.FakeOptions() def check_parser(self, cmd, args, verify_args): cmd_parser = cmd.get_parser('check_parser') diff --git a/openstackclient/tests/volume/v2/fakes.py b/openstackclient/tests/volume/v2/fakes.py index bd15076f..e61fe8aa 100644 --- a/openstackclient/tests/volume/v2/fakes.py +++ b/openstackclient/tests/volume/v2/fakes.py @@ -442,6 +442,8 @@ class FakeVolume(object): 'size': random.randint(1, 20), 'volume_type': random.choice(['fake_lvmdriver-1', 'fake_lvmdriver-2']), + 'bootable': + random.randint(0, 1), 'metadata': { 'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex, 'key' + uuid.uuid4().hex: 'val' + uuid.uuid4().hex, @@ -500,6 +502,44 @@ class FakeVolume(object): return mock.MagicMock(side_effect=volumes) + @staticmethod + def get_volume_columns(volume=None): + """Get the volume columns from a faked volume object. + + :param volume: + A FakeResource objects faking volume + :return + A tuple which may include the following keys: + ('id', 'name', 'description', 'status', 'size', 'volume_type', + 'metadata', 'snapshot', 'availability_zone', 'attachments') + """ + if volume is not None: + return tuple(k for k in sorted(volume.keys())) + return tuple([]) + + @staticmethod + def get_volume_data(volume=None): + """Get the volume data from a faked volume object. + + :param volume: + A FakeResource objects faking volume + :return + A tuple which may include the following values: + ('ce26708d', 'fake_volume', 'fake description', 'available', + 20, 'fake_lvmdriver-1', "Alpha='a', Beta='b', Gamma='g'", + 1, 'nova', [{'device': '/dev/ice', 'server_id': '1233'}]) + """ + data_list = [] + if volume is not None: + for x in sorted(volume.keys()): + if x == 'tags': + # The 'tags' should be format_list + data_list.append( + common_utils.format_list(volume.info.get(x))) + else: + data_list.append(volume.info.get(x)) + return tuple(data_list) + class FakeAvailabilityZone(object): """Fake one or more volume availability zones (AZs).""" @@ -547,3 +587,238 @@ class FakeAvailabilityZone(object): availability_zones.append(availability_zone) return availability_zones + + +class FakeBackup(object): + """Fake one or more backup.""" + + @staticmethod + def create_one_backup(attrs=None): + """Create a fake backup. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object with id, name, volume_id, etc. + """ + attrs = attrs or {} + + # Set default attributes. + backup_info = { + "id": 'backup-id-' + uuid.uuid4().hex, + "name": 'backup-name-' + uuid.uuid4().hex, + "volume_id": 'volume-id-' + uuid.uuid4().hex, + "description": 'description-' + uuid.uuid4().hex, + "object_count": None, + "container": 'container-' + uuid.uuid4().hex, + "size": random.randint(1, 20), + "status": "error", + "availability_zone": 'zone' + uuid.uuid4().hex, + } + + # Overwrite default attributes. + backup_info.update(attrs) + + backup = fakes.FakeResource( + info=copy.deepcopy(backup_info), + loaded=True) + return backup + + @staticmethod + def create_backups(attrs=None, count=2): + """Create multiple fake backups. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of backups to fake + :return: + A list of FakeResource objects faking the backups + """ + backups = [] + for i in range(0, count): + backup = FakeBackup.create_one_backup(attrs) + backups.append(backup) + + return backups + + +class FakeQos(object): + """Fake one or more Qos specification.""" + + @staticmethod + def create_one_qos(attrs=None): + """Create a fake Qos specification. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object with id, name, consumer, etc. + """ + attrs = attrs or {} + + # Set default attributes. + qos_info = { + "id": 'qos-id-' + uuid.uuid4().hex, + "name": 'qos-name-' + uuid.uuid4().hex, + "consumer": 'front-end', + "specs": {"foo": "bar", "iops": "9001"}, + } + + # Overwrite default attributes. + qos_info.update(attrs) + + qos = fakes.FakeResource( + info=copy.deepcopy(qos_info), + loaded=True) + return qos + + @staticmethod + def create_one_qos_association(attrs=None): + """Create a fake Qos specification association. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object with id, name, association_type, etc. + """ + attrs = attrs or {} + + # Set default attributes. + qos_association_info = { + "id": 'type-id-' + uuid.uuid4().hex, + "name": 'type-name-' + uuid.uuid4().hex, + "association_type": 'volume_type', + } + + # Overwrite default attributes. + qos_association_info.update(attrs) + + qos_association = fakes.FakeResource( + info=copy.deepcopy(qos_association_info), + loaded=True) + return qos_association + + @staticmethod + def create_qoses(attrs=None, count=2): + """Create multiple fake Qos specifications. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of Qos specifications to fake + :return: + A list of FakeResource objects faking the Qos specifications + """ + qoses = [] + for i in range(0, count): + qos = FakeQos.create_one_qos(attrs) + qoses.append(qos) + + return qoses + + +class FakeSnapshot(object): + """Fake one or more snapshot.""" + + @staticmethod + def create_one_snapshot(attrs=None): + """Create a fake snapshot. + + :param Dictionary attrs: + A dictionary with all attributes + :return: + A FakeResource object with id, name, description, etc. + """ + attrs = attrs or {} + + # Set default attributes. + snapshot_info = { + "id": 'snapshot-id-' + uuid.uuid4().hex, + "name": 'snapshot-name-' + uuid.uuid4().hex, + "description": 'snapshot-description-' + uuid.uuid4().hex, + "size": 10, + "status": "available", + "metadata": {"foo": "bar"}, + "created_at": "2015-06-03T18:49:19.000000", + "volume_id": 'vloume-id-' + uuid.uuid4().hex, + } + + # Overwrite default attributes. + snapshot_info.update(attrs) + + snapshot = fakes.FakeResource( + info=copy.deepcopy(snapshot_info), + loaded=True) + return snapshot + + @staticmethod + def create_snapshots(attrs=None, count=2): + """Create multiple fake snapshots. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of snapshots to fake + :return: + A list of FakeResource objects faking the snapshots + """ + snapshots = [] + for i in range(0, count): + snapshot = FakeSnapshot.create_one_snapshot(attrs) + snapshots.append(snapshot) + + return snapshots + + +class FakeType(object): + """Fake one or more type.""" + + @staticmethod + def create_one_type(attrs=None, methods=None): + """Create a fake type. + + :param Dictionary attrs: + A dictionary with all attributes + :param Dictionary methods: + A dictionary with all methods + :return: + A FakeResource object with id, name, description, etc. + """ + attrs = attrs or {} + methods = methods or {} + + # Set default attributes. + type_info = { + "id": 'type-id-' + uuid.uuid4().hex, + "name": 'type-name-' + uuid.uuid4().hex, + "description": 'type-description-' + uuid.uuid4().hex, + "extra_specs": {"foo": "bar"}, + } + + # Overwrite default attributes. + type_info.update(attrs) + + volume_type = fakes.FakeResource( + info=copy.deepcopy(type_info), + methods=methods, + loaded=True) + return volume_type + + @staticmethod + def create_types(attrs=None, count=2): + """Create multiple fake types. + + :param Dictionary attrs: + A dictionary with all attributes + :param int count: + The number of types to fake + :return: + A list of FakeResource objects faking the types + """ + volume_types = [] + for i in range(0, count): + volume_type = FakeType.create_one_type(attrs) + volume_types.append(volume_type) + + return volume_types diff --git a/openstackclient/tests/volume/v2/test_backup.py b/openstackclient/tests/volume/v2/test_backup.py index 0e906e7b..8a151a91 100644 --- a/openstackclient/tests/volume/v2/test_backup.py +++ b/openstackclient/tests/volume/v2/test_backup.py @@ -12,9 +12,6 @@ # under the License. # -import copy - -from openstackclient.tests import fakes from openstackclient.tests.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import backup @@ -34,83 +31,101 @@ class TestBackup(volume_fakes.TestVolume): class TestBackupCreate(TestBackup): + volume = volume_fakes.FakeVolume.create_one_volume() + new_backup = volume_fakes.FakeBackup.create_one_backup( + attrs={'volume_id': volume.id}) + + columns = ( + 'availability_zone', + 'container', + 'description', + 'id', + 'name', + 'object_count', + 'size', + 'status', + 'volume_id', + ) + data = ( + new_backup.availability_zone, + new_backup.container, + new_backup.description, + new_backup.id, + new_backup.name, + new_backup.object_count, + new_backup.size, + new_backup.status, + new_backup.volume_id, + ) + def setUp(self): super(TestBackupCreate, self).setUp() - self.volumes_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True - ) + self.volumes_mock.get.return_value = self.volume + self.backups_mock.create.return_value = self.new_backup - self.backups_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.BACKUP), - loaded=True - ) # Get the command object to test self.cmd = backup.CreateBackup(self.app, None) def test_backup_create(self): arglist = [ - volume_fakes.volume_id, - "--name", volume_fakes.backup_name, - "--description", volume_fakes.backup_description, - "--container", volume_fakes.backup_name + "--name", self.new_backup.name, + "--description", self.new_backup.description, + "--container", self.new_backup.container, + self.new_backup.volume_id, ] verifylist = [ - ("volume", volume_fakes.volume_id), - ("name", volume_fakes.backup_name), - ("description", volume_fakes.backup_description), - ("container", volume_fakes.backup_name) + ("name", self.new_backup.name), + ("description", self.new_backup.description), + ("container", self.new_backup.container), + ("volume", self.new_backup.volume_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.backups_mock.create.assert_called_with( - volume_fakes.volume_id, - container=volume_fakes.backup_name, - name=volume_fakes.backup_name, - description=volume_fakes.backup_description + self.new_backup.volume_id, + container=self.new_backup.container, + name=self.new_backup.name, + description=self.new_backup.description ) - self.assertEqual(columns, volume_fakes.BACKUP_columns) - self.assertEqual(data, volume_fakes.BACKUP_data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_backup_create_without_name(self): arglist = [ - volume_fakes.volume_id, - "--description", volume_fakes.backup_description, - "--container", volume_fakes.backup_name + "--description", self.new_backup.description, + "--container", self.new_backup.container, + self.new_backup.volume_id, ] verifylist = [ - ("volume", volume_fakes.volume_id), - ("description", volume_fakes.backup_description), - ("container", volume_fakes.backup_name) + ("description", self.new_backup.description), + ("container", self.new_backup.container), + ("volume", self.new_backup.volume_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.backups_mock.create.assert_called_with( - volume_fakes.volume_id, - container=volume_fakes.backup_name, + self.new_backup.volume_id, + container=self.new_backup.container, name=None, - description=volume_fakes.backup_description + description=self.new_backup.description ) - self.assertEqual(columns, volume_fakes.BACKUP_columns) - self.assertEqual(data, volume_fakes.BACKUP_data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestBackupDelete(TestBackup): + backup = volume_fakes.FakeBackup.create_one_backup() + def setUp(self): super(TestBackupDelete, self).setUp() - self.backups_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.BACKUP), - loaded=True) + self.backups_mock.get.return_value = self.backup self.backups_mock.delete.return_value = None # Get the command object to mock @@ -118,21 +133,25 @@ class TestBackupDelete(TestBackup): def test_backup_delete(self): arglist = [ - volume_fakes.backup_id + self.backup.id ] verifylist = [ - ("backups", [volume_fakes.backup_id]) + ("backups", [self.backup.id]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.backups_mock.delete.assert_called_with(volume_fakes.backup_id) + self.backups_mock.delete.assert_called_with(self.backup.id) self.assertIsNone(result) class TestBackupList(TestBackup): + volume = volume_fakes.FakeVolume.create_one_volume() + backups = volume_fakes.FakeBackup.create_backups( + attrs={'volume_id': volume.name}, count=3) + columns = [ 'ID', 'Name', @@ -140,33 +159,39 @@ class TestBackupList(TestBackup): 'Status', 'Size', ] - datalist = ( - ( - volume_fakes.backup_id, - volume_fakes.backup_name, - volume_fakes.backup_description, - volume_fakes.backup_status, - volume_fakes.backup_size - ), - ) + columns_long = columns + [ + 'Availability Zone', + 'Volume', + 'Container', + ] + + data = [] + for b in backups: + data.append(( + b.id, + b.name, + b.description, + b.status, + b.size, + )) + data_long = [] + for b in backups: + data_long.append(( + b.id, + b.name, + b.description, + b.status, + b.size, + b.availability_zone, + b.volume_id, + b.container, + )) def setUp(self): super(TestBackupList, self).setUp() - self.volumes_mock.list.return_value = [ - fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True - ) - ] - self.backups_mock.list.return_value = [ - fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.BACKUP), - loaded=True - ) - ] + self.volumes_mock.list.return_value = [self.volume] + self.backups_mock.list.return_value = self.backups # Get the command to test self.cmd = backup.ListBackup(self.app, None) @@ -178,7 +203,7 @@ class TestBackupList(TestBackup): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - self.assertEqual(self.datalist, tuple(data)) + self.assertEqual(self.data, list(data)) def test_backup_list_with_options(self): arglist = ["--long"] @@ -187,86 +212,87 @@ class TestBackupList(TestBackup): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - columns = self.columns + [ - 'Availability Zone', - 'Volume', - 'Container', - ] - - self.assertEqual(columns, columns) - - datalist = (( - volume_fakes.backup_id, - volume_fakes.backup_name, - volume_fakes.backup_description, - volume_fakes.backup_status, - volume_fakes.backup_size, - volume_fakes.volume_availability_zone, - volume_fakes.backup_volume_id, - volume_fakes.backup_container - ),) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.columns_long, columns) + self.assertEqual(self.data_long, list(data)) class TestBackupRestore(TestBackup): + volume = volume_fakes.FakeVolume.create_one_volume() + backup = volume_fakes.FakeBackup.create_one_backup( + attrs={'volume_id': volume.id}) + def setUp(self): super(TestBackupRestore, self).setUp() - self.backups_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.BACKUP), - loaded=True - ) - self.volumes_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True - ) + self.backups_mock.get.return_value = self.backup + self.volumes_mock.get.return_value = self.volume self.restores_mock.restore.return_value = None # Get the command object to mock self.cmd = backup.RestoreBackup(self.app, None) def test_backup_restore(self): arglist = [ - volume_fakes.backup_id, - volume_fakes.volume_id + self.backup.id, + self.backup.volume_id ] verifylist = [ - ("backup", volume_fakes.backup_id), - ("volume", volume_fakes.volume_id) + ("backup", self.backup.id), + ("volume", self.backup.volume_id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.restores_mock.restore.assert_called_with(volume_fakes.backup_id, - volume_fakes.volume_id) + self.restores_mock.restore.assert_called_with(self.backup.id, + self.backup.volume_id) self.assertIsNone(result) class TestBackupShow(TestBackup): + backup = volume_fakes.FakeBackup.create_one_backup() + + columns = ( + 'availability_zone', + 'container', + 'description', + 'id', + 'name', + 'object_count', + 'size', + 'status', + 'volume_id', + ) + data = ( + backup.availability_zone, + backup.container, + backup.description, + backup.id, + backup.name, + backup.object_count, + backup.size, + backup.status, + backup.volume_id, + ) + def setUp(self): super(TestBackupShow, self).setUp() - self.backups_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.BACKUP), - loaded=True) + self.backups_mock.get.return_value = self.backup # Get the command object to test self.cmd = backup.ShowBackup(self.app, None) def test_backup_show(self): arglist = [ - volume_fakes.backup_id + self.backup.id ] verifylist = [ - ("backup", volume_fakes.backup_id) + ("backup", self.backup.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.backups_mock.get.assert_called_with(volume_fakes.backup_id) + self.backups_mock.get.assert_called_with(self.backup.id) - self.assertEqual(volume_fakes.BACKUP_columns, columns) - self.assertEqual(volume_fakes.BACKUP_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) diff --git a/openstackclient/tests/volume/v2/test_qos_specs.py b/openstackclient/tests/volume/v2/test_qos_specs.py index 5232285c..741f4e70 100644 --- a/openstackclient/tests/volume/v2/test_qos_specs.py +++ b/openstackclient/tests/volume/v2/test_qos_specs.py @@ -13,10 +13,7 @@ # under the License. # -import copy - from openstackclient.common import utils -from openstackclient.tests import fakes from openstackclient.tests.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import qos_specs @@ -35,275 +32,228 @@ class TestQos(volume_fakes.TestVolume): class TestQosAssociate(TestQos): + volume_type = volume_fakes.FakeType.create_one_type() + qos_spec = volume_fakes.FakeQos.create_one_qos() + def setUp(self): super(TestQosAssociate, self).setUp() + self.qos_mock.get.return_value = self.qos_spec + self.types_mock.get.return_value = self.volume_type # Get the command object to test self.cmd = qos_specs.AssociateQos(self.app, None) def test_qos_associate(self): - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS), - loaded=True - ) - self.types_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True - ) arglist = [ - volume_fakes.qos_id, - volume_fakes.type_id + self.qos_spec.id, + self.volume_type.id ] verifylist = [ - ('qos_spec', volume_fakes.qos_id), - ('volume_type', volume_fakes.type_id) + ('qos_spec', self.qos_spec.id), + ('volume_type', self.volume_type.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.qos_mock.associate.assert_called_with( - volume_fakes.qos_id, - volume_fakes.type_id + self.qos_spec.id, + self.volume_type.id ) self.assertIsNone(result) class TestQosCreate(TestQos): + new_qos_spec = volume_fakes.FakeQos.create_one_qos() columns = ( 'consumer', 'id', - 'name' + 'name', + 'specs' ) - datalist = ( - volume_fakes.qos_consumer, - volume_fakes.qos_id, - volume_fakes.qos_name + data = ( + new_qos_spec.consumer, + new_qos_spec.id, + new_qos_spec.name, + new_qos_spec.specs ) def setUp(self): super(TestQosCreate, self).setUp() + self.qos_mock.create.return_value = self.new_qos_spec # Get the command object to test self.cmd = qos_specs.CreateQos(self.app, None) def test_qos_create_without_properties(self): - self.qos_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS_DEFAULT_CONSUMER), - loaded=True - ) - arglist = [ - volume_fakes.qos_name, + self.new_qos_spec.name, ] verifylist = [ - ('name', volume_fakes.qos_name), + ('name', self.new_qos_spec.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.create.assert_called_with( - volume_fakes.qos_name, - {'consumer': volume_fakes.qos_default_consumer} + self.new_qos_spec.name, + {'consumer': 'both'} ) self.assertEqual(self.columns, columns) - datalist = ( - volume_fakes.qos_default_consumer, - volume_fakes.qos_id, - volume_fakes.qos_name - ) - self.assertEqual(datalist, data) + self.assertEqual(self.data, data) def test_qos_create_with_consumer(self): - self.qos_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS), - loaded=True - ) - arglist = [ - volume_fakes.qos_name, - '--consumer', volume_fakes.qos_consumer + '--consumer', self.new_qos_spec.consumer, + self.new_qos_spec.name, ] verifylist = [ - ('name', volume_fakes.qos_name), - ('consumer', volume_fakes.qos_consumer) + ('consumer', self.new_qos_spec.consumer), + ('name', self.new_qos_spec.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.create.assert_called_with( - volume_fakes.qos_name, - {'consumer': volume_fakes.qos_consumer} + self.new_qos_spec.name, + {'consumer': self.new_qos_spec.consumer} ) self.assertEqual(self.columns, columns) - self.assertEqual(self.datalist, data) + self.assertEqual(self.data, data) def test_qos_create_with_properties(self): - self.qos_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS_WITH_SPECS), - loaded=True - ) - arglist = [ - volume_fakes.qos_name, - '--consumer', volume_fakes.qos_consumer, + '--consumer', self.new_qos_spec.consumer, '--property', 'foo=bar', - '--property', 'iops=9001' + '--property', 'iops=9001', + self.new_qos_spec.name, ] verifylist = [ - ('name', volume_fakes.qos_name), - ('consumer', volume_fakes.qos_consumer), - ('property', volume_fakes.qos_specs) + ('consumer', self.new_qos_spec.consumer), + ('property', self.new_qos_spec.specs), + ('name', self.new_qos_spec.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - specs = volume_fakes.qos_specs.copy() - specs.update({'consumer': volume_fakes.qos_consumer}) + self.new_qos_spec.specs.update( + {'consumer': self.new_qos_spec.consumer}) self.qos_mock.create.assert_called_with( - volume_fakes.qos_name, - specs + self.new_qos_spec.name, + self.new_qos_spec.specs ) - columns = self.columns + ( - 'specs', - ) - self.assertEqual(columns, columns) - datalist = self.datalist + ( - volume_fakes.qos_specs, - ) - self.assertEqual(datalist, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestQosDelete(TestQos): + qos_spec = volume_fakes.FakeQos.create_one_qos() + def setUp(self): super(TestQosDelete, self).setUp() - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS), - loaded=True, - ) - + self.qos_mock.get.return_value = self.qos_spec # Get the command object to test self.cmd = qos_specs.DeleteQos(self.app, None) - def test_qos_delete_with_id(self): - arglist = [ - volume_fakes.qos_id - ] - verifylist = [ - ('qos_specs', [volume_fakes.qos_id]) - ] - parsed_args = self.check_parser(self.cmd, arglist, verifylist) - - result = self.cmd.take_action(parsed_args) - - self.qos_mock.delete.assert_called_with(volume_fakes.qos_id) - self.assertIsNone(result) - - def test_qos_delete_with_name(self): + def test_qos_delete(self): arglist = [ - volume_fakes.qos_name + self.qos_spec.id ] verifylist = [ - ('qos_specs', [volume_fakes.qos_name]) + ('qos_specs', [self.qos_spec.id]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.qos_mock.delete.assert_called_with(volume_fakes.qos_id) + self.qos_mock.delete.assert_called_with(self.qos_spec.id) self.assertIsNone(result) class TestQosDisassociate(TestQos): + volume_type = volume_fakes.FakeType.create_one_type() + qos_spec = volume_fakes.FakeQos.create_one_qos() + def setUp(self): super(TestQosDisassociate, self).setUp() + self.qos_mock.get.return_value = self.qos_spec + self.types_mock.get.return_value = self.volume_type # Get the command object to test self.cmd = qos_specs.DisassociateQos(self.app, None) def test_qos_disassociate_with_volume_type(self): - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS), - loaded=True - ) - self.types_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True - ) arglist = [ - volume_fakes.qos_id, - '--volume-type', volume_fakes.type_id + '--volume-type', self.volume_type.id, + self.qos_spec.id, ] verifylist = [ - ('qos_spec', volume_fakes.qos_id), - ('volume_type', volume_fakes.type_id) + ('volume_type', self.volume_type.id), + ('qos_spec', self.qos_spec.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.qos_mock.disassociate.assert_called_with( - volume_fakes.qos_id, - volume_fakes.type_id + self.qos_spec.id, + self.volume_type.id ) self.assertIsNone(result) def test_qos_disassociate_with_all_volume_types(self): - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS), - loaded=True - ) - arglist = [ - volume_fakes.qos_id, - '--all' + '--all', + self.qos_spec.id, ] verifylist = [ - ('qos_spec', volume_fakes.qos_id) + ('qos_spec', self.qos_spec.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.qos_mock.disassociate_all.assert_called_with(volume_fakes.qos_id) + self.qos_mock.disassociate_all.assert_called_with(self.qos_spec.id) self.assertIsNone(result) class TestQosList(TestQos): + qos_specs = volume_fakes.FakeQos.create_qoses(count=2) + qos_association = volume_fakes.FakeQos.create_one_qos_association() + + columns = ( + 'ID', + 'Name', + 'Consumer', + 'Associations', + 'Specs', + ) + data = [] + for q in qos_specs: + data.append(( + q.id, + q.name, + q.consumer, + qos_association.name, + utils.format_dict(q.specs), + )) + def setUp(self): super(TestQosList, self).setUp() - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS_WITH_ASSOCIATIONS), - loaded=True, - ) - self.qos_mock.list.return_value = [self.qos_mock.get.return_value] - self.qos_mock.get_associations.return_value = [fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.qos_association), - loaded=True, - )] + self.qos_mock.list.return_value = self.qos_specs + self.qos_mock.get_associations.return_value = [self.qos_association] # Get the command object to test self.cmd = qos_specs.ListQos(self.app, None) @@ -317,139 +267,117 @@ class TestQosList(TestQos): columns, data = self.cmd.take_action(parsed_args) self.qos_mock.list.assert_called_with() - collist = ( - 'ID', - 'Name', - 'Consumer', - 'Associations', - 'Specs', - ) - self.assertEqual(collist, columns) - datalist = (( - volume_fakes.qos_id, - volume_fakes.qos_name, - volume_fakes.qos_consumer, - volume_fakes.type_name, - utils.format_dict(volume_fakes.qos_specs), - ), ) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, list(data)) class TestQosSet(TestQos): + qos_spec = volume_fakes.FakeQos.create_one_qos() + def setUp(self): super(TestQosSet, self).setUp() + self.qos_mock.get.return_value = self.qos_spec # Get the command object to test self.cmd = qos_specs.SetQos(self.app, None) def test_qos_set_with_properties_with_id(self): - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS_WITH_SPECS), - loaded=True - ) arglist = [ - volume_fakes.qos_id, '--property', 'foo=bar', - '--property', 'iops=9001' + '--property', 'iops=9001', + self.qos_spec.id, ] verifylist = [ - ('qos_spec', volume_fakes.qos_id), - ('property', volume_fakes.qos_specs) + ('property', self.qos_spec.specs), + ('qos_spec', self.qos_spec.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.qos_mock.set_keys.assert_called_with( - volume_fakes.qos_id, - volume_fakes.qos_specs + self.qos_spec.id, + self.qos_spec.specs ) self.assertIsNone(result) class TestQosShow(TestQos): + qos_spec = volume_fakes.FakeQos.create_one_qos() + qos_association = volume_fakes.FakeQos.create_one_qos_association() + + columns = ( + 'associations', + 'consumer', + 'id', + 'name', + 'specs' + ) + data = ( + qos_association.name, + qos_spec.consumer, + qos_spec.id, + qos_spec.name, + utils.format_dict(qos_spec.specs), + ) + def setUp(self): super(TestQosShow, self).setUp() - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS_WITH_ASSOCIATIONS), - loaded=True, - ) - self.qos_mock.get_associations.return_value = [fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.qos_association), - loaded=True, - )] + self.qos_mock.get.return_value = self.qos_spec + self.qos_mock.get_associations.return_value = [self.qos_association] # Get the command object to test self.cmd = qos_specs.ShowQos(self.app, None) def test_qos_show(self): arglist = [ - volume_fakes.qos_id + self.qos_spec.id ] verifylist = [ - ('qos_spec', volume_fakes.qos_id) + ('qos_spec', self.qos_spec.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.qos_mock.get.assert_called_with( - volume_fakes.qos_id + self.qos_spec.id ) - collist = ( - 'associations', - 'consumer', - 'id', - 'name', - 'specs' - ) - self.assertEqual(collist, columns) - datalist = ( - volume_fakes.type_name, - volume_fakes.qos_consumer, - volume_fakes.qos_id, - volume_fakes.qos_name, - utils.format_dict(volume_fakes.qos_specs), - ) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, tuple(data)) class TestQosUnset(TestQos): + qos_spec = volume_fakes.FakeQos.create_one_qos() + def setUp(self): super(TestQosUnset, self).setUp() + self.qos_mock.get.return_value = self.qos_spec # Get the command object to test self.cmd = qos_specs.UnsetQos(self.app, None) def test_qos_unset_with_properties(self): - self.qos_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.QOS), - loaded=True - ) arglist = [ - volume_fakes.qos_id, '--property', 'iops', - '--property', 'foo' + '--property', 'foo', + self.qos_spec.id, ] verifylist = [ - ('qos_spec', volume_fakes.qos_id), - ('property', ['iops', 'foo']) + ('property', ['iops', 'foo']), + ('qos_spec', self.qos_spec.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.qos_mock.unset_keys.assert_called_with( - volume_fakes.qos_id, + self.qos_spec.id, ['iops', 'foo'] ) self.assertIsNone(result) diff --git a/openstackclient/tests/volume/v2/test_snapshot.py b/openstackclient/tests/volume/v2/test_snapshot.py index 8c75dfb2..fe6fbb52 100644 --- a/openstackclient/tests/volume/v2/test_snapshot.py +++ b/openstackclient/tests/volume/v2/test_snapshot.py @@ -12,9 +12,7 @@ # under the License. # -import copy - -from openstackclient.tests import fakes +from openstackclient.common import utils from openstackclient.tests.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import snapshot @@ -32,58 +30,75 @@ class TestSnapshot(volume_fakes.TestVolume): class TestSnapshotCreate(TestSnapshot): + columns = ( + 'created_at', + 'description', + 'id', + 'name', + 'properties', + 'size', + 'status', + 'volume_id', + ) + def setUp(self): super(TestSnapshotCreate, self).setUp() - self.volumes_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True + self.volume = volume_fakes.FakeVolume.create_one_volume() + self.new_snapshot = volume_fakes.FakeSnapshot.create_one_snapshot( + attrs={'volume_id': self.volume.id}) + + self.data = ( + self.new_snapshot.created_at, + self.new_snapshot.description, + self.new_snapshot.id, + self.new_snapshot.name, + utils.format_dict(self.new_snapshot.metadata), + self.new_snapshot.size, + self.new_snapshot.status, + self.new_snapshot.volume_id, ) - self.snapshots_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.SNAPSHOT), - loaded=True - ) + self.volumes_mock.get.return_value = self.volume + self.snapshots_mock.create.return_value = self.new_snapshot # Get the command object to test self.cmd = snapshot.CreateSnapshot(self.app, None) def test_snapshot_create(self): arglist = [ - volume_fakes.volume_id, - "--name", volume_fakes.snapshot_name, - "--description", volume_fakes.snapshot_description, - "--force" + "--name", self.new_snapshot.name, + "--description", self.new_snapshot.description, + "--force", + self.new_snapshot.volume_id, ] verifylist = [ - ("volume", volume_fakes.volume_id), - ("name", volume_fakes.snapshot_name), - ("description", volume_fakes.snapshot_description), - ("force", True) + ("name", self.new_snapshot.name), + ("description", self.new_snapshot.description), + ("force", True), + ("volume", self.new_snapshot.volume_id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.create.assert_called_with( - volume_fakes.volume_id, + self.new_snapshot.volume_id, force=True, - name=volume_fakes.snapshot_name, - description=volume_fakes.snapshot_description + name=self.new_snapshot.name, + description=self.new_snapshot.description ) - self.assertEqual(columns, volume_fakes.SNAPSHOT_columns) - self.assertEqual(data, volume_fakes.SNAPSHOT_data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) def test_snapshot_create_without_name(self): arglist = [ - volume_fakes.volume_id, - "--description", volume_fakes.snapshot_description, + self.new_snapshot.volume_id, + "--description", self.new_snapshot.description, "--force" ] verifylist = [ - ("volume", volume_fakes.volume_id), - ("description", volume_fakes.snapshot_description), + ("volume", self.new_snapshot.volume_id), + ("description", self.new_snapshot.description), ("force", True) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -91,24 +106,23 @@ class TestSnapshotCreate(TestSnapshot): columns, data = self.cmd.take_action(parsed_args) self.snapshots_mock.create.assert_called_with( - volume_fakes.volume_id, + self.new_snapshot.volume_id, force=True, name=None, - description=volume_fakes.snapshot_description + description=self.new_snapshot.description ) - self.assertEqual(columns, volume_fakes.SNAPSHOT_columns) - self.assertEqual(data, volume_fakes.SNAPSHOT_data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestSnapshotDelete(TestSnapshot): + snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() + def setUp(self): super(TestSnapshotDelete, self).setUp() - self.snapshots_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.SNAPSHOT), - loaded=True) + self.snapshots_mock.get.return_value = self.snapshot self.snapshots_mock.delete.return_value = None # Get the command object to mock @@ -116,21 +130,25 @@ class TestSnapshotDelete(TestSnapshot): def test_snapshot_delete(self): arglist = [ - volume_fakes.snapshot_id + self.snapshot.id ] verifylist = [ - ("snapshots", [volume_fakes.snapshot_id]) + ("snapshots", [self.snapshot.id]) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.snapshots_mock.delete.assert_called_with(volume_fakes.snapshot_id) + self.snapshots_mock.delete.assert_called_with(self.snapshot.id) self.assertIsNone(result) class TestSnapshotList(TestSnapshot): + volume = volume_fakes.FakeVolume.create_one_volume() + snapshots = volume_fakes.FakeSnapshot.create_snapshots( + attrs={'volume_id': volume.name}, count=3) + columns = [ "ID", "Name", @@ -138,24 +156,39 @@ class TestSnapshotList(TestSnapshot): "Status", "Size" ] + columns_long = columns + [ + "Created At", + "Volume", + "Properties" + ] + + data = [] + for s in snapshots: + data.append(( + s.id, + s.name, + s.description, + s.status, + s.size, + )) + data_long = [] + for s in snapshots: + data_long.append(( + s.id, + s.name, + s.description, + s.status, + s.size, + s.created_at, + s.volume_id, + utils.format_dict(s.metadata), + )) def setUp(self): super(TestSnapshotList, self).setUp() - self.volumes_mock.list.return_value = [ - fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True - ) - ] - self.snapshots_mock.list.return_value = [ - fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.SNAPSHOT), - loaded=True - ) - ] + self.volumes_mock.list.return_value = [self.volume] + self.snapshots_mock.list.return_value = self.snapshots # Get the command to test self.cmd = snapshot.ListSnapshot(self.app, None) @@ -169,14 +202,7 @@ class TestSnapshotList(TestSnapshot): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - datalist = (( - volume_fakes.snapshot_id, - volume_fakes.snapshot_name, - volume_fakes.snapshot_description, - "available", - volume_fakes.snapshot_size - ),) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.data, list(data)) def test_snapshot_list_with_options(self): arglist = ["--long"] @@ -185,24 +211,8 @@ class TestSnapshotList(TestSnapshot): columns, data = self.cmd.take_action(parsed_args) - columns = self.columns + [ - "Created At", - "Volume", - "Properties" - ] - self.assertEqual(columns, columns) - - datalist = (( - volume_fakes.snapshot_id, - volume_fakes.snapshot_name, - volume_fakes.snapshot_description, - "available", - volume_fakes.snapshot_size, - "2015-06-03T18:49:19.000000", - volume_fakes.volume_name, - volume_fakes.EXPECTED_SNAPSHOT.get("properties") - ),) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.columns_long, columns) + self.assertEqual(self.data_long, list(data)) def test_snapshot_list_all_projects(self): arglist = [ @@ -217,27 +227,17 @@ class TestSnapshotList(TestSnapshot): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - - datalist = (( - volume_fakes.snapshot_id, - volume_fakes.snapshot_name, - volume_fakes.snapshot_description, - "available", - volume_fakes.snapshot_size - ), ) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.data, list(data)) class TestSnapshotSet(TestSnapshot): + snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() + def setUp(self): super(TestSnapshotSet, self).setUp() - self.snapshots_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.SNAPSHOT), - loaded=True - ) + self.snapshots_mock.get.return_value = self.snapshot self.snapshots_mock.set_metadata.return_value = None self.snapshots_mock.update.return_value = None # Get the command object to mock @@ -245,16 +245,16 @@ class TestSnapshotSet(TestSnapshot): def test_snapshot_set(self): arglist = [ - volume_fakes.snapshot_id, "--name", "new_snapshot", "--property", "x=y", - "--property", "foo=foo" + "--property", "foo=foo", + self.snapshot.id, ] new_property = {"x": "y", "foo": "foo"} verifylist = [ - ("snapshot", volume_fakes.snapshot_id), ("name", "new_snapshot"), - ("property", new_property) + ("property", new_property), + ("snapshot", self.snapshot.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -264,69 +264,106 @@ class TestSnapshotSet(TestSnapshot): "name": "new_snapshot", } self.snapshots_mock.update.assert_called_with( - volume_fakes.snapshot_id, **kwargs) + self.snapshot.id, **kwargs) self.snapshots_mock.set_metadata.assert_called_with( - volume_fakes.snapshot_id, new_property + self.snapshot.id, new_property ) self.assertIsNone(result) + def test_snapshot_set_state_to_error(self): + arglist = [ + "--state", "error", + self.snapshot.id + ] + verifylist = [ + ("state", "error"), + ("snapshot", self.snapshot.id) + ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) + + result = self.cmd.take_action(parsed_args) + + self.snapshots_mock.reset_state.assert_called_with( + self.snapshot.id, "error") + self.assertIsNone(result) + class TestSnapshotShow(TestSnapshot): + columns = ( + 'created_at', + 'description', + 'id', + 'name', + 'properties', + 'size', + 'status', + 'volume_id', + ) + def setUp(self): super(TestSnapshotShow, self).setUp() - self.snapshots_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.SNAPSHOT), - loaded=True) + self.snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() + + self.data = ( + self.snapshot.created_at, + self.snapshot.description, + self.snapshot.id, + self.snapshot.name, + utils.format_dict(self.snapshot.metadata), + self.snapshot.size, + self.snapshot.status, + self.snapshot.volume_id, + ) + + self.snapshots_mock.get.return_value = self.snapshot # Get the command object to test self.cmd = snapshot.ShowSnapshot(self.app, None) def test_snapshot_show(self): arglist = [ - volume_fakes.snapshot_id + self.snapshot.id ] verifylist = [ - ("snapshot", volume_fakes.snapshot_id) + ("snapshot", self.snapshot.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.snapshots_mock.get.assert_called_with(volume_fakes.snapshot_id) + self.snapshots_mock.get.assert_called_with(self.snapshot.id) - self.assertEqual(volume_fakes.SNAPSHOT_columns, columns) - self.assertEqual(volume_fakes.SNAPSHOT_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestSnapshotUnset(TestSnapshot): + snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() + def setUp(self): super(TestSnapshotUnset, self).setUp() - self.snapshots_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.SNAPSHOT), - loaded=True - ) + self.snapshots_mock.get.return_value = self.snapshot self.snapshots_mock.delete_metadata.return_value = None # Get the command object to mock self.cmd = snapshot.UnsetSnapshot(self.app, None) def test_snapshot_unset(self): arglist = [ - volume_fakes.snapshot_id, - "--property", "foo" + "--property", "foo", + self.snapshot.id, ] verifylist = [ - ("snapshot", volume_fakes.snapshot_id), - ("property", ["foo"]) + ("property", ["foo"]), + ("snapshot", self.snapshot.id), ] + parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) self.snapshots_mock.delete_metadata.assert_called_with( - volume_fakes.snapshot_id, ["foo"] + self.snapshot.id, ["foo"] ) self.assertIsNone(result) diff --git a/openstackclient/tests/volume/v2/test_type.py b/openstackclient/tests/volume/v2/test_type.py index f0ca9b01..872b4ae9 100644 --- a/openstackclient/tests/volume/v2/test_type.py +++ b/openstackclient/tests/volume/v2/test_type.py @@ -14,6 +14,7 @@ import copy +from openstackclient.common import utils from openstackclient.tests import fakes from openstackclient.tests.identity.v3 import fakes as identity_fakes from openstackclient.tests import utils as tests_utils @@ -21,20 +22,6 @@ from openstackclient.tests.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import volume_type -class FakeTypeResource(fakes.FakeResource): - - _keys = {'property': 'value'} - - def set_keys(self, args): - self._keys.update(args) - - def unset_keys(self, key): - self._keys.pop(key, None) - - def get_keys(self): - return self._keys - - class TestType(volume_fakes.TestVolume): def setUp(self): @@ -58,82 +45,78 @@ class TestTypeCreate(TestType): 'id', 'name', ) - datalist = ( - volume_fakes.type_description, - volume_fakes.type_id, - volume_fakes.type_name, - ) def setUp(self): super(TestTypeCreate, self).setUp() - self.types_mock.create.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True + self.new_volume_type = volume_fakes.FakeType.create_one_type() + self.data = ( + self.new_volume_type.description, + self.new_volume_type.id, + self.new_volume_type.name, ) + + self.types_mock.create.return_value = self.new_volume_type # Get the command object to test self.cmd = volume_type.CreateVolumeType(self.app, None) def test_type_create_public(self): arglist = [ - volume_fakes.type_name, - "--description", volume_fakes.type_description, - "--public" + "--description", self.new_volume_type.description, + "--public", + self.new_volume_type.name, ] verifylist = [ - ("name", volume_fakes.type_name), - ("description", volume_fakes.type_description), + ("description", self.new_volume_type.description), ("public", True), ("private", False), + ("name", self.new_volume_type.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.create.assert_called_with( - volume_fakes.type_name, - description=volume_fakes.type_description, + self.new_volume_type.name, + description=self.new_volume_type.description, is_public=True, ) self.assertEqual(self.columns, columns) - self.assertEqual(self.datalist, data) + self.assertEqual(self.data, data) def test_type_create_private(self): arglist = [ - volume_fakes.type_name, - "--description", volume_fakes.type_description, + "--description", self.new_volume_type.description, "--private", + self.new_volume_type.name, ] verifylist = [ - ("name", volume_fakes.type_name), - ("description", volume_fakes.type_description), + ("description", self.new_volume_type.description), ("public", False), ("private", True), + ("name", self.new_volume_type.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) self.types_mock.create.assert_called_with( - volume_fakes.type_name, - description=volume_fakes.type_description, + self.new_volume_type.name, + description=self.new_volume_type.description, is_public=False, ) self.assertEqual(self.columns, columns) - self.assertEqual(self.datalist, data) + self.assertEqual(self.data, data) class TestTypeDelete(TestType): + volume_type = volume_fakes.FakeType.create_one_type() + def setUp(self): super(TestTypeDelete, self).setUp() - self.types_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True - ) + self.types_mock.get.return_value = self.volume_type self.types_mock.delete.return_value = None # Get the command object to mock @@ -141,36 +124,51 @@ class TestTypeDelete(TestType): def test_type_delete(self): arglist = [ - volume_fakes.type_id + self.volume_type.id ] verifylist = [ - ("volume_type", volume_fakes.type_id) + ("volume_type", self.volume_type.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) - self.types_mock.delete.assert_called_with(volume_fakes.type_id) + self.types_mock.delete.assert_called_with(self.volume_type.id) self.assertIsNone(result) class TestTypeList(TestType): + volume_types = volume_fakes.FakeType.create_types() + columns = [ "ID", "Name" ] + columns_long = columns + [ + "Description", + "Properties" + ] + + data = [] + for t in volume_types: + data.append(( + t.id, + t.name, + )) + data_long = [] + for t in volume_types: + data_long.append(( + t.id, + t.name, + t.description, + utils.format_dict(t.extra_specs), + )) def setUp(self): super(TestTypeList, self).setUp() - self.types_mock.list.return_value = [ - fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True - ) - ] + self.types_mock.list.return_value = self.volume_types # get the command to test self.cmd = volume_type.ListVolumeType(self.app, None) @@ -183,11 +181,7 @@ class TestTypeList(TestType): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - datalist = (( - volume_fakes.type_id, - volume_fakes.type_name, - ),) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.data, list(data)) def test_type_list_with_options(self): arglist = ["--long"] @@ -195,30 +189,19 @@ class TestTypeList(TestType): parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - columns = self.columns + [ - "Description", - "Properties" - ] - self.assertEqual(columns, columns) - datalist = (( - volume_fakes.type_id, - volume_fakes.type_name, - volume_fakes.type_description, - "foo='bar'" - ),) - self.assertEqual(datalist, tuple(data)) + self.assertEqual(self.columns_long, columns) + self.assertEqual(self.data_long, list(data)) class TestTypeSet(TestType): + volume_type = volume_fakes.FakeType.create_one_type( + methods={'set_keys': None}) + def setUp(self): super(TestTypeSet, self).setUp() - self.types_mock.get.return_value = FakeTypeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True, - ) + self.types_mock.get.return_value = self.volume_type # Return a project self.projects_mock.get.return_value = fakes.FakeResource( @@ -226,7 +209,6 @@ class TestTypeSet(TestType): copy.deepcopy(identity_fakes.PROJECT), loaded=True, ) - # Get the command object to test self.cmd = volume_type.SetVolumeType(self.app, None) @@ -234,13 +216,13 @@ class TestTypeSet(TestType): new_name = 'new_name' arglist = [ '--name', new_name, - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('name', new_name), ('description', None), ('property', None), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -251,7 +233,7 @@ class TestTypeSet(TestType): 'name': new_name, } self.types_mock.update.assert_called_with( - volume_fakes.type_id, + self.volume_type.id, **kwargs ) self.assertIsNone(result) @@ -260,13 +242,13 @@ class TestTypeSet(TestType): new_desc = 'new_desc' arglist = [ '--description', new_desc, - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('name', None), ('description', new_desc), ('property', None), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -277,7 +259,7 @@ class TestTypeSet(TestType): 'description': new_desc, } self.types_mock.update.assert_called_with( - volume_fakes.type_id, + self.volume_type.id, **kwargs ) self.assertIsNone(result) @@ -285,31 +267,29 @@ class TestTypeSet(TestType): def test_type_set_property(self): arglist = [ '--property', 'myprop=myvalue', - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('name', None), ('description', None), ('property', {'myprop': 'myvalue'}), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) + self.volume_type.set_keys.assert_called_once_with( + {'myprop': 'myvalue'}) self.assertIsNone(result) - result = self.types_mock.get.return_value._keys - self.assertIn('myprop', result) - self.assertEqual('myvalue', result['myprop']) - def test_type_set_not_called_without_project_argument(self): arglist = [ '--project', '', - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('project', ''), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -336,11 +316,11 @@ class TestTypeSet(TestType): def test_type_set_project_access(self): arglist = [ '--project', identity_fakes.project_id, - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('project', identity_fakes.project_id), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -348,51 +328,61 @@ class TestTypeSet(TestType): self.assertIsNone(result) self.types_access_mock.add_project_access.assert_called_with( - volume_fakes.type_id, + self.volume_type.id, identity_fakes.project_id, ) class TestTypeShow(TestType): + columns = ( + 'description', + 'id', + 'name', + 'properties', + ) + def setUp(self): super(TestTypeShow, self).setUp() - self.types_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True + self.volume_type = volume_fakes.FakeType.create_one_type() + self.data = ( + self.volume_type.description, + self.volume_type.id, + self.volume_type.name, + utils.format_dict(self.volume_type.extra_specs) ) + self.types_mock.get.return_value = self.volume_type + # Get the command object to test self.cmd = volume_type.ShowVolumeType(self.app, None) def test_type_show(self): arglist = [ - volume_fakes.type_id + self.volume_type.id ] verifylist = [ - ("volume_type", volume_fakes.type_id) + ("volume_type", self.volume_type.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.types_mock.get.assert_called_with(volume_fakes.type_id) + self.types_mock.get.assert_called_with(self.volume_type.id) - self.assertEqual(volume_fakes.TYPE_FORMATTED_columns, columns) - self.assertEqual(volume_fakes.TYPE_FORMATTED_data, data) + self.assertEqual(self.columns, columns) + self.assertEqual(self.data, data) class TestTypeUnset(TestType): + volume_type = volume_fakes.FakeType.create_one_type( + methods={'unset_keys': None}) + def setUp(self): super(TestTypeUnset, self).setUp() - self.types_mock.get.return_value = FakeTypeResource( - None, - copy.deepcopy(volume_fakes.TYPE), - loaded=True - ) + self.types_mock.get.return_value = self.volume_type # Return a project self.projects_mock.get.return_value = fakes.FakeResource( @@ -407,29 +397,27 @@ class TestTypeUnset(TestType): def test_type_unset(self): arglist = [ '--property', 'property', - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('property', 'property'), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) result = self.cmd.take_action(parsed_args) + self.volume_type.unset_keys.assert_called_once_with('property') self.assertIsNone(result) - result = self.types_mock.get.return_value._keys - self.assertNotIn('property', result) - def test_type_unset_project_access(self): arglist = [ '--project', identity_fakes.project_id, - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('project', identity_fakes.project_id), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -437,18 +425,18 @@ class TestTypeUnset(TestType): self.assertIsNone(result) self.types_access_mock.remove_project_access.assert_called_with( - volume_fakes.type_id, + self.volume_type.id, identity_fakes.project_id, ) def test_type_unset_not_called_without_project_argument(self): arglist = [ '--project', '', - volume_fakes.type_id, + self.volume_type.id, ] verifylist = [ ('project', ''), - ('volume_type', volume_fakes.type_id), + ('volume_type', self.volume_type.id), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) diff --git a/openstackclient/tests/volume/v2/test_volume.py b/openstackclient/tests/volume/v2/test_volume.py index e4ac7c10..fb48d8ac 100644 --- a/openstackclient/tests/volume/v2/test_volume.py +++ b/openstackclient/tests/volume/v2/test_volume.py @@ -14,12 +14,12 @@ import copy -import mock from mock import call from openstackclient.common import utils from openstackclient.tests import fakes from openstackclient.tests.identity.v3 import fakes as identity_fakes +from openstackclient.tests.image.v2 import fakes as image_fakes from openstackclient.tests.volume.v2 import fakes as volume_fakes from openstackclient.volume.v2 import volume @@ -58,6 +58,7 @@ class TestVolumeCreate(TestVolume): columns = ( 'attachments', 'availability_zone', + 'bootable', 'description', 'id', 'name', @@ -77,6 +78,7 @@ class TestVolumeCreate(TestVolume): self.datalist = ( self.new_volume.attachments, self.new_volume.availability_zone, + self.new_volume.bootable, self.new_volume.description, self.new_volume.id, self.new_volume.name, @@ -299,19 +301,16 @@ class TestVolumeCreate(TestVolume): self.assertEqual(self.datalist, data) def test_volume_create_image_id(self): - self.images_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.IMAGE), - loaded=True, - ) + image = image_fakes.FakeImage.create_one_image() + self.images_mock.get.return_value = image arglist = [ - '--image', volume_fakes.image_id, + '--image', image.id, '--size', str(self.new_volume.size), self.new_volume.name, ] verifylist = [ - ('image', volume_fakes.image_id), + ('image', image.id), ('size', self.new_volume.size), ('name', self.new_volume.name), ] @@ -332,7 +331,7 @@ class TestVolumeCreate(TestVolume): project_id=None, availability_zone=None, metadata=None, - imageRef=volume_fakes.image_id, + imageRef=image.id, source_volid=None, ) @@ -340,19 +339,16 @@ class TestVolumeCreate(TestVolume): self.assertEqual(self.datalist, data) def test_volume_create_image_name(self): - self.images_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.IMAGE), - loaded=True, - ) + image = image_fakes.FakeImage.create_one_image() + self.images_mock.get.return_value = image arglist = [ - '--image', volume_fakes.image_name, + '--image', image.name, '--size', str(self.new_volume.size), self.new_volume.name, ] verifylist = [ - ('image', volume_fakes.image_name), + ('image', image.name), ('size', self.new_volume.size), ('name', self.new_volume.name), ] @@ -373,7 +369,7 @@ class TestVolumeCreate(TestVolume): project_id=None, availability_zone=None, metadata=None, - imageRef=volume_fakes.image_id, + imageRef=image.id, source_volid=None ) @@ -381,21 +377,21 @@ class TestVolumeCreate(TestVolume): self.assertEqual(self.datalist, data) def test_volume_create_with_snapshot(self): + snapshot = volume_fakes.FakeSnapshot.create_one_snapshot() + self.new_volume.snapshot_id = snapshot.id arglist = [ '--size', str(self.new_volume.size), - '--snapshot', volume_fakes.snapshot_id, + '--snapshot', self.new_volume.snapshot_id, self.new_volume.name, ] verifylist = [ ('size', self.new_volume.size), - ('snapshot', volume_fakes.snapshot_id), + ('snapshot', self.new_volume.snapshot_id), ('name', self.new_volume.name), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) - fake_snapshot = mock.Mock() - fake_snapshot.id = volume_fakes.snapshot_id - self.snapshots_mock.get.return_value = fake_snapshot + self.snapshots_mock.get.return_value = snapshot # 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 @@ -404,7 +400,7 @@ class TestVolumeCreate(TestVolume): self.volumes_mock.create.assert_called_once_with( size=self.new_volume.size, - snapshot_id=fake_snapshot.id, + snapshot_id=snapshot.id, name=self.new_volume.name, description=None, volume_type=None, @@ -475,13 +471,8 @@ class TestVolumeList(TestVolume): def setUp(self): super(TestVolumeList, self).setUp() - self.volumes_mock.list.return_value = [ - fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True, - ), - ] + self.mock_volume = volume_fakes.FakeVolume.create_one_volume() + self.volumes_mock.list.return_value = [self.mock_volume] self.users_mock.get.return_value = [ fakes.FakeResource( @@ -516,14 +507,14 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) @@ -544,14 +535,14 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) @@ -574,14 +565,14 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) @@ -601,14 +592,14 @@ class TestVolumeList(TestVolume): columns, data = self.cmd.take_action(parsed_args) self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) @@ -631,26 +622,26 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) def test_volume_list_name(self): arglist = [ - '--name', volume_fakes.volume_name, + '--name', self.mock_volume.name, ] verifylist = [ ('long', False), ('all_projects', False), - ('name', volume_fakes.volume_name), + ('name', self.mock_volume.name), ('status', None), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -659,27 +650,27 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) def test_volume_list_status(self): arglist = [ - '--status', volume_fakes.volume_status, + '--status', self.mock_volume.status, ] verifylist = [ ('long', False), ('all_projects', False), ('name', None), - ('status', volume_fakes.volume_status), + ('status', self.mock_volume.status), ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) @@ -687,14 +678,14 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) @@ -715,14 +706,14 @@ class TestVolumeList(TestVolume): self.assertEqual(self.columns, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, msg, ), ) self.assertEqual(datalist, tuple(data)) @@ -754,18 +745,18 @@ class TestVolumeList(TestVolume): ] self.assertEqual(collist, columns) - server = volume_fakes.volume_attachment_server['server_id'] - device = volume_fakes.volume_attachment_server['device'] + server = self.mock_volume.attachments[0]['server_id'] + device = self.mock_volume.attachments[0]['device'] msg = 'Attached to %s on %s ' % (server, device) datalist = (( - volume_fakes.volume_id, - volume_fakes.volume_name, - volume_fakes.volume_status, - volume_fakes.volume_size, - volume_fakes.volume_type, - '', + self.mock_volume.id, + self.mock_volume.name, + self.mock_volume.status, + self.mock_volume.size, + self.mock_volume.volume_type, + self.mock_volume.bootable, msg, - "Alpha='a', Beta='b', Gamma='g'", + utils.format_dict(self.mock_volume.metadata), ), ) self.assertEqual(datalist, tuple(data)) @@ -775,27 +766,30 @@ class TestVolumeShow(TestVolume): def setUp(self): super(TestVolumeShow, self).setUp() - self.volumes_mock.get.return_value = fakes.FakeResource( - None, - copy.deepcopy(volume_fakes.VOLUME), - loaded=True) + self._volume = volume_fakes.FakeVolume.create_one_volume() + self.volumes_mock.get.return_value = self._volume # Get the command object to test self.cmd = volume.ShowVolume(self.app, None) def test_volume_show(self): arglist = [ - volume_fakes.volume_id + self._volume.id ] verifylist = [ - ("volume", volume_fakes.volume_id) + ("volume", self._volume.id) ] parsed_args = self.check_parser(self.cmd, arglist, verifylist) columns, data = self.cmd.take_action(parsed_args) - self.volumes_mock.get.assert_called_with(volume_fakes.volume_id) + self.volumes_mock.get.assert_called_with(self._volume.id) + + self.assertEqual( + volume_fakes.FakeVolume.get_volume_columns(self._volume), + columns) - self.assertEqual(volume_fakes.VOLUME_columns, columns) - self.assertEqual(volume_fakes.VOLUME_data, data) + self.assertEqual( + volume_fakes.FakeVolume.get_volume_data(self._volume), + data) class TestVolumeSet(TestVolume): |
