Merge "Fix unit tests cleanup for --resource-list option"
diff --git a/releasenotes/notes/Add-http_qcow2_image-config-option-a9dca410897c3044.yaml b/releasenotes/notes/Add-http_qcow2_image-config-option-a9dca410897c3044.yaml
new file mode 100644
index 0000000..c1b0033
--- /dev/null
+++ b/releasenotes/notes/Add-http_qcow2_image-config-option-a9dca410897c3044.yaml
@@ -0,0 +1,8 @@
+---
+features:
+  - |
+    Added a new config option in the `image` section, `http_qcow2_image`,
+    which will use `qcow2` format image to download from the external
+    source specified and use it for image conversion in glance tests. By
+    default it will download
+    `http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-disk.img`
diff --git a/releasenotes/notes/image-config-http-image-default-value-change-476622e984e16ab5.yaml b/releasenotes/notes/image-config-http-image-default-value-change-476622e984e16ab5.yaml
new file mode 100644
index 0000000..96e9251
--- /dev/null
+++ b/releasenotes/notes/image-config-http-image-default-value-change-476622e984e16ab5.yaml
@@ -0,0 +1,7 @@
+---
+upgrade:
+  - |
+    Changed the default value of 'http_image' config option in the
+    'image' group to 'http://download.cirros-cloud.net/0.6.2/cirros-0.6.2-x86_64-uec.tar.gz'
+    from 'http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz' as former
+    image is very old and we should always use latest one.
\ No newline at end of file
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 89d5f91..0cc088a 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -100,10 +100,9 @@
         """Create Image & stage image file for glance-direct import method."""
         image_name = data_utils.rand_name('test-image')
         container_format = CONF.image.container_formats[0]
-        disk_format = CONF.image.disk_formats[0]
         image = self.create_image(name=image_name,
                                   container_format=container_format,
-                                  disk_format=disk_format,
+                                  disk_format='raw',
                                   visibility='private')
         self.assertEqual('queued', image['status'])
 
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index e468e32..5bb8eef 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -76,7 +76,7 @@
                                      '%s import method' % method)
 
     def _stage_and_check(self):
-        image = self._create_image()
+        image = self._create_image(disk_format='raw')
         # Stage image data
         file_content = data_utils.random_bytes()
         image_file = io.BytesIO(file_content)
@@ -131,7 +131,7 @@
         self.assertEqual(image['id'], body['id'])
         self.assertEqual('queued', body['status'])
         # import image from web to backend
-        image_uri = CONF.image.http_image
+        image_uri = CONF.image.http_qcow2_image
         self.client.image_import(image['id'], method='web-download',
                                  import_params={'uri': image_uri})
         waiters.wait_for_image_imported_to_stores(self.client, image['id'])
diff --git a/tempest/api/image/v2/test_images_dependency.py b/tempest/api/image/v2/test_images_dependency.py
index 326045b..41611bb 100644
--- a/tempest/api/image/v2/test_images_dependency.py
+++ b/tempest/api/image/v2/test_images_dependency.py
@@ -56,9 +56,10 @@
                 "not enabled" % (cls.__name__))
             raise cls.skipException(skip_msg)
 
-    def _create_instance_snapshot(self):
+    def _create_instance_snapshot(self, bfv=False):
         """Create instance from image and then snapshot the instance."""
         # Create image and store data to image
+        source = 'volume' if bfv else 'image'
         image_name = data_utils.rand_name(
             prefix=CONF.resource_name_prefix,
             name='image-dependency-test')
@@ -71,12 +72,20 @@
         self.client.store_image_file(image['id'], image_file)
         waiters.wait_for_image_status(
             self.client, image['id'], 'active')
-        # Create instance
-        instance = self.create_test_server(
-            name='instance-depend-image',
-            image_id=image['id'],
-            wait_until='ACTIVE')
-        LOG.info("Instance from image is created %s", instance)
+        if bfv:
+            # Create instance
+            instance = self.create_test_server(
+                name='instance-depend-image',
+                image_id=image['id'],
+                volume_backed=True,
+                wait_until='ACTIVE')
+        else:
+            # Create instance
+            instance = self.create_test_server(
+                name='instance-depend-image',
+                image_id=image['id'],
+                wait_until='ACTIVE')
+        LOG.info("Instance from %s is created %s", source, instance)
         instance_observed = \
             self.servers_client.show_server(instance['id'])['server']
         # Create instance snapshot
@@ -101,3 +110,26 @@
         fetched_images_id = [img['id'] for img in images_list]
         self.assertNotIn(base_image_id, fetched_images_id)
         self.assertIn(snapshot_image_id, fetched_images_id)
