Merge "Fix test_network_quota_exceeding test"
diff --git a/releasenotes/notes/Add-volume_size_extend-config--opt-for-volume-tests-041f7d25fc2f3e05.yaml b/releasenotes/notes/Add-volume_size_extend-config--opt-for-volume-tests-041f7d25fc2f3e05.yaml
new file mode 100644
index 0000000..8069bd3
--- /dev/null
+++ b/releasenotes/notes/Add-volume_size_extend-config--opt-for-volume-tests-041f7d25fc2f3e05.yaml
@@ -0,0 +1,10 @@
+---
+features:
+  - |
+    Adding new config option for volume tests which allows to specify the size
+    a volume will be extended by (if a test does extend a volume or needs
+    a new bigger volume). The option is beneficial in case such tests are
+    executed on systems where the chunk size (the minimum size a volume can be
+    extended by) is other than 1 (originally hardcoded in the tests).:
+
+    CONF.volume.volume_size_extend
diff --git a/releasenotes/notes/log-resource-client-20e58a295f729902.yaml b/releasenotes/notes/log-resource-client-20e58a295f729902.yaml
new file mode 100644
index 0000000..405fc5f
--- /dev/null
+++ b/releasenotes/notes/log-resource-client-20e58a295f729902.yaml
@@ -0,0 +1,5 @@
+---
+features:
+  - |
+    Add a new client to lists, creates, shows information for,
+    and updates neutron log resource.
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index b6bf369..260ba74 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -84,6 +84,7 @@
         cls.network_versions_client = cls.os_primary.network_versions_client
         cls.service_providers_client = cls.os_primary.service_providers_client
         cls.tags_client = cls.os_primary.tags_client
+        cls.log_resource_client = cls.os_primary.log_resource_client
 
     @classmethod
     def resource_setup(cls):
diff --git a/tempest/api/volume/test_volumes_clone.py b/tempest/api/volume/test_volumes_clone.py
index eb54426..9ca1c5e 100644
--- a/tempest/api/volume/test_volumes_clone.py
+++ b/tempest/api/volume/test_volumes_clone.py
@@ -49,13 +49,14 @@
         # Creates a volume from another volume passing a size different from
         # the source volume.
         src_size = CONF.volume.volume_size
+        extend_size = CONF.volume.volume_size_extend
 
         src_vol = self.create_volume(size=src_size)
         # Destination volume bigger than source
         dst_vol = self.create_volume(source_volid=src_vol['id'],
-                                     size=src_size + 1)
+                                     size=src_size + extend_size)
 
-        self._verify_volume_clone(src_vol, dst_vol, extra_size=1)
+        self._verify_volume_clone(src_vol, dst_vol, extra_size=extend_size)
 
     @decorators.idempotent_id('cbbcd7c6-5a6c-481a-97ac-ca55ab715d16')
     @utils.services('image')
diff --git a/tempest/api/volume/test_volumes_clone_negative.py b/tempest/api/volume/test_volumes_clone_negative.py
index 4bfb166..115465c 100644
--- a/tempest/api/volume/test_volumes_clone_negative.py
+++ b/tempest/api/volume/test_volumes_clone_negative.py
@@ -36,11 +36,11 @@
         """Test cloning a volume with decreasing size will fail"""
         # Creates a volume from another volume passing a size different from
         # the source volume.
-        src_size = CONF.volume.volume_size + 1
+        src_size = CONF.volume.volume_size + CONF.volume.volume_size_extend
         src_vol = self.create_volume(size=src_size)
 
         # Destination volume smaller than source
         self.assertRaises(exceptions.BadRequest,
                           self.volumes_client.create_volume,
-                          size=src_size - 1,
+                          size=src_size - CONF.volume.volume_size_extend,
                           source_volid=src_vol['id'])
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 35dd0ca..554fc6a 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -45,7 +45,7 @@
             container_format=CONF.image.container_formats[0],
             disk_format=CONF.image.disk_formats[0],
             visibility='private',
-            min_disk=CONF.volume.volume_size + 1)
+            min_disk=CONF.volume.volume_size + CONF.volume.volume_size_extend)
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.images_client.delete_image, image['id'])
 
@@ -223,7 +223,7 @@
     @decorators.idempotent_id('8f05a943-013c-4063-ac71-7baf561e82eb')
     def test_volume_extend_with_nonexistent_volume_id(self):
         """Test extending non existent volume should fail"""
-        extend_size = self.volume['size'] + 1
+        extend_size = self.volume['size'] + CONF.volume.volume_size_extend
         self.assertRaises(lib_exc.NotFound, self.volumes_client.extend_volume,
                           data_utils.rand_uuid(), new_size=extend_size)
 
