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 |
Eric Harney | 92e0b85 | 2021-08-24 20:30:10 +0000 | [diff] [blame] | 17 | from tempest.common import waiters |
| 18 | from tempest import config |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 19 | from tempest.lib import decorators |
| 20 | |
Eric Harney | 92e0b85 | 2021-08-24 20:30:10 +0000 | [diff] [blame] | 21 | import testtools |
| 22 | |
Luigi Toscano | 3c5c8a2 | 2021-02-23 10:24:01 +0100 | [diff] [blame] | 23 | from cinder_tempest_plugin.scenario import manager |
| 24 | |
Eric Harney | 92e0b85 | 2021-08-24 20:30:10 +0000 | [diff] [blame] | 25 | CONF = config.CONF |
| 26 | |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 27 | |
| 28 | class SnapshotDataIntegrityTests(manager.ScenarioTest): |
| 29 | |
| 30 | def setUp(self): |
| 31 | super(SnapshotDataIntegrityTests, self).setUp() |
Dan Smith | 51c56f2 | 2023-04-27 15:49:10 -0700 | [diff] [blame] | 32 | self.validation_resources = self.get_test_validation_resources( |
| 33 | self.os_primary) |
| 34 | # NOTE(danms): If validation is enabled, we will have a keypair to use, |
| 35 | # otherwise we need to create our own. |
| 36 | if 'keypair' in self.validation_resources: |
| 37 | self.keypair = self.validation_resources['keypair'] |
| 38 | else: |
| 39 | self.keypair = self.create_keypair() |
Rajat Dhasmana | 638f230 | 2021-05-12 06:23:45 -0400 | [diff] [blame] | 40 | self.security_group = self.create_security_group() |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 41 | |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 42 | @decorators.idempotent_id('ff10644e-5a70-4a9f-9801-8204bb81fb61') |
| 43 | @utils.services('compute', 'volume', 'image', 'network') |
| 44 | def test_snapshot_data_integrity(self): |
| 45 | """This test checks the data integrity after creating and restoring |
| 46 | |
| 47 | snapshots. The procedure is as follows: |
| 48 | |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 49 | 1) Create an instance with ephemeral disk |
| 50 | 2) Create a volume, attach it to the instance and create a filesystem |
| 51 | on it and mount it |
whoami-rajat | 027295a | 2021-12-12 12:31:59 -0500 | [diff] [blame] | 52 | 3) Create a file and write data into it, Unmount it |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 53 | 4) create snapshot |
| 54 | 5) repeat 3 and 4 two more times (simply creating 3 snapshots) |
| 55 | |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 56 | Now create volume from the snapshots one by one, attach it to the |
| 57 | instance and check the number of files and file content at each |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 58 | point when snapshot was created. |
| 59 | """ |
| 60 | |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 61 | # Create an instance |
| 62 | server = self.create_server( |
| 63 | key_name=self.keypair['name'], |
Dan Smith | 51c56f2 | 2023-04-27 15:49:10 -0700 | [diff] [blame] | 64 | validatable=True, |
| 65 | validation_resources=self.validation_resources, |
| 66 | wait_until='SSHABLE', |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 67 | security_groups=[{'name': self.security_group['name']}]) |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 68 | |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 69 | # Create an empty volume |
| 70 | volume = self.create_volume() |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 71 | |
| 72 | instance_ip = self.get_server_ip(server) |
| 73 | |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 74 | # Attach volume to instance and find it's device name (eg: /dev/vdb) |
Rajat Dhasmana | 638f230 | 2021-05-12 06:23:45 -0400 | [diff] [blame] | 75 | volume_device_name, __ = self._attach_and_get_volume_device_name( |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 76 | server, volume, instance_ip, self.keypair['private_key']) |
| 77 | |
| 78 | # Create filesystem on the volume |
| 79 | self._make_fs(instance_ip, self.keypair['private_key'], server, |
| 80 | volume_device_name) |
| 81 | |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 82 | # Write data to volume |
| 83 | file1_md5 = self.create_md5_new_file( |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 84 | instance_ip, dev_name=volume_device_name, filename="file1", |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 85 | private_key=self.keypair['private_key'], |
| 86 | server=instance_ip) |
| 87 | |
| 88 | # Create first snapshot |
| 89 | snapshot1 = self.create_volume_snapshot(volume['id'], force=True) |
| 90 | |
| 91 | # Write data to volume |
| 92 | file2_md5 = self.create_md5_new_file( |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 93 | instance_ip, dev_name=volume_device_name, filename="file2", |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 94 | private_key=self.keypair['private_key'], |
| 95 | server=instance_ip) |
| 96 | |
| 97 | # Create second snapshot |
| 98 | snapshot2 = self.create_volume_snapshot(volume['id'], force=True) |
| 99 | |
| 100 | # Write data to volume |
| 101 | file3_md5 = self.create_md5_new_file( |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 102 | instance_ip, dev_name=volume_device_name, filename="file3", |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 103 | private_key=self.keypair['private_key'], |
| 104 | server=instance_ip) |
| 105 | |
| 106 | # Create third snapshot |
| 107 | snapshot3 = self.create_volume_snapshot(volume['id'], force=True) |
| 108 | |
Rajat Dhasmana | d9e5925 | 2021-05-11 16:03:47 -0400 | [diff] [blame] | 109 | # Detach the volume |
| 110 | self.nova_volume_detach(server, volume) |
| 111 | |
whoami-rajat | 027295a | 2021-12-12 12:31:59 -0500 | [diff] [blame] | 112 | snap_map = {1: snapshot1, 2: snapshot2, 3: snapshot3} |
| 113 | file_map = {1: file1_md5, 2: file2_md5, 3: file3_md5} |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 114 | |
whoami-rajat | 027295a | 2021-12-12 12:31:59 -0500 | [diff] [blame] | 115 | # Loop over 3 times to check the data integrity of all 3 snapshots |
| 116 | for i in range(1, 4): |
| 117 | # Create volume from snapshot, attach it to instance and check file |
| 118 | # and contents for snap |
| 119 | volume_snap = self.create_volume(snapshot_id=snap_map[i]['id']) |
| 120 | volume_device_name, __ = self._attach_and_get_volume_device_name( |
| 121 | server, volume_snap, instance_ip, self.keypair['private_key']) |
| 122 | count_snap, md5_file = self.get_md5_from_file( |
| 123 | server, instance_ip, 'file' + str(i), |
| 124 | dev_name=volume_device_name) |
| 125 | # Detach the volume |
| 126 | self.nova_volume_detach(server, volume_snap) |
Rajat Dhasmana | 21d63a3 | 2020-01-14 17:41:22 +0000 | [diff] [blame] | 127 | |
whoami-rajat | 027295a | 2021-12-12 12:31:59 -0500 | [diff] [blame] | 128 | self.assertEqual(count_snap, i) |
| 129 | self.assertEqual(file_map[i], md5_file) |
Eric Harney | 92e0b85 | 2021-08-24 20:30:10 +0000 | [diff] [blame] | 130 | |
| 131 | |
| 132 | class SnapshotDependencyTests(manager.ScenarioTest): |
| 133 | @testtools.skipUnless(CONF.volume_feature_enabled.volume_image_dep_tests, |
| 134 | 'dependency tests not enabled') |
| 135 | @decorators.idempotent_id('e7028f52-f6d4-479c-8809-6f6cf96cfe0f') |
| 136 | @utils.services('image', 'volume') |
| 137 | def test_snapshot_removal(self): |
| 138 | volume_1 = self.create_volume() |
| 139 | |
| 140 | snapshot_1 = self.create_volume_snapshot(volume_1['id'], force=True) |
| 141 | waiters.wait_for_volume_resource_status( |
| 142 | self.snapshots_client, snapshot_1['id'], 'available') |
| 143 | |
| 144 | clone_kwargs = {'snapshot_id': snapshot_1['id'], |
| 145 | 'size': volume_1['size']} |
| 146 | volume_2 = self.volumes_client.create_volume(**clone_kwargs)['volume'] |
| 147 | |
| 148 | waiters.wait_for_volume_resource_status( |
| 149 | self.volumes_client, volume_2['id'], 'available') |
| 150 | volume_2 = self.volumes_client.show_volume(volume_2['id'])['volume'] |
| 151 | |
| 152 | self.snapshots_client.delete_snapshot(snapshot_1['id']) |
| 153 | self.snapshots_client.wait_for_resource_deletion(snapshot_1['id']) |
| 154 | |
| 155 | self.volumes_client.delete_volume(volume_1['id']) |
| 156 | self.volumes_client.wait_for_resource_deletion(volume_1['id']) |
| 157 | |
| 158 | self.volumes_client.delete_volume(volume_2['id']) |
| 159 | self.volumes_client.wait_for_resource_deletion(volume_2['id']) |