Merge "Update the documentation link for doc migration"
diff --git a/.zuul.yaml b/.zuul.yaml
new file mode 100644
index 0000000..dd66e2c
--- /dev/null
+++ b/.zuul.yaml
@@ -0,0 +1,36 @@
+- project:
+    check:
+      jobs:
+        - cinder-tempest-plugin-lvm-lio
+    gate:
+      jobs:
+        - cinder-tempest-plugin-lvm-lio
+
+- job:
+    name: cinder-tempest-plugin-lvm-lio
+    description: |
+      Run Cinder Tempest Plugin tests
+    parent: devstack-tempest
+    required-projects:
+      - openstack-infra/devstack-gate
+      - openstack/barbican
+      - openstack/python-barbicanclient
+      - openstack/tempest
+      - openstack/os-brick
+      - openstack/cinder-tempest-plugin
+      - openstack/cinder
+    vars:
+      tempest_test_regex: (tempest\.(api|scenario)|cinder_tempest_plugin)
+      tempest_test_blacklist: "{{ ansible_user_dir }}/{{ zuul.project.src_dir }}/tempest_blacklist.txt"
+      tox_envlist: 'all'
+      devstack_localrc:
+        CINDER_ISCSI_HELPER: 'lioadm'
+        TEMPEST_PLUGINS: '/opt/stack/cinder-tempest-plugin'
+      devstack_plugins:
+        barbican: 'git://git.openstack.org/openstack/barbican'
+      devstack_services:
+        barbican: true
+    irrelevant-files:
+      - ^.*\.rst$
+      - ^doc/.*$
+      - ^releasenotes/.*$
diff --git a/cinder_tempest_plugin/api/volume/test_create_from_image.py b/cinder_tempest_plugin/api/volume/test_create_from_image.py
new file mode 100644
index 0000000..02fbd24
--- /dev/null
+++ b/cinder_tempest_plugin/api/volume/test_create_from_image.py
@@ -0,0 +1,79 @@
+#    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.common import waiters
+from tempest import config
+from tempest.lib.common.utils import data_utils
+from tempest.lib.common.utils import test_utils
+from tempest.lib import decorators
+
+from cinder_tempest_plugin.api.volume import base
+
+CONF = config.CONF
+
+
+class VolumeFromImageTest(base.BaseVolumeTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(VolumeFromImageTest, cls).skip_checks()
+        if not CONF.service_available.glance:
+            raise cls.skipException("Glance service is disabled")
+
+    @classmethod
+    def create_volume_no_wait(cls, **kwargs):
+        """Returns a test volume.
+
+        This does not wait for volume creation to finish,
+        so that multiple operations can happen on the
+        Cinder server in parallel.
+        """
+        if 'size' not in kwargs:
+            kwargs['size'] = CONF.volume.volume_size
+
+        if 'imageRef' in kwargs:
+            image = cls.os_primary.image_client_v2.show_image(
+                kwargs['imageRef'])
+            min_disk = image['min_disk']
+            kwargs['size'] = max(kwargs['size'], min_disk)
+
+        if 'name' not in kwargs:
+            name = data_utils.rand_name(cls.__name__ + '-Volume')
+            kwargs['name'] = name
+
+        volume = cls.volumes_client.create_volume(**kwargs)['volume']
+        cls.addClassResourceCleanup(
+            cls.volumes_client.wait_for_resource_deletion, volume['id'])
+        cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
+                                    cls.volumes_client.delete_volume,
+                                    volume['id'])
+
+        return volume
+
+    @decorators.idempotent_id('8976a11b-1ddc-49b6-b66f-8c26adf3fa9e')
+    def test_create_from_image_multiple(self):
+        """Create a handful of volumes from the same image at once.
+
+        The purpose of this test is to stress volume drivers,
+        image download, the image cache, etc., within Cinder.
+        """
+
+        img_uuid = CONF.compute.image_ref
+
+        vols = []
+        for v in range(0, 5):
+            vols.append(self.create_volume_no_wait(imageRef=img_uuid))
+
+        for v in vols:
+            waiters.wait_for_volume_resource_status(self.volumes_client,
+                                                    v['id'],
+                                                    'available')
diff --git a/cinder_tempest_plugin/api/volume/test_volume_revert.py b/cinder_tempest_plugin/api/volume/test_volume_revert.py
index 15e4aed..f7e9169 100644
--- a/cinder_tempest_plugin/api/volume/test_volume_revert.py
+++ b/cinder_tempest_plugin/api/volume/test_volume_revert.py
@@ -43,13 +43,14 @@
     def setUp(self):
         super(VolumeRevertTests, self).setUp()
         # Create volume