@@ -231,7 +231,7 @@
     @decorators.idempotent_id('aff8ba64-6d6f-4f2e-bc33-41a08ee9f115')
     def test_volume_extend_without_passing_volume_id(self):
         """Test extending volume without passing volume id should fail"""
-        extend_size = self.volume['size'] + 1
+        extend_size = self.volume['size'] + CONF.volume.volume_size_extend
         self.assertRaises(lib_exc.NotFound, self.volumes_client.extend_volume,
                           None, new_size=extend_size)
 
diff --git a/tempest/clients.py b/tempest/clients.py
index 6080f01..ebf2540 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -73,6 +73,7 @@
         self.qos_min_bw_client = self.network.QosMinimumBandwidthRulesClient()
         self.segments_client = self.network.SegmentsClient()
         self.trunks_client = self.network.TrunksClient()
+        self.log_resource_client = self.network.LogResourceClient()
 
     def _set_image_clients(self):
         if CONF.service_available.glance:
diff --git a/tempest/config.py b/tempest/config.py
index c409db6..6715a00 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -1000,6 +1000,11 @@
     cfg.IntOpt('volume_size',
                default=1,
                help='Default size in GB for volumes created by volumes tests'),
+    cfg.IntOpt('volume_size_extend',
+               default=1,
+               help="Size in GB a volume is extended by - if a test "
+                    "extends a volume, the size of the new volume will be "
+                    "volume_size + volume_size_extend."),
     cfg.ListOpt('manage_volume_ref',
                 default=['source-name', 'volume-%s'],
                 help="A reference to existing volume for volume manage. "
diff --git a/tempest/lib/common/dynamic_creds.py b/tempest/lib/common/dynamic_creds.py
index e2ff00a..32dea44 100644
--- a/tempest/lib/common/dynamic_creds.py
+++ b/tempest/lib/common/dynamic_creds.py
@@ -407,13 +407,23 @@
             # Maintained until tests are ported
             LOG.info("Acquired dynamic creds:\n"
                      " credentials: %s", credentials)
-            if (self.neutron_available and self.create_networks):
-                network, subnet, router = self._create_network_resources(
-                    credentials.tenant_id)
-                credentials.set_resources(network=network, subnet=subnet,
-                                          router=router)
-                LOG.info("Created isolated network resources for:\n"
-                         " credentials: %s", credentials)
+            # NOTE(gmann): For 'domain' and 'system' scoped token, there is no
+            # project_id so we are skipping the network creation for both
+            # scope. How these scoped token can create the network, Nova
+            # server or other project mapped resources is one of the open
+            # question and discussed a lot in Xena cycle PTG. Once we sort
+            # out that then if needed we can update the network creation here.
+            if (not scope or scope == 'project'):
+                if (self.neutron_available and self.create_networks):
+                    network, subnet, router = self._create_network_resources(
+                        credentials.tenant_id)
+                    credentials.set_resources(network=network, subnet=subnet,
+                                              router=router)
+                    LOG.info("Created isolated network resources for:\n"
+                             " credentials: %s", credentials)
+            else:
+                LOG.info("Network resources are not created for scope: %s",
+                         scope)
         return credentials
 
     # TODO(gmann): Remove this method in favor of get_project_member_creds()
diff --git a/tempest/lib/services/network/__init__.py b/tempest/lib/services/network/__init__.py
index 7e57499..fc85140 100644
--- a/tempest/lib/services/network/__init__.py
+++ b/tempest/lib/services/network/__init__.py
@@ -15,6 +15,7 @@
 from tempest.lib.services.network.agents_client import AgentsClient
 from tempest.lib.services.network.extensions_client import ExtensionsClient
 from tempest.lib.services.network.floating_ips_client import FloatingIPsClient
+from tempest.lib.services.network.log_resource_client import LogResourceClient
 from tempest.lib.services.network.metering_label_rules_client import \
     MeteringLabelRulesClient
 from tempest.lib.services.network.metering_labels_client import \
@@ -45,4 +46,4 @@
            'QosClient', 'QosMinimumBandwidthRulesClient', 'QuotasClient',
            'RoutersClient', 'SecurityGroupRulesClient', 'SecurityGroupsClient',
            'SegmentsClient', 'ServiceProvidersClient', 'SubnetpoolsClient',
-           'SubnetsClient', 'TagsClient', 'TrunksClient']
+           'SubnetsClient', 'TagsClient', 'TrunksClient', 'LogResourceClient']
diff --git a/tempest/lib/services/network/log_resource_client.py b/tempest/lib/services/network/log_resource_client.py
new file mode 100644
index 0000000..727b138
--- /dev/null
+++ b/tempest/lib/services/network/log_resource_client.py
@@ -0,0 +1,74 @@
+# Copyright 2021 Red Hat, Inc.
+# All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.lib.services.network import base
+
+
+class LogResourceClient(base.BaseNetworkClient):
+
+    def create_log(self, **kwargs):
+        """Creates a log resource.
+
+        Creates a log resource by using the configuration that you define in
+        the request object.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/network/v2/index.html#create-log
+        """
+        uri = '/log/logs/'
+        post_data = {'log': kwargs}
+        return self.create_resource(uri, post_data)
+
+    def update_log(self, log_id, **kwargs):
+        """Updates a log resource.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/network/v2/index.html#update-log
+        """
+        uri = '/log/logs/%s' % log_id
+        post_data = {'log': kwargs}
+        return self.update_resource(uri, post_data)
+
+    def show_log(self, log_id, **fields):
+        """Shows details for a log id.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/network/v2/index.html#show-log
+        """
+        uri = '/log/logs/%s' % log_id
+        return self.show_resource(uri, **fields)
+
+    def delete_log(self, log_id):
+        """Deletes a log resource.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/network/v2/index.html#delete-log
+        """
+        uri = '/log/logs/%s' % log_id
+        return self.delete_resource(uri)
+
+    def list_logs(self, **filters):
+        """Lists Logs.
+
+        For a full list of available parameters, please refer to the official
+        API reference:
+        https://docs.openstack.org/api-ref/network/v2/index.html#list-logs
+        """
+        uri = '/log/logs'
+        return self.list_resources(uri, **filters)
diff --git a/tempest/tests/lib/cmd/test_check_uuid.py b/tempest/tests/lib/cmd/test_check_uuid.py
index 5d63dec..a621a75 100644
--- a/tempest/tests/lib/cmd/test_check_uuid.py
+++ b/tempest/tests/lib/cmd/test_check_uuid.py
@@ -19,7 +19,6 @@
 from unittest import mock
 
 from tempest.lib.cmd import check_uuid
