895 lines
30 KiB
Python
895 lines
30 KiB
Python
# Copyright 2013 Mirantis, Inc.
|
|
|
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
|
# not use this file except in compliance with the License. You may obtain
|
|
# a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
# License for the specific language governing permissions and limitations
|
|
# under the License.
|
|
|
|
import logging
|
|
|
|
from fuel_health import heatmanager
|
|
|
|
|
|
LOG = logging.getLogger(__name__)
|
|
|
|
|
|
class HeatSmokeTests(heatmanager.HeatBaseTest):
|
|
"""Test class verifies Heat API calls, rollback and
|
|
autoscaling use-cases.
|
|
"""
|
|
def setUp(self):
|
|
super(HeatSmokeTests, self).setUp()
|
|
if not self.config.compute.compute_nodes:
|
|
self.skipTest('There are no compute nodes')
|
|
self.min_required_ram_mb = 7000
|
|
|
|
def test_advanced_actions(self):
|
|
"""Advanced stack actions: suspend, resume and check
|
|
Target component: Heat
|
|
|
|
Scenario:
|
|
1. Create test flavor.
|
|
2. Create a stack.
|
|
3. Wait until the stack status will change to 'CREATE_COMPLETE'.
|
|
4. Call stack suspend action.
|
|
5. Wait until the stack status will change to 'SUSPEND_COMPLETE'.
|
|
6. Check that stack resources are in 'SUSPEND_COMPLETE' status.
|
|
7. Check that server owned by stack is in 'SUSPENDED' status.
|
|
8. Call stack resume action.
|
|
9. Wait until the stack status will change to 'RESUME_COMPLETE'.
|
|
10. Check that stack resources are in 'RESUME_COMPLETE' status.
|
|
11. Check that instance owned by stack is in 'ACTIVE' status.
|
|
12. Call stack check action.
|
|
13. Wait until the stack status will change to 'CHECK_COMPLETE'.
|
|
14. Check that stack resources are in 'CHECK_COMPLETE' status.
|
|
15. Check that instance owned by stack is in 'ACTIVE' status.
|
|
16. Delete the stack and wait for the stack to be deleted.
|
|
|
|
Duration: 900 s.
|
|
Available since release: 2014.2-6.1
|
|
"""
|
|
|
|
self.check_image_exists()
|
|
|
|
# create test flavor
|
|
fail_msg = 'Test flavor was not created.'
|
|
heat_flavor = self.verify(
|
|
60, self.create_flavor,
|
|
1, fail_msg,
|
|
'flavor creation'
|
|
)
|
|
|
|
# define stack parameters
|
|
parameters = {
|
|
'InstanceType': heat_flavor.name,
|
|
'ImageId': self.config.compute.image_name
|
|
}
|
|
if 'neutron' in self.config.network.network_provider:
|
|
parameters['network'], _ = self.create_network_resources()
|
|
template = self.load_template(
|
|
'heat_create_neutron_stack_template.yaml')
|
|
else:
|
|
template = self.load_template(
|
|
'heat_create_nova_stack_template.yaml')
|
|
|
|
# create stack
|
|
fail_msg = 'Stack was not created properly.'
|
|
stack = self.verify(
|
|
90, self.create_stack,
|
|
2, fail_msg,
|
|
'stack creation',
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
420, self.wait_for_stack_status,
|
|
3, fail_msg,
|
|
'stack status becoming "CREATE_COMPLETE"',
|
|
stack.id, 'CREATE_COMPLETE'
|
|
)
|
|
res = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)
|
|
|
|
# suspend stack
|
|
fail_msg = 'Stack suspend failed.'
|
|
self.verify(
|
|
10, self.heat_client.actions.suspend,
|
|
4, fail_msg,
|
|
'executing suspend stack action',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
90, self.wait_for_stack_status,
|
|
5, fail_msg,
|
|
'stack status becoming "SUSPEND_COMPLETE"',
|
|
stack.id, 'SUSPEND_COMPLETE'
|
|
)
|
|
res = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)
|
|
self.verify_response_body_content(
|
|
'SUSPEND_COMPLETE', res[0].resource_status,
|
|
'Stack resource is not in "SUSPEND_COMPLETE" status.', 6
|
|
)
|
|
instance = self.compute_client.servers.get(res[0].physical_resource_id)
|
|
self.verify_response_body_content(
|
|
'SUSPENDED', instance.status,
|
|
'Instance owned by stack is not in "SUSPENDED" status.', 7
|
|
)
|
|
|
|
# resume stack
|
|
fail_msg = 'Stack resume failed.'
|
|
self.verify(
|
|
10, self.heat_client.actions.resume,
|
|
8, fail_msg,
|
|
'executing resume stack action',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
90, self.wait_for_stack_status,
|
|
9, fail_msg,
|
|
'stack status becoming "RESUME_COMPLETE"',
|
|
stack.id, 'RESUME_COMPLETE'
|
|
)
|
|
res = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)
|
|
self.verify_response_body_content(
|
|
'RESUME_COMPLETE', res[0].resource_status,
|
|
'Stack resource is not in "RESUME_COMPLETE".', 10
|
|
)
|
|
instance = self.compute_client.servers.get(res[0].physical_resource_id)
|
|
self.verify_response_body_content(
|
|
'ACTIVE', instance.status,
|
|
'Instance owned by stack is not in "ACTIVE" status.', 11
|
|
)
|
|
|
|
# stack check
|
|
fail_msg = 'Stack check failed.'
|
|
self.verify(
|
|
10, self.heat_client.actions.check,
|
|
12, fail_msg,
|
|
'executing check stack action',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
90, self.wait_for_stack_status,
|
|
13, fail_msg,
|
|
'stack status becoming "CHECK_COMPLETE"',
|
|
stack.id, 'CHECK_COMPLETE'
|
|
)
|
|
res = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)
|
|
self.verify_response_body_content(
|
|
'CHECK_COMPLETE', res[0].resource_status,
|
|
'Stack resource is not in "CHECK_COMPLETE" status', 14
|
|
)
|
|
instance = self.compute_client.servers.get(res[0].physical_resource_id)
|
|
self.verify_response_body_content(
|
|
'ACTIVE', instance.status,
|
|
'Instance owned by stack is not in "ACTIVE" status', 15
|
|
)
|
|
|
|
# delete stack
|
|
fail_msg = 'Cannot delete stack.'
|
|
self.verify(
|
|
10, self.heat_client.stacks.delete,
|
|
16, fail_msg,
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
60, self.wait_for_stack_deleted,
|
|
16, fail_msg,
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
|
|
def test_actions(self):
|
|
"""Typical stack actions: create, delete, show details, etc.
|
|
Target component: Heat
|
|
|
|
Scenario:
|
|
1. Create test flavor.
|
|
2. Create a stack.
|
|
3. Wait for the stack status to change to 'CREATE_COMPLETE'.
|
|
4. Get the details of the created stack by its name.
|
|
5. Get the resources list of the created stack.
|
|
6. Get the details of the stack resource.
|
|
7. Get the events list of the created stack.
|
|
8. Get the details of the stack event.
|
|
9. Get the stack template details.
|
|
10. Delete the stack and wait for the stack to be deleted.
|
|
|
|
Duration: 720 s.
|
|
"""
|
|
|
|
self.check_image_exists()
|
|
|
|
# create test flavor
|
|
fail_msg = 'Test flavor was not created.'
|
|
heat_flavor = self.verify(
|
|
50, self.create_flavor,
|
|
1, fail_msg,
|
|
'flavor creation'
|
|
)
|
|
|
|
# define stack parameters
|
|
parameters = {
|
|
'InstanceType': heat_flavor.name,
|
|
'ImageId': self.config.compute.image_name
|
|
}
|
|
if 'neutron' in self.config.network.network_provider:
|
|
parameters['network'], _ = self.create_network_resources()
|
|
template = self.load_template(
|
|
'heat_create_neutron_stack_template.yaml')
|
|
else:
|
|
template = self.load_template(
|
|
'heat_create_nova_stack_template.yaml')
|
|
|
|
# create stack
|
|
fail_msg = 'Stack was not created properly.'
|
|
stack = self.verify(
|
|
90, self.create_stack,
|
|
2, fail_msg,
|
|
'stack creation',
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
420, self.wait_for_stack_status,
|
|
3, fail_msg,
|
|
'stack status becoming "CREATE_COMPLETE"',
|
|
stack.id, 'CREATE_COMPLETE'
|
|
)
|
|
|
|
# get stack details
|
|
fail_msg = 'Cannot retrieve stack details.'
|
|
details = self.verify(
|
|
20, self.get_stack,
|
|
4, fail_msg,
|
|
'retrieving stack details',
|
|
stack.stack_name
|
|
)
|
|
fail_msg = 'Stack details contain incorrect values.'
|
|
self.verify_response_body_content(
|
|
stack.id, details.id,
|
|
fail_msg, 4
|
|
)
|
|
self.verify_response_body_content(
|
|
self.config.compute.image_name, details.parameters['ImageId'],
|
|
fail_msg, 4
|
|
)
|
|
self.verify_response_body_content(
|
|
'CREATE_COMPLETE', details.stack_status,
|
|
fail_msg, 4
|
|
)
|
|
|
|
# get resources list
|
|
fail_msg = 'Cannot retrieve list of stack resources.'
|
|
resources = self.verify(
|
|
10, self.get_stack_objects,
|
|
5, fail_msg,
|
|
'retrieving list of stack resources',
|
|
self.heat_client.resources,
|
|
stack.id
|
|
)
|
|
self.verify_response_body_content(
|
|
1, len(resources),
|
|
fail_msg, 5
|
|
)
|
|
|
|
# get resource details
|
|
resource_name = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)[0].logical_resource_id
|
|
|
|
fail_msg = 'Cannot retrieve stack resource details.'
|
|
res_details = self.verify(
|
|
10, self.heat_client.resources.get,
|
|
6, fail_msg,
|
|
'retrieving stack resource details',
|
|
stack.id, resource_name
|
|
)
|
|
fail_msg = 'Resource details contain incorrect values.'
|
|
self.verify_response_body_content(
|
|
'CREATE_COMPLETE', res_details.resource_status,
|
|
fail_msg, 6
|
|
)
|
|
self.verify_response_body_content(
|
|
'OS::Nova::Server', res_details.resource_type,
|
|
fail_msg, 6
|
|
)
|
|
|
|
# get events list
|
|
fail_msg = 'Cannot retrieve list of stack events.'
|
|
events = self.verify(
|
|
10, self.get_stack_objects,
|
|
7, fail_msg,
|
|
'retrieving list of stack events',
|
|
self.heat_client.events,
|
|
stack.id
|
|
)
|
|
self.verify_response_body_not_equal(
|
|
0, len(events),
|
|
fail_msg, 7
|
|
)
|
|
|
|
# get event details
|
|
event_id = self.get_stack_objects(
|
|
self.heat_client.events, stack.id,
|
|
key='resource_name', value=resource_name
|
|
)[0].id
|
|
|
|
fail_msg = 'Cannot retrieve stack event details.'
|
|
ev_details = self.verify(
|
|
10, self.heat_client.events.get,
|
|
8, fail_msg,
|
|
'retrieving stack event details',
|
|
stack.id, resource_name, event_id
|
|
)
|
|
fail_msg = 'Event details contain incorrect values.'
|
|
self.verify_response_body_content(
|
|
event_id, ev_details.id,
|
|
fail_msg, 8
|
|
)
|
|
self.verify_response_body_content(
|
|
resource_name, ev_details.logical_resource_id,
|
|
fail_msg, 8
|
|
)
|
|
|
|
# show template
|
|
fail_msg = 'Cannot retrieve template of the stack.'
|
|
act_tpl = self.verify(
|
|
10, self.heat_client.stacks.template,
|
|
9, fail_msg,
|
|
'retrieving stack template',
|
|
stack.id
|
|
)
|
|
self.verify_response_body_content(
|
|
'OS::Nova::Server', act_tpl['resources'][resource_name]['type'],
|
|
fail_msg, 9
|
|
)
|
|
|
|
# delete stack
|
|
fail_msg = 'Can not delete stack.'
|
|
self.verify(
|
|
30, self.heat_client.stacks.delete,
|
|
10, fail_msg,
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
100, self.wait_for_stack_deleted,
|
|
10, fail_msg,
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
|
|
def test_update(self):
|
|
"""Update stack actions: inplace, replace and update whole template
|
|
Target component: Heat
|
|
|
|
Scenario:
|
|
1. Create test flavor.
|
|
2. Create a stack.
|
|
3. Wait for the stack status to change to 'CREATE_COMPLETE'.
|
|
4. Change instance name, execute update stack in-place.
|
|
5. Wait for the stack status to change to 'UPDATE_COMPLETE'.
|
|
6. Check that instance name was changed.
|
|
7. Create one more test flavor.
|
|
8. Change instance flavor to just created and update stack
|
|
(update replace).
|
|
9. Wait for the stack status to change to 'UPDATE_COMPLETE'.
|
|
10. Check that instance flavor was changed.
|
|
11. Change stack template and update it.
|
|
12. Wait for the stack status to change to 'UPDATE_COMPLETE'.
|
|
13. Check that there are only two newly created stack instances.
|
|
14. Delete the stack.
|
|
15. Wait for the stack to be deleted.
|
|
|
|
Duration: 1300 s.
|
|
"""
|
|
|
|
self.check_image_exists()
|
|
|
|
# create test flavor
|
|
fail_msg = 'Test flavor was not created.'
|
|
heat_flavor = self.verify(
|
|
50, self.create_flavor,
|
|
1, fail_msg,
|
|
'flavor creation'
|
|
)
|
|
|
|
# define stack parameters
|
|
parameters = {
|
|
'InstanceType': heat_flavor.name,
|
|
'ImageId': self.config.compute.image_name
|
|
}
|
|
if 'neutron' in self.config.network.network_provider:
|
|
parameters['network'], _ = self.create_network_resources()
|
|
template = self.load_template(
|
|
'heat_create_neutron_stack_template.yaml')
|
|
else:
|
|
template = self.load_template(
|
|
'heat_create_nova_stack_template.yaml')
|
|
|
|
# create stack
|
|
fail_msg = 'Stack was not created properly.'
|
|
stack = self.verify(
|
|
90, self.create_stack,
|
|
2, fail_msg,
|
|
'stack creation',
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
420, self.wait_for_stack_status,
|
|
3, fail_msg,
|
|
'stack status becoming "CREATE_COMPLETE"',
|
|
stack.id, 'CREATE_COMPLETE'
|
|
)
|
|
|
|
fail_msg = 'Can not update stack.'
|
|
|
|
# update inplace
|
|
template = template.replace(
|
|
'name: ost1-test_heat',
|
|
'name: ost1-test_updated'
|
|
)
|
|
|
|
stack = self.verify(
|
|
30, self.update_stack,
|
|
4, fail_msg,
|
|
'updating stack, changing resource name',
|
|
stack.id,
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
100, self.wait_for_stack_status,
|
|
5, fail_msg,
|
|
'stack status becoming "UPDATE_COMPLETE"',
|
|
stack.id, 'UPDATE_COMPLETE'
|
|
)
|
|
|
|
instances = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)
|
|
instance_id = instances[0].physical_resource_id
|
|
new_instance_name = self.compute_client.servers.get(
|
|
instance_id).name
|
|
|
|
self.verify_response_body_content(
|
|
'ost1-test_updated', new_instance_name,
|
|
'Update inplace failed, instance name was not changed', 6
|
|
)
|
|
|
|
# creation of one more flavor, that will be used for 'update replace'
|
|
flavor = self.verify(
|
|
60, self.create_flavor,
|
|
7, 'Test flavor was not created.',
|
|
'flavor creation'
|
|
)
|
|
|
|
# update replace
|
|
parameters['InstanceType'] = flavor.name
|
|
|
|
stack = self.verify(
|
|
30, self.update_stack,
|
|
8, fail_msg,
|
|
'updating stack, changing instance flavor',
|
|
stack.id,
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
150, self.wait_for_stack_status,
|
|
9, fail_msg,
|
|
'stack status becoming "UPDATE_COMPLETE"',
|
|
stack.id, 'UPDATE_COMPLETE'
|
|
)
|
|
instances = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_type', value='OS::Nova::Server'
|
|
)
|
|
instance_id = instances[0].physical_resource_id
|
|
new_instance_flavor = self.compute_client.servers.get(
|
|
instance_id).flavor['id']
|
|
|
|
self.verify_response_body_content(
|
|
flavor.id, new_instance_flavor,
|
|
'Update replace failed, instance flavor was not changed.', 10
|
|
)
|
|
|
|
# update the whole template: one old resource will be deleted and
|
|
# two new resources will be created
|
|
|
|
parameters = {
|
|
'InstanceType': heat_flavor.name,
|
|
'ImageId': self.config.compute.image_name
|
|
}
|
|
if 'neutron' in self.config.network.network_provider:
|
|
parameters['network'], _ = self.create_network_resources()
|
|
template = self.load_template(
|
|
'heat_update_neutron_stack_template.yaml')
|
|
else:
|
|
template = self.load_template(
|
|
'heat_update_nova_stack_template.yaml')
|
|
|
|
stack = self.verify(
|
|
30, self.update_stack,
|
|
11, fail_msg,
|
|
'updating stack, changing template',
|
|
stack.id,
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
300, self.wait_for_stack_status,
|
|
12, fail_msg,
|
|
'stack status becoming "UPDATE_COMPLETE"',
|
|
stack.id, 'UPDATE_COMPLETE'
|
|
)
|
|
|
|
instances = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id
|
|
)
|
|
self.verify(
|
|
2, self.assertTrue,
|
|
13, 'Number of instances belonging to stack is not equal 2.',
|
|
'verifying the number of instances after template update',
|
|
len(instances) == 2
|
|
)
|
|
|
|
if instance_id in [ins.physical_resource_id for ins in instances]:
|
|
self.fail('Failed step: 13. Previously create instance '
|
|
'was not deleted during stack update.')
|
|
|
|
# delete stack
|
|
fail_msg = 'Can not delete stack.'
|
|
self.verify(
|
|
30, self.heat_client.stacks.delete,
|
|
14, fail_msg,
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
100, self.wait_for_stack_deleted,
|
|
15, fail_msg,
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
|
|
def test_autoscaling(self):
|
|
"""Check stack autoscaling
|
|
Target component: Heat
|
|
|
|
Scenario:
|
|
1. Create test flavor.
|
|
2. Create a keypair.
|
|
3. Save generated private key to file on Controller node.
|
|
4. Create a security group.
|
|
5. Create a stack.
|
|
6. Wait for the stack status to change to 'CREATE_COMPLETE'.
|
|
7. Create a floating IP.
|
|
8. Assign the floating IP to the instance of the stack.
|
|
9. Wait when the instance is ready to connect.
|
|
10. Wait for the 2nd instance to be launched.
|
|
11. Wait for the 2nd instance to be terminated.
|
|
12. Delete the file with private key.
|
|
13. Delete the stack.
|
|
14. Wait for the stack to be deleted.
|
|
|
|
Duration: 2200 s.
|
|
Deployment tags: Ceilometer
|
|
"""
|
|
|
|
self.check_image_exists()
|
|
|
|
self.check_required_resources(self.min_required_ram_mb)
|
|
|
|
# creation of test flavor
|
|
heat_flavor = self.verify(
|
|
50, self.create_flavor,
|
|
1, 'Test flavor can not be created.',
|
|
'flavor creation'
|
|
)
|
|
|
|
# creation of test keypair
|
|
keypair = self.verify(
|
|
10, self._create_keypair,
|
|
2, 'Keypair can not be created.',
|
|
'keypair creation',
|
|
self.compute_client
|
|
)
|
|
path_to_key = self.verify(
|
|
10, self.save_key_to_file,
|
|
3, 'Private key can not be saved to file.',
|
|
'saving private key to the file',
|
|
keypair.private_key
|
|
)
|
|
|
|
# creation of test security group
|
|
sec_group = self.verify(
|
|
60, self._create_security_group,
|
|
4, 'Security group can not be created.',
|
|
'security group creation',
|
|
self.compute_client, 'ost1_test-sgroup'
|
|
)
|
|
|
|
# definition of stack parameters
|
|
parameters = {
|
|
'KeyName': keypair.name,
|
|
'InstanceType': heat_flavor.name,
|
|
'ImageId': self.config.compute.image_name,
|
|
'SecurityGroup': sec_group.name
|
|
}
|
|
|
|
if 'neutron' in self.config.network.network_provider:
|
|
parameters['Net'], _ = self.create_network_resources()
|
|
template = self.load_template('heat_autoscaling_neutron.yaml')
|
|
else:
|
|
template = self.load_template('heat_autoscaling_nova.yaml')
|
|
|
|
# creation of stack
|
|
fail_msg = 'Stack was not created properly.'
|
|
stack = self.verify(
|
|
60, self.create_stack,
|
|
5, fail_msg,
|
|
'stack creation',
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
600, self.wait_for_stack_status,
|
|
6, fail_msg,
|
|
'stack status becoming "CREATE_COMPLETE"',
|
|
stack.id, 'CREATE_COMPLETE', 600, 15
|
|
)
|
|
|
|
reduced_stack_name = '{0}-{1}'.format(
|
|
stack.stack_name[:2], stack.stack_name[-4:])
|
|
|
|
instances = self.get_instances_by_name_mask(reduced_stack_name)
|
|
self.verify(
|
|
2, self.assertTrue,
|
|
6, 'Instance for the stack was not created.',
|
|
'verifying the number of instances after template update',
|
|
len(instances) != 0
|
|
)
|
|
|
|
# assigning floating ip
|
|
floating_ip = self.verify(
|
|
10, self._create_floating_ip,
|
|
7, 'Floating IP can not be created.',
|
|
'floating IP creation'
|
|
)
|
|
self.verify(
|
|
20, self._assign_floating_ip_to_instance,
|
|
8, 'Floating IP can not be assigned.',
|
|
'assigning floating IP',
|
|
self.compute_client, instances[0], floating_ip
|
|
)
|
|
|
|
# vm connection check
|
|
vm_connection = ('ssh -o StrictHostKeyChecking=no -i {0} {1}@{2}'.
|
|
format(path_to_key, 'cirros', floating_ip.ip))
|
|
|
|
self.verify(
|
|
120, self.wait_for_vm_ready_for_load,
|
|
9, 'VM is not ready or connection can not be established.',
|
|
'test script execution on VM',
|
|
vm_connection, 120, 15
|
|
)
|
|
|
|
# launching the second instance during autoscaling
|
|
self.verify(
|
|
1500, self.wait_for_autoscaling,
|
|
10, 'Failed to launch the 2nd instance per autoscaling alarm.',
|
|
'launching the new instance per autoscaling alarm',
|
|
len(instances) + 2, 1500, 10, reduced_stack_name
|
|
)
|
|
|
|
# termination of the second instance during autoscaling
|
|
self.verify(
|
|
1500, self.wait_for_autoscaling,
|
|
11, 'Failed to terminate the 2nd instance per autoscaling alarm.',
|
|
'terminating the 2nd instance per autoscaling alarm',
|
|
len(instances) + 1, 1500, 10, reduced_stack_name
|
|
)
|
|
|
|
# deletion of file with keypair from vm
|
|
self.verify(
|
|
10, self.delete_key_file,
|
|
12, 'The file with private key can not be deleted.',
|
|
'deleting the file with private key',
|
|
path_to_key
|
|
)
|
|
|
|
# deletion of stack
|
|
self.verify(
|
|
20, self.heat_client.stacks.delete,
|
|
13, 'Can not delete stack.',
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
100, self.wait_for_stack_deleted,
|
|
14, 'Can not delete stack.',
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
|
|
def test_rollback(self):
|
|
"""Check stack rollback
|
|
Target component: Heat
|
|
|
|
Scenario:
|
|
1. Create extra large flavor.
|
|
2. Start stack creation with rollback enabled.
|
|
3. Verify the stack appears with status 'CREATE_IN_PROGRESS'.
|
|
4. Wait for the stack to be deleted in result of rollback after
|
|
expiration of timeout defined in WaitHandle resource
|
|
of the stack.
|
|
5. Verify the instance of the stack has been deleted.
|
|
|
|
Duration: 470 s.
|
|
"""
|
|
self.check_image_exists()
|
|
|
|
# create test flavor
|
|
fail_msg = 'Test flavor was not created.'
|
|
large_flavor = self.verify(
|
|
50, self.create_flavor,
|
|
1, fail_msg,
|
|
'flavor creation',
|
|
ram=1048576
|
|
)
|
|
|
|
parameters = {
|
|
'InstanceType': large_flavor.name,
|
|
'ImageId': self.config.compute.image_name
|
|
}
|
|
if 'neutron' in self.config.network.network_provider:
|
|
parameters['network'], _ = self.create_network_resources()
|
|
template = self.load_template(
|
|
'heat_create_neutron_stack_template.yaml')
|
|
else:
|
|
template = self.load_template(
|
|
'heat_create_nova_stack_template.yaml')
|
|
|
|
fail_msg = 'Stack creation was not started.'
|
|
stack = self.verify(
|
|
90, self.create_stack,
|
|
2, fail_msg,
|
|
'starting stack creation',
|
|
template, disable_rollback=False, parameters=parameters
|
|
)
|
|
|
|
self.verify_response_body_content(
|
|
'CREATE_IN_PROGRESS', stack.stack_status,
|
|
fail_msg, 3
|
|
)
|
|
self.verify(
|
|
420, self.wait_for_stack_deleted,
|
|
4, 'Rollback of the stack failed.',
|
|
'rolling back the stack after its creation failed',
|
|
stack.id
|
|
)
|
|
|
|
instances = self.get_stack_objects(
|
|
self.heat_client.resources, stack.id,
|
|
key='resource_name', value='OS::Nova::Server'
|
|
)
|
|
|
|
fail_msg = 'The stack instance rollback failed.'
|
|
self.verify(
|
|
30, self.assertTrue,
|
|
5, fail_msg,
|
|
'verifying if the instance was rolled back',
|
|
len(instances) == 0
|
|
)
|
|
|
|
def test_wait_condition(self):
|
|
"""Check creation of stack with Wait Condition/Handle resources
|
|
Target component: Heat
|
|
|
|
Scenario:
|
|
1. Create test flavor.
|
|
2. Create a keypair.
|
|
3. Save generated private key to file on Controller node.
|
|
4. Create a stack using template.
|
|
5. Wait for the stack status to change to 'CREATE_COMPLETE'.
|
|
6. Delete the file with private key.
|
|
7. Delete the stack.
|
|
8. Wait for the stack to be deleted.
|
|
|
|
Duration: 820 s.
|
|
Available since release: 2015.1.0-8.0
|
|
"""
|
|
|
|
self.check_image_exists()
|
|
|
|
self.check_required_resources(self.min_required_ram_mb)
|
|
|
|
# creation of test flavor
|
|
heat_flavor = self.verify(
|
|
50, self.create_flavor,
|
|
1, 'Test flavor can not be created.',
|
|
'flavor creation'
|
|
)
|
|
|
|
# creation of test keypair
|
|
keypair = self.verify(
|
|
10, self._create_keypair,
|
|
2, 'Keypair can not be created.',
|
|
'keypair creation',
|
|
self.compute_client
|
|
)
|
|
path_to_key = self.verify(
|
|
10, self.save_key_to_file,
|
|
3, 'Private key can not be saved to file.',
|
|
'saving private key to the file',
|
|
keypair.private_key
|
|
)
|
|
|
|
# definition of stack parameters
|
|
parameters = {
|
|
'key_name': keypair.name,
|
|
'flavor': heat_flavor.name,
|
|
'image': self.config.compute.image_name,
|
|
}
|
|
|
|
if 'neutron' in self.config.network.network_provider:
|
|
private, public = self.create_network_resources()
|
|
parameters['net'], parameters['floating_net'] = private, public
|
|
template = self.load_template('heat_wait_condition_neutron.yaml')
|
|
else:
|
|
template = self.load_template('heat_wait_condition_nova.yaml')
|
|
|
|
# creation of stack
|
|
fail_msg = 'Stack was not created properly.'
|
|
stack = self.verify(
|
|
60, self.create_stack,
|
|
4, fail_msg,
|
|
'stack creation',
|
|
template, parameters=parameters
|
|
)
|
|
self.verify(
|
|
600, self.wait_for_stack_status,
|
|
5, fail_msg,
|
|
'stack status becoming "CREATE_COMPLETE"',
|
|
stack.id, 'CREATE_COMPLETE', 600, 15
|
|
)
|
|
|
|
# deletion of file with keypair from vm
|
|
self.verify(
|
|
10, self.delete_key_file,
|
|
6, 'The file with private key can not be deleted.',
|
|
'deleting the file with private key',
|
|
path_to_key
|
|
)
|
|
|
|
# deletion of stack
|
|
self.verify(
|
|
20, self.heat_client.stacks.delete,
|
|
7, 'Can not delete stack.',
|
|
'deleting stack',
|
|
stack.id
|
|
)
|
|
self.verify(
|
|
100, self.wait_for_stack_deleted,
|
|
8, 'Can not delete stack.',
|
|
'deleting stack',
|
|
stack.id
|
|
)
|