+
+    @utils.services('compute', 'volume')
+    @decorators.idempotent_id('f0c8a35d-8f8f-443c-8bcb-85a9c0f87d19')
+    def test_image_volume_server_snapshot_dependency(self):
+        """Test with image > volume > instance > snapshot dependency.
+
+        We are going to perform the following steps in the test:
+        * Create image
+        * Create a bootable volume from Image
+        * Launch an instance from the bootable volume
+        * Take snapshot of the instance -- which creates the volume snapshot
+        * Delete the image.
+
+        This will test the dependency chain of image -> volume -> snapshot.
+        """
+        base_image_id, snapshot_image_id = self._create_instance_snapshot(
+            bfv=True)
+        self.client.delete_image(base_image_id)
+        self.client.wait_for_resource_deletion(base_image_id)
+        images_list = self.client.list_images()['images']
+        fetched_images_id = [img['id'] for img in images_list]
+        self.assertNotIn(base_image_id, fetched_images_id)
+        self.assertIn(snapshot_image_id, fetched_images_id)
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index fd93779..b1fba2d 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -389,17 +389,20 @@
         # belong to other tests and their state may have changed during this
         # test
         body = self.subnets_client.list_subnets(network_id=public_network_id)
+        extensions = [
+            ext['alias'] for ext in
+            self.network_extensions_client.list_extensions()['extensions']]
+        is_sen_ext = 'subnet-external-network' in extensions
 
         # check subnet visibility of external_network
-        if external_network['shared']:
-            self.assertNotEmpty(body['subnets'], "Subnets should be visible "
-                                                 "for shared public network %s"
-                                % public_network_id)
+        if external_network['shared'] or is_sen_ext:
+            self.assertNotEmpty(body['subnets'],
+                                'Subnets should be visible for shared or '
+                                'external networks %s' % public_network_id)
         else:
-            self.assertEmpty(body['subnets'], "Subnets should not be visible "
-                                              "for non-shared public "
-                                              "network %s"
-                             % public_network_id)
+            self.assertEmpty(body['subnets'],
+                             'Subnets should not be visible for non-shared or'
+                             'non-external networks %s' % public_network_id)
 
     @decorators.idempotent_id('c72c1c0c-2193-4aca-ccc4-b1442640bbbb')
     @utils.requires_ext(extension="standard-attr-description",
diff --git a/tempest/config.py b/tempest/config.py
index 8ddb5a4..63d4824 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -638,9 +638,14 @@
                       "service, operator should set this parameter to True "
                       "if 'image_cache_dir' is set in glance-api.conf")),
     cfg.StrOpt('http_image',
-               default='http://download.cirros-cloud.net/0.3.1/'
-               'cirros-0.3.1-x86_64-uec.tar.gz',
+               default='http://download.cirros-cloud.net/0.6.2/'
+               'cirros-0.6.2-x86_64-uec.tar.gz',
                help='http accessible image'),
+    cfg.StrOpt('http_qcow2_image',
+               default='http://download.cirros-cloud.net/0.6.2/'
+               'cirros-0.6.2-x86_64-disk.img',
+               help='http qcow2 accessible image which will be used '
+                    'for image conversion if enabled.'),
     cfg.IntOpt('build_timeout',
                default=300,
                help="Timeout in seconds to wait for an image to "
@@ -918,8 +923,8 @@
                     "connect_method=floating."),
     cfg.StrOpt('ssh_key_type',
                default='ecdsa',
-               help='Type of key to use for ssh connections. '
-                    'Valid types are rsa, ecdsa'),
+               choices=['ecdsa', 'rsa'],
+               help='Type of key to use for ssh connections.'),
     cfg.FloatOpt('allowed_network_downtime',
                  default=5.0,
                  help="Allowed VM network connection downtime during live "
diff --git a/zuul.d/integrated-gate.yaml b/zuul.d/integrated-gate.yaml
index 2fd6e36..1343a7c 100644
--- a/zuul.d/integrated-gate.yaml
+++ b/zuul.d/integrated-gate.yaml
@@ -65,6 +65,10 @@
     branches:
       regex: ^.*/(victoria|wallaby)$
       negate: true
+    # NOTE(sean-k-mooney): this job and its descendants frequently times out
+    # run on rax-* providers with a timeout of 2 hours. temporary increase
+    # the timeout to 2.5 hours.
+    timeout: 9000
     description: |
       Base integration test with Neutron networking, horizon, swift enable,
       and py3.
@@ -78,6 +82,8 @@
       # end up 6 in upstream CI. Higher concurrency means high parallel
       # requests to services and can cause more oom issues. To avoid the
       # oom issue, setting the concurrency to 4 in this job.
+      # NOTE(sean-k-mooney): now that we use zswap we should be able to
+      # increase the concurrency to 6.
       tempest_concurrency: 4
       tox_envlist: integrated-full
       devstack_localrc:
@@ -133,11 +139,18 @@
       This job runs integration tests for compute. This is
       subset of 'tempest-full-py3' job and run Nova, Neutron, Cinder (except backup tests)
       and Glance related tests. This is meant to be run on Nova gate only.
+    # NOTE(sean-k-mooney): this job and its descendants frequently times out
+    # when run on rax-* providers, recent optimizations have reduced the
+    # runtime of the job but it still times out. temporary increase the
+    # timeout to 2.5 hours.
+    timeout: 9000
     vars:
       # NOTE(gmann): Default concurrency is higher (number of cpu -2) which
       # end up 6 in upstream CI. Higher concurrency means high parallel
       # requests to services and can cause more oom issues. To avoid the
       # oom issue, setting the concurrency to 4 in this job.
+      # NOTE(sean-k-mooney): now that we use zswap we should be able to
+      # increase the concurrency to 6.
       tempest_concurrency: 4
       tox_envlist: integrated-compute
       tempest_exclude_regex: ""