From 871450abcd89f9bb5ee9f75cdef3b812695eae93 Mon Sep 17 00:00:00 2001
From: Dean Troyer <dtroyer@gmail.com>
Date: Wed, 26 Apr 2017 17:02:12 -0500
Subject: [PATCH] Fix quota functional tests for nova-net

We need to skip some functional tests when testing against a nova-net cloud
so add the bits to detect that.

Also JSON-ify the quota functional tests and add the skips for nova-net.

Change-Id: Ibfeeb3f967f34c98e80271a8214cf95dc50407f1
---
 openstackclient/common/quota.py               |   7 +-
 openstackclient/tests/functional/base.py      |  12 ++
 .../tests/functional/common/test_quota.py     | 153 ++++++++++++------
 3 files changed, 119 insertions(+), 53 deletions(-)

diff --git a/openstackclient/common/quota.py b/openstackclient/common/quota.py
index ec4c8b51b1..73dfd9091d 100644
--- a/openstackclient/common/quota.py
+++ b/openstackclient/common/quota.py
@@ -299,7 +299,6 @@ class SetQuota(command.Command):
         identity_client = self.app.client_manager.identity
         compute_client = self.app.client_manager.compute
         volume_client = self.app.client_manager.volume
-        network_client = self.app.client_manager.network
         compute_kwargs = {}
         for k, v in COMPUTE_QUOTAS.items():
             value = getattr(parsed_args, k, None)
@@ -352,7 +351,11 @@ class SetQuota(command.Command):
                 volume_client.quotas.update(
                     project,
                     **volume_kwargs)
-            if network_kwargs:
+            if (
+                    network_kwargs and
+                    self.app.client_manager.is_network_endpoint_enabled()
+            ):
+                network_client = self.app.client_manager.network
                 network_client.update_quota(
                     project,
                     **network_kwargs)
diff --git a/openstackclient/tests/functional/base.py b/openstackclient/tests/functional/base.py
index 8574329621..2d0706456b 100644
--- a/openstackclient/tests/functional/base.py
+++ b/openstackclient/tests/functional/base.py
@@ -42,6 +42,18 @@ def execute(cmd, fail_ok=False, merge_stderr=False):
     return result
 
 
+def is_service_enabled(service):
+    """Ask client cloud if service is available"""
+    try:
+        ret = execute('openstack service show -f value -c enabled ' + service)
+    except exceptions.CommandFailed:
+        # We get here for multiple reasons, all of them mean that a working
+        # service is not avilable
+        return False
+
+    return "True" in ret
+
+
 class TestCase(testtools.TestCase):
 
     delimiter_line = re.compile('^\+\-[\+\-]+\-\+$')
diff --git a/openstackclient/tests/functional/common/test_quota.py b/openstackclient/tests/functional/common/test_quota.py
index 8092b3cee8..1b13e95ed2 100644
--- a/openstackclient/tests/functional/common/test_quota.py
+++ b/openstackclient/tests/functional/common/test_quota.py
@@ -10,74 +10,125 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import json
+
 from openstackclient.tests.functional import base
 
 
 class QuotaTests(base.TestCase):
-    """Functional tests for quota. """
-    # Test quota information for compute, network and volume.
-    EXPECTED_FIELDS = ['instances', 'networks', 'volumes']
-    EXPECTED_CLASS_FIELDS = ['instances', 'volumes']
+    """Functional tests for quota
+
+    Note that for 'set' tests use different quotas for each API in different
+    test runs as these may run in parallel and otherwise step on each other.
+    """
+
     PROJECT_NAME = None
 
     @classmethod
     def setUpClass(cls):
+        cls.haz_network = base.is_service_enabled('network')
         cls.PROJECT_NAME =\
             cls.get_openstack_configuration_value('auth.project_name')
 
     def test_quota_list_network_option(self):
-        self.openstack('quota set --networks 40 ' +
-                       self.PROJECT_NAME)
-        raw_output = self.openstack('quota list --network')
-        self.assertIsNotNone(raw_output)
-        self.assertIn("40", raw_output)
+        if not self.haz_network:
+            self.skipTest("No Network service present")
+        self.openstack('quota set --networks 40 ' + self.PROJECT_NAME)
+        cmd_output = json.loads(self.openstack(
+            'quota list -f json --network'
+        ))
+        self.assertIsNotNone(cmd_output)
+        self.assertEqual(
+            40,
+            cmd_output[0]["Networks"],
+        )
 
     def test_quota_list_compute_option(self):
