From c19dbbd2e6c926aa1f8050b9ece48b55e209f3c3 Mon Sep 17 00:00:00 2001
From: Alexey Ovchinnikov <aovchinnikov@mirantis.com>
Date: Thu, 22 Sep 2016 10:20:58 +0300
Subject: [PATCH] Enable scenario tests for LVM and ZFSonLinux drivers

In addition to functional tests.

Also, make some corrections to scenario tests code to make it work
with shares located on localhost.

Co-Authored-By: Alexey Ovchinnikov <aovchinnikov@mirantis.com>
Co-Authored-By: Valeriy Ponomaryov <vponomaryov@mirantis.com>
Change-Id: Ice61a7593f5e4e443cffbe78ecd71d683a9c274e
---
 contrib/ci/post_test_hook.sh                  | 20 ++++
 contrib/ci/pre_test_hook.sh                   |  5 +
 devstack/settings                             |  4 +-
 manila_tempest_tests/config.py                |  2 +-
 .../tests/scenario/test_share_basic_ops.py    | 92 +++++++++++--------
 5 files changed, 82 insertions(+), 41 deletions(-)

diff --git a/contrib/ci/post_test_hook.sh b/contrib/ci/post_test_hook.sh
index e47e65ed37..0a85c91738 100755
--- a/contrib/ci/post_test_hook.sh
+++ b/contrib/ci/post_test_hook.sh
@@ -153,12 +153,16 @@ elif [[ "$DRIVER" == "generic" ]]; then
 fi
 
 if [[ "$DRIVER" == "lvm" ]]; then
+    MANILA_TESTS="(^manila_tempest_tests.tests)(?=.*\[.*\bbackend\b.*\])"
     MANILA_TEMPEST_CONCURRENCY=8
     RUN_MANILA_CG_TESTS=False
     RUN_MANILA_MANAGE_TESTS=False
     iniset $TEMPEST_CONFIG share run_shrink_tests False
     iniset $TEMPEST_CONFIG share enable_ip_rules_for_protocols 'nfs'
     iniset $TEMPEST_CONFIG share enable_user_rules_for_protocols 'cifs'
+    iniset $TEMPEST_CONFIG share image_with_share_tools 'manila-service-image-master'
+    iniset $TEMPEST_CONFIG auth use_dynamic_credentials True
+    iniset $TEMPEST_CONFIG share capability_snapshot_support True
     if ! grep $USERNAME_FOR_USER_RULES "/etc/passwd"; then
         sudo useradd $USERNAME_FOR_USER_RULES
     fi
@@ -170,6 +174,7 @@ if [[ "$DRIVER" == "lvm" ]]; then
     fi
     sudo service $samba_daemon_name restart
 elif [[ "$DRIVER" == "zfsonlinux" ]]; then
+    MANILA_TESTS="(^manila_tempest_tests.tests)(?=.*\[.*\bbackend\b.*\])"
     MANILA_TEMPEST_CONCURRENCY=8
     RUN_MANILA_CG_TESTS=False
     RUN_MANILA_MANAGE_TESTS=True
@@ -191,6 +196,9 @@ elif [[ "$DRIVER" == "zfsonlinux" ]]; then
     iniset $TEMPEST_CONFIG share multitenancy_enabled False
     iniset $TEMPEST_CONFIG share multi_backend True
     iniset $TEMPEST_CONFIG share backend_replication_type 'readable'
+    iniset $TEMPEST_CONFIG share image_with_share_tools 'manila-service-image-master'
+    iniset $TEMPEST_CONFIG auth use_dynamic_credentials True
+    iniset $TEMPEST_CONFIG share capability_snapshot_support True
 elif [[ "$DRIVER" == "dummy" ]]; then
     MANILA_TEMPEST_CONCURRENCY=24
     RUN_MANILA_CG_TESTS=True
@@ -252,6 +260,18 @@ export OS_USER_DOMAIN_NAME=$ADMIN_DOMAIN_NAME
 source $BASE/new/manila/contrib/ci/common.sh
 manila_wait_for_drivers_init $MANILA_CONF
 
