Merge "Improve snapshot data integrity test"
This commit is contained in:
commit
961bab0212
|
@ -14,10 +14,15 @@
|
|||
# under the License.
|
||||
|
||||
from tempest.common import utils
|
||||
from tempest import config
|
||||
from tempest.lib.common.utils import test_utils
|
||||
from tempest.lib import decorators
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
|
||||
from cinder_tempest_plugin.scenario import manager
|
||||
|
||||
CONF = config.CONF
|
||||
|
||||
|
||||
class SnapshotDataIntegrityTests(manager.ScenarioTest):
|
||||
|
||||
|
@ -26,62 +31,109 @@ class SnapshotDataIntegrityTests(manager.ScenarioTest):
|
|||
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):
|
||||
def _attached_volume_name(
|
||||
self, disks_list_before_attach, ip_address, private_key):
|
||||
ssh = self.get_remote_client(ip_address, private_key=private_key)
|
||||
|
||||
def _wait_for_volume_available_on_system():
|
||||
disks_list_after_attach = ssh.list_disks()
|
||||
return len(disks_list_after_attach) > len(disks_list_before_attach)
|
||||
|
||||
if not test_utils.call_until_true(_wait_for_volume_available_on_system,
|
||||
CONF.compute.build_timeout,
|
||||
CONF.compute.build_interval):
|
||||
raise lib_exc.TimeoutException
|
||||
|
||||
disks_list_after_attach = ssh.list_disks()
|
||||
volume_name = [item for item in disks_list_after_attach
|
||||
if item not in disks_list_before_attach][0]
|
||||
return volume_name
|
||||
|
||||
def _get_file_md5(self, ip_address, filename, dev_name=None,
|
||||
mount_path='/mnt', private_key=None, server=None):
|
||||
|
||||
ssh_client = self.get_remote_client(ip_address,
|
||||
private_key=private_key,
|
||||
server=server)
|
||||
if dev_name is not None:
|
||||
ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
|
||||
mount_path))
|
||||
|
||||
md5_sum = ssh_client.exec_command(
|
||||
'sudo md5sum %s/%s|cut -c 1-32' % (mount_path, filename))
|
||||
if dev_name is not None:
|
||||
ssh_client.exec_command('sudo umount %s' % mount_path)
|
||||
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',
|
||||
def _count_files(self, ip_address, dev_name=None, mount_path='/mnt',
|
||||
private_key=None, server=None):
|
||||
ssh_client = self.get_remote_client(ip_address,
|
||||
private_key=private_key,
|
||||
server=server)
|
||||
if dev_name is not None:
|
||||
ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
|
||||
mount_path))
|
||||
count = ssh_client.exec_command('sudo ls -l %s | wc -l' % mount_path)
|
||||
if dev_name is not None:
|
||||
ssh_client.exec_command('sudo umount %s' % mount_path)
|
||||
# We subtract 2 from the count since `wc -l` also includes the count
|
||||
# of new line character and while creating the filesystem, a
|
||||
# lost+found folder is also created
|
||||
return int(count) - 2
|
||||
|
||||
def _make_fs(self, ip_address, private_key, server, dev_name, fs='ext4'):
|
||||
ssh_client = self.get_remote_client(ip_address,
|
||||
private_key=private_key,
|
||||
server=server)
|
||||
|
||||
ssh_client.make_fs(dev_name, fs=fs)
|
||||
|
||||
def create_md5_new_file(self, ip_address, filename, dev_name=None,
|
||||
mount_path='/mnt', private_key=None, server=None):
|
||||
ssh_client = self.get_remote_client(ip_address,
|
||||
private_key=private_key,
|
||||
server=server)
|
||||
|
||||
if dev_name is not None:
|
||||
ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
|
||||
mount_path))
|
||||
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')
|
||||
if dev_name is not None:
|
||||
ssh_client.exec_command('sudo umount %s' % mount_path)
|
||||
return md5
|
||||
|
||||
def get_md5_from_file(self, instance, filename):
|
||||
|
||||
instance_ip = self.get_server_ip(instance)
|
||||
def get_md5_from_file(self, instance, instance_ip, filename,
|
||||
dev_name=None):
|
||||
|
||||
md5_sum = self._get_file_md5(instance_ip, filename=filename,
|
||||
dev_name=dev_name,
|
||||
private_key=self.keypair['private_key'],
|
||||
server=instance)
|
||||
count = self._count_files(instance_ip,
|
||||
count = self._count_files(instance_ip, dev_name=dev_name,
|
||||
private_key=self.keypair['private_key'],
|
||||
server=instance)
|
||||
return count, md5_sum
|
||||
|
||||
def _attach_and_get_volume_device_name(self, server, volume, instance_ip,
|
||||
private_key):
|
||||
ssh_client = self.get_remote_client(
|
||||
instance_ip, private_key=private_key,
|
||||
server=server)
|
||||
# List disks before volume attachment
|
||||
disks_list_before_attach = ssh_client.list_disks()
|
||||
# Attach volume
|
||||
volume = self.nova_volume_attach(server, volume)
|
||||
# Find the difference between disks before and after attachment that
|
||||
# gives us the volume device name
|
||||
volume_device_name = self._attached_volume_name(
|
||||
disks_list_before_attach, instance_ip, private_key)
|
||||
return volume_device_name
|
||||
|
||||
@decorators.idempotent_id('ff10644e-5a70-4a9f-9801-8204bb81fb61')
|
||||
@utils.services('compute', 'volume', 'image', 'network')
|
||||
def test_snapshot_data_integrity(self):
|
||||
|
@ -89,32 +141,39 @@ class SnapshotDataIntegrityTests(manager.ScenarioTest):
|
|||
|
||||
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
|
||||
1) Create an instance with ephemeral disk
|
||||
2) Create a volume, attach it to the instance and create a filesystem
|
||||
on it and mount it
|
||||
3) Mount the volume, create a file and write data into it, Unmount 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
|
||||
Now create volume from the snapshots one by one, attach it to the
|
||||
instance 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
|
||||
server = self.create_server(
|
||||
key_name=self.keypair['name'],
|
||||
security_groups=[{'name': self.security_group['name']}])
|
||||
|
||||
# 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)
|
||||
# Create an empty volume
|
||||
volume = self.create_volume()
|
||||
|
||||
instance_ip = self.get_server_ip(server)
|
||||
|
||||
# Attach volume to instance and find it's device name (eg: /dev/vdb)
|
||||
volume_device_name = self._attach_and_get_volume_device_name(
|
||||
server, volume, instance_ip, self.keypair['private_key'])
|
||||
|
||||
# Create filesystem on the volume
|
||||
self._make_fs(instance_ip, self.keypair['private_key'], server,
|
||||
volume_device_name)
|
||||
|
||||
# Write data to volume
|
||||
file1_md5 = self.create_md5_new_file(
|
||||
instance_ip, filename="file1",
|
||||
instance_ip, dev_name=volume_device_name, filename="file1",
|
||||
private_key=self.keypair['private_key'],
|
||||
server=instance_ip)
|
||||
|
||||
|
@ -123,7 +182,7 @@ class SnapshotDataIntegrityTests(manager.ScenarioTest):
|
|||
|
||||
# Write data to volume
|
||||
file2_md5 = self.create_md5_new_file(
|
||||
instance_ip, filename="file2",
|
||||
instance_ip, dev_name=volume_device_name, filename="file2",
|
||||
private_key=self.keypair['private_key'],
|
||||
server=instance_ip)
|
||||
|
||||
|
@ -132,33 +191,51 @@ class SnapshotDataIntegrityTests(manager.ScenarioTest):
|
|||
|
||||
# Write data to volume
|
||||
file3_md5 = self.create_md5_new_file(
|
||||
instance_ip, filename="file3",
|
||||
instance_ip, dev_name=volume_device_name, 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')
|
||||
# Detach the volume
|
||||
self.nova_volume_detach(server, volume)
|
||||
|
||||
# Create volume from snapshot, attach it to instance and check file
|
||||
# and contents for snap1
|
||||
volume_snap_1 = self.create_volume(snapshot_id=snapshot1['id'])
|
||||
volume_device_name = self._attach_and_get_volume_device_name(
|
||||
server, volume_snap_1, instance_ip, self.keypair['private_key'])
|
||||
count_snap_1, md5_file_1 = self.get_md5_from_file(
|
||||
server, instance_ip, 'file1', dev_name=volume_device_name)
|
||||
# Detach the volume
|
||||
self.nova_volume_detach(server, volume_snap_1)
|
||||
|
||||
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')
|
||||
# Create volume from snapshot, attach it to instance and check file
|
||||
# and contents for snap2
|
||||
volume_snap_2 = self.create_volume(snapshot_id=snapshot2['id'])
|
||||
volume_device_name = self._attach_and_get_volume_device_name(
|
||||
server, volume_snap_2, instance_ip, self.keypair['private_key'])
|
||||
count_snap_2, md5_file_2 = self.get_md5_from_file(
|
||||
server, instance_ip, 'file2', dev_name=volume_device_name)
|
||||
# Detach the volume
|
||||
self.nova_volume_detach(server, volume_snap_2)
|
||||
|
||||
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')
|
||||
# Create volume from snapshot, attach it to instance and check file
|
||||
# and contents for snap3
|
||||
volume_snap_3 = self.create_volume(snapshot_id=snapshot3['id'])
|
||||
volume_device_name = self._attach_and_get_volume_device_name(
|
||||
server, volume_snap_3, instance_ip, self.keypair['private_key'])
|
||||
count_snap_3, md5_file_3 = self.get_md5_from_file(
|
||||
server, instance_ip, 'file3', dev_name=volume_device_name)
|
||||
# Detach the volume
|
||||
self.nova_volume_detach(server, volume_snap_3)
|
||||
|
||||
self.assertEqual(count_snap_3, 3)
|
||||
self.assertEqual(file3_md5, md5_file_3)
|
||||
|
|
Loading…
Reference in New Issue