-from tempest.lib import decorators
 from tempest.tests import base
 
 
@@ -50,7 +49,6 @@
         with open(tests_file, "r") as f:
             self.assertTrue(TestCLInterface.CODE == f.read())
 
-    @decorators.skip_because(bug='1918316')
     def test_fix_argument_yes(self):
         temp_dir = tempfile.mkdtemp(prefix='check-uuid-yes', dir=".")
         self.addCleanup(shutil.rmtree, temp_dir, ignore_errors=True)
diff --git a/tempest/tests/lib/services/network/test_log_resource_client.py b/tempest/tests/lib/services/network/test_log_resource_client.py
new file mode 100644
index 0000000..ef502bc
--- /dev/null
+++ b/tempest/tests/lib/services/network/test_log_resource_client.py
@@ -0,0 +1,145 @@
+# Copyright 2021 Red Hat, Inc.
+# 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 copy
+
+from tempest.lib.services.network import log_resource_client
+from tempest.tests.lib import fake_auth_provider
+from tempest.tests.lib.services import base
+
+
+class TestLogResourceClient(base.BaseServiceTest):
+
+    FAKE_LOGS = {
+        "logs": [
+            {
+                "name": "security group log1",
+                "description": "Log for test demo.",
+                "id": "2f245a7b-796b-4f26-9cf9-9e82d248fda7",
+                "project_id": "92a5a4f4245a4abbafacb7ca73b027b0",
+                "tenant_id": "92a5a4f4245a4abbafacb7ca73b027b0",
+                "created_at": "2018-04-03T21:03:04Z",
+                "updated_at": "2018-04-03T21:03:04Z",
+                "enabled": True,
+                "revision_number": 1,
+                "resource_type": "security_group",
+                "resource_id": None,
+                "target_id": None,
+                "event": "ALL"
+            },
+            {
+                "name": "security group log2",
+                "description": "Log for test demo.",
+                "id": "46ebaec1-0570-43ac-82f6-60d2b03168c4",
+                "project_id": "82a5a4f4245a4abbafacb7ca73b027b0",
+                "tenant_id": "82a5a4f4245a4abbafacb7ca73b027b0",
+                "created_at": "2018-04-03T21:04:04Z",
+                "updated_at": "2018-04-03T21:04:04Z",
+                "enabled": True,
+                "revision_number": 2,
+                "resource_type": "security_group",
+                "resource_id": None,
+                "target_id": None,
+                "event": "ALL"
+            }
+        ]
+    }
+
+    FAKE_LOG_ID = "2f245a7b-796b-4f26-9cf9-9e82d248fda7"
+
+    def setUp(self):
+        super(TestLogResourceClient, self).setUp()
+        fake_auth = fake_auth_provider.FakeAuthProvider()
+        self.log_resource_client = log_resource_client.LogResourceClient(
+            fake_auth, "network", "regionOne")
+
+    def _test_list_logs(self, bytes_body=False):
+        self.check_service_client_function(
+            self.log_resource_client.list_logs,
+            "tempest.lib.common.rest_client.RestClient.get",
+            self.FAKE_LOGS,
+            bytes_body,
+            200)
+
+    def _test_show_log(self, bytes_body=False):
+        self.check_service_client_function(
+            self.log_resource_client.show_log,
+            "tempest.lib.common.rest_client.RestClient.get",
+            {"log": self.FAKE_LOGS["logs"][0]},
+            bytes_body,
+            200,
+            log_id=self.FAKE_LOG_ID)
+
+    def _test_create_log(self, bytes_body=False):
+        self.check_service_client_function(
+            self.log_resource_client.create_log,
+            "tempest.lib.common.rest_client.RestClient.post",
+            {"logs": self.FAKE_LOGS["logs"][1]},
+            bytes_body,
+            201,
+            log_id="2f245a7b-796b-4f26-9cf9-9e82d248fda7")
+
+    def _test_update_log(self, bytes_body=False):
+        update_kwargs = {
+            "tenant_id": "83a5a4f4245a4abbafacb7ca73b027b0"
+        }
+
+        resp_body = {
+            "logs": copy.deepcopy(
+                self.FAKE_LOGS["logs"][0]
+            )
+        }
+        resp_body["logs"].update(update_kwargs)
+
+        self.check_service_client_function(
+            self.log_resource_client.update_log,
+            "tempest.lib.common.rest_client.RestClient.put",
+            resp_body,
+            bytes_body,
+            200,
+            log_id=self.FAKE_LOG_ID,
+            **update_kwargs)
+
+    def test_list_logs_with_str_body(self):
+        self._test_list_logs()
+
+    def test_list_logs_with_bytes_body(self):
+        self._test_list_logs(bytes_body=True)
+
+    def test_create_log_with_str_body(self):
+        self._test_create_log()
+
+    def test_create_log_with_bytes_body(self):
+        self._test_create_log(bytes_body=True)
+
+    def test_show_log_with_str_body(self):
+        self._test_show_log()
+
+    def test_show_log_with_bytes_body(self):
+        self._test_show_log(bytes_body=True)
+
+    def test_update_log_with_str_body(self):
+        self._test_update_log()
+
+    def test_update_log_with_bytes_body(self):
+        self._test_update_log(bytes_body=True)
+
+    def test_delete_log(self):
+        self.check_service_client_function(
+            self.log_resource_client.delete_log,
+            'tempest.lib.common.rest_client.RestClient.delete',
+            {},
+            status=204,
+            log_id=self.FAKE_LOG_ID)
diff --git a/zuul.d/integrated-gate.yaml b/zuul.d/integrated-gate.yaml
index 622bbad..2da5579 100644
--- a/zuul.d/integrated-gate.yaml
+++ b/zuul.d/integrated-gate.yaml
@@ -254,7 +254,7 @@
     timeout: 10800
     # This job runs on stable/stein onwards.
     branches: ^(?!stable/(ocata|pike|queens|rocky)).*$