-        self.openstack('quota set --instances 40 ' +
-                       self.PROJECT_NAME)
-        raw_output = self.openstack('quota list --compute')
-        self.assertIsNotNone(raw_output)
-        self.assertIn("40", raw_output)
+        self.openstack('quota set --instances 30 ' + self.PROJECT_NAME)
+        cmd_output = json.loads(self.openstack(
+            'quota list -f json --compute'
+        ))
+        self.assertIsNotNone(cmd_output)
+        self.assertEqual(
+            30,
+            cmd_output[0]["Instances"],
+        )
 
     def test_quota_list_volume_option(self):
-        self.openstack('quota set --backups 40 ' +
-                       self.PROJECT_NAME)
-        raw_output = self.openstack('quota list --volume')
-        self.assertIsNotNone(raw_output)
-        self.assertIn("40", raw_output)
+        self.openstack('quota set --volumes 20 ' + self.PROJECT_NAME)
+        cmd_output = json.loads(self.openstack(
+            'quota list -f json --volume'
+        ))
+        self.assertIsNotNone(cmd_output)
+        self.assertEqual(
+            20,
+            cmd_output[0]["Volumes"],
+        )
 
-    def test_quota_set(self):
-        self.openstack('quota set --instances 11 --volumes 11 --networks 11 ' +
-                       self.PROJECT_NAME)
-        opts = self.get_opts(self.EXPECTED_FIELDS)
-        raw_output = self.openstack('quota show ' + self.PROJECT_NAME + opts)
-        self.assertEqual("11\n11\n11\n", raw_output)
+    def test_quota_set_project(self):
+        """Test quota set, show"""
+        network_option = ""
+        if self.haz_network:
+            network_option = "--routers 21 "
+        self.openstack(
+            'quota set --cores 31 --backups 41 ' +
+            network_option +
+            self.PROJECT_NAME
+        )
+        cmd_output = json.loads(self.openstack(
+            'quota show -f json ' + self.PROJECT_NAME
+        ))
+        self.assertIsNotNone(cmd_output)
+        self.assertEqual(
+            31,
+            cmd_output["cores"],
+        )
+        self.assertEqual(
+            41,
+            cmd_output["backups"],
+        )
+        if self.haz_network:
+            self.assertEqual(
+                21,
+                cmd_output["routers"],
+            )
 
-    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)
+        # Check default quotas
+        cmd_output = json.loads(self.openstack(
+            'quota show -f json --default'
+        ))
+        self.assertIsNotNone(cmd_output)
+        # We don't necessarily know the default quotas, we're checking the
+        # returned attributes
+        self.assertTrue(cmd_output["cores"] >= 0)
+        self.assertTrue(cmd_output["backups"] >= 0)
+        if self.haz_network:
+            self.assertTrue(cmd_output["routers"] >= 0)
 
-    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)
+    def test_quota_set_class(self):
+        self.openstack(
+            'quota set --key-pairs 33 --snapshots 43 ' +
+            '--class default'
+        )
+        cmd_output = json.loads(self.openstack(
+            'quota show -f json --class default'
+        ))
+        self.assertIsNotNone(cmd_output)
+        self.assertEqual(
+            33,
+            cmd_output["key-pairs"],
+        )
+        self.assertEqual(
+            43,
+            cmd_output["snapshots"],
+        )
 
-    def test_quota_show_with_default_option(self):
-        raw_output = self.openstack('quota show --default')
-        for expected_field in self.EXPECTED_FIELDS:
-            self.assertIn(expected_field, raw_output)
-
-    def test_quota_show_with_class_option(self):
-        raw_output = self.openstack('quota show --class')
-        for expected_field in self.EXPECTED_CLASS_FIELDS:
-            self.assertIn(expected_field, raw_output)
-
-    def test_quota_class_set(self):
-        class_name = 'default'
-        class_expected_fields = ['instances', 'volumes']
-        self.openstack('quota set --instances 11 --volumes 11 --class ' +
-                       class_name)
-        opts = self.get_opts(class_expected_fields)
-        raw_output = self.openstack('quota show --class ' + class_name + opts)
-        self.assertEqual("11\n11\n", raw_output)
+        # Check default quota class
+        cmd_output = json.loads(self.openstack(
+            'quota show -f json --class'
+        ))
+        self.assertIsNotNone(cmd_output)
+        # We don't necessarily know the default quotas, we're checking the
+        # returned attributes
+        self.assertTrue(cmd_output["key-pairs"] >= 0)
+        self.assertTrue(cmd_output["snapshots"] >= 0)