summaryrefslogtreecommitdiff
path: root/openstackclient/tests
diff options
context:
space:
mode:
Diffstat (limited to 'openstackclient/tests')
-rw-r--r--openstackclient/tests/functional/common/test_quota.py6
-rw-r--r--openstackclient/tests/functional/compute/v2/test_flavor.py227
-rw-r--r--openstackclient/tests/functional/identity/v3/common.py3
-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.py149
-rw-r--r--openstackclient/tests/functional/network/v2/test_meter.py102
-rw-r--r--openstackclient/tests/functional/network/v2/test_network.py263
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_agent.py4
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py32
-rw-r--r--openstackclient/tests/functional/network/v2/test_network_service_provider.py2
-rw-r--r--openstackclient/tests/functional/network/v2/test_port.py3
-rw-r--r--openstackclient/tests/functional/network/v2/test_security_group_rule.py3
-rwxr-xr-xopenstackclient/tests/functional/post_test_hook_tips.sh46
-rw-r--r--openstackclient/tests/functional/volume/v2/test_volume_type.py5
-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/compute/v2/fakes.py65
-rw-r--r--openstackclient/tests/unit/compute/v2/test_flavor.py5
-rw-r--r--openstackclient/tests/unit/compute/v2/test_usage.py179
-rw-r--r--openstackclient/tests/unit/fakes.py3
-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_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.py33
-rw-r--r--openstackclient/tests/unit/network/v2/fakes.py119
-rw-r--r--openstackclient/tests/unit/network/v2/test_address_scope.py98
-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.py55
-rw-r--r--openstackclient/tests/unit/network/v2/test_network_agent.py35
-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_port.py2
-rw-r--r--openstackclient/tests/unit/network/v2/test_router.py183
-rw-r--r--openstackclient/tests/unit/test_shell.py2
-rw-r--r--openstackclient/tests/unit/volume/v1/test_volume.py136
-rw-r--r--openstackclient/tests/unit/volume/v2/test_backup.py24
-rw-r--r--openstackclient/tests/unit/volume/v2/test_snapshot.py28
-rw-r--r--openstackclient/tests/unit/volume/v2/test_type.py27
-rw-r--r--openstackclient/tests/unit/volume/v2/test_volume.py265
47 files changed, 2798 insertions, 154 deletions
diff --git a/openstackclient/tests/functional/common/test_quota.py b/openstackclient/tests/functional/common/test_quota.py
index c1de9aa9..fbb8e563 100644
--- a/openstackclient/tests/functional/common/test_quota.py
+++ b/openstackclient/tests/functional/common/test_quota.py
@@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from openstackclient.tests.functional import base
@@ -25,6 +27,7 @@ class QuotaTests(base.TestCase):
cls.PROJECT_NAME =\
cls.get_openstack_configuration_value('auth.project_name')
+ @testtools.skip('broken SDK testing')
def test_quota_set(self):
self.openstack('quota set --instances 11 --volumes 11 --networks 11 ' +
self.PROJECT_NAME)
@@ -32,16 +35,19 @@ class QuotaTests(base.TestCase):
raw_output = self.openstack('quota show ' + self.PROJECT_NAME + opts)
self.assertEqual("11\n11\n11\n", raw_output)
+ @testtools.skip('broken SDK testing')
def test_quota_show(self):
raw_output = self.openstack('quota show ' + self.PROJECT_NAME)
for expected_field in self.EXPECTED_FIELDS:
self.assertIn(expected_field, raw_output)
+ @testtools.skip('broken SDK testing')
def test_quota_show_default_project(self):
raw_output = self.openstack('quota show')
for expected_field in self.EXPECTED_FIELDS:
self.assertIn(expected_field, raw_output)
+ @testtools.skip('broken SDK testing')
def test_quota_show_with_default_option(self):
raw_output = self.openstack('quota show --default')
for expected_field in self.EXPECTED_FIELDS:
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/v3/common.py b/openstackclient/tests/functional/identity/v3/common.py
index 5dd42e70..3b6fc27b 100644
--- a/openstackclient/tests/functional/identity/v3/common.py
+++ b/openstackclient/tests/functional/identity/v3/common.py
@@ -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..5f642f04 100644
--- a/openstackclient/tests/functional/network/v2/test_floating_ip.py
+++ b/openstackclient/tests/functional/network/v2/test_floating_ip.py
@@ -10,49 +10,154 @@
# License for the specific language governing permissions and limitations
# under the License.
+import random
+import re
import uuid
+import testtools
+
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
+ @testtools.skip('broken SDK testing')
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
+ # 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+)")
+
+ # Make a random subnet
+ cls.subnet = ".".join(map(
+ str,
+ (random.randint(0, 255) for _ in range(3))
+ )) + ".0/26"
+
+ # Create a network for the floating ip
+ raw_output = cls.openstack(
+ 'network create --external ' + cls.NETWORK_NAME
)
- opts = cls.get_opts(cls.FIELDS)
+ cls.network_id = re.search(cls.re_id, raw_output).group(1)
+
+ # Create a subnet for the network
raw_output = cls.openstack(
- 'floating ip create ' + cls.NETWORK_NAME + opts)
- cls.ID = raw_output.strip('\n')
+ 'subnet create ' +
+ '--network ' + cls.NETWORK_NAME + ' ' +
+ '--subnet-range ' + cls.subnet + ' ' +
+ cls.SUBNET_NAME
+ )
+ 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)
+ @testtools.skip('broken SDK testing')
+ 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)
+
+ @testtools.skip('broken SDK testing')
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
+
+ @testtools.skip('broken SDK testing')
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..ef42dcce 100644
--- a/openstackclient/tests/functional/network/v2/test_network.py
+++ b/openstackclient/tests/functional/network/v2/test_network.py
@@ -10,41 +10,256 @@
# License for the specific language governing permissions and limitations
# under the License.
+import re
import uuid
+import testtools
+
from openstackclient.tests.functional import base
class NetworkTests(base.TestCase):
- """Functional tests for network. """
- NAME = uuid.uuid4().hex
- HEADERS = ['Name']
- FIELDS = ['name']
+ """Functional tests for network"""
@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)
+ # Set up some regex for matching below
+ cls.re_id = re.compile("id\s+\|\s+(\S+)")
+ cls.re_description = re.compile("description\s+\|\s+([^|]+?)\s+\|")
+ cls.re_enabled = re.compile("admin_state_up\s+\|\s+(\S+)")
+ cls.re_shared = re.compile("shared\s+\|\s+(\S+)")
+ cls.re_external = re.compile("router:external\s+\|\s+(\S+)")
+ cls.re_default = re.compile("is_default\s+\|\s+(\S+)")
+ cls.re_port_security = re.compile(
+ "port_security_enabled\s+\|\s+(\S+)"
+ )
- @classmethod
- def tearDownClass(cls):
- raw_output = cls.openstack('network delete ' + cls.NAME)
- cls.assertOutput('', raw_output)
+ def test_network_delete(self):
+ """Test create, delete multiple"""
+ name1 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'network create ' +
+ '--description aaaa ' +
+ name1
+ )
+ self.assertEqual(
+ 'aaaa',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ name2 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'network create ' +
+ '--description bbbb ' +
+ name2
+ )
+ self.assertEqual(
+ 'bbbb',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ del_output = self.openstack('network delete ' + name1 + ' ' + name2)
+ self.assertOutput('', del_output)
+
+ @testtools.skip('broken SDK testing')
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
+ raw_output = self.openstack(
+ 'network create ' +
+ '--description aaaa ' +
+ name1
+ )
+ self.addCleanup(self.openstack, 'network delete ' + name1)
+ self.assertEqual(
+ 'aaaa',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ # Check the default values
+ self.assertEqual(
+ 'UP',
+ re.search(self.re_enabled, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'Internal',
+ re.search(self.re_external, raw_output).group(1),
+ )
+ # NOTE(dtroyer): is_default is not present in the create output
+ # so make sure it stays that way.
+ self.assertIsNone(re.search(self.re_default, raw_output))
+ self.assertEqual(
+ 'True',
+ re.search(self.re_port_security, raw_output).group(1),
+ )
+
+ name2 = uuid.uuid4().hex
+ raw_output = self.openstack(
+ 'network create ' +
+ '--description bbbb ' +
+ '--disable ' +
+ '--share ' +
+ name2
+ )
+ self.addCleanup(self.openstack, 'network delete ' + name2)
+ self.assertEqual(
+ 'bbbb',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'DOWN',
+ re.search(self.re_enabled, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'True',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+
+ # Test list --long
+ raw_output = self.openstack('network list --long')
+ self.assertIsNotNone(
+ re.search("\|\s+" + name1 + "\s+\|\s+ACTIVE", raw_output)
+ )
+ self.assertIsNotNone(
+ re.search("\|\s+" + name2 + "\s+\|\s+ACTIVE", raw_output)
+ )
+
+ # Test list --long --enable
+ raw_output = self.openstack('network list --long --enable')
+ self.assertIsNotNone(
+ re.search("\|\s+" + name1 + "\s+\|\s+ACTIVE", raw_output)
+ )
+ self.assertIsNone(
+ re.search("\|\s+" + name2 + "\s+\|\s+ACTIVE", raw_output)
+ )
+
+ # Test list --long --disable
+ raw_output = self.openstack('network list --long --disable')
+ self.assertIsNone(
+ re.search("\|\s+" + name1 + "\s+\|\s+ACTIVE", raw_output)
+ )
+ self.assertIsNotNone(
+ re.search("\|\s+" + name2 + "\s+\|\s+ACTIVE", raw_output)
+ )
+
+ # Test list --long --share
+ raw_output = self.openstack('network list --long --share')
+ self.assertIsNone(
+ re.search("\|\s+" + name1 + "\s+\|\s+ACTIVE", raw_output)
+ )
+ self.assertIsNotNone(
+ re.search("\|\s+" + name2 + "\s+\|\s+ACTIVE", raw_output)
+ )
+ # Test list --long --no-share
+ raw_output = self.openstack('network list --long --no-share')
+ self.assertIsNotNone(
+ re.search("\|\s+" + name1 + "\s+\|\s+ACTIVE", raw_output)
+ )
+ self.assertIsNone(
+ re.search("\|\s+" + name2 + "\s+\|\s+ACTIVE", raw_output)
+ )
+
+ @testtools.skip('broken SDK testing')
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
+ raw_output = self.openstack(
+ 'network create ' +
+ '--description aaaa ' +
+ '--enable ' +
+ '--no-share ' +
+ '--internal ' +
+ '--no-default ' +
+ '--enable-port-security ' +
+ name
+ )
+ self.addCleanup(self.openstack, 'network delete ' + name)
+ self.assertEqual(
+ 'aaaa',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'UP',
+ re.search(self.re_enabled, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'False',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'Internal',
+ re.search(self.re_external, raw_output).group(1),
+ )
+ # NOTE(dtroyer): is_default is not present in the create output
+ # so make sure it stays that way.
+ self.assertIsNone(re.search(self.re_default, raw_output))
+ self.assertEqual(
+ 'True',
+ re.search(self.re_port_security, raw_output).group(1),
+ )
+
+ raw_output = self.openstack(
+ 'network set ' +
+ '--description cccc ' +
+ '--disable ' +
+ '--share ' +
+ '--external ' +
+ '--disable-port-security ' +
+ name
+ )
+ self.assertOutput('', raw_output)
+
+ raw_output = self.openstack('network show ' + name)
+
+ self.assertEqual(
+ 'cccc',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'DOWN',
+ re.search(self.re_enabled, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'True',
+ re.search(self.re_shared, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'External',
+ re.search(self.re_external, raw_output).group(1),
+ )
+ # why not 'None' like above??
+ self.assertEqual(
+ 'False',
+ re.search(self.re_default, raw_output).group(1),
+ )
+ self.assertEqual(
+ 'False',
+ re.search(self.re_port_security, raw_output).group(1),
+ )
+
+ # 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)
+
+ raw_output = self.openstack('network show ' + name)
+
+ self.assertEqual(
+ 'cccc',
+ re.search(self.re_description, raw_output).group(1),
+ )
+ # NOTE(dtroyer): This should be 'True'
+ self.assertEqual(
+ 'False',
+ re.search(self.re_default, raw_output).group(1),
+ )
diff --git a/openstackclient/tests/functional/network/v2/test_network_agent.py b/openstackclient/tests/functional/network/v2/test_network_agent.py
index dd6112e7..e99dcef6 100644
--- a/openstackclient/tests/functional/network/v2/test_network_agent.py
+++ b/openstackclient/tests/functional/network/v2/test_network_agent.py
@@ -10,6 +10,8 @@
# License for the specific language governing permissions and limitations
# under the License.
+import testtools
+
from openstackclient.tests.functional import base
@@ -26,11 +28,13 @@ class NetworkAgentTests(base.TestCase):
# get the list of network agent IDs.
cls.IDs = raw_output.split('\n')
+ @testtools.skip('broken SDK testing')
def test_network_agent_show(self):
opts = self.get_opts(self.FIELDS)
raw_output = self.openstack('network agent show ' + self.IDs[0] + opts)
self.assertEqual(self.IDs[0] + "\n", raw_output)
+ @testtools.skip('broken SDK testing')
def test_network_agent_set(self):
opts = self.get_opts(['admin_state_up'])
self.openstack('network agent set --disable ' + self.IDs[0])
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..2bb04a9d
--- /dev/null
+++ b/openstackclient/tests/functional/network/v2/test_network_qos_rule_type.py
@@ -0,0 +1,32 @@
+# 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 testtools
+
+from openstackclient.tests.functional import base
+
+
+class NetworkQosRuleTypeTests(base.TestCase):
+ """Functional tests for Network QoS rule type. """
+
+ AVAILABLE_RULE_TYPES = ['dscp_marking',
+ 'bandwidth_limit',
+ 'minimum_bandwidth']
+
+ @testtools.skip('broken SDK testing')
+ 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..976fbedb 100644
--- a/openstackclient/tests/functional/network/v2/test_port.py
+++ b/openstackclient/tests/functional/network/v2/test_port.py
@@ -12,6 +12,8 @@
import uuid
+import testtools
+
from openstackclient.tests.functional import base
@@ -23,6 +25,7 @@ class PortTests(base.TestCase):
FIELDS = ['name']
@classmethod
+ @testtools.skip('broken SDK testing')
def setUpClass(cls):
# Create a network for the subnet.
cls.openstack('network create ' + cls.NETWORK_NAME)
diff --git a/openstackclient/tests/functional/network/v2/test_security_group_rule.py b/openstackclient/tests/functional/network/v2/test_security_group_rule.py
index c91de1a5..ec3731eb 100644
--- a/openstackclient/tests/functional/network/v2/test_security_group_rule.py
+++ b/openstackclient/tests/functional/network/v2/test_security_group_rule.py
@@ -12,6 +12,8 @@
import uuid
+import testtools
+
from openstackclient.tests.functional import base
@@ -52,6 +54,7 @@ class SecurityGroupRuleTests(base.TestCase):
cls.SECURITY_GROUP_NAME)
cls.assertOutput('', raw_output)
+ @testtools.skip('broken SDK testing')
def test_security_group_rule_list(self):
opts = self.get_opts(self.ID_HEADER)
raw_output = self.openstack('security group rule list ' +
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..994142d8
--- /dev/null
+++ b/openstackclient/tests/functional/post_test_hook_tips.sh
@@ -0,0 +1,46 @@
+#!/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 and openstacksdk
+
+function generate_testr_results {
+ if [ -f .testrepository/0 ]; then
+ sudo .tox/functional/bin/testr last --subunit > $WORKSPACE/testrepository.subunit
+ sudo mv $WORKSPACE/testrepository.subunit $BASE/logs/testrepository.subunit
+ sudo .tox/functional/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 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_volume_type.py b/openstackclient/tests/functional/volume/v2/test_volume_type.py
index d8bd3a96..b4df5b2d 100644
--- a/openstackclient/tests/functional/volume/v2/test_volume_type.py
+++ b/openstackclient/tests/functional/volume/v2/test_volume_type.py
@@ -42,6 +42,11 @@ class VolumeTypeTests(common.BaseVolumeTests):
raw_output = self.openstack('volume type list' + opts)
self.assertIn(self.NAME, raw_output)
+ def test_volume_type_list_default(self):
+ opts = self.get_opts(self.HEADERS)
+ raw_output = self.openstack('volume type list --default' + opts)
+ self.assertEqual("lvmdriver-1\n", raw_output)
+
def test_volume_type_show(self):
opts = self.get_opts(self.FIELDS)
raw_output = self.openstack('volume type show ' + self.NAME + opts)
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/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_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..ca6b1d31 100644
--- a/openstackclient/tests/unit/fakes.py
+++ b/openstackclient/tests/unit/fakes.py
@@ -212,6 +212,9 @@ class FakeResource(object):
def keys(self):
return self._info.keys()
+ def to_dict(self):
+ return self._info
+
@property
def info(self):
return self._info
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_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..a1513119 100644
--- a/openstackclient/tests/unit/image/v2/test_image.py
+++ b/openstackclient/tests/unit/image/v2/test_image.py
@@ -845,6 +845,39 @@ class TestImageSet(TestImage):
self.assertIsNone(result)
+ self.image_members_mock.update.assert_not_called()
+
+ def test_image_set_membership_option(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
+
+ for status in ('accept', 'reject', 'pending'):
+ arglist = [
+ '--%s' % status,
+ image_fakes.image_id,
+ ]
+ verifylist = [
+ (status, 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,
+ status if status == 'pending' else status + 'ed'
+ )
+ self.image_members_mock.update.reset_mock()
+
+ # 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 97d07076..b931cb55 100644
--- a/openstackclient/tests/unit/network/v2/fakes.py
+++ b/openstackclient/tests/unit/network/v2/fakes.py
@@ -297,15 +297,17 @@ class FakeNetwork(object):
'admin_state_up': True,
'shared': False,
'subnets': ['a', 'b'],
- 'provider_network_type': 'vlan',
- 'provider_physical_network': 'physnet1',
- 'provider_segmentation_id': "400",
+ 'provider:network_type': 'vlan',
+ 'provider:physical_network': 'physnet1',
+ 'provider:segmentation_id': "400",
'router:external': True,
'availability_zones': [],
'availability_zone_hints': [],
'is_default': False,
'port_security_enabled': True,
'qos_policy_id': 'qos-policy-id-' + uuid.uuid4().hex,
+ 'ipv4_address_scope': 'ipv4' + uuid.uuid4().hex,
+ 'ipv6_address_scope': 'ipv6' + uuid.uuid4().hex,
}
# Overwrite default attributes.
@@ -317,8 +319,21 @@ class FakeNetwork(object):
# Set attributes with special mapping in OpenStack SDK.
network.project_id = network_attrs['tenant_id']
network.is_router_external = network_attrs['router:external']
+ network.is_admin_state_up = network_attrs['admin_state_up']
network.is_port_security_enabled = \
network_attrs['port_security_enabled']
+ network.subnet_ids = network_attrs['subnets']
+ network.is_shared = network_attrs['shared']
+ network.provider_network_type = \
+ network_attrs['provider:network_type']
+ network.provider_physical_network = \
+ network_attrs['provider:physical_network']
+ network.provider_segmentation_id = \
+ network_attrs['provider:segmentation_id']
+ network.ipv4_address_scope_id = \
+ network_attrs['ipv4_address_scope']
+ network.ipv6_address_scope_id = \
+ network_attrs['ipv6_address_scope']
return network
@@ -461,12 +476,15 @@ class FakePort(object):
loaded=True)
# Set attributes with special mappings in OpenStack SDK.
- port.project_id = port_attrs['tenant_id']
port.binding_host_id = port_attrs['binding:host_id']
port.binding_profile = port_attrs['binding:profile']
port.binding_vif_details = port_attrs['binding:vif_details']
port.binding_vif_type = port_attrs['binding:vif_type']
port.binding_vnic_type = port_attrs['binding:vnic_type']
+ port.is_admin_state_up = port_attrs['admin_state_up']
+ port.is_port_security_enabled = port_attrs['port_security_enabled']
+ port.project_id = port_attrs['tenant_id']
+ port.security_group_ids = port_attrs['security_groups']
return port
@@ -795,6 +813,51 @@ class FakeNetworkQosPolicy(object):
return mock.Mock(side_effect=qos_policies)
+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):
"""Fake one or more routers."""
@@ -834,6 +897,9 @@ class FakeRouter(object):
# Set attributes with special mapping in OpenStack SDK.
router.project_id = router_attrs['tenant_id']
+ router.is_admin_state_up = router_attrs['admin_state_up']
+ router.is_distributed = router_attrs['distributed']
+ router.is_ha = router_attrs['ha']
return router
@@ -1192,6 +1258,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_address_scope.py b/openstackclient/tests/unit/network/v2/test_address_scope.py
index 12c3f1d6..516b8795 100644
--- a/openstackclient/tests/unit/network/v2/test_address_scope.py
+++ b/openstackclient/tests/unit/network/v2/test_address_scope.py
@@ -275,6 +275,104 @@ class TestListAddressScope(TestAddressScope):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_address_scope_list_name(self):
+ arglist = [
+ '--name', self.address_scopes[0].name,
+ ]
+ verifylist = [
+ ('name', self.address_scopes[0].name),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.address_scopes.assert_called_once_with(
+ **{'name': self.address_scopes[0].name})
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_address_scope_list_ip_version(self):
+ arglist = [
+ '--ip-version', str(4),
+ ]
+ verifylist = [
+ ('ip_version', 4),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.address_scopes.assert_called_once_with(
+ **{'ip_version': 4})
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_address_scope_list_project(self):
+ project = identity_fakes_v3.FakeProject.create_one_project()
+ self.projects_mock.get.return_value = project
+ arglist = [
+ '--project', project.id,
+ ]
+ verifylist = [
+ ('project', project.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.address_scopes.assert_called_once_with(
+ **{'tenant_id': project.id, 'project_id': project.id})
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_address_scope_project_domain(self):
+ project = identity_fakes_v3.FakeProject.create_one_project()
+ self.projects_mock.get.return_value = project
+ arglist = [
+ '--project', project.id,
+ '--project-domain', project.domain_id,
+ ]
+ verifylist = [
+ ('project', project.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ filters = {'tenant_id': project.id, 'project_id': project.id}
+
+ self.network.address_scopes.assert_called_once_with(**filters)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_address_scope_list_share(self):
+ arglist = [
+ '--share',
+ ]
+ verifylist = [
+ ('share', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.address_scopes.assert_called_once_with(
+ **{'shared': True, 'is_shared': True}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
+ def test_address_scope_list_no_share(self):
+ arglist = [
+ '--no-share',
+ ]
+ verifylist = [
+ ('no_share', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.network.address_scopes.assert_called_once_with(
+ **{'shared': False, 'is_shared': False}
+ )
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, list(data))
+
class TestSetAddressScope(TestAddressScope):
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.py b/openstackclient/tests/unit/network/v2/test_network.py
index 96b1b102..c5283443 100644
--- a/openstackclient/tests/unit/network/v2/test_network.py
+++ b/openstackclient/tests/unit/network/v2/test_network.py
@@ -62,13 +62,15 @@ class TestCreateNetworkIdentityV3(TestNetwork):
'availability_zones',
'description',
'id',
+ 'ipv4_address_scope',
+ 'ipv6_address_scope',
'is_default',
'name',
'port_security_enabled',
'project_id',
- 'provider_network_type',
- 'provider_physical_network',
- 'provider_segmentation_id',
+ 'provider:network_type',
+ 'provider:physical_network',
+ 'provider:segmentation_id',
'qos_policy_id',
'router:external',
'shared',
@@ -82,6 +84,8 @@ class TestCreateNetworkIdentityV3(TestNetwork):
utils.format_list(_network.availability_zones),
_network.description,
_network.id,
+ _network.ipv4_address_scope_id,
+ _network.ipv6_address_scope_id,
_network.is_default,
_network.name,
_network.is_port_security_enabled,
@@ -236,13 +240,15 @@ class TestCreateNetworkIdentityV2(TestNetwork):
'availability_zones',
'description',
'id',
+ 'ipv4_address_scope',
+ 'ipv6_address_scope',
'is_default',
'name',
'port_security_enabled',
'project_id',
- 'provider_network_type',
- 'provider_physical_network',
- 'provider_segmentation_id',
+ 'provider:network_type',
+ 'provider:physical_network',
+ 'provider:segmentation_id',
'qos_policy_id',
'router:external',
'shared',
@@ -256,6 +262,8 @@ class TestCreateNetworkIdentityV2(TestNetwork):
utils.format_list(_network.availability_zones),
_network.description,
_network.id,
+ _network.ipv4_address_scope_id,
+ _network.ipv6_address_scope_id,
_network.is_default,
_network.name,
_network.is_port_security_enabled,
@@ -512,7 +520,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'router:external': True}
+ **{'router:external': True, 'is_router_external': True}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -529,7 +537,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'router:external': False}
+ **{'router:external': False, 'is_router_external': False}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -585,7 +593,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'admin_state_up': True}
+ **{'admin_state_up': True, 'is_admin_state_up': True}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -603,7 +611,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'admin_state_up': False}
+ **{'admin_state_up': False, 'is_admin_state_up': False}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -621,7 +629,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'tenant_id': project.id}
+ **{'tenant_id': project.id, 'project_id': project.id}
)
self.assertEqual(self.columns, columns)
@@ -640,7 +648,7 @@ class TestListNetwork(TestNetwork):
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.networks.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -658,7 +666,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'shared': True}
+ **{'shared': True, 'is_shared': True}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -675,7 +683,7 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'shared': False}
+ **{'shared': False, 'is_shared': False}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -711,7 +719,8 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'provider:network_type': network_type}
+ **{'provider:network_type': network_type,
+ 'provider_network_type': network_type}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -728,7 +737,8 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'provider:physical_network': physical_network}
+ **{'provider:physical_network': physical_network,
+ 'provider_physical_network': physical_network}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -745,7 +755,8 @@ class TestListNetwork(TestNetwork):
columns, data = self.cmd.take_action(parsed_args)
self.network.networks.assert_called_once_with(
- **{'provider:segmentation_id': segmentation_id}
+ **{'provider:segmentation_id': segmentation_id,
+ 'provider_segmentation_id': segmentation_id}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -878,13 +889,15 @@ class TestShowNetwork(TestNetwork):
'availability_zones',
'description',
'id',
+ 'ipv4_address_scope',
+ 'ipv6_address_scope',
'is_default',
'name',
'port_security_enabled',
'project_id',
- 'provider_network_type',
- 'provider_physical_network',
- 'provider_segmentation_id',
+ 'provider:network_type',
+ 'provider:physical_network',
+ 'provider:segmentation_id',
'qos_policy_id',
'router:external',
'shared',
@@ -898,6 +911,8 @@ class TestShowNetwork(TestNetwork):
utils.format_list(_network.availability_zones),
_network.description,
_network.id,
+ _network.ipv4_address_scope_id,
+ _network.ipv6_address_scope_id,
_network.is_default,
_network.name,
_network.is_port_security_enabled,
diff --git a/openstackclient/tests/unit/network/v2/test_network_agent.py b/openstackclient/tests/unit/network/v2/test_network_agent.py
index 9f5b442a..9fd395b4 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,6 +160,40 @@ 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))
+
class TestSetNetworkAgent(TestNetworkAgent):
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_port.py b/openstackclient/tests/unit/network/v2/test_port.py
index aeb9884a..255e8116 100644
--- a/openstackclient/tests/unit/network/v2/test_port.py
+++ b/openstackclient/tests/unit/network/v2/test_port.py
@@ -324,7 +324,7 @@ class TestCreatePort(TestPort):
self.assertEqual(ref_columns, columns)
self.assertEqual(ref_data, data)
- def test_create_with_no_secuirty_groups(self):
+ def test_create_with_no_security_groups(self):
arglist = [
'--network', self._port.network_id,
'--no-security-group',
diff --git a/openstackclient/tests/unit/network/v2/test_router.py b/openstackclient/tests/unit/network/v2/test_router.py
index b0409447..b837afd1 100644
--- a/openstackclient/tests/unit/network/v2/test_router.py
+++ b/openstackclient/tests/unit/network/v2/test_router.py
@@ -459,7 +459,7 @@ class TestListRouter(TestRouter):
columns, data = self.cmd.take_action(parsed_args)
self.network.routers.assert_called_once_with(
- **{'admin_state_up': True}
+ **{'admin_state_up': True, 'is_admin_state_up': True}
)
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
@@ -476,7 +476,7 @@ class TestListRouter(TestRouter):
columns, data = self.cmd.take_action(parsed_args)
self.network.routers.assert_called_once_with(
- **{'admin_state_up': False}
+ **{'admin_state_up': False, 'is_admin_state_up': False}
)
self.assertEqual(self.columns, columns)
@@ -494,7 +494,7 @@ class TestListRouter(TestRouter):
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.routers.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -514,7 +514,7 @@ class TestListRouter(TestRouter):
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.routers.assert_called_once_with(**filters)
self.assertEqual(self.columns, columns)
@@ -602,17 +602,19 @@ class TestSetRouter(TestRouter):
# The router to set.
_default_route = {'destination': '10.20.20.0/24', 'nexthop': '10.20.30.1'}
+ _network = network_fakes.FakeNetwork.create_one_network()
+ _subnet = network_fakes.FakeSubnet.create_one_subnet()
_router = network_fakes.FakeRouter.create_one_router(
attrs={'routes': [_default_route]}
)
def setUp(self):
super(TestSetRouter, self).setUp()
-
+ self.network.router_add_gateway = mock.Mock()
self.network.update_router = mock.Mock(return_value=None)
-
self.network.find_router = mock.Mock(return_value=self._router)
-
+ self.network.find_network = mock.Mock(return_value=self._network)
+ self.network.find_subnet = mock.Mock(return_value=self._subnet)
# Get the command object to test
self.cmd = router.SetRouter(self.app, self.namespace)
@@ -702,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)
@@ -731,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 = [
@@ -767,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 = [
@@ -799,6 +821,110 @@ class TestSetRouter(TestRouter):
self._router, **attrs)
self.assertIsNone(result)
+ def test_wrong_gateway_params(self):
+ arglist = [
+ "--fixed-ip", "subnet='abc'",
+ self._router.id,
+ ]
+ verifylist = [
+ ('fixed_ip', [{'subnet': "'abc'"}]),
+ ('router', self._router.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+ self.assertRaises(exceptions.CommandError,
+ self.cmd.take_action, parsed_args)
+
+ def test_set_gateway_network_only(self):
+ arglist = [
+ "--external-gateway", self._network.id,
+ self._router.id,
+ ]
+ verifylist = [
+ ('external_gateway', self._network.id),
+ ('router', self._router.id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network.update_router.assert_called_with(
+ self._router, **{'external_gateway_info': {
+ 'network_id': self._network.id}})
+ self.assertIsNone(result)
+
+ def test_set_gateway_options_subnet_only(self):
+ arglist = [
+ "--external-gateway", self._network.id,
+ "--fixed-ip", "subnet='abc'",
+ self._router.id,
+ '--enable-snat',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('external_gateway', self._network.id),
+ ('fixed_ip', [{'subnet': "'abc'"}]),
+ ('enable_snat', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network.update_router.assert_called_with(
+ self._router, **{'external_gateway_info': {
+ 'network_id': self._network.id,
+ 'external_fixed_ips': [{
+ 'subnet_id': self._subnet.id, }],
+ 'enable_snat': True, }})
+ self.assertIsNone(result)
+
+ def test_set_gateway_option_ipaddress_only(self):
+ arglist = [
+ "--external-gateway", self._network.id,
+ "--fixed-ip", "ip-address=10.0.1.1",
+ self._router.id,
+ '--enable-snat',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('external_gateway', self._network.id),
+ ('fixed_ip', [{'ip-address': "10.0.1.1"}]),
+ ('enable_snat', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network.update_router.assert_called_with(
+ self._router, **{'external_gateway_info': {
+ 'network_id': self._network.id,
+ 'external_fixed_ips': [{
+ 'ip_address': "10.0.1.1", }],
+ 'enable_snat': True, }})
+ self.assertIsNone(result)
+
+ def test_set_gateway_options_subnet_ipaddress(self):
+ arglist = [
+ "--external-gateway", self._network.id,
+ "--fixed-ip", "subnet='abc',ip-address=10.0.1.1",
+ self._router.id,
+ '--enable-snat',
+ ]
+ verifylist = [
+ ('router', self._router.id),
+ ('external_gateway', self._network.id),
+ ('fixed_ip', [{'subnet': "'abc'",
+ 'ip-address': "10.0.1.1"}]),
+ ('enable_snat', True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ result = self.cmd.take_action(parsed_args)
+ self.network.update_router.assert_called_with(
+ self._router, **{'external_gateway_info': {
+ 'network_id': self._network.id,
+ 'external_fixed_ips': [{
+ 'subnet_id': self._subnet.id,
+ 'ip_address': "10.0.1.1", }],
+ 'enable_snat': True, }})
+ self.assertIsNone(result)
+
class TestShowRouter(TestRouter):
@@ -915,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/test_shell.py b/openstackclient/tests/unit/test_shell.py
index 3d91da9b..b9fac684 100644
--- a/openstackclient/tests/unit/test_shell.py
+++ b/openstackclient/tests/unit/test_shell.py
@@ -422,7 +422,7 @@ class TestShellArgV(TestShell):
Use the argv supplied by the test runner so we get actual Python
runtime behaviour; we only need to check the type of argv[0]
- which will alwyas be present.
+ which will always be present.
"""
with mock.patch(
diff --git a/openstackclient/tests/unit/volume/v1/test_volume.py b/openstackclient/tests/unit/volume/v1/test_volume.py
index 7a44dea8..6c6d9a1d 100644
--- a/openstackclient/tests/unit/volume/v1/test_volume.py
+++ b/openstackclient/tests/unit/volume/v1/test_volume.py
@@ -431,6 +431,142 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
+ def test_volume_create_with_bootable_and_readonly(self):
+ arglist = [
+ '--bootable',
+ '--read-only',
+ '--size', str(self.new_volume.size),
+ self.new_volume.display_name,
+ ]
+ verifylist = [
+ ('bootable', True),
+ ('non_bootable', False),
+ ('read_only', True),
+ ('read_write', False),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.display_name),
+ ]
+
+ parsed_args = self.check_parser(
+ self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.create.assert_called_with(
+ self.new_volume.size,
+ None,
+ None,
+ self.new_volume.display_name,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+ self.volumes_mock.set_bootable.assert_called_with(
+ self.new_volume.id, True)
+ self.volumes_mock.update_readonly_flag.assert_called_with(
+ self.new_volume.id, True)
+
+ def test_volume_create_with_nonbootable_and_readwrite(self):
+ arglist = [
+ '--non-bootable',
+ '--read-write',
+ '--size', str(self.new_volume.size),
+ self.new_volume.display_name,
+ ]
+ verifylist = [
+ ('bootable', False),
+ ('non_bootable', True),
+ ('read_only', False),
+ ('read_write', True),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.display_name),
+ ]
+
+ parsed_args = self.check_parser(
+ self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.create.assert_called_with(
+ self.new_volume.size,
+ None,
+ None,
+ self.new_volume.display_name,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+ self.volumes_mock.set_bootable.assert_called_with(
+ self.new_volume.id, False)
+ self.volumes_mock.update_readonly_flag.assert_called_with(
+ self.new_volume.id, False)
+
+ @mock.patch.object(volume.LOG, 'error')
+ def test_volume_create_with_bootable_and_readonly_fail(
+ self, mock_error):
+
+ self.volumes_mock.set_bootable.side_effect = (
+ exceptions.CommandError())
+
+ self.volumes_mock.update_readonly_flag.side_effect = (
+ exceptions.CommandError())
+
+ arglist = [
+ '--bootable',
+ '--read-only',
+ '--size', str(self.new_volume.size),
+ self.new_volume.display_name,
+ ]
+ verifylist = [
+ ('bootable', True),
+ ('non_bootable', False),
+ ('read_only', True),
+ ('read_write', False),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.display_name),
+ ]
+
+ parsed_args = self.check_parser(
+ self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.create.assert_called_with(
+ self.new_volume.size,
+ None,
+ None,
+ self.new_volume.display_name,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ None,
+ )
+
+ self.assertEqual(2, mock_error.call_count)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+ self.volumes_mock.set_bootable.assert_called_with(
+ self.new_volume.id, True)
+ self.volumes_mock.update_readonly_flag.assert_called_with(
+ self.new_volume.id, True)
+
def test_volume_create_without_size(self):
arglist = [
self.new_volume.display_name,
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_snapshot.py b/openstackclient/tests/unit/volume/v2/test_snapshot.py
index cedf21a9..8ce356ae 100644
--- a/openstackclient/tests/unit/volume/v2/test_snapshot.py
+++ b/openstackclient/tests/unit/volume/v2/test_snapshot.py
@@ -67,6 +67,7 @@ class TestSnapshotCreate(TestSnapshot):
self.volumes_mock.get.return_value = self.volume
self.snapshots_mock.create.return_value = self.new_snapshot
+ self.snapshots_mock.manage.return_value = self.new_snapshot
# Get the command object to test
self.cmd = volume_snapshot.CreateVolumeSnapshot(self.app, None)
@@ -152,6 +153,33 @@ class TestSnapshotCreate(TestSnapshot):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, data)
+ def test_snapshot_create_without_remote_source(self):
+ arglist = [
+ '--remote-source', 'source-name=test_source_name',
+ '--remote-source', 'source-id=test_source_id',
+ '--volume', self.new_snapshot.volume_id,
+ ]
+ ref_dict = {'source-name': 'test_source_name',
+ 'source-id': 'test_source_id'}
+ verifylist = [
+ ('remote_source', ref_dict),
+ ('volume', self.new_snapshot.volume_id),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.snapshots_mock.manage.assert_called_with(
+ volume_id=self.new_snapshot.volume_id,
+ ref=ref_dict,
+ name=None,
+ description=None,
+ metadata=None,
+ )
+ self.snapshots_mock.create.assert_not_called()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data, data)
+
class TestSnapshotDelete(TestSnapshot):
diff --git a/openstackclient/tests/unit/volume/v2/test_type.py b/openstackclient/tests/unit/volume/v2/test_type.py
index 325872d7..0d556e13 100644
--- a/openstackclient/tests/unit/volume/v2/test_type.py
+++ b/openstackclient/tests/unit/volume/v2/test_type.py
@@ -172,7 +172,11 @@ class TestTypeList(TestType):
"Description",
"Properties"
]
-
+ data_with_default_type = [(
+ volume_types[0].id,
+ volume_types[0].name,
+ True
+ )]
data = []
for t in volume_types:
data.append((
@@ -194,6 +198,7 @@ class TestTypeList(TestType):
super(TestTypeList, self).setUp()
self.types_mock.list.return_value = self.volume_types
+ self.types_mock.default.return_value = self.volume_types[0]
# get the command to test
self.cmd = volume_type.ListVolumeType(self.app, None)
@@ -203,6 +208,7 @@ class TestTypeList(TestType):
("long", False),
("private", False),
("public", False),
+ ("default", False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -220,6 +226,7 @@ class TestTypeList(TestType):
("long", True),
("private", False),
("public", True),
+ ("default", False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -236,6 +243,7 @@ class TestTypeList(TestType):
("long", False),
("private", True),
("public", False),
+ ("default", False),
]
parsed_args = self.check_parser(self.cmd, arglist, verifylist)
@@ -244,6 +252,23 @@ class TestTypeList(TestType):
self.assertEqual(self.columns, columns)
self.assertEqual(self.data, list(data))
+ def test_type_list_with_default_option(self):
+ arglist = [
+ "--default",
+ ]
+ verifylist = [
+ ("long", False),
+ ("private", False),
+ ("public", False),
+ ("default", True),
+ ]
+ parsed_args = self.check_parser(self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+ self.types_mock.default.assert_called_once_with()
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.data_with_default_type, list(data))
+
class TestTypeSet(TestType):
diff --git a/openstackclient/tests/unit/volume/v2/test_volume.py b/openstackclient/tests/unit/volume/v2/test_volume.py
index 41728342..4fef9dd9 100644
--- a/openstackclient/tests/unit/volume/v2/test_volume.py
+++ b/openstackclient/tests/unit/volume/v2/test_volume.py
@@ -450,6 +450,154 @@ class TestVolumeCreate(TestVolume):
self.assertEqual(self.columns, columns)
self.assertEqual(self.datalist, data)
+ def test_volume_create_with_bootable_and_readonly(self):
+ arglist = [
+ '--bootable',
+ '--read-only',
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
+ ]
+ verifylist = [
+ ('bootable', True),
+ ('non_bootable', False),
+ ('read_only', True),
+ ('read_write', False),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
+ ]
+
+ parsed_args = self.check_parser(
+ self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.create.assert_called_with(
+ size=self.new_volume.size,
+ snapshot_id=None,
+ name=self.new_volume.name,
+ description=None,
+ volume_type=None,
+ user_id=None,
+ project_id=None,
+ availability_zone=None,
+ metadata=None,
+ imageRef=None,
+ source_volid=None,
+ consistencygroup_id=None,
+ source_replica=None,
+ multiattach=False,
+ scheduler_hints=None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+ self.volumes_mock.set_bootable.assert_called_with(
+ self.new_volume.id, True)
+ self.volumes_mock.update_readonly_flag.assert_called_with(
+ self.new_volume.id, True)
+
+ def test_volume_create_with_nonbootable_and_readwrite(self):
+ arglist = [
+ '--non-bootable',
+ '--read-write',
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
+ ]
+ verifylist = [
+ ('bootable', False),
+ ('non_bootable', True),
+ ('read_only', False),
+ ('read_write', True),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
+ ]
+
+ parsed_args = self.check_parser(
+ self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.create.assert_called_with(
+ size=self.new_volume.size,
+ snapshot_id=None,
+ name=self.new_volume.name,
+ description=None,
+ volume_type=None,
+ user_id=None,
+ project_id=None,
+ availability_zone=None,
+ metadata=None,
+ imageRef=None,
+ source_volid=None,
+ consistencygroup_id=None,
+ source_replica=None,
+ multiattach=False,
+ scheduler_hints=None,
+ )
+
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+ self.volumes_mock.set_bootable.assert_called_with(
+ self.new_volume.id, False)
+ self.volumes_mock.update_readonly_flag.assert_called_with(
+ self.new_volume.id, False)
+
+ @mock.patch.object(volume.LOG, 'error')
+ def test_volume_create_with_bootable_and_readonly_fail(
+ self, mock_error):
+
+ self.volumes_mock.set_bootable.side_effect = (
+ exceptions.CommandError())
+
+ self.volumes_mock.update_readonly_flag.side_effect = (
+ exceptions.CommandError())
+
+ arglist = [
+ '--bootable',
+ '--read-only',
+ '--size', str(self.new_volume.size),
+ self.new_volume.name,
+ ]
+ verifylist = [
+ ('bootable', True),
+ ('non_bootable', False),
+ ('read_only', True),
+ ('read_write', False),
+ ('size', self.new_volume.size),
+ ('name', self.new_volume.name),
+ ]
+
+ parsed_args = self.check_parser(
+ self.cmd, arglist, verifylist)
+
+ columns, data = self.cmd.take_action(parsed_args)
+
+ self.volumes_mock.create.assert_called_with(
+ size=self.new_volume.size,
+ snapshot_id=None,
+ name=self.new_volume.name,
+ description=None,
+ volume_type=None,
+ user_id=None,
+ project_id=None,
+ availability_zone=None,
+ metadata=None,
+ imageRef=None,
+ source_volid=None,
+ consistencygroup_id=None,
+ source_replica=None,
+ multiattach=False,
+ scheduler_hints=None,
+ )
+
+ self.assertEqual(2, mock_error.call_count)
+ self.assertEqual(self.columns, columns)
+ self.assertEqual(self.datalist, data)
+ self.volumes_mock.set_bootable.assert_called_with(
+ self.new_volume.id, True)
+ self.volumes_mock.update_readonly_flag.assert_called_with(
+ self.new_volume.id, True)
+
def test_volume_create_with_source_replicated(self):
self.volumes_mock.get.return_value = self.new_volume
arglist = [
@@ -675,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']
@@ -705,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']
@@ -737,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']
@@ -767,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']
@@ -798,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']
@@ -828,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']
@@ -858,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']
@@ -888,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']
@@ -919,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',