Add Snapshot data integrity test
This patch adds data integrity tests for snapshot with the following
procedure :
1) create a volume from image
2) Boot an instance from the volume
3) create file on vm and write data into it
4) create first snapshot
5) repeat 3
5) create second snapshot
6) repeat 3
7) create third snapshot
Now restore the snapshots one by one into volume, create instances
from it and check the number of files and file content at each
point snapshot was created.
We are also temporarily making a copy of tempest scenario manager until
the actual manager is available for import in tempest plugins.
Change-Id: I5c5ff6f996dd39b52fada82f3938b628e58b0a2c
diff --git a/cinder_tempest_plugin/scenario/test_snapshots.py b/cinder_tempest_plugin/scenario/test_snapshots.py
new file mode 100644
index 0000000..2cb172f
--- /dev/null
+++ b/cinder_tempest_plugin/scenario/test_snapshots.py
@@ -0,0 +1,163 @@
+# Copyright 2020 Red Hat, Inc.
+# All Rights Reserved.
+#
+# 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 cinder_tempest_plugin.scenario import manager
+from tempest.common import utils
+from tempest.lib import decorators
+
+
+class SnapshotDataIntegrityTests(manager.ScenarioTest):
+
+ def setUp(self):
+ super(SnapshotDataIntegrityTests, self).setUp()
+ self.keypair = self.create_keypair()
+ self.security_group = self._create_security_group()
+
+ def _get_file_md5(self, ip_address, filename, mount_path='/mnt',
+ private_key=None, server=None):
+ ssh_client = self.get_remote_client(ip_address,
+ private_key=private_key,
+ server=server)
+
+ md5_sum = ssh_client.exec_command(
+ 'sudo md5sum %s/%s|cut -c 1-32' % (mount_path, filename))
+ return md5_sum
+
+ def _count_files(self, ip_address, mount_path='/mnt', private_key=None,
+ server=None):
+ ssh_client = self.get_remote_client(ip_address,
+ private_key=private_key,
+ server=server)
+ count = ssh_client.exec_command('sudo ls -l %s | wc -l' % mount_path)
+ return int(count) - 1
+
+ def _launch_instance_from_snapshot(self, snap):
+ volume_snap = self.create_volume(snapshot_id=snap['id'],
+ size=snap['size'])
+
+ server_snap = self.boot_instance_from_resource(
+ source_id=volume_snap['id'],
+ source_type='volume',
+ keypair=self.keypair,
+ security_group=self.security_group)
+
+ return server_snap
+
+ def create_md5_new_file(self, ip_address, filename, mount_path='/mnt',
+ private_key=None, server=None):
+ ssh_client = self.get_remote_client(ip_address,
+ private_key=private_key,
+ server=server)
+
+ ssh_client.exec_command(
+ 'sudo dd bs=1024 count=100 if=/dev/urandom of=/%s/%s' %
+ (mount_path, filename))
+ md5 = ssh_client.exec_command(
+ 'sudo md5sum -b %s/%s|cut -c 1-32' % (mount_path, filename))
+ ssh_client.exec_command('sudo sync')
+ return md5
+
+ def get_md5_from_file(self, instance, filename):
+
+ instance_ip = self.get_server_ip(instance)
+
+ md5_sum = self._get_file_md5(instance_ip, filename=filename,
+ private_key=self.keypair['private_key'],
+ server=instance)
+ count = self._count_files(instance_ip,
+ private_key=self.keypair['private_key'],
+ server=instance)
+ return count, md5_sum
+
+ @decorators.idempotent_id('ff10644e-5a70-4a9f-9801-8204bb81fb61')
+ @utils.services('compute', 'volume', 'image', 'network')
+ def test_snapshot_data_integrity(self):
+ """This test checks the data integrity after creating and restoring
+
+ snapshots. The procedure is as follows:
+
+ 1) create a volume from image
+ 2) Boot an instance from the volume
+ 3) create file on vm and write data into it
+ 4) create snapshot
+ 5) repeat 3 and 4 two more times (simply creating 3 snapshots)
+
+ Now restore the snapshots one by one into volume, create instances
+ from it and check the number of files and file content at each
+ point when snapshot was created.
+ """
+
+ # Create a volume from image
+ volume = self.create_volume_from_image()
+
+ # create an instance from bootable volume
+ server = self.boot_instance_from_resource(
+ source_id=volume['id'],
+ source_type='volume',
+ keypair=self.keypair,
+ security_group=self.security_group)
+
+ instance_ip = self.get_server_ip(server)
+
+ # Write data to volume
+ file1_md5 = self.create_md5_new_file(
+ instance_ip, filename="file1",
+ private_key=self.keypair['private_key'],
+ server=instance_ip)
+
+ # Create first snapshot
+ snapshot1 = self.create_volume_snapshot(volume['id'], force=True)
+
+ # Write data to volume
+ file2_md5 = self.create_md5_new_file(
+ instance_ip, filename="file2",
+ private_key=self.keypair['private_key'],
+ server=instance_ip)
+
+ # Create second snapshot
+ snapshot2 = self.create_volume_snapshot(volume['id'], force=True)
+
+ # Write data to volume
+ file3_md5 = self.create_md5_new_file(
+ instance_ip, filename="file3",
+ private_key=self.keypair['private_key'],
+ server=instance_ip)
+
+ # Create third snapshot
+ snapshot3 = self.create_volume_snapshot(volume['id'], force=True)
+
+ # Create volume, instance and check file and contents for snap1
+ instance_1 = self._launch_instance_from_snapshot(snapshot1)
+ count_snap_1, md5_file_1 = self.get_md5_from_file(instance_1,
+ 'file1')
+
+ self.assertEqual(count_snap_1, 1)
+ self.assertEqual(file1_md5, md5_file_1)
+
+ # Create volume, instance and check file and contents for snap2
+ instance_2 = self._launch_instance_from_snapshot(snapshot2)
+ count_snap_2, md5_file_2 = self.get_md5_from_file(instance_2,
+ 'file2')
+
+ self.assertEqual(count_snap_2, 2)
+ self.assertEqual(file2_md5, md5_file_2)
+
+ # Create volume, instance and check file and contents for snap3
+ instance_3 = self._launch_instance_from_snapshot(snapshot3)
+ count_snap_3, md5_file_3 = self.get_md5_from_file(instance_3,
+ 'file3')
+
+ self.assertEqual(count_snap_3, 3)
+ self.assertEqual(file3_md5, md5_file_3)