blob: 603c8f2117f11103cb32b7480e031ff70bfdcaf8 [file] [log] [blame]
Steve Bakera5bd9122014-08-11 14:39:00 +12001# Licensed under the Apache License, Version 2.0 (the "License"); you may
2# not use this file except in compliance with the License. You may obtain
3# a copy of the License at
4#
5# http://www.apache.org/licenses/LICENSE-2.0
6#
7# Unless required by applicable law or agreed to in writing, software
8# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
9# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
10# License for the specific language governing permissions and limitations
11# under the License.
12
Steve Bakera5bd9122014-08-11 14:39:00 +120013
14from cinderclient import exceptions as cinder_exceptions
Steve Baker24641292015-03-13 10:47:50 +130015from oslo_log import log as logging
Pavlo Shchelokovskyy60e0ecd2014-12-14 22:17:21 +020016import six
Steve Bakera5bd9122014-08-11 14:39:00 +120017
Steve Baker50d3e8c2014-10-21 11:08:50 +130018from heat_integrationtests.common import exceptions
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +040019from heat_integrationtests.scenario import scenario_base
Steve Bakera5bd9122014-08-11 14:39:00 +120020
21LOG = logging.getLogger(__name__)
22
23
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +040024class VolumeBackupRestoreIntegrationTest(scenario_base.ScenarioTestsBase):
Peter Razumovskyf0ac9582015-09-24 16:49:03 +030025 """Class is responsible for testing of volume backup."""
Steve Bakera5bd9122014-08-11 14:39:00 +120026
27 def setUp(self):
28 super(VolumeBackupRestoreIntegrationTest, self).setUp()
Steve Bakera5bd9122014-08-11 14:39:00 +120029 self.volume_description = 'A test volume description 123'
30 self.volume_size = self.conf.volume_size
31
32 def _cinder_verify(self, volume_id, expected_status='available'):
33 self.assertIsNotNone(volume_id)
34 volume = self.volume_client.volumes.get(volume_id)
35 self.assertIsNotNone(volume)
36 self.assertEqual(expected_status, volume.status)
37 self.assertEqual(self.volume_size, volume.size)
38 self.assertEqual(self.volume_description,
39 volume.display_description)
40
41 def _outputs_verify(self, stack, expected_status='available'):
42 self.assertEqual(expected_status,
43 self._stack_output(stack, 'status'))
44 self.assertEqual(six.text_type(self.volume_size),
45 self._stack_output(stack, 'size'))
46 self.assertEqual(self.volume_description,
47 self._stack_output(stack, 'display_description'))
48
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +040049 def check_stack(self, stack_id):
50 stack = self.client.stacks.get(stack_id)
Sergey Kraynevef9d8422015-02-13 03:41:46 -050051
Steve Bakera5bd9122014-08-11 14:39:00 +120052 # Verify with cinder that the volume exists, with matching details
53 volume_id = self._stack_output(stack, 'volume_id')
54 self._cinder_verify(volume_id, expected_status='in-use')
55
56 # Verify the stack outputs are as expected
57 self._outputs_verify(stack, expected_status='in-use')
58
59 # Delete the stack and ensure a backup is created for volume_id
60 # but the volume itself is gone
Sergey Kraynevbf67ce32015-04-17 10:54:20 -040061 self._stack_delete(stack_id)
Steve Bakera5bd9122014-08-11 14:39:00 +120062 self.assertRaises(cinder_exceptions.NotFound,
63 self.volume_client.volumes.get,
64 volume_id)
65
66 backups = self.volume_client.backups.list()
67 self.assertIsNotNone(backups)
68 backups_filtered = [b for b in backups if b.volume_id == volume_id]
69 self.assertEqual(1, len(backups_filtered))
70 backup = backups_filtered[0]
71 self.addCleanup(self.volume_client.backups.delete, backup.id)
72
73 # Now, we create another stack where the volume is created from the
74 # backup created by the previous stack
Steve Baker50d3e8c2014-10-21 11:08:50 +130075 try:
Sergey Kraynevef9d8422015-02-13 03:41:46 -050076 stack_identifier2 = self.launch_stack(
Steve Baker50d3e8c2014-10-21 11:08:50 +130077 template_name='test_volumes_create_from_backup.yaml',
78 add_parameters={'backup_id': backup.id})
Sergey Kraynevef9d8422015-02-13 03:41:46 -050079 stack2 = self.client.stacks.get(stack_identifier2)
Zane Bitter015fb6e2016-06-06 17:06:19 -040080 except exceptions.StackBuildErrorException:
81 LOG.exception("Halting test due to bug: #1382300")
Steve Baker50d3e8c2014-10-21 11:08:50 +130082 return
Steve Bakera5bd9122014-08-11 14:39:00 +120083
84 # Verify with cinder that the volume exists, with matching details
85 volume_id2 = self._stack_output(stack2, 'volume_id')
86 self._cinder_verify(volume_id2, expected_status='in-use')
87
88 # Verify the stack outputs are as expected
89 self._outputs_verify(stack2, expected_status='in-use')
90 testfile_data = self._stack_output(stack2, 'testfile_data')
91 self.assertEqual('{"instance1": "Volume Data:ateststring"}',
92 testfile_data)
93
94 # Delete the stack and ensure the volume is gone
Sergey Kraynevbf67ce32015-04-17 10:54:20 -040095 self._stack_delete(stack_identifier2)
Steve Bakera5bd9122014-08-11 14:39:00 +120096 self.assertRaises(cinder_exceptions.NotFound,
97 self.volume_client.volumes.get,
98 volume_id2)
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +040099
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +0400100 def test_cinder_volume_create_backup_restore(self):
Peter Razumovskyf0ac9582015-09-24 16:49:03 +0300101 """Ensure the 'Snapshot' deletion policy works.
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +0400102
103 This requires a more complex test, but it tests several aspects
104 of the heat cinder resources:
105 1. Create a volume, attach it to an instance, write some data to it
106 2. Delete the stack, with 'Snapshot' specified, creates a backup
107 3. Check the snapshot has created a volume backup
108 4. Create a new stack, where the volume is created from the backup
109 5. Verify the test data written in (1) is present in the new volume
110 """
111 parameters = {
112 'key_name': self.keypair_name,
Pavlo Shchelokovskyy46e5cb22015-03-23 12:01:25 +0000113 'instance_type': self.conf.minimal_instance_type,
Anastasia Kuznetsovae45bfff2015-02-25 12:50:34 +0400114 'image_id': self.conf.minimal_image_ref,
115 'volume_description': self.volume_description,
116 'timeout': self.conf.build_timeout,
117 'network': self.net['id']
118 }
119
120 # Launch stack
121 stack_id = self.launch_stack(
122 template_name='test_volumes_delete_snapshot.yaml',
123 parameters=parameters,
124 add_parameters={'volume_size': self.volume_size}
125 )
126
127 # Check stack
128 self.check_stack(stack_id)