Merge "Pass custom args to create_port through create_server"
diff --git a/doc/source/supported_version.rst b/doc/source/supported_version.rst
index 388b4cd..4ca7f0d 100644
--- a/doc/source/supported_version.rst
+++ b/doc/source/supported_version.rst
@@ -9,9 +9,9 @@
 
 Tempest master supports the below OpenStack Releases:
 
+* Victoria
 * Ussuri
 * Train
-* Stein
 
 For older OpenStack Release:
 
@@ -34,3 +34,4 @@
 
 * Python 3.6
 * Python 3.7
+* Python 3.8
diff --git a/releasenotes/source/index.rst b/releasenotes/source/index.rst
index d8702f9..21f414e 100644
--- a/releasenotes/source/index.rst
+++ b/releasenotes/source/index.rst
@@ -6,6 +6,7 @@
    :maxdepth: 1
 
    unreleased
+   v26.0.0
    v24.0.0
    v23.0.0
    v22.1.0
diff --git a/releasenotes/source/v26.0.0.rst b/releasenotes/source/v26.0.0.rst
new file mode 100644
index 0000000..4161f89
--- /dev/null
+++ b/releasenotes/source/v26.0.0.rst
@@ -0,0 +1,5 @@
+=====================
+v26.0.0 Release Notes
+=====================
+.. release-notes:: 26.0.0 Release Notes
+   :version: 26.0.0
diff --git a/tempest/lib/common/rest_client.py b/tempest/lib/common/rest_client.py
index b47b511..a987e03 100644
--- a/tempest/lib/common/rest_client.py
+++ b/tempest/lib/common/rest_client.py
@@ -104,16 +104,18 @@
                                        'location', 'proxy-authenticate',
                                        'retry-after', 'server',
                                        'vary', 'www-authenticate'))
-        dscv = disable_ssl_certificate_validation
+        self.dscv = disable_ssl_certificate_validation
 
         if proxy_url:
             self.http_obj = http.ClosingProxyHttp(
                 proxy_url,
-                disable_ssl_certificate_validation=dscv, ca_certs=ca_certs,
+                disable_ssl_certificate_validation=self.dscv,
+                ca_certs=ca_certs,
                 timeout=http_timeout, follow_redirects=follow_redirects)
         else:
             self.http_obj = http.ClosingHttp(
-                disable_ssl_certificate_validation=dscv, ca_certs=ca_certs,
+                disable_ssl_certificate_validation=self.dscv,
+                ca_certs=ca_certs,
                 timeout=http_timeout, follow_redirects=follow_redirects)
 
     def get_headers(self, accept_type=None, send_type=None):
diff --git a/tempest/lib/services/object_storage/object_client.py b/tempest/lib/services/object_storage/object_client.py
index 383aff6..6970c0a 100644
--- a/tempest/lib/services/object_storage/object_client.py
+++ b/tempest/lib/services/object_storage/object_client.py
@@ -12,6 +12,7 @@
 #    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 ssl
 
 from six.moves import http_client as httplib
 from six.moves.urllib import parse as urlparse
@@ -118,7 +119,7 @@
         path = str(parsed.path) + "/"
         path += "%s/%s" % (str(container), str(object_name))
 
-        conn = _create_connection(parsed)
+        conn = self._create_connection(parsed)
         # Send the PUT request and the headers including the "Expect" header
         conn.putrequest('PUT', path)
 
@@ -151,15 +152,21 @@
 
         return resp.status, resp.reason
 
+    def _create_connection(self, parsed_url):
+        """Helper function to create connection with httplib
 
-def _create_connection(parsed_url):
-    """Helper function to create connection with httplib
+        :param parsed_url: parsed url of the remote location
+        """
+        context = None
+        # If CONF.identity.disable_ssl_certificate_validation is true,
+        # do not check ssl certification.
+        if self.dscv:
+            context = ssl._create_unverified_context()
+        if parsed_url.scheme == 'https':
+            conn = httplib.HTTPSConnection(parsed_url.netloc,
+                                           context=context)
+        else:
+            conn = httplib.HTTPConnection(parsed_url.netloc,
+                                          context=context)
 
-    :param parsed_url: parsed url of the remote location
-    """
-    if parsed_url.scheme == 'https':
-        conn = httplib.HTTPSConnection(parsed_url.netloc)
-    else:
-        conn = httplib.HTTPConnection(parsed_url.netloc)
-
-    return conn
+        return conn
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 905ed50..acc563a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -415,19 +415,17 @@
         self.assertEqual(backup_id, restore['backup_id'])
         return restore
 
-    def rebuild_server(self, server_id, image=None,
-                       preserve_ephemeral=False, wait=True,
-                       rebuild_kwargs=None):
+    def rebuild_server(self, server_id, image=None, preserve_ephemeral=False,
+                       wait=True, **kwargs):
         if image is None:
             image = CONF.compute.image_ref
-        rebuild_kwargs = rebuild_kwargs or {}
         LOG.debug("Rebuilding server (id: %s, image: %s, preserve eph: %s)",
                   server_id, image, preserve_ephemeral)
         self.servers_client.rebuild_server(
             server_id=server_id,
             image_ref=image,
             preserve_ephemeral=preserve_ephemeral,
-            **rebuild_kwargs)
+            **kwargs)
         if wait:
             waiters.wait_for_server_status(self.servers_client,
                                            server_id, 'ACTIVE')
@@ -754,14 +752,12 @@
     def nova_volume_detach(self, server, volume):
         """Compute volume detach
 
-        This utility detaches volume from compute and check whether the
-        volume status is 'available' state, and if not, an exception
-        will be thrown.
+        This utility detaches the volume from the server and checks whether the
+        volume attachment has been removed from Nova.
         """
         self.servers_client.detach_volume(server['id'], volume['id'])