+# (aovchinnikov): extra rules are needed to allow instances talk to host.
+sudo iptables -N manila-nfs
+sudo iptables -I INPUT 1 -j manila-nfs
+TCP_PORTS=(2049 111 32803 892 875 662)
+UDP_PORTS=(111 32769 892 875 662)
+for port in ${TCP_PORTS[*]}; do
+    sudo iptables -A manila-nfs -m tcp -p tcp --dport $port -j ACCEPT
+done
+for port in ${UDP_PORTS[*]}; do
+    sudo iptables -A manila-nfs -m udp -p udp --dport $port -j ACCEPT
+done
+
 echo "Running tempest manila test suites"
 sudo -H -u jenkins tox -eall-plugin $MANILA_TESTS -- --concurrency=$MANILA_TEMPEST_CONCURRENCY
 RETVAL=$?
diff --git a/contrib/ci/pre_test_hook.sh b/contrib/ci/pre_test_hook.sh
index 55b82e96ba..d3a9331673 100755
--- a/contrib/ci/pre_test_hook.sh
+++ b/contrib/ci/pre_test_hook.sh
@@ -145,9 +145,11 @@ elif [[ "$DRIVER" == "dummy" ]]; then
     export MANILA_TEMPEST_CONCURRENCY=24
 
 elif [[ "$DRIVER" == "lvm" ]]; then
+    MANILA_SERVICE_IMAGE_ENABLED=True
     save_configuration "SHARE_DRIVER" "manila.share.drivers.lvm.LVMShareDriver"
     save_configuration "SHARE_BACKING_FILE_SIZE" "32000M"
 elif [[ "$DRIVER" == "zfsonlinux" ]]; then
+    MANILA_SERVICE_IMAGE_ENABLED=True
     save_configuration "SHARE_DRIVER" "manila.share.drivers.zfsonlinux.driver.ZFSonLinuxShareDriver"
     save_configuration "RUN_MANILA_REPLICATION_TESTS" "True"
     # Set the replica_state_update_interval to 60 seconds to make
@@ -155,6 +157,9 @@ elif [[ "$DRIVER" == "zfsonlinux" ]]; then
     # the build timeout for ZFS on the gate.
     save_configuration "MANILA_REPLICA_STATE_UPDATE_INTERVAL" "60"
     save_configuration "MANILA_ZFSONLINUX_USE_SSH" "True"
+    # Set proper host IP for user export to be able to run scenario tests correctly
+    save_configuration "MANILA_ZFSONLINUX_SHARE_EXPORT_IP" "$HOST"
+    save_configuration "MANILA_ZFSONLINUX_SERVICE_IP" "127.0.0.1"
 elif [[ "$DRIVER" == "container" ]]; then
     save_configuration "SHARE_DRIVER" "manila.share.drivers.container.driver.ContainerShareDriver"
     save_configuration "SHARE_BACKING_FILE_SIZE" "64000M"
diff --git a/devstack/settings b/devstack/settings
index 07c7565840..04fcff02ee 100644
--- a/devstack/settings
+++ b/devstack/settings
@@ -145,8 +145,8 @@ MANILA_REPLICA_STATE_UPDATE_INTERVAL=${MANILA_REPLICA_STATE_UPDATE_INTERVAL:-300
 # will be used for creation of sparse files.
 MANILA_ZFSONLINUX_ZPOOL_SIZE=${MANILA_ZFSONLINUX_ZPOOL_SIZE:-"30G"}
 MANILA_ZFSONLINUX_BACKEND_FILES_CONTAINER_DIR=${MANILA_ZFSONLINUX_BACKEND_FILES_CONTAINER_DIR:-"/opt/stack/data/manila/zfsonlinux"}
-MANILA_ZFSONLINUX_SHARE_EXPORT_IP=${MANILA_ZFSONLINUX_SHARE_EXPORT_IP:-"127.0.0.1"}
-MANILA_ZFSONLINUX_SERVICE_IP=${MANILA_ZFSONLINUX_SERVICE_IP:-"127.0.0.1"}
+MANILA_ZFSONLINUX_SHARE_EXPORT_IP=${MANILA_ZFSONLINUX_SHARE_EXPORT_IP:-$HOST_IP}
+MANILA_ZFSONLINUX_SERVICE_IP=${MANILA_ZFSONLINUX_SERVICE_IP:-$HOST_IP}
 MANILA_ZFSONLINUX_DATASET_CREATION_OPTIONS=${MANILA_ZFSONLINUX_DATASET_CREATION_OPTIONS:-"compression=gzip"}
 MANILA_ZFSONLINUX_USE_SSH=${MANILA_ZFSONLINUX_USE_SSH:-"False"}
 MANILA_ZFSONLINUX_SSH_USERNAME=${MANILA_ZFSONLINUX_SSH_USERNAME:-$STACK_USER}
diff --git a/manila_tempest_tests/config.py b/manila_tempest_tests/config.py
index 9314da05f9..6d0a466cdf 100644
--- a/manila_tempest_tests/config.py
+++ b/manila_tempest_tests/config.py
@@ -189,7 +189,7 @@ ShareGroup = [
                      "careful enabling this opt."),
 
     cfg.StrOpt("image_with_share_tools",
-               default="manila-service-image",
+               default="manila-service-image-master",
                help="Image name for vm booting with nfs/smb clients tool."),
     cfg.StrOpt("image_username",
                default="manila",
diff --git a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
index e83f78dbb1..71ed0e33eb 100644
--- a/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
+++ b/manila_tempest_tests/tests/scenario/test_share_basic_ops.py
@@ -49,9 +49,17 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
     def setUp(self):
         super(ShareBasicOpsBase, self).setUp()
         base.verify_test_has_appropriate_tags(self)
+        self.image_ref = None
         # Setup image and flavor the test instance
         # Support both configured and injected values
-        self.image_ref = None
+        self.floatings = {}
+        if self.protocol not in CONF.share.enable_protocols:
+            message = "%s tests are disabled" % self.protocol
+            raise self.skipException(message)
+        if self.protocol not in CONF.share.enable_ip_rules_for_protocols:
+            message = ("%s tests for access rules other than IP are disabled" %
+                       self.protocol)
+            raise self.skipException(message)
         if not hasattr(self, 'flavor_ref'):
             self.flavor_ref = CONF.share.client_vm_flavor_ref
         if CONF.share.image_with_share_tools:
@@ -70,8 +78,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
                       image=self.image_ref, flavor=self.flavor_ref,
                       ssh_user=self.ssh_user))
         self.security_group = self._create_security_group()
