blob: 20561ae0d87d996109c7e95cf921c979d6206547 [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
Attila Fazekas70431ba2013-07-26 18:47:37 +020018from cinderclient import exceptions as cinder_exceptions
Sean Daguefe8a6092013-07-27 08:15:55 -040019
Masayuki Igawa259c1132013-10-31 17:48:44 +090020from tempest.common.utils import data_utils
Matthew Treinish6c072292014-01-29 19:15:52 +000021from tempest import config
Attila Fazekas70431ba2013-07-26 18:47:37 +020022from tempest import exceptions
Matthew Treinishf4a9b0f2013-07-26 16:58:26 -040023from tempest.openstack.common import log as logging
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000024from tempest.scenario import manager
Attila Fazekas70431ba2013-07-26 18:47:37 +020025import tempest.test
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000026
Matthew Treinish6c072292014-01-29 19:15:52 +000027CONF = config.CONF
28
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000029LOG = logging.getLogger(__name__)
30
31
32class TestStampPattern(manager.OfficialClientTest):
33 """
34 This test is for snapshotting an instance/volume and attaching the volume
35 created from snapshot to the instance booted from snapshot.
36 The following is the scenario outline:
37 1. Boot an instance "instance1"
38 2. Create a volume "volume1"
39 3. Attach volume1 to instance1
40 4. Create a filesystem on volume1
41 5. Mount volume1
42 6. Create a file which timestamp is written in volume1
43 7. Unmount volume1
44 8. Detach volume1 from instance1
45 9. Get a snapshot "snapshot_from_volume" of volume1
46 10. Get a snapshot "snapshot_from_instance" of instance1
47 11. Boot an instance "instance2" from snapshot_from_instance
48 12. Create a volume "volume2" from snapshot_from_volume
49 13. Attach volume2 to instance2
50 14. Check the existence of a file which created at 6. in volume2
51 """
52
JordanPbce55532014-03-19 12:10:32 +010053 @classmethod
54 def setUpClass(cls):
55 super(TestStampPattern, cls).setUpClass()
56
57 if not CONF.volume_feature_enabled.snapshot:
58 raise cls.skipException("Cinder volume snapshots are disabled")
59
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000060 def _wait_for_volume_snapshot_status(self, volume_snapshot, status):
61 self.status_timeout(self.volume_client.volume_snapshots,
62 volume_snapshot.id, status)
63
64 def _boot_image(self, image_id):
Grishkin0f1e11c2014-05-04 20:44:52 +040065 security_groups = [self.security_group.name]
Ken'ichi Ohmichi61f272b2013-08-15 15:58:53 +090066 create_kwargs = {
Grishkin0f1e11c2014-05-04 20:44:52 +040067 'key_name': self.keypair.name,
68 'security_groups': security_groups
Ken'ichi Ohmichi61f272b2013-08-15 15:58:53 +090069 }
Giulio Fidente61cadca2013-09-24 18:33:37 +020070 return self.create_server(image=image_id, create_kwargs=create_kwargs)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000071
72 def _add_keypair(self):
Ken'ichi Ohmichi599d1b82013-08-19 18:48:37 +090073 self.keypair = self.create_keypair()
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000074
75 def _create_floating_ip(self):
76 floating_ip = self.compute_client.floating_ips.create()
77 self.addCleanup(floating_ip.delete)
78 return floating_ip
79
80 def _add_floating_ip(self, server, floating_ip):
81 server.add_floating_ip(floating_ip)
82
Attila Fazekas70431ba2013-07-26 18:47:37 +020083 def _ssh_to_server(self, server_or_ip):
Elena Ezhova91db24e2014-02-28 20:47:10 +040084 return self.get_remote_client(server_or_ip)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000085
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000086 def _create_volume_snapshot(self, volume):
Masayuki Igawa259c1132013-10-31 17:48:44 +090087 snapshot_name = data_utils.rand_name('scenario-snapshot-')
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000088 volume_snapshots = self.volume_client.volume_snapshots
89 snapshot = volume_snapshots.create(
90 volume.id, display_name=snapshot_name)
91
92 def cleaner():
93 volume_snapshots.delete(snapshot)
94 try:
95 while volume_snapshots.get(snapshot.id):
96 time.sleep(1)
Attila Fazekas70431ba2013-07-26 18:47:37 +020097 except cinder_exceptions.NotFound:
Yuiko Takadaebcf6af2013-07-09 05:10:55 +000098 pass
99 self.addCleanup(cleaner)
100 self._wait_for_volume_status(volume, 'available')
101 self._wait_for_volume_snapshot_status(snapshot, 'available')
Chang Bo Guofc77e932013-09-16 17:38:26 -0700102 self.assertEqual(snapshot_name, snapshot.display_name)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000103 return snapshot
104
105 def _wait_for_volume_status(self, volume, status):
106 self.status_timeout(
107 self.volume_client.volumes, volume.id, status)
108
109 def _create_volume(self, snapshot_id=None):
Ken'ichi Ohmichi70672df2013-08-19 18:35:19 +0900110 return self.create_volume(snapshot_id=snapshot_id)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000111
112 def _attach_volume(self, server, volume):
113 attach_volume_client = self.compute_client.volumes.create_server_volume
114 attached_volume = attach_volume_client(server.id,
115 volume.id,
116 '/dev/vdb')
117 self.assertEqual(volume.id, attached_volume.id)
118 self._wait_for_volume_status(attached_volume, 'in-use')
119
120 def _detach_volume(self, server, volume):
121 detach_volume_client = self.compute_client.volumes.delete_server_volume
122 detach_volume_client(server.id, volume.id)
123 self._wait_for_volume_status(volume, 'available')
124
Marc Solanasb15d8b62014-02-07 00:04:15 -0800125 def _wait_for_volume_available_on_the_system(self, server_or_ip):
Ken'ichi Ohmichib3aa9122013-08-22 23:27:25 +0900126 ssh = self.get_remote_client(server_or_ip)
Attila Fazekas70431ba2013-07-26 18:47:37 +0200127
128 def _func():
129 part = ssh.get_partitions()
130 LOG.debug("Partitions:%s" % part)
131 return 'vdb' in part
132
133 if not tempest.test.call_until_true(_func,
Matthew Treinish6c072292014-01-29 19:15:52 +0000134 CONF.compute.build_timeout,
135 CONF.compute.build_interval):
Attila Fazekas70431ba2013-07-26 18:47:37 +0200136 raise exceptions.TimeoutException
137
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000138 def _create_timestamp(self, server_or_ip):
139 ssh_client = self._ssh_to_server(server_or_ip)
140 ssh_client.exec_command('sudo /usr/sbin/mkfs.ext4 /dev/vdb')
141 ssh_client.exec_command('sudo mount /dev/vdb /mnt')
142 ssh_client.exec_command('sudo sh -c "date > /mnt/timestamp;sync"')
143 self.timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
144 ssh_client.exec_command('sudo umount /mnt')
145
146 def _check_timestamp(self, server_or_ip):
147 ssh_client = self._ssh_to_server(server_or_ip)
148 ssh_client.exec_command('sudo mount /dev/vdb /mnt')
149 got_timestamp = ssh_client.exec_command('sudo cat /mnt/timestamp')
150 self.assertEqual(self.timestamp, got_timestamp)
151
Giulio Fidente386ac8f2013-10-07 14:29:27 +0200152 @tempest.test.skip_because(bug="1205344")
Matthew Treinish2153ec02013-09-09 20:57:30 +0000153 @tempest.test.services('compute', 'network', 'volume', 'image')
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000154 def test_stamp_pattern(self):
155 # prepare for booting a instance
156 self._add_keypair()
Grishkin0f1e11c2014-05-04 20:44:52 +0400157 self.security_group = self._create_security_group_nova()
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000158
159 # boot an instance and create a timestamp file in it
160 volume = self._create_volume()
Matthew Treinish6c072292014-01-29 19:15:52 +0000161 server = self._boot_image(CONF.compute.image_ref)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000162
163 # create and add floating IP to server1
Matthew Treinish6c072292014-01-29 19:15:52 +0000164 if CONF.compute.use_floatingip_for_ssh:
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000165 floating_ip_for_server = self._create_floating_ip()
166 self._add_floating_ip(server, floating_ip_for_server)
167 ip_for_server = floating_ip_for_server.ip
168 else:
169 ip_for_server = server
170
171 self._attach_volume(server, volume)
Marc Solanasb15d8b62014-02-07 00:04:15 -0800172 self._wait_for_volume_available_on_the_system(ip_for_server)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000173 self._create_timestamp(ip_for_server)
174 self._detach_volume(server, volume)
175
176 # snapshot the volume
177 volume_snapshot = self._create_volume_snapshot(volume)
178
179 # snapshot the instance
Ken'ichi Ohmichia4912232013-08-26 14:03:25 +0900180 snapshot_image = self.create_server_snapshot(server=server)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000181
182 # create second volume from the snapshot(volume2)
183 volume_from_snapshot = self._create_volume(
184 snapshot_id=volume_snapshot.id)
185
186 # boot second instance from the snapshot(instance2)
Ken'ichi Ohmichia4912232013-08-26 14:03:25 +0900187 server_from_snapshot = self._boot_image(snapshot_image.id)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000188
189 # create and add floating IP to server_from_snapshot
Matthew Treinish6c072292014-01-29 19:15:52 +0000190 if CONF.compute.use_floatingip_for_ssh:
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000191 floating_ip_for_snapshot = self._create_floating_ip()
192 self._add_floating_ip(server_from_snapshot,
193 floating_ip_for_snapshot)
194 ip_for_snapshot = floating_ip_for_snapshot.ip
195 else:
196 ip_for_snapshot = server_from_snapshot
197
198 # attach volume2 to instance2
199 self._attach_volume(server_from_snapshot, volume_from_snapshot)
Marc Solanasb15d8b62014-02-07 00:04:15 -0800200 self._wait_for_volume_available_on_the_system(ip_for_snapshot)
Yuiko Takadaebcf6af2013-07-09 05:10:55 +0000201
202 # check the existence of the timestamp file in the volume2
203 self._check_timestamp(ip_for_snapshot)