Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 1 | # Copyright 2020 Red Hat, Inc. |
| 2 | # All Rights Reserved. |
| 3 | # |
| 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 5 | # not use this file except in compliance with the License. You may obtain |
| 6 | # a copy of the License at |
| 7 | # |
| 8 | # http://www.apache.org/licenses/LICENSE-2.0 |
| 9 | # |
| 10 | # Unless required by applicable law or agreed to in writing, software |
| 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| 13 | # License for the specific language governing permissions and limitations |
| 14 | # under the License. |
| 15 | |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 16 | from tempest.common import utils |
| 17 | from tempest.lib import decorators |
| 18 | |
Luigi Toscano | 3c5c8a2 | 2021-02-23 10:24:01 +0100 | [diff] [blame] | 19 | from cinder_tempest_plugin.scenario import manager |
| 20 | |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 21 | |
| 22 | class SnapshotDataIntegrityTests(manager.ScenarioTest): |
| 23 | |
| 24 | def setUp(self): |
| 25 | super(SnapshotDataIntegrityTests, self).setUp() |
| 26 | self.keypair = self.create_keypair() |
| 27 | self.security_group = self._create_security_group() |
| 28 | |
| 29 | def _get_file_md5(self, ip_address, filename, mount_path='/mnt', |
| 30 | private_key=None, server=None): |
| 31 | ssh_client = self.get_remote_client(ip_address, |
| 32 | private_key=private_key, |
| 33 | server=server) |
| 34 | |
| 35 | md5_sum = ssh_client.exec_command( |
| 36 | 'sudo md5sum %s/%s|cut -c 1-32' % (mount_path, filename)) |
| 37 | return md5_sum |
| 38 | |
| 39 | def _count_files(self, ip_address, mount_path='/mnt', private_key=None, |
| 40 | server=None): |
| 41 | ssh_client = self.get_remote_client(ip_address, |
| 42 | private_key=private_key, |
| 43 | server=server) |
| 44 | count = ssh_client.exec_command('sudo ls -l %s | wc -l' % mount_path) |
| 45 | return int(count) - 1 |
| 46 | |
| 47 | def _launch_instance_from_snapshot(self, snap): |
| 48 | volume_snap = self.create_volume(snapshot_id=snap['id'], |
| 49 | size=snap['size']) |
| 50 | |
| 51 | server_snap = self.boot_instance_from_resource( |
| 52 | source_id=volume_snap['id'], |
| 53 | source_type='volume', |
| 54 | keypair=self.keypair, |
| 55 | security_group=self.security_group) |
| 56 | |
| 57 | return server_snap |
| 58 | |
| 59 | def create_md5_new_file(self, ip_address, filename, mount_path='/mnt', |
| 60 | private_key=None, server=None): |
| 61 | ssh_client = self.get_remote_client(ip_address, |
| 62 | private_key=private_key, |
| 63 | server=server) |
| 64 | |
| 65 | ssh_client.exec_command( |
| 66 | 'sudo dd bs=1024 count=100 if=/dev/urandom of=/%s/%s' % |
| 67 | (mount_path, filename)) |
| 68 | md5 = ssh_client.exec_command( |
| 69 | 'sudo md5sum -b %s/%s|cut -c 1-32' % (mount_path, filename)) |
| 70 | ssh_client.exec_command('sudo sync') |
| 71 | return md5 |
| 72 | |
| 73 | def get_md5_from_file(self, instance, filename): |
| 74 | |
| 75 | instance_ip = self.get_server_ip(instance) |
| 76 | |
| 77 | md5_sum = self._get_file_md5(instance_ip, filename=filename, |
| 78 | private_key=self.keypair['private_key'], |
| 79 | server=instance) |
| 80 | count = self._count_files(instance_ip, |
| 81 | private_key=self.keypair['private_key'], |
| 82 | server=instance) |
| 83 | return count, md5_sum |
| 84 | |
| 85 | @decorators.idempotent_id('ff10644e-5a70-4a9f-9801-8204bb81fb61') |
| 86 | @utils.services('compute', 'volume', 'image', 'network') |
| 87 | def test_snapshot_data_integrity(self): |
| 88 | """This test checks the data integrity after creating and restoring |
| 89 | |
| 90 | snapshots. The procedure is as follows: |
| 91 | |
| 92 | 1) create a volume from image |
| 93 | 2) Boot an instance from the volume |
| 94 | 3) create file on vm and write data into it |
| 95 | 4) create snapshot |
| 96 | 5) repeat 3 and 4 two more times (simply creating 3 snapshots) |
| 97 | |
| 98 | Now restore the snapshots one by one into volume, create instances |
| 99 | from it and check the number of files and file content at each |
| 100 | point when snapshot was created. |
| 101 | """ |
| 102 | |
| 103 | # Create a volume from image |
| 104 | volume = self.create_volume_from_image() |
| 105 | |
| 106 | # create an instance from bootable volume |
| 107 | server = self.boot_instance_from_resource( |
| 108 | source_id=volume['id'], |
| 109 | source_type='volume', |
| 110 | keypair=self.keypair, |
| 111 | security_group=self.security_group) |
| 112 | |
| 113 | instance_ip = self.get_server_ip(server) |
| 114 | |
| 115 | # Write data to volume |
| 116 | file1_md5 = self.create_md5_new_file( |
| 117 | instance_ip, filename="file1", |
| 118 | private_key=self.keypair['private_key'], |
| 119 | server=instance_ip) |
| 120 | |
| 121 | # Create first snapshot |
| 122 | snapshot1 = self.create_volume_snapshot(volume['id'], force=True) |
| 123 | |
| 124 | # Write data to volume |
| 125 | file2_md5 = self.create_md5_new_file( |
| 126 | instance_ip, filename="file2", |
| 127 | private_key=self.keypair['private_key'], |
| 128 | server=instance_ip) |
| 129 | |
| 130 | # Create second snapshot |
| 131 | snapshot2 = self.create_volume_snapshot(volume['id'], force=True) |
| 132 | |
| 133 | # Write data to volume |
| 134 | file3_md5 = self.create_md5_new_file( |
| 135 | instance_ip, filename="file3", |
| 136 | private_key=self.keypair['private_key'], |
| 137 | server=instance_ip) |
| 138 | |
| 139 | # Create third snapshot |
| 140 | snapshot3 = self.create_volume_snapshot(volume['id'], force=True) |
| 141 | |
| 142 | # Create volume, instance and check file and contents for snap1 |
| 143 | instance_1 = self._launch_instance_from_snapshot(snapshot1) |
| 144 | count_snap_1, md5_file_1 = self.get_md5_from_file(instance_1, |
| 145 | 'file1') |
| 146 | |
| 147 | self.assertEqual(count_snap_1, 1) |
| 148 | self.assertEqual(file1_md5, md5_file_1) |
| 149 | |
| 150 | # Create volume, instance and check file and contents for snap2 |
| 151 | instance_2 = self._launch_instance_from_snapshot(snapshot2) |
| 152 | count_snap_2, md5_file_2 = self.get_md5_from_file(instance_2, |
| 153 | 'file2') |
| 154 | |
| 155 | self.assertEqual(count_snap_2, 2) |
| 156 | self.assertEqual(file2_md5, md5_file_2) |
| 157 | |
| 158 | # Create volume, instance and check file and contents for snap3 |
| 159 | instance_3 = self._launch_instance_from_snapshot(snapshot3) |
| 160 | count_snap_3, md5_file_3 = self.get_md5_from_file(instance_3, |
| 161 | 'file3') |
| 162 | |
| 163 | self.assertEqual(count_snap_3, 3) |
| 164 | self.assertEqual(file3_md5, md5_file_3) |