diff --git a/releasenotes/notes/remove-heat-tests-9efb42cac3e0b306.yaml b/releasenotes/notes/remove-heat-tests-9efb42cac3e0b306.yaml new file mode 100644 index 0000000000..4d0f3ce067 --- /dev/null +++ b/releasenotes/notes/remove-heat-tests-9efb42cac3e0b306.yaml @@ -0,0 +1,4 @@ +--- +upgrade: + - The Heat API tests have been removed from tempest, they were unmaintained. + The future direction of api test for heat is their in-tree Gabbi tests diff --git a/tempest/api/orchestration/__init__.py b/tempest/api/orchestration/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py deleted file mode 100644 index d9d8017872..0000000000 --- a/tempest/api/orchestration/base.py +++ /dev/null @@ -1,169 +0,0 @@ -# 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 os.path - -import yaml - -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib.common.utils import test_utils -import tempest.test - -CONF = config.CONF - - -class BaseOrchestrationTest(tempest.test.BaseTestCase): - """Base test case class for all Orchestration API tests.""" - - credentials = ['primary'] - - @classmethod - def skip_checks(cls): - super(BaseOrchestrationTest, cls).skip_checks() - if not CONF.service_available.heat: - raise cls.skipException("Heat support is required") - - @classmethod - def setup_credentials(cls): - super(BaseOrchestrationTest, cls).setup_credentials() - stack_owner_role = CONF.orchestration.stack_owner_role - cls.os = cls.get_client_manager(roles=[stack_owner_role]) - - @classmethod - def setup_clients(cls): - super(BaseOrchestrationTest, cls).setup_clients() - cls.orchestration_client = cls.os_primary.orchestration_client - cls.client = cls.orchestration_client - cls.servers_client = cls.os_primary.servers_client - cls.keypairs_client = cls.os_primary.keypairs_client - cls.networks_client = cls.os_primary.networks_client - cls.images_v2_client = cls.os_primary.image_client_v2 - cls.volumes_client = cls.os_primary.volumes_v2_client - - @classmethod - def resource_setup(cls): - super(BaseOrchestrationTest, cls).resource_setup() - cls.build_timeout = CONF.orchestration.build_timeout - cls.build_interval = CONF.orchestration.build_interval - cls.stacks = [] - cls.keypairs = [] - cls.images = [] - - @classmethod - def create_stack(cls, stack_name, template_data, parameters=None, - environment=None, files=None): - if parameters is None: - parameters = {} - body = cls.client.create_stack( - stack_name, - template=template_data, - parameters=parameters, - environment=environment, - files=files) - stack_id = body.response['location'].split('/')[-1] - stack_identifier = '%s/%s' % (stack_name, stack_id) - cls.stacks.append(stack_identifier) - return stack_identifier - - @classmethod - def _clear_stacks(cls): - for stack_identifier in cls.stacks: - test_utils.call_and_ignore_notfound_exc( - cls.client.delete_stack, stack_identifier) - - for stack_identifier in cls.stacks: - test_utils.call_and_ignore_notfound_exc( - cls.client.wait_for_stack_status, stack_identifier, - 'DELETE_COMPLETE') - - @classmethod - def _create_keypair(cls, name_start='keypair-heat-'): - kp_name = data_utils.rand_name(name_start) - body = cls.keypairs_client.create_keypair(name=kp_name)['keypair'] - cls.keypairs.append(kp_name) - return body - - @classmethod - def _clear_keypairs(cls): - for kp_name in cls.keypairs: - try: - cls.keypairs_client.delete_keypair(kp_name) - except Exception: - pass - - @classmethod - def _create_image(cls, name_start='image-heat-', container_format='bare', - disk_format='iso'): - image_name = data_utils.rand_name(name_start) - body = cls.images_v2_client.create_image(image_name, - container_format, - disk_format) - image_id = body['id'] - cls.images.append(image_id) - return body - - @classmethod - def _clear_images(cls): - for image_id in cls.images: - test_utils.call_and_ignore_notfound_exc( - cls.images_v2_client.delete_image, image_id) - - @classmethod - def read_template(cls, name, ext='yaml'): - loc = ["stacks", "templates", "%s.%s" % (name, ext)] - fullpath = os.path.join(os.path.dirname(__file__), *loc) - - with open(fullpath, "r") as f: - content = f.read() - return content - - @classmethod - def load_template(cls, name, ext='yaml'): - loc = ["stacks", "templates", "%s.%s" % (name, ext)] - fullpath = os.path.join(os.path.dirname(__file__), *loc) - - with open(fullpath, "r") as f: - return yaml.safe_load(f) - - @classmethod - def resource_cleanup(cls): - cls._clear_stacks() - cls._clear_keypairs() - cls._clear_images() - super(BaseOrchestrationTest, cls).resource_cleanup() - - @staticmethod - def stack_output(stack, output_key): - """Return a stack output value for a given key.""" - return next((o['output_value'] for o in stack['outputs'] - if o['output_key'] == output_key), None) - - def assert_fields_in_dict(self, obj, *fields): - for field in fields: - self.assertIn(field, obj) - - def list_resources(self, stack_identifier): - """Get a dict mapping of resource names to types.""" - resources = self.client.list_resources(stack_identifier)['resources'] - self.assertIsInstance(resources, list) - for res in resources: - self.assert_fields_in_dict(res, 'logical_resource_id', - 'resource_type', 'resource_status', - 'updated_time') - - return dict((r['resource_name'], r['resource_type']) - for r in resources) - - def get_stack_output(self, stack_identifier, output_key): - body = self.client.show_stack(stack_identifier)['stack'] - return self.stack_output(body, output_key) diff --git a/tempest/api/orchestration/stacks/__init__.py b/tempest/api/orchestration/stacks/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/tempest/api/orchestration/stacks/templates/cinder_basic.yaml b/tempest/api/orchestration/stacks/templates/cinder_basic.yaml deleted file mode 100644 index 61c271c6c5..0000000000 --- a/tempest/api/orchestration/stacks/templates/cinder_basic.yaml +++ /dev/null @@ -1,33 +0,0 @@ -heat_template_version: 2013-05-23 - -parameters: - volume_size: - type: number - default: 1 - -resources: - volume: - type: OS::Cinder::Volume - properties: - size: { get_param: volume_size } - description: a descriptive description - name: volume_name - -outputs: - status: - description: status - value: { get_attr: ['volume', 'status'] } - - size: - description: size - value: { get_attr: ['volume', 'size'] } - - display_description: - description: display_description - value: { get_attr: ['volume', 'display_description'] } - - display_name: - value: { get_attr: ['volume', 'display_name'] } - - volume_id: - value: { get_resource: volume } diff --git a/tempest/api/orchestration/stacks/templates/cinder_basic_delete_retain.yaml b/tempest/api/orchestration/stacks/templates/cinder_basic_delete_retain.yaml deleted file mode 100644 index 0bc6d69af5..0000000000 --- a/tempest/api/orchestration/stacks/templates/cinder_basic_delete_retain.yaml +++ /dev/null @@ -1,34 +0,0 @@ -heat_template_version: 2013-05-23 - -parameters: - volume_size: - type: number - default: 1 - -resources: - volume: - deletion_policy: 'Retain' - type: OS::Cinder::Volume - properties: - size: { get_param: volume_size } - description: a descriptive description - name: volume_name - -outputs: - status: - description: status - value: { get_attr: ['volume', 'status'] } - - size: - description: size - value: { get_attr: ['volume', 'size'] } - - display_description: - description: display_description - value: { get_attr: ['volume', 'display_description'] } - - display_name: - value: { get_attr: ['volume', 'display_name'] } - - volume_id: - value: { get_resource: volume } diff --git a/tempest/api/orchestration/stacks/templates/neutron_basic.yaml b/tempest/api/orchestration/stacks/templates/neutron_basic.yaml deleted file mode 100644 index ccb1b54c9a..0000000000 --- a/tempest/api/orchestration/stacks/templates/neutron_basic.yaml +++ /dev/null @@ -1,72 +0,0 @@ -heat_template_version: '2013-05-23' -description: | - Template which creates single EC2 instance -parameters: - KeyName: - type: string - InstanceType: - type: string - ImageId: - type: string - SubNetCidr: - type: string - ExternalNetworkId: - type: string - DNSServers: - type: comma_delimited_list - timeout: - type: number -resources: - Network: - type: OS::Neutron::Net - properties: - name: NewNetwork - Subnet: - type: OS::Neutron::Subnet - properties: - network_id: {Ref: Network} - name: NewSubnet - ip_version: 4 - cidr: { get_param: SubNetCidr } - dns_nameservers: { get_param: DNSServers } - Router: - type: OS::Neutron::Router - properties: - name: NewRouter - admin_state_up: true - external_gateway_info: - network: {get_param: ExternalNetworkId} - RouterInterface: - type: OS::Neutron::RouterInterface - properties: - router_id: {get_resource: Router} - subnet_id: {get_resource: Subnet} - Server: - type: OS::Nova::Server - metadata: - Name: SmokeServerNeutron - properties: - image: {get_param: ImageId} - flavor: {get_param: InstanceType} - key_name: {get_param: KeyName} - networks: - - network: {get_resource: Network} - user_data_format: RAW - user_data: - str_replace: - template: | - #!/bin/sh -v - - SIGNAL_DATA='{"Status": "SUCCESS", "Reason": "SmokeServerNeutron created", "Data": "Application has completed configuration.", "UniqueId": "00000"}' - while ! curl --insecure --fail -X PUT -H 'Content-Type:' --data-binary "$SIGNAL_DATA" \ - 'wait_handle' ; do sleep 3; done - params: - wait_handle: {get_resource: WaitHandleNeutron} - WaitHandleNeutron: - type: AWS::CloudFormation::WaitConditionHandle - WaitCondition: - type: AWS::CloudFormation::WaitCondition - depends_on: Server - properties: - Handle: {get_resource: WaitHandleNeutron} - Timeout: {get_param: timeout} diff --git a/tempest/api/orchestration/stacks/templates/non_empty_stack.yaml b/tempest/api/orchestration/stacks/templates/non_empty_stack.yaml deleted file mode 100644 index 4f9df91eab..0000000000 --- a/tempest/api/orchestration/stacks/templates/non_empty_stack.yaml +++ /dev/null @@ -1,36 +0,0 @@ -HeatTemplateFormatVersion: '2012-12-12' -Description: | - Template which creates some simple resources -Parameters: - trigger: - Type: String - Default: not_yet - image: - Type: String - flavor: - Type: String -Resources: - fluffy: - Type: AWS::AutoScaling::LaunchConfiguration - Metadata: - kittens: - - Tom - - Stinky - Properties: - ImageId: {Ref: image} - InstanceType: {Ref: flavor} - UserData: - Fn::Replace: - - variable_a: {Ref: trigger} - variable_b: bee - - | - A == variable_a - B == variable_b -Outputs: - fluffy: - Description: "fluffies irc nick" - Value: - Fn::Replace: - - nick: {Ref: fluffy} - - | - #nick diff --git a/tempest/api/orchestration/stacks/templates/nova_keypair.json b/tempest/api/orchestration/stacks/templates/nova_keypair.json deleted file mode 100644 index 63d3817f31..0000000000 --- a/tempest/api/orchestration/stacks/templates/nova_keypair.json +++ /dev/null @@ -1,48 +0,0 @@ -{ - "AWSTemplateFormatVersion" : "2010-09-09", - "Description" : "Template which create two key pairs.", - "Parameters" : { - "KeyPairName1": { - "Type": "String", - "Default": "testkey1" - }, - "KeyPairName2": { - "Type": "String", - "Default": "testkey2" - } - }, - "Resources" : { - "KeyPairSavePrivate": { - "Type": "OS::Nova::KeyPair", - "Properties": { - "name" : { "Ref" : "KeyPairName1" }, - "save_private_key": true - } - }, - "KeyPairDontSavePrivate": { - "Type": "OS::Nova::KeyPair", - "Properties": { - "name" : { "Ref" : "KeyPairName2" }, - "save_private_key": false - } - } - }, - "Outputs": { - "KeyPair_PublicKey": { - "Description": "Public Key of generated keypair.", - "Value": { "Fn::GetAtt" : ["KeyPairSavePrivate", "public_key"] } - }, - "KeyPair_PrivateKey": { - "Description": "Private Key of generated keypair.", - "Value": { "Fn::GetAtt" : ["KeyPairSavePrivate", "private_key"] } - }, - "KeyPairDontSavePrivate_PublicKey": { - "Description": "Public Key of generated keypair.", - "Value": { "Fn::GetAtt" : ["KeyPairDontSavePrivate", "public_key"] } - }, - "KeyPairDontSavePrivate_PrivateKey": { - "Description": "Private Key of generated keypair.", - "Value": { "Fn::GetAtt" : ["KeyPairDontSavePrivate", "private_key"] } - } - } -} diff --git a/tempest/api/orchestration/stacks/templates/nova_keypair.yaml b/tempest/api/orchestration/stacks/templates/nova_keypair.yaml deleted file mode 100644 index 81ad99c805..0000000000 --- a/tempest/api/orchestration/stacks/templates/nova_keypair.yaml +++ /dev/null @@ -1,43 +0,0 @@ -heat_template_version: 2013-05-23 - -description: > - Template which creates two key pairs. - -parameters: - KeyPairName1: - type: string - default: testkey - - KeyPairName2: - type: string - default: testkey2 - -resources: - KeyPairSavePrivate: - type: OS::Nova::KeyPair - properties: - name: { get_param: KeyPairName1 } - save_private_key: true - - KeyPairDontSavePrivate: - type: OS::Nova::KeyPair - properties: - name: { get_param: KeyPairName2 } - save_private_key: false - -outputs: - KeyPair_PublicKey: - description: Public Key of generated keypair - value: { get_attr: [KeyPairSavePrivate, public_key] } - - KeyPair_PrivateKey: - description: Private Key of generated keypair - value: { get_attr: [KeyPairSavePrivate, private_key] } - - KeyPairDontSavePrivate_PublicKey: - description: Public Key of generated keypair - value: { get_attr: [KeyPairDontSavePrivate, public_key] } - - KeyPairDontSavePrivate_PrivateKey: - description: Private Key of generated keypair - value: { get_attr: [KeyPairDontSavePrivate, private_key] } diff --git a/tempest/api/orchestration/stacks/templates/random_string.yaml b/tempest/api/orchestration/stacks/templates/random_string.yaml deleted file mode 100644 index dfd23424b6..0000000000 --- a/tempest/api/orchestration/stacks/templates/random_string.yaml +++ /dev/null @@ -1,18 +0,0 @@ -heat_template_version: 2013-05-23 - -parameters: - random_length: - type: number - default: 10 - -resources: - random: - type: OS::Heat::RandomString - properties: - length: {get_param: random_length} - -outputs: - random_length: - value: {get_param: random_length} - random_value: - value: {get_attr: [random, value]} diff --git a/tempest/api/orchestration/stacks/templates/swift_basic.yaml b/tempest/api/orchestration/stacks/templates/swift_basic.yaml deleted file mode 100644 index 713f8bc122..0000000000 --- a/tempest/api/orchestration/stacks/templates/swift_basic.yaml +++ /dev/null @@ -1,23 +0,0 @@ -heat_template_version: 2013-05-23 -description: Template which creates a Swift container resource - -resources: - SwiftContainerWebsite: - deletion_policy: "Delete" - type: OS::Swift::Container - properties: - X-Container-Read: ".r:*" - X-Container-Meta: - web-index: "index.html" - web-error: "error.html" - - SwiftContainer: - type: OS::Swift::Container - -outputs: - WebsiteURL: - description: "URL for website hosted on S3" - value: { get_attr: [SwiftContainer, WebsiteURL] } - DomainName: - description: "Domain of Swift host" - value: { get_attr: [SwiftContainer, DomainName] } diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py deleted file mode 100644 index c8a9aa7343..0000000000 --- a/tempest/api/orchestration/stacks/test_environment.py +++ /dev/null @@ -1,92 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - - -class StackEnvironmentTest(base.BaseOrchestrationTest): - - @decorators.idempotent_id('37d4346b-1abd-4442-b7b1-2a4e5749a1e3') - def test_environment_parameter(self): - """Test passing a stack parameter via the environment.""" - stack_name = data_utils.rand_name('heat') - template = self.read_template('random_string') - environment = {'parameters': {'random_length': 20}} - - stack_identifier = self.create_stack(stack_name, template, - environment=environment) - self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') - - random_len = self.get_stack_output(stack_identifier, 'random_length') - self.assertEqual(20, random_len) - - random_value = self.get_stack_output(stack_identifier, 'random_value') - self.assertEqual(20, len(random_value)) - - @decorators.idempotent_id('73bce717-ad22-4853-bbef-6ed89b632701') - def test_environment_provider_resource(self): - """Test passing resource_registry defining a provider resource.""" - stack_name = data_utils.rand_name('heat') - template = ''' -heat_template_version: 2013-05-23 -resources: - random: - type: My:Random::String -outputs: - random_value: - value: {get_attr: [random, random_value]} -''' - environment = {'resource_registry': - {'My:Random::String': 'my_random.yaml'}} - files = {'my_random.yaml': self.read_template('random_string')} - - stack_identifier = self.create_stack(stack_name, template, - environment=environment, - files=files) - self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') - - # random_string.yaml specifies a length of 10 - random_value = self.get_stack_output(stack_identifier, 'random_value') - random_string_template = self.load_template('random_string') - expected_length = random_string_template['parameters'][ - 'random_length']['default'] - self.assertEqual(expected_length, len(random_value)) - - @decorators.idempotent_id('9d682e5a-f4bb-47d5-8472-9d3cacb855df') - def test_files_provider_resource(self): - """Test untyped defining of a provider resource via "files".""" - # It's also possible to specify the filename directly in the template. - # without adding the type alias to resource_registry - stack_name = data_utils.rand_name('heat') - template = ''' -heat_template_version: 2013-05-23 -resources: - random: - type: my_random.yaml -outputs: - random_value: - value: {get_attr: [random, random_value]} -''' - files = {'my_random.yaml': self.read_template('random_string')} - - stack_identifier = self.create_stack(stack_name, template, - files=files) - self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') - - # random_string.yaml specifies a length of 10 - random_value = self.get_stack_output(stack_identifier, 'random_value') - random_string_template = self.load_template('random_string') - expected_length = random_string_template['parameters'][ - 'random_length']['default'] - self.assertEqual(expected_length, len(random_value)) diff --git a/tempest/api/orchestration/stacks/test_limits.py b/tempest/api/orchestration/stacks/test_limits.py deleted file mode 100644 index 9c9d4f98e9..0000000000 --- a/tempest/api/orchestration/stacks/test_limits.py +++ /dev/null @@ -1,49 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc - -CONF = config.CONF - - -class TestServerStackLimits(base.BaseOrchestrationTest): - - @decorators.idempotent_id('ec9bed71-c460-45c9-ab98-295caa9fd76b') - def test_exceed_max_template_size_fails(self): - stack_name = data_utils.rand_name('heat') - fill = 'A' * CONF.orchestration.max_template_size - template = ''' -HeatTemplateFormatVersion: '2012-12-12' -Description: '%s' -Outputs: - Foo: bar''' % fill - ex = self.assertRaises(lib_exc.BadRequest, self.create_stack, - stack_name, template) - self.assertIn('exceeds maximum allowed size', str(ex)) - - @decorators.idempotent_id('d1b83e73-7cad-4a22-9839-036548c5387c') - def test_exceed_max_resources_per_stack(self): - stack_name = data_utils.rand_name('heat') - # Create a big template, one resource more than the limit - template = 'heat_template_version: \'2013-05-23\'\nresources:\n' - rsrc_snippet = ' random%s:\n type: \'OS::Heat::RandomString\'\n' - num_resources = CONF.orchestration.max_resources_per_stack + 1 - for i in range(num_resources): - template += rsrc_snippet % i - - ex = self.assertRaises(lib_exc.BadRequest, self.create_stack, - stack_name, template) - self.assertIn('Maximum resources per stack exceeded', str(ex)) diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py deleted file mode 100644 index 36881bfbd6..0000000000 --- a/tempest/api/orchestration/stacks/test_neutron_resources.py +++ /dev/null @@ -1,196 +0,0 @@ -# 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 netaddr -from oslo_log import log as logging - -from tempest.api.orchestration import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions -from tempest import test - -CONF = config.CONF - -LOG = logging.getLogger(__name__) - - -class NeutronResourcesTestJSON(base.BaseOrchestrationTest): - - @classmethod - def skip_checks(cls): - super(NeutronResourcesTestJSON, cls).skip_checks() - if not CONF.service_available.neutron: - raise cls.skipException("Neutron support is required") - - @classmethod - def setup_credentials(cls): - cls.set_network_resources() - super(NeutronResourcesTestJSON, cls).setup_credentials() - - @classmethod - def setup_clients(cls): - super(NeutronResourcesTestJSON, cls).setup_clients() - cls.subnets_client = cls.os_primary.subnets_client - cls.ports_client = cls.os_primary.ports_client - cls.routers_client = cls.os_primary.routers_client - - @classmethod - def resource_setup(cls): - super(NeutronResourcesTestJSON, cls).resource_setup() - cls.neutron_basic_template = cls.load_template('neutron_basic') - cls.stack_name = data_utils.rand_name('heat') - template = cls.read_template('neutron_basic') - cls.keypair_name = (CONF.orchestration.keypair_name or - cls._create_keypair()['name']) - cls.external_network_id = CONF.network.public_network_id - - tenant_cidr = netaddr.IPNetwork(CONF.network.project_network_cidr) - mask_bits = CONF.network.project_network_mask_bits - cls.subnet_cidr = tenant_cidr.subnet(mask_bits).next() - - # create the stack - cls.stack_identifier = cls.create_stack( - cls.stack_name, - template, - parameters={ - 'KeyName': cls.keypair_name, - 'InstanceType': CONF.orchestration.instance_type, - 'ImageId': CONF.compute.image_ref, - 'ExternalNetworkId': cls.external_network_id, - 'timeout': CONF.orchestration.build_timeout, - 'DNSServers': CONF.network.dns_servers, - 'SubNetCidr': str(cls.subnet_cidr) - }) - cls.stack_id = cls.stack_identifier.split('/')[1] - try: - cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE') - resources = (cls.client.list_resources(cls.stack_identifier) - ['resources']) - except exceptions.TimeoutException: - if CONF.compute_feature_enabled.console_output: - # attempt to log the server console to help with debugging - # the cause of the server not signalling the waitcondition - # to heat. - body = cls.client.show_resource(cls.stack_identifier, - 'Server') - server_id = body.get('physical_resource_id') - if server_id: - LOG.debug('Console output for %s', server_id) - output = cls.servers_client.get_console_output( - server_id)['output'] - LOG.debug(output) - else: - LOG.debug('Server resource is %s', body) - raise # original exception - - cls.test_resources = {} - for resource in resources: - cls.test_resources[resource['logical_resource_id']] = resource - - @decorators.idempotent_id('f9e2664c-bc44-4eef-98b6-495e4f9d74b3') - def test_created_resources(self): - """Verifies created neutron resources.""" - resources = [('Network', self.neutron_basic_template['resources'][ - 'Network']['type']), - ('Subnet', self.neutron_basic_template['resources'][ - 'Subnet']['type']), - ('RouterInterface', self.neutron_basic_template[ - 'resources']['RouterInterface']['type']), - ('Server', self.neutron_basic_template['resources'][ - 'Server']['type'])] - for resource_name, resource_type in resources: - resource = self.test_resources.get(resource_name, None) - self.assertIsInstance(resource, dict) - self.assertEqual(resource_name, resource['logical_resource_id']) - self.assertEqual(resource_type, resource['resource_type']) - self.assertEqual('CREATE_COMPLETE', resource['resource_status']) - - @decorators.idempotent_id('c572b915-edb1-4e90-b196-c7199a6848c0') - @test.services('network') - def test_created_network(self): - """Verifies created network.""" - network_id = self.test_resources.get('Network')['physical_resource_id'] - body = self.networks_client.show_network(network_id) - network = body['network'] - self.assertIsInstance(network, dict) - self.assertEqual(network_id, network['id']) - self.assertEqual(self.neutron_basic_template['resources'][ - 'Network']['properties']['name'], network['name']) - - @decorators.idempotent_id('e8f84b96-f9d7-4684-ad5f-340203e9f2c2') - @test.services('network') - def test_created_subnet(self): - """Verifies created subnet.""" - subnet_id = self.test_resources.get('Subnet')['physical_resource_id'] - body = self.subnets_client.show_subnet(subnet_id) - subnet = body['subnet'] - network_id = self.test_resources.get('Network')['physical_resource_id'] - self.assertEqual(subnet_id, subnet['id']) - self.assertEqual(network_id, subnet['network_id']) - self.assertEqual(self.neutron_basic_template['resources'][ - 'Subnet']['properties']['name'], subnet['name']) - self.assertEqual(sorted(CONF.network.dns_servers), - sorted(subnet['dns_nameservers'])) - self.assertEqual(self.neutron_basic_template['resources'][ - 'Subnet']['properties']['ip_version'], subnet['ip_version']) - self.assertEqual(str(self.subnet_cidr), subnet['cidr']) - - @decorators.idempotent_id('96af4c7f-5069-44bc-bdcf-c0390f8a67d1') - @test.services('network') - def test_created_router(self): - """Verifies created router.""" - router_id = self.test_resources.get('Router')['physical_resource_id'] - body = self.routers_client.show_router(router_id) - router = body['router'] - self.assertEqual(self.neutron_basic_template['resources'][ - 'Router']['properties']['name'], router['name']) - self.assertEqual(self.external_network_id, - router['external_gateway_info']['network_id']) - self.assertEqual(True, router['admin_state_up']) - - @decorators.idempotent_id('89f605bd-153e-43ee-a0ed-9919b63423c5') - @test.services('network') - def test_created_router_interface(self): - """Verifies created router interface.""" - router_id = self.test_resources.get('Router')['physical_resource_id'] - network_id = self.test_resources.get('Network')['physical_resource_id'] - subnet_id = self.test_resources.get('Subnet')['physical_resource_id'] - body = self.ports_client.list_ports() - ports = body['ports'] - router_ports = filter(lambda port: port['device_id'] == - router_id, ports) - created_network_ports = filter(lambda port: port['network_id'] == - network_id, router_ports) - self.assertEqual(1, len(created_network_ports)) - router_interface = created_network_ports[0] - fixed_ips = router_interface['fixed_ips'] - subnet_fixed_ips = filter(lambda port: port['subnet_id'] == - subnet_id, fixed_ips) - self.assertEqual(1, len(subnet_fixed_ips)) - router_interface_ip = subnet_fixed_ips[0]['ip_address'] - self.assertEqual(str(self.subnet_cidr.iter_hosts().next()), - router_interface_ip) - - @decorators.idempotent_id('75d85316-4ac2-4c0e-a1a9-edd2148fc10e') - @test.services('compute', 'network') - def test_created_server(self): - """Verifies created sever.""" - server_id = self.test_resources.get('Server')['physical_resource_id'] - server = self.servers_client.show_server(server_id)['server'] - self.assertEqual(self.keypair_name, server['key_name']) - self.assertEqual('ACTIVE', server['status']) - network = server['addresses'][self.neutron_basic_template['resources'][ - 'Network']['properties']['name']][0] - self.assertEqual(4, network['version']) - self.assertIn(netaddr.IPAddress(network['addr']), self.subnet_cidr) diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py deleted file mode 100644 index 6b9c88be97..0000000000 --- a/tempest/api/orchestration/stacks/test_non_empty_stack.py +++ /dev/null @@ -1,150 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - -CONF = config.CONF - - -class StacksTestJSON(base.BaseOrchestrationTest): - - @classmethod - def resource_setup(cls): - super(StacksTestJSON, cls).resource_setup() - cls.stack_name = data_utils.rand_name('heat') - template = cls.read_template('non_empty_stack') - image_id = (CONF.compute.image_ref or - cls._create_image()['id']) - flavor = CONF.orchestration.instance_type - # create the stack - cls.stack_identifier = cls.create_stack( - cls.stack_name, - template, - parameters={ - 'trigger': 'start', - 'image': image_id, - 'flavor': flavor - }) - cls.stack_id = cls.stack_identifier.split('/')[1] - cls.resource_name = 'fluffy' - cls.resource_type = 'AWS::AutoScaling::LaunchConfiguration' - cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE') - - def _list_stacks(self, expected_num=None, **filter_kwargs): - stacks = self.client.list_stacks(params=filter_kwargs)['stacks'] - self.assertIsInstance(stacks, list) - if expected_num is not None: - self.assertEqual(expected_num, len(stacks)) - return stacks - - @decorators.idempotent_id('065c652a-720d-4760-9132-06aedeb8e3ab') - def test_stack_list(self): - """Created stack should be in the list of existing stacks.""" - stacks = self._list_stacks() - stacks_names = map(lambda stack: stack['stack_name'], stacks) - self.assertIn(self.stack_name, stacks_names) - - @decorators.idempotent_id('992f96e3-41ee-4ff6-91c7-bcfb670c0919') - def test_stack_show(self): - """Getting details about created stack should be possible.""" - stack = self.client.show_stack(self.stack_name)['stack'] - self.assertIsInstance(stack, dict) - self.assert_fields_in_dict(stack, 'stack_name', 'id', 'links', - 'parameters', 'outputs', 'disable_rollback', - 'stack_status_reason', 'stack_status', - 'creation_time', 'updated_time', - 'capabilities', 'notification_topics', - 'timeout_mins', 'template_description') - self.assert_fields_in_dict(stack['parameters'], 'AWS::StackId', - 'trigger', 'AWS::Region', 'AWS::StackName') - self.assertEqual(True, stack['disable_rollback'], - 'disable_rollback should default to True') - self.assertEqual(self.stack_name, stack['stack_name']) - self.assertEqual(self.stack_id, stack['id']) - self.assertEqual('fluffy', stack['outputs'][0]['output_key']) - - @decorators.idempotent_id('fe719f7a-305a-44d8-bbb5-c91e93d9da17') - def test_suspend_resume_stack(self): - """Suspend and resume a stack.""" - self.client.suspend_stack(self.stack_identifier) - self.client.wait_for_stack_status(self.stack_identifier, - 'SUSPEND_COMPLETE') - self.client.resume_stack(self.stack_identifier) - self.client.wait_for_stack_status(self.stack_identifier, - 'RESUME_COMPLETE') - - @decorators.idempotent_id('c951d55e-7cce-4c1f-83a0-bad735437fa6') - def test_list_resources(self): - """Get list of created resources for the stack should be possible.""" - resources = self.list_resources(self.stack_identifier) - self.assertEqual({self.resource_name: self.resource_type}, resources) - - @decorators.idempotent_id('2aba03b3-392f-4237-900b-1f5a5e9bd962') - def test_show_resource(self): - """Getting details about created resource should be possible.""" - resource = self.client.show_resource(self.stack_identifier, - self.resource_name)['resource'] - self.assertIsInstance(resource, dict) - self.assert_fields_in_dict(resource, 'resource_name', 'description', - 'links', 'logical_resource_id', - 'resource_status', 'updated_time', - 'required_by', 'resource_status_reason', - 'physical_resource_id', 'resource_type') - self.assertEqual(self.resource_name, resource['logical_resource_id']) - self.assertEqual(self.resource_type, resource['resource_type']) - - @decorators.idempotent_id('898070a9-eba5-4fae-b7d6-cf3ffa03090f') - def test_resource_metadata(self): - """Getting metadata for created resources should be possible.""" - metadata = self.client.show_resource_metadata( - self.stack_identifier, - self.resource_name)['metadata'] - self.assertIsInstance(metadata, dict) - self.assertEqual(['Tom', 'Stinky'], metadata.get('kittens', None)) - - @decorators.idempotent_id('46567533-0a7f-483b-8942-fa19e0f17839') - def test_list_events(self): - """Getting list of created events for the stack should be possible.""" - events = self.client.list_events(self.stack_identifier)['events'] - self.assertIsInstance(events, list) - - for event in events: - self.assert_fields_in_dict(event, 'logical_resource_id', 'id', - 'resource_status_reason', - 'resource_status', 'event_time') - - resource_statuses = [event['resource_status'] for event in events] - self.assertIn('CREATE_IN_PROGRESS', resource_statuses) - self.assertIn('CREATE_COMPLETE', resource_statuses) - - @decorators.idempotent_id('92465723-1673-400a-909d-4773757a3f21') - def test_show_event(self): - """Getting details about an event should be possible.""" - events = self.client.list_resource_events(self.stack_identifier, - self.resource_name)['events'] - self.assertNotEqual([], events) - events.sort(key=lambda event: event['event_time']) - event_id = events[0]['id'] - event = self.client.show_event(self.stack_identifier, - self.resource_name, event_id)['event'] - self.assertIsInstance(event, dict) - self.assert_fields_in_dict(event, 'resource_name', 'event_time', - 'links', 'logical_resource_id', - 'resource_status', 'resource_status_reason', - 'physical_resource_id', 'id', - 'resource_properties', 'resource_type') - self.assertEqual(self.resource_name, event['resource_name']) - self.assertEqual('state changed', event['resource_status_reason']) - self.assertEqual(self.resource_name, event['logical_resource_id']) diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py deleted file mode 100644 index a51648fbb9..0000000000 --- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py +++ /dev/null @@ -1,92 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - - -class NovaKeyPairResourcesYAMLTest(base.BaseOrchestrationTest): - _tpl_type = 'yaml' - _resource = 'resources' - _type = 'type' - - @classmethod - def resource_setup(cls): - super(NovaKeyPairResourcesYAMLTest, cls).resource_setup() - cls.stack_name = data_utils.rand_name('heat') - template = cls.read_template('nova_keypair', ext=cls._tpl_type) - - # create the stack, avoid any duplicated key. - cls.stack_identifier = cls.create_stack( - cls.stack_name, - template, - parameters={ - 'KeyPairName1': cls.stack_name + '_1', - 'KeyPairName2': cls.stack_name + '_2' - }) - - cls.stack_id = cls.stack_identifier.split('/')[1] - cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE') - resources = (cls.client.list_resources(cls.stack_identifier) - ['resources']) - cls.test_resources = {} - for resource in resources: - cls.test_resources[resource['logical_resource_id']] = resource - - @decorators.idempotent_id('b476eac2-a302-4815-961f-18c410a2a537') - def test_created_resources(self): - """Verifies created keypair resource.""" - - nova_keypair_template = self.load_template('nova_keypair', - ext=self._tpl_type) - resources = [('KeyPairSavePrivate', - nova_keypair_template[self._resource][ - 'KeyPairSavePrivate'][self._type]), - ('KeyPairDontSavePrivate', - nova_keypair_template[self._resource][ - 'KeyPairDontSavePrivate'][self._type])] - - for resource_name, resource_type in resources: - resource = self.test_resources.get(resource_name, None) - self.assertIsInstance(resource, dict) - self.assertEqual(resource_name, resource['logical_resource_id']) - self.assertEqual(resource_type, resource['resource_type']) - self.assertEqual('CREATE_COMPLETE', resource['resource_status']) - - @decorators.idempotent_id('8d77dec7-91fd-45a6-943d-5abd45e338a4') - def test_stack_keypairs_output(self): - stack = self.client.show_stack(self.stack_name)['stack'] - self.assertIsInstance(stack, dict) - - output_map = {} - for outputs in stack['outputs']: - output_map[outputs['output_key']] = outputs['output_value'] - # Test that first key generated public and private keys - self.assertIn('KeyPair_PublicKey', output_map) - self.assertIn("Generated", output_map['KeyPair_PublicKey']) - self.assertIn('KeyPair_PrivateKey', output_map) - self.assertIn('-----BEGIN', output_map['KeyPair_PrivateKey']) - # Test that second key generated public key, and private key is not - # in the output due to save_private_key = false - self.assertIn('KeyPairDontSavePrivate_PublicKey', output_map) - self.assertIn('Generated', - output_map['KeyPairDontSavePrivate_PublicKey']) - self.assertIn(u'KeyPairDontSavePrivate_PrivateKey', output_map) - private_key = output_map['KeyPairDontSavePrivate_PrivateKey'] - self.assertEqual(0, len(private_key)) - - -class NovaKeyPairResourcesAWSTest(NovaKeyPairResourcesYAMLTest): - _tpl_type = 'json' - _resource = 'Resources' - _type = 'Type' diff --git a/tempest/api/orchestration/stacks/test_resource_types.py b/tempest/api/orchestration/stacks/test_resource_types.py deleted file mode 100644 index 6d0707e552..0000000000 --- a/tempest/api/orchestration/stacks/test_resource_types.py +++ /dev/null @@ -1,49 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest.lib import decorators - - -class ResourceTypesTest(base.BaseOrchestrationTest): - - @decorators.attr(type='smoke') - @decorators.idempotent_id('7123d082-3577-4a30-8f00-f805327c4ffd') - def test_resource_type_list(self): - """Verify it is possible to list resource types.""" - resource_types = self.client.list_resource_types()['resource_types'] - self.assertIsInstance(resource_types, list) - self.assertIn('OS::Nova::Server', resource_types) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('0e85a483-828b-4a28-a0e3-f0a21809192b') - def test_resource_type_show(self): - """Verify it is possible to get schema about resource types.""" - resource_types = self.client.list_resource_types()['resource_types'] - self.assertNotEmpty(resource_types) - - for resource_type in resource_types: - type_schema = self.client.show_resource_type(resource_type) - self.assert_fields_in_dict(type_schema, 'properties', - 'attributes', 'resource_type') - self.assertEqual(resource_type, type_schema['resource_type']) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('8401821d-65fe-4d43-9fa3-57d5ce3a35c7') - def test_resource_type_template(self): - """Verify it is possible to get template about resource types.""" - type_template = self.client.show_resource_type_template( - 'OS::Nova::Server') - self.assert_fields_in_dict( - type_template, - 'Outputs', - 'Parameters', 'Resources') diff --git a/tempest/api/orchestration/stacks/test_soft_conf.py b/tempest/api/orchestration/stacks/test_soft_conf.py deleted file mode 100644 index 81929995b7..0000000000 --- a/tempest/api/orchestration/stacks/test_soft_conf.py +++ /dev/null @@ -1,169 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc - - -class TestSoftwareConfig(base.BaseOrchestrationTest): - - def setUp(self): - super(TestSoftwareConfig, self).setUp() - self.configs = [] - # Add 2 sets of software configuration - self.configs.append(self._config_create('a')) - self.configs.append(self._config_create('b')) - # Create a deployment using config a's id - self._deployment_create(self.configs[0]['id']) - - def _config_create(self, suffix): - configuration = {'group': 'script', - 'inputs': [], - 'outputs': [], - 'options': {}} - configuration['name'] = 'heat_soft_config_%s' % suffix - configuration['config'] = '#!/bin/bash echo init-%s' % suffix - api_config = self.client.create_software_config(**configuration) - configuration['id'] = api_config['software_config']['id'] - self.addCleanup(self._config_delete, configuration['id']) - self._validate_config(configuration, api_config) - return configuration - - def _validate_config(self, configuration, api_config): - # Assert all expected keys are present with matching data - for k in configuration: - self.assertEqual(configuration[k], - api_config['software_config'][k]) - - def _deployment_create(self, config_id): - self.server_id = data_utils.rand_name('dummy-server') - self.action = 'ACTION_0' - self.status = 'STATUS_0' - self.input_values = {} - self.output_values = [] - self.status_reason = 'REASON_0' - self.signal_transport = 'NO_SIGNAL' - self.deployment = self.client.create_software_deploy( - self.server_id, config_id, self.action, self.status, - self.input_values, self.output_values, self.status_reason, - self.signal_transport) - self.deployment_id = self.deployment['software_deployment']['id'] - self.addCleanup(self._deployment_delete, self.deployment_id) - - def _deployment_delete(self, deploy_id): - self.client.delete_software_deploy(deploy_id) - # Testing that it is really gone - self.assertRaises( - lib_exc.NotFound, self.client.show_software_deployment, - self.deployment_id) - - def _config_delete(self, config_id): - self.client.delete_software_config(config_id) - # Testing that it is really gone - self.assertRaises( - lib_exc.NotFound, self.client.show_software_config, config_id) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('136162ed-9445-4b9c-b7fc-306af8b5da99') - def test_get_software_config(self): - """Testing software config get.""" - for conf in self.configs: - api_config = self.client.show_software_config(conf['id']) - self._validate_config(conf, api_config) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('1275c835-c967-4a2c-8d5d-ad533447ed91') - def test_get_deployment_list(self): - """Getting a list of all deployments""" - deploy_list = self.client.list_software_deployments() - deploy_ids = [deploy['id'] for deploy in - deploy_list['software_deployments']] - self.assertIn(self.deployment_id, deploy_ids) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('fe7cd9f9-54b1-429c-a3b7-7df8451db913') - def test_get_deployment_metadata(self): - """Testing deployment metadata get""" - metadata = self.client.show_software_deployment_metadata( - self.server_id) - conf_ids = [conf['id'] for conf in metadata['metadata']] - self.assertIn(self.configs[0]['id'], conf_ids) - - def _validate_deployment(self, action, status, reason, config_id): - deployment = self.client.show_software_deployment(self.deployment_id) - self.assertEqual(action, deployment['software_deployment']['action']) - self.assertEqual(status, deployment['software_deployment']['status']) - self.assertEqual(reason, - deployment['software_deployment']['status_reason']) - self.assertEqual(config_id, - deployment['software_deployment']['config_id']) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('f29d21f3-ed75-47cf-8cdc-ef1bdeb4c674') - def test_software_deployment_create_validate(self): - """Testing software deployment was created as expected.""" - # Asserting that all fields were created - self.assert_fields_in_dict( - self.deployment['software_deployment'], 'action', 'config_id', - 'id', 'input_values', 'output_values', 'server_id', 'status', - 'status_reason') - # Testing get for this deployment and verifying parameters - self._validate_deployment(self.action, self.status, - self.status_reason, self.configs[0]['id']) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('2ac43ab3-34f2-415d-be2e-eabb4d14ee32') - def test_software_deployment_update_no_metadata_change(self): - """Testing software deployment update without metadata change.""" - metadata = self.client.show_software_deployment_metadata( - self.server_id) - # Updating values without changing the configuration ID - new_action = 'ACTION_1' - new_status = 'STATUS_1' - new_reason = 'REASON_1' - self.client.update_software_deploy( - self.deployment_id, self.server_id, self.configs[0]['id'], - new_action, new_status, self.input_values, self.output_values, - new_reason, self.signal_transport) - # Verifying get and that the deployment was updated as expected - self._validate_deployment(new_action, new_status, - new_reason, self.configs[0]['id']) - - # Metadata should not be changed at this point - test_metadata = self.client.show_software_deployment_metadata( - self.server_id) - for key in metadata['metadata'][0]: - self.assertEqual( - metadata['metadata'][0][key], - test_metadata['metadata'][0][key]) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('92c48944-d79d-4595-a840-8e1a581c1a72') - def test_software_deployment_update_with_metadata_change(self): - """Testing software deployment update with metadata change.""" - metadata = self.client.show_software_deployment_metadata( - self.server_id) - self.client.update_software_deploy( - self.deployment_id, self.server_id, self.configs[1]['id'], - self.action, self.status, self.input_values, - self.output_values, self.status_reason, self.signal_transport) - self._validate_deployment(self.action, self.status, - self.status_reason, self.configs[1]['id']) - # Metadata should now be changed - new_metadata = self.client.show_software_deployment_metadata( - self.server_id) - # Its enough to test the ID in this case - meta_id = metadata['metadata'][0]['id'] - test_id = new_metadata['metadata'][0]['id'] - self.assertNotEqual(meta_id, test_id) diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py deleted file mode 100644 index dc1bb4f817..0000000000 --- a/tempest/api/orchestration/stacks/test_stacks.py +++ /dev/null @@ -1,59 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - - -class StacksTestJSON(base.BaseOrchestrationTest): - empty_template = "HeatTemplateFormatVersion: '2012-12-12'\n" - - @decorators.attr(type='smoke') - @decorators.idempotent_id('d35d628c-07f6-4674-85a1-74db9919e986') - def test_stack_list_responds(self): - stacks = self.client.list_stacks()['stacks'] - self.assertIsInstance(stacks, list) - - @decorators.attr(type='smoke') - @decorators.idempotent_id('10498bd5-a83e-4b62-a817-ce24afe938fe') - def test_stack_crud_no_resources(self): - stack_name = data_utils.rand_name('heat') - - # create the stack - stack_identifier = self.create_stack( - stack_name, self.empty_template) - stack_id = stack_identifier.split('/')[1] - - # wait for create complete (with no resources it should be instant) - self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') - - # check for stack in list - stacks = self.client.list_stacks()['stacks'] - list_ids = list([stack['id'] for stack in stacks]) - self.assertIn(stack_id, list_ids) - - # fetch the stack - stack = self.client.show_stack(stack_identifier)['stack'] - self.assertEqual('CREATE_COMPLETE', stack['stack_status']) - - # fetch the stack by name - stack = self.client.show_stack(stack_name)['stack'] - self.assertEqual('CREATE_COMPLETE', stack['stack_status']) - - # fetch the stack by id - stack = self.client.show_stack(stack_id)['stack'] - self.assertEqual('CREATE_COMPLETE', stack['stack_status']) - - # delete the stack - self.client.delete_stack(stack_identifier) - self.client.wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE') diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py deleted file mode 100644 index d63cde8e1b..0000000000 --- a/tempest/api/orchestration/stacks/test_swift_resources.py +++ /dev/null @@ -1,120 +0,0 @@ -# Copyright (C) 2013 eNovance SAS -# -# 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. - -from tempest.api.orchestration import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest import test - - -CONF = config.CONF - - -class SwiftResourcesTestJSON(base.BaseOrchestrationTest): - @classmethod - def skip_checks(cls): - super(SwiftResourcesTestJSON, cls).skip_checks() - if not CONF.service_available.swift: - raise cls.skipException("Swift support is required") - - @classmethod - def setup_credentials(cls): - super(SwiftResourcesTestJSON, cls).setup_credentials() - stack_owner_role = CONF.orchestration.stack_owner_role - operator_role = CONF.object_storage.operator_role - cls.os = cls.get_client_manager( - roles=[stack_owner_role, operator_role]) - - @classmethod - def setup_clients(cls): - super(SwiftResourcesTestJSON, cls).setup_clients() - cls.account_client = cls.os_primary.account_client - cls.container_client = cls.os_primary.container_client - - @classmethod - def resource_setup(cls): - super(SwiftResourcesTestJSON, cls).resource_setup() - cls.stack_name = data_utils.rand_name('heat') - template = cls.read_template('swift_basic') - # create the stack - cls.stack_identifier = cls.create_stack( - cls.stack_name, - template) - cls.stack_id = cls.stack_identifier.split('/')[1] - cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE') - cls.test_resources = {} - resources = (cls.client.list_resources(cls.stack_identifier) - ['resources']) - for resource in resources: - cls.test_resources[resource['logical_resource_id']] = resource - - @decorators.idempotent_id('1a6fe69e-4be4-4990-9a7a-84b6f18019cb') - def test_created_resources(self): - """Created stack should be in the list of existing stacks.""" - swift_basic_template = self.load_template('swift_basic') - resources = [('SwiftContainer', swift_basic_template['resources'][ - 'SwiftContainer']['type']), - ('SwiftContainerWebsite', swift_basic_template[ - 'resources']['SwiftContainerWebsite']['type'])] - for resource_name, resource_type in resources: - resource = self.test_resources.get(resource_name) - self.assertIsInstance(resource, dict) - self.assertEqual(resource_type, resource['resource_type']) - self.assertEqual(resource_name, resource['logical_resource_id']) - self.assertEqual('CREATE_COMPLETE', resource['resource_status']) - - @decorators.idempotent_id('bd438b18-5494-4d5a-9ce6-d2a942ec5060') - @test.services('object_storage') - def test_created_containers(self): - params = {'format': 'json'} - _, container_list = \ - self.account_client.list_account_containers(params=params) - created_containers = [cont for cont in container_list - if cont['name'].startswith(self.stack_name)] - self.assertEqual(2, len(created_containers)) - - @decorators.idempotent_id('73d0c093-9922-44a0-8b1d-1fc092dee367') - @test.services('object_storage') - def test_acl(self): - acl_headers = ('x-container-meta-web-index', 'x-container-read') - - swcont = self.test_resources.get( - 'SwiftContainer')['physical_resource_id'] - swcont_website = self.test_resources.get( - 'SwiftContainerWebsite')['physical_resource_id'] - - headers, _ = self.container_client.list_container_metadata(swcont) - for h in acl_headers: - self.assertNotIn(h, headers) - headers, _ = self.container_client.list_container_metadata( - swcont_website) - for h in acl_headers: - self.assertIn(h, headers) - - @decorators.idempotent_id('fda06135-6777-4594-aefa-0f6107169698') - @test.services('object_storage') - def test_metadata(self): - swift_basic_template = self.load_template('swift_basic') - metadatas = swift_basic_template['resources']['SwiftContainerWebsite'][ - 'properties']['X-Container-Meta'] - swcont_website = self.test_resources.get( - 'SwiftContainerWebsite')['physical_resource_id'] - headers, _ = self.container_client.list_container_metadata( - swcont_website) - - for meta in metadatas: - header_meta = "x-container-meta-%s" % meta - self.assertIn(header_meta, headers) - self.assertEqual(headers[header_meta], metadatas[meta]) diff --git a/tempest/api/orchestration/stacks/test_templates.py b/tempest/api/orchestration/stacks/test_templates.py deleted file mode 100644 index 4ff951d5b6..0000000000 --- a/tempest/api/orchestration/stacks/test_templates.py +++ /dev/null @@ -1,61 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators - - -class TemplateYAMLTestJSON(base.BaseOrchestrationTest): - template = """ -HeatTemplateFormatVersion: '2012-12-12' -Description: | - Template which creates only a new user -Resources: - CfnUser: - Type: AWS::IAM::User -""" - - @classmethod - def resource_setup(cls): - super(TemplateYAMLTestJSON, cls).resource_setup() - cls.stack_name = data_utils.rand_name('heat') - cls.stack_identifier = cls.create_stack(cls.stack_name, cls.template) - cls.client.wait_for_stack_status(cls.stack_identifier, - 'CREATE_COMPLETE') - cls.stack_id = cls.stack_identifier.split('/')[1] - cls.parameters = {} - - @decorators.idempotent_id('47430699-c368-495e-a1db-64c26fd967d7') - def test_show_template(self): - """Getting template used to create the stack.""" - self.client.show_template(self.stack_identifier) - - @decorators.idempotent_id('ed53debe-8727-46c5-ab58-eba6090ec4de') - def test_validate_template(self): - """Validating template passing it content.""" - self.client.validate_template(self.template, - self.parameters) - - -class TemplateAWSTestJSON(TemplateYAMLTestJSON): - template = """ -{ - "AWSTemplateFormatVersion" : "2010-09-09", - "Description" : "Template which creates only a new user", - "Resources" : { - "CfnUser" : { - "Type" : "AWS::IAM::User" - } - } -} -""" diff --git a/tempest/api/orchestration/stacks/test_templates_negative.py b/tempest/api/orchestration/stacks/test_templates_negative.py deleted file mode 100644 index eb93d95a9d..0000000000 --- a/tempest/api/orchestration/stacks/test_templates_negative.py +++ /dev/null @@ -1,60 +0,0 @@ -# Copyright 2014 NEC Corporation. All rights reserved. -# -# 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. - -from tempest.api.orchestration import base -from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc - - -class TemplateYAMLNegativeTestJSON(base.BaseOrchestrationTest): - template = """ -HeatTemplateFormatVersion: '2012-12-12' -Description: | - Template which creates only a new user -Resources: - CfnUser: - Type: AWS::IAM::User -""" - - invalid_template_url = 'http:///template.yaml' - - @classmethod - def resource_setup(cls): - super(TemplateYAMLNegativeTestJSON, cls).resource_setup() - cls.parameters = {} - - @decorators.attr(type=['negative']) - @decorators.idempotent_id('5586cbca-ddc4-4152-9db8-fa1ce5fc1876') - def test_validate_template_url(self): - """Validating template passing url to it.""" - self.assertRaises(lib_exc.BadRequest, - self.client.validate_template_url, - template_url=self.invalid_template_url, - parameters=self.parameters) - - -class TemplateAWSNegativeTestJSON(TemplateYAMLNegativeTestJSON): - template = """ -{ - "AWSTemplateFormatVersion" : "2010-09-09", - "Description" : "Template which creates only a new user", - "Resources" : { - "CfnUser" : { - "Type" : "AWS::IAM::User" - } - } -} -""" - - invalid_template_url = 'http:///template.template' diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py deleted file mode 100644 index 7ddf7afd3d..0000000000 --- a/tempest/api/orchestration/stacks/test_volumes.py +++ /dev/null @@ -1,116 +0,0 @@ -# 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. - -from tempest.api.orchestration import base -from tempest import config -from tempest.lib.common.utils import data_utils -from tempest.lib import decorators -from tempest.lib import exceptions as lib_exc -from tempest import test - - -CONF = config.CONF - - -class CinderResourcesTest(base.BaseOrchestrationTest): - - @classmethod - def skip_checks(cls): - super(CinderResourcesTest, cls).skip_checks() - if not CONF.service_available.cinder: - raise cls.skipException('Cinder support is required') - - def _cinder_verify(self, volume_id, template): - self.assertIsNotNone(volume_id) - volume = self.volumes_client.show_volume(volume_id)['volume'] - self.assertEqual('available', volume.get('status')) - self.assertEqual(CONF.volume.volume_size, volume.get('size')) - - self.assertEqual(template['resources']['volume']['properties'][ - 'description'], volume.get('description')) - self.assertEqual(template['resources']['volume']['properties'][ - 'name'], volume.get('name')) - - def _outputs_verify(self, stack_identifier, template): - self.assertEqual('available', - self.get_stack_output(stack_identifier, 'status')) - self.assertEqual(str(CONF.volume.volume_size), - self.get_stack_output(stack_identifier, 'size')) - self.assertEqual(template['resources']['volume']['properties'][ - 'description'], self.get_stack_output(stack_identifier, - 'display_description')) - self.assertEqual(template['resources']['volume']['properties'][ - 'name'], self.get_stack_output(stack_identifier, 'display_name')) - - @decorators.idempotent_id('c3243329-7bdd-4730-b402-4d19d50c41d8') - @test.services('volume') - def test_cinder_volume_create_delete(self): - """Create and delete a volume via OS::Cinder::Volume.""" - stack_name = data_utils.rand_name('heat') - template = self.read_template('cinder_basic') - stack_identifier = self.create_stack( - stack_name, - template, - parameters={ - 'volume_size': CONF.volume.volume_size - }) - self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') - - # Verify with cinder that the volume exists, with matching details - volume_id = self.get_stack_output(stack_identifier, 'volume_id') - cinder_basic_template = self.load_template('cinder_basic') - self._cinder_verify(volume_id, cinder_basic_template) - - # Verify the stack outputs are as expected - self._outputs_verify(stack_identifier, cinder_basic_template) - - # Delete the stack and ensure the volume is gone - self.client.delete_stack(stack_identifier) - self.client.wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE') - self.assertRaises(lib_exc.NotFound, - self.volumes_client.show_volume, - volume_id) - - def _cleanup_volume(self, volume_id): - """Cleanup the volume direct with cinder.""" - self.volumes_client.delete_volume(volume_id) - self.volumes_client.wait_for_resource_deletion(volume_id) - - @decorators.idempotent_id('ea8b3a46-b932-4c18-907a-fe23f00b33f8') - @test.services('volume') - def test_cinder_volume_create_delete_retain(self): - """Ensure the 'Retain' deletion policy is respected.""" - stack_name = data_utils.rand_name('heat') - template = self.read_template('cinder_basic_delete_retain') - stack_identifier = self.create_stack( - stack_name, - template, - parameters={ - 'volume_size': CONF.volume.volume_size - }) - self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE') - - # Verify with cinder that the volume exists, with matching details - volume_id = self.get_stack_output(stack_identifier, 'volume_id') - self.addCleanup(self._cleanup_volume, volume_id) - retain_template = self.load_template('cinder_basic_delete_retain') - self._cinder_verify(volume_id, retain_template) - - # Verify the stack outputs are as expected - self._outputs_verify(stack_identifier, retain_template) - - # Delete the stack and ensure the volume is *not* gone - self.client.delete_stack(stack_identifier) - self.client.wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE') - self._cinder_verify(volume_id, retain_template) - - # Volume cleanup happens via addCleanup calling _cleanup_volume