blob: a60ffb08f957fda42c97e49d9f27bdcbc37703c7 [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
13import logging
Steve Bakera5bd9122014-08-11 14:39:00 +120014
15from cinderclient import exceptions as cinder_exceptions
Pavlo Shchelokovskyy60e0ecd2014-12-14 22:17:21 +020016import six
17from testtools import testcase
Steve Bakera5bd9122014-08-11 14:39:00 +120018
Steve Baker50d3e8c2014-10-21 11:08:50 +130019from heat_integrationtests.common import exceptions
Steve Bakera5bd9122014-08-11 14:39:00 +120020from heat_integrationtests.common import test
21
22LOG = logging.getLogger(__name__)
23
24
25class VolumeBackupRestoreIntegrationTest(test.HeatIntegrationTest):
26
27 def setUp(self):
28 super(VolumeBackupRestoreIntegrationTest, self).setUp()
29 self.client = self.orchestration_client
Sergey Krayneva265c132015-02-13 03:51:03 -050030 self.assign_keypair()
Steve Bakera5bd9122014-08-11 14:39:00 +120031 self.volume_description = 'A test volume description 123'
32 self.volume_size = self.conf.volume_size
33
34 def _cinder_verify(self, volume_id, expected_status='available'):
35 self.assertIsNotNone(volume_id)
36 volume = self.volume_client.volumes.get(volume_id)
37 self.assertIsNotNone(volume)
38 self.assertEqual(expected_status, volume.status)
39 self.assertEqual(self.volume_size, volume.size)
40 self.assertEqual(self.volume_description,
41 volume.display_description)
42
43 def _outputs_verify(self, stack, expected_status='available'):
44 self.assertEqual(expected_status,
45 self._stack_output(stack, 'status'))
46 self.assertEqual(six.text_type(self.volume_size),
47 self._stack_output(stack, 'size'))
48 self.assertEqual(self.volume_description,
49 self._stack_output(stack, 'display_description'))
50
Sergey Kraynevef9d8422015-02-13 03:41:46 -050051 def launch_stack(self, template_name, add_parameters={}):
Steve Bakera5bd9122014-08-11 14:39:00 +120052 net = self._get_default_network()
Sergey Kraynevd6fa5c02015-02-13 03:03:55 -050053 template = self._load_template(__file__, template_name, 'templates')
Steve Bakera5bd9122014-08-11 14:39:00 +120054 parameters = {'key_name': self.keypair_name,
55 'instance_type': self.conf.instance_type,
56 'image_id': self.conf.minimal_image_ref,
57 'volume_description': self.volume_description,
58 'timeout': self.conf.build_timeout,
59 'network': net['id']}
60 parameters.update(add_parameters)
Sergey Kraynevef9d8422015-02-13 03:41:46 -050061 return self.stack_create(template=template,
62 parameters=parameters)
Steve Bakera5bd9122014-08-11 14:39:00 +120063
Peter Razumovsky986ff142014-11-25 19:11:31 +030064 @testcase.skip('Skipped until failure rate '
65 'can be reduced ref bug #1382300')
Steve Bakera5bd9122014-08-11 14:39:00 +120066 def test_cinder_volume_create_backup_restore(self):
67 """Ensure the 'Snapshot' deletion policy works.
68
69 This requires a more complex test, but it tests several aspects
70 of the heat cinder resources:
71 1. Create a volume, attach it to an instance, write some data to it
72 2. Delete the stack, with 'Snapshot' specified, creates a backup
73 3. Check the snapshot has created a volume backup
74 4. Create a new stack, where the volume is created from the backup
75 5. Verify the test data written in (1) is present in the new volume
76 """
Sergey Kraynevef9d8422015-02-13 03:41:46 -050077 stack_identifier = self.launch_stack(
Steve Bakera5bd9122014-08-11 14:39:00 +120078 template_name='test_volumes_delete_snapshot.yaml',
79 add_parameters={'volume_size': self.volume_size})
80
Sergey Kraynevef9d8422015-02-13 03:41:46 -050081 stack = self.client.stacks.get(stack_identifier)
82
Steve Bakera5bd9122014-08-11 14:39:00 +120083 # Verify with cinder that the volume exists, with matching details
84 volume_id = self._stack_output(stack, 'volume_id')
85 self._cinder_verify(volume_id, expected_status='in-use')
86
87 # Verify the stack outputs are as expected
88 self._outputs_verify(stack, expected_status='in-use')
89
90 # Delete the stack and ensure a backup is created for volume_id
91 # but the volume itself is gone
92 self.client.stacks.delete(stack_identifier)
93 self._wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE')
94 self.assertRaises(cinder_exceptions.NotFound,
95 self.volume_client.volumes.get,
96 volume_id)
97
98 backups = self.volume_client.backups.list()
99 self.assertIsNotNone(backups)
100 backups_filtered = [b for b in backups if b.volume_id == volume_id]
101 self.assertEqual(1, len(backups_filtered))
102 backup = backups_filtered[0]
103 self.addCleanup(self.volume_client.backups.delete, backup.id)
104
105 # Now, we create another stack where the volume is created from the
106 # backup created by the previous stack
Steve Baker50d3e8c2014-10-21 11:08:50 +1300107 try:
Sergey Kraynevef9d8422015-02-13 03:41:46 -0500108 stack_identifier2 = self.launch_stack(
Steve Baker50d3e8c2014-10-21 11:08:50 +1300109 template_name='test_volumes_create_from_backup.yaml',
110 add_parameters={'backup_id': backup.id})
Sergey Kraynevef9d8422015-02-13 03:41:46 -0500111 stack2 = self.client.stacks.get(stack_identifier2)
Steve Baker50d3e8c2014-10-21 11:08:50 +1300112 except exceptions.StackBuildErrorException as e:
113 LOG.error("Halting test due to bug: #1382300")
114 LOG.exception(e)
115 return
Steve Bakera5bd9122014-08-11 14:39:00 +1200116
117 # Verify with cinder that the volume exists, with matching details
118 volume_id2 = self._stack_output(stack2, 'volume_id')
119 self._cinder_verify(volume_id2, expected_status='in-use')
120
121 # Verify the stack outputs are as expected
122 self._outputs_verify(stack2, expected_status='in-use')
123 testfile_data = self._stack_output(stack2, 'testfile_data')
124 self.assertEqual('{"instance1": "Volume Data:ateststring"}',
125 testfile_data)
126
127 # Delete the stack and ensure the volume is gone
128 self.client.stacks.delete(stack_identifier2)
129 self._wait_for_stack_status(stack_identifier2, 'DELETE_COMPLETE')
130 self.assertRaises(cinder_exceptions.NotFound,
131 self.volume_client.volumes.get,
132 volume_id2)