-        if CONF.share.multitenancy_enabled:
-            self.create_share_network()
+        self.create_share_network()
 
     def boot_instance(self, wait_until="ACTIVE"):
         self.keypair = self.create_keypair()
@@ -91,6 +98,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         # Obtain a floating IP
         floating_ip = (self.compute_floating_ips_client.create_floating_ip()
                        ['floating_ip'])
+        self.floatings[instance['id']] = floating_ip
         self.addCleanup(test_utils.call_and_ignore_notfound_exc,
                         self.compute_floating_ips_client.delete_floating_ip,
                         floating_ip['id'])
@@ -152,6 +160,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         return self._create_share_type(
             data_utils.rand_name("share_type"),
             extra_specs={
+                'snapshot_support': CONF.share.capability_snapshot_support,
                 'driver_handles_share_servers': CONF.share.multitenancy_enabled
             },)['share_type']
 
@@ -182,6 +191,18 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         self._allow_access(share_id, access_type='ip', access_to=ip,
                            cleanup=cleanup)
 
+    def provide_access_to_auxiliary_instance(self, instance, share=None):
+        share = share or self.share
+        if self.protocol.lower() == 'cifs':
+            self.allow_access_ip(share['id'], instance=instance, cleanup=False)
+        elif not CONF.share.multitenancy_enabled:
+            self.allow_access_ip(
+                share['id'], ip=self.floatings[instance['id']]['ip'],
+                instance=instance, cleanup=False)
+        elif (CONF.share.multitenancy_enabled and
+              self.protocol.lower() == 'nfs'):
+            self.allow_access_ip(share['id'], instance=instance, cleanup=False)
+
     def wait_for_active_instance(self, instance_id):
         waiters.wait_for_server_status(
             self.manager.servers_client, instance_id, "ACTIVE")
@@ -192,10 +213,10 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         instance = self.boot_instance(wait_until="BUILD")
         self.create_share()
         instance = self.wait_for_active_instance(instance["id"])
-        self.allow_access_ip(self.share['id'], instance=instance,
-                             cleanup=False)
         ssh_client = self.init_ssh(instance)
 
+        self.provide_access_to_auxiliary_instance(instance)
+
         if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
             locations = self.share['export_locations']
         else:
@@ -220,9 +241,8 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         instance2 = self.wait_for_active_instance(instance2["id"])
 
         # Write data to first VM
-        self.allow_access_ip(self.share['id'], instance=instance1,
-                             cleanup=False)
         ssh_client_inst1 = self.init_ssh(instance1)
+        self.provide_access_to_auxiliary_instance(instance1)
 
         if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
             locations = self.share['export_locations']
@@ -237,9 +257,8 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         self.write_data(test_data, ssh_client_inst1)
 
         # Read from second VM
