From ce0eb7ab12c259849948205344d10d2af77d26b4 Mon Sep 17 00:00:00 2001 From: Chris MacNaughton Date: Thu, 7 Nov 2019 09:40:01 +0800 Subject: [PATCH] Add functional tests for Manila with Ganesha Add a functional gate where we mount a share on two VMs in the cloud under test to validate that manila + ganesha shares work correctly. --- requirements.txt | 1 + .../charm_tests/manila_ganesha/__init__.py | 18 +++ .../charm_tests/manila_ganesha/setup.py | 43 +++++++ .../charm_tests/manila_ganesha/tests.py | 118 ++++++++++++++++++ 4 files changed, 180 insertions(+) create mode 100644 zaza/openstack/charm_tests/manila_ganesha/__init__.py create mode 100644 zaza/openstack/charm_tests/manila_ganesha/setup.py create mode 100644 zaza/openstack/charm_tests/manila_ganesha/tests.py diff --git a/requirements.txt b/requirements.txt index 1ee936a..5d27b15 100644 --- a/requirements.txt +++ b/requirements.txt @@ -27,6 +27,7 @@ python-cinderclient python-glanceclient python-heatclient python-keystoneclient +python-manilaclient python-neutronclient python-novaclient python-octaviaclient diff --git a/zaza/openstack/charm_tests/manila_ganesha/__init__.py b/zaza/openstack/charm_tests/manila_ganesha/__init__.py new file mode 100644 index 0000000..d9238d6 --- /dev/null +++ b/zaza/openstack/charm_tests/manila_ganesha/__init__.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python3 + +# Copyright 2019 Canonical Ltd. +# +# 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. + + +"""Encapsulate Manila Ganesha setup and testing.""" diff --git a/zaza/openstack/charm_tests/manila_ganesha/setup.py b/zaza/openstack/charm_tests/manila_ganesha/setup.py new file mode 100644 index 0000000..d2b694e --- /dev/null +++ b/zaza/openstack/charm_tests/manila_ganesha/setup.py @@ -0,0 +1,43 @@ +#!/usr/bin/env python3 + +# Copyright 2019 Canonical Ltd. +# +# 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. + + +"""Encapsulate Manila Ganesha setup.""" + + +import zaza.openstack.utilities.openstack as openstack_utils + +from manilaclient import client as manilaclient + + +def setup_ganesha_share_type(manila_client=None): + """Create a share type for manila with Ganesha. + + :param manila_client: Authenticated manilaclient + :type manila_client: manilaclient.Client + """ + if manila_client is None: + keystone_session = openstack_utils.get_overcloud_keystone_session() + manila_client = manilaclient.Client( + session=keystone_session, client_version='2') + + manila_client.share_types.create( + name="cephfsnfstype", spec_driver_handles_share_servers=False, + extra_specs={ + 'vendor_name': 'Ceph', + 'storage_protocol': 'NFS', + 'snapshot_support': False, + }) diff --git a/zaza/openstack/charm_tests/manila_ganesha/tests.py b/zaza/openstack/charm_tests/manila_ganesha/tests.py new file mode 100644 index 0000000..f7b5ade --- /dev/null +++ b/zaza/openstack/charm_tests/manila_ganesha/tests.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python3 + +# Copyright 2019 Canonical Ltd. +# +# 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. + +"""Encapsulate Manila Ganesha testing.""" + + +from manilaclient import client as manilaclient + +import zaza.openstack.charm_tests.glance.setup as glance_setup +import zaza.openstack.charm_tests.neutron.tests as neutron_tests +import zaza.openstack.charm_tests.nova.utils as nova_utils +import zaza.openstack.charm_tests.test_utils as test_utils +import zaza.openstack.configure.guest as guest +import zaza.openstack.utilities.openstack as openstack_utils + + +class ManilaGaneshaTests(test_utils.OpenStackBaseTest): + """Encapsulate Manila Ganesha tests.""" + + RESOURCE_PREFIX = 'zaza-manilatests' + + @classmethod + def setUpClass(cls): + """Run class setup for running tests.""" + super(ManilaGaneshaTests, cls).setUpClass() + cls.nova_client = ( + openstack_utils.get_nova_session_client(cls.keystone_session)) + cls.manila_client = manilaclient.Client( + session=cls.keystone_session, client_version='2') + + def test_manila_share(self): + """Test that Manila + Ganesha shares can be accessed on two instances. + + 1. create a share + 2. Spawn two servers + 3. mount it on both + 4. write a file on one + 5. read it on the other + 6. profit + """ + # Create a share + share = self.manila_client.shares.create( + share_type='cephfsnfstype', name='cephnfsshare1', + share_proto="nfs", size=1) + + # Spawn Servers + guest.launch_instance( + glance_setup.LTS_IMAGE_NAME, + vm_name='{}-ins-1'.format(self.RESOURCE_PREFIX)) + guest.launch_instance( + glance_setup.LTS_IMAGE_NAME, + vm_name='{}-ins-2'.format(self.RESOURCE_PREFIX)) + + instance_1 = self.nova_client.servers.find( + name='{}-ins-1'.format(self.RESOURCE_PREFIX)) + fip_1 = neutron_tests.floating_ips_from_instance(instance_1)[0] + instance_2 = self.nova_client.servers.find( + name='{}-ins-2'.format(self.RESOURCE_PREFIX)) + fip_2 = neutron_tests.floating_ips_from_instance(instance_2)[0] + + share.allow(access_type='ip', access=fip_1, access_level='rw') + share.allow(access_type='ip', access=fip_2, access_level='rw') + + # Mount Share + username = guest.boot_tests['bionic']['username'] + password = guest.boot_tests['bionic'].get('password') + privkey = openstack_utils.get_private_key(nova_utils.KEYPAIR_NAME) + mount_path = share.export_locations[0] + + # Write a file on instance_1 + def verify_setup(stdin, stdout, stderr): + status = stdout.channel.recv_exit_status() + self.assertEqual(status, 0) + + openstack_utils.ssh_command( + username, fip_1, 'instance-1', + 'sudo apt install -yq nfs-common && ' + 'sudo mkdir -p /mnt/ceph && ' + 'sudo mount -t nfs -o nfsvers=4.1,proto=tcp {} /mnt/ceph && ' + 'echo "test" | sudo tee /mnt/ceph/test'.format( + mount_path), + password=password, privkey=privkey, verify=verify_setup) + + # Read that file on instance_2 + openstack_utils.ssh_command( + username, fip_2, 'instance-2', + 'sudo apt install -yq nfs-common && ' + 'sudo /bin/mkdir -p /mnt/ceph && ' + 'sudo /bin/mount -t nfs -o nfsvers=4.1,proto=tcp {} /mnt/ceph' + .format(mount_path), + password=password, privkey=privkey, verify=verify_setup) + + def verify(stdin, stdout, stderr): + status = stdout.channel.recv_exit_status() + out = "" + print("[{}] Stdout:".format(status)) + for line in iter(stdout.readline, ""): + out += line + self.assertEqual(out, "test\n") + + openstack_utils.ssh_command( + username, fip_2, 'instance-2', + 'sudo cat /mnt/ceph/test'.format( + mount_path), + password=password, privkey=privkey, verify=verify)