blob: 3614e9795add5255eb1dc53a73c91841ec9f3718 [file] [log] [blame]
Yuiko Takadaebcf6af2013-07-09 05:10:55 +00001# Copyright 2013 NEC Corporation
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
Sean Daguefe8a6092013-07-27 08:15:55 -040016import time
17
Matthew Treinishc49fcbe2015-02-05 23:37:34 -050018from tempest_lib import decorators
Masayuki Igawabfa07602015-01-20 18:47:17 +090019from tempest_lib import exceptions as lib_exc
Adam Gandelmanfbc95ac2014-06-19 17:33:43 -070020import testtools
Sean Daguefe8a6092013-07-27 08:15:55 -040021
Masayuki Igawa259c1132013-10-31 17:48:44 +090022from tempest.common.utils import data_utils
Matthew Treinish6c072292014-01-29 19:15:52 +000023from tempest import config
Attila Fazekas70431ba2013-07-26 18:47:37 +020024from tempest import exceptions
Matthew Treinishf4a9b0f2013-07-26 16:58:26 -040025from tempest.openstack.common import log as logging
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000026from tempest.scenario import manager
Chris Hoge7579c1a2015-02-26 14:12:15 -080027from tempest import test
Attila Fazekas70431ba2013-07-26 18:47:37 +020028import tempest.test
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000029
Matthew Treinish6c072292014-01-29 19:15:52 +000030CONF = config.CONF
31
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000032LOG = logging.getLogger(__name__)
33
34
Andrea Frittolic0651b22014-09-17 16:34:01 +010035class TestStampPattern(manager.ScenarioTest):
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000036 """
37 This test is for snapshotting an instance/volume and attaching the volume
38 created from snapshot to the instance booted from snapshot.
39 The following is the scenario outline:
40 1. Boot an instance "instance1"
41 2. Create a volume "volume1"
42 3. Attach volume1 to instance1
43 4. Create a filesystem on volume1
44 5. Mount volume1
45 6. Create a file which timestamp is written in volume1
46 7. Unmount volume1
47 8. Detach volume1 from instance1
48 9. Get a snapshot "snapshot_from_volume" of volume1
49 10. Get a snapshot "snapshot_from_instance" of instance1
50 11. Boot an instance "instance2" from snapshot_from_instance
51 12. Create a volume "volume2" from snapshot_from_volume
52 13. Attach volume2 to instance2
53 14. Check the existence of a file which created at 6. in volume2
54 """
55
JordanPbce55532014-03-19 12:10:32 +010056 @classmethod
Emily Hugenbruch5e2d2a22015-02-25 21:35:45 +000057 def skip_checks(cls):
58 super(TestStampPattern, cls).skip_checks()
JordanPbce55532014-03-19 12:10:32 +010059 if not CONF.volume_feature_enabled.snapshot:
60 raise cls.skipException("Cinder volume snapshots are disabled")
61
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000062 def _wait_for_volume_snapshot_status(self, volume_snapshot, status):
Andrea Frittolic0651b22014-09-17 16:34:01 +010063 self.snapshots_client.wait_for_snapshot_status(volume_snapshot['id'],
64 status)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000065
66 def _boot_image(self, image_id):
Ken'ichi Ohmichi1b3461e2014-12-02 03:41:07 +000067 security_groups = [{'name': self.security_group['name']}]
Ken'ichi Ohmichi61f272b2013-08-15 15:58:53 +090068 create_kwargs = {
Andrea Frittolic0651b22014-09-17 16:34:01 +010069 'key_name': self.keypair['name'],
Grishkin0f1e11c2014-05-04 20:44:52 +040070 'security_groups': security_groups
Ken'ichi Ohmichi61f272b2013-08-15 15:58:53 +090071 }
Giulio Fidente61cadca2013-09-24 18:33:37 +020072 return self.create_server(image=image_id, create_kwargs=create_kwargs)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000073
74 def _add_keypair(self):
Ken'ichi Ohmichi599d1b82013-08-19 18:48:37 +090075 self.keypair = self.create_keypair()
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000076
Attila Fazekas70431ba2013-07-26 18:47:37 +020077 def _ssh_to_server(self, server_or_ip):
Elena Ezhova91db24e2014-02-28 20:47:10 +040078 return self.get_remote_client(server_or_ip)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000079
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000080 def _create_volume_snapshot(self, volume):
Masayuki Igawa259c1132013-10-31 17:48:44 +090081 snapshot_name = data_utils.rand_name('scenario-snapshot-')
Andrea Frittolic0651b22014-09-17 16:34:01 +010082 _, snapshot = self.snapshots_client.create_snapshot(
83 volume['id'], display_name=snapshot_name)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000084
85 def cleaner():
Andrea Frittolic0651b22014-09-17 16:34:01 +010086 self.snapshots_client.delete_snapshot(snapshot['id'])
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000087 try:
Andrea Frittolic0651b22014-09-17 16:34:01 +010088 while self.snapshots_client.get_snapshot(snapshot['id']):
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000089 time.sleep(1)
Masayuki Igawabfa07602015-01-20 18:47:17 +090090 except lib_exc.NotFound:
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000091 pass
92 self.addCleanup(cleaner)
93 self._wait_for_volume_status(volume, 'available')
Andrea Frittolic0651b22014-09-17 16:34:01 +010094 self.snapshots_client.wait_for_snapshot_status(snapshot['id'],
95 'available')
96 self.assertEqual(snapshot_name, snapshot['display_name'])
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000097 return snapshot
98
99 def _wait_for_volume_status(self, volume, status):
Andrea Frittolic0651b22014-09-17 16:34:01 +0100100 self.volumes_client.wait_for_volume_status(volume['id'], status)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000101
102 def _create_volume(self, snapshot_id=None):
Ken'ichi Ohmichi70672df2013-08-19 18:35:19 +0900103 return self.create_volume(snapshot_id=snapshot_id)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000104
105 def _attach_volume(self, server, volume):
Andrea Frittolic0651b22014-09-17 16:34:01 +0100106 # TODO(andreaf) we should use device from config instead if vdb
David Kranz3ebc7212015-02-10 12:19:19 -0500107 attached_volume = self.servers_client.attach_volume(
Andrea Frittolic0651b22014-09-17 16:34:01 +0100108 server['id'], volume['id'], device='/dev/vdb')
Andrea Frittolic0651b22014-09-17 16:34:01 +0100109 self.assertEqual(volume['id'], attached_volume['id'])
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000110 self._wait_for_volume_status(attached_volume, 'in-use')
111
112 def _detach_volume(self, server, volume):
Andrea Frittolic0651b22014-09-17 16:34:01 +0100113 self.servers_client.detach_volume(server['id'], volume['id'])
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000114 self._wait_for_volume_status(volume, 'available')
115
Marc Solanasb15d8b62014-02-07 00:04:15 -0800116 def _wait_for_volume_available_on_the_system(self, server_or_ip):
Ken'ichi Ohmichib3aa9122013-08-22 23:27:25 +0900117 ssh = self.get_remote_client(server_or_ip)
Attila Fazekas70431ba2013-07-26 18:47:37 +0200118
119 def _func():
120 part = ssh.get_partitions()
121 LOG.debug("Partitions:%s" % part)
122 return 'vdb' in part
123
124 if not tempest.test.call_until_true(_func,
Matthew Treinish6c072292014-01-29 19:15:52 +0000125 CONF.compute.build_timeout,
126 CONF.compute.build_interval):
Attila Fazekas70431ba2013-07-26 18:47:37 +0200127 raise exceptions.TimeoutException
128
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000129 def _create_timestamp(self, server_or_ip):
130 ssh_client = self._ssh_to_server(server_or_ip)
131 ssh_client.exec_command('sudo /usr/sbin/mkfs.ext4 /dev/vdb')
132 ssh_client.exec_command('sudo mount /dev/vdb /mnt')
133 ssh_client.exec_command('sudo sh -c "date > /mnt/timestamp;sync"')
134 self.timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
135 ssh_client.exec_command('sudo umount /mnt')
136
137 def _check_timestamp(self, server_or_ip):
138 ssh_client = self._ssh_to_server(server_or_ip)
139 ssh_client.exec_command('sudo mount /dev/vdb /mnt')
140 got_timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
141 self.assertEqual(self.timestamp, got_timestamp)
142
Matthew Treinishc49fcbe2015-02-05 23:37:34 -0500143 @decorators.skip_because(bug="1205344")
Chris Hoge7579c1a2015-02-26 14:12:15 -0800144 @test.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
Adam Gandelmanfbc95ac2014-06-19 17:33:43 -0700145 @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
146 'Snapshotting is not available.')
Matthew Treinish2153ec02013-09-09 20:57:30 +0000147 @tempest.test.services('compute', 'network', 'volume', 'image')
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000148 def test_stamp_pattern(self):
149 # prepare for booting a instance
150 self._add_keypair()
Andrea Frittolic0651b22014-09-17 16:34:01 +0100151 self.security_group = self._create_security_group()
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000152
153 # boot an instance and create a timestamp file in it
154 volume = self._create_volume()
Matthew Treinish6c072292014-01-29 19:15:52 +0000155 server = self._boot_image(CONF.compute.image_ref)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000156
157 # create and add floating IP to server1
Matthew Treinish6c072292014-01-29 19:15:52 +0000158 if CONF.compute.use_floatingip_for_ssh:
Yair Friedae0e73d2014-11-24 11:56:26 +0200159 floating_ip_for_server = self.create_floating_ip(server)
Andrea Frittolic0651b22014-09-17 16:34:01 +0100160 ip_for_server = floating_ip_for_server['ip']
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000161 else:
162 ip_for_server = server
163
164 self._attach_volume(server, volume)
Marc Solanasb15d8b62014-02-07 00:04:15 -0800165 self._wait_for_volume_available_on_the_system(ip_for_server)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000166 self._create_timestamp(ip_for_server)
167 self._detach_volume(server, volume)
168
169 # snapshot the volume
170 volume_snapshot = self._create_volume_snapshot(volume)
171
172 # snapshot the instance
Ken'ichi Ohmichia4912232013-08-26 14:03:25 +0900173 snapshot_image = self.create_server_snapshot(server=server)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000174
175 # create second volume from the snapshot(volume2)
176 volume_from_snapshot = self._create_volume(
Andrea Frittolic0651b22014-09-17 16:34:01 +0100177 snapshot_id=volume_snapshot['id'])
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000178
179 # boot second instance from the snapshot(instance2)
Andrea Frittolic0651b22014-09-17 16:34:01 +0100180 server_from_snapshot = self._boot_image(snapshot_image['id'])
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000181
182 # create and add floating IP to server_from_snapshot
Matthew Treinish6c072292014-01-29 19:15:52 +0000183 if CONF.compute.use_floatingip_for_ssh:
Yair Friedae0e73d2014-11-24 11:56:26 +0200184 floating_ip_for_snapshot = self.create_floating_ip(
185 server_from_snapshot)
Andrea Frittolic0651b22014-09-17 16:34:01 +0100186 ip_for_snapshot = floating_ip_for_snapshot['ip']
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000187 else:
188 ip_for_snapshot = server_from_snapshot
189
190 # attach volume2 to instance2
191 self._attach_volume(server_from_snapshot, volume_from_snapshot)
Marc Solanasb15d8b62014-02-07 00:04:15 -0800192 self._wait_for_volume_available_on_the_system(ip_for_snapshot)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000193
194 # check the existence of the timestamp file in the volume2
195 self._check_timestamp(ip_for_snapshot)