-        self.allow_access_ip(
-            self.share['id'], instance=instance2, cleanup=False)
         ssh_client_inst2 = self.init_ssh(instance2)
+        self.provide_access_to_auxiliary_instance(instance2)
         self.mount_share(locations[0], ssh_client_inst2)
         self.addCleanup(self.umount_share,
                         ssh_client_inst2)
@@ -252,7 +271,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
                           "Share migration tests are disabled.")
     def test_migration_files(self):
 
-        if self.protocol != "NFS":
+        if self.protocol != "nfs":
             raise self.skipException("Only NFS protocol supported "
                                      "at this moment.")
 
@@ -278,9 +297,8 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
 
         dest_pool = dest_pool['name']
 
-        self.allow_access_ip(
-            self.share['id'], instance=instance, cleanup=False)
         ssh_client = self.init_ssh(instance)
+        self.provide_access_to_auxiliary_instance(instance)
 
         if utils.is_microversion_lt(CONF.share.max_api_microversion, "2.9"):
             exports = self.share['export_locations']
@@ -293,24 +311,24 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
 
         self.mount_share(exports[0], ssh_client)
 
-        ssh_client.exec_command("mkdir -p /mnt/f1")
-        ssh_client.exec_command("mkdir -p /mnt/f2")
-        ssh_client.exec_command("mkdir -p /mnt/f3")
-        ssh_client.exec_command("mkdir -p /mnt/f4")
-        ssh_client.exec_command("mkdir -p /mnt/f1/ff1")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f1")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f2")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f3")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f4")
+        ssh_client.exec_command("sudo mkdir -p /mnt/f1/ff1")
         ssh_client.exec_command("sleep 1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f1/1m1.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f2/1m2.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f3/1m3.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f4/1m4.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("dd if=/dev/zero of=/mnt/f1/ff1/1m5.bin bs=1M"
-                                " count=1")
-        ssh_client.exec_command("chmod -R 555 /mnt/f3")
-        ssh_client.exec_command("chmod -R 777 /mnt/f4")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f1/1m1.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f2/1m2.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f3/1m3.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f4/1m4.bin bs=1M count=1")
+        ssh_client.exec_command(
+            "sudo dd if=/dev/zero of=/mnt/f1/ff1/1m5.bin bs=1M count=1")
+        ssh_client.exec_command("sudo chmod -R 555 /mnt/f3")
+        ssh_client.exec_command("sudo chmod -R 777 /mnt/f4")
 
         self.umount_share(ssh_client)
 
@@ -372,13 +390,12 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         instance = self.wait_for_active_instance(instance["id"])
         self.addCleanup(self.servers_client.delete_server, instance['id'])
 
-        # 3 - Provide RW access to S1, ok, provided
-        self.allow_access_ip(
-            parent_share['id'], instance=instance, cleanup=False)
-
-        # 4 - SSH to UVM, ok, connected
+        # 3 - SSH to UVM, ok, connected
         ssh_client = self.init_ssh(instance)
 
+        # 4 - Provide RW access to S1, ok, provided
+        self.provide_access_to_auxiliary_instance(instance, parent_share)
+
         # 5 - Try mount S1 to UVM, ok, mounted
         user_export_location = self._get_user_export_location(parent_share)
         parent_share_dir = "/mnt/parent"
@@ -411,8 +428,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
         )
 
         # 11 - Provide RW access to S2, ok, provided
-        self.allow_access_ip(
-            child_share['id'], instance=instance, cleanup=False)
+        self.provide_access_to_auxiliary_instance(instance, child_share)
 
         # 12 - Try mount S2, ok, mounted
         self.mount_share(user_export_location, ssh_client, child_share_dir)
@@ -440,7 +456,7 @@ class ShareBasicOpsBase(manager.ShareScenarioTest):
 
 
 class TestShareBasicOpsNFS(ShareBasicOpsBase):
-    protocol = "NFS"
+    protocol = "nfs"
 
     def mount_share(self, location, ssh_client, target_dir=None):
         target_dir = target_dir or "/mnt"
@@ -449,7 +465,7 @@ class TestShareBasicOpsNFS(ShareBasicOpsBase):
 
 
 class TestShareBasicOpsCIFS(ShareBasicOpsBase):
-    protocol = "CIFS"
+    protocol = "cifs"
 
     def mount_share(self, location, ssh_client, target_dir=None):
         location = location.replace("\\", "/")