-        self.volume = self.create_volume(size=1)
+        self.volume = self.create_volume()
         # Create snapshot
         self.snapshot = self.create_snapshot(self.volume['id'])
 
     @decorators.idempotent_id('87b7dcb7-4950-4a3a-802c-ece55491846d')
     def test_volume_revert_to_snapshot(self):
         """Test revert to snapshot"""
+        expected_size = self.volume['size']
         # Revert to snapshot
         self.volume_revert_client.revert_to_snapshot(self.volume,
                                                      self.snapshot['id'])
@@ -61,13 +62,16 @@
             self.snapshot['id'], 'available')
         volume = self.volumes_client.show_volume(self.volume['id'])['volume']
 
-        self.assertEqual(1, volume['size'])
+        self.assertEqual(expected_size, volume['size'])
 
     @decorators.idempotent_id('4e8b0788-87fe-430d-be7a-444d7f8e0347')
     def test_volume_revert_to_snapshot_after_extended(self):
         """Test revert to snapshot after extended"""
+        # Extend volume to double the size
+        expected_size = self.volume['size'] * 2
         # Extend the volume
-        self.volumes_client.extend_volume(self.volume['id'], new_size=2)
+        self.volumes_client.extend_volume(self.volume['id'],
+                                          new_size=expected_size)
         waiters.wait_for_volume_resource_status(self.volumes_client,
                                                 self.volume['id'], 'available')
         # Revert to snapshot
@@ -80,4 +84,4 @@
             self.snapshots_client,
             self.snapshot['id'], 'available')
         volume = self.volumes_client.show_volume(self.volume['id'])['volume']
-        self.assertEqual(2, volume['size'])
+        self.assertEqual(expected_size, volume['size'])
diff --git a/cinder_tempest_plugin/services/volume_revert_client.py b/cinder_tempest_plugin/services/volume_revert_client.py
index 0d54701..fc9b6ad 100644
--- a/cinder_tempest_plugin/services/volume_revert_client.py
+++ b/cinder_tempest_plugin/services/volume_revert_client.py
@@ -24,6 +24,8 @@
     def __init__(self, auth_provider, service, region, **kwargs):
         super(VolumeRevertClient, self).__init__(
             auth_provider, service, region, **kwargs)
+        # revert needs v3 of the volume API
+        self.api_version = 'v3'
 
     def revert_to_snapshot(self, volume, snapshot_id):
         """Revert a volume to snapshot."""
diff --git a/tempest_blacklist.txt b/tempest_blacklist.txt
new file mode 100644
index 0000000..4d173c5
--- /dev/null
+++ b/tempest_blacklist.txt
@@ -0,0 +1,10 @@
+# List of tests getting skipped
+.*\[.*\bslow\b.*\]
+.*\.*VolumesSnapshotTestJSON\.test_snapshot_backup
+.*\.*VolumesBackupsTest\.test_backup_create_attached_volume
+.*\.*VolumesBackupsTest\.test_backup_create_and_restore_to_an_existing_volume
+.*\.*VolumesBackupsTest\.test_bootable_volume_backup_and_restore
+.*\.*VolumesBackupsTest\.test_incremental_backup
+.*\.*VolumesBackupsTest\.test_volume_backup_create_get_detailed_list_restore_delete
+.*\.*VolumesBackupsTest\.test_volume_snapshot_backup
+.*\.*VolumesBackupsV39Test\.test_update_backup