blob: 0abc13cfb1ba4d1c5c000157dddf2759fe12f9d5 [file] [log] [blame]
Rajat Dhasmana21d63a32020-01-14 17:41:22 +00001# 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 Dhasmana21d63a32020-01-14 17:41:22 +000016from tempest.common import utils
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040017from tempest import config
18from tempest.lib.common.utils import test_utils
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000019from tempest.lib import decorators
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040020from tempest.lib import exceptions as lib_exc
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000021
Luigi Toscano3c5c8a22021-02-23 10:24:01 +010022from cinder_tempest_plugin.scenario import manager
23
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040024CONF = config.CONF
25
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000026
27class SnapshotDataIntegrityTests(manager.ScenarioTest):
28
29 def setUp(self):
30 super(SnapshotDataIntegrityTests, self).setUp()
31 self.keypair = self.create_keypair()
32 self.security_group = self._create_security_group()
33
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040034 def _attached_volume_name(
35 self, disks_list_before_attach, ip_address, private_key):
36 ssh = self.get_remote_client(ip_address, private_key=private_key)
37
38 def _wait_for_volume_available_on_system():
39 disks_list_after_attach = ssh.list_disks()
40 return len(disks_list_after_attach) > len(disks_list_before_attach)
41
42 if not test_utils.call_until_true(_wait_for_volume_available_on_system,
43 CONF.compute.build_timeout,
44 CONF.compute.build_interval):
45 raise lib_exc.TimeoutException
46
47 disks_list_after_attach = ssh.list_disks()
48 volume_name = [item for item in disks_list_after_attach
49 if item not in disks_list_before_attach][0]
50 return volume_name
51
52 def _get_file_md5(self, ip_address, filename, dev_name=None,
53 mount_path='/mnt', private_key=None, server=None):
54
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000055 ssh_client = self.get_remote_client(ip_address,
56 private_key=private_key,
57 server=server)
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040058 if dev_name is not None:
59 ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
60 mount_path))
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000061
62 md5_sum = ssh_client.exec_command(
63 'sudo md5sum %s/%s|cut -c 1-32' % (mount_path, filename))
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040064 if dev_name is not None:
65 ssh_client.exec_command('sudo umount %s' % mount_path)
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000066 return md5_sum
67
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040068 def _count_files(self, ip_address, dev_name=None, mount_path='/mnt',
69 private_key=None, server=None):
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000070 ssh_client = self.get_remote_client(ip_address,
71 private_key=private_key,
72 server=server)
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040073 if dev_name is not None:
74 ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
75 mount_path))
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000076 count = ssh_client.exec_command('sudo ls -l %s | wc -l' % mount_path)
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040077 if dev_name is not None:
78 ssh_client.exec_command('sudo umount %s' % mount_path)
79 # We subtract 2 from the count since `wc -l` also includes the count
80 # of new line character and while creating the filesystem, a
81 # lost+found folder is also created
82 return int(count) - 2
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000083
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040084 def _make_fs(self, ip_address, private_key, server, dev_name, fs='ext4'):
Rajat Dhasmana21d63a32020-01-14 17:41:22 +000085 ssh_client = self.get_remote_client(ip_address,
86 private_key=private_key,
87 server=server)
88
Rajat Dhasmanad9e59252021-05-11 16:03:47 -040089 ssh_client.make_fs(dev_name, fs=fs)
90
91 def create_md5_new_file(self, ip_address, filename, dev_name=None,
92 mount_path='/mnt', private_key=None, server=None):
93 ssh_client = self.get_remote_client(ip_address,
94 private_key=private_key,
95 server=server)
96
97 if dev_name is not None:
98 ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
99 mount_path))
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000100 ssh_client.exec_command(
101 'sudo dd bs=1024 count=100 if=/dev/urandom of=/%s/%s' %
102 (mount_path, filename))
103 md5 = ssh_client.exec_command(
104 'sudo md5sum -b %s/%s|cut -c 1-32' % (mount_path, filename))
105 ssh_client.exec_command('sudo sync')
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400106 if dev_name is not None:
107 ssh_client.exec_command('sudo umount %s' % mount_path)
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000108 return md5
109
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400110 def get_md5_from_file(self, instance, instance_ip, filename,
111 dev_name=None):
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000112
113 md5_sum = self._get_file_md5(instance_ip, filename=filename,
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400114 dev_name=dev_name,
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000115 private_key=self.keypair['private_key'],
116 server=instance)
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400117 count = self._count_files(instance_ip, dev_name=dev_name,
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000118 private_key=self.keypair['private_key'],
119 server=instance)
120 return count, md5_sum
121
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400122 def _attach_and_get_volume_device_name(self, server, volume, instance_ip,
123 private_key):
124 ssh_client = self.get_remote_client(
125 instance_ip, private_key=private_key,
126 server=server)
127 # List disks before volume attachment
128 disks_list_before_attach = ssh_client.list_disks()
129 # Attach volume
130 volume = self.nova_volume_attach(server, volume)
131 # Find the difference between disks before and after attachment that
132 # gives us the volume device name
133 volume_device_name = self._attached_volume_name(
134 disks_list_before_attach, instance_ip, private_key)
135 return volume_device_name
136
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000137 @decorators.idempotent_id('ff10644e-5a70-4a9f-9801-8204bb81fb61')
138 @utils.services('compute', 'volume', 'image', 'network')
139 def test_snapshot_data_integrity(self):
140 """This test checks the data integrity after creating and restoring
141
142 snapshots. The procedure is as follows:
143
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400144 1) Create an instance with ephemeral disk
145 2) Create a volume, attach it to the instance and create a filesystem
146 on it and mount it
147 3) Mount the volume, create a file and write data into it, Unmount it
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000148 4) create snapshot
149 5) repeat 3 and 4 two more times (simply creating 3 snapshots)
150
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400151 Now create volume from the snapshots one by one, attach it to the
152 instance and check the number of files and file content at each
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000153 point when snapshot was created.
154 """
155
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400156 # Create an instance
157 server = self.create_server(
158 key_name=self.keypair['name'],
159 security_groups=[{'name': self.security_group['name']}])
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000160
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400161 # Create an empty volume
162 volume = self.create_volume()
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000163
164 instance_ip = self.get_server_ip(server)
165
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400166 # Attach volume to instance and find it's device name (eg: /dev/vdb)
167 volume_device_name = self._attach_and_get_volume_device_name(
168 server, volume, instance_ip, self.keypair['private_key'])
169
170 # Create filesystem on the volume
171 self._make_fs(instance_ip, self.keypair['private_key'], server,
172 volume_device_name)
173
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000174 # Write data to volume
175 file1_md5 = self.create_md5_new_file(
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400176 instance_ip, dev_name=volume_device_name, filename="file1",
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000177 private_key=self.keypair['private_key'],
178 server=instance_ip)
179
180 # Create first snapshot
181 snapshot1 = self.create_volume_snapshot(volume['id'], force=True)
182
183 # Write data to volume
184 file2_md5 = self.create_md5_new_file(
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400185 instance_ip, dev_name=volume_device_name, filename="file2",
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000186 private_key=self.keypair['private_key'],
187 server=instance_ip)
188
189 # Create second snapshot
190 snapshot2 = self.create_volume_snapshot(volume['id'], force=True)
191
192 # Write data to volume
193 file3_md5 = self.create_md5_new_file(
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400194 instance_ip, dev_name=volume_device_name, filename="file3",
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000195 private_key=self.keypair['private_key'],
196 server=instance_ip)
197
198 # Create third snapshot
199 snapshot3 = self.create_volume_snapshot(volume['id'], force=True)
200
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400201 # Detach the volume
202 self.nova_volume_detach(server, volume)
203
204 # Create volume from snapshot, attach it to instance and check file
205 # and contents for snap1
206 volume_snap_1 = self.create_volume(snapshot_id=snapshot1['id'])
207 volume_device_name = self._attach_and_get_volume_device_name(
208 server, volume_snap_1, instance_ip, self.keypair['private_key'])
209 count_snap_1, md5_file_1 = self.get_md5_from_file(
210 server, instance_ip, 'file1', dev_name=volume_device_name)
211 # Detach the volume
212 self.nova_volume_detach(server, volume_snap_1)
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000213
214 self.assertEqual(count_snap_1, 1)
215 self.assertEqual(file1_md5, md5_file_1)
216
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400217 # Create volume from snapshot, attach it to instance and check file
218 # and contents for snap2
219 volume_snap_2 = self.create_volume(snapshot_id=snapshot2['id'])
220 volume_device_name = self._attach_and_get_volume_device_name(
221 server, volume_snap_2, instance_ip, self.keypair['private_key'])
222 count_snap_2, md5_file_2 = self.get_md5_from_file(
223 server, instance_ip, 'file2', dev_name=volume_device_name)
224 # Detach the volume
225 self.nova_volume_detach(server, volume_snap_2)
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000226
227 self.assertEqual(count_snap_2, 2)
228 self.assertEqual(file2_md5, md5_file_2)
229
Rajat Dhasmanad9e59252021-05-11 16:03:47 -0400230 # Create volume from snapshot, attach it to instance and check file
231 # and contents for snap3
232 volume_snap_3 = self.create_volume(snapshot_id=snapshot3['id'])
233 volume_device_name = self._attach_and_get_volume_device_name(
234 server, volume_snap_3, instance_ip, self.keypair['private_key'])
235 count_snap_3, md5_file_3 = self.get_md5_from_file(
236 server, instance_ip, 'file3', dev_name=volume_device_name)
237 # Detach the volume
238 self.nova_volume_detach(server, volume_snap_3)
Rajat Dhasmana21d63a32020-01-14 17:41:22 +0000239
240 self.assertEqual(count_snap_3, 3)
241 self.assertEqual(file3_md5, md5_file_3)