summaryrefslogtreecommitdiff
path: root/openstackclient/tests
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/tests')
-rw-r--r--openstackclient/tests/functional/base.py32
-rw-r--r--openstackclient/tests/functional/common/test_help.py7
-rw-r--r--openstackclient/tests/functional/compute/v2/test_aggregate.py46
-rw-r--r--openstackclient/tests/functional/compute/v2/test_flavor.py227
-rw-r--r--openstackclient/tests/functional/identity/v2/common.py9
-rw-r--r--openstackclient/tests/functional/identity/v3/common.py11
-rw-r--r--openstackclient/tests/functional/identity/v3/test_idp.py3
-rw-r--r--openstackclient/tests/functional/image/v2/test_image.py22
-rw-r--r--openstackclient/tests/functional/network/v2/test_address_scope.py148
-rw-r--r--openstackclient/tests/functional/network/v2/test_floating_ip.py158
-rw-r--r--openstackclient/tests/functional/network/v2/test_meter.py102
-rw-r--r--openstackclient/tests/functional/network/v2/test_network.py292
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_qos_rule.py181
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py28
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_service_provider.py2
-rw-r--r--openstackclient/tests/functional/network/v2/test_port.py164
-rwxr-xr-xopenstackclient/tests/functional/post_test_hook_tips.sh47
-rw-r--r--openstackclient/tests/functional/volume/v2/test_qos.py4
-rw-r--r--openstackclient/tests/functional/volume/v2/test_snapshot.py239
-rw-r--r--openstackclient/tests/functional/volume/v2/test_volume.py305
-rw-r--r--openstackclient/tests/unit/api/test_image_v1.py2
-rw-r--r--openstackclient/tests/unit/api/test_image_v2.py2
-rw-r--r--openstackclient/tests/unit/common/test_quota.py72
-rw-r--r--openstackclient/tests/unit/compute/v2/fakes.py65
-rw-r--r--openstackclient/tests/unit/compute/v2/test_flavor.py5
-rw-r--r--openstackclient/tests/unit/compute/v2/test_server.py23
-rw-r--r--openstackclient/tests/unit/compute/v2/test_usage.py179
-rw-r--r--openstackclient/tests/unit/fakes.py9
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_project.py29
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_role.py27
-rw-r--r--openstackclient/tests/unit/identity/v2_0/test_user.py27
-rw-r--r--openstackclient/tests/unit/identity/v3/test_group.py27
-rw-r--r--openstackclient/tests/unit/identity/v3/test_mappings.py8
-rw-r--r--openstackclient/tests/unit/identity/v3/test_project.py27
-rw-r--r--openstackclient/tests/unit/identity/v3/test_role.py34
-rw-r--r--openstackclient/tests/unit/identity/v3/test_trust.py31
-rw-r--r--openstackclient/tests/unit/identity/v3/test_user.py29
-rw-r--r--openstackclient/tests/unit/image/v2/test_image.py100
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py255
-rw-r--r--openstackclient/tests/unit/network/v2/test_floating_ip.py90
-rw-r--r--openstackclient/tests/unit/network/v2/test_ip_availability.py10
-rw-r--r--openstackclient/tests/unit/network/v2/test_meter.py304
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_agent.py39
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_qos_rule.py1049
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py62
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_rbac.py64
-rw-r--r--openstackclient/tests/unit/network/v2/test_router.py63
-rw-r--r--openstackclient/tests/unit/network/v2/test_security_group.py4
-rw-r--r--openstackclient/tests/unit/volume/v2/fakes.py20
-rw-r--r--openstackclient/tests/unit/volume/v2/test_backup.py24
-rw-r--r--openstackclient/tests/unit/volume/v2/test_consistency_group.py206
-rw-r--r--openstackclient/tests/unit/volume/v2/test_qos_specs.py28
-rw-r--r--openstackclient/tests/unit/volume/v2/test_snapshot.py15
-rw-r--r--openstackclient/tests/unit/volume/v2/test_type.py58
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume.py117
55 files changed, 4647 insertions, 484 deletions
diff --git a/openstackclient/tests/functional/base.py b/openstackclient/tests/functional/base.py
index 885abc02..85743296 100644
--- a/openstackclient/tests/functional/base.py
+++ b/openstackclient/tests/functional/base.py
@@ -16,7 +16,6 @@ import shlex
import subprocess
import testtools
-import six
from tempest.lib.cli import output_parser
from tempest.lib import exceptions
@@ -77,29 +76,28 @@ class TestCase(testtools.TestCase):
if expected not in actual:
raise Exception(expected + ' not in ' + actual)
+ @classmethod
+ def assertsOutputNotNone(cls, observed):
+ if observed is None:
+ raise Exception('No output observed')
+
def assert_table_structure(self, items, field_names):
"""Verify that all items have keys listed in field_names."""
for item in items:
for field in field_names:
self.assertIn(field, item)
- def assert_show_fields(self, items, field_names):
+ def assert_show_fields(self, show_output, field_names):
"""Verify that all items have keys listed in field_names."""
- for item in items:
- for key in six.iterkeys(item):
- self.assertIn(key, field_names)
-
- def assert_show_structure(self, items, field_names):
- """Verify that all field_names listed in keys of all items."""
- if isinstance(items, list):
- o = {}
- for d in items:
- o.update(d)
- else:
- o = items
- item_keys = o.keys()
- for field in field_names:
- self.assertIn(field, item_keys)
+
+ # field_names = ['name', 'description']
+ # show_output = [{'name': 'fc2b98d8faed4126b9e371eda045ade2'},
+ # {'description': 'description-821397086'}]
+ # this next line creates a flattened list of all 'keys' (like 'name',
+ # and 'description' out of the output
+ all_headers = [item for sublist in show_output for item in sublist]
+ for field_name in field_names:
+ self.assertIn(field_name, all_headers)
def parse_show_as_object(self, raw_output):
"""Return a dict with values parsed from cli output."""
diff --git a/openstackclient/tests/functional/common/test_help.py b/openstackclient/tests/functional/common/test_help.py
index bbc52197..211c52b1 100644
--- a/openstackclient/tests/functional/common/test_help.py
+++ b/openstackclient/tests/functional/common/test_help.py
@@ -64,3 +64,10 @@ class HelpTests(base.TestCase):
raw_output = self.openstack('help server')
for command in [row[0] for row in self.SERVER_COMMANDS]:
self.assertIn(command, raw_output)
+
+ def test_networking_commands_help(self):
+ """Check networking related commands in help message."""
+ raw_output = self.openstack('help network list')
+ self.assertIn('List networks', raw_output)
+ raw_output = self.openstack('network create --help')
+ self.assertIn('Create new network', raw_output)
diff --git a/openstackclient/tests/functional/compute/v2/test_aggregate.py b/openstackclient/tests/functional/compute/v2/test_aggregate.py
index 2bc88e7b..38368103 100644
--- a/openstackclient/tests/functional/compute/v2/test_aggregate.py
+++ b/openstackclient/tests/functional/compute/v2/test_aggregate.py
@@ -48,7 +48,7 @@ class AggregateTests(base.TestCase):
self.assertEqual(self.NAME + "\n", raw_output)
def test_aggregate_properties(self):
- opts = self.get_opts(['properties'])
+ opts = self.get_opts(['name', 'properties'])
raw_output = self.openstack(
'aggregate set --property a=b --property c=d ' + self.NAME
@@ -56,7 +56,7 @@ class AggregateTests(base.TestCase):
self.assertEqual('', raw_output)
raw_output = self.openstack('aggregate show ' + self.NAME + opts)
- self.assertIn("a='b', c='d'\n", raw_output)
+ self.assertIn(self.NAME + "\na='b', c='d'\n", raw_output)
raw_output = self.openstack(
'aggregate unset --property a ' + self.NAME
@@ -64,4 +64,44 @@ class AggregateTests(base.TestCase):
self.assertEqual('', raw_output)
raw_output = self.openstack('aggregate show ' + self.NAME + opts)
- self.assertIn("c='d'\n", raw_output)
+ self.assertIn(self.NAME + "\nc='d'\n", raw_output)
+
+ raw_output = self.openstack(
+ 'aggregate set --property a=b --property c=d ' + self.NAME
+ )
+ self.assertEqual('', raw_output)
+
+ raw_output = self.openstack(
+ 'aggregate set --no-property ' + self.NAME
+ )
+ self.assertEqual('', raw_output)
+
+ raw_output = self.openstack('aggregate show ' + self.NAME + opts)
+ self.assertNotIn("a='b', c='d'", raw_output)
+
+ def test_aggregate_set(self):
+ opts = self.get_opts(["name", "availability_zone"])
+
+ raw_output = self.openstack(
+ 'aggregate set --zone Zone_1 ' + self.NAME)
+ self.assertEqual("", raw_output)
+
+ raw_output = self.openstack('aggregate show ' + self.NAME + opts)
+ self.assertEqual("Zone_1\n" + self.NAME + "\n", raw_output)
+
+ def test_aggregate_add_and_remove_host(self):
+ opts = self.get_opts(["hosts", "name"])
+
+ raw_output = self.openstack('host list -f value -c "Host Name"')
+ host_name = raw_output.split()[0]
+
+ self.openstack(
+ 'aggregate add host ' + self.NAME + ' ' + host_name)
+ raw_output = self.openstack('aggregate show ' + self.NAME + opts)
+ self.assertEqual("[u'" + host_name + "']" + "\n" + self.NAME + "\n",
+ raw_output)
+
+ self.openstack(
+ 'aggregate remove host ' + self.NAME + ' ' + host_name)
+ raw_output = self.openstack('aggregate show ' + self.NAME + opts)
+ self.assertEqual("[]\n" + self.NAME + "\n", raw_output)
diff --git a/openstackclient/tests/functional/compute/v2/test_flavor.py b/openstackclient/tests/functional/compute/v2/test_flavor.py
index 794a6cc3..0b01da51 100644
--- a/openstackclient/tests/functional/compute/v2/test_flavor.py
+++ b/openstackclient/tests/functional/compute/v2/test_flavor.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
import uuid
from openstackclient.tests.functional import base
@@ -18,52 +19,224 @@ from openstackclient.tests.functional import base
class FlavorTests(base.TestCase):
"""Functional tests for flavor."""
- NAME = uuid.uuid4().hex
- HEADERS = ['Name']
- FIELDS = ['name']
+ PROJECT_NAME = uuid.uuid4().hex
@classmethod
def setUpClass(cls):
- opts = cls.get_opts(cls.FIELDS)
- raw_output = cls.openstack(
- 'flavor create --property a=b --property c=d ' + cls.NAME + opts)
- expected = cls.NAME + '\n'
- cls.assertOutput(expected, raw_output)
+ # Make a project
+ cmd_output = json.loads(cls.openstack(
+ "project create -f json --enable " + cls.PROJECT_NAME
+ ))
+ cls.project_id = cmd_output["id"]
@classmethod
def tearDownClass(cls):
- raw_output = cls.openstack('flavor delete ' + cls.NAME)
+ raw_output = cls.openstack("project delete " + cls.PROJECT_NAME)
cls.assertOutput('', raw_output)
+ def test_flavor_delete(self):
+ """Test create w/project, delete multiple"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ "flavor create -f json " +
+ "--project " + self.PROJECT_NAME + " " +
+ "--private " +
+ name1
+ ))
+ self.assertIsNotNone(cmd_output["id"])
+
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ "flavor create -f json " +
+ "--id qaz " +
+ "--project " + self.PROJECT_NAME + " " +
+ "--private " +
+ name2
+ ))
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ "qaz",
+ cmd_output["id"],
+ )
+
+ raw_output = self.openstack(
+ "flavor delete " + name1 + " " + name2,
+ )
+ self.assertOutput('', raw_output)
+
def test_flavor_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('flavor list' + opts)
- self.assertIn("small", raw_output)
- self.assertIn(self.NAME, raw_output)
+ """Test create defaults, list filters, delete"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ "flavor create -f json " +
+ "--property a=b " +
+ "--property c=d " +
+ name1
+ ))
+ self.addCleanup(self.openstack, "flavor delete " + name1)
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ name1,
+ cmd_output["name"],
+ )
+
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ "flavor create -f json " +
+ "--id qaz " +
+ "--ram 123 " +
+ "--private " +
+ "--property a=b2 " +
+ "--property b=d2 " +
+ name2
+ ))
+ self.addCleanup(self.openstack, "flavor delete " + name2)
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ "qaz",
+ cmd_output["id"],
+ )
+ self.assertEqual(
+ name2,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ 123,
+ cmd_output["ram"],
+ )
+ self.assertEqual(
+ 0,
+ cmd_output["disk"],
+ )
+ self.assertEqual(
+ False,
+ cmd_output["os-flavor-access:is_public"],
+ )
+ self.assertEqual(
+ "a='b2', b='d2'",
+ cmd_output["properties"],
+ )
- def test_flavor_show(self):
- opts = self.get_opts(self.FIELDS)
- raw_output = self.openstack('flavor show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\n", raw_output)
+ # Test list
+ cmd_output = json.loads(self.openstack(
+ "flavor list -f json"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertNotIn(name2, col_name)
+
+ # Test list --long
+ cmd_output = json.loads(self.openstack(
+ "flavor list -f json " +
+ "--long"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ col_properties = [x['Properties'] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertIn("a='b', c='d'", col_properties)
+ self.assertNotIn(name2, col_name)
+ self.assertNotIn("b2', b='d2'", col_properties)
+
+ # Test list --public
+ cmd_output = json.loads(self.openstack(
+ "flavor list -f json " +
+ "--public"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertNotIn(name2, col_name)
+
+ # Test list --private
+ cmd_output = json.loads(self.openstack(
+ "flavor list -f json " +
+ "--private"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertNotIn(name1, col_name)
+ self.assertIn(name2, col_name)
+
+ # Test list --all
+ cmd_output = json.loads(self.openstack(
+ "flavor list -f json " +
+ "--all"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertIn(name2, col_name)
def test_flavor_properties(self):
- opts = self.get_opts(['properties'])
- # check the properties we added in create command.
- raw_output = self.openstack('flavor show ' + self.NAME + opts)
- self.assertEqual("a='b', c='d'\n", raw_output)
+ """Test create defaults, list filters, delete"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ "flavor create -f json " +
+ "--id qaz " +
+ "--ram 123 " +
+ "--disk 20 " +
+ "--private " +
+ "--property a=first " +
+ "--property b=second " +
+ name1
+ ))
+ self.addCleanup(self.openstack, "flavor delete " + name1)
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ "qaz",
+ cmd_output["id"],
+ )
+ self.assertEqual(
+ name1,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ 123,
+ cmd_output["ram"],
+ )
+ self.assertEqual(
+ 20,
+ cmd_output["disk"],
+ )
+ self.assertEqual(
+ False,
+ cmd_output["os-flavor-access:is_public"],
+ )
+ self.assertEqual(
+ "a='first', b='second'",
+ cmd_output["properties"],
+ )
raw_output = self.openstack(
- 'flavor set --property e=f --property g=h ' + self.NAME
+ "flavor set " +
+ "--property a='third and 10' " +
+ "--property g=fourth " +
+ name1
)
self.assertEqual('', raw_output)
- raw_output = self.openstack('flavor show ' + self.NAME + opts)
- self.assertEqual("a='b', c='d', e='f', g='h'\n", raw_output)
+ cmd_output = json.loads(self.openstack(
+ "flavor show -f json " +
+ name1
+ ))
+ self.assertEqual(
+ "qaz",
+ cmd_output["id"],
+ )
+ self.assertEqual(
+ "a='third and 10', b='second', g='fourth'",
+ cmd_output['properties'],
+ )
raw_output = self.openstack(
- 'flavor unset --property a --property c ' + self.NAME
+ "flavor unset " +
+ "--property b " +
+ name1
)
self.assertEqual('', raw_output)
- raw_output = self.openstack('flavor show ' + self.NAME + opts)
- self.assertEqual("e='f', g='h'\n", raw_output)
+ cmd_output = json.loads(self.openstack(
+ "flavor show -f json " +
+ name1
+ ))
+ self.assertEqual(
+ "a='third and 10', g='fourth'",
+ cmd_output["properties"],
+ )
diff --git a/openstackclient/tests/functional/identity/v2/common.py b/openstackclient/tests/functional/identity/v2/common.py
index b390c5bc..ad02f779 100644
--- a/openstackclient/tests/functional/identity/v2/common.py
+++ b/openstackclient/tests/functional/identity/v2/common.py
@@ -22,14 +22,13 @@ BASIC_LIST_HEADERS = ['ID', 'Name']
class IdentityTests(base.TestCase):
"""Functional tests for Identity commands. """
- USER_FIELDS = ['email', 'enabled', 'id', 'name', 'project_id',
- 'username', 'domain_id', 'default_project_id']
- PROJECT_FIELDS = ['enabled', 'id', 'name', 'description', 'domain_id']
+ USER_FIELDS = ['email', 'enabled', 'id', 'name', 'project_id', 'username']
+ PROJECT_FIELDS = ['enabled', 'id', 'name', 'description']
TOKEN_FIELDS = ['expires', 'id', 'project_id', 'user_id']
- ROLE_FIELDS = ['id', 'name', 'links', 'domain_id']
+ ROLE_FIELDS = ['id', 'name', 'domain_id']
SERVICE_FIELDS = ['id', 'enabled', 'name', 'type', 'description']
ENDPOINT_FIELDS = ['id', 'region', 'service_id', 'service_name',
- 'service_type', 'enabled', 'publicurl',
+ 'service_type', 'publicurl',
'adminurl', 'internalurl']
EC2_CREDENTIALS_FIELDS = ['access', 'project_id', 'secret',
diff --git a/openstackclient/tests/functional/identity/v3/common.py b/openstackclient/tests/functional/identity/v3/common.py
index 5dd42e70..a509574c 100644
--- a/openstackclient/tests/functional/identity/v3/common.py
+++ b/openstackclient/tests/functional/identity/v3/common.py
@@ -23,15 +23,15 @@ BASIC_LIST_HEADERS = ['ID', 'Name']
class IdentityTests(base.TestCase):
"""Functional tests for Identity commands. """
- DOMAIN_FIELDS = ['description', 'enabled', 'id', 'name', 'links']
- GROUP_FIELDS = ['description', 'domain_id', 'id', 'name', 'links']
+ DOMAIN_FIELDS = ['description', 'enabled', 'id', 'name']
+ GROUP_FIELDS = ['description', 'domain_id', 'id', 'name']
TOKEN_FIELDS = ['expires', 'id', 'project_id', 'user_id']
USER_FIELDS = ['email', 'enabled', 'id', 'name', 'name',
'domain_id', 'default_project_id', 'description',
'password_expires_at']
PROJECT_FIELDS = ['description', 'id', 'domain_id', 'is_domain',
- 'enabled', 'name', 'parent_id', 'links']
- ROLE_FIELDS = ['id', 'name', 'links', 'domain_id']
+ 'enabled', 'name', 'parent_id']
+ ROLE_FIELDS = ['id', 'name', 'domain_id']
SERVICE_FIELDS = ['id', 'enabled', 'name', 'type', 'description']
REGION_FIELDS = ['description', 'enabled', 'parent_region', 'region']
ENDPOINT_FIELDS = ['id', 'region', 'region_id', 'service_id',
@@ -42,7 +42,8 @@ class IdentityTests(base.TestCase):
ENDPOINT_LIST_HEADERS = ['ID', 'Region', 'Service Name', 'Service Type',
'Enabled', 'Interface', 'URL']
- IDENTITY_PROVIDER_FIELDS = ['description', 'enabled', 'id', 'remote_ids']
+ IDENTITY_PROVIDER_FIELDS = ['description', 'enabled', 'id', 'remote_ids',
+ 'domain_id']
IDENTITY_PROVIDER_LIST_HEADERS = ['ID', 'Enabled', 'Description']
SERVICE_PROVIDER_FIELDS = ['auth_url', 'description', 'enabled',
diff --git a/openstackclient/tests/functional/identity/v3/test_idp.py b/openstackclient/tests/functional/identity/v3/test_idp.py
index f9d8cb80..5db3610a 100644
--- a/openstackclient/tests/functional/identity/v3/test_idp.py
+++ b/openstackclient/tests/functional/identity/v3/test_idp.py
@@ -10,9 +10,10 @@
# License for the specific language governing permissions and limitations
# under the License.
-from openstackclient.tests.functional.identity.v3 import common
from tempest.lib.common.utils import data_utils
+from openstackclient.tests.functional.identity.v3 import common
+
class IdentityProviderTests(common.IdentityTests):
# Introduce functional test case for command 'Identity Provider'
diff --git a/openstackclient/tests/functional/image/v2/test_image.py b/openstackclient/tests/functional/image/v2/test_image.py
index 3f432b02..6faff94a 100644
--- a/openstackclient/tests/functional/image/v2/test_image.py
+++ b/openstackclient/tests/functional/image/v2/test_image.py
@@ -74,3 +74,25 @@ class ImageTests(base.TestCase):
self.openstack('image unset --property a --property c ' + self.NAME)
raw_output = self.openstack('image show ' + self.NAME + opts)
self.assertEqual(self.NAME + "\n\n", raw_output)
+
+ def test_image_members(self):
+ opts = self.get_opts(['project_id'])
+ my_project_id = self.openstack('token issue' + opts).strip()
+ self.openstack(
+ 'image add project {} {}'.format(self.NAME, my_project_id))
+
+ self.openstack(
+ 'image set --accept ' + self.NAME)
+ shared_img_list = self.parse_listing(
+ self.openstack('image list --shared', self.get_opts(['name']))
+ )
+ self.assertIn(self.NAME, [img['Name'] for img in shared_img_list])
+
+ self.openstack(
+ 'image set --reject ' + self.NAME)
+ shared_img_list = self.parse_listing(
+ self.openstack('image list --shared', self.get_opts(['name']))
+ )
+
+ self.openstack(
+ 'image remove project {} {}'.format(self.NAME, my_project_id))
diff --git a/openstackclient/tests/functional/network/v2/test_address_scope.py b/openstackclient/tests/functional/network/v2/test_address_scope.py
index ef4b5756..75f84344 100644
--- a/openstackclient/tests/functional/network/v2/test_address_scope.py
+++ b/openstackclient/tests/functional/network/v2/test_address_scope.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import re
import uuid
from openstackclient.tests.functional import base
@@ -17,33 +18,138 @@ from openstackclient.tests.functional import base
class AddressScopeTests(base.TestCase):
"""Functional tests for address scope. """
- NAME = uuid.uuid4().hex
- HEADERS = ['Name']
- FIELDS = ['name']
+
+ # NOTE(dtroyer): Do not normalize the setup and teardown of the resource
+ # creation and deletion. Little is gained when each test
+ # has its own needs and there are collisions when running
+ # tests in parallel.
@classmethod
def setUpClass(cls):
- opts = cls.get_opts(cls.FIELDS)
- raw_output = cls.openstack('address scope create ' + cls.NAME + opts)
- cls.assertOutput(cls.NAME + "\n", raw_output)
+ # Set up some regex for matching below
+ cls.re_name = re.compile("name\s+\|\s+([^|]+?)\s+\|")
+ cls.re_ip_version = re.compile("ip_version\s+\|\s+(\S+)")
+ cls.re_shared = re.compile("shared\s+\|\s+(\S+)")
- @classmethod
- def tearDownClass(cls):
- raw_output = cls.openstack('address scope delete ' + cls.NAME)
- cls.assertOutput('', raw_output)
+ def test_address_scope_delete(self):
+ """Test create, delete multiple"""
+ name1 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'address scope create ' + name1,
+ )
+ self.assertEqual(
+ name1,
+ re.search(self.re_name, raw_output).group(1),
+ )
+ # Check the default values
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+
+ name2 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'address scope create ' + name2,
+ )
+ self.assertEqual(
+ name2,
+ re.search(self.re_name, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'address scope delete ' + name1 + ' ' + name2,
+ )
+ self.assertOutput('', raw_output)
def test_address_scope_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('address scope list' + opts)
- self.assertIn(self.NAME, raw_output)
+ """Test create defaults, list filters, delete"""
+ name1 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'address scope create --ip-version 4 --share ' + name1,
+ )
+ self.addCleanup(self.openstack, 'address scope delete ' + name1)
+ self.assertEqual(
+ '4',
+ re.search(self.re_ip_version, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'True',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+
+ name2 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'address scope create --ip-version 6 --no-share ' + name2,
+ )
+ self.addCleanup(self.openstack, 'address scope delete ' + name2)
+ self.assertEqual(
+ '6',
+ re.search(self.re_ip_version, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1),
+ )
- def test_address_scope_show(self):
- opts = self.get_opts(self.FIELDS)
- raw_output = self.openstack('address scope show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\n", raw_output)
+ # Test list
+ raw_output = self.openstack('address scope list')
+ self.assertIsNotNone(re.search(name1 + "\s+\|\s+4", raw_output))
+ self.assertIsNotNone(re.search(name2 + "\s+\|\s+6", raw_output))
+
+ # Test list --share
+ # TODO(dtroyer): returns 'HttpException: Bad Request'
+ # raw_output = self.openstack('address scope list --share')
+ # self.assertIsNotNone(re.search(name1 + "\s+\|\s+4", raw_output))
+ # self.assertIsNotNone(re.search(name2 + "\s+\|\s+6", raw_output))
+
+ # Test list --no-share
+ # TODO(dtroyer): returns 'HttpException: Bad Request'
+ # raw_output = self.openstack('address scope list --no-share')
+ # self.assertIsNotNone(re.search(name1 + "\s+\|\s+4", raw_output))
+ # self.assertIsNotNone(re.search(name2 + "\s+\|\s+6", raw_output))
def test_address_scope_set(self):
- self.openstack('address scope set --share ' + self.NAME)
- opts = self.get_opts(['shared'])
- raw_output = self.openstack('address scope show ' + self.NAME + opts)
- self.assertEqual("True\n", raw_output)
+ """Tests create options, set, show, delete"""
+ name = uuid.uuid4().hex
+ newname = name + "_"
+ raw_output = self.openstack(
+ 'address scope create ' +
+ '--ip-version 4 ' +
+ '--no-share ' +
+ name,
+ )
+ self.addCleanup(self.openstack, 'address scope delete ' + newname)
+ self.assertEqual(
+ name,
+ re.search(self.re_name, raw_output).group(1),
+ )
+ self.assertEqual(
+ '4',
+ re.search(self.re_ip_version, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'address scope set ' +
+ '--name ' + newname +
+ ' --share ' +
+ name,
+ )
+ self.assertOutput('', raw_output)
+
+ raw_output = self.openstack('address scope show ' + newname)
+ self.assertEqual(
+ newname,
+ re.search(self.re_name, raw_output).group(1),
+ )
+ self.assertEqual(
+ '4',
+ re.search(self.re_ip_version, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'True',
+ re.search(self.re_shared, raw_output).group(1),
+ )
diff --git a/openstackclient/tests/functional/network/v2/test_floating_ip.py b/openstackclient/tests/functional/network/v2/test_floating_ip.py
index f3a1971f..8fbec3d5 100644
--- a/openstackclient/tests/functional/network/v2/test_floating_ip.py
+++ b/openstackclient/tests/functional/network/v2/test_floating_ip.py
@@ -10,49 +10,161 @@
# License for the specific language governing permissions and limitations
# under the License.
+import random
+import re
import uuid
from openstackclient.tests.functional import base
class FloatingIpTests(base.TestCase):
- """Functional tests for floating ip. """
+ """Functional tests for floating ip"""
SUBNET_NAME = uuid.uuid4().hex
NETWORK_NAME = uuid.uuid4().hex
- ID = None
- HEADERS = ['ID']
- FIELDS = ['id']
@classmethod
def setUpClass(cls):
- # Create a network for the floating ip.
- cls.openstack('network create --external ' + cls.NETWORK_NAME)
- # Create a subnet for the network.
- cls.openstack(
- 'subnet create --network ' + cls.NETWORK_NAME +
- ' --subnet-range 10.10.10.0/24 ' +
- cls.SUBNET_NAME
- )
- opts = cls.get_opts(cls.FIELDS)
+ # Set up some regex for matching below
+ cls.re_id = re.compile("id\s+\|\s+(\S+)")
+ cls.re_floating_ip = re.compile("floating_ip_address\s+\|\s+(\S+)")
+ cls.re_fixed_ip = re.compile("fixed_ip_address\s+\|\s+(\S+)")
+ cls.re_description = re.compile("description\s+\|\s+([^|]+?)\s+\|")
+ cls.re_network_id = re.compile("floating_network_id\s+\|\s+(\S+)")
+
+ # Create a network for the floating ip
raw_output = cls.openstack(
- 'floating ip create ' + cls.NETWORK_NAME + opts)
- cls.ID = raw_output.strip('\n')
+ 'network create --external ' + cls.NETWORK_NAME
+ )
+ cls.network_id = re.search(cls.re_id, raw_output).group(1)
+
+ # Try random subnet range for subnet creating
+ # Because we can not determine ahead of time what subnets are already
+ # in use, possibly by another test running in parallel, try 4 times
+ for i in range(4):
+ # Make a random subnet
+ cls.subnet = ".".join(map(
+ str,
+ (random.randint(0, 223) for _ in range(3))
+ )) + ".0/26"
+ try:
+ # Create a subnet for the network
+ raw_output = cls.openstack(
+ 'subnet create ' +
+ '--network ' + cls.NETWORK_NAME + ' ' +
+ '--subnet-range ' + cls.subnet + ' ' +
+ cls.SUBNET_NAME
+ )
+ except Exception:
+ if (i == 3):
+ # raise the exception at the last time
+ raise
+ pass
+ else:
+ # break and no longer retry if create sucessfully
+ break
+
+ cls.subnet_id = re.search(cls.re_id, raw_output).group(1)
@classmethod
def tearDownClass(cls):
- raw_output = cls.openstack('floating ip delete ' + cls.ID)
- cls.assertOutput('', raw_output)
raw_output = cls.openstack('subnet delete ' + cls.SUBNET_NAME)
cls.assertOutput('', raw_output)
raw_output = cls.openstack('network delete ' + cls.NETWORK_NAME)
cls.assertOutput('', raw_output)
+ def test_floating_ip_delete(self):
+ """Test create, delete multiple"""
+ raw_output = self.openstack(
+ 'floating ip create ' +
+ '--description aaaa ' +
+ self.NETWORK_NAME
+ )
+ re_ip = re.search(self.re_floating_ip, raw_output)
+ self.assertIsNotNone(re_ip)
+ ip1 = re_ip.group(1)
+ self.assertEqual(
+ 'aaaa',
+ re.search(self.re_description, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'floating ip create ' +
+ '--description bbbb ' +
+ self.NETWORK_NAME
+ )
+ ip2 = re.search(self.re_floating_ip, raw_output).group(1)
+ self.assertEqual(
+ 'bbbb',
+ re.search(self.re_description, raw_output).group(1),
+ )
+
+ # Clean up after ourselves
+ raw_output = self.openstack('floating ip delete ' + ip1 + ' ' + ip2)
+ self.assertOutput('', raw_output)
+
def test_floating_ip_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('floating ip list' + opts)
- self.assertIn(self.ID, raw_output)
+ """Test create defaults, list filters, delete"""
+ raw_output = self.openstack(
+ 'floating ip create ' +
+ '--description aaaa ' +
+ self.NETWORK_NAME
+ )
+ re_ip = re.search(self.re_floating_ip, raw_output)
+ self.assertIsNotNone(re_ip)
+ ip1 = re_ip.group(1)
+ self.addCleanup(self.openstack, 'floating ip delete ' + ip1)
+ self.assertEqual(
+ 'aaaa',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertIsNotNone(re.search(self.re_network_id, raw_output))
+
+ raw_output = self.openstack(
+ 'floating ip create ' +
+ '--description bbbb ' +
+ self.NETWORK_NAME
+ )
+ ip2 = re.search(self.re_floating_ip, raw_output).group(1)
+ self.addCleanup(self.openstack, 'floating ip delete ' + ip2)
+ self.assertEqual(
+ 'bbbb',
+ re.search(self.re_description, raw_output).group(1),
+ )
+
+ # Test list
+ raw_output = self.openstack('floating ip list')
+ self.assertIsNotNone(re.search("\|\s+" + ip1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + ip2 + "\s+\|", raw_output))
+
+ # Test list --long
+ raw_output = self.openstack('floating ip list --long')
+ self.assertIsNotNone(re.search("\|\s+" + ip1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + ip2 + "\s+\|", raw_output))
+
+ # TODO(dtroyer): add more filter tests
def test_floating_ip_show(self):
- opts = self.get_opts(self.FIELDS)
- raw_output = self.openstack('floating ip show ' + self.ID + opts)
- self.assertEqual(self.ID + "\n", raw_output)
+ """Test show"""
+ raw_output = self.openstack(
+ 'floating ip create ' +
+ '--description shosho ' +
+ # '--fixed-ip-address 1.2.3.4 ' +
+ self.NETWORK_NAME
+ )
+ re_ip = re.search(self.re_floating_ip, raw_output)
+ self.assertIsNotNone(re_ip)
+ ip = re_ip.group(1)
+
+ raw_output = self.openstack('floating ip show ' + ip)
+ self.addCleanup(self.openstack, 'floating ip delete ' + ip)
+
+ self.assertEqual(
+ 'shosho',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ # TODO(dtroyer): not working???
+ # self.assertEqual(
+ # '1.2.3.4',
+ # re.search(self.re_floating_ip, raw_output).group(1),
+ # )
+ self.assertIsNotNone(re.search(self.re_network_id, raw_output))
diff --git a/openstackclient/tests/functional/network/v2/test_meter.py b/openstackclient/tests/functional/network/v2/test_meter.py
new file mode 100644
index 00000000..7dce34e7
--- /dev/null
+++ b/openstackclient/tests/functional/network/v2/test_meter.py
@@ -0,0 +1,102 @@
+# 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 re
+import uuid
+
+from openstackclient.tests.functional import base
+
+
+class TestMeter(base.TestCase):
+ """Functional tests for network meter."""
+
+ # NOTE(dtroyer): Do not normalize the setup and teardown of the resource
+ # creation and deletion. Little is gained when each test
+ # has its own needs and there are collisions when running
+ # tests in parallel.
+
+ @classmethod
+ def setUpClass(cls):
+ # Set up some regex for matching below
+ cls.re_name = re.compile("name\s+\|\s+([^|]+?)\s+\|")
+ cls.re_shared = re.compile("shared\s+\|\s+(\S+)")
+ cls.re_description = re.compile("description\s+\|\s+([^|]+?)\s+\|")
+
+ def test_meter_delete(self):
+ """Test create, delete multiple"""
+ name1 = uuid.uuid4().hex
+ name2 = uuid.uuid4().hex
+
+ raw_output = self.openstack(
+ 'network meter create ' + name1,
+ )
+ self.assertEqual(
+ name1,
+ re.search(self.re_name, raw_output).group(1),
+ )
+ # Check if default shared values
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1)
+ )
+
+ raw_output = self.openstack(
+ 'network meter create ' + name2,
+ )
+ self.assertEqual(
+ name2,
+ re.search(self.re_name, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'network meter delete ' + name1 + ' ' + name2,
+ )
+ self.assertOutput('', raw_output)
+
+ def test_meter_list(self):
+ """Test create, list filters, delete"""
+ name1 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'network meter create --description Test1 --share ' + name1,
+ )
+ self.addCleanup(self.openstack, 'network meter delete ' + name1)
+
+ self.assertEqual(
+ 'Test1',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'True',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+
+ name2 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'network meter create --description Test2 --no-share ' + name2,
+ )
+ self.addCleanup(self.openstack, 'network meter delete ' + name2)
+
+ self.assertEqual(
+ 'Test2',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+
+ raw_output = self.openstack('network meter list')
+ self.assertIsNotNone(re.search(name1 + "\s+\|\s+Test1", raw_output))
+ self.assertIsNotNone(re.search(name2 + "\s+\|\s+Test2", raw_output))
diff --git a/openstackclient/tests/functional/network/v2/test_network.py b/openstackclient/tests/functional/network/v2/test_network.py
index c77ff642..c55d70f9 100644
--- a/openstackclient/tests/functional/network/v2/test_network.py
+++ b/openstackclient/tests/functional/network/v2/test_network.py
@@ -10,41 +10,277 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
import uuid
from openstackclient.tests.functional import base
class NetworkTests(base.TestCase):
- """Functional tests for network. """
- NAME = uuid.uuid4().hex
- HEADERS = ['Name']
- FIELDS = ['name']
-
- @classmethod
- def setUpClass(cls):
- opts = cls.get_opts(cls.FIELDS)
- raw_output = cls.openstack('network create ' + cls.NAME + opts)
- expected = cls.NAME + '\n'
- cls.assertOutput(expected, raw_output)
-
- @classmethod
- def tearDownClass(cls):
- raw_output = cls.openstack('network delete ' + cls.NAME)
- cls.assertOutput('', raw_output)
+ """Functional tests for network"""
+
+ def test_network_delete(self):
+ """Test create, delete multiple"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'network create -f json ' +
+ '--description aaaa ' +
+ name1
+ ))
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ 'aaaa',
+ cmd_output["description"],
+ )
+
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'network create -f json ' +
+ '--description bbbb ' +
+ name2
+ ))
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ 'bbbb',
+ cmd_output["description"],
+ )
+
+ del_output = self.openstack('network delete ' + name1 + ' ' + name2)
+ self.assertOutput('', del_output)
def test_network_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('network list' + opts)
- self.assertIn(self.NAME, raw_output)
+ """Test create defaults, list filters, delete"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'network create -f json ' +
+ '--description aaaa ' +
+ name1
+ ))
+ self.addCleanup(self.openstack, 'network delete ' + name1)
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ 'aaaa',
+ cmd_output["description"],
+ )
+ # Check the default values
+ self.assertEqual(
+ 'UP',
+ cmd_output["admin_state_up"],
+ )
+ self.assertEqual(
+ False,
+ cmd_output["shared"],
+ )
+ self.assertEqual(
+ 'Internal',
+ cmd_output["router:external"],
+ )
+ # NOTE(dtroyer): is_default is not present in the create output
+ # so make sure it stays that way.
+ # NOTE(stevemar): is_default *is* present in SDK 0.9.11 and newer,
+ # but the value seems to always be None, regardless
+ # of the --default or --no-default value.
+ # self.assertEqual('x', cmd_output)
+ if ('is_default' in cmd_output):
+ self.assertEqual(
+ None,
+ cmd_output["is_default"],
+ )
+ self.assertEqual(
+ True,
+ cmd_output["port_security_enabled"],
+ )
+
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'network create -f json ' +
+ '--description bbbb ' +
+ '--disable ' +
+ '--share ' +
+ name2
+ ))
+ self.addCleanup(self.openstack, 'network delete ' + name2)
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ 'bbbb',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ 'DOWN',
+ cmd_output["admin_state_up"],
+ )
+ self.assertEqual(
+ True,
+ cmd_output["shared"],
+ )
+ if ('is_default' in cmd_output):
+ self.assertEqual(
+ None,
+ cmd_output["is_default"],
+ )
+ self.assertEqual(
+ True,
+ cmd_output["port_security_enabled"],
+ )
+
+ # Test list --long
+ cmd_output = json.loads(self.openstack(
+ "network list -f json " +
+ "--long"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertIn(name2, col_name)
+
+ # Test list --long --enable
+ cmd_output = json.loads(self.openstack(
+ "network list -f json " +
+ "--enable " +
+ "--long"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertNotIn(name2, col_name)
+
+ # Test list --long --disable
+ cmd_output = json.loads(self.openstack(
+ "network list -f json " +
+ "--disable " +
+ "--long"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertNotIn(name1, col_name)
+ self.assertIn(name2, col_name)
+
+ # Test list --long --share
+ cmd_output = json.loads(self.openstack(
+ "network list -f json " +
+ "--share " +
+ "--long"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertNotIn(name1, col_name)
+ self.assertIn(name2, col_name)
+
+ # Test list --long --no-share
+ cmd_output = json.loads(self.openstack(
+ "network list -f json " +
+ "--no-share " +
+ "--long"
+ ))
+ col_name = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, col_name)
+ self.assertNotIn(name2, col_name)
def test_network_set(self):
- raw_output = self.openstack('network set --disable ' + self.NAME)
- opts = self.get_opts(['name', 'admin_state_up'])
- raw_output = self.openstack('network show ' + self.NAME + opts)
- self.assertEqual("DOWN\n" + self.NAME + "\n", raw_output)
-
- def test_network_show(self):
- opts = self.get_opts(self.FIELDS)
- raw_output = self.openstack('network show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\n", raw_output)
+ """Tests create options, set, show, delete"""
+ name = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'network create -f json ' +
+ '--description aaaa ' +
+ '--enable ' +
+ '--no-share ' +
+ '--internal ' +
+ '--no-default ' +
+ '--enable-port-security ' +
+ name
+ ))
+ self.addCleanup(self.openstack, 'network delete ' + name)
+ self.assertIsNotNone(cmd_output["id"])
+ self.assertEqual(
+ 'aaaa',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ 'UP',
+ cmd_output["admin_state_up"],
+ )
+ self.assertEqual(
+ False,
+ cmd_output["shared"],
+ )
+ self.assertEqual(
+ 'Internal',
+ cmd_output["router:external"],
+ )
+ # NOTE(dtroyer): is_default is not present in the create output
+ # so make sure it stays that way.
+ # NOTE(stevemar): is_default *is* present in SDK 0.9.11 and newer,
+ # but the value seems to always be None, regardless
+ # of the --default or --no-default value.
+ if ('is_default' in cmd_output):
+ self.assertEqual(
+ None,
+ cmd_output["is_default"],
+ )
+ self.assertEqual(
+ True,
+ cmd_output["port_security_enabled"],
+ )
+
+ raw_output = self.openstack(
+ 'network set ' +
+ '--description cccc ' +
+ '--disable ' +
+ '--share ' +
+ '--external ' +
+ '--disable-port-security ' +
+ name
+ )
+ self.assertOutput('', raw_output)
+
+ cmd_output = json.loads(self.openstack(
+ 'network show -f json ' + name
+ ))
+
+ self.assertEqual(
+ 'cccc',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ 'DOWN',
+ cmd_output["admin_state_up"],
+ )
+ self.assertEqual(
+ True,
+ cmd_output["shared"],
+ )
+ self.assertEqual(
+ 'External',
+ cmd_output["router:external"],
+ )
+ # why not 'None' like above??
+ self.assertEqual(
+ False,
+ cmd_output["is_default"],
+ )
+ self.assertEqual(
+ False,
+ cmd_output["port_security_enabled"],
+ )
+
+ # NOTE(dtroyer): There is ambiguity around is_default in that
+ # it is not in the API docs and apparently can
+ # not be set when the network is --external,
+ # although the option handling code only looks at
+ # the value of is_default when external is True.
+ raw_output = self.openstack(
+ 'network set ' +
+ '--default ' +
+ name
+ )
+ self.assertOutput('', raw_output)
+
+ cmd_output = json.loads(self.openstack(
+ 'network show -f json ' + name
+ ))
+
+ self.assertEqual(
+ 'cccc',
+ cmd_output["description"],
+ )
+ # NOTE(dtroyer): This should be 'True'
+ self.assertEqual(
+ False,
+ cmd_output["port_security_enabled"],
+ )
diff --git a/openstackclient/tests/functional/network/v2/test_network_qos_rule.py b/openstackclient/tests/functional/network/v2/test_network_qos_rule.py
new file mode 100644
index 00000000..af0c9bac
--- /dev/null
+++ b/openstackclient/tests/functional/network/v2/test_network_qos_rule.py
@@ -0,0 +1,181 @@
+# 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 uuid
+
+from openstackclient.tests.functional import base
+
+
+class NetworkQosRuleTestsMinimumBandwidth(base.TestCase):
+ """Functional tests for QoS minimum bandwidth rule."""
+ RULE_ID = None
+ QOS_POLICY_NAME = 'qos_policy_' + uuid.uuid4().hex
+ MIN_KBPS = 2800
+ MIN_KBPS_MODIFIED = 7500
+ DIRECTION = '--egress'
+ HEADERS = ['ID']
+ FIELDS = ['id']
+ TYPE = 'minimum-bandwidth'
+
+ @classmethod
+ def setUpClass(cls):
+ opts = cls.get_opts(cls.FIELDS)
+ cls.openstack('network qos policy create ' + cls.QOS_POLICY_NAME)
+ cls.RULE_ID = cls.openstack('network qos rule create --type ' +
+ cls.TYPE + ' --min-kbps ' +
+ str(cls.MIN_KBPS) + ' ' + cls.DIRECTION +
+ ' ' + cls.QOS_POLICY_NAME + opts)
+ cls.assertsOutputNotNone(cls.RULE_ID)
+
+ @classmethod
+ def tearDownClass(cls):
+ raw_output = cls.openstack('network qos rule delete ' +
+ cls.QOS_POLICY_NAME + ' ' + cls.RULE_ID)
+ cls.openstack('network qos policy delete ' + cls.QOS_POLICY_NAME)
+ cls.assertOutput('', raw_output)
+
+ def test_qos_policy_list(self):
+ opts = self.get_opts(self.HEADERS)
+ raw_output = self.openstack('network qos rule list '
+ + self.QOS_POLICY_NAME + opts)
+ self.assertIn(self.RULE_ID, raw_output)
+
+ def test_qos_policy_show(self):
+ opts = self.get_opts(self.FIELDS)
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(self.RULE_ID, raw_output)
+
+ def test_qos_policy_set(self):
+ self.openstack('network qos rule set --min-kbps ' +
+ str(self.MIN_KBPS_MODIFIED) + ' ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID)
+ opts = self.get_opts(['min_kbps'])
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(str(self.MIN_KBPS_MODIFIED) + "\n", raw_output)
+
+
+class NetworkQosRuleTestsDSCPMarking(base.TestCase):
+ """Functional tests for QoS DSCP marking rule."""
+ RULE_ID = None
+ QOS_POLICY_NAME = 'qos_policy_' + uuid.uuid4().hex
+ DSCP_MARK = 8
+ DSCP_MARK_MODIFIED = 32
+ HEADERS = ['ID']
+ FIELDS = ['id']
+ TYPE = 'dscp-marking'
+
+ @classmethod
+ def setUpClass(cls):
+ opts = cls.get_opts(cls.FIELDS)
+ cls.openstack('network qos policy create ' + cls.QOS_POLICY_NAME)
+ cls.RULE_ID = cls.openstack('network qos rule create --type ' +
+ cls.TYPE + ' --dscp-mark ' +
+ str(cls.DSCP_MARK) + ' ' +
+ cls.QOS_POLICY_NAME + opts)
+ cls.assertsOutputNotNone(cls.RULE_ID)
+
+ @classmethod
+ def tearDownClass(cls):
+ raw_output = cls.openstack('network qos rule delete ' +
+ cls.QOS_POLICY_NAME + ' ' + cls.RULE_ID)
+ cls.openstack('network qos policy delete ' + cls.QOS_POLICY_NAME)
+ cls.assertOutput('', raw_output)
+
+ def test_qos_policy_list(self):
+ opts = self.get_opts(self.HEADERS)
+ raw_output = self.openstack('network qos rule list '
+ + self.QOS_POLICY_NAME + opts)
+ self.assertIn(self.RULE_ID, raw_output)
+
+ def test_qos_policy_show(self):
+ opts = self.get_opts(self.FIELDS)
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(self.RULE_ID, raw_output)
+
+ def test_qos_policy_set(self):
+ self.openstack('network qos rule set --dscp-mark ' +
+ str(self.DSCP_MARK_MODIFIED) + ' ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID)
+ opts = self.get_opts(['dscp_mark'])
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(str(self.DSCP_MARK_MODIFIED) + "\n", raw_output)
+
+
+class NetworkQosRuleTestsBandwidthLimit(base.TestCase):
+ """Functional tests for QoS bandwidth limit rule."""
+ RULE_ID = None
+ QOS_POLICY_NAME = 'qos_policy_' + uuid.uuid4().hex
+ MAX_KBPS = 10000
+ MAX_KBPS_MODIFIED = 15000
+ MAX_BURST_KBITS = 1400
+ MAX_BURST_KBITS_MODIFIED = 1800
+ HEADERS = ['ID']
+ FIELDS = ['id']
+ TYPE = 'bandwidth-limit'
+
+ @classmethod
+ def setUpClass(cls):
+ opts = cls.get_opts(cls.FIELDS)
+ cls.openstack('network qos policy create ' + cls.QOS_POLICY_NAME)
+ cls.RULE_ID = cls.openstack('network qos rule create --type ' +
+ cls.TYPE + ' --max-kbps ' +
+ str(cls.MAX_KBPS) + ' --max-burst-kbits ' +
+ str(cls.MAX_BURST_KBITS) + ' ' +
+ cls.QOS_POLICY_NAME + opts)
+ cls.assertsOutputNotNone(cls.RULE_ID)
+
+ @classmethod
+ def tearDownClass(cls):
+ raw_output = cls.openstack('network qos rule delete ' +
+ cls.QOS_POLICY_NAME + ' ' + cls.RULE_ID)
+ cls.openstack('network qos policy delete ' + cls.QOS_POLICY_NAME)
+ cls.assertOutput('', raw_output)
+
+ def test_qos_policy_list(self):
+ opts = self.get_opts(self.HEADERS)
+ raw_output = self.openstack('network qos rule list '
+ + self.QOS_POLICY_NAME + opts)
+ self.assertIn(self.RULE_ID, raw_output)
+
+ def test_qos_policy_show(self):
+ opts = self.get_opts(self.FIELDS)
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(self.RULE_ID, raw_output)
+
+ def test_qos_policy_set(self):
+ self.openstack('network qos rule set --max-kbps ' +
+ str(self.MAX_KBPS_MODIFIED) + ' --max-burst-kbits ' +
+ str(self.MAX_BURST_KBITS_MODIFIED) + ' ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID)
+ opts = self.get_opts(['max_kbps'])
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(str(self.MAX_KBPS_MODIFIED) + "\n", raw_output)
+ opts = self.get_opts(['max_burst_kbps'])
+ raw_output = self.openstack('network qos rule show ' +
+ self.QOS_POLICY_NAME + ' ' + self.RULE_ID +
+ opts)
+ self.assertEqual(str(self.MAX_BURST_KBITS_MODIFIED) + "\n", raw_output)
diff --git a/openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py b/openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py
new file mode 100644
index 00000000..7dff0cbd
--- /dev/null
+++ b/openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py
@@ -0,0 +1,28 @@
+# 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 NetworkQosRuleTypeTests(base.TestCase):
+ """Functional tests for Network QoS rule type. """
+
+ AVAILABLE_RULE_TYPES = ['dscp_marking',
+ 'bandwidth_limit']
+
+ def test_qos_rule_type_list(self):
+ raw_output = self.openstack('network qos rule type list')
+ for rule_type in self.AVAILABLE_RULE_TYPES:
+ self.assertIn(rule_type, raw_output)
diff --git a/openstackclient/tests/functional/network/v2/test_network_service_provider.py b/openstackclient/tests/functional/network/v2/test_network_service_provider.py
index 379de430..6fbff6c8 100644
--- a/openstackclient/tests/functional/network/v2/test_network_service_provider.py
+++ b/openstackclient/tests/functional/network/v2/test_network_service_provider.py
@@ -19,7 +19,7 @@ from openstackclient.tests.functional import base
class TestNetworkServiceProvider(base.TestCase):
"""Functional tests for network service provider"""
- SERVICE_TYPE = ['L3_ROUTER_NAT']
+ SERVICE_TYPE = 'L3_ROUTER_NAT'
def test_network_service_provider_list(self):
raw_output = self.openstack('network service provider list')
diff --git a/openstackclient/tests/functional/network/v2/test_port.py b/openstackclient/tests/functional/network/v2/test_port.py
index decd9553..e100bd82 100644
--- a/openstackclient/tests/functional/network/v2/test_port.py
+++ b/openstackclient/tests/functional/network/v2/test_port.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import re
import uuid
from openstackclient.tests.functional import base
@@ -24,35 +25,152 @@ class PortTests(base.TestCase):
@classmethod
def setUpClass(cls):
- # Create a network for the subnet.
- cls.openstack('network create ' + cls.NETWORK_NAME)
- opts = cls.get_opts(cls.FIELDS)
- raw_output = cls.openstack(
- 'port create --network ' + cls.NETWORK_NAME + ' ' +
- cls.NAME + opts
- )
- expected = cls.NAME + '\n'
- cls.assertOutput(expected, raw_output)
+ # Set up some regex for matching below
+ cls.re_id = re.compile("\s+id\s+\|\s+(\S+)")
+ cls.re_name = re.compile("\s+name\s+\|\s+([^|]+?)\s+\|")
+ cls.re_description = re.compile("\s+description\s+\|\s+([^|]+?)\s+\|")
+ cls.re_mac_address = re.compile("\s+mac_address\s+\|\s+([^|]+?)\s+\|")
+ cls.re_state = re.compile("\s+admin_state_up\s+\|\s+([^|]+?)\s+\|")
+
+ # Create a network for the port
+ raw_output = cls.openstack('network create ' + cls.NETWORK_NAME)
+ cls.network_id = re.search(cls.re_id, raw_output).group(1)
@classmethod
def tearDownClass(cls):
- raw_output = cls.openstack('port delete ' + cls.NAME)
- cls.assertOutput('', raw_output)
raw_output = cls.openstack('network delete ' + cls.NETWORK_NAME)
cls.assertOutput('', raw_output)
+ def test_port_delete(self):
+ """Test create, delete multiple"""
+ raw_output = self.openstack(
+ 'port create --network ' + self.NETWORK_NAME + ' ' + self.NAME
+ )
+ re_id1 = re.search(self.re_id, raw_output)
+ self.assertIsNotNone(re_id1)
+ id1 = re_id1.group(1)
+ self.assertIsNotNone(
+ re.search(self.re_mac_address, raw_output).group(1),
+ )
+ self.assertEqual(
+ self.NAME,
+ re.search(self.re_name, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'port create ' +
+ '--network ' + self.NETWORK_NAME + ' ' +
+ self.NAME + 'x'
+ )
+ id2 = re.search(self.re_id, raw_output).group(1)
+ self.assertIsNotNone(
+ re.search(self.re_mac_address, raw_output).group(1),
+ )
+ self.assertEqual(
+ self.NAME + 'x',
+ re.search(self.re_name, raw_output).group(1),
+ )
+
+ # Clean up after ourselves
+ raw_output = self.openstack('port delete ' + id1 + ' ' + id2)
+ self.assertOutput('', raw_output)
+
def test_port_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('port list' + opts)
- self.assertIn(self.NAME, raw_output)
+ """Test create defaults, list, delete"""
+ raw_output = self.openstack(
+ 'port create --network ' + self.NETWORK_NAME + ' ' + self.NAME
+ )
+ re_id1 = re.search(self.re_id, raw_output)
+ self.assertIsNotNone(re_id1)
+ id1 = re_id1.group(1)
+ mac1 = re.search(self.re_mac_address, raw_output).group(1)
+ self.addCleanup(self.openstack, 'port delete ' + id1)
+ self.assertEqual(
+ self.NAME,
+ re.search(self.re_name, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'port create ' +
+ '--network ' + self.NETWORK_NAME + ' ' +
+ self.NAME + 'x'
+ )
+ id2 = re.search(self.re_id, raw_output).group(1)
+ mac2 = re.search(self.re_mac_address, raw_output).group(1)
+ self.addCleanup(self.openstack, 'port delete ' + id2)
+ self.assertEqual(
+ self.NAME + 'x',
+ re.search(self.re_name, raw_output).group(1),
+ )
+
+ # Test list
+ raw_output = self.openstack('port list')
+ self.assertIsNotNone(re.search("\|\s+" + id1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + id2 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + mac1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + mac2 + "\s+\|", raw_output))
+
+ # Test list --long
+ raw_output = self.openstack('port list --long')
+ self.assertIsNotNone(re.search("\|\s+" + id1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + id2 + "\s+\|", raw_output))
+
+ # Test list --mac-address
+ raw_output = self.openstack('port list --mac-address ' + mac2)
+ self.assertIsNone(re.search("\|\s+" + id1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + id2 + "\s+\|", raw_output))
+ self.assertIsNone(re.search("\|\s+" + mac1 + "\s+\|", raw_output))
+ self.assertIsNotNone(re.search("\|\s+" + mac2 + "\s+\|", raw_output))
def test_port_set(self):
- self.openstack('port set --disable ' + self.NAME)
- opts = self.get_opts(['name', 'admin_state_up'])
- raw_output = self.openstack('port show ' + self.NAME + opts)
- self.assertEqual("DOWN\n" + self.NAME + "\n", raw_output)
-
- def test_port_show(self):
- opts = self.get_opts(self.FIELDS)
- raw_output = self.openstack('port show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\n", raw_output)
+ """Test create, set, show, delete"""
+ raw_output = self.openstack(
+ 'port create ' +
+ '--network ' + self.NETWORK_NAME + ' ' +
+ '--description xyzpdq '
+ '--disable ' +
+ self.NAME
+ )
+ re_id = re.search(self.re_id, raw_output)
+ self.assertIsNotNone(re_id)
+ id = re_id.group(1)
+ self.addCleanup(self.openstack, 'port delete ' + id)
+ self.assertEqual(
+ self.NAME,
+ re.search(self.re_name, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'xyzpdq',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'DOWN',
+ re.search(self.re_state, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'port set ' +
+ '--enable ' +
+ self.NAME
+ )
+ self.assertOutput('', raw_output)
+
+ raw_output = self.openstack(
+ 'port show ' +
+ self.NAME
+ )
+ self.assertEqual(
+ self.NAME,
+ re.search(self.re_name, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'xyzpdq',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'UP',
+ re.search(self.re_state, raw_output).group(1),
+ )
+ self.assertIsNotNone(
+ re.search(self.re_mac_address, raw_output).group(1),
+ )
diff --git a/openstackclient/tests/functional/post_test_hook_tips.sh b/openstackclient/tests/functional/post_test_hook_tips.sh
new file mode 100755
index 00000000..28ab9580
--- /dev/null
+++ b/openstackclient/tests/functional/post_test_hook_tips.sh
@@ -0,0 +1,47 @@
+#!/bin/bash
+
+# This is a script that kicks off a series of functional tests against an
+# OpenStack cloud. It will attempt to create an instance if one is not
+# available. Do not run this script unless you know what you're doing.
+# For more information refer to:
+# http://docs.openstack.org/developer/python-openstackclient/
+
+# This particular script differs from the normal post_test_hook because
+# it installs the master (tip) version of osc-lib, os-client-config
+# and openstacksdk, OSCs most important dependencies.
+
+function generate_testr_results {
+ if [ -f .testrepository/0 ]; then
+ sudo .tox/functional-tips/bin/testr last --subunit > $WORKSPACE/testrepository.subunit
+ sudo mv $WORKSPACE/testrepository.subunit $BASE/logs/testrepository.subunit
+ sudo .tox/functional-tips/bin/subunit2html $BASE/logs/testrepository.subunit $BASE/logs/testr_results.html
+ sudo gzip -9 $BASE/logs/testrepository.subunit
+ sudo gzip -9 $BASE/logs/testr_results.html
+ sudo chown jenkins:jenkins $BASE/logs/testrepository.subunit.gz $BASE/logs/testr_results.html.gz
+ sudo chmod a+r $BASE/logs/testrepository.subunit.gz $BASE/logs/testr_results.html.gz
+ fi
+}
+
+export OPENSTACKCLIENT_DIR="$BASE/new/python-openstackclient"
+sudo chown -R jenkins:stack $OPENSTACKCLIENT_DIR
+
+# Go to the openstackclient dir
+cd $OPENSTACKCLIENT_DIR
+
+# Run tests
+echo "Running openstackclient functional-tips test suite"
+set +e
+
+# Source environment variables to kick things off
+source ~stack/devstack/openrc admin admin
+echo 'Running tests with:'
+env | grep OS
+
+# Preserve env for OS_ credentials
+sudo -E -H -u jenkins tox -e functional-tips
+EXIT_CODE=$?
+set -e
+
+# Collect and parse result
+generate_testr_results
+exit $EXIT_CODE
diff --git a/openstackclient/tests/functional/volume/v2/test_qos.py b/openstackclient/tests/functional/volume/v2/test_qos.py
index a54acbfd..1558c216 100644
--- a/openstackclient/tests/functional/volume/v2/test_qos.py
+++ b/openstackclient/tests/functional/volume/v2/test_qos.py
@@ -50,13 +50,13 @@ class QosTests(common.BaseVolumeTests):
raw_output = self.openstack(
'volume qos set --property a=b --property c=d ' + self.ID)
self.assertEqual("", raw_output)
- opts = self.get_opts(['name', 'specs'])
+ opts = self.get_opts(['name', 'properties'])
raw_output = self.openstack('volume qos show ' + self.ID + opts)
self.assertEqual(self.NAME + "\na='b', c='d'\n", raw_output)
raw_output = self.openstack(
'volume qos unset --property a ' + self.ID)
self.assertEqual("", raw_output)
- opts = self.get_opts(['name', 'specs'])
+ opts = self.get_opts(['name', 'properties'])
raw_output = self.openstack('volume qos show ' + self.ID + opts)
self.assertEqual(self.NAME + "\nc='d'\n", raw_output)
diff --git a/openstackclient/tests/functional/volume/v2/test_snapshot.py b/openstackclient/tests/functional/volume/v2/test_snapshot.py
index 4eb69e9d..c83e79f8 100644
--- a/openstackclient/tests/functional/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/functional/volume/v2/test_snapshot.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
import time
import uuid
@@ -20,9 +21,6 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
"""Functional tests for volume snapshot. """
VOLLY = uuid.uuid4().hex
- NAME = uuid.uuid4().hex
- OTHER_NAME = uuid.uuid4().hex
- HEADERS = ['"Name"']
@classmethod
def wait_for_status(cls, command, status, tries):
@@ -37,52 +35,211 @@ class VolumeSnapshotTests(common.BaseVolumeTests):
@classmethod
def setUpClass(cls):
super(VolumeSnapshotTests, cls).setUpClass()
- cls.openstack('volume create --size 1 ' + cls.VOLLY)
- cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 3)
- opts = cls.get_opts(['status'])
- raw_output = cls.openstack('volume snapshot create --volume ' +
- cls.VOLLY + ' ' + cls.NAME + opts)
- cls.assertOutput('creating\n', raw_output)
- cls.wait_for_status(
- 'volume snapshot show ' + cls.NAME, 'available\n', 3)
+ # create a volume for all tests to create snapshot
+ cmd_output = json.loads(cls.openstack(
+ 'volume create -f json ' +
+ '--size 1 ' +
+ cls.VOLLY
+ ))
+ cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6)
+ cls.VOLUME_ID = cmd_output['id']
@classmethod
def tearDownClass(cls):
- # Rename test
- raw_output = cls.openstack(
- 'volume snapshot set --name ' + cls.OTHER_NAME + ' ' + cls.NAME)
- cls.assertOutput('', raw_output)
- # Delete test
- raw_output_snapshot = cls.openstack(
- 'volume snapshot delete ' + cls.OTHER_NAME)
cls.wait_for_status('volume show ' + cls.VOLLY, 'available\n', 6)
- raw_output_volume = cls.openstack('volume delete --force ' + cls.VOLLY)
- cls.assertOutput('', raw_output_snapshot)
- cls.assertOutput('', raw_output_volume)
+ raw_output = cls.openstack('volume delete --force ' + cls.VOLLY)
+ cls.assertOutput('', raw_output)
- def test_snapshot_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('volume snapshot list' + opts)
- self.assertIn(self.NAME, raw_output)
+ def test_volume_snapshot__delete(self):
+ """Test create, delete multiple"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot create -f json ' +
+ name1 +
+ ' --volume ' + self.VOLLY
+ ))
+ self.assertEqual(
+ name1,
+ cmd_output["name"],
+ )
- def test_snapshot_properties(self):
- raw_output = self.openstack(
- 'volume snapshot set --property a=b --property c=d ' + self.NAME)
- self.assertEqual("", raw_output)
- opts = self.get_opts(["properties"])
- raw_output = self.openstack('volume snapshot show ' + self.NAME + opts)
- self.assertEqual("a='b', c='d'\n", raw_output)
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot create -f json ' +
+ name2 +
+ ' --volume ' + self.VOLLY
+ ))
+ self.assertEqual(
+ name2,
+ cmd_output["name"],
+ )
+
+ self.wait_for_status(
+ 'volume snapshot show ' + name1, 'available\n', 6)
+ self.wait_for_status(
+ 'volume snapshot show ' + name2, 'available\n', 6)
+
+ del_output = self.openstack(
+ 'volume snapshot delete ' + name1 + ' ' + name2)
+ self.assertOutput('', del_output)
+
+ def test_volume_snapshot_list(self):
+ """Test create, list filter"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot create -f json ' +
+ name1 +
+ ' --volume ' + self.VOLLY
+ ))
+ self.addCleanup(self.openstack, 'volume snapshot delete ' + name1)
+ self.assertEqual(
+ name1,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ self.VOLUME_ID,
+ cmd_output["volume_id"],
+ )
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+ self.wait_for_status(
+ 'volume snapshot show ' + name1, 'available\n', 6)
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot create -f json ' +
+ name2 +
+ ' --volume ' + self.VOLLY
+ ))
+ self.addCleanup(self.openstack, 'volume snapshot delete ' + name2)
+ self.assertEqual(
+ name2,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ self.VOLUME_ID,
+ cmd_output["volume_id"],
+ )
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+ self.wait_for_status(
+ 'volume snapshot show ' + name2, 'available\n', 6)
raw_output = self.openstack(
- 'volume snapshot unset --property a ' + self.NAME)
- self.assertEqual("", raw_output)
- raw_output = self.openstack('volume snapshot show ' + self.NAME + opts)
- self.assertEqual("c='d'\n", raw_output)
+ 'volume snapshot set ' +
+ '--state error ' +
+ name2
+ )
+ self.assertOutput('', raw_output)
+
+ # Test list --long, --status
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot list -f json ' +
+ '--long ' +
+ '--status error'
+ ))
+ names = [x["Name"] for x in cmd_output]
+ self.assertNotIn(name1, names)
+ self.assertIn(name2, names)
+
+ # Test list --volume
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot list -f json ' +
+ '--volume ' + self.VOLLY
+ ))
+ names = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, names)
+ self.assertIn(name2, names)
+
+ # Test list --name
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot list -f json ' +
+ '--name ' + name1
+ ))
+ names = [x["Name"] for x in cmd_output]
+ self.assertIn(name1, names)
+ self.assertNotIn(name2, names)
def test_snapshot_set(self):
+ """Test create, set, unset, show, delete volume snapshot"""
+ name = uuid.uuid4().hex
+ new_name = name + "_"
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot create -f json ' +
+ '--volume ' + self.VOLLY +
+ ' --description aaaa ' +
+ '--property Alpha=a ' +
+ name
+ ))
+ self.addCleanup(self.openstack, 'volume snapshot delete ' + new_name)
+ self.assertEqual(
+ name,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+ self.assertEqual(
+ 'aaaa',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ "Alpha='a'",
+ cmd_output["properties"],
+ )
+ self.wait_for_status(
+ 'volume snapshot show ' + name, 'available\n', 6)
+
+ # Test volume snapshot set
raw_output = self.openstack(
- 'volume snapshot set --description backup ' + self.NAME)
- self.assertEqual("", raw_output)
- opts = self.get_opts(["description", "name"])
- raw_output = self.openstack('volume snapshot show ' + self.NAME + opts)
- self.assertEqual("backup\n" + self.NAME + "\n", raw_output)
+ 'volume snapshot set ' +
+ '--name ' + new_name +
+ ' --description bbbb ' +
+ '--property Alpha=c ' +
+ '--property Beta=b ' +
+ name,
+ )
+ self.assertOutput('', raw_output)
+
+ # Show snapshot set result
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot show -f json ' +
+ new_name
+ ))
+ self.assertEqual(
+ new_name,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+ self.assertEqual(
+ 'bbbb',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ "Alpha='c', Beta='b'",
+ cmd_output["properties"],
+ )
+
+ # Test volume unset
+ raw_output = self.openstack(
+ 'volume snapshot unset ' +
+ '--property Alpha ' +
+ new_name,
+ )
+ self.assertOutput('', raw_output)
+
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot show -f json ' +
+ new_name
+ ))
+ self.assertEqual(
+ "Beta='b'",
+ cmd_output["properties"],
+ )
diff --git a/openstackclient/tests/functional/volume/v2/test_volume.py b/openstackclient/tests/functional/volume/v2/test_volume.py
index ea891cba..203ca819 100644
--- a/openstackclient/tests/functional/volume/v2/test_volume.py
+++ b/openstackclient/tests/functional/volume/v2/test_volume.py
@@ -10,6 +10,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import json
import time
import uuid
@@ -19,118 +20,220 @@ from openstackclient.tests.functional.volume.v2 import common
class VolumeTests(common.BaseVolumeTests):
"""Functional tests for volume. """
- NAME = uuid.uuid4().hex
- SNAPSHOT_NAME = uuid.uuid4().hex
- VOLUME_FROM_SNAPSHOT_NAME = uuid.uuid4().hex
- OTHER_NAME = uuid.uuid4().hex
- HEADERS = ['"Display Name"']
- FIELDS = ['name']
-
- @classmethod
- def setUpClass(cls):
- super(VolumeTests, cls).setUpClass()
- opts = cls.get_opts(cls.FIELDS)
-
- # Create test volume
- raw_output = cls.openstack('volume create --size 1 ' + cls.NAME + opts)
- expected = cls.NAME + '\n'
- cls.assertOutput(expected, raw_output)
-
- @classmethod
- def tearDownClass(cls):
- # Rename test volume
- raw_output = cls.openstack(
- 'volume set --name ' + cls.OTHER_NAME + ' ' + cls.NAME)
- cls.assertOutput('', raw_output)
-
- # Set volume state
- cls.openstack('volume set --state error ' + cls.OTHER_NAME)
- opts = cls.get_opts(["status"])
- raw_output_status = cls.openstack(
- 'volume show ' + cls.OTHER_NAME + opts)
-
- # Delete test volume
- raw_output = cls.openstack('volume delete ' + cls.OTHER_NAME)
- cls.assertOutput('', raw_output)
- cls.assertOutput('error\n', raw_output_status)
+ def test_volume_delete(self):
+ """Test create, delete multiple"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--size 1 ' +
+ name1
+ ))
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--size 2 ' +
+ name2
+ ))
+ self.assertEqual(
+ 2,
+ cmd_output["size"],
+ )
+
+ self.wait_for("volume", name1, "available")
+ self.wait_for("volume", name2, "available")
+ del_output = self.openstack('volume delete ' + name1 + ' ' + name2)
+ self.assertOutput('', del_output)
def test_volume_list(self):
- opts = self.get_opts(self.HEADERS)
- raw_output = self.openstack('volume list' + opts)
- self.assertIn(self.NAME, raw_output)
-
- def test_volume_show(self):
- opts = self.get_opts(self.FIELDS)
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\n", raw_output)
-
- def test_volume_properties(self):
+ """Test create, list filter"""
+ name1 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--size 1 ' +
+ name1
+ ))
+ self.addCleanup(self.openstack, 'volume delete ' + name1)
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+ self.wait_for("volume", name1, "available")
+
+ name2 = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--size 2 ' +
+ name2
+ ))
+ self.addCleanup(self.openstack, 'volume delete ' + name2)
+ self.assertEqual(
+ 2,
+ cmd_output["size"],
+ )
+ self.wait_for("volume", name2, "available")
raw_output = self.openstack(
- 'volume set --property a=b --property c=d ' + self.NAME)
- self.assertEqual("", raw_output)
- opts = self.get_opts(["properties"])
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual("a='b', c='d'\n", raw_output)
+ 'volume set ' +
+ '--state error ' +
+ name2
+ )
+ self.assertOutput('', raw_output)
- raw_output = self.openstack('volume unset --property a ' + self.NAME)
- self.assertEqual("", raw_output)
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual("c='d'\n", raw_output)
+ # Test list --long
+ cmd_output = json.loads(self.openstack(
+ 'volume list -f json ' +
+ '--long'
+ ))
+ names = [x["Display Name"] for x in cmd_output]
+ self.assertIn(name1, names)
+ self.assertIn(name2, names)
+
+ # Test list --status
+ cmd_output = json.loads(self.openstack(
+ 'volume list -f json ' +
+ '--status error'
+ ))
+ names = [x["Display Name"] for x in cmd_output]
+ self.assertNotIn(name1, names)
+ self.assertIn(name2, names)
+
+ # TODO(qiangjiahui): Add project option to filter tests when we can
+ # specify volume with project
def test_volume_set(self):
- discription = uuid.uuid4().hex
- self.openstack('volume set --description ' + discription + ' ' +
- self.NAME)
- opts = self.get_opts(["description", "name"])
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual(discription + "\n" + self.NAME + "\n", raw_output)
-
- def test_volume_set_size(self):
- self.openstack('volume set --size 2 ' + self.NAME)
- opts = self.get_opts(["name", "size"])
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual(self.NAME + "\n2\n", raw_output)
-
- def test_volume_set_bootable(self):
- self.openstack('volume set --bootable ' + self.NAME)
- opts = self.get_opts(["bootable"])
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual("true\n", raw_output)
-
- self.openstack('volume set --non-bootable ' + self.NAME)
- opts = self.get_opts(["bootable"])
- raw_output = self.openstack('volume show ' + self.NAME + opts)
- self.assertEqual("false\n", raw_output)
+ """Tests create volume, set, unset, show, delete"""
+ name = uuid.uuid4().hex
+ new_name = name + "_"
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--size 1 ' +
+ '--description aaaa ' +
+ '--property Alpha=a ' +
+ name
+ ))
+ self.addCleanup(self.openstack, 'volume delete ' + new_name)
+ self.assertEqual(
+ name,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ 1,
+ cmd_output["size"],
+ )
+ self.assertEqual(
+ 'aaaa',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ "Alpha='a'",
+ cmd_output["properties"],
+ )
+ self.assertEqual(
+ 'false',
+ cmd_output["bootable"],
+ )
+ self.wait_for("volume", name, "available")
+
+ # Test volume set
+ raw_output = self.openstack(
+ 'volume set ' +
+ '--name ' + new_name +
+ ' --size 2 ' +
+ '--description bbbb ' +
+ '--property Alpha=c ' +
+ '--property Beta=b ' +
+ '--bootable ' +
+ name,
+ )
+ self.assertOutput('', raw_output)
- def test_volume_snapshot(self):
- opts = self.get_opts(self.FIELDS)
-
- # Create snapshot from test volume
- raw_output = self.openstack('volume snapshot create ' +
- self.SNAPSHOT_NAME +
- ' --volume ' + self.NAME + opts)
- expected = self.SNAPSHOT_NAME + '\n'
- self.assertOutput(expected, raw_output)
- self.wait_for("volume snapshot", self.SNAPSHOT_NAME, "available")
-
- # Create volume from snapshot
- raw_output = self.openstack('volume create --size 2 --snapshot ' +
- self.SNAPSHOT_NAME + ' ' +
- self.VOLUME_FROM_SNAPSHOT_NAME + opts)
- expected = self.VOLUME_FROM_SNAPSHOT_NAME + '\n'
- self.assertOutput(expected, raw_output)
- self.wait_for("volume", self.VOLUME_FROM_SNAPSHOT_NAME, "available")
-
- # Delete volume that create from snapshot
- raw_output = self.openstack('volume delete ' +
- self.VOLUME_FROM_SNAPSHOT_NAME)
+ cmd_output = json.loads(self.openstack(
+ 'volume show -f json ' +
+ new_name
+ ))
+ self.assertEqual(
+ new_name,
+ cmd_output["name"],
+ )
+ self.assertEqual(
+ 2,
+ cmd_output["size"],
+ )
+ self.assertEqual(
+ 'bbbb',
+ cmd_output["description"],
+ )
+ self.assertEqual(
+ "Alpha='c', Beta='b'",
+ cmd_output["properties"],
+ )
+ self.assertEqual(
+ 'true',
+ cmd_output["bootable"],
+ )
+
+ # Test volume unset
+ raw_output = self.openstack(
+ 'volume unset ' +
+ '--property Alpha ' +
+ new_name,
+ )
self.assertOutput('', raw_output)
- # Delete test snapshot
+ cmd_output = json.loads(self.openstack(
+ 'volume show -f json ' +
+ new_name
+ ))
+ self.assertEqual(
+ "Beta='b'",
+ cmd_output["properties"],
+ )
+
+ def test_volume_snapshot(self):
+ """Tests volume create from snapshot"""
+
+ volume_name = uuid.uuid4().hex
+ snapshot_name = uuid.uuid4().hex
+ # Make a snapshot
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--size 1 ' +
+ volume_name
+ ))
+ self.wait_for("volume", volume_name, "available")
+ self.assertEqual(
+ volume_name,
+ cmd_output["name"],
+ )
+ cmd_output = json.loads(self.openstack(
+ 'volume snapshot create -f json ' +
+ snapshot_name +
+ ' --volume ' + volume_name
+ ))
+ self.wait_for("volume snapshot", snapshot_name, "available")
+
+ name = uuid.uuid4().hex
+ cmd_output = json.loads(self.openstack(
+ 'volume create -f json ' +
+ '--snapshot ' + snapshot_name +
+ ' ' + name
+ ))
+ self.addCleanup(self.openstack, 'volume delete ' + name)
+ self.addCleanup(self.openstack, 'volume delete ' + volume_name)
+ self.assertEqual(
+ name,
+ cmd_output["name"],
+ )
+ self.wait_for("volume", name, "available")
+
+ # Delete snapshot
raw_output = self.openstack(
- 'volume snapshot delete ' + self.SNAPSHOT_NAME)
+ 'volume snapshot delete ' + snapshot_name)
self.assertOutput('', raw_output)
- self.wait_for("volume", self.NAME, "available")
def wait_for(self, check_type, check_name, desired_status, wait=120,
interval=5, failures=['ERROR']):
diff --git a/openstackclient/tests/unit/api/test_image_v1.py b/openstackclient/tests/unit/api/test_image_v1.py
index e02ef381..6ce3ddea 100644
--- a/openstackclient/tests/unit/api/test_image_v1.py
+++ b/openstackclient/tests/unit/api/test_image_v1.py
@@ -21,7 +21,7 @@ from openstackclient.tests.unit import utils
FAKE_PROJECT = 'xyzpdq'
-FAKE_URL = 'http://gopher.com'
+FAKE_URL = 'http://gopher.dev10.com'
class TestImageAPIv1(utils.TestCase):
diff --git a/openstackclient/tests/unit/api/test_image_v2.py b/openstackclient/tests/unit/api/test_image_v2.py
index 5dbb51e0..22490e46 100644
--- a/openstackclient/tests/unit/api/test_image_v2.py
+++ b/openstackclient/tests/unit/api/test_image_v2.py
@@ -21,7 +21,7 @@ from openstackclient.tests.unit import utils
FAKE_PROJECT = 'xyzpdq'
-FAKE_URL = 'http://gopher.com'
+FAKE_URL = 'http://gopher.dev20.com'
class TestImageAPIv2(utils.TestCase):
diff --git a/openstackclient/tests/unit/common/test_quota.py b/openstackclient/tests/unit/common/test_quota.py
index 7dd23373..244d74d2 100644
--- a/openstackclient/tests/unit/common/test_quota.py
+++ b/openstackclient/tests/unit/common/test_quota.py
@@ -13,6 +13,8 @@
import copy
import mock
+from openstack.network.v2 import quota as _quota
+
from openstackclient.common import quota
from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
from openstackclient.tests.unit import fakes
@@ -282,27 +284,32 @@ class TestQuotaSet(TestQuota):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- result = self.cmd.take_action(parsed_args)
- kwargs = {
- 'subnet': network_fakes.QUOTA['subnet'],
- 'network': network_fakes.QUOTA['network'],
- 'floatingip': network_fakes.QUOTA['floatingip'],
- 'subnetpool': network_fakes.QUOTA['subnetpool'],
- 'security_group_rule':
- network_fakes.QUOTA['security_group_rule'],
- 'security_group': network_fakes.QUOTA['security_group'],
- 'router': network_fakes.QUOTA['router'],
- 'rbac_policy': network_fakes.QUOTA['rbac_policy'],
- 'port': network_fakes.QUOTA['port'],
- 'vip': network_fakes.QUOTA['vip'],
- 'healthmonitor': network_fakes.QUOTA['healthmonitor'],
- 'l7policy': network_fakes.QUOTA['l7policy'],
- }
- self.network_mock.update_quota.assert_called_once_with(
- identity_fakes.project_id,
- **kwargs
- )
- self.assertIsNone(result)
+ # TODO(huanxuan): Remove this if condition once the fixed
+ # SDK Quota class is the minimum required version.
+ # This is expected to be SDK release 0.9.13
+ if not hasattr(_quota.Quota, 'allow_get'):
+ # Just run this when sdk <= 0.9.10
+ result = self.cmd.take_action(parsed_args)
+ kwargs = {
+ 'subnet': network_fakes.QUOTA['subnet'],
+ 'network': network_fakes.QUOTA['network'],
+ 'floatingip': network_fakes.QUOTA['floatingip'],
+ 'subnetpool': network_fakes.QUOTA['subnetpool'],
+ 'security_group_rule':
+ network_fakes.QUOTA['security_group_rule'],
+ 'security_group': network_fakes.QUOTA['security_group'],
+ 'router': network_fakes.QUOTA['router'],
+ 'rbac_policy': network_fakes.QUOTA['rbac_policy'],
+ 'port': network_fakes.QUOTA['port'],
+ 'vip': network_fakes.QUOTA['vip'],
+ 'healthmonitor': network_fakes.QUOTA['healthmonitor'],
+ 'l7policy': network_fakes.QUOTA['l7policy'],
+ }
+ self.network_mock.update_quota.assert_called_once_with(
+ identity_fakes.project_id,
+ **kwargs
+ )
+ self.assertIsNone(result)
def test_quota_set_with_class(self):
arglist = [
@@ -476,15 +483,20 @@ class TestQuotaShow(TestQuota):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- self.cmd.take_action(parsed_args)
-
- self.quotas_mock.defaults.assert_called_once_with(
- identity_fakes.project_id)
- self.volume_quotas_mock.defaults.assert_called_once_with(
- identity_fakes.project_id)
- self.network.get_quota_default.assert_called_once_with(
- identity_fakes.project_id)
- self.assertNotCalled(self.network.get_quota)
+ # TODO(huanxuan): Remove this if condition once the fixed
+ # SDK QuotaDefault class is the minimum required version.
+ # This is expected to be SDK release 0.9.13
+ if not hasattr(_quota.QuotaDefault, 'project'):
+ # Just run this when sdk <= 0.9.10
+ self.cmd.take_action(parsed_args)
+
+ self.quotas_mock.defaults.assert_called_once_with(
+ identity_fakes.project_id)
+ self.volume_quotas_mock.defaults.assert_called_once_with(
+ identity_fakes.project_id)
+ self.network.get_quota_default.assert_called_once_with(
+ identity_fakes.project_id)
+ self.assertNotCalled(self.network.get_quota)
def test_quota_show_with_class(self):
arglist = [
diff --git a/openstackclient/tests/unit/compute/v2/fakes.py b/openstackclient/tests/unit/compute/v2/fakes.py
index 985ce5e2..4fe735b6 100644
--- a/openstackclient/tests/unit/compute/v2/fakes.py
+++ b/openstackclient/tests/unit/compute/v2/fakes.py
@@ -168,6 +168,9 @@ class FakeComputev2Client(object):
self.quota_classes = mock.Mock()
self.quota_classes.resource_class = fakes.FakeResource(None, {})
+ self.usage = mock.Mock()
+ self.usage.resource_class = fakes.FakeResource(None, {})
+
self.volumes = mock.Mock()
self.volumes.resource_class = fakes.FakeResource(None, {})
@@ -1248,3 +1251,65 @@ class FakeServerGroup(object):
info=copy.deepcopy(server_group_info),
loaded=True)
return server_group
+
+
+class FakeUsage(object):
+ """Fake one or more usage."""
+
+ @staticmethod
+ def create_one_usage(attrs=None):
+ """Create a fake usage.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object, with tenant_id and other attributes
+ """
+ if attrs is None:
+ attrs = {}
+
+ # Set default attributes.
+ usage_info = {
+ 'tenant_id': 'usage-tenant-id-' + uuid.uuid4().hex,
+ 'total_memory_mb_usage': 512.0,
+ 'total_vcpus_usage': 1.0,
+ 'total_local_gb_usage': 1.0,
+ 'server_usages': [
+ {
+ 'ended_at': None,
+ 'flavor': 'usage-flavor-' + uuid.uuid4().hex,
+ 'hours': 1.0,
+ 'local_gb': 1,
+ 'memory_mb': 512,
+ 'name': 'usage-name-' + uuid.uuid4().hex,
+ 'state': 'active',
+ 'uptime': 3600,
+ 'vcpus': 1
+ }
+ ]
+ }
+
+ # Overwrite default attributes.
+ usage_info.update(attrs)
+
+ usage = fakes.FakeResource(info=copy.deepcopy(usage_info),
+ loaded=True)
+
+ return usage
+
+ @staticmethod
+ def create_usages(attrs=None, count=2):
+ """Create multiple fake services.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of services to fake
+ :return:
+ A list of FakeResource objects faking the services
+ """
+ usages = []
+ for i in range(0, count):
+ usages.append(FakeUsage.create_one_usage(attrs))
+
+ return usages
diff --git a/openstackclient/tests/unit/compute/v2/test_flavor.py b/openstackclient/tests/unit/compute/v2/test_flavor.py
index 93ad9d14..632fcda1 100644
--- a/openstackclient/tests/unit/compute/v2/test_flavor.py
+++ b/openstackclient/tests/unit/compute/v2/test_flavor.py
@@ -160,7 +160,7 @@ class TestFlavorCreate(TestFlavor):
self.flavor.is_public = False
arglist = [
- '--id', self.flavor.id,
+ '--id', 'auto',
'--ram', str(self.flavor.ram),
'--disk', str(self.flavor.disk),
'--ephemeral', str(self.flavor.ephemeral),
@@ -174,7 +174,6 @@ class TestFlavorCreate(TestFlavor):
self.flavor.name,
]
verifylist = [
- ('id', self.flavor.id),
('ram', self.flavor.ram),
('disk', self.flavor.disk),
('ephemeral', self.flavor.ephemeral),
@@ -193,7 +192,7 @@ class TestFlavorCreate(TestFlavor):
self.flavor.ram,
self.flavor.vcpus,
self.flavor.disk,
- self.flavor.id,
+ 'auto',
self.flavor.ephemeral,
self.flavor.swap,
self.flavor.rxtx_factor,
diff --git a/openstackclient/tests/unit/compute/v2/test_server.py b/openstackclient/tests/unit/compute/v2/test_server.py
index 57221189..54f36209 100644
--- a/openstackclient/tests/unit/compute/v2/test_server.py
+++ b/openstackclient/tests/unit/compute/v2/test_server.py
@@ -36,10 +36,6 @@ class TestServer(compute_fakes.TestComputev2):
self.servers_mock = self.app.client_manager.compute.servers
self.servers_mock.reset_mock()
- # Get a shortcut to the compute client ImageManager Mock
- self.cimages_mock = self.app.client_manager.compute.images
- self.cimages_mock.reset_mock()
-
# Get a shortcut to the compute client FlavorManager Mock
self.flavors_mock = self.app.client_manager.compute.flavors
self.flavors_mock.reset_mock()
@@ -259,7 +255,7 @@ class TestServerCreate(TestServer):
self.servers_mock.create.return_value = self.new_server
self.image = image_fakes.FakeImage.create_one_image()
- self.cimages_mock.get.return_value = self.image
+ self.images_mock.get.return_value = self.image
self.flavor = compute_fakes.FakeFlavor.create_one_flavor()
self.flavors_mock.get.return_value = self.flavor
@@ -859,7 +855,7 @@ class TestServerList(TestServer):
self.servers_mock.list.return_value = self.servers
self.image = image_fakes.FakeImage.create_one_image()
- self.cimages_mock.get.return_value = self.image
+ self.images_mock.get.return_value = self.image
self.flavor = compute_fakes.FakeFlavor.create_one_flavor()
self.flavors_mock.get.return_value = self.flavor
@@ -943,7 +939,7 @@ class TestServerList(TestServer):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
- self.cimages_mock.get.assert_any_call(self.image.id)
+ self.images_mock.get.assert_any_call(self.image.id)
self.search_opts['image'] = self.image.id
self.servers_mock.list.assert_called_with(**self.kwargs)
@@ -1019,7 +1015,7 @@ class TestServerRebuild(TestServer):
# Return value for utils.find_resource for image
self.image = image_fakes.FakeImage.create_one_image()
- self.cimages_mock.get.return_value = self.image
+ self.images_mock.get.return_value = self.image
# Fake the rebuilt new server.
new_server = compute_fakes.FakeServer.create_one_server()
@@ -1059,7 +1055,7 @@ class TestServerRebuild(TestServer):
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id)
- self.cimages_mock.get.assert_called_with(self.image.id)
+ self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, None)
def test_rebuild_with_current_image_and_password(self):
@@ -1078,7 +1074,7 @@ class TestServerRebuild(TestServer):
self.cmd.take_action(parsed_args)
self.servers_mock.get.assert_called_with(self.server.id)
- self.cimages_mock.get.assert_called_with(self.image.id)
+ self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, password)
@mock.patch.object(common_utils, 'wait_for_status', return_value=True)
@@ -1106,7 +1102,7 @@ class TestServerRebuild(TestServer):
)
self.servers_mock.get.assert_called_with(self.server.id)
- self.cimages_mock.get.assert_called_with(self.image.id)
+ self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, None)
@mock.patch.object(common_utils, 'wait_for_status', return_value=False)
@@ -1130,7 +1126,7 @@ class TestServerRebuild(TestServer):
)
self.servers_mock.get.assert_called_with(self.server.id)
- self.cimages_mock.get.assert_called_with(self.image.id)
+ self.images_mock.get.assert_called_with(self.image.id)
self.server.rebuild.assert_called_with(self.image, None)
@@ -1628,7 +1624,7 @@ class TestServerShow(TestServer):
# This is the return value for utils.find_resource()
self.servers_mock.get.return_value = self.server
- self.cimages_mock.get.return_value = self.image
+ self.images_mock.get.return_value = self.image
self.flavors_mock.get.return_value = self.flavor
# Get the command object to test
@@ -1986,6 +1982,7 @@ class TestServerGeneral(TestServer):
# Call _prep_server_detail().
server_detail = server._prep_server_detail(
self.app.client_manager.compute,
+ self.app.client_manager.image,
_server
)
# 'networks' is used to create _server. Remove it.
diff --git a/openstackclient/tests/unit/compute/v2/test_usage.py b/openstackclient/tests/unit/compute/v2/test_usage.py
new file mode 100644
index 00000000..a383e903
--- /dev/null
+++ b/openstackclient/tests/unit/compute/v2/test_usage.py
@@ -0,0 +1,179 @@
+# 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 datetime
+import mock
+
+from openstackclient.compute.v2 import usage
+from openstackclient.tests.unit.compute.v2 import fakes as compute_fakes
+from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
+
+
+class TestUsage(compute_fakes.TestComputev2):
+
+ def setUp(self):
+ super(TestUsage, self).setUp()
+
+ self.usage_mock = self.app.client_manager.compute.usage
+ self.usage_mock.reset_mock()
+
+ self.projects_mock = self.app.client_manager.identity.projects
+ self.projects_mock.reset_mock()
+
+
+class TestUsageList(TestUsage):
+
+ project = identity_fakes.FakeProject.create_one_project()
+ # Return value of self.usage_mock.list().
+ usages = compute_fakes.FakeUsage.create_usages(
+ attrs={'tenant_id': project.name}, count=1)
+
+ columns = (
+ "Project",
+ "Servers",
+ "RAM MB-Hours",
+ "CPU Hours",
+ "Disk GB-Hours"
+ )
+
+ data = [(
+ usages[0].tenant_id,
+ len(usages[0].server_usages),
+ float("%.2f" % usages[0].total_memory_mb_usage),
+ float("%.2f" % usages[0].total_vcpus_usage),
+ float("%.2f" % usages[0].total_local_gb_usage),
+ )]
+
+ def setUp(self):
+ super(TestUsageList, self).setUp()
+
+ self.usage_mock.list.return_value = self.usages
+
+ self.projects_mock.list.return_value = [self.project]
+ # Get the command object to test
+ self.cmd = usage.ListUsage(self.app, None)
+
+ def test_usage_list_no_options(self):
+
+ arglist = []
+ verifylist = [
+ ('start', None),
+ ('end', None),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.projects_mock.list.assert_called_with()
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(tuple(self.data), tuple(data))
+
+ def test_usage_list_with_options(self):
+ arglist = [
+ '--start', '2016-11-11',
+ '--end', '2016-12-20',
+ ]
+ verifylist = [
+ ('start', '2016-11-11'),
+ ('end', '2016-12-20'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.projects_mock.list.assert_called_with()
+ self.usage_mock.list.assert_called_with(
+ datetime.datetime(2016, 11, 11, 0, 0),
+ datetime.datetime(2016, 12, 20, 0, 0),
+ detailed=True)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(tuple(self.data), tuple(data))
+
+
+class TestUsageShow(TestUsage):
+
+ project = identity_fakes.FakeProject.create_one_project()
+ # Return value of self.usage_mock.list().
+ usage = compute_fakes.FakeUsage.create_one_usage(
+ attrs={'tenant_id': project.name})
+
+ columns = (
+ 'CPU Hours',
+ 'Disk GB-Hours',
+ 'RAM MB-Hours',
+ 'Servers',
+ )
+
+ data = (
+ float("%.2f" % usage.total_vcpus_usage),
+ float("%.2f" % usage.total_local_gb_usage),
+ float("%.2f" % usage.total_memory_mb_usage),
+ len(usage.server_usages),
+ )
+
+ def setUp(self):
+ super(TestUsageShow, self).setUp()
+
+ self.usage_mock.get.return_value = self.usage
+
+ self.projects_mock.get.return_value = self.project
+ # Get the command object to test
+ self.cmd = usage.ShowUsage(self.app, None)
+
+ def test_usage_show_no_options(self):
+
+ self.app.client_manager.auth_ref = mock.Mock()
+ self.app.client_manager.auth_ref.project_id = self.project.id
+
+ arglist = []
+ verifylist = [
+ ('project', None),
+ ('start', None),
+ ('end', None),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_usage_show_with_options(self):
+
+ arglist = [
+ '--project', self.project.id,
+ '--start', '2016-11-11',
+ '--end', '2016-12-20',
+ ]
+ verifylist = [
+ ('project', self.project.id),
+ ('start', '2016-11-11'),
+ ('end', '2016-12-20'),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.usage_mock.get.assert_called_with(
+ self.project.id,
+ datetime.datetime(2016, 11, 11, 0, 0),
+ datetime.datetime(2016, 12, 20, 0, 0))
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/fakes.py b/openstackclient/tests/unit/fakes.py
index f7cb5676..626b466d 100644
--- a/openstackclient/tests/unit/fakes.py
+++ b/openstackclient/tests/unit/fakes.py
@@ -212,10 +212,19 @@ class FakeResource(object):
def keys(self):
return self._info.keys()
+ def to_dict(self):
+ return self._info
+
@property
def info(self):
return self._info
+ def __getitem__(self, item):
+ return self._info.get(item)
+
+ def get(self, item, default=None):
+ return self._info.get(item, default)
+
class FakeResponse(requests.Response):
diff --git a/openstackclient/tests/unit/identity/v2_0/test_project.py b/openstackclient/tests/unit/identity/v2_0/test_project.py
index c1f00762..4e1077db 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_project.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_project.py
@@ -13,8 +13,11 @@
# under the License.
#
+import mock
+
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v2_0 import project
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
@@ -302,6 +305,32 @@ class TestProjectDelete(TestProject):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_projects_with_exception(self, find_mock):
+ find_mock.side_effect = [self.fake_project,
+ exceptions.CommandError]
+ arglist = [
+ self.fake_project.id,
+ 'unexist_project',
+ ]
+ verifylist = [
+ ('projects', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 projects failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.projects_mock, self.fake_project.id)
+ find_mock.assert_any_call(self.projects_mock, 'unexist_project')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.projects_mock.delete.assert_called_once_with(self.fake_project.id)
+
class TestProjectList(TestProject):
diff --git a/openstackclient/tests/unit/identity/v2_0/test_role.py b/openstackclient/tests/unit/identity/v2_0/test_role.py
index 68ebf141..684ce803 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_role.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_role.py
@@ -17,6 +17,7 @@ import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v2_0 import role
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
@@ -240,6 +241,32 @@ class TestRoleDelete(TestRole):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_roles_with_exception(self, find_mock):
+ find_mock.side_effect = [self.fake_role,
+ exceptions.CommandError]
+ arglist = [
+ self.fake_role.id,
+ 'unexist_role',
+ ]
+ verifylist = [
+ ('roles', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 roles failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.roles_mock, self.fake_role.id)
+ find_mock.assert_any_call(self.roles_mock, 'unexist_role')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.roles_mock.delete.assert_called_once_with(self.fake_role.id)
+
class TestRoleList(TestRole):
diff --git a/openstackclient/tests/unit/identity/v2_0/test_user.py b/openstackclient/tests/unit/identity/v2_0/test_user.py
index 765f8559..a8b9497e 100644
--- a/openstackclient/tests/unit/identity/v2_0/test_user.py
+++ b/openstackclient/tests/unit/identity/v2_0/test_user.py
@@ -17,6 +17,7 @@ import mock
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v2_0 import user
from openstackclient.tests.unit.identity.v2_0 import fakes as identity_fakes
@@ -411,6 +412,32 @@ class TestUserDelete(TestUser):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_users_with_exception(self, find_mock):
+ find_mock.side_effect = [self.fake_user,
+ exceptions.CommandError]
+ arglist = [
+ self.fake_user.id,
+ 'unexist_user',
+ ]
+ verifylist = [
+ ('users', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 users failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.users_mock, self.fake_user.id)
+ find_mock.assert_any_call(self.users_mock, 'unexist_user')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.users_mock.delete.assert_called_once_with(self.fake_user.id)
+
class TestUserList(TestUser):
diff --git a/openstackclient/tests/unit/identity/v3/test_group.py b/openstackclient/tests/unit/identity/v3/test_group.py
index eb50adb5..8558de95 100644
--- a/openstackclient/tests/unit/identity/v3/test_group.py
+++ b/openstackclient/tests/unit/identity/v3/test_group.py
@@ -16,6 +16,7 @@ from mock import call
from keystoneauth1 import exceptions as ks_exc
from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v3 import group
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@@ -257,6 +258,32 @@ class TestGroupDelete(TestGroup):
self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_groups_with_exception(self, find_mock):
+ find_mock.side_effect = [self.groups[0],
+ exceptions.CommandError]
+ arglist = [
+ self.groups[0].id,
+ 'unexist_group',
+ ]
+ verifylist = [
+ ('groups', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 groups failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.groups_mock, self.groups[0].id)
+ find_mock.assert_any_call(self.groups_mock, 'unexist_group')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.groups_mock.delete.assert_called_once_with(self.groups[0].id)
+
class TestGroupList(TestGroup):
diff --git a/openstackclient/tests/unit/identity/v3/test_mappings.py b/openstackclient/tests/unit/identity/v3/test_mappings.py
index 5086724c..93fe1196 100644
--- a/openstackclient/tests/unit/identity/v3/test_mappings.py
+++ b/openstackclient/tests/unit/identity/v3/test_mappings.py
@@ -181,16 +181,12 @@ class TestMappingSet(TestMapping):
mocker.return_value = identity_fakes.MAPPING_RULES_2
with mock.patch("openstackclient.identity.v3.mapping."
"SetMapping._read_rules", mocker):
- columns, data = self.cmd.take_action(parsed_args)
+ result = self.cmd.take_action(parsed_args)
self.mapping_mock.update.assert_called_with(
mapping=identity_fakes.mapping_id,
rules=identity_fakes.MAPPING_RULES_2)
- collist = ('id', 'rules')
- self.assertEqual(collist, columns)
- datalist = (identity_fakes.mapping_id,
- identity_fakes.MAPPING_RULES_2)
- self.assertEqual(datalist, data)
+ self.assertIsNone(result)
def test_set_rules_wrong_file_path(self):
arglist = [
diff --git a/openstackclient/tests/unit/identity/v3/test_project.py b/openstackclient/tests/unit/identity/v3/test_project.py
index 702d9209..2b898090 100644
--- a/openstackclient/tests/unit/identity/v3/test_project.py
+++ b/openstackclient/tests/unit/identity/v3/test_project.py
@@ -16,6 +16,7 @@
import mock
from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v3 import project
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@@ -445,6 +446,32 @@ class TestProjectDelete(TestProject):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_projects_with_exception(self, find_mock):
+ find_mock.side_effect = [self.project,
+ exceptions.CommandError]
+ arglist = [
+ self.project.id,
+ 'unexist_project',
+ ]
+ verifylist = [
+ ('projects', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 projects failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.projects_mock, self.project.id)
+ find_mock.assert_any_call(self.projects_mock, 'unexist_project')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.projects_mock.delete.assert_called_once_with(self.project.id)
+
class TestProjectList(TestProject):
diff --git a/openstackclient/tests/unit/identity/v3/test_role.py b/openstackclient/tests/unit/identity/v3/test_role.py
index 448e18d3..c0b68bdf 100644
--- a/openstackclient/tests/unit/identity/v3/test_role.py
+++ b/openstackclient/tests/unit/identity/v3/test_role.py
@@ -14,6 +14,10 @@
#
import copy
+import mock
+
+from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v3 import role
from openstackclient.tests.unit import fakes
@@ -428,6 +432,36 @@ class TestRoleDelete(TestRole):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_roles_with_exception(self, find_mock):
+ find_mock.side_effect = [self.roles_mock.get.return_value,
+ exceptions.CommandError]
+ arglist = [
+ identity_fakes.role_name,
+ 'unexist_role',
+ ]
+ verifylist = [
+ ('roles', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 roles failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.roles_mock,
+ identity_fakes.role_name,
+ domain_id=None)
+ find_mock.assert_any_call(self.roles_mock,
+ 'unexist_role',
+ domain_id=None)
+
+ self.assertEqual(2, find_mock.call_count)
+ self.roles_mock.delete.assert_called_once_with(identity_fakes.role_id)
+
class TestRoleList(TestRole):
diff --git a/openstackclient/tests/unit/identity/v3/test_trust.py b/openstackclient/tests/unit/identity/v3/test_trust.py
index 4eeb8bfe..93e8f63d 100644
--- a/openstackclient/tests/unit/identity/v3/test_trust.py
+++ b/openstackclient/tests/unit/identity/v3/test_trust.py
@@ -12,6 +12,10 @@
#
import copy
+import mock
+
+from osc_lib import exceptions
+from osc_lib import utils
from openstackclient.identity.v3 import trust
from openstackclient.tests.unit import fakes
@@ -148,6 +152,33 @@ class TestTrustDelete(TestTrust):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_trusts_with_exception(self, find_mock):
+ find_mock.side_effect = [self.trusts_mock.get.return_value,
+ exceptions.CommandError]
+ arglist = [
+ identity_fakes.trust_id,
+ 'unexist_trust',
+ ]
+ verifylist = [
+ ('trust', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 trusts failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.trusts_mock, identity_fakes.trust_id)
+ find_mock.assert_any_call(self.trusts_mock, 'unexist_trust')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.trusts_mock.delete.assert_called_once_with(
+ identity_fakes.trust_id)
+
class TestTrustList(TestTrust):
diff --git a/openstackclient/tests/unit/identity/v3/test_user.py b/openstackclient/tests/unit/identity/v3/test_user.py
index 6150a5f3..3c1f49a6 100644
--- a/openstackclient/tests/unit/identity/v3/test_user.py
+++ b/openstackclient/tests/unit/identity/v3/test_user.py
@@ -16,6 +16,9 @@
import contextlib
import mock
+from osc_lib import exceptions
+from osc_lib import utils
+
from openstackclient.identity.v3 import user
from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes
@@ -465,6 +468,32 @@ class TestUserDelete(TestUser):
)
self.assertIsNone(result)
+ @mock.patch.object(utils, 'find_resource')
+ def test_delete_multi_users_with_exception(self, find_mock):
+ find_mock.side_effect = [self.user,
+ exceptions.CommandError]
+ arglist = [
+ self.user.id,
+ 'unexist_user',
+ ]
+ verifylist = [
+ ('users', arglist),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ try:
+ self.cmd.take_action(parsed_args)
+ self.fail('CommandError should be raised.')
+ except exceptions.CommandError as e:
+ self.assertEqual('1 of 2 users failed to delete.',
+ str(e))
+
+ find_mock.assert_any_call(self.users_mock, self.user.id)
+ find_mock.assert_any_call(self.users_mock, 'unexist_user')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.users_mock.delete.assert_called_once_with(self.user.id)
+
class TestUserList(TestUser):
diff --git a/openstackclient/tests/unit/image/v2/test_image.py b/openstackclient/tests/unit/image/v2/test_image.py
index a054e513..164185df 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -829,6 +829,11 @@ class TestImageSet(TestImage):
self.images_mock.get.return_value = self.model(**image_fakes.IMAGE)
self.images_mock.update.return_value = self.model(**image_fakes.IMAGE)
+
+ self.app.client_manager.auth_ref = mock.Mock(
+ project_id=self.project.id,
+ )
+
# Get the command object to test
self.cmd = image.SetImage(self.app, None)
@@ -845,6 +850,101 @@ class TestImageSet(TestImage):
self.assertIsNone(result)
+ self.image_members_mock.update.assert_not_called()
+
+ def test_image_set_membership_option_accept(self):
+ membership = image_fakes.FakeImage.create_one_image_member(
+ attrs={'image_id': image_fakes.image_id,
+ 'member_id': self.project.id}
+ )
+ self.image_members_mock.update.return_value = membership
+
+ arglist = [
+ '--accept',
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ ('accept', True),
+ ('reject', False),
+ ('pending', False),
+ ('image', image_fakes.image_id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+
+ self.image_members_mock.update.assert_called_once_with(
+ image_fakes.image_id,
+ self.app.client_manager.auth_ref.project_id,
+ 'accepted',
+ )
+
+ # Assert that the 'update image" route is also called, in addition to
+ # the 'update membership' route.
+ self.images_mock.update.assert_called_with(image_fakes.image_id)
+
+ def test_image_set_membership_option_reject(self):
+ membership = image_fakes.FakeImage.create_one_image_member(
+ attrs={'image_id': image_fakes.image_id,
+ 'member_id': self.project.id}
+ )
+ self.image_members_mock.update.return_value = membership
+
+ arglist = [
+ '--reject',
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ ('accept', False),
+ ('reject', True),
+ ('pending', False),
+ ('image', image_fakes.image_id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+
+ self.image_members_mock.update.assert_called_once_with(
+ image_fakes.image_id,
+ self.app.client_manager.auth_ref.project_id,
+ 'rejected',
+ )
+
+ # Assert that the 'update image" route is also called, in addition to
+ # the 'update membership' route.
+ self.images_mock.update.assert_called_with(image_fakes.image_id)
+
+ def test_image_set_membership_option_pending(self):
+ membership = image_fakes.FakeImage.create_one_image_member(
+ attrs={'image_id': image_fakes.image_id,
+ 'member_id': self.project.id}
+ )
+ self.image_members_mock.update.return_value = membership
+
+ arglist = [
+ '--pending',
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ ('accept', False),
+ ('reject', False),
+ ('pending', True),
+ ('image', image_fakes.image_id)
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+
+ self.image_members_mock.update.assert_called_once_with(
+ image_fakes.image_id,
+ self.app.client_manager.auth_ref.project_id,
+ 'pending',
+ )
+
+ # Assert that the 'update image" route is also called, in addition to
+ # the 'update membership' route.
+ self.images_mock.update.assert_called_with(image_fakes.image_id)
+
def test_image_set_options(self):
arglist = [
'--name', 'new-name',
diff --git a/openstackclient/tests/unit/network/v2/fakes.py b/openstackclient/tests/unit/network/v2/fakes.py
index 84f145fb..524285ab 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -14,6 +14,8 @@
import argparse
import copy
import mock
+from random import choice
+from random import randint
import uuid
from openstackclient.tests.unit import fakes
@@ -37,10 +39,20 @@ QUOTA = {
"l7policy": 5,
}
+RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth-limit'
+RULE_TYPE_DSCP_MARKING = 'dscp-marking'
+RULE_TYPE_MINIMUM_BANDWIDTH = 'minimum-bandwidth'
+VALID_QOS_RULES = [RULE_TYPE_BANDWIDTH_LIMIT,
+ RULE_TYPE_DSCP_MARKING,
+ RULE_TYPE_MINIMUM_BANDWIDTH]
+VALID_DSCP_MARKS = [0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
+ 34, 36, 38, 40, 46, 48, 56]
+
class FakeNetworkV2Client(object):
def __init__(self, **kwargs):
+ self.session = mock.Mock()
self.extensions = mock.Mock()
self.extensions.resource_class = fakes.FakeResource(None, {})
@@ -553,6 +565,8 @@ class FakeNetworkAgent(object):
agent_attrs.update(attrs)
agent = fakes.FakeResource(info=copy.deepcopy(agent_attrs),
loaded=True)
+ agent.is_admin_state_up = agent_attrs['admin_state_up']
+ agent.is_alive = agent_attrs['alive']
return agent
@staticmethod
@@ -662,83 +676,90 @@ class FakeNetworkRBAC(object):
return mock.Mock(side_effect=rbac_policies)
-class FakeNetworkQosBandwidthLimitRule(object):
- """Fake one or more QoS bandwidth limit rules."""
+class FakeNetworkQosPolicy(object):
+ """Fake one or more QoS policies."""
@staticmethod
- def create_one_qos_bandwidth_limit_rule(attrs=None):
- """Create a fake QoS bandwidth limit rule.
+ def create_one_qos_policy(attrs=None):
+ """Create a fake QoS policy.
:param Dictionary attrs:
A dictionary with all attributes
:return:
- A FakeResource object with id, qos_policy_id, max_kbps and
- max_burst_kbps attributes.
+ A FakeResource object with name, id, etc.
"""
attrs = attrs or {}
+ qos_id = attrs.get('id') or 'qos-policy-id-' + uuid.uuid4().hex
+ rule_attrs = {'qos_policy_id': qos_id}
+ rules = [FakeNetworkQosRule.create_one_qos_rule(rule_attrs)]
# Set default attributes.
- qos_bandwidth_limit_rule_attrs = {
- 'id': 'qos-bandwidth-limit-rule-id-' + uuid.uuid4().hex,
- 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
- 'max_kbps': 1500,
- 'max_burst_kbps': 1200,
+ qos_policy_attrs = {
+ 'name': 'qos-policy-name-' + uuid.uuid4().hex,
+ 'id': qos_id,
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ 'shared': False,
+ 'description': 'qos-policy-description-' + uuid.uuid4().hex,
+ 'rules': rules,
}
# Overwrite default attributes.
- qos_bandwidth_limit_rule_attrs.update(attrs)
+ qos_policy_attrs.update(attrs)
- qos_bandwidth_limit_rule = fakes.FakeResource(
- info=copy.deepcopy(qos_bandwidth_limit_rule_attrs),
+ qos_policy = fakes.FakeResource(
+ info=copy.deepcopy(qos_policy_attrs),
loaded=True)
- return qos_bandwidth_limit_rule
+ # 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
@staticmethod
- def create_qos_bandwidth_limit_rules(attrs=None, count=2):
- """Create multiple fake QoS bandwidth limit rules.
+ def create_qos_policies(attrs=None, count=2):
+ """Create multiple fake QoS policies.
:param Dictionary attrs:
A dictionary with all attributes
:param int count:
- The number of QoS bandwidth limit rules to fake
+ The number of QoS policies to fake
:return:
- A list of FakeResource objects faking the QoS bandwidth limit rules
+ A list of FakeResource objects faking the QoS policies
"""
qos_policies = []
for i in range(0, count):
- qos_policies.append(FakeNetworkQosBandwidthLimitRule.
- create_one_qos_bandwidth_limit_rule(attrs))
+ qos_policies.append(
+ FakeNetworkQosPolicy.create_one_qos_policy(attrs))
return qos_policies
@staticmethod
- def get_qos_bandwidth_limit_rules(qos_rules=None, count=2):
- """Get a list of faked QoS bandwidth limit rules.
+ def get_qos_policies(qos_policies=None, count=2):
+ """Get an iterable MagicMock object with a list of faked QoS policies.
- If QoS bandwidth limit rules list is provided, then initialize the
- Mock object with the list. Otherwise create one.
+ If qos policies list is provided, then initialize the Mock object
+ with the list. Otherwise create one.
:param List address scopes:
- A list of FakeResource objects faking QoS bandwidth limit rules
+ A list of FakeResource objects faking qos policies
:param int count:
- The number of QoS bandwidth limit rules to fake
+ The number of QoS policies to fake
:return:
An iterable Mock object with side_effect set to a list of faked
- qos bandwidth limit rules
+ QoS policies
"""
- if qos_rules is None:
- qos_rules = (FakeNetworkQosBandwidthLimitRule.
- create_qos_bandwidth_limit_rules(count))
- return mock.Mock(side_effect=qos_rules)
+ if qos_policies is None:
+ qos_policies = FakeNetworkQosPolicy.create_qos_policies(count)
+ return mock.Mock(side_effect=qos_policies)
-class FakeNetworkQosPolicy(object):
- """Fake one or more QoS policies."""
+class FakeNetworkQosRule(object):
+ """Fake one or more Network QoS rules."""
@staticmethod
- def create_one_qos_policy(attrs=None):
- """Create a fake QoS policy.
+ def create_one_qos_rule(attrs=None):
+ """Create a fake Network QoS rule.
:param Dictionary attrs:
A dictionary with all attributes
@@ -746,71 +767,114 @@ class FakeNetworkQosPolicy(object):
A FakeResource object with name, id, etc.
"""
attrs = attrs or {}
- qos_id = attrs.get('id') or 'qos-policy-id-' + uuid.uuid4().hex
- rule_attrs = {'qos_policy_id': qos_id}
- rules = [
- FakeNetworkQosBandwidthLimitRule.
- create_one_qos_bandwidth_limit_rule(rule_attrs)]
# Set default attributes.
- qos_policy_attrs = {
- 'name': 'qos-policy-name-' + uuid.uuid4().hex,
- 'id': qos_id,
+ type = attrs.get('type') or choice(VALID_QOS_RULES)
+ qos_rule_attrs = {
+ 'id': 'qos-rule-id-' + uuid.uuid4().hex,
+ 'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
'tenant_id': 'project-id-' + uuid.uuid4().hex,
- 'shared': False,
- 'description': 'qos-policy-description-' + uuid.uuid4().hex,
- 'rules': rules,
+ 'type': type,
}
+ if type == RULE_TYPE_BANDWIDTH_LIMIT:
+ qos_rule_attrs['max_kbps'] = randint(1, 10000)
+ qos_rule_attrs['max_burst_kbits'] = randint(1, 10000)
+ elif type == RULE_TYPE_DSCP_MARKING:
+ qos_rule_attrs['dscp_mark'] = choice(VALID_DSCP_MARKS)
+ elif type == RULE_TYPE_MINIMUM_BANDWIDTH:
+ qos_rule_attrs['min_kbps'] = randint(1, 10000)
+ qos_rule_attrs['direction'] = 'egress'
# Overwrite default attributes.
- qos_policy_attrs.update(attrs)
+ qos_rule_attrs.update(attrs)
- qos_policy = fakes.FakeResource(
- info=copy.deepcopy(qos_policy_attrs),
- loaded=True)
+ qos_rule = fakes.FakeResource(info=copy.deepcopy(qos_rule_attrs),
+ 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']
+ qos_rule.project_id = qos_rule['tenant_id']
- return qos_policy
+ return qos_rule
@staticmethod
- def create_qos_policies(attrs=None, count=2):
- """Create multiple fake QoS policies.
+ def create_qos_rules(attrs=None, count=2):
+ """Create multiple fake Network QoS rules.
:param Dictionary attrs:
A dictionary with all attributes
:param int count:
- The number of QoS policies to fake
+ The number of Network QoS rule to fake
:return:
- A list of FakeResource objects faking the QoS policies
+ A list of FakeResource objects faking the Network QoS rules
"""
- qos_policies = []
+ qos_rules = []
for i in range(0, count):
- qos_policies.append(
- FakeNetworkQosPolicy.create_one_qos_policy(attrs))
-
- return qos_policies
+ qos_rules.append(FakeNetworkQosRule.create_one_qos_rule(attrs))
+ return qos_rules
@staticmethod
- def get_qos_policies(qos_policies=None, count=2):
- """Get an iterable MagicMock object with a list of faked QoS policies.
+ def get_qos_rules(qos_rules=None, count=2):
+ """Get a list of faked Network QoS rules.
- If qos policies list is provided, then initialize the Mock object
- with the list. Otherwise create one.
+ If Network QoS rules list is provided, then initialize the Mock
+ object with the list. Otherwise create one.
:param List address scopes:
- A list of FakeResource objects faking qos policies
+ A list of FakeResource objects faking Network QoS rules
:param int count:
- The number of QoS policies to fake
+ The number of QoS minimum bandwidth rules to fake
:return:
An iterable Mock object with side_effect set to a list of faked
- QoS policies
+ qos minimum bandwidth rules
"""
- if qos_policies is None:
- qos_policies = FakeNetworkQosPolicy.create_qos_policies(count)
- return mock.Mock(side_effect=qos_policies)
+ if qos_rules is None:
+ qos_rules = (FakeNetworkQosRule.create_qos_rules(count))
+ return mock.Mock(side_effect=qos_rules)
+
+
+class FakeNetworkQosRuleType(object):
+ """Fake one or more Network QoS rule types."""
+
+ @staticmethod
+ def create_one_qos_rule_type(attrs=None):
+ """Create a fake Network QoS rule type.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :return:
+ A FakeResource object with name, id, etc.
+ """
+ attrs = attrs or {}
+
+ # Set default attributes.
+ qos_rule_type_attrs = {
+ 'type': 'rule-type-' + uuid.uuid4().hex,
+ }
+
+ # Overwrite default attributes.
+ qos_rule_type_attrs.update(attrs)
+
+ return fakes.FakeResource(
+ info=copy.deepcopy(qos_rule_type_attrs),
+ loaded=True)
+
+ @staticmethod
+ def create_qos_rule_types(attrs=None, count=2):
+ """Create multiple fake Network QoS rule types.
+
+ :param Dictionary attrs:
+ A dictionary with all attributes
+ :param int count:
+ The number of QoS rule types to fake
+ :return:
+ A list of FakeResource objects faking the QoS rule types
+ """
+ qos_rule_types = []
+ for i in range(0, count):
+ qos_rule_types.append(
+ FakeNetworkQosRuleType.create_one_qos_rule_type(attrs))
+
+ return qos_rule_types
class FakeRouter(object):
@@ -1213,6 +1277,51 @@ class FakeFloatingIP(object):
return mock.Mock(side_effect=floating_ips)
+class FakeNetworkMeter(object):
+ """Fake network meter"""
+
+ @staticmethod
+ def create_one_meter(attrs=None):
+ """Create metering pool"""
+ attrs = attrs or {}
+
+ meter_attrs = {
+ 'id': 'meter-id-' + uuid.uuid4().hex,
+ 'name': 'meter-name-' + uuid.uuid4().hex,
+ 'description': 'meter-description-' + uuid.uuid4().hex,
+ 'tenant_id': 'project-id-' + uuid.uuid4().hex,
+ 'shared': False
+ }
+
+ meter_attrs.update(attrs)
+
+ meter = fakes.FakeResource(
+ info=copy.deepcopy(meter_attrs),
+ loaded=True)
+
+ meter.project_id = meter_attrs['tenant_id']
+
+ return meter
+
+ @staticmethod
+ def create_meter(attrs=None, count=2):
+ """Create multiple meters"""
+
+ meters = []
+ for i in range(0, count):
+ meters.append(FakeNetworkMeter.
+ create_one_meter(attrs))
+ return meters
+
+ @staticmethod
+ def get_meter(meter=None, count=2):
+ """Get a list of meters"""
+ if meter is None:
+ meter = (FakeNetworkMeter.
+ create_meter(count))
+ return mock.Mock(side_effect=meter)
+
+
class FakeSubnetPool(object):
"""Fake one or more subnet pools."""
diff --git a/openstackclient/tests/unit/network/v2/test_floating_ip.py b/openstackclient/tests/unit/network/v2/test_floating_ip.py
index 63d22bf8..e395300d 100644
--- a/openstackclient/tests/unit/network/v2/test_floating_ip.py
+++ b/openstackclient/tests/unit/network/v2/test_floating_ip.py
@@ -208,13 +208,19 @@ class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork):
super(TestDeleteFloatingIPNetwork, self).setUp()
self.network.delete_ip = mock.Mock(return_value=None)
- self.network.find_ip = (
- network_fakes.FakeFloatingIP.get_floating_ips(self.floating_ips))
# Get the command object to test
self.cmd = floating_ip.DeleteFloatingIP(self.app, self.namespace)
- def test_floating_ip_delete(self):
+ @mock.patch(
+ "openstackclient.tests.unit.network.v2.test_floating_ip." +
+ "floating_ip._find_floating_ip"
+ )
+ def test_floating_ip_delete(self, find_floating_ip_mock):
+ find_floating_ip_mock.side_effect = [
+ (self.floating_ips[0], []),
+ (self.floating_ips[1], []),
+ ]
arglist = [
self.floating_ips[0].id,
]
@@ -225,12 +231,24 @@ class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork):
result = self.cmd.take_action(parsed_args)
- self.network.find_ip.assert_called_once_with(
- self.floating_ips[0].id, ignore_missing=False)
+ find_floating_ip_mock.assert_called_once_with(
+ mock.ANY,
+ [],
+ self.floating_ips[0].id,
+ ignore_missing=False,
+ )
self.network.delete_ip.assert_called_once_with(self.floating_ips[0])
self.assertIsNone(result)
- def test_multi_floating_ips_delete(self):
+ @mock.patch(
+ "openstackclient.tests.unit.network.v2.test_floating_ip." +
+ "floating_ip._find_floating_ip"
+ )
+ def test_floating_ip_delete_multi(self, find_floating_ip_mock):
+ find_floating_ip_mock.side_effect = [
+ (self.floating_ips[0], []),
+ (self.floating_ips[1], []),
+ ]
arglist = []
verifylist = []
@@ -243,13 +261,37 @@ class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork):
result = self.cmd.take_action(parsed_args)
+ calls = [
+ call(
+ mock.ANY,
+ [],
+ self.floating_ips[0].id,
+ ignore_missing=False,
+ ),
+ call(
+ mock.ANY,
+ [],
+ self.floating_ips[1].id,
+ ignore_missing=False,
+ ),
+ ]
+ find_floating_ip_mock.assert_has_calls(calls)
+
calls = []
for f in self.floating_ips:
calls.append(call(f))
self.network.delete_ip.assert_has_calls(calls)
self.assertIsNone(result)
- def test_multi_floating_ips_delete_with_exception(self):
+ @mock.patch(
+ "openstackclient.tests.unit.network.v2.test_floating_ip." +
+ "floating_ip._find_floating_ip"
+ )
+ def test_floating_ip_delete_multi_exception(self, find_floating_ip_mock):
+ find_floating_ip_mock.side_effect = [
+ (self.floating_ips[0], []),
+ exceptions.CommandError,
+ ]
arglist = [
self.floating_ips[0].id,
'unexist_floating_ip',
@@ -260,21 +302,24 @@ class TestDeleteFloatingIPNetwork(TestFloatingIPNetwork):
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
- find_mock_result = [self.floating_ips[0], exceptions.CommandError]
- self.network.find_ip = (
- mock.Mock(side_effect=find_mock_result)
- )
-
try:
self.cmd.take_action(parsed_args)
self.fail('CommandError should be raised.')
except exceptions.CommandError as e:
self.assertEqual('1 of 2 floating_ips failed to delete.', str(e))
- self.network.find_ip.assert_any_call(
- self.floating_ips[0].id, ignore_missing=False)
- self.network.find_ip.assert_any_call(
- 'unexist_floating_ip', ignore_missing=False)
+ find_floating_ip_mock.assert_any_call(
+ mock.ANY,
+ [],
+ self.floating_ips[0].id,
+ ignore_missing=False,
+ )
+ find_floating_ip_mock.assert_any_call(
+ mock.ANY,
+ [],
+ 'unexist_floating_ip',
+ ignore_missing=False,
+ )
self.network.delete_ip.assert_called_once_with(
self.floating_ips[0]
)
@@ -534,7 +579,12 @@ class TestShowFloatingIPNetwork(TestFloatingIPNetwork):
# Get the command object to test
self.cmd = floating_ip.ShowFloatingIP(self.app, self.namespace)
- def test_floating_ip_show(self):
+ @mock.patch(
+ "openstackclient.tests.unit.network.v2.test_floating_ip." +
+ "floating_ip._find_floating_ip"
+ )
+ def test_floating_ip_show(self, find_floating_ip_mock):
+ find_floating_ip_mock.return_value = (self.floating_ip, [])
arglist = [
self.floating_ip.id,
]
@@ -545,9 +595,11 @@ class TestShowFloatingIPNetwork(TestFloatingIPNetwork):
columns, data = self.cmd.take_action(parsed_args)
- self.network.find_ip.assert_called_once_with(
+ find_floating_ip_mock.assert_called_once_with(
+ mock.ANY,
+ [],
self.floating_ip.id,
- ignore_missing=False
+ ignore_missing=False,
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/network/v2/test_ip_availability.py b/openstackclient/tests/unit/network/v2/test_ip_availability.py
index 4bdbddc4..c7c5a9b4 100644
--- a/openstackclient/tests/unit/network/v2/test_ip_availability.py
+++ b/openstackclient/tests/unit/network/v2/test_ip_availability.py
@@ -118,8 +118,10 @@ class TestListIPAvailability(TestIPAvailability):
class TestShowIPAvailability(TestIPAvailability):
+ _network = network_fakes.FakeNetwork.create_one_network()
_ip_availability = \
- network_fakes.FakeIPAvailability.create_one_ip_availability()
+ network_fakes.FakeIPAvailability.create_one_ip_availability(
+ attrs={'network_id': _network.id})
columns = (
'network_id',
@@ -144,6 +146,8 @@ class TestShowIPAvailability(TestIPAvailability):
self.network.find_network_ip_availability = mock.Mock(
return_value=self._ip_availability)
+ self.network.find_network = mock.Mock(
+ return_value=self._network)
# Get the command object to test
self.cmd = ip_availability.ShowIPAvailability(
@@ -166,8 +170,10 @@ class TestShowIPAvailability(TestIPAvailability):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
columns, data = self.cmd.take_action(parsed_args)
self.network.find_network_ip_availability.assert_called_once_with(
+ self._ip_availability.network_id,
+ ignore_missing=False)
+ self.network.find_network.assert_called_once_with(
self._ip_availability.network_name,
ignore_missing=False)
-
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/network/v2/test_meter.py b/openstackclient/tests/unit/network/v2/test_meter.py
new file mode 100644
index 00000000..b393f7fa
--- /dev/null
+++ b/openstackclient/tests/unit/network/v2/test_meter.py
@@ -0,0 +1,304 @@
+# 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 mock import call
+
+from osc_lib import exceptions
+
+from openstackclient.network.v2 import meter
+from openstackclient.tests.unit.identity.v3 import fakes as identity_fakes_v3
+from openstackclient.tests.unit.network.v2 import fakes as network_fakes
+from openstackclient.tests.unit import utils as tests_utils
+
+
+class TestMeter(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestMeter, self).setUp()
+ self.network = self.app.client_manager.network
+ self.projects_mock = self.app.client_manager.identity.projects
+ self.domains_mock = self.app.client_manager.identity.domains
+
+
+class TestCreateMeter(TestMeter):
+ project = identity_fakes_v3.FakeProject.create_one_project()
+ domain = identity_fakes_v3.FakeDomain.create_one_domain()
+
+ new_meter = (
+ network_fakes.FakeNetworkMeter.
+ create_one_meter()
+ )
+ columns = (
+ 'description',
+ 'id',
+ 'name',
+ 'project_id',
+ 'shared',
+ )
+
+ data = (
+ new_meter.description,
+ new_meter.id,
+ new_meter.name,
+ new_meter.project_id,
+ new_meter.shared,
+ )
+
+ def setUp(self):
+ super(TestCreateMeter, self).setUp()
+ self.network.create_metering_label = mock.Mock(
+ return_value=self.new_meter)
+ self.projects_mock.get.return_value = self.project
+ self.cmd = meter.CreateMeter(self.app, self.namespace)
+
+ def test_create_no_options(self):
+ arglist = []
+ verifylist = []
+
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_create_default_options(self):
+ arglist = [
+ self.new_meter.name,
+ ]
+
+ verifylist = [
+ ('name', self.new_meter.name),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_metering_label.assert_called_once_with(
+ **{'name': self.new_meter.name}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_create_all_options(self):
+ arglist = [
+ "--description", self.new_meter.description,
+ "--project", self.new_meter.project_id,
+ "--project-domain", self.domain.name,
+ "--share",
+ self.new_meter.name,
+ ]
+
+ verifylist = [
+ ('description', self.new_meter.description),
+ ('name', self.new_meter.name),
+ ('project', self.new_meter.project_id),
+ ('project_domain', self.domain.name),
+ ('share', True),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_metering_label.assert_called_once_with(
+ **{'description': self.new_meter.description,
+ 'name': self.new_meter.name,
+ 'tenant_id': self.project.id,
+ 'shared': True, }
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+
+class TestDeleteMeter(TestMeter):
+
+ def setUp(self):
+ super(TestDeleteMeter, self).setUp()
+
+ self.meter_list = \
+ network_fakes.FakeNetworkMeter.create_meter(count=2)
+
+ self.network.delete_metering_label = mock.Mock(return_value=None)
+
+ self.network.find_metering_label = network_fakes \
+ .FakeNetworkMeter.get_meter(
+ meter=self.meter_list
+ )
+
+ self.cmd = meter.DeleteMeter(self.app, self.namespace)
+
+ def test_delete_one_meter(self):
+ arglist = [
+ self.meter_list[0].name,
+ ]
+ verifylist = [
+ ('meter', [self.meter_list[0].name]),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.delete_metering_label.assert_called_once_with(
+ self.meter_list[0]
+ )
+ self.assertIsNone(result)
+
+ def test_delete_multiple_meters(self):
+ arglist = []
+ for n in self.meter_list:
+ arglist.append(n.id)
+ verifylist = [
+ ('meter', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for n in self.meter_list:
+ calls.append(call(n))
+ self.network.delete_metering_label.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+ def test_delete_multiple_meter_exception(self):
+ arglist = [
+ self.meter_list[0].id,
+ 'xxxx-yyyy-zzzz',
+ self.meter_list[1].id,
+ ]
+ verifylist = [
+ ('meter', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ return_find = [
+ self.meter_list[0],
+ exceptions.NotFound('404'),
+ self.meter_list[1],
+ ]
+ self.network.find_meter = mock.Mock(side_effect=return_find)
+
+ ret_delete = [
+ None,
+ exceptions.NotFound('404'),
+ ]
+ self.network.delete_metering_label = mock.Mock(side_effect=ret_delete)
+
+ self.assertRaises(exceptions.CommandError, self.cmd.take_action,
+ parsed_args)
+
+ calls = [
+ call(self.meter_list[0]),
+ call(self.meter_list[1]),
+ ]
+ self.network.delete_metering_label.assert_has_calls(calls)
+
+
+class TestListMeter(TestMeter):
+
+ meter_list = \
+ network_fakes.FakeNetworkMeter.create_meter(count=2)
+
+ columns = (
+ 'ID',
+ 'Name',
+ 'Description',
+ 'Shared',
+ )
+
+ data = []
+
+ for meters in meter_list:
+ data.append((
+ meters.id,
+ meters.name,
+ meters.description,
+ meters.shared,
+ ))
+
+ def setUp(self):
+ super(TestListMeter, self).setUp()
+
+ self.network.metering_labels = mock.Mock(
+ return_value=self.meter_list
+ )
+
+ self.cmd = meter.ListMeter(self.app, self.namespace)
+
+ def test_meter_list(self):
+ arglist = []
+ verifylist = []
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.metering_labels.assert_called_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+
+class TestShowMeter(TestMeter):
+ new_meter = (
+ network_fakes.FakeNetworkMeter.
+ create_one_meter()
+ )
+ columns = (
+ 'description',
+ 'id',
+ 'name',
+ 'project_id',
+ 'shared',
+ )
+
+ data = (
+ new_meter.description,
+ new_meter.id,
+ new_meter.name,
+ new_meter.project_id,
+ new_meter.shared,
+ )
+
+ def setUp(self):
+ super(TestShowMeter, self).setUp()
+
+ self.cmd = meter.ShowMeter(self.app, self.namespace)
+
+ self.network.find_metering_label = \
+ mock.Mock(return_value=self.new_meter)
+
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
+
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_meter_show_option(self):
+ arglist = [
+ self.new_meter.name,
+ ]
+ verifylist = [
+ ('meter', self.new_meter.name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.find_metering_label.assert_called_with(
+ self.new_meter.name, ignore_missing=False
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
diff --git a/openstackclient/tests/unit/network/v2/test_network_agent.py b/openstackclient/tests/unit/network/v2/test_network_agent.py
index 9f5b442a..2fc0c043 100644
--- a/openstackclient/tests/unit/network/v2/test_network_agent.py
+++ b/openstackclient/tests/unit/network/v2/test_network_agent.py
@@ -130,6 +130,7 @@ class TestListNetworkAgent(TestNetworkAgent):
)
data = []
for agent in network_agents:
+ agent.agent_type = 'DHCP agent'
data.append((
agent.id,
agent.agent_type,
@@ -159,7 +160,43 @@ class TestListNetworkAgent(TestNetworkAgent):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_network_agents_list_agent_type(self):
+ arglist = [
+ '--agent-type', 'dhcp',
+ ]
+ verifylist = [
+ ('agent_type', 'dhcp'),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.agents.assert_called_once_with(**{
+ 'agent_type': self.network_agents[0].agent_type,
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_network_agents_list_host(self):
+ arglist = [
+ '--host', self.network_agents[0].host,
+ ]
+ verifylist = [
+ ('host', self.network_agents[0].host),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.agents.assert_called_once_with(**{
+ 'host': self.network_agents[0].host,
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+# TODO(huanxuan): Also update by the new attribute name
+# "is_admin_state_up" after sdk 0.9.12
class TestSetNetworkAgent(TestNetworkAgent):
_network_agent = (
@@ -289,6 +326,6 @@ class TestShowNetworkAgent(TestNetworkAgent):
columns, data = self.cmd.take_action(parsed_args)
self.network.get_agent.assert_called_once_with(
- self._network_agent.id, ignore_missing=False)
+ self._network_agent.id)
self.assertEqual(self.columns, columns)
self.assertEqual(list(self.data), list(data))
diff --git a/openstackclient/tests/unit/network/v2/test_network_qos_rule.py b/openstackclient/tests/unit/network/v2/test_network_qos_rule.py
new file mode 100644
index 00000000..41ccae32
--- /dev/null
+++ b/openstackclient/tests/unit/network/v2/test_network_qos_rule.py
@@ -0,0 +1,1049 @@
+# 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 osc_lib import exceptions
+
+from openstackclient.network.v2 import network_qos_rule
+from openstackclient.tests.unit.network.v2 import fakes as network_fakes
+from openstackclient.tests.unit import utils as tests_utils
+
+
+RULE_TYPE_BANDWIDTH_LIMIT = 'bandwidth-limit'
+RULE_TYPE_DSCP_MARKING = 'dscp-marking'
+RULE_TYPE_MINIMUM_BANDWIDTH = 'minimum-bandwidth'
+DSCP_VALID_MARKS = [0, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32,
+ 34, 36, 38, 40, 46, 48, 56]
+
+
+class TestNetworkQosRule(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestNetworkQosRule, self).setUp()
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+ self.qos_policy = (network_fakes.FakeNetworkQosPolicy.
+ create_one_qos_policy())
+ self.network.find_qos_policy = mock.Mock(return_value=self.qos_policy)
+
+
+class TestCreateNetworkQosRuleMinimumBandwidth(TestNetworkQosRule):
+
+ def test_check_type_parameters(self):
+ pass
+
+ def setUp(self):
+ super(TestCreateNetworkQosRuleMinimumBandwidth, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_MINIMUM_BANDWIDTH}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.columns = (
+ 'direction',
+ 'id',
+ 'min_kbps',
+ 'project_id',
+ 'qos_policy_id',
+ 'type'
+ )
+
+ self.data = (
+ self.new_rule.direction,
+ self.new_rule.id,
+ self.new_rule.min_kbps,
+ self.new_rule.project_id,
+ self.new_rule.qos_policy_id,
+ self.new_rule.type,
+ )
+ self.network.create_qos_minimum_bandwidth_rule = mock.Mock(
+ return_value=self.new_rule)
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.CreateNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_create_no_options(self):
+ arglist = []
+ verifylist = []
+
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_create_default_options(self):
+ arglist = [
+ '--type', RULE_TYPE_MINIMUM_BANDWIDTH,
+ '--min-kbps', str(self.new_rule.min_kbps),
+ '--egress',
+ self.new_rule.qos_policy_id,
+ ]
+
+ verifylist = [
+ ('type', RULE_TYPE_MINIMUM_BANDWIDTH),
+ ('min_kbps', self.new_rule.min_kbps),
+ ('egress', True),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_qos_minimum_bandwidth_rule.assert_called_once_with(
+ self.qos_policy.id,
+ **{'min_kbps': self.new_rule.min_kbps,
+ 'direction': self.new_rule.direction}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_create_wrong_options(self):
+ arglist = [
+ '--type', RULE_TYPE_MINIMUM_BANDWIDTH,
+ '--max-kbps', '10000',
+ self.new_rule.qos_policy_id,
+ ]
+
+ verifylist = [
+ ('type', RULE_TYPE_MINIMUM_BANDWIDTH),
+ ('max_kbps', 10000),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('"Create" rule command for type "minimum-bandwidth" '
+ 'requires arguments min_kbps, direction')
+ self.assertEqual(msg, str(e))
+
+
+class TestCreateNetworkQosRuleDSCPMarking(TestNetworkQosRule):
+
+ def test_check_type_parameters(self):
+ pass
+
+ def setUp(self):
+ super(TestCreateNetworkQosRuleDSCPMarking, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_DSCP_MARKING}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.columns = (
+ 'dscp_mark',
+ 'id',
+ 'project_id',
+ 'qos_policy_id',
+ 'type'
+ )
+
+ self.data = (
+ self.new_rule.dscp_mark,
+ self.new_rule.id,
+ self.new_rule.project_id,
+ self.new_rule.qos_policy_id,
+ self.new_rule.type,
+ )
+ self.network.create_qos_dscp_marking_rule = mock.Mock(
+ return_value=self.new_rule)
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.CreateNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_create_no_options(self):
+ arglist = []
+ verifylist = []
+
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_create_default_options(self):
+ arglist = [
+ '--type', RULE_TYPE_DSCP_MARKING,
+ '--dscp-mark', str(self.new_rule.dscp_mark),
+ self.new_rule.qos_policy_id,
+ ]
+
+ verifylist = [
+ ('type', RULE_TYPE_DSCP_MARKING),
+ ('dscp_mark', self.new_rule.dscp_mark),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.create_qos_dscp_marking_rule.assert_called_once_with(
+ self.qos_policy.id,
+ **{'dscp_mark': self.new_rule.dscp_mark}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_create_wrong_options(self):
+ arglist = [
+ '--type', RULE_TYPE_DSCP_MARKING,
+ '--max-kbps', '10000',
+ self.new_rule.qos_policy_id,
+ ]
+
+ verifylist = [
+ ('type', RULE_TYPE_DSCP_MARKING),
+ ('max_kbps', 10000),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('"Create" rule command for type "dscp-marking" '
+ 'requires arguments dscp_mark')
+ self.assertEqual(msg, str(e))
+
+
+class TestCreateNetworkQosRuleBandwidtLimit(TestNetworkQosRule):
+
+ def test_check_type_parameters(self):
+ pass
+
+ def setUp(self):
+ super(TestCreateNetworkQosRuleBandwidtLimit, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_BANDWIDTH_LIMIT}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.columns = (
+ 'id',
+ 'max_burst_kbits',
+ 'max_kbps',
+ 'project_id',
+ 'qos_policy_id',
+ 'type'
+ )
+
+ self.data = (
+ self.new_rule.id,
+ self.new_rule.max_burst_kbits,
+ self.new_rule.max_kbps,
+ self.new_rule.project_id,
+ self.new_rule.qos_policy_id,
+ self.new_rule.type,
+ )
+ self.network.create_qos_bandwidth_limit_rule = mock.Mock(
+ return_value=self.new_rule)
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.CreateNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_create_no_options(self):
+ arglist = []
+ verifylist = []
+
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_create_default_options(self):
+ arglist = [
+ '--type', RULE_TYPE_BANDWIDTH_LIMIT,
+ '--max-kbps', str(self.new_rule.max_kbps),
+ '--max-burst-kbits', str(self.new_rule.max_burst_kbits),
+ self.new_rule.qos_policy_id,
+ ]
+
+ verifylist = [
+ ('type', RULE_TYPE_BANDWIDTH_LIMIT),
+ ('max_kbps', self.new_rule.max_kbps),
+ ('max_burst_kbits', self.new_rule.max_burst_kbits),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = (self.cmd.take_action(parsed_args))
+
+ self.network.create_qos_bandwidth_limit_rule.assert_called_once_with(
+ self.qos_policy.id,
+ **{'max_kbps': self.new_rule.max_kbps,
+ 'max_burst_kbps': self.new_rule.max_burst_kbits}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
+ def test_create_wrong_options(self):
+ arglist = [
+ '--type', RULE_TYPE_BANDWIDTH_LIMIT,
+ '--min-kbps', '10000',
+ self.new_rule.qos_policy_id,
+ ]
+
+ verifylist = [
+ ('type', RULE_TYPE_BANDWIDTH_LIMIT),
+ ('min_kbps', 10000),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('"Create" rule command for type "bandwidth-limit" '
+ 'requires arguments max_kbps, max_burst_kbps')
+ self.assertEqual(msg, str(e))
+
+
+class TestDeleteNetworkQosRuleMinimumBandwidth(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestDeleteNetworkQosRuleMinimumBandwidth, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_MINIMUM_BANDWIDTH}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.network.delete_qos_minimum_bandwidth_rule = mock.Mock(
+ return_value=None)
+ self.network.find_qos_minimum_bandwidth_rule = (
+ network_fakes.FakeNetworkQosRule.get_qos_rules(
+ qos_rules=self.new_rule)
+ )
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.DeleteNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_qos_policy_delete(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ self.network.find_qos_policy.assert_called_once_with(
+ self.qos_policy.id, ignore_missing=False)
+ self.network.delete_qos_minimum_bandwidth_rule.assert_called_once_with(
+ self.new_rule.id, self.qos_policy.id)
+ self.assertIsNone(result)
+
+ def test_qos_policy_delete_error(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ self.network.delete_qos_minimum_bandwidth_rule.side_effect = \
+ Exception('Error message')
+ try:
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('Failed to delete Network QoS rule ID "%(rule)s": %(e)s' %
+ {'rule': self.new_rule.id, 'e': 'Error message'})
+ self.assertEqual(msg, str(e))
+
+
+class TestDeleteNetworkQosRuleDSCPMarking(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestDeleteNetworkQosRuleDSCPMarking, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_DSCP_MARKING}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.network.delete_qos_dscp_marking_rule = mock.Mock(
+ return_value=None)
+ self.network.find_qos_dscp_marking_rule = (
+ network_fakes.FakeNetworkQosRule.get_qos_rules(
+ qos_rules=self.new_rule)
+ )
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.DeleteNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_qos_policy_delete(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ self.network.find_qos_policy.assert_called_once_with(
+ self.qos_policy.id, ignore_missing=False)
+ self.network.delete_qos_dscp_marking_rule.assert_called_once_with(
+ self.new_rule.id, self.qos_policy.id)
+ self.assertIsNone(result)
+
+ def test_qos_policy_delete_error(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ self.network.delete_qos_dscp_marking_rule.side_effect = \
+ Exception('Error message')
+ try:
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('Failed to delete Network QoS rule ID "%(rule)s": %(e)s' %
+ {'rule': self.new_rule.id, 'e': 'Error message'})
+ self.assertEqual(msg, str(e))
+
+
+class TestDeleteNetworkQosRuleBandwidthLimit(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestDeleteNetworkQosRuleBandwidthLimit, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_BANDWIDTH_LIMIT}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.network.delete_qos_bandwidth_limit_rule = mock.Mock(
+ return_value=None)
+ self.network.find_qos_bandwidth_limit_rule = (
+ network_fakes.FakeNetworkQosRule.get_qos_rules(
+ qos_rules=self.new_rule)
+ )
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.DeleteNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_qos_policy_delete(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ self.network.find_qos_policy.assert_called_once_with(
+ self.qos_policy.id, ignore_missing=False)
+ self.network.delete_qos_bandwidth_limit_rule.assert_called_once_with(
+ self.new_rule.id, self.qos_policy.id)
+ self.assertIsNone(result)
+
+ def test_qos_policy_delete_error(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ self.network.delete_qos_bandwidth_limit_rule.side_effect = \
+ Exception('Error message')
+ try:
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('Failed to delete Network QoS rule ID "%(rule)s": %(e)s' %
+ {'rule': self.new_rule.id, 'e': 'Error message'})
+ self.assertEqual(msg, str(e))
+
+
+class TestSetNetworkQosRuleMinimumBandwidth(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestSetNetworkQosRuleMinimumBandwidth, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_MINIMUM_BANDWIDTH}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs=attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.network.update_qos_minimum_bandwidth_rule = mock.Mock(
+ return_value=None)
+ self.network.find_qos_minimum_bandwidth_rule = mock.Mock(
+ return_value=self.new_rule)
+ self.network.find_qos_policy = mock.Mock(
+ return_value=self.qos_policy)
+
+ # Get the command object to test
+ self.cmd = (network_qos_rule.SetNetworkQosRule(self.app,
+ self.namespace))
+
+ def test_set_nothing(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.update_qos_minimum_bandwidth_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id)
+ self.assertIsNone(result)
+
+ def test_set_min_kbps(self):
+ self._set_min_kbps()
+
+ def test_set_min_kbps_to_zero(self):
+ self._set_min_kbps(min_kbps=0)
+
+ def _set_min_kbps(self, min_kbps=None):
+ if min_kbps:
+ previous_min_kbps = self.new_rule.min_kbps
+ self.new_rule.min_kbps = min_kbps
+
+ arglist = [
+ '--min-kbps', str(self.new_rule.min_kbps),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('min_kbps', self.new_rule.min_kbps),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ attrs = {
+ 'min_kbps': self.new_rule.min_kbps,
+ }
+ self.network.update_qos_minimum_bandwidth_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id, **attrs)
+ self.assertIsNone(result)
+
+ if min_kbps:
+ self.new_rule.min_kbps = previous_min_kbps
+
+ def test_set_wrong_options(self):
+ arglist = [
+ '--max-kbps', str(10000),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('max_kbps', 10000),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('Failed to set Network QoS rule ID "%(rule)s": Rule type '
+ '"minimum-bandwidth" only requires arguments min_kbps, '
+ 'direction' % {'rule': self.new_rule.id})
+ self.assertEqual(msg, str(e))
+
+
+class TestSetNetworkQosRuleDSCPMarking(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestSetNetworkQosRuleDSCPMarking, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_DSCP_MARKING}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs=attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.network.update_qos_dscp_marking_rule = mock.Mock(
+ return_value=None)
+ self.network.find_qos_dscp_marking_rule = mock.Mock(
+ return_value=self.new_rule)
+ self.network.find_qos_policy = mock.Mock(
+ return_value=self.qos_policy)
+
+ # Get the command object to test
+ self.cmd = (network_qos_rule.SetNetworkQosRule(self.app,
+ self.namespace))
+
+ def test_set_nothing(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.update_qos_dscp_marking_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id)
+ self.assertIsNone(result)
+
+ def test_set_dscp_mark(self):
+ self._set_dscp_mark()
+
+ def test_set_dscp_mark_to_zero(self):
+ self._set_dscp_mark(dscp_mark=0)
+
+ def _set_dscp_mark(self, dscp_mark=None):
+ if dscp_mark:
+ previous_dscp_mark = self.new_rule.dscp_mark
+ self.new_rule.dscp_mark = dscp_mark
+
+ arglist = [
+ '--dscp-mark', str(self.new_rule.dscp_mark),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('dscp_mark', self.new_rule.dscp_mark),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ attrs = {
+ 'dscp_mark': self.new_rule.dscp_mark,
+ }
+ self.network.update_qos_dscp_marking_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id, **attrs)
+ self.assertIsNone(result)
+
+ if dscp_mark:
+ self.new_rule.dscp_mark = previous_dscp_mark
+
+ def test_set_wrong_options(self):
+ arglist = [
+ '--max-kbps', str(10000),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('max_kbps', 10000),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('Failed to set Network QoS rule ID "%(rule)s": Rule type '
+ '"dscp-marking" only requires arguments dscp_mark' %
+ {'rule': self.new_rule.id})
+ self.assertEqual(msg, str(e))
+
+
+class TestSetNetworkQosRuleBandwidthLimit(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestSetNetworkQosRuleBandwidthLimit, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_BANDWIDTH_LIMIT}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs=attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.network.update_qos_bandwidth_limit_rule = mock.Mock(
+ return_value=None)
+ self.network.find_qos_bandwidth_limit_rule = mock.Mock(
+ return_value=self.new_rule)
+ self.network.find_qos_policy = mock.Mock(
+ return_value=self.qos_policy)
+
+ # Get the command object to test
+ self.cmd = (network_qos_rule.SetNetworkQosRule(self.app,
+ self.namespace))
+
+ def test_set_nothing(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ self.network.update_qos_bandwidth_limit_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id)
+ self.assertIsNone(result)
+
+ def test_set_max_kbps(self):
+ self._set_max_kbps()
+
+ def test_set_max_kbps_to_zero(self):
+ self._set_max_kbps(max_kbps=0)
+
+ def _set_max_kbps(self, max_kbps=None):
+ if max_kbps:
+ previous_max_kbps = self.new_rule.max_kbps
+ self.new_rule.max_kbps = max_kbps
+
+ arglist = [
+ '--max-kbps', str(self.new_rule.max_kbps),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('max_kbps', self.new_rule.max_kbps),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ attrs = {
+ 'max_kbps': self.new_rule.max_kbps,
+ }
+ self.network.update_qos_bandwidth_limit_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id, **attrs)
+ self.assertIsNone(result)
+
+ if max_kbps:
+ self.new_rule.max_kbps = previous_max_kbps
+
+ def test_set_max_burst_kbits(self):
+ self._set_max_burst_kbits()
+
+ def test_set_max_burst_kbits_to_zero(self):
+ self._set_max_burst_kbits(max_burst_kbits=0)
+
+ def _set_max_burst_kbits(self, max_burst_kbits=None):
+ if max_burst_kbits:
+ previous_max_burst_kbits = self.new_rule.max_burst_kbits
+ self.new_rule.max_burst_kbits = max_burst_kbits
+
+ arglist = [
+ '--max-burst-kbits', str(self.new_rule.max_burst_kbits),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('max_burst_kbits', self.new_rule.max_burst_kbits),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ attrs = {
+ 'max_burst_kbps': self.new_rule.max_burst_kbits,
+ }
+ self.network.update_qos_bandwidth_limit_rule.assert_called_with(
+ self.new_rule, self.qos_policy.id, **attrs)
+ self.assertIsNone(result)
+
+ if max_burst_kbits:
+ self.new_rule.max_burst_kbits = previous_max_burst_kbits
+
+ def test_set_wrong_options(self):
+ arglist = [
+ '--min-kbps', str(10000),
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('min_kbps', 10000),
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ try:
+ self.cmd.take_action(parsed_args)
+ except exceptions.CommandError as e:
+ msg = ('Failed to set Network QoS rule ID "%(rule)s": Rule type '
+ '"bandwidth-limit" only requires arguments max_kbps, '
+ 'max_burst_kbps' % {'rule': self.new_rule.id})
+ self.assertEqual(msg, str(e))
+
+
+class TestListNetworkQosRule(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestListNetworkQosRule, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_MINIMUM_BANDWIDTH}
+ self.new_rule_min_bw = (network_fakes.FakeNetworkQosRule.
+ create_one_qos_rule(attrs=attrs))
+ attrs['type'] = RULE_TYPE_DSCP_MARKING
+ self.new_rule_dscp_mark = (network_fakes.FakeNetworkQosRule.
+ create_one_qos_rule(attrs=attrs))
+ attrs['type'] = RULE_TYPE_BANDWIDTH_LIMIT
+ self.new_rule_max_bw = (network_fakes.FakeNetworkQosRule.
+ create_one_qos_rule(attrs=attrs))
+ self.qos_policy.rules = [self.new_rule_min_bw,
+ self.new_rule_dscp_mark,
+ self.new_rule_max_bw]
+ self.network.find_qos_minimum_bandwidth_rule = mock.Mock(
+ return_value=self.new_rule_min_bw)
+ self.network.find_qos_dscp_marking_rule = mock.Mock(
+ return_value=self.new_rule_dscp_mark)
+ self.network.find_qos_bandwidth_limit_rule = mock.Mock(
+ return_value=self.new_rule_max_bw)
+ self.columns = (
+ 'ID',
+ 'QoS Policy ID',
+ 'Type',
+ 'Max Kbps',
+ 'Max Burst Kbits',
+ 'Min Kbps',
+ 'DSCP mark',
+ 'Direction',
+ )
+ self.data = []
+ for index in range(len(self.qos_policy.rules)):
+ self.data.append((
+ self.qos_policy.rules[index].id,
+ self.qos_policy.rules[index].qos_policy_id,
+ self.qos_policy.rules[index].type,
+ getattr(self.qos_policy.rules[index], 'max_kbps', ''),
+ getattr(self.qos_policy.rules[index], 'max_burst_kbps', ''),
+ getattr(self.qos_policy.rules[index], 'min_kbps', ''),
+ getattr(self.qos_policy.rules[index], 'dscp_mark', ''),
+ getattr(self.qos_policy.rules[index], 'direction', ''),
+ ))
+ # Get the command object to test
+ self.cmd = network_qos_rule.ListNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_qos_rule_list(self):
+ arglist = [
+ self.qos_policy.id
+ ]
+ verifylist = [
+ ('qos_policy', self.qos_policy.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.find_qos_policy.assert_called_once_with(
+ self.qos_policy.id, ignore_missing=False)
+ self.assertEqual(self.columns, columns)
+ list_data = list(data)
+ self.assertEqual(len(self.data), len(list_data))
+ for index in range(len(list_data)):
+ self.assertEqual(self.data[index], list_data[index])
+
+
+class TestShowNetworkQosRuleMinimumBandwidth(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestShowNetworkQosRuleMinimumBandwidth, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_MINIMUM_BANDWIDTH}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.columns = (
+ 'direction',
+ 'id',
+ 'min_kbps',
+ 'project_id',
+ 'qos_policy_id',
+ 'type'
+ )
+ self.data = (
+ self.new_rule.direction,
+ self.new_rule.id,
+ self.new_rule.min_kbps,
+ self.new_rule.project_id,
+ self.new_rule.qos_policy_id,
+ self.new_rule.type,
+ )
+
+ self.network.get_qos_minimum_bandwidth_rule = mock.Mock(
+ return_value=self.new_rule)
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.ShowNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
+
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_show_all_options(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.get_qos_minimum_bandwidth_rule.assert_called_once_with(
+ self.new_rule.id, self.qos_policy.id)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(list(self.data), list(data))
+
+
+class TestShowNetworkQosDSCPMarking(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestShowNetworkQosDSCPMarking, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_DSCP_MARKING}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.columns = (
+ 'dscp_mark',
+ 'id',
+ 'project_id',
+ 'qos_policy_id',
+ 'type'
+ )
+ self.data = (
+ self.new_rule.dscp_mark,
+ self.new_rule.id,
+ self.new_rule.project_id,
+ self.new_rule.qos_policy_id,
+ self.new_rule.type,
+ )
+
+ self.network.get_qos_dscp_marking_rule = mock.Mock(
+ return_value=self.new_rule)
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.ShowNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
+
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_show_all_options(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.get_qos_dscp_marking_rule.assert_called_once_with(
+ self.new_rule.id, self.qos_policy.id)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(list(self.data), list(data))
+
+
+class TestShowNetworkQosBandwidthLimit(TestNetworkQosRule):
+
+ def setUp(self):
+ super(TestShowNetworkQosBandwidthLimit, self).setUp()
+ attrs = {'qos_policy_id': self.qos_policy.id,
+ 'type': RULE_TYPE_BANDWIDTH_LIMIT}
+ self.new_rule = network_fakes.FakeNetworkQosRule.create_one_qos_rule(
+ attrs)
+ self.qos_policy.rules = [self.new_rule]
+ self.columns = (
+ 'id',
+ 'max_burst_kbits',
+ 'max_kbps',
+ 'project_id',
+ 'qos_policy_id',
+ 'type'
+ )
+ self.data = (
+ self.new_rule.id,
+ self.new_rule.max_burst_kbits,
+ self.new_rule.max_kbps,
+ self.new_rule.project_id,
+ self.new_rule.qos_policy_id,
+ self.new_rule.type,
+ )
+
+ self.network.get_qos_bandwidth_limit_rule = mock.Mock(
+ return_value=self.new_rule)
+
+ # Get the command object to test
+ self.cmd = network_qos_rule.ShowNetworkQosRule(self.app,
+ self.namespace)
+
+ def test_show_no_options(self):
+ arglist = []
+ verifylist = []
+
+ # Missing required args should bail here
+ self.assertRaises(tests_utils.ParserException, self.check_parser,
+ self.cmd, arglist, verifylist)
+
+ def test_show_all_options(self):
+ arglist = [
+ self.new_rule.qos_policy_id,
+ self.new_rule.id,
+ ]
+ verifylist = [
+ ('qos_policy', self.new_rule.qos_policy_id),
+ ('id', self.new_rule.id),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.get_qos_bandwidth_limit_rule.assert_called_once_with(
+ self.new_rule.id, self.qos_policy.id)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(list(self.data), list(data))
diff --git a/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py b/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py
new file mode 100644
index 00000000..b93abe80
--- /dev/null
+++ b/openstackclient/tests/unit/network/v2/test_network_qos_rule_type.py
@@ -0,0 +1,62 @@
+# 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_qos_rule_type as _qos_rule_type
+from openstackclient.tests.unit.network.v2 import fakes as network_fakes
+
+
+class TestNetworkQosRuleType(network_fakes.TestNetworkV2):
+
+ def setUp(self):
+ super(TestNetworkQosRuleType, self).setUp()
+ # Get a shortcut to the network client
+ self.network = self.app.client_manager.network
+
+
+class TestListNetworkQosRuleType(TestNetworkQosRuleType):
+
+ # The QoS policies to list up.
+ qos_rule_types = (
+ network_fakes.FakeNetworkQosRuleType.create_qos_rule_types(count=3))
+ columns = (
+ 'Type',
+ )
+ data = []
+ for qos_rule_type in qos_rule_types:
+ data.append((
+ qos_rule_type.type,
+ ))
+
+ def setUp(self):
+ super(TestListNetworkQosRuleType, self).setUp()
+ self.network.qos_rule_types = mock.Mock(
+ return_value=self.qos_rule_types)
+
+ # Get the command object to test
+ self.cmd = _qos_rule_type.ListNetworkQosRuleType(self.app,
+ self.namespace)
+
+ def test_qos_rule_type_list(self):
+ arglist = []
+ verifylist = []
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.qos_rule_types.assert_called_once_with(**{})
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
diff --git a/openstackclient/tests/unit/network/v2/test_network_rbac.py b/openstackclient/tests/unit/network/v2/test_network_rbac.py
index b884dbc0..935ce075 100644
--- a/openstackclient/tests/unit/network/v2/test_network_rbac.py
+++ b/openstackclient/tests/unit/network/v2/test_network_rbac.py
@@ -327,7 +327,12 @@ class TestListNetworkRABC(TestNetworkRBAC):
'Object Type',
'Object ID',
)
-
+ columns_long = (
+ 'ID',
+ 'Object Type',
+ 'Object ID',
+ 'Action',
+ )
data = []
for r in rbac_policies:
data.append((
@@ -335,6 +340,14 @@ class TestListNetworkRABC(TestNetworkRBAC):
r.object_type,
r.object_id,
))
+ data_long = []
+ for r in rbac_policies:
+ data_long.append((
+ r.id,
+ r.object_type,
+ r.object_id,
+ r.action,
+ ))
def setUp(self):
super(TestListNetworkRABC, self).setUp()
@@ -356,6 +369,55 @@ class TestListNetworkRABC(TestNetworkRBAC):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_network_rbac_list_type_opt(self):
+ arglist = [
+ '--type', self.rbac_policies[0].object_type, ]
+ verifylist = [
+ ('type', self.rbac_policies[0].object_type)]
+ 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.rbac_policies.assert_called_with(**{
+ 'object_type': self.rbac_policies[0].object_type
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_network_rbac_list_action_opt(self):
+ arglist = [
+ '--action', self.rbac_policies[0].action, ]
+ verifylist = [
+ ('action', self.rbac_policies[0].action)]
+ 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.rbac_policies.assert_called_with(**{
+ 'action': self.rbac_policies[0].action
+ })
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_network_rbac_list_with_long(self):
+ arglist = [
+ '--long',
+ ]
+
+ verifylist = [
+ ('long', True),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.rbac_policies.assert_called_with()
+ self.assertEqual(self.columns_long, columns)
+ self.assertEqual(self.data_long, list(data))
+
class TestSetNetworkRBAC(TestNetworkRBAC):
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index 9183cb63..b837afd1 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -704,10 +704,10 @@ class TestSetRouter(TestRouter):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
-
+ routes = [{'destination': '10.20.30.0/24',
+ 'nexthop': '10.20.30.1'}]
attrs = {
- 'routes': self._router.routes + [{'destination': '10.20.30.0/24',
- 'nexthop': '10.20.30.1'}],
+ 'routes': routes + self._router.routes
}
self.network.update_router.assert_called_once_with(
self._router, **attrs)
@@ -733,21 +733,31 @@ class TestSetRouter(TestRouter):
self._router, **attrs)
self.assertIsNone(result)
- def test_set_route_no_route(self):
+ def test_set_route_overwrite_route(self):
+ _testrouter = network_fakes.FakeRouter.create_one_router(
+ {'routes': [{"destination": "10.0.0.2",
+ "nexthop": "1.1.1.1"}]})
+ self.network.find_router = mock.Mock(return_value=_testrouter)
arglist = [
- self._router.name,
+ _testrouter.name,
'--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
'--no-route',
]
verifylist = [
- ('router', self._router.name),
+ ('router', _testrouter.name),
('routes', [{'destination': '10.20.30.0/24',
'gateway': '10.20.30.1'}]),
('no_route', True),
]
-
- self.assertRaises(tests_utils.ParserException, self.check_parser,
- self.cmd, arglist, verifylist)
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ attrs = {
+ 'routes': [{'destination': '10.20.30.0/24',
+ 'nexthop': '10.20.30.1'}]
+ }
+ self.network.update_router.assert_called_once_with(
+ _testrouter, **attrs)
+ self.assertIsNone(result)
def test_set_clear_routes(self):
arglist = [
@@ -769,21 +779,31 @@ class TestSetRouter(TestRouter):
self._router, **attrs)
self.assertIsNone(result)
- def test_set_route_clear_routes(self):
+ def test_overwrite_route_clear_routes(self):
+ _testrouter = network_fakes.FakeRouter.create_one_router(
+ {'routes': [{"destination": "10.0.0.2",
+ "nexthop": "1.1.1.1"}]})
+ self.network.find_router = mock.Mock(return_value=_testrouter)
arglist = [
- self._router.name,
+ _testrouter.name,
'--route', 'destination=10.20.30.0/24,gateway=10.20.30.1',
'--clear-routes',
]
verifylist = [
- ('router', self._router.name),
+ ('router', _testrouter.name),
('routes', [{'destination': '10.20.30.0/24',
'gateway': '10.20.30.1'}]),
('clear_routes', True),
]
-
- self.assertRaises(tests_utils.ParserException, self.check_parser,
- self.cmd, arglist, verifylist)
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ attrs = {
+ 'routes': [{'destination': '10.20.30.0/24',
+ 'nexthop': '10.20.30.1'}]
+ }
+ self.network.update_router.assert_called_once_with(
+ _testrouter, **attrs)
+ self.assertIsNone(result)
def test_set_nothing(self):
arglist = [
@@ -1021,3 +1041,16 @@ class TestUnsetRouter(TestRouter):
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
self.assertRaises(exceptions.CommandError,
self.cmd.take_action, parsed_args)
+
+ def test_unset_router_external_gateway(self):
+ arglist = [
+ '--external-gateway',
+ self._testrouter.name,
+ ]
+ verifylist = [('external_gateway', True)]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+ attrs = {'external_gateway_info': {}}
+ self.network.update_router.assert_called_once_with(
+ self._testrouter, **attrs)
+ self.assertIsNone(result)
diff --git a/openstackclient/tests/unit/network/v2/test_security_group.py b/openstackclient/tests/unit/network/v2/test_security_group.py
index 43aa07cc..9a30267e 100644
--- a/openstackclient/tests/unit/network/v2/test_security_group.py
+++ b/openstackclient/tests/unit/network/v2/test_security_group.py
@@ -456,7 +456,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
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.security_groups.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -476,7 +476,7 @@ class TestListSecurityGroupNetwork(TestSecurityGroupNetwork):
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.security_groups.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
diff --git a/openstackclient/tests/unit/volume/v2/fakes.py b/openstackclient/tests/unit/volume/v2/fakes.py
index d5cd72ec..a6676403 100644
--- a/openstackclient/tests/unit/volume/v2/fakes.py
+++ b/openstackclient/tests/unit/volume/v2/fakes.py
@@ -903,3 +903,23 @@ class FakeType(object):
volume_types.append(volume_type)
return volume_types
+
+ @staticmethod
+ def get_types(types=None, count=2):
+ """Get an iterable MagicMock object with a list of faked types.
+
+ If types list is provided, then initialize the Mock object with the
+ list. Otherwise create one.
+
+ :param List types:
+ A list of FakeResource objects faking types
+ :param Integer count:
+ The number of types to be faked
+ :return
+ An iterable Mock object with side_effect set to a list of faked
+ types
+ """
+ if types is None:
+ types = FakeType.create_types(count)
+
+ return mock.Mock(side_effect=types)
diff --git a/openstackclient/tests/unit/volume/v2/test_backup.py b/openstackclient/tests/unit/volume/v2/test_backup.py
index 10e7aac5..a8e81c7e 100644
--- a/openstackclient/tests/unit/volume/v2/test_backup.py
+++ b/openstackclient/tests/unit/volume/v2/test_backup.py
@@ -418,6 +418,30 @@ class TestBackupSet(TestBackup):
self.backup.id, **{'name': 'new_name'})
self.assertIsNone(result)
+ def test_backup_set_description(self):
+ arglist = [
+ '--description', 'new_description',
+ self.backup.id,
+ ]
+ verifylist = [
+ ('name', None),
+ ('description', 'new_description'),
+ ('backup', self.backup.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'description': 'new_description'
+ }
+ self.backups_mock.update.assert_called_once_with(
+ self.backup.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
def test_backup_set_state(self):
arglist = [
'--state', 'error',
diff --git a/openstackclient/tests/unit/volume/v2/test_consistency_group.py b/openstackclient/tests/unit/volume/v2/test_consistency_group.py
index bc99ca8d..6eeeae39 100644
--- a/openstackclient/tests/unit/volume/v2/test_consistency_group.py
+++ b/openstackclient/tests/unit/volume/v2/test_consistency_group.py
@@ -36,10 +36,115 @@ class TestConsistencyGroup(volume_fakes.TestVolume):
self.app.client_manager.volume.cgsnapshots)
self.cgsnapshots_mock.reset_mock()
+ self.volumes_mock = (
+ self.app.client_manager.volume.volumes)
+ self.volumes_mock.reset_mock()
+
self.types_mock = self.app.client_manager.volume.volume_types
self.types_mock.reset_mock()
+class TestConsistencyGroupAddVolume(TestConsistencyGroup):
+
+ _consistency_group = (
+ volume_fakes.FakeConsistencyGroup.create_one_consistency_group())
+
+ def setUp(self):
+ super(TestConsistencyGroupAddVolume, self).setUp()
+
+ self.consistencygroups_mock.get.return_value = (
+ self._consistency_group)
+ # Get the command object to test
+ self.cmd = \
+ consistency_group.AddVolumeToConsistencyGroup(self.app, None)
+
+ def test_add_one_volume_to_consistency_group(self):
+ volume = volume_fakes.FakeVolume.create_one_volume()
+ self.volumes_mock.get.return_value = volume
+ arglist = [
+ self._consistency_group.id,
+ volume.id,
+ ]
+ verifylist = [
+ ('consistency_group', self._consistency_group.id),
+ ('volumes', [volume.id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'add_volumes': volume.id,
+ }
+ self.consistencygroups_mock.update.assert_called_once_with(
+ self._consistency_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_add_multiple_volumes_to_consistency_group(self):
+ volumes = volume_fakes.FakeVolume.create_volumes(count=2)
+ self.volumes_mock.get = volume_fakes.FakeVolume.get_volumes(volumes)
+ arglist = [
+ self._consistency_group.id,
+ volumes[0].id,
+ volumes[1].id,
+ ]
+ verifylist = [
+ ('consistency_group', self._consistency_group.id),
+ ('volumes', [volumes[0].id, volumes[1].id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'add_volumes': volumes[0].id + ',' + volumes[1].id,
+ }
+ self.consistencygroups_mock.update.assert_called_once_with(
+ self._consistency_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ @mock.patch.object(consistency_group.LOG, 'error')
+ def test_add_multiple_volumes_to_consistency_group_with_exception(
+ self, mock_error):
+ volume = volume_fakes.FakeVolume.create_one_volume()
+ arglist = [
+ self._consistency_group.id,
+ volume.id,
+ 'unexist_volume',
+ ]
+ verifylist = [
+ ('consistency_group', self._consistency_group.id),
+ ('volumes', [volume.id, 'unexist_volume']),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ find_mock_result = [volume,
+ exceptions.CommandError,
+ self._consistency_group]
+ with mock.patch.object(utils, 'find_resource',
+ side_effect=find_mock_result) as find_mock:
+ result = self.cmd.take_action(parsed_args)
+ mock_error.assert_called_with("1 of 2 volumes failed to add.")
+ self.assertIsNone(result)
+ find_mock.assert_any_call(self.consistencygroups_mock,
+ self._consistency_group.id)
+ find_mock.assert_any_call(self.volumes_mock,
+ volume.id)
+ find_mock.assert_any_call(self.volumes_mock,
+ 'unexist_volume')
+ self.assertEqual(3, find_mock.call_count)
+ self.consistencygroups_mock.update.assert_called_once_with(
+ self._consistency_group.id, add_volumes=volume.id
+ )
+
+
class TestConsistencyGroupCreate(TestConsistencyGroup):
volume_type = volume_fakes.FakeType.create_one_type()
@@ -394,6 +499,107 @@ class TestConsistencyGroupList(TestConsistencyGroup):
self.assertEqual(self.data_long, list(data))
+class TestConsistencyGroupRemoveVolume(TestConsistencyGroup):
+
+ _consistency_group = (
+ volume_fakes.FakeConsistencyGroup.create_one_consistency_group())
+
+ def setUp(self):
+ super(TestConsistencyGroupRemoveVolume, self).setUp()
+
+ self.consistencygroups_mock.get.return_value = (
+ self._consistency_group)
+ # Get the command object to test
+ self.cmd = \
+ consistency_group.RemoveVolumeFromConsistencyGroup(self.app, None)
+
+ def test_remove_one_volume_from_consistency_group(self):
+ volume = volume_fakes.FakeVolume.create_one_volume()
+ self.volumes_mock.get.return_value = volume
+ arglist = [
+ self._consistency_group.id,
+ volume.id,
+ ]
+ verifylist = [
+ ('consistency_group', self._consistency_group.id),
+ ('volumes', [volume.id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'remove_volumes': volume.id,
+ }
+ self.consistencygroups_mock.update.assert_called_once_with(
+ self._consistency_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ def test_remove_multi_volumes_from_consistency_group(self):
+ volumes = volume_fakes.FakeVolume.create_volumes(count=2)
+ self.volumes_mock.get = volume_fakes.FakeVolume.get_volumes(volumes)
+ arglist = [
+ self._consistency_group.id,
+ volumes[0].id,
+ volumes[1].id,
+ ]
+ verifylist = [
+ ('consistency_group', self._consistency_group.id),
+ ('volumes', [volumes[0].id, volumes[1].id]),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+
+ # Set expected values
+ kwargs = {
+ 'remove_volumes': volumes[0].id + ',' + volumes[1].id,
+ }
+ self.consistencygroups_mock.update.assert_called_once_with(
+ self._consistency_group.id,
+ **kwargs
+ )
+ self.assertIsNone(result)
+
+ @mock.patch.object(consistency_group.LOG, 'error')
+ def test_remove_multiple_volumes_from_consistency_group_with_exception(
+ self, mock_error):
+ volume = volume_fakes.FakeVolume.create_one_volume()
+ arglist = [
+ self._consistency_group.id,
+ volume.id,
+ 'unexist_volume',
+ ]
+ verifylist = [
+ ('consistency_group', self._consistency_group.id),
+ ('volumes', [volume.id, 'unexist_volume']),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ find_mock_result = [volume,
+ exceptions.CommandError,
+ self._consistency_group]
+ with mock.patch.object(utils, 'find_resource',
+ side_effect=find_mock_result) as find_mock:
+ result = self.cmd.take_action(parsed_args)
+ mock_error.assert_called_with("1 of 2 volumes failed to remove.")
+ self.assertIsNone(result)
+ find_mock.assert_any_call(self.consistencygroups_mock,
+ self._consistency_group.id)
+ find_mock.assert_any_call(self.volumes_mock,
+ volume.id)
+ find_mock.assert_any_call(self.volumes_mock,
+ 'unexist_volume')
+ self.assertEqual(3, find_mock.call_count)
+ self.consistencygroups_mock.update.assert_called_once_with(
+ self._consistency_group.id, remove_volumes=volume.id
+ )
+
+
class TestConsistencyGroupSet(TestConsistencyGroup):
consistency_group = (
diff --git a/openstackclient/tests/unit/volume/v2/test_qos_specs.py b/openstackclient/tests/unit/volume/v2/test_qos_specs.py
index 7597e852..35d9a345 100644
--- a/openstackclient/tests/unit/volume/v2/test_qos_specs.py
+++ b/openstackclient/tests/unit/volume/v2/test_qos_specs.py
@@ -70,24 +70,26 @@ class TestQosAssociate(TestQos):
class TestQosCreate(TestQos):
- new_qos_spec = volume_fakes.FakeQos.create_one_qos()
columns = (
'consumer',
'id',
'name',
- 'specs'
- )
- data = (
- new_qos_spec.consumer,
- new_qos_spec.id,
- new_qos_spec.name,
- new_qos_spec.specs
+ 'properties'
)
def setUp(self):
super(TestQosCreate, self).setUp()
+ self.new_qos_spec = volume_fakes.FakeQos.create_one_qos()
self.qos_mock.create.return_value = self.new_qos_spec
+
+ self.data = (
+ self.new_qos_spec.consumer,
+ self.new_qos_spec.id,
+ self.new_qos_spec.name,
+ utils.format_dict(self.new_qos_spec.specs)
+ )
+
# Get the command object to test
self.cmd = qos_specs.CreateQos(self.app, None)
@@ -147,11 +149,11 @@ class TestQosCreate(TestQos):
columns, data = self.cmd.take_action(parsed_args)
- self.new_qos_spec.specs.update(
- {'consumer': self.new_qos_spec.consumer})
self.qos_mock.create.assert_called_with(
self.new_qos_spec.name,
- self.new_qos_spec.specs
+ {'consumer': self.new_qos_spec.consumer,
+ 'foo': 'bar',
+ 'iops': '9001'}
)
self.assertEqual(self.columns, columns)
@@ -307,7 +309,7 @@ class TestQosList(TestQos):
'Name',
'Consumer',
'Associations',
- 'Specs',
+ 'Properties',
)
data = []
for q in qos_specs:
@@ -383,7 +385,7 @@ class TestQosShow(TestQos):
'consumer',
'id',
'name',
- 'specs'
+ 'properties'
)
data = (
qos_association.name,
diff --git a/openstackclient/tests/unit/volume/v2/test_snapshot.py b/openstackclient/tests/unit/volume/v2/test_snapshot.py
index 8ce356ae..12d1e390 100644
--- a/openstackclient/tests/unit/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/unit/volume/v2/test_snapshot.py
@@ -19,6 +19,7 @@ from mock import call
from osc_lib import exceptions
from osc_lib import utils
+from openstackclient.tests.unit.identity.v3 import fakes as project_fakes
from openstackclient.tests.unit.volume.v2 import fakes as volume_fakes
from openstackclient.volume.v2 import volume_snapshot
@@ -32,6 +33,8 @@ class TestSnapshot(volume_fakes.TestVolume):
self.snapshots_mock.reset_mock()
self.volumes_mock = self.app.client_manager.volume.volumes
self.volumes_mock.reset_mock()
+ self.project_mock = self.app.client_manager.identity.projects
+ self.project_mock.reset_mock()
class TestSnapshotCreate(TestSnapshot):
@@ -278,6 +281,7 @@ class TestSnapshotDelete(TestSnapshot):
class TestSnapshotList(TestSnapshot):
volume = volume_fakes.FakeVolume.create_one_volume()
+ project = project_fakes.FakeProject.create_one_project()
snapshots = volume_fakes.FakeSnapshot.create_snapshots(
attrs={'volume_id': volume.name}, count=3)
@@ -321,6 +325,7 @@ class TestSnapshotList(TestSnapshot):
self.volumes_mock.list.return_value = [self.volume]
self.volumes_mock.get.return_value = self.volume
+ self.project_mock.get.return_value = self.project
self.snapshots_mock.list.return_value = self.snapshots
# Get the command to test
self.cmd = volume_snapshot.ListVolumeSnapshot(self.app, None)
@@ -341,6 +346,7 @@ class TestSnapshotList(TestSnapshot):
'all_tenants': False,
'name': None,
'status': None,
+ 'project_id': None,
'volume_id': None
}
)
@@ -351,11 +357,13 @@ class TestSnapshotList(TestSnapshot):
arglist = [
"--long",
"--limit", "2",
+ "--project", self.project.id,
"--marker", self.snapshots[0].id,
]
verifylist = [
("long", True),
("limit", 2),
+ ("project", self.project.id),
("marker", self.snapshots[0].id),
('all_projects', False),
]
@@ -367,7 +375,8 @@ class TestSnapshotList(TestSnapshot):
limit=2,
marker=self.snapshots[0].id,
search_opts={
- 'all_tenants': False,
+ 'all_tenants': True,
+ 'project_id': self.project.id,
'name': None,
'status': None,
'volume_id': None
@@ -394,6 +403,7 @@ class TestSnapshotList(TestSnapshot):
'all_tenants': True,
'name': None,
'status': None,
+ 'project_id': None,
'volume_id': None
}
)
@@ -419,6 +429,7 @@ class TestSnapshotList(TestSnapshot):
'all_tenants': False,
'name': self.snapshots[0].name,
'status': None,
+ 'project_id': None,
'volume_id': None
}
)
@@ -444,6 +455,7 @@ class TestSnapshotList(TestSnapshot):
'all_tenants': False,
'name': None,
'status': self.snapshots[0].status,
+ 'project_id': None,
'volume_id': None
}
)
@@ -469,6 +481,7 @@ class TestSnapshotList(TestSnapshot):
'all_tenants': False,
'name': None,
'status': None,
+ 'project_id': None,
'volume_id': self.volume.id
}
)
diff --git a/openstackclient/tests/unit/volume/v2/test_type.py b/openstackclient/tests/unit/volume/v2/test_type.py
index 0d556e13..cec01bd8 100644
--- a/openstackclient/tests/unit/volume/v2/test_type.py
+++ b/openstackclient/tests/unit/volume/v2/test_type.py
@@ -13,6 +13,7 @@
#
import mock
+from mock import call
from osc_lib import exceptions
from osc_lib import utils
@@ -133,12 +134,13 @@ class TestTypeCreate(TestType):
class TestTypeDelete(TestType):
- volume_type = volume_fakes.FakeType.create_one_type()
+ volume_types = volume_fakes.FakeType.create_types(count=2)
def setUp(self):
super(TestTypeDelete, self).setUp()
- self.types_mock.get.return_value = self.volume_type
+ self.types_mock.get = volume_fakes.FakeType.get_types(
+ self.volume_types)
self.types_mock.delete.return_value = None
# Get the command object to mock
@@ -146,18 +148,64 @@ class TestTypeDelete(TestType):
def test_type_delete(self):
arglist = [
- self.volume_type.id
+ self.volume_types[0].id
]
verifylist = [
- ("volume_types", [self.volume_type.id])
+ ("volume_types", [self.volume_types[0].id])
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
result = self.cmd.take_action(parsed_args)
- self.types_mock.delete.assert_called_with(self.volume_type)
+ self.types_mock.delete.assert_called_with(self.volume_types[0])
self.assertIsNone(result)
+ def test_delete_multiple_types(self):
+ arglist = []
+ for t in self.volume_types:
+ arglist.append(t.id)
+ verifylist = [
+ ('volume_types', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ result = self.cmd.take_action(parsed_args)
+
+ calls = []
+ for t in self.volume_types:
+ calls.append(call(t))
+ self.types_mock.delete.assert_has_calls(calls)
+ self.assertIsNone(result)
+
+ def test_delete_multiple_types_with_exception(self):
+ arglist = [
+ self.volume_types[0].id,
+ 'unexist_type',
+ ]
+ verifylist = [
+ ('volume_types', arglist),
+ ]
+
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ find_mock_result = [self.volume_types[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 volume types failed to delete.',
+ str(e))
+ find_mock.assert_any_call(
+ self.types_mock, self.volume_types[0].id)
+ find_mock.assert_any_call(self.types_mock, 'unexist_type')
+
+ self.assertEqual(2, find_mock.call_count)
+ self.types_mock.delete.assert_called_once_with(
+ self.volume_types[0]
+ )
+
class TestTypeList(TestType):
diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index 1529c2e2..4fef9dd9 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -823,6 +823,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': False,
+ 'project_id': None,
+ 'user_id': None,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -853,6 +866,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': True,
+ 'project_id': self.project.id,
+ 'user_id': None,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -885,6 +911,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': True,
+ 'project_id': self.project.id,
+ 'user_id': None,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -915,6 +954,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': False,
+ 'project_id': None,
+ 'user_id': self.user.id,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
device = self.mock_volume.attachments[0]['device']
@@ -946,6 +998,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': False,
+ 'project_id': None,
+ 'user_id': self.user.id,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -976,6 +1041,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': False,
+ 'project_id': None,
+ 'user_id': None,
+ 'display_name': self.mock_volume.name,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -1006,6 +1084,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': False,
+ 'project_id': None,
+ 'user_id': None,
+ 'display_name': None,
+ 'status': self.mock_volume.status,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -1036,6 +1127,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': True,
+ 'project_id': None,
+ 'user_id': None,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
self.assertEqual(self.columns, columns)
server = self.mock_volume.attachments[0]['server_id']
@@ -1067,6 +1171,19 @@ class TestVolumeList(TestVolume):
columns, data = self.cmd.take_action(parsed_args)
+ search_opts = {
+ 'all_tenants': False,
+ 'project_id': None,
+ 'user_id': None,
+ 'display_name': None,
+ 'status': None,
+ }
+ self.volumes_mock.list.assert_called_once_with(
+ search_opts=search_opts,
+ marker=None,
+ limit=None,
+ )
+
collist = [
'ID',
'Display Name',