-        waiters.wait_for_volume_resource_status(self.volumes_client,
-                                                volume['id'], 'available')
-        volume = self.volumes_client.show_volume(volume['id'])['volume']
+        waiters.wait_for_volume_attachment_remove_from_server(
+            self.servers_client, server['id'], volume['id'])
 
     def ping_ip_address(self, ip_address, should_succeed=True,
                         ping_timeout=None, mtu=None, server=None):
@@ -1080,12 +1076,19 @@
         def cidr_in_use(cidr, project_id):
             """Check cidr existence
 
-            :returns: True if subnet with cidr already exist in tenant
-                  False else
+            :returns: True if subnet with cidr already exist in tenant or
+                  external False else
             """
-            cidr_in_use = self.os_admin.subnets_client.list_subnets(
+            tenant_subnets = self.os_admin.subnets_client.list_subnets(
                 project_id=project_id, cidr=cidr)['subnets']
-            return len(cidr_in_use) != 0
+            external_nets = self.os_admin.networks_client.list_networks(
+                **{"router:external": True})['networks']
+            external_subnets = []
+            for ext_net in external_nets:
+                external_subnets.extend(
+                    self.os_admin.subnets_client.list_subnets(
+                        network_id=ext_net['id'], cidr=cidr)['subnets'])
+            return len(tenant_subnets + external_subnets) != 0
 
         ip_version = kwargs.pop('ip_version', 4)
 
diff --git a/tempest/tests/lib/services/object_storage/test_object_client.py b/tempest/tests/lib/services/object_storage/test_object_client.py
index c646d61..d6df243 100644
--- a/tempest/tests/lib/services/object_storage/test_object_client.py
+++ b/tempest/tests/lib/services/object_storage/test_object_client.py
@@ -31,15 +31,18 @@
         self.object_client = object_client.ObjectClient(self.fake_auth,
                                                         'swift', 'region1')
 
-    @mock.patch.object(object_client, '_create_connection')
+    @mock.patch('tempest.lib.services.object_storage.object_client.'
+                'ObjectClient._create_connection')
     def test_create_object_continue_no_data(self, mock_poc):
         self._validate_create_object_continue(None, mock_poc)
 
-    @mock.patch.object(object_client, '_create_connection')
+    @mock.patch('tempest.lib.services.object_storage.object_client.'
+                'ObjectClient._create_connection')
     def test_create_object_continue_with_data(self, mock_poc):
         self._validate_create_object_continue('hello', mock_poc)
 
-    @mock.patch.object(object_client, '_create_connection')
+    @mock.patch('tempest.lib.services.object_storage.object_client.'
+                'ObjectClient._create_connection')
     def test_create_continue_with_no_continue_received(self, mock_poc):
         self._validate_create_object_continue('hello', mock_poc,
                                               initial_status=201)
diff --git a/tox.ini b/tox.ini
index 80d5de2..d8e059a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -11,7 +11,7 @@
     VIRTUAL_ENV={envdir}
     OS_TEST_PATH=./tempest/test_discover
 deps =
-    -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
+    -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
     -r{toxinidir}/requirements.txt
 
 [testenv]
@@ -28,7 +28,7 @@
 install_command = pip install {opts} {packages}
 whitelist_externals = *
 deps =
-    -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
+    -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
     -r{toxinidir}/requirements.txt
     -r{toxinidir}/test-requirements.txt
 commands =
@@ -263,7 +263,7 @@
 
 [testenv:venv]
 deps =
-  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
+  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
   -r{toxinidir}/requirements.txt
   -r{toxinidir}/doc/requirements.txt
 commands = {posargs}
@@ -278,7 +278,7 @@
 
 [testenv:docs]
 deps =
-  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
+  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
   -r{toxinidir}/doc/requirements.txt
 commands =
   sphinx-apidoc -f -o doc/source/tests/compute tempest/api/compute
@@ -363,7 +363,7 @@
 
 [testenv:releasenotes]
 deps =
-  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/victoria}
+  -c{env:UPPER_CONSTRAINTS_FILE:https://releases.openstack.org/constraints/upper/master}
   -r{toxinidir}/doc/requirements.txt
 commands =
   rm -rf releasenotes/build
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index f2522af..5dcd27f 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -48,8 +48,6 @@
             irrelevant-files: *tempest-irrelevant-files
         - tempest-full-train-py3:
             irrelevant-files: *tempest-irrelevant-files
-        - tempest-full-stein-py3:
-            irrelevant-files: *tempest-irrelevant-files
         - tempest-multinode-full-py3:
             irrelevant-files: *tempest-irrelevant-files
         - tempest-tox-plugin-sanity-check:
@@ -139,7 +137,6 @@
         - tempest-full-victoria-py3
         - tempest-full-ussuri-py3
         - tempest-full-train-py3
-        - tempest-full-stein-py3
     periodic:
       jobs:
         - tempest-all
diff --git a/zuul.d/stable-jobs.yaml b/zuul.d/stable-jobs.yaml
index 832a0d5..769b280 100644
--- a/zuul.d/stable-jobs.yaml
+++ b/zuul.d/stable-jobs.yaml
@@ -15,9 +15,3 @@
     parent: tempest-full-py3
     nodeset: openstack-single-node-bionic
     override-checkout: stable/train
-
-- job:
-    name: tempest-full-stein-py3
-    parent: tempest-full-py3
-    nodeset: openstack-single-node-bionic
-    override-checkout: stable/stein