summaryrefslogtreecommitdiff
path: root/openstackclient/tests
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/tests')
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_service_provider.py26
-rw-r--r--openstackclient/tests/unit/image/v1/test_image.py6
-rw-r--r--openstackclient/tests/unit/image/v2/test_image.py14
-rw-r--r--openstackclient/tests/unit/network/test_common.py14
-rw-r--r--openstackclient/tests/unit/network/test_sdk_utils.py59
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py50
-rw-r--r--openstackclient/tests/unit/network/v2/test_floating_ip.py63
-rw-r--r--openstackclient/tests/unit/network/v2/test_network.py89
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_rbac.py40
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_service_provider.py71
-rw-r--r--openstackclient/tests/unit/network/v2/test_port.py118
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group_rule.py226
-rw-r--r--openstackclient/tests/unit/network/v2/test_subnet.py16
-rw-r--r--openstackclient/tests/unit/network/v2/test_subnet_pool.py8
-rw-r--r--openstackclient/tests/unit/volume/v1/fakes.py109
-rw-r--r--openstackclient/tests/unit/volume/v1/test_backup.py45
-rw-r--r--openstackclient/tests/unit/volume/v1/test_type.py6
-rw-r--r--openstackclient/tests/unit/volume/v1/test_volume.py160
-rw-r--r--openstackclient/tests/unit/volume/v2/fakes.py107
-rw-r--r--openstackclient/tests/unit/volume/v2/test_backup.py58
-rw-r--r--openstackclient/tests/unit/volume/v2/test_consistency_group.py276
-rw-r--r--openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py351
-rw-r--r--openstackclient/tests/unit/volume/v2/test_type.py5
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume.py197
24 files changed, 1927 insertions, 187 deletions
diff --git a/openstackclient/tests/functional/network/v2/test_network_service_provider.py b/openstackclient/tests/functional/network/v2/test_network_service_provider.py
new file mode 100644
index 00000000..379de430
--- /dev/null
+++ b/openstackclient/tests/functional/network/v2/test_network_service_provider.py
@@ -0,0 +1,26 @@
+# Copyright (c) 2016, Intel Corporation.
+# 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.tests.functional import base
+
+
+class TestNetworkServiceProvider(base.TestCase):
+ """Functional tests for network service provider"""
+
+ SERVICE_TYPE = ['L3_ROUTER_NAT']
+
+ def test_network_service_provider_list(self):
+ raw_output = self.openstack('network service provider list')
+ self.assertIn(self.SERVICE_TYPE, raw_output)
diff --git a/openstackclient/tests/unit/image/v1/test_image.py b/openstackclient/tests/unit/image/v1/test_image.py
index aef74f04..036c8336 100644
--- a/openstackclient/tests/unit/image/v1/test_image.py
+++ b/openstackclient/tests/unit/image/v1/test_image.py
@@ -116,7 +116,7 @@ class TestImageCreate(TestImage):
self.images_mock.configure_mock(**mock_exception)
arglist = [
'--container-format', 'ovf',
- '--disk-format', 'fs',
+ '--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
'--protected',
@@ -126,7 +126,7 @@ class TestImageCreate(TestImage):
]
verifylist = [
('container_format', 'ovf'),
- ('disk_format', 'fs'),
+ ('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('protected', True),
@@ -147,7 +147,7 @@ class TestImageCreate(TestImage):
self.images_mock.create.assert_called_with(
name=self.new_image.name,
container_format='ovf',
- disk_format='fs',
+ disk_format='ami',
min_disk=10,
min_ram=4,
protected=True,
diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py
index ebc9c3a7..2f2212e4 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -130,7 +130,7 @@ class TestImageCreate(TestImage):
self.images_mock.configure_mock(**mock_exception)
arglist = [
'--container-format', 'ovf',
- '--disk-format', 'fs',
+ '--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
('--protected'
@@ -143,7 +143,7 @@ class TestImageCreate(TestImage):
]
verifylist = [
('container_format', 'ovf'),
- ('disk_format', 'fs'),
+ ('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('protected', self.new_image.protected),
@@ -165,7 +165,7 @@ class TestImageCreate(TestImage):
self.images_mock.create.assert_called_with(
name=self.new_image.name,
container_format='ovf',
- disk_format='fs',
+ disk_format='ami',
min_disk=10,
min_ram=4,
owner=self.project.id,
@@ -193,7 +193,7 @@ class TestImageCreate(TestImage):
arglist = [
'--container-format', 'ovf',
- '--disk-format', 'fs',
+ '--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
'--owner', 'unexist_owner',
@@ -203,7 +203,7 @@ class TestImageCreate(TestImage):
]
verifylist = [
('container_format', 'ovf'),
- ('disk_format', 'fs'),
+ ('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('owner', 'unexist_owner'),
@@ -227,7 +227,7 @@ class TestImageCreate(TestImage):
arglist = [
'--container-format', 'ovf',
- '--disk-format', 'fs',
+ '--disk-format', 'ami',
'--min-disk', '10',
'--min-ram', '4',
'--protected',
@@ -237,7 +237,7 @@ class TestImageCreate(TestImage):
]
verifylist = [
('container_format', 'ovf'),
- ('disk_format', 'fs'),
+ ('disk_format', 'ami'),
('min_disk', 10),
('min_ram', 4),
('protected', True),
diff --git a/openstackclient/tests/unit/network/test_common.py b/openstackclient/tests/unit/network/test_common.py
index 325aad2a..4b9a754b 100644
--- a/openstackclient/tests/unit/network/test_common.py
+++ b/openstackclient/tests/unit/network/test_common.py
@@ -14,6 +14,8 @@
import argparse
import mock
+import openstack
+from openstackclient.common import exceptions
from openstackclient.network import common
from openstackclient.tests.unit import utils
@@ -172,3 +174,15 @@ class TestNetworkAndComputeShowOne(TestNetworkAndCompute):
def setUp(self):
super(TestNetworkAndComputeShowOne, self).setUp()
self.cmd = FakeNetworkAndComputeShowOne(self.app, self.namespace)
+
+ def test_take_action_with_http_exception(self):
+ with mock.patch.object(self.cmd, 'take_action_network') as m_action:
+ m_action.side_effect = openstack.exceptions.HttpException("bar")
+ self.assertRaisesRegex(exceptions.CommandError, "bar",
+ self.cmd.take_action, mock.Mock())
+
+ self.app.client_manager.network_endpoint_enabled = False
+ with mock.patch.object(self.cmd, 'take_action_compute') as m_action:
+ m_action.side_effect = openstack.exceptions.HttpException("bar")
+ self.assertRaisesRegex(exceptions.CommandError, "bar",
+ self.cmd.take_action, mock.Mock())
diff --git a/openstackclient/tests/unit/network/test_sdk_utils.py b/openstackclient/tests/unit/network/test_sdk_utils.py
new file mode 100644
index 00000000..d1efa7e4
--- /dev/null
+++ b/openstackclient/tests/unit/network/test_sdk_utils.py
@@ -0,0 +1,59 @@
+# 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.network import sdk_utils
+from openstackclient.tests.unit import utils as tests_utils
+
+
+class TestSDKUtils(tests_utils.TestCase):
+
+ def setUp(self):
+ super(TestSDKUtils, self).setUp()
+
+ def _test_get_osc_show_columns_for_sdk_resource(
+ self, sdk_resource, column_map,
+ expected_display_columns, expected_attr_columns):
+ display_columns, attr_columns = \
+ sdk_utils.get_osc_show_columns_for_sdk_resource(
+ sdk_resource, column_map)
+ self.assertEqual(expected_display_columns, display_columns)
+ self.assertEqual(expected_attr_columns, attr_columns)
+
+ def test_get_osc_show_columns_for_sdk_resource_empty(self):
+ self._test_get_osc_show_columns_for_sdk_resource(
+ {}, {}, tuple(), tuple())
+
+ def test_get_osc_show_columns_for_sdk_resource_empty_map(self):
+ self._test_get_osc_show_columns_for_sdk_resource(
+ {'foo': 'foo1'}, {},
+ ('foo',), ('foo',))
+
+ def test_get_osc_show_columns_for_sdk_resource_empty_data(self):
+ self._test_get_osc_show_columns_for_sdk_resource(
+ {}, {'foo': 'foo_map'},
+ ('foo_map',), ('foo_map',))
+
+ def test_get_osc_show_columns_for_sdk_resource_map(self):
+ self._test_get_osc_show_columns_for_sdk_resource(
+ {'foo': 'foo1'}, {'foo': 'foo_map'},
+ ('foo_map',), ('foo',))
+
+ def test_get_osc_show_columns_for_sdk_resource_map_dup(self):
+ self._test_get_osc_show_columns_for_sdk_resource(
+ {'foo': 'foo1', 'foo_map': 'foo1'}, {'foo': 'foo_map'},
+ ('foo_map',), ('foo',))
+
+ def test_get_osc_show_columns_for_sdk_resource_map_full(self):
+ self._test_get_osc_show_columns_for_sdk_resource(
+ {'foo': 'foo1', 'bar': 'bar1'},
+ {'foo': 'foo_map', 'new': 'bar'},
+ ('bar', 'foo_map'), ('bar', 'foo'))
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index 94727ae3..c18511f7 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -98,6 +98,7 @@ class FakeAddressScope(object):
loaded=True)
# Set attributes with special mapping in OpenStack SDK.
+ address_scope.is_shared = address_scope_attrs['shared']
address_scope.project_id = address_scope_attrs['tenant_id']
return address_scope
@@ -291,11 +292,14 @@ class FakeNetwork(object):
'shared': False,
'subnets': ['a', 'b'],
'provider_network_type': 'vlan',
+ 'provider_physical_network': 'physnet1',
+ 'provider_segmentation_id': "400",
'router:external': True,
'availability_zones': [],
'availability_zone_hints': [],
'is_default': False,
'port_security_enabled': True,
+ 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
}
# Overwrite default attributes.
@@ -427,6 +431,7 @@ class FakePort(object):
'binding:vif_details': {},
'binding:vif_type': 'ovs',
'binding:vnic_type': 'normal',
+ 'description': 'description-' + uuid.uuid4().hex,
'device_id': 'device-id-' + uuid.uuid4().hex,
'device_owner': 'compute:nova',
'dns_assignment': [{}],
@@ -741,6 +746,7 @@ class FakeNetworkQosPolicy(object):
loaded=True)
# Set attributes with special mapping in OpenStack SDK.
+ qos_policy.is_shared = qos_policy_attrs['shared']
qos_policy.project_id = qos_policy_attrs['tenant_id']
return qos_policy
@@ -951,6 +957,8 @@ class FakeSecurityGroupRule(object):
# Set default attributes.
security_group_rule_attrs = {
+ 'description': 'security-group-rule-description-' +
+ uuid.uuid4().hex,
'direction': 'ingress',
'ethertype': 'IPv4',
'id': 'security-group-rule-id-' + uuid.uuid4().hex,
@@ -1057,6 +1065,8 @@ class FakeSubnet(object):
loaded=True)
# Set attributes with special mappings in OpenStack SDK.
+ subnet.is_dhcp_enabled = subnet_attrs['enable_dhcp']
+ subnet.subnet_pool_id = subnet_attrs['subnetpool_id']
subnet.project_id = subnet_attrs['tenant_id']
return subnet
@@ -1216,6 +1226,11 @@ class FakeSubnetPool(object):
)
# Set attributes with special mapping in OpenStack SDK.
+ subnet_pool.default_prefix_length = \
+ subnet_pool_attrs['default_prefixlen']
+ subnet_pool.is_shared = subnet_pool_attrs['shared']
+ subnet_pool.maximum_prefix_length = subnet_pool_attrs['max_prefixlen']
+ subnet_pool.minimum_prefix_length = subnet_pool_attrs['min_prefixlen']
subnet_pool.project_id = subnet_pool_attrs['tenant_id']
return subnet_pool
@@ -1257,3 +1272,38 @@ class FakeSubnetPool(object):
if subnet_pools is None:
subnet_pools = FakeSubnetPool.create_subnet_pools(count)
return mock.Mock(side_effect=subnet_pools)
+
+
+class FakeNetworkServiceProvider(object):
+ """Fake Network Service Providers"""
+
+ @staticmethod
+ def create_one_network_service_provider(attrs=None):
+ """Create service provider"""
+ attrs = attrs or {}
+
+ service_provider = {
+ 'name': 'provider-name-' + uuid.uuid4().hex,
+ 'service_type': 'service-type-' + uuid.uuid4().hex,
+ 'default': False,
+ }
+
+ service_provider.update(attrs)
+
+ provider = fakes.FakeResource(
+ info=copy.deepcopy(service_provider),
+ loaded=True)
+ provider.is_default = service_provider['default']
+
+ return provider
+
+ @staticmethod
+ def create_network_service_providers(attrs=None, count=2):
+ """Create multiple service providers"""
+
+ service_providers = []
+ for i in range(0, count):
+ service_providers.append(FakeNetworkServiceProvider.
+ create_one_network_service_provider(
+ attrs))
+ return service_providers
diff --git a/openstackclient/tests/unit/network/v2/test_floating_ip.py b/openstackclient/tests/unit/network/v2/test_floating_ip.py
index 578c6154..10f3067d 100644
--- a/openstackclient/tests/unit/network/v2/test_floating_ip.py
+++ b/openstackclient/tests/unit/network/v2/test_floating_ip.py
@@ -231,6 +231,12 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
# The floating ips to list up
floating_ips = network_fakes.FakeFloatingIP.create_floating_ips(count=3)
+ fake_network = network_fakes.FakeNetwork.create_one_network({
+ 'id': 'fake_network_id',
+ })
+ fake_port = network_fakes.FakePort.create_one_port({
+ 'id': 'fake_port_id',
+ })
columns = (
'ID',
@@ -256,6 +262,8 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
super(TestListFloatingIPNetwork, self).setUp()
self.network.ips = mock.Mock(return_value=self.floating_ips)
+ self.network.find_network = mock.Mock(return_value=self.fake_network)
+ self.network.find_port = mock.Mock(return_value=self.fake_port)
# Get the command object to test
self.cmd = floating_ip.ListFloatingIP(self.app, self.namespace)
@@ -267,7 +275,58 @@ class TestListFloatingIPNetwork(TestFloatingIPNetwork):
columns, data = self.cmd.take_action(parsed_args)
- self.network.ips.assert_called_once_with(**{})
+ self.network.ips.assert_called_once_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_floating_ip_list_network(self):
+ arglist = [
+ '--network', 'fake_network_id',
+ ]
+ verifylist = [
+ ('network', 'fake_network_id'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.ips.assert_called_once_with(**{
+ 'floating_network_id': 'fake_network_id',
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_floating_ip_list_port(self):
+ arglist = [
+ '--port', 'fake_port_id',
+ ]
+ verifylist = [
+ ('port', 'fake_port_id'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.ips.assert_called_once_with(**{
+ 'port_id': 'fake_port_id',
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_floating_ip_list_fixed_ip_address(self):
+ arglist = [
+ '--fixed-ip-address', self.floating_ips[0].fixed_ip_address,
+ ]
+ verifylist = [
+ ('fixed_ip_address', self.floating_ips[0].fixed_ip_address),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.ips.assert_called_once_with(**{
+ 'fixed_ip_address': self.floating_ips[0].fixed_ip_address,
+ })
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -300,7 +359,7 @@ class TestShowFloatingIPNetwork(TestFloatingIPNetwork):
floating_ip.floating_network_id,
floating_ip.id,
floating_ip.port_id,
- floating_ip.tenant_id,
+ floating_ip.project_id,
floating_ip.router_id,
floating_ip.status,
)
diff --git a/openstackclient/tests/unit/network/v2/test_network.py b/openstackclient/tests/unit/network/v2/test_network.py
index 828da4a2..96b1b102 100644
--- a/openstackclient/tests/unit/network/v2/test_network.py
+++ b/openstackclient/tests/unit/network/v2/test_network.py
@@ -53,6 +53,8 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'availability_zone_hints': ["nova"],
}
)
+ qos_policy = (network_fakes.FakeNetworkQosPolicy.
+ create_one_qos_policy(attrs={'id': _network.qos_policy_id}))
columns = (
'admin_state_up',
@@ -65,6 +67,9 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'port_security_enabled',
'project_id',
'provider_network_type',
+ 'provider_physical_network',
+ 'provider_segmentation_id',
+ 'qos_policy_id',
'router:external',
'shared',
'status',
@@ -82,6 +87,9 @@ class TestCreateNetworkIdentityV3(TestNetwork):
_network.is_port_security_enabled,
_network.project_id,
_network.provider_network_type,
+ _network.provider_physical_network,
+ _network.provider_segmentation_id,
+ _network.qos_policy_id,
network._format_router_external(_network.is_router_external),
_network.shared,
_network.status,
@@ -98,6 +106,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
self.projects_mock.get.return_value = self.project
self.domains_mock.get.return_value = self.domain
+ self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
def test_create_no_options(self):
arglist = []
@@ -140,6 +149,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
"--provider-network-type", "vlan",
"--provider-physical-network", "physnet1",
"--provider-segment", "400",
+ "--qos-policy", self.qos_policy.id,
"--transparent-vlan",
"--enable-port-security",
self._network.name,
@@ -156,6 +166,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
('provider_network_type', 'vlan'),
('physical_network', 'physnet1'),
('segmentation_id', '400'),
+ ('qos_policy', self.qos_policy.id),
('transparent_vlan', True),
('enable_port_security', True),
('name', self._network.name),
@@ -176,6 +187,7 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'provider:network_type': 'vlan',
'provider:physical_network': 'physnet1',
'provider:segmentation_id': '400',
+ 'qos_policy_id': self.qos_policy.id,
'vlan_transparent': True,
'port_security_enabled': True,
})
@@ -229,6 +241,9 @@ class TestCreateNetworkIdentityV2(TestNetwork):
'port_security_enabled',
'project_id',
'provider_network_type',
+ 'provider_physical_network',
+ 'provider_segmentation_id',
+ 'qos_policy_id',
'router:external',
'shared',
'status',
@@ -246,6 +261,9 @@ class TestCreateNetworkIdentityV2(TestNetwork):
_network.is_port_security_enabled,
_network.project_id,
_network.provider_network_type,
+ _network.provider_physical_network,
+ _network.provider_segmentation_id,
+ _network.qos_policy_id,
network._format_router_external(_network.is_router_external),
_network.shared,
_network.status,
@@ -681,11 +699,64 @@ class TestListNetwork(TestNetwork):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_network_list_provider_network_type(self):
+ network_type = self._network[0].provider_network_type
+ arglist = [
+ '--provider-network-type', network_type,
+ ]
+ verifylist = [
+ ('provider_network_type', network_type),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.networks.assert_called_once_with(
+ **{'provider:network_type': network_type}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_network_list_provider_physical_network(self):
+ physical_network = self._network[0].provider_physical_network
+ arglist = [
+ '--provider-physical-network', physical_network,
+ ]
+ verifylist = [
+ ('physical_network', physical_network),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.networks.assert_called_once_with(
+ **{'provider:physical_network': physical_network}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_network_list_provider_segment(self):
+ segmentation_id = self._network[0].provider_segmentation_id
+ arglist = [
+ '--provider-segment', segmentation_id,
+ ]
+ verifylist = [
+ ('segmentation_id', segmentation_id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.networks.assert_called_once_with(
+ **{'provider:segmentation_id': segmentation_id}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
class TestSetNetwork(TestNetwork):
# The network to set.
_network = network_fakes.FakeNetwork.create_one_network()
+ qos_policy = (network_fakes.FakeNetworkQosPolicy.
+ create_one_qos_policy(attrs={'id': _network.qos_policy_id}))
def setUp(self):
super(TestSetNetwork, self).setUp()
@@ -693,6 +764,7 @@ class TestSetNetwork(TestNetwork):
self.network.update_network = mock.Mock(return_value=None)
self.network.find_network = mock.Mock(return_value=self._network)
+ self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
# Get the command object to test
self.cmd = network.SetNetwork(self.app, self.namespace)
@@ -711,6 +783,7 @@ class TestSetNetwork(TestNetwork):
'--provider-segment', '400',
'--no-transparent-vlan',
'--enable-port-security',
+ '--qos-policy', self.qos_policy.name,
]
verifylist = [
('network', self._network.name),
@@ -725,6 +798,7 @@ class TestSetNetwork(TestNetwork):
('segmentation_id', '400'),
('no_transparent_vlan', True),
('enable_port_security', True),
+ ('qos_policy', self.qos_policy.name),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -742,6 +816,7 @@ class TestSetNetwork(TestNetwork):
'provider:segmentation_id': '400',
'vlan_transparent': False,
'port_security_enabled': True,
+ 'qos_policy_id': self.qos_policy.id,
}
self.network.update_network.assert_called_once_with(
self._network, **attrs)
@@ -754,6 +829,7 @@ class TestSetNetwork(TestNetwork):
'--no-share',
'--internal',
'--disable-port-security',
+ '--no-qos-policy',
]
verifylist = [
('network', self._network.name),
@@ -761,6 +837,7 @@ class TestSetNetwork(TestNetwork):
('no_share', True),
('internal', True),
('disable_port_security', True),
+ ('no_qos_policy', True),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -771,6 +848,7 @@ class TestSetNetwork(TestNetwork):
'shared': False,
'router:external': False,
'port_security_enabled': False,
+ 'qos_policy_id': None,
}
self.network.update_network.assert_called_once_with(
self._network, **attrs)
@@ -805,6 +883,9 @@ class TestShowNetwork(TestNetwork):
'port_security_enabled',
'project_id',
'provider_network_type',
+ 'provider_physical_network',
+ 'provider_segmentation_id',
+ 'qos_policy_id',
'router:external',
'shared',
'status',
@@ -822,6 +903,9 @@ class TestShowNetwork(TestNetwork):
_network.is_port_security_enabled,
_network.project_id,
_network.provider_network_type,
+ _network.provider_physical_network,
+ _network.provider_segmentation_id,
+ _network.qos_policy_id,
network._format_router_external(_network.is_router_external),
_network.shared,
_network.status,
@@ -1111,10 +1195,7 @@ class TestListNetworkCompute(TestNetworkCompute):
def test_network_list_no_options(self):
arglist = []
- verifylist = [
- ('external', False),
- ('long', False),
- ]
+ verifylist = []
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
# In base command class Lister in cliff, abstract method take_action()
diff --git a/openstackclient/tests/unit/network/v2/test_network_rbac.py b/openstackclient/tests/unit/network/v2/test_network_rbac.py
index c526ae4e..b884dbc0 100644
--- a/openstackclient/tests/unit/network/v2/test_network_rbac.py
+++ b/openstackclient/tests/unit/network/v2/test_network_rbac.py
@@ -36,6 +36,7 @@ class TestNetworkRBAC(network_fakes.TestNetworkV2):
class TestCreateNetworkRBAC(TestNetworkRBAC):
network_object = network_fakes.FakeNetwork.create_one_network()
+ qos_object = network_fakes.FakeNetworkQosPolicy.create_one_qos_policy()
project = identity_fakes_v3.FakeProject.create_one_project()
rbac_policy = network_fakes.FakeNetworkRBAC.create_one_network_rbac(
attrs={'tenant_id': project.id,
@@ -71,6 +72,8 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
return_value=self.rbac_policy)
self.network.find_network = mock.Mock(
return_value=self.network_object)
+ self.network.find_qos_policy = mock.Mock(
+ return_value=self.qos_object)
self.projects_mock.get.return_value = self.project
def test_network_rbac_create_no_type(self):
@@ -194,6 +197,43 @@ class TestCreateNetworkRBAC(TestNetworkRBAC):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_network_rbac_create_qos_object(self):
+ self.rbac_policy.object_type = 'qos_policy'
+ self.rbac_policy.object_id = self.qos_object.id
+ arglist = [
+ '--type', 'qos_policy',
+ '--action', self.rbac_policy.action,
+ '--target-project', self.rbac_policy.target_tenant,
+ self.qos_object.name,
+ ]
+ verifylist = [
+ ('type', 'qos_policy'),
+ ('action', self.rbac_policy.action),
+ ('target_project', self.rbac_policy.target_tenant),
+ ('rbac_object', self.qos_object.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ # DisplayCommandBase.take_action() returns two tuples
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_rbac_policy.assert_called_with(**{
+ 'object_id': self.qos_object.id,
+ 'object_type': 'qos_policy',
+ 'action': self.rbac_policy.action,
+ 'target_tenant': self.rbac_policy.target_tenant,
+ })
+ self.data = [
+ self.rbac_policy.action,
+ self.rbac_policy.id,
+ self.qos_object.id,
+ 'qos_policy',
+ self.rbac_policy.tenant_id,
+ self.rbac_policy.target_tenant,
+ ]
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
class TestDeleteNetworkRBAC(TestNetworkRBAC):
diff --git a/openstackclient/tests/unit/network/v2/test_network_service_provider.py b/openstackclient/tests/unit/network/v2/test_network_service_provider.py
new file mode 100644
index 00000000..5ba85ddb
--- /dev/null
+++ b/openstackclient/tests/unit/network/v2/test_network_service_provider.py
@@ -0,0 +1,71 @@
+# Copyright (c) 2016, Intel Corporation.
+# 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.
+
+import mock
+
+from openstackclient.network.v2 import network_service_provider \
+ as service_provider
+from openstackclient.tests.unit.network.v2 import fakes
+
+
+class TestNetworkServiceProvider(fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestNetworkServiceProvider, self).setUp()
+ self.network = self.app.client_manager.network
+
+
+class TestListNetworkServiceProvider(TestNetworkServiceProvider):
+ provider_list = \
+ fakes.FakeNetworkServiceProvider.create_network_service_providers(
+ count=2
+ )
+
+ columns = (
+ 'Service Type',
+ 'Name',
+ 'Default',
+ )
+
+ data = []
+
+ for provider in provider_list:
+ data.append((
+ provider.service_type,
+ provider.name,
+ provider.is_default,
+ ))
+
+ def setUp(self):
+ super(TestListNetworkServiceProvider, self).setUp()
+ self.network.service_providers = mock.Mock(
+ return_value=self.provider_list
+ )
+
+ self.cmd = \
+ service_provider.ListNetworkServiceProvider(self.app,
+ self.namespace)
+
+ def test_network_service_provider_list(self):
+ arglist = []
+ verifylist = []
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.service_providers.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
diff --git a/openstackclient/tests/unit/network/v2/test_port.py b/openstackclient/tests/unit/network/v2/test_port.py
index 4ff278a9..9312a897 100644
--- a/openstackclient/tests/unit/network/v2/test_port.py
+++ b/openstackclient/tests/unit/network/v2/test_port.py
@@ -41,6 +41,7 @@ class TestPort(network_fakes.TestNetworkV2):
'binding_vif_details',
'binding_vif_type',
'binding_vnic_type',
+ 'description',
'device_id',
'device_owner',
'dns_assignment',
@@ -65,6 +66,7 @@ class TestPort(network_fakes.TestNetworkV2):
utils.format_dict(fake_port.binding_vif_details),
fake_port.binding_vif_type,
fake_port.binding_vnic_type,
+ fake_port.description,
fake_port.device_id,
fake_port.device_owner,
utils.format_list_of_dicts(fake_port.dns_assignment),
@@ -130,6 +132,7 @@ class TestCreatePort(TestPort):
'--mac-address', 'aa:aa:aa:aa:aa:aa',
'--fixed-ip', 'subnet=%s,ip-address=10.0.0.2'
% self.fake_subnet.id,
+ '--description', self._port.description,
'--device', 'deviceid',
'--device-owner', 'fakeowner',
'--disable',
@@ -146,6 +149,7 @@ class TestCreatePort(TestPort):
'fixed_ip',
[{'subnet': self.fake_subnet.id, 'ip-address': '10.0.0.2'}]
),
+ ('description', self._port.description),
('device', 'deviceid'),
('device_owner', 'fakeowner'),
('disable', True),
@@ -163,6 +167,7 @@ class TestCreatePort(TestPort):
'mac_address': 'aa:aa:aa:aa:aa:aa',
'fixed_ips': [{'subnet_id': self.fake_subnet.id,
'ip_address': '10.0.0.2'}],
+ 'description': self._port.description,
'device_id': 'deviceid',
'device_owner': 'fakeowner',
'admin_state_up': False,
@@ -315,6 +320,54 @@ class TestCreatePort(TestPort):
self.assertEqual(ref_columns, columns)
self.assertEqual(ref_data, data)
+ def test_create_port_security_enabled(self):
+ arglist = [
+ '--network', self._port.network_id,
+ '--enable-port-security',
+ 'test-port',
+ ]
+ verifylist = [
+ ('network', self._port.network_id,),
+ ('enable', True),
+ ('enable_port_security', True),
+ ('name', 'test-port'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ self.network.create_port.assert_called_once_with(**{
+ 'admin_state_up': True,
+ 'network_id': self._port.network_id,
+ 'port_security_enabled': True,
+ 'name': 'test-port',
+ })
+
+ def test_create_port_security_disabled(self):
+ arglist = [
+ '--network', self._port.network_id,
+ '--disable-port-security',
+ 'test-port',
+ ]
+ verifylist = [
+ ('network', self._port.network_id,),
+ ('enable', True),
+ ('disable_port_security', True),
+ ('name', 'test-port'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ self.network.create_port.assert_called_once_with(**{
+ 'admin_state_up': True,
+ 'network_id': self._port.network_id,
+ 'port_security_enabled': False,
+ 'name': 'test-port',
+ })
+
class TestDeletePort(TestPort):
@@ -530,12 +583,14 @@ class TestListPort(TestPort):
'--device-owner', self._ports[0].device_owner,
'--router', 'fake-router-name',
'--network', 'fake-network-name',
+ '--mac-address', self._ports[0].mac_address,
]
verifylist = [
('device_owner', self._ports[0].device_owner),
('router', 'fake-router-name'),
- ('network', 'fake-network-name')
+ ('network', 'fake-network-name'),
+ ('mac_address', self._ports[0].mac_address)
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -545,7 +600,27 @@ class TestListPort(TestPort):
self.network.ports.assert_called_once_with(**{
'device_owner': self._ports[0].device_owner,
'device_id': 'fake-router-id',
- 'network_id': 'fake-network-id'
+ 'network_id': 'fake-network-id',
+ 'mac_address': self._ports[0].mac_address
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_port_list_mac_address_opt(self):
+ arglist = [
+ '--mac-address', self._ports[0].mac_address,
+ ]
+
+ verifylist = [
+ ('mac_address', self._ports[0].mac_address)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.ports.assert_called_once_with(**{
+ 'mac_address': self._ports[0].mac_address
})
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -693,6 +768,7 @@ class TestSetPort(TestPort):
def test_set_that(self):
arglist = [
+ '--description', 'newDescription',
'--enable',
'--vnic-type', 'macvtap',
'--binding-profile', 'foo=bar',
@@ -701,6 +777,7 @@ class TestSetPort(TestPort):
self._port.name,
]
verifylist = [
+ ('description', 'newDescription'),
('enable', True),
('vnic_type', 'macvtap'),
('binding_profile', {'foo': 'bar'}),
@@ -717,6 +794,7 @@ class TestSetPort(TestPort):
'binding:vnic_type': 'macvtap',
'binding:profile': {'foo': 'bar'},
'binding:host_id': 'binding-host-id-xxxx',
+ 'description': 'newDescription',
'name': 'newName',
}
self.network.update_port.assert_called_once_with(self._port, **attrs)
@@ -868,6 +946,42 @@ class TestSetPort(TestPort):
self.network.update_port.assert_called_once_with(_testport, **attrs)
self.assertIsNone(result)
+ def test_port_security_enabled(self):
+ arglist = [
+ '--enable-port-security',
+ self._port.id,
+ ]
+ verifylist = [
+ ('enable_port_security', True),
+ ('port', self._port.id,)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ self.network.update_port.assert_called_once_with(self._port, **{
+ 'port_security_enabled': True,
+ })
+
+ def test_port_security_disabled(self):
+ arglist = [
+ '--disable-port-security',
+ self._port.id,
+ ]
+ verifylist = [
+ ('disable_port_security', True),
+ ('port', self._port.id,)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ self.cmd.take_action(parsed_args)
+
+ self.network.update_port.assert_called_once_with(self._port, **{
+ 'port_security_enabled': False,
+ })
+
class TestShowPort(TestPort):
diff --git a/openstackclient/tests/unit/network/v2/test_security_group_rule.py b/openstackclient/tests/unit/network/v2/test_security_group_rule.py
index 96d58e5c..5fe9013e 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group_rule.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group_rule.py
@@ -60,6 +60,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
network_fakes.FakeSecurityGroup.create_one_security_group()
expected_columns = (
+ 'description',
'direction',
'ethertype',
'id',
@@ -81,6 +82,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.network.create_security_group_rule = mock.Mock(
return_value=self._security_group_rule)
self.expected_data = (
+ self._security_group_rule.description,
self._security_group_rule.direction,
self._security_group_rule.ethertype,
self._security_group_rule.id,
@@ -119,6 +121,15 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertRaises(tests_utils.ParserException,
self.check_parser, self.cmd, arglist, [])
+ def test_create_all_remote_options(self):
+ arglist = [
+ '--remote-ip', '10.10.0.0/24',
+ '--remote-group', self._security_group.id,
+ self._security_group.id,
+ ]
+ self.assertRaises(tests_utils.ParserException,
+ self.check_parser, self.cmd, arglist, [])
+
def test_create_bad_ethertype(self):
arglist = [
'--ethertype', 'foo',
@@ -213,7 +224,7 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertEqual(self.expected_columns, columns)
self.assertEqual(self.expected_data, data)
- def test_create_source_group(self):
+ def test_create_remote_group(self):
self._setup_security_group_rule({
'port_range_max': 22,
'port_range_min': 22,
@@ -248,6 +259,34 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertEqual(self.expected_columns, columns)
self.assertEqual(self.expected_data, data)
+ def test_create_source_group(self):
+ self._setup_security_group_rule({
+ 'remote_group_id': self._security_group.id,
+ })
+ arglist = [
+ '--ingress',
+ '--src-group', self._security_group.name,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('ingress', True),
+ ('src_group', self._security_group.name),
+ ('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_group_id': self._security_group_rule.remote_group_id,
+ 'security_group_id': self._security_group.id,
+ })
+ 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',
@@ -277,6 +316,35 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertEqual(self.expected_columns, columns)
self.assertEqual(self.expected_data, data)
+ def test_create_remote_ip(self):
+ self._setup_security_group_rule({
+ 'protocol': 'icmp',
+ 'remote_ip_prefix': '10.0.2.0/24',
+ })
+ arglist = [
+ '--protocol', self._security_group_rule.protocol,
+ '--remote-ip', self._security_group_rule.remote_ip_prefix,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('protocol', self._security_group_rule.protocol),
+ ('remote_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_network_options(self):
self._setup_security_group_rule({
'direction': 'egress',
@@ -452,6 +520,33 @@ class TestCreateSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertEqual(self.expected_columns, columns)
self.assertEqual(self.expected_data, data)
+ def test_create_with_description(self):
+ self._setup_security_group_rule({
+ 'description': 'Setting SGR',
+ })
+ arglist = [
+ '--description', self._security_group_rule.description,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('description', self._security_group_rule.description),
+ ('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(**{
+ 'description': self._security_group_rule.description,
+ '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)
+
class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
@@ -498,6 +593,15 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
self.assertRaises(tests_utils.ParserException,
self.check_parser, self.cmd, arglist, [])
+ def test_create_all_remote_options(self):
+ arglist = [
+ '--remote-ip', '10.10.0.0/24',
+ '--remote-group', self._security_group.id,
+ self._security_group.id,
+ ]
+ self.assertRaises(tests_utils.ParserException,
+ self.check_parser, self.cmd, arglist, [])
+
def test_create_bad_protocol(self):
arglist = [
'--protocol', 'foo',
@@ -588,6 +692,38 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
self.assertEqual(expected_columns, columns)
self.assertEqual(expected_data, data)
+ def test_create_remote_group(self):
+ expected_columns, expected_data = self._setup_security_group_rule({
+ 'from_port': 22,
+ 'to_port': 22,
+ 'group': {'name': self._security_group.name},
+ })
+ arglist = [
+ '--dst-port', str(self._security_group_rule.from_port),
+ '--remote-group', self._security_group.name,
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('dst_port', (self._security_group_rule.from_port,
+ self._security_group_rule.to_port)),
+ ('remote_group', self._security_group.name),
+ ('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'],
+ self._security_group.id,
+ )
+ self.assertEqual(expected_columns, columns)
+ self.assertEqual(expected_data, data)
+
def test_create_source_ip(self):
expected_columns, expected_data = self._setup_security_group_rule({
'ip_protocol': 'icmp',
@@ -620,6 +756,38 @@ class TestCreateSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
self.assertEqual(expected_columns, columns)
self.assertEqual(expected_data, data)
+ def test_create_remote_ip(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 = [
+ '--protocol', self._security_group_rule.ip_protocol,
+ '--remote-ip', self._security_group_rule.ip_range['cidr'],
+ self._security_group.id,
+ ]
+ verifylist = [
+ ('protocol', self._security_group_rule.ip_protocol),
+ ('remote_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',
@@ -942,6 +1110,60 @@ class TestListSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
self.assertEqual(self.expected_columns_no_group, columns)
self.assertEqual(self.expected_data_no_group, list(data))
+ def test_list_with_protocol(self):
+ self._security_group_rule_tcp.port_range_min = 80
+ arglist = [
+ '--protocol', 'tcp',
+ ]
+ verifylist = [
+ ('protocol', 'tcp'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.security_group_rules.assert_called_once_with(**{
+ 'protocol': 'tcp',
+ })
+ self.assertEqual(self.expected_columns_no_group, columns)
+ self.assertEqual(self.expected_data_no_group, list(data))
+
+ def test_list_with_ingress(self):
+ self._security_group_rule_tcp.port_range_min = 80
+ arglist = [
+ '--ingress',
+ ]
+ verifylist = [
+ ('ingress', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.security_group_rules.assert_called_once_with(**{
+ 'direction': 'ingress',
+ })
+ self.assertEqual(self.expected_columns_no_group, columns)
+ self.assertEqual(self.expected_data_no_group, list(data))
+
+ def test_list_with_wrong_egress(self):
+ self._security_group_rule_tcp.port_range_min = 80
+ arglist = [
+ '--egress',
+ ]
+ verifylist = [
+ ('egress', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.security_group_rules.assert_called_once_with(**{
+ 'direction': 'egress',
+ })
+ self.assertEqual(self.expected_columns_no_group, columns)
+ self.assertEqual(self.expected_data_no_group, list(data))
+
class TestListSecurityGroupRuleCompute(TestSecurityGroupRuleCompute):
@@ -1075,6 +1297,7 @@ class TestShowSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
network_fakes.FakeSecurityGroupRule.create_one_security_group_rule()
columns = (
+ 'description',
'direction',
'ethertype',
'id',
@@ -1088,6 +1311,7 @@ class TestShowSecurityGroupRuleNetwork(TestSecurityGroupRuleNetwork):
)
data = (
+ _security_group_rule.description,
_security_group_rule.direction,
_security_group_rule.ethertype,
_security_group_rule.id,
diff --git a/openstackclient/tests/unit/network/v2/test_subnet.py b/openstackclient/tests/unit/network/v2/test_subnet.py
index 2d51aa4a..47de5616 100644
--- a/openstackclient/tests/unit/network/v2/test_subnet.py
+++ b/openstackclient/tests/unit/network/v2/test_subnet.py
@@ -636,7 +636,7 @@ class TestListSubnet(TestSubnet):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'enable_dhcp': True}
+ filters = {'enable_dhcp': True, 'is_dhcp_enabled': True}
self.network.subnets.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -652,7 +652,7 @@ class TestListSubnet(TestSubnet):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'enable_dhcp': False}
+ filters = {'enable_dhcp': False, 'is_dhcp_enabled': False}
self.network.subnets.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -685,7 +685,7 @@ class TestListSubnet(TestSubnet):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'tenant_id': project.id}
+ filters = {'tenant_id': project.id, 'project_id': project.id}
self.network.subnets.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -723,7 +723,7 @@ class TestListSubnet(TestSubnet):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'tenant_id': project.id}
+ filters = {'tenant_id': project.id, 'project_id': project.id}
self.network.subnets.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -925,13 +925,16 @@ class TestSetSubnet(TestSubnet):
{'host_routes': [{'destination': '10.20.20.0/24',
'nexthop': '10.20.20.1'}],
'allocation_pools': [{'start': '8.8.8.200',
- 'end': '8.8.8.250'}], })
+ 'end': '8.8.8.250'}],
+ 'dns_nameservers': ["10.0.0.1"], })
self.network.find_subnet = mock.Mock(return_value=_testsubnet)
arglist = [
'--host-route', 'destination=10.30.30.30/24,gateway=10.30.30.1',
'--no-host-route',
'--allocation-pool', 'start=8.8.8.100,end=8.8.8.150',
'--no-allocation-pool',
+ '--dns-nameserver', '10.1.10.1',
+ '--no-dns-nameservers',
_testsubnet.name,
]
verifylist = [
@@ -939,6 +942,8 @@ class TestSetSubnet(TestSubnet):
"destination": "10.30.30.30/24", "gateway": "10.30.30.1"}]),
('allocation_pools', [{
'start': '8.8.8.100', 'end': '8.8.8.150'}]),
+ ('dns_nameservers', ['10.1.10.1']),
+ ('no_dns_nameservers', True),
('no_host_route', True),
('no_allocation_pool', True),
]
@@ -948,6 +953,7 @@ class TestSetSubnet(TestSubnet):
'host_routes': [{
"destination": "10.30.30.30/24", "nexthop": "10.30.30.1"}],
'allocation_pools': [{'start': '8.8.8.100', 'end': '8.8.8.150'}],
+ 'dns_nameservers': ["10.1.10.1"],
}
self.network.update_subnet.assert_called_once_with(
_testsubnet, **attrs)
diff --git a/openstackclient/tests/unit/network/v2/test_subnet_pool.py b/openstackclient/tests/unit/network/v2/test_subnet_pool.py
index fa6ffff3..f12537e7 100644
--- a/openstackclient/tests/unit/network/v2/test_subnet_pool.py
+++ b/openstackclient/tests/unit/network/v2/test_subnet_pool.py
@@ -435,7 +435,7 @@ class TestListSubnetPool(TestSubnetPool):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'shared': False}
+ filters = {'shared': False, 'is_shared': False}
self.network.subnet_pools.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -451,7 +451,7 @@ class TestListSubnetPool(TestSubnetPool):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'shared': True}
+ filters = {'shared': True, 'is_shared': True}
self.network.subnet_pools.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -501,7 +501,7 @@ class TestListSubnetPool(TestSubnetPool):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'tenant_id': project.id}
+ filters = {'tenant_id': project.id, 'project_id': project.id}
self.network.subnet_pools.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -521,7 +521,7 @@ class TestListSubnetPool(TestSubnetPool):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- filters = {'tenant_id': project.id}
+ filters = {'tenant_id': project.id, 'project_id': project.id}
self.network.subnet_pools.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
diff --git a/openstackclient/tests/unit/volume/v1/fakes.py b/openstackclient/tests/unit/volume/v1/fakes.py
index a11ea491..78a8227e 100644
--- a/openstackclient/tests/unit/volume/v1/fakes.py
+++ b/openstackclient/tests/unit/volume/v1/fakes.py
@@ -23,115 +23,6 @@ from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
from openstackclient.tests.unit import utils
-volume_id = 'vvvvvvvv-vvvv-vvvv-vvvvvvvv'
-volume_name = 'nigel'
-volume_description = 'Nigel Tufnel'
-volume_status = 'available'
-volume_size = 120
-volume_type = 'to-eleven'
-volume_zone = 'stonehenge'
-volume_metadata = {
- 'Alpha': 'a',
- 'Beta': 'b',
- 'Gamma': 'g',
-}
-volume_metadata_str = "Alpha='a', Beta='b', Gamma='g'"
-
-VOLUME = {
- 'id': volume_id,
- 'display_name': volume_name,
- 'display_description': volume_description,
- 'size': volume_size,
- 'status': volume_status,
- 'attach_status': 'detached',
- 'availability_zone': volume_zone,
- 'volume_type': volume_type,
- 'metadata': volume_metadata,
-}
-
-extension_name = 'SchedulerHints'
-extension_namespace = 'http://docs.openstack.org/'\
- 'block-service/ext/scheduler-hints/api/v2'
-extension_description = 'Pass arbitrary key/value'\
- 'pairs to the scheduler.'
-extension_updated = '2014-02-07T12:00:0-00:00'
-extension_alias = 'OS-SCH-HNT'
-extension_links = '[{"href":'\
- '"https://github.com/openstack/block-api", "type":'\
- ' "text/html", "rel": "describedby"}]'
-
-EXTENSION = {
- 'name': extension_name,
- 'namespace': extension_namespace,
- 'description': extension_description,
- 'updated': extension_updated,
- 'alias': extension_alias,
- 'links': extension_links,
-}
-
-# NOTE(dtroyer): duplicating here the minimum image info needed to test
-# volume create --image until circular references can be
-# avoided by refactoring the test fakes.
-
-image_id = 'im1'
-image_name = 'graven'
-
-
-IMAGE = {
- 'id': image_id,
- 'name': image_name,
-}
-
-type_id = "5520dc9e-6f9b-4378-a719-729911c0f407"
-type_name = "fake-lvmdriver-1"
-
-TYPE = {
- 'id': type_id,
- 'name': type_name
-}
-
-qos_id = '6f2be1de-997b-4230-b76c-a3633b59e8fb'
-qos_consumer = 'front-end'
-qos_default_consumer = 'both'
-qos_name = "fake-qos-specs"
-qos_specs = {
- 'foo': 'bar',
- 'iops': '9001'
-}
-qos_association = {
- 'association_type': 'volume_type',
- 'name': type_name,
- 'id': type_id
-}
-
-QOS = {
- 'id': qos_id,
- 'consumer': qos_consumer,
- 'name': qos_name
-}
-
-QOS_DEFAULT_CONSUMER = {
- 'id': qos_id,
- 'consumer': qos_default_consumer,
- 'name': qos_name
-}
-
-QOS_WITH_SPECS = {
- 'id': qos_id,
- 'consumer': qos_consumer,
- 'name': qos_name,
- 'specs': qos_specs
-}
-
-QOS_WITH_ASSOCIATIONS = {
- 'id': qos_id,
- 'consumer': qos_consumer,
- 'name': qos_name,
- 'specs': qos_specs,
- 'associations': [qos_association]
-}
-
-
class FakeTransfer(object):
"""Fake one or more Transfer."""
diff --git a/openstackclient/tests/unit/volume/v1/test_backup.py b/openstackclient/tests/unit/volume/v1/test_backup.py
index 32c2fd22..1097d3f1 100644
--- a/openstackclient/tests/unit/volume/v1/test_backup.py
+++ b/openstackclient/tests/unit/volume/v1/test_backup.py
@@ -249,26 +249,65 @@ class TestBackupList(TestBackup):
self.volumes_mock.list.return_value = [self.volume]
self.backups_mock.list.return_value = self.backups
+ self.volumes_mock.get.return_value = self.volume
# Get the command to test
self.cmd = backup.ListVolumeBackup(self.app, None)
def test_backup_list_without_options(self):
arglist = []
- verifylist = [("long", False)]
+ verifylist = [
+ ("long", False),
+ ("name", None),
+ ("status", None),
+ ("volume", None),
+ ('all_projects', False),
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ "name": None,
+ "status": None,
+ "volume_id": None,
+ "all_tenants": False,
+ }
+ self.volumes_mock.get.assert_not_called()
+ self.backups_mock.list.assert_called_with(
+ search_opts=search_opts,
+ )
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_backup_list_with_options(self):
- arglist = ["--long"]
- verifylist = [("long", True)]
+ arglist = [
+ "--long",
+ "--name", self.backups[0].name,
+ "--status", "error",
+ "--volume", self.volume.id,
+ "--all-projects"
+ ]
+ verifylist = [
+ ("long", True),
+ ("name", self.backups[0].name),
+ ("status", "error"),
+ ("volume", self.volume.id),
+ ('all_projects', True),
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ "name": self.backups[0].name,
+ "status": "error",
+ "volume_id": self.volume.id,
+ "all_tenants": True,
+ }
+ self.volumes_mock.get.assert_called_once_with(self.volume.id)
+ self.backups_mock.list.assert_called_with(
+ search_opts=search_opts,
+ )
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
diff --git a/openstackclient/tests/unit/volume/v1/test_type.py b/openstackclient/tests/unit/volume/v1/test_type.py
index 23a1186d..81ad8301 100644
--- a/openstackclient/tests/unit/volume/v1/test_type.py
+++ b/openstackclient/tests/unit/volume/v1/test_type.py
@@ -158,11 +158,13 @@ class TestTypeList(TestType):
columns = (
"ID",
- "Name"
+ "Name",
+ "Is Public",
)
columns_long = (
"ID",
"Name",
+ "Is Public",
"Properties"
)
@@ -171,12 +173,14 @@ class TestTypeList(TestType):
data.append((
t.id,
t.name,
+ t.is_public,
))
data_long = []
for t in volume_types:
data_long.append((
t.id,
t.name,
+ t.is_public,
utils.format_dict(t.extra_specs),
))
diff --git a/openstackclient/tests/unit/volume/v1/test_volume.py b/openstackclient/tests/unit/volume/v1/test_volume.py
index 73c00844..7a44dea8 100644
--- a/openstackclient/tests/unit/volume/v1/test_volume.py
+++ b/openstackclient/tests/unit/volume/v1/test_volume.py
@@ -14,15 +14,14 @@
#
import argparse
-import copy
import mock
from mock import call
from osc_lib import exceptions
from osc_lib import utils
-from openstackclient.tests.unit import fakes
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
+from openstackclient.tests.unit.image.v1 import fakes as image_fakes
from openstackclient.tests.unit import utils as tests_utils
from openstackclient.tests.unit.volume.v1 import fakes as volume_fakes
from openstackclient.volume.v1 import volume
@@ -58,10 +57,6 @@ class TestVolume(volume_fakes.TestVolumev1):
return volumes
-# TODO(dtroyer): The volume create tests are incomplete, only the minimal
-# options and the options that require additional processing
-# are implemented at this time.
-
class TestVolumeCreate(TestVolume):
project = identity_fakes.FakeProject.create_one_project()
@@ -321,19 +316,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.display_name,
]
verifylist = [
- ('image', volume_fakes.image_id),
+ ('image', image.id),
('size', self.new_volume.size),
('name', self.new_volume.display_name),
]
@@ -360,26 +352,23 @@ class TestVolumeCreate(TestVolume):
None,
None,
None,
- volume_fakes.image_id,
+ image.id,
)
self.assertEqual(self.columns, columns)
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.display_name,
]
verifylist = [
- ('image', volume_fakes.image_name),
+ ('image', image.name),
('size', self.new_volume.size),
('name', self.new_volume.display_name),
]
@@ -406,7 +395,7 @@ class TestVolumeCreate(TestVolume):
None,
None,
None,
- volume_fakes.image_id,
+ image.id,
)
self.assertEqual(self.columns, columns)
@@ -739,6 +728,68 @@ class TestVolumeList(TestVolume):
self.cmd, arglist, verifylist)
+class TestVolumeMigrate(TestVolume):
+
+ _volume = volume_fakes.FakeVolume.create_one_volume()
+
+ def setUp(self):
+ super(TestVolumeMigrate, self).setUp()
+
+ self.volumes_mock.get.return_value = self._volume
+ self.volumes_mock.migrate_volume.return_value = None
+ # Get the command object to test
+ self.cmd = volume.MigrateVolume(self.app, None)
+
+ def test_volume_migrate(self):
+ arglist = [
+ "--host", "host@backend-name#pool",
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", False),
+ ("host", "host@backend-name#pool"),
+ ("volume", self._volume.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.get.assert_called_once_with(self._volume.id)
+ self.volumes_mock.migrate_volume.assert_called_once_with(
+ self._volume.id, "host@backend-name#pool", False)
+ self.assertIsNone(result)
+
+ def test_volume_migrate_with_option(self):
+ arglist = [
+ "--force-host-copy",
+ "--host", "host@backend-name#pool",
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", True),
+ ("host", "host@backend-name#pool"),
+ ("volume", self._volume.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.get.assert_called_once_with(self._volume.id)
+ self.volumes_mock.migrate_volume.assert_called_once_with(
+ self._volume.id, "host@backend-name#pool", True)
+ self.assertIsNone(result)
+
+ def test_volume_migrate_without_host(self):
+ arglist = [
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", False),
+ ("volume", self._volume.id),
+ ]
+
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+
class TestVolumeSet(TestVolume):
_volume = volume_fakes.FakeVolume.create_one_volume()
@@ -844,8 +895,7 @@ class TestVolumeSet(TestVolume):
)
self.assertIsNone(result)
- @mock.patch.object(volume.LOG, 'error')
- def test_volume_set_size_smaller(self, mock_log_error):
+ def test_volume_set_size_smaller(self):
self._volume.status = 'available'
arglist = [
'--size', '1',
@@ -860,15 +910,11 @@ class TestVolumeSet(TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
-
- mock_log_error.assert_called_with("New size must be greater "
- "than %s GB",
- self._volume.size)
- self.assertIsNone(result)
+ self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
- @mock.patch.object(volume.LOG, 'error')
- def test_volume_set_size_not_available(self, mock_log_error):
+ def test_volume_set_size_not_available(self):
self._volume.status = 'error'
arglist = [
'--size', '130',
@@ -883,12 +929,9 @@ class TestVolumeSet(TestVolume):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
-
- mock_log_error.assert_called_with("Volume is in %s state, it must be "
- "available before size can be "
- "extended", 'error')
- self.assertIsNone(result)
+ self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action,
+ parsed_args)
def test_volume_set_property(self):
arglist = [
@@ -896,6 +939,8 @@ class TestVolumeSet(TestVolume):
self._volume.display_name,
]
verifylist = [
+ ('read_only', False),
+ ('read_write', False),
('name', None),
('description', None),
('size', None),
@@ -916,6 +961,7 @@ class TestVolumeSet(TestVolume):
self._volume.id,
metadata
)
+ self.volumes_mock.update_readonly_flag.assert_not_called()
self.assertIsNone(result)
def test_volume_set_bootable(self):
@@ -943,6 +989,44 @@ class TestVolumeSet(TestVolume):
self.volumes_mock.set_bootable.assert_called_with(
self._volume.id, verifylist[index][0][1])
+ def test_volume_set_readonly(self):
+ arglist = [
+ '--read-only',
+ self._volume.id
+ ]
+ verifylist = [
+ ('read_only', True),
+ ('read_write', False),
+ ('volume', self._volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self._volume.id,
+ True)
+ self.assertIsNone(result)
+
+ def test_volume_set_read_write(self):
+ arglist = [
+ '--read-write',
+ self._volume.id
+ ]
+ verifylist = [
+ ('read_only', False),
+ ('read_write', True),
+ ('volume', self._volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self._volume.id,
+ False)
+ self.assertIsNone(result)
+
class TestVolumeShow(TestVolume):
diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py
index 5e1d16e1..3137bfb0 100644
--- a/openstackclient/tests/unit/volume/v2/fakes.py
+++ b/openstackclient/tests/unit/volume/v2/fakes.py
@@ -224,6 +224,8 @@ class FakeVolumeClient(object):
self.quota_classes.resource_class = fakes.FakeResource(None, {})
self.consistencygroups = mock.Mock()
self.consistencygroups.resource_class = fakes.FakeResource(None, {})
+ self.cgsnapshots = mock.Mock()
+ self.cgsnapshots.resource_class = fakes.FakeResource(None, {})
self.auth_token = kwargs['token']
self.management_url = kwargs['endpoint']
@@ -248,10 +250,7 @@ class TestVolume(utils.TestCommand):
class FakeVolume(object):
- """Fake one or more volumes.
-
- TODO(xiexs): Currently, only volume API v2 is supported by this class.
- """
+ """Fake one or more volumes."""
@staticmethod
def create_one_volume(attrs=None):
@@ -547,6 +546,106 @@ class FakeConsistencyGroup(object):
return consistency_groups
+ @staticmethod
+ def get_consistency_groups(consistency_groups=None, count=2):
+ """Note:
+
+ Get an iterable MagicMock object with a list of faked
+ consistency_groups.
+
+ If consistency_groups list is provided, then initialize
+ the Mock object with the list. Otherwise create one.
+
+ :param List consistency_groups:
+ A list of FakeResource objects faking consistency_groups
+ :param Integer count:
+ The number of consistency_groups to be faked
+ :return
+ An iterable Mock object with side_effect set to a list of faked
+ consistency_groups
+ """
+ if consistency_groups is None:
+ consistency_groups = (FakeConsistencyGroup.
+ create_consistency_groups(count))
+
+ return mock.Mock(side_effect=consistency_groups)
+
+
+class FakeConsistencyGroupSnapshot(object):
+ """Fake one or more consistency group snapshot."""
+
+ @staticmethod
+ def create_one_consistency_group_snapshot(attrs=None):
+ """Create a fake consistency group snapshot.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object with id, name, description, etc.
+ """
+ attrs = attrs or {}
+
+ # Set default attributes.
+ consistency_group_snapshot_info = {
+ "id": 'id-' + uuid.uuid4().hex,
+ "name": 'backup-name-' + uuid.uuid4().hex,
+ "description": 'description-' + uuid.uuid4().hex,
+ "status": "error",
+ "consistencygroup_id": 'consistency-group-id' + uuid.uuid4().hex,
+ "created_at": 'time-' + uuid.uuid4().hex,
+ }
+
+ # Overwrite default attributes.
+ consistency_group_snapshot_info.update(attrs)
+
+ consistency_group_snapshot = fakes.FakeResource(
+ info=copy.deepcopy(consistency_group_snapshot_info),
+ loaded=True)
+ return consistency_group_snapshot
+
+ @staticmethod
+ def create_consistency_group_snapshots(attrs=None, count=2):
+ """Create multiple fake consistency group snapshots.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of consistency group snapshots to fake
+ :return:
+ A list of FakeResource objects faking the
+ consistency group snapshots
+ """
+ consistency_group_snapshots = []
+ for i in range(0, count):
+ consistency_group_snapshot = (
+ FakeConsistencyGroupSnapshot.
+ create_one_consistency_group_snapshot(attrs)
+ )
+ consistency_group_snapshots.append(consistency_group_snapshot)
+
+ return consistency_group_snapshots
+
+ @staticmethod
+ def get_consistency_group_snapshots(snapshots=None, count=2):
+ """Get an iterable MagicMock object with a list of faked cgsnapshots.
+
+ If consistenct group snapshots list is provided, then initialize
+ the Mock object with the list. Otherwise create one.
+
+ :param List snapshots:
+ A list of FakeResource objects faking consistency group snapshots
+ :param Integer count:
+ The number of consistency group snapshots to be faked
+ :return
+ An iterable Mock object with side_effect set to a list of faked
+ consistency groups
+ """
+ if snapshots is None:
+ snapshots = (FakeConsistencyGroupSnapshot.
+ create_consistency_group_snapshots(count))
+
+ return mock.Mock(side_effect=snapshots)
+
class FakeExtension(object):
"""Fake one or more extension."""
diff --git a/openstackclient/tests/unit/volume/v2/test_backup.py b/openstackclient/tests/unit/volume/v2/test_backup.py
index 306c9eb3..10e7aac5 100644
--- a/openstackclient/tests/unit/volume/v2/test_backup.py
+++ b/openstackclient/tests/unit/volume/v2/test_backup.py
@@ -280,26 +280,78 @@ class TestBackupList(TestBackup):
self.volumes_mock.list.return_value = [self.volume]
self.backups_mock.list.return_value = self.backups
+ self.volumes_mock.get.return_value = self.volume
+ self.backups_mock.get.return_value = self.backups[0]
# Get the command to test
self.cmd = backup.ListVolumeBackup(self.app, None)
def test_backup_list_without_options(self):
arglist = []
- verifylist = [("long", False)]
+ verifylist = [
+ ("long", False),
+ ("name", None),
+ ("status", None),
+ ("volume", None),
+ ("marker", None),
+ ("limit", None),
+ ('all_projects', False),
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ "name": None,
+ "status": None,
+ "volume_id": None,
+ 'all_tenants': False,
+ }
+ self.volumes_mock.get.assert_not_called()
+ self.backups_mock.get.assert_not_called()
+ self.backups_mock.list.assert_called_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
def test_backup_list_with_options(self):
- arglist = ["--long"]
- verifylist = [("long", True)]
+ arglist = [
+ "--long",
+ "--name", self.backups[0].name,
+ "--status", "error",
+ "--volume", self.volume.id,
+ "--marker", self.backups[0].id,
+ "--all-projects",
+ "--limit", "3",
+ ]
+ verifylist = [
+ ("long", True),
+ ("name", self.backups[0].name),
+ ("status", "error"),
+ ("volume", self.volume.id),
+ ("marker", self.backups[0].id),
+ ('all_projects', True),
+ ("limit", 3),
+ ]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ "name": self.backups[0].name,
+ "status": "error",
+ "volume_id": self.volume.id,
+ 'all_tenants': True,
+ }
+ self.volumes_mock.get.assert_called_once_with(self.volume.id)
+ self.backups_mock.get.assert_called_once_with(self.backups[0].id)
+ self.backups_mock.list.assert_called_with(
+ search_opts=search_opts,
+ marker=self.backups[0].id,
+ limit=3,
+ )
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
diff --git a/openstackclient/tests/unit/volume/v2/test_consistency_group.py b/openstackclient/tests/unit/volume/v2/test_consistency_group.py
index 00e1b60e..5beb6ef2 100644
--- a/openstackclient/tests/unit/volume/v2/test_consistency_group.py
+++ b/openstackclient/tests/unit/volume/v2/test_consistency_group.py
@@ -12,6 +12,10 @@
# under the License.
#
+import mock
+from mock import call
+
+from osc_lib import exceptions
from osc_lib import utils
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
@@ -28,6 +32,235 @@ class TestConsistencyGroup(volume_fakes.TestVolume):
self.app.client_manager.volume.consistencygroups)
self.consistencygroups_mock.reset_mock()
+ self.types_mock = self.app.client_manager.volume.volume_types
+ self.types_mock.reset_mock()
+
+
+class TestConsistencyGroupCreate(TestConsistencyGroup):
+
+ volume_type = volume_fakes.FakeType.create_one_type()
+ new_consistency_group = (
+ volume_fakes.FakeConsistencyGroup.create_one_consistency_group())
+
+ columns = (
+ 'availability_zone',
+ 'created_at',
+ 'description',
+ 'id',
+ 'name',
+ 'status',
+ 'volume_types',
+ )
+ data = (
+ new_consistency_group.availability_zone,
+ new_consistency_group.created_at,
+ new_consistency_group.description,
+ new_consistency_group.id,
+ new_consistency_group.name,
+ new_consistency_group.status,
+ new_consistency_group.volume_types,
+ )
+
+ def setUp(self):
+ super(TestConsistencyGroupCreate, self).setUp()
+ self.consistencygroups_mock.create.return_value = (
+ self.new_consistency_group)
+ self.consistencygroups_mock.create_from_src.return_value = (
+ self.new_consistency_group)
+ self.consistencygroups_mock.get.return_value = (
+ self.new_consistency_group)
+ self.types_mock.get.return_value = self.volume_type
+
+ # Get the command object to test
+ self.cmd = consistency_group.CreateConsistencyGroup(self.app, None)
+
+ def test_consistency_group_create(self):
+ arglist = [
+ '--volume-type', self.volume_type.id,
+ '--description', self.new_consistency_group.description,
+ '--availability-zone',
+ self.new_consistency_group.availability_zone,
+ self.new_consistency_group.name,
+ ]
+ verifylist = [
+ ('volume_type', self.volume_type.id),
+ ('description', self.new_consistency_group.description),
+ ('availability_zone',
+ self.new_consistency_group.availability_zone),
+ ('name', self.new_consistency_group.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.types_mock.get.assert_called_once_with(
+ self.volume_type.id)
+ self.consistencygroups_mock.get.assert_not_called()
+ self.consistencygroups_mock.create.assert_called_once_with(
+ self.volume_type.id,
+ name=self.new_consistency_group.name,
+ description=self.new_consistency_group.description,
+ availability_zone=self.new_consistency_group.availability_zone,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_consistency_group_create_without_name(self):
+ arglist = [
+ '--volume-type', self.volume_type.id,
+ '--description', self.new_consistency_group.description,
+ '--availability-zone',
+ self.new_consistency_group.availability_zone,
+ ]
+ verifylist = [
+ ('volume_type', self.volume_type.id),
+ ('description', self.new_consistency_group.description),
+ ('availability_zone',
+ self.new_consistency_group.availability_zone),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.types_mock.get.assert_called_once_with(
+ self.volume_type.id)
+ self.consistencygroups_mock.get.assert_not_called()
+ self.consistencygroups_mock.create.assert_called_once_with(
+ self.volume_type.id,
+ name=None,
+ description=self.new_consistency_group.description,
+ availability_zone=self.new_consistency_group.availability_zone,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_consistency_group_create_from_source(self):
+ arglist = [
+ '--consistency-group-source', self.new_consistency_group.id,
+ '--description', self.new_consistency_group.description,
+ self.new_consistency_group.name,
+ ]
+ verifylist = [
+ ('consistency_group_source', self.new_consistency_group.id),
+ ('description', self.new_consistency_group.description),
+ ('name', self.new_consistency_group.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.types_mock.get.assert_not_called()
+ self.consistencygroups_mock.get.assert_called_once_with(
+ self.new_consistency_group.id)
+ self.consistencygroups_mock.create_from_src.assert_called_with(
+ None,
+ self.new_consistency_group.id,
+ name=self.new_consistency_group.name,
+ description=self.new_consistency_group.description,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+
+class TestConsistencyGroupDelete(TestConsistencyGroup):
+
+ consistency_groups =\
+ volume_fakes.FakeConsistencyGroup.create_consistency_groups(count=2)
+
+ def setUp(self):
+ super(TestConsistencyGroupDelete, self).setUp()
+
+ self.consistencygroups_mock.get = volume_fakes.FakeConsistencyGroup.\
+ get_consistency_groups(self.consistency_groups)
+ self.consistencygroups_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = consistency_group.DeleteConsistencyGroup(self.app, None)
+
+ def test_consistency_group_delete(self):
+ arglist = [
+ self.consistency_groups[0].id
+ ]
+ verifylist = [
+ ("consistency_groups", [self.consistency_groups[0].id])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.consistencygroups_mock.delete.assert_called_with(
+ self.consistency_groups[0].id, False)
+ self.assertIsNone(result)
+
+ def test_consistency_group_delete_with_force(self):
+ arglist = [
+ '--force',
+ self.consistency_groups[0].id,
+ ]
+ verifylist = [
+ ('force', True),
+ ("consistency_groups", [self.consistency_groups[0].id])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.consistencygroups_mock.delete.assert_called_with(
+ self.consistency_groups[0].id, True)
+ self.assertIsNone(result)
+
+ def test_delete_multiple_consistency_groups(self):
+ arglist = []
+ for b in self.consistency_groups:
+ arglist.append(b.id)
+ verifylist = [
+ ('consistency_groups', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for b in self.consistency_groups:
+ calls.append(call(b.id, False))
+ self.consistencygroups_mock.delete.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+ def test_delete_multiple_consistency_groups_with_exception(self):
+ arglist = [
+ self.consistency_groups[0].id,
+ 'unexist_consistency_group',
+ ]
+ verifylist = [
+ ('consistency_groups', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ find_mock_result = [self.consistency_groups[0],
+ exceptions.CommandError]
+ with mock.patch.object(utils, 'find_resource',
+ side_effect=find_mock_result) as find_mock:
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 consistency groups failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.consistencygroups_mock,
+ self.consistency_groups[0].id)
+ find_mock.assert_any_call(self.consistencygroups_mock,
+ 'unexist_consistency_group')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.consistencygroups_mock.delete.assert_called_once_with(
+ self.consistency_groups[0].id, False
+ )
+
class TestConsistencyGroupList(TestConsistencyGroup):
@@ -120,3 +353,46 @@ class TestConsistencyGroupList(TestConsistencyGroup):
detailed=True, search_opts={'all_tenants': False})
self.assertEqual(self.columns_long, columns)
self.assertEqual(self.data_long, list(data))
+
+
+class TestConsistencyGroupShow(TestConsistencyGroup):
+ columns = (
+ 'availability_zone',
+ 'created_at',
+ 'description',
+ 'id',
+ 'name',
+ 'status',
+ 'volume_types',
+ )
+
+ def setUp(self):
+ super(TestConsistencyGroupShow, self).setUp()
+
+ self.consistency_group = (
+ volume_fakes.FakeConsistencyGroup.create_one_consistency_group())
+ self.data = (
+ self.consistency_group.availability_zone,
+ self.consistency_group.created_at,
+ self.consistency_group.description,
+ self.consistency_group.id,
+ self.consistency_group.name,
+ self.consistency_group.status,
+ self.consistency_group.volume_types,
+ )
+ self.consistencygroups_mock.get.return_value = self.consistency_group
+ self.cmd = consistency_group.ShowConsistencyGroup(self.app, None)
+
+ def test_consistency_group_show(self):
+ arglist = [
+ self.consistency_group.id
+ ]
+ verifylist = [
+ ("consistency_group", self.consistency_group.id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.consistencygroups_mock.get.assert_called_once_with(
+ self.consistency_group.id)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py b/openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py
new file mode 100644
index 00000000..3bfe93df
--- /dev/null
+++ b/openstackclient/tests/unit/volume/v2/test_consistency_group_snapshot.py
@@ -0,0 +1,351 @@
+#
+# 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 mock import call
+
+from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
+from openstackclient.volume.v2 import consistency_group_snapshot
+
+
+class TestConsistencyGroupSnapshot(volume_fakes.TestVolume):
+
+ def setUp(self):
+ super(TestConsistencyGroupSnapshot, self).setUp()
+
+ # Get a shortcut to the TransferManager Mock
+ self.cgsnapshots_mock = (
+ self.app.client_manager.volume.cgsnapshots)
+ self.cgsnapshots_mock.reset_mock()
+ self.consistencygroups_mock = (
+ self.app.client_manager.volume.consistencygroups)
+ self.consistencygroups_mock.reset_mock()
+
+
+class TestConsistencyGroupSnapshotCreate(TestConsistencyGroupSnapshot):
+
+ _consistency_group_snapshot = (
+ volume_fakes.
+ FakeConsistencyGroupSnapshot.
+ create_one_consistency_group_snapshot()
+ )
+ consistency_group = (
+ volume_fakes.FakeConsistencyGroup.create_one_consistency_group())
+
+ columns = (
+ 'consistencygroup_id',
+ 'created_at',
+ 'description',
+ 'id',
+ 'name',
+ 'status',
+ )
+ data = (
+ _consistency_group_snapshot.consistencygroup_id,
+ _consistency_group_snapshot.created_at,
+ _consistency_group_snapshot.description,
+ _consistency_group_snapshot.id,
+ _consistency_group_snapshot.name,
+ _consistency_group_snapshot.status,
+ )
+
+ def setUp(self):
+ super(TestConsistencyGroupSnapshotCreate, self).setUp()
+ self.cgsnapshots_mock.create.return_value = (
+ self._consistency_group_snapshot)
+ self.consistencygroups_mock.get.return_value = (
+ self.consistency_group)
+
+ # Get the command object to test
+ self.cmd = (consistency_group_snapshot.
+ CreateConsistencyGroupSnapshot(self.app, None))
+
+ def test_consistency_group_snapshot_create(self):
+ arglist = [
+ '--consistency-group', self.consistency_group.id,
+ '--description', self._consistency_group_snapshot.description,
+ self._consistency_group_snapshot.name,
+ ]
+ verifylist = [
+ ('consistency_group', self.consistency_group.id),
+ ('description', self._consistency_group_snapshot.description),
+ ('snapshot_name', self._consistency_group_snapshot.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.consistencygroups_mock.get.assert_called_once_with(
+ self.consistency_group.id)
+ self.cgsnapshots_mock.create.assert_called_once_with(
+ self.consistency_group.id,
+ name=self._consistency_group_snapshot.name,
+ description=self._consistency_group_snapshot.description,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_consistency_group_snapshot_create_no_consistency_group(self):
+ arglist = [
+ '--description', self._consistency_group_snapshot.description,
+ self._consistency_group_snapshot.name,
+ ]
+ verifylist = [
+ ('description', self._consistency_group_snapshot.description),
+ ('snapshot_name', self._consistency_group_snapshot.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.consistencygroups_mock.get.assert_called_once_with(
+ self._consistency_group_snapshot.name)
+ self.cgsnapshots_mock.create.assert_called_once_with(
+ self.consistency_group.id,
+ name=self._consistency_group_snapshot.name,
+ description=self._consistency_group_snapshot.description,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+
+class TestConsistencyGroupSnapshotDelete(TestConsistencyGroupSnapshot):
+
+ consistency_group_snapshots = (
+ volume_fakes.FakeConsistencyGroupSnapshot.
+ create_consistency_group_snapshots(count=2)
+ )
+
+ def setUp(self):
+ super(TestConsistencyGroupSnapshotDelete, self).setUp()
+
+ self.cgsnapshots_mock.get = (
+ volume_fakes.FakeConsistencyGroupSnapshot.
+ get_consistency_group_snapshots(self.consistency_group_snapshots)
+ )
+ self.cgsnapshots_mock.delete.return_value = None
+
+ # Get the command object to mock
+ self.cmd = (consistency_group_snapshot.
+ DeleteConsistencyGroupSnapshot(self.app, None))
+
+ def test_consistency_group_snapshot_delete(self):
+ arglist = [
+ self.consistency_group_snapshots[0].id
+ ]
+ verifylist = [
+ ("consistency_group_snapshot",
+ [self.consistency_group_snapshots[0].id])
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.cgsnapshots_mock.delete.assert_called_once_with(
+ self.consistency_group_snapshots[0].id)
+ self.assertIsNone(result)
+
+ def test_multiple_consistency_group_snapshots_delete(self):
+ arglist = []
+ for c in self.consistency_group_snapshots:
+ arglist.append(c.id)
+ verifylist = [
+ ('consistency_group_snapshot', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for c in self.consistency_group_snapshots:
+ calls.append(call(c.id))
+ self.cgsnapshots_mock.delete.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+
+class TestConsistencyGroupSnapshotList(TestConsistencyGroupSnapshot):
+
+ consistency_group_snapshots = (
+ volume_fakes.FakeConsistencyGroupSnapshot.
+ create_consistency_group_snapshots(count=2)
+ )
+ consistency_group = (
+ volume_fakes.FakeConsistencyGroup.create_one_consistency_group()
+ )
+
+ columns = [
+ 'ID',
+ 'Status',
+ 'Name',
+ ]
+ columns_long = [
+ 'ID',
+ 'Status',
+ 'ConsistencyGroup ID',
+ 'Name',
+ 'Description',
+ 'Created At',
+ ]
+ data = []
+ for c in consistency_group_snapshots:
+ data.append((
+ c.id,
+ c.status,
+ c.name,
+ ))
+ data_long = []
+ for c in consistency_group_snapshots:
+ data_long.append((
+ c.id,
+ c.status,
+ c.consistencygroup_id,
+ c.name,
+ c.description,
+ c.created_at,
+ ))
+
+ def setUp(self):
+ super(TestConsistencyGroupSnapshotList, self).setUp()
+
+ self.cgsnapshots_mock.list.return_value = (
+ self.consistency_group_snapshots)
+ self.consistencygroups_mock.get.return_value = self.consistency_group
+ # Get the command to test
+ self.cmd = (
+ consistency_group_snapshot.
+ ListConsistencyGroupSnapshot(self.app, None)
+ )
+
+ def test_consistency_group_snapshot_list_without_options(self):
+ arglist = []
+ verifylist = [
+ ("all_projects", False),
+ ("long", False),
+ ("status", None),
+ ("consistency_group", None),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ search_opts = {
+ 'all_tenants': False,
+ 'status': None,
+ 'consistencygroup_id': None,
+ }
+ self.cgsnapshots_mock.list.assert_called_once_with(
+ detailed=True, search_opts=search_opts)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_consistency_group_snapshot_list_with_long(self):
+ arglist = [
+ "--long",
+ ]
+ verifylist = [
+ ("all_projects", False),
+ ("long", True),
+ ("status", None),
+ ("consistency_group", None),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ search_opts = {
+ 'all_tenants': False,
+ 'status': None,
+ 'consistencygroup_id': None,
+ }
+ self.cgsnapshots_mock.list.assert_called_once_with(
+ detailed=True, search_opts=search_opts)
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
+
+ def test_consistency_group_snapshot_list_with_options(self):
+ arglist = [
+ "--all-project",
+ "--status", self.consistency_group_snapshots[0].status,
+ "--consistency-group", self.consistency_group.id,
+ ]
+ verifylist = [
+ ("all_projects", True),
+ ("long", False),
+ ("status", self.consistency_group_snapshots[0].status),
+ ("consistency_group", self.consistency_group.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ search_opts = {
+ 'all_tenants': True,
+ 'status': self.consistency_group_snapshots[0].status,
+ 'consistencygroup_id': self.consistency_group.id,
+ }
+ self.consistencygroups_mock.get.assert_called_once_with(
+ self.consistency_group.id)
+ self.cgsnapshots_mock.list.assert_called_once_with(
+ detailed=True, search_opts=search_opts)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+
+class TestConsistencyGroupSnapshotShow(TestConsistencyGroupSnapshot):
+
+ _consistency_group_snapshot = (
+ volume_fakes.
+ FakeConsistencyGroupSnapshot.
+ create_one_consistency_group_snapshot()
+ )
+
+ columns = (
+ 'consistencygroup_id',
+ 'created_at',
+ 'description',
+ 'id',
+ 'name',
+ 'status',
+ )
+ data = (
+ _consistency_group_snapshot.consistencygroup_id,
+ _consistency_group_snapshot.created_at,
+ _consistency_group_snapshot.description,
+ _consistency_group_snapshot.id,
+ _consistency_group_snapshot.name,
+ _consistency_group_snapshot.status,
+ )
+
+ def setUp(self):
+ super(TestConsistencyGroupSnapshotShow, self).setUp()
+
+ self.cgsnapshots_mock.get.return_value = (
+ self._consistency_group_snapshot)
+ self.cmd = (consistency_group_snapshot.
+ ShowConsistencyGroupSnapshot(self.app, None))
+
+ def test_consistency_group_snapshot_show(self):
+ arglist = [
+ self._consistency_group_snapshot.id
+ ]
+ verifylist = [
+ ("consistency_group_snapshot", self._consistency_group_snapshot.id)
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+ self.cgsnapshots_mock.get.assert_called_once_with(
+ self._consistency_group_snapshot.id)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/volume/v2/test_type.py b/openstackclient/tests/unit/volume/v2/test_type.py
index 84f87e3b..325872d7 100644
--- a/openstackclient/tests/unit/volume/v2/test_type.py
+++ b/openstackclient/tests/unit/volume/v2/test_type.py
@@ -165,7 +165,8 @@ class TestTypeList(TestType):
columns = [
"ID",
- "Name"
+ "Name",
+ "Is Public",
]
columns_long = columns + [
"Description",
@@ -177,12 +178,14 @@ class TestTypeList(TestType):
data.append((
t.id,
t.name,
+ t.is_public,
))
data_long = []
for t in volume_types:
data_long.append((
t.id,
t.name,
+ t.is_public,
t.description,
utils.format_dict(t.extra_specs),
))
diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index f4a7c142..41728342 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -46,6 +46,9 @@ class TestVolume(volume_fakes.TestVolume):
self.snapshots_mock = self.app.client_manager.volume.volume_snapshots
self.snapshots_mock.reset_mock()
+ self.types_mock = self.app.client_manager.volume.volume_types
+ self.types_mock.reset_mock()
+
self.consistencygroups_mock = (
self.app.client_manager.volume.consistencygroups)
self.consistencygroups_mock.reset_mock()
@@ -996,13 +999,106 @@ class TestVolumeList(TestVolume):
self.cmd, arglist, verifylist)
+class TestVolumeMigrate(TestVolume):
+
+ _volume = volume_fakes.FakeVolume.create_one_volume()
+
+ def setUp(self):
+ super(TestVolumeMigrate, self).setUp()
+
+ self.volumes_mock.get.return_value = self._volume
+ self.volumes_mock.migrate_volume.return_value = None
+ # Get the command object to test
+ self.cmd = volume.MigrateVolume(self.app, None)
+
+ def test_volume_migrate(self):
+ arglist = [
+ "--host", "host@backend-name#pool",
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", False),
+ ("lock_volume", False),
+ ("unlock_volume", False),
+ ("host", "host@backend-name#pool"),
+ ("volume", self._volume.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.get.assert_called_once_with(self._volume.id)
+ self.volumes_mock.migrate_volume.assert_called_once_with(
+ self._volume.id, "host@backend-name#pool", False, False)
+ self.assertIsNone(result)
+
+ def test_volume_migrate_with_option(self):
+ arglist = [
+ "--force-host-copy",
+ "--lock-volume",
+ "--host", "host@backend-name#pool",
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", True),
+ ("lock_volume", True),
+ ("unlock_volume", False),
+ ("host", "host@backend-name#pool"),
+ ("volume", self._volume.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.get.assert_called_once_with(self._volume.id)
+ self.volumes_mock.migrate_volume.assert_called_once_with(
+ self._volume.id, "host@backend-name#pool", True, True)
+ self.assertIsNone(result)
+
+ def test_volume_migrate_with_unlock_volume(self):
+ arglist = [
+ "--unlock-volume",
+ "--host", "host@backend-name#pool",
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", False),
+ ("lock_volume", False),
+ ("unlock_volume", True),
+ ("host", "host@backend-name#pool"),
+ ("volume", self._volume.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.get.assert_called_once_with(self._volume.id)
+ self.volumes_mock.migrate_volume.assert_called_once_with(
+ self._volume.id, "host@backend-name#pool", False, False)
+ self.assertIsNone(result)
+
+ def test_volume_migrate_without_host(self):
+ arglist = [
+ self._volume.id,
+ ]
+ verifylist = [
+ ("force_host_copy", False),
+ ("lock_volume", False),
+ ("unlock_volume", False),
+ ("volume", self._volume.id),
+ ]
+
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+
class TestVolumeSet(TestVolume):
+ volume_type = volume_fakes.FakeType.create_one_type()
+
def setUp(self):
super(TestVolumeSet, self).setUp()
self.new_volume = volume_fakes.FakeVolume.create_one_volume()
self.volumes_mock.get.return_value = self.new_volume
+ self.types_mock.get.return_value = self.volume_type
# Get the command object to test
self.cmd = volume.SetVolume(self.app, None)
@@ -1033,6 +1129,8 @@ class TestVolumeSet(TestVolume):
self.new_volume.id
]
verifylist = [
+ ('read_only', False),
+ ('read_write', False),
('state', 'error'),
('volume', self.new_volume.id)
]
@@ -1042,6 +1140,7 @@ class TestVolumeSet(TestVolume):
result = self.cmd.take_action(parsed_args)
self.volumes_mock.reset_state.assert_called_with(
self.new_volume.id, 'error')
+ self.volumes_mock.update_readonly_flag.assert_not_called()
self.assertIsNone(result)
def test_volume_set_state_failed(self):
@@ -1090,6 +1189,104 @@ class TestVolumeSet(TestVolume):
self.volumes_mock.set_bootable.assert_called_with(
self.new_volume.id, verifylist[index][0][1])
+ def test_volume_set_readonly(self):
+ arglist = [
+ '--read-only',
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('read_only', True),
+ ('read_write', False),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self.new_volume.id,
+ True)
+ self.assertIsNone(result)
+
+ def test_volume_set_read_write(self):
+ arglist = [
+ '--read-write',
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('read_only', False),
+ ('read_write', True),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.update_readonly_flag.assert_called_once_with(
+ self.new_volume.id,
+ False)
+ self.assertIsNone(result)
+
+ def test_volume_set_type(self):
+ arglist = [
+ '--type', self.volume_type.id,
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('retype_policy', None),
+ ('type', self.volume_type.id),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.retype.assert_called_once_with(
+ self.new_volume.id,
+ self.volume_type.id,
+ 'never')
+ self.assertIsNone(result)
+
+ def test_volume_set_type_with_policy(self):
+ arglist = [
+ '--retype-policy', 'on-demand',
+ '--type', self.volume_type.id,
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('retype_policy', 'on-demand'),
+ ('type', self.volume_type.id),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.retype.assert_called_once_with(
+ self.new_volume.id,
+ self.volume_type.id,
+ 'on-demand')
+ self.assertIsNone(result)
+
+ @mock.patch.object(volume.LOG, 'warning')
+ def test_volume_set_with_only_retype_policy(self, mock_warning):
+ arglist = [
+ '--retype-policy', 'on-demand',
+ self.new_volume.id
+ ]
+ verifylist = [
+ ('retype_policy', 'on-demand'),
+ ('volume', self.new_volume.id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.volumes_mock.retype.assert_not_called()
+ mock_warning.assert_called_with("'--retype-policy' option will "
+ "not work without '--type' option")
+ self.assertIsNone(result)
+
class TestVolumeShow(TestVolume):