-    vars:
+    vars: &tempest_slow_vars
       tox_envlist: slow-serial
       devstack_localrc:
         CINDER_ENABLED_BACKENDS: lvm:lvmdriver-1,lvm:lvmdriver-2
@@ -275,10 +275,12 @@
 
 - job:
     name: tempest-slow-py3
-    parent: tempest-slow
+    parent: tempest-multinode-full-py3
     # This job version is with swift enabled on py3
     # as swift is ready on py3 from stable/ussuri onwards.
+    timeout: 10800
     branches: ^(?!stable/(ocata|pike|queens|rocky|stein|train)).*$
+    vars: *tempest_slow_vars
 
 - job:
     name: tempest-cinder-v2-api
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index 698df53..c876579 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -68,18 +68,6 @@
             irrelevant-files: *tempest-irrelevant-files
         - grenade:
             irrelevant-files: *tempest-irrelevant-files
-        - puppet-openstack-integration-4-scenario001-tempest-centos-7:
-            voting: false
-            irrelevant-files: *tempest-irrelevant-files
-        - puppet-openstack-integration-4-scenario002-tempest-centos-7:
-            voting: false
-            irrelevant-files: *tempest-irrelevant-files
-        - puppet-openstack-integration-4-scenario003-tempest-centos-7:
-            voting: false
-            irrelevant-files: *tempest-irrelevant-files
-        - puppet-openstack-integration-4-scenario004-tempest-centos-7:
-            voting: false
-            irrelevant-files: *tempest-irrelevant-files
         - neutron-tempest-dvr:
             voting: false
             irrelevant-files: *tempest-irrelevant-files