Remove tests for Interop Tests for add-on trademark program

Remove tests which been planned to added to add-on trademark
program. We now maintain these tests in heat tempest plugin.

Change-Id: I458d39f988019c4f1d62c7e39a325a2082a98561
This commit is contained in:
ricolin 2017-12-17 21:40:43 +08:00 committed by Zane Bitter
parent 41cc012b34
commit d2bf5ecf6a
23 changed files with 32 additions and 2232 deletions

View File

@ -1,55 +0,0 @@
defaults:
request_headers:
X-Auth-Token: $ENVIRON['OS_TOKEN']
tests:
- name: environment with parameter
POST: /stacks
request_headers:
content-type: application/json
data:
files: {}
disable_rollback: true
parameters: {}
stack_name: $ENVIRON['PREFIX']-envstack
environment:
parameters:
test_val: test
template:
heat_template_version: '2016-04-08'
parameters:
test_val:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
value: {get_param: test_val}
outputs:
output_value:
value: {get_attr: [test, output]}
status: 201
response_headers:
location: //stacks/$ENVIRON['PREFIX']-envstack/[a-f0-9-]+/
- name: poll for envstack CREATE_COMPLETE
GET: $LOCATION
redirects: True
poll:
count: 5
delay: 1.0
response_json_paths:
$.stack.stack_status: CREATE_COMPLETE
- name: get stack output
GET: $LAST_URL/outputs/output_value
redirects: True
status: 200
response_json_paths:
$.output.output_value: test
- name: delete envstack
DELETE: /stacks/$ENVIRON['PREFIX']-envstack
redirects: True
status: 204

View File

@ -1,90 +0,0 @@
defaults:
request_headers:
X-Auth-Token: $ENVIRON['OS_TOKEN']
tests:
- name: create stack with resources
POST: /stacks
request_headers:
content-type: application/json
data:
files: {}
disable_rollback: true
parameters: {}
stack_name: $ENVIRON['PREFIX']-rsrcstack
template:
heat_template_version: '2016-04-08'
parameters:
test_val:
type: string
default: test
resources:
test:
type: OS::Heat::TestResource
properties:
value: {get_param: test_val}
status: 201
response_headers:
location: //stacks/$ENVIRON['PREFIX']-rsrcstack/[a-f0-9-]+/
- name: poll for rsrcstack CREATE_COMPLETE
GET: $LOCATION
redirects: True
poll:
count: 5
delay: 1.0
response_json_paths:
$.stack.stack_status: CREATE_COMPLETE
- name: list resources
GET: $LAST_URL/resources
request_headers:
content-type: application/json
status: 200
response_json_paths:
$.resources[0].logical_resource_id: test
$.resources[0].resource_status: CREATE_COMPLETE
- name: list filtered resources
GET: $LAST_URL
request_headers:
content-type: application/json
query_parameters:
type: OS::Nova::Server
status: 200
response_json_paths:
$.resources: []
- name: show resource
GET: $LAST_URL/test
request_headers:
content-type: application/json
status: 200
response_json_paths:
$.resource.attributes.output: test
- name: mark resource unhealthy
PATCH: $LAST_URL
request_headers:
content-type: application/json
data:
mark_unhealthy: true
resource_status_reason: 'resource deleted'
status: 200
- name: show unhealthy resource
GET: $LAST_URL
status: 200
response_json_paths:
$.resource.resource_status: CHECK_FAILED
$.resource.resource_status_reason: 'resource deleted'
- name: signal resource
POST: $LAST_URL/signal
status: 400
- name: delete stack with resources
DELETE: /stacks/$ENVIRON['PREFIX']-rsrcstack
redirects: True
status: 204

View File

@ -1,24 +0,0 @@
defaults:
request_headers:
X-Auth-Token: $ENVIRON['OS_TOKEN']
tests:
- name: list resource types
GET: /resource_types
status: 200
- name: show resource type
GET: /resource_types/OS::Heat::TestResource
status: 200
response_json_paths:
$.support_status.status: SUPPORTED
$.properties.wait_secs.default: 0
- name: resource type template
GET: /resource_types/OS::Heat::TestResource/template
query_parameters:
template_type: hot
status: 200
response_json_paths:
$.resources.TestResource.type: OS::Heat::TestResource
$.heat_template_version: '2016-10-14'

View File

@ -1,162 +0,0 @@
defaults:
request_headers:
X-Auth-Token: $ENVIRON['OS_TOKEN']
tests:
- name: stack list
GET: /stacks
status: 200
response_headers:
content-type: application/json
- name: create empty stack
POST: /stacks
request_headers:
content-type: application/json
data:
files: {}
disable_rollback: true
parameters: {}
stack_name: $ENVIRON['PREFIX']-empty
environment: {}
template:
heat_template_version: '2016-04-08'
status: 201
response_headers:
location: //stacks/$ENVIRON['PREFIX']-empty/[a-f0-9-]+/
- name: poll for empty CREATE_COMPLETE
GET: $LOCATION
redirects: True
poll:
count: 5
delay: 1.0
response_json_paths:
$.stack.stack_status: CREATE_COMPLETE
- name: show empty stack
GET: $LAST_URL
redirects: True
status: 200
- name: delete empty stack
DELETE: $LAST_URL
redirects: True
status: 204
- name: create stack
POST: /stacks
request_headers:
content-type: application/json
data:
files: {}
disable_rollback: true
parameters: {'test_val': value}
stack_name: $ENVIRON['PREFIX']-stack
template:
heat_template_version: pike
parameters:
test_val:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
value: {get_param: test_val}
outputs:
output_value:
value: {get_attr: [test, output]}
status: 201
response_headers:
location: //stacks/$ENVIRON['PREFIX']-stack/[a-f0-9-]+/
- name: poll for stack CREATE_COMPLETE
GET: $LOCATION
redirects: True
poll:
count: 5
delay: 1.0
response_json_paths:
$.stack.stack_status: CREATE_COMPLETE
- name: show stack
GET: $LAST_URL
redirects: True
status: 200
- name: update stack
PUT: $LAST_URL
request_headers:
content-type: application/json
data:
files: {}
disable_rollback: true
parameters: {'test_val': new_value}
stack_name: $ENVIRON['PREFIX']-stack
template:
heat_template_version: pike
parameters:
test_val:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
value: {get_param: test_val}
action_wait_secs:
update: 1
outputs:
output_value:
value: {get_attr: [test, output]}
status: 202
- name: poll for stack UPDATE_COMPLETE
GET: $LAST_URL
redirects: True
poll:
count: 5
delay: 1.0
response_json_paths:
$.stack.stack_status: UPDATE_COMPLETE
- name: patch update stack
PATCH: $LAST_URL
request_headers:
content-type: application/json
data:
parameters: {'test_val': new_patched_value}
status: 202
- name: poll for stack patch UPDATE_COMPLETE
GET: $LAST_URL
redirects: True
poll:
count: 5
delay: 1.0
response_json_paths:
$.stack.stack_status: UPDATE_COMPLETE
$.stack.updated_time: /^(?!$HISTORY['poll for stack UPDATE_COMPLETE'].$RESPONSE['$.stack.updated_time'])/
- name: list stack outputs
GET: $LAST_URL/outputs
redirects: True
status: 200
response_json_paths:
$.outputs[0].output_key: output_value
- name: get stack output
GET: $LAST_URL/output_value
redirects: True
status: 200
response_json_paths:
$.output.output_value: new_patched_value
- name: delete stack
DELETE: /stacks/$ENVIRON['PREFIX']-stack
redirects: True
status: 204

View File

@ -1,37 +0,0 @@
defaults:
request_headers:
X-Auth-Token: $ENVIRON['OS_TOKEN']
tests:
- name: list template versions
GET: /template_versions
status: 200
response_json_paths:
$.template_versions[?(@.version='heat_template_version.2017-02-24')].type: hot
- name: list template functions
GET: /template_versions/heat_template_version.2016-10-14/functions
status: 200
response_json_paths:
$.template_functions[?(@.functions='get_file')].description:
A function for including a file inline.
- name: template validate
POST: /validate
request_headers:
content-type: application/json
data:
template:
heat_template_version: '2016-04-08'
parameters:
test_val:
type: string
resources:
test:
type: OS::Heat::TestResource
properties:
value: {get_param: test_val}
outputs:
output_value:
value: {get_attr: [test, output]}
status: 200

View File

@ -1,44 +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.
"""A test module to exercise the Heat API with gabbi. """
import os
from gabbi import driver
from six.moves.urllib import parse as urlparse
from heat_integrationtests.common import clients
from heat_integrationtests.common import config
from heat_integrationtests.common import test
TESTS_DIR = 'gabbits'
def load_tests(loader, tests, pattern):
"""Provide a TestSuite to the discovery process."""
test_dir = os.path.join(os.path.dirname(__file__), TESTS_DIR)
conf = config.init_conf().heat_plugin
if conf.auth_url is None:
# It's not configured, let's not load tests
return
manager = clients.ClientManager(conf)
endpoint = manager.identity_client.get_endpoint_url(
'orchestration', conf.region)
host = urlparse.urlparse(endpoint).hostname
os.environ['OS_TOKEN'] = manager.identity_client.auth_token
os.environ['PREFIX'] = test.rand_name('api')
return driver.build_tests(test_dir, loader, host=host,
url=endpoint, test_loader_name=__name__)

View File

@ -1,83 +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 heat_integrationtests.functional import functional_base
class ExternalReferencesTest(functional_base.FunctionalTestsBase):
TEMPLATE = '''
heat_template_version: 2016-10-14
resources:
test1:
type: OS::Heat::TestResource
'''
TEMPLATE_WITH_EX_REF = '''
heat_template_version: 2016-10-14
resources:
test1:
type: OS::Heat::TestResource
external_id: foobar
outputs:
str:
value: {get_resource: test1}
'''
def test_create_with_external_ref(self):
stack_name = self._stack_rand_name()
stack_identifier = self.stack_create(
stack_name=stack_name,
template=self.TEMPLATE_WITH_EX_REF,
files={},
disable_rollback=True,
parameters={},
environment={}
)
stack = self.client.stacks.get(stack_identifier)
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
expected_resources = {'test1': 'OS::Heat::TestResource'}
self.assertEqual(expected_resources,
self.list_resources(stack_identifier))
stack = self.client.stacks.get(stack_identifier)
self.assertEqual(
[{'description': 'No description given',
'output_key': 'str',
'output_value': 'foobar'}], stack.outputs)
def test_update_with_external_ref(self):
stack_name = self._stack_rand_name()
stack_identifier = self.stack_create(
stack_name=stack_name,
template=self.TEMPLATE,
files={},
disable_rollback=True,
parameters={},
environment={}
)
stack = self.client.stacks.get(stack_identifier)
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
expected_resources = {'test1': 'OS::Heat::TestResource'}
self.assertEqual(expected_resources,
self.list_resources(stack_identifier))
stack = self.client.stacks.get(stack_identifier)
self.assertEqual([], stack.outputs)
stack_name = stack_identifier.split('/')[0]
kwargs = {'stack_id': stack_identifier, 'stack_name': stack_name,
'template': self.TEMPLATE_WITH_EX_REF, 'files': {},
'disable_rollback': True, 'parameters': {}, 'environment': {}
}
self.client.stacks.update(**kwargs)
self._wait_for_stack_status(stack_identifier, 'UPDATE_FAILED')

View File

@ -1,281 +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 yaml
from heat_integrationtests.functional import functional_base
class HooksTest(functional_base.FunctionalTestsBase):
def setUp(self):
super(HooksTest, self).setUp()
self.template = {'heat_template_version': '2014-10-16',
'resources': {
'foo_step1': {'type': 'OS::Heat::RandomString'},
'foo_step2': {'type': 'OS::Heat::RandomString',
'depends_on': 'foo_step1'},
'foo_step3': {'type': 'OS::Heat::RandomString',
'depends_on': 'foo_step2'}}}
def test_hook_pre_create(self):
env = {'resource_registry':
{'resources':
{'foo_step2':
{'hooks': 'pre-create'}}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=self.template,
environment=env,
expected_status='CREATE_IN_PROGRESS')
self._wait_for_resource_status(
stack_identifier, 'foo_step1', 'CREATE_COMPLETE')
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'INIT_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-create'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
def test_hook_pre_update_nochange(self):
env = {'resource_registry':
{'resources':
{'foo_step2':
{'hooks': 'pre-update'}}}}
stack_identifier = self.stack_create(
template=self.template,
environment=env)
res_before = self.client.resources.get(stack_identifier, 'foo_step2')
# Note we don't wait for UPDATE_COMPLETE, because we need to
# signal to clear the hook before update will complete
self.update_stack(
stack_identifier,
template=self.template,
environment=env,
expected_status='UPDATE_IN_PROGRESS')
# Note when a hook is specified, the resource status doesn't change
# when we hit the hook, so we look for the event, then assert the
# state is unchanged.
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='UPDATE paused until Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-update'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
res_after = self.client.resources.get(stack_identifier, 'foo_step2')
self.assertEqual(res_before.physical_resource_id,
res_after.physical_resource_id)
def test_hook_pre_update_replace(self):
env = {'resource_registry':
{'resources':
{'foo_step2':
{'hooks': 'pre-update'}}}}
stack_identifier = self.stack_create(
template=self.template,
environment=env)
res_before = self.client.resources.get(stack_identifier, 'foo_step2')
# Note we don't wait for UPDATE_COMPLETE, because we need to
# signal to clear the hook before update will complete
self.template['resources']['foo_step2']['properties'] = {'length': 10}
self.update_stack(
stack_identifier,
template=self.template,
environment=env,
expected_status='UPDATE_IN_PROGRESS')
# Note when a hook is specified, the resource status doesn't change
# when we hit the hook, so we look for the event, then assert the
# state is unchanged.
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='UPDATE paused until Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-update'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-update is cleared',
rsrc_name='foo_step2')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
res_after = self.client.resources.get(stack_identifier, 'foo_step2')
self.assertNotEqual(res_before.physical_resource_id,
res_after.physical_resource_id)
def test_hook_pre_update_in_place(self):
env = {'resource_registry':
{'resources':
{'rg':
{'hooks': 'pre-update'}}}}
template = {'heat_template_version': '2014-10-16',
'resources': {
'rg': {
'type': 'OS::Heat::ResourceGroup',
'properties': {
'count': 1,
'resource_def': {
'type': 'OS::Heat::RandomString'}}}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=template,
environment=env)
res_before = self.client.resources.get(stack_identifier, 'rg')
template['resources']['rg']['properties']['count'] = 2
self.update_stack(
stack_identifier,
template=template,
environment=env,
expected_status='UPDATE_IN_PROGRESS')
# Note when a hook is specified, the resource status doesn't change
# when we hit the hook, so we look for the event, then assert the
# state is unchanged.
self._wait_for_resource_status(
stack_identifier, 'rg', 'CREATE_COMPLETE')
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='UPDATE paused until Hook pre-update is cleared',
rsrc_name='rg')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self.client.resources.signal(stack_identifier, 'rg',
data={'unset_hook': 'pre-update'})
ev = self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-update is cleared',
rsrc_name='rg')
self.assertEqual('CREATE_COMPLETE', ev[0].resource_status)
self._wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
res_after = self.client.resources.get(stack_identifier, 'rg')
self.assertEqual(res_before.physical_resource_id,
res_after.physical_resource_id)
def test_hook_pre_create_nested(self):
files = {'nested.yaml': yaml.safe_dump(self.template)}
env = {'resource_registry':
{'resources':
{'nested':
{'foo_step2':
{'hooks': 'pre-create'}}}}}
template = {'heat_template_version': '2014-10-16',
'resources': {
'nested': {'type': 'nested.yaml'}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=template,
environment=env,
files=files,
expected_status='CREATE_IN_PROGRESS')
self._wait_for_resource_status(stack_identifier, 'nested',
'CREATE_IN_PROGRESS')
nested_identifier = self.assert_resource_is_a_stack(
stack_identifier, 'nested', wait=True)
self._wait_for_resource_status(
nested_identifier, 'foo_step1', 'CREATE_COMPLETE')
self._wait_for_resource_status(
nested_identifier, 'foo_step2', 'INIT_COMPLETE')
ev = self.wait_for_event_with_reason(
nested_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self.client.resources.signal(nested_identifier, 'foo_step2',
data={'unset_hook': 'pre-create'})
ev = self.wait_for_event_with_reason(
nested_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step2')
self.assertEqual('INIT_COMPLETE', ev[0].resource_status)
self._wait_for_resource_status(
nested_identifier, 'foo_step2', 'CREATE_COMPLETE')
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
def test_hook_pre_create_wildcard(self):
env = {'resource_registry':
{'resources':
{'foo_*':
{'hooks': 'pre-create'}}}}
# Note we don't wait for CREATE_COMPLETE, because we need to
# signal to clear the hook before create will complete
stack_identifier = self.stack_create(
template=self.template,
environment=env,
expected_status='CREATE_IN_PROGRESS')
self._wait_for_resource_status(
stack_identifier, 'foo_step1', 'INIT_COMPLETE')
self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step1')
self.client.resources.signal(stack_identifier, 'foo_step1',
data={'unset_hook': 'pre-create'})
self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step1')
self._wait_for_resource_status(
stack_identifier, 'foo_step2', 'INIT_COMPLETE')
self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step2')
self.client.resources.signal(stack_identifier, 'foo_step2',
data={'unset_hook': 'pre-create'})
self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step2')
self._wait_for_resource_status(
stack_identifier, 'foo_step3', 'INIT_COMPLETE')
self.wait_for_event_with_reason(
stack_identifier,
reason='CREATE paused until Hook pre-create is cleared',
rsrc_name='foo_step3')
self.client.resources.signal(stack_identifier, 'foo_step3',
data={'unset_hook': 'pre-create'})
self.wait_for_event_with_reason(
stack_identifier,
reason='Hook pre-create is cleared',
rsrc_name='foo_step3')
self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')

View File

@ -1,237 +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 heat_integrationtests.functional import functional_base
from heatclient import exc
import six
class StackPreviewTest(functional_base.FunctionalTestsBase):
template = '''
heat_template_version: 2015-04-30
parameters:
incomming:
type: string
resources:
one:
type: OS::Heat::TestResource
properties:
value: fred
two:
type: OS::Heat::TestResource
properties:
value: {get_param: incomming}
depends_on: one
outputs:
main_out:
value: {get_attr: [two, output]}
'''
env = '''
parameters:
incomming: abc
'''
def setUp(self):
super(StackPreviewTest, self).setUp()
self.client = self.orchestration_client
self.project_id = self.identity_client.project_id
def _assert_resource(self, res, stack_name):
self.assertEqual(stack_name, res['stack_name'])
self.assertEqual('INIT', res['resource_action'])
self.assertEqual('COMPLETE', res['resource_status'])
for field in ('resource_status_reason', 'physical_resource_id',
'description'):
self.assertIn(field, res)
self.assertEqual('', res[field])
# 'creation_time' and 'updated_time' are None when preview
for field in ('creation_time', 'updated_time'):
self.assertIn(field, res)
self.assertIsNone(res[field])
self.assertIn('output', res['attributes'])
# resource_identity
self.assertEqual(stack_name,
res['resource_identity']['stack_name'])
self.assertEqual('None', res['resource_identity']['stack_id'])
self.assertEqual(self.project_id,
res['resource_identity']['tenant'])
self.assertEqual('/resources/%s' % res['resource_name'],
res['resource_identity']['path'])
# stack_identity
self.assertEqual(stack_name,
res['stack_identity']['stack_name'])
self.assertEqual('None', res['stack_identity']['stack_id'])
self.assertEqual(self.project_id,
res['stack_identity']['tenant'])
self.assertEqual('', res['stack_identity']['path'])
def _assert_results(self, result, stack_name):
# global stuff.
self.assertEqual(stack_name, result['stack_name'])
self.assertTrue(result['disable_rollback'])
self.assertEqual('None', result['id'])
self.assertIsNone(result['parent'])
self.assertEqual('No description', result['template_description'])
# parameters
self.assertEqual('None', result['parameters']['OS::stack_id'])
self.assertEqual(stack_name, result['parameters']['OS::stack_name'])
self.assertEqual('abc', result['parameters']['incomming'])
def test_basic_pass(self):
stack_name = self._stack_rand_name()
result = self.client.stacks.preview(
template=self.template,
stack_name=stack_name,
disable_rollback=True,
environment=self.env).to_dict()
self._assert_results(result, stack_name)
for res in result['resources']:
self._assert_resource(res, stack_name)
self.assertEqual('OS::Heat::TestResource',
res['resource_type'])
# common properties
self.assertFalse(res['properties']['fail'])
self.assertEqual(0, res['properties']['wait_secs'])
self.assertFalse(res['properties']['update_replace'])
if res['resource_name'] == 'one':
self.assertEqual('fred', res['properties']['value'])
self.assertEqual(['two'], res['required_by'])
if res['resource_name'] == 'two':
self.assertEqual('abc', res['properties']['value'])
self.assertEqual([], res['required_by'])
def test_basic_fail(self):
stack_name = self._stack_rand_name()
# break the template so it fails validation.
wont_work = self.template.replace('get_param: incomming',
'get_param: missing')
excp = self.assertRaises(exc.HTTPBadRequest,
self.client.stacks.preview,
template=wont_work,
stack_name=stack_name,
disable_rollback=True,
environment=self.env)
self.assertIn('Property error: : resources.two.properties.value: '
': The Parameter (missing) was not provided.',
six.text_type(excp))
def test_nested_pass(self):
"""Nested stacks need to recurse down the stacks."""
main_template = '''
heat_template_version: 2015-04-30
parameters:
incomming:
type: string
resources:
main:
type: nested.yaml
properties:
value: {get_param: incomming}
outputs:
main_out:
value: {get_attr: [main, output]}
'''
nested_template = '''
heat_template_version: 2015-04-30
parameters:
value:
type: string
resources:
nested:
type: OS::Heat::TestResource
properties:
value: {get_param: value}
outputs:
output:
value: {get_attr: [nested, output]}
'''
stack_name = self._stack_rand_name()
result = self.client.stacks.preview(
disable_rollback=True,
stack_name=stack_name,
template=main_template,
files={'nested.yaml': nested_template},
environment=self.env).to_dict()
self._assert_results(result, stack_name)
# nested resources return a list of their resources.
res = result['resources'][0][0]
nested_stack_name = '%s-%s' % (stack_name,
res['parent_resource'])
self._assert_resource(res, nested_stack_name)
self.assertEqual('OS::Heat::TestResource',
res['resource_type'])
self.assertFalse(res['properties']['fail'])
self.assertEqual(0, res['properties']['wait_secs'])
self.assertFalse(res['properties']['update_replace'])
self.assertEqual('abc', res['properties']['value'])
self.assertEqual([], res['required_by'])
def test_res_group_with_nested_template(self):
main_template = '''
heat_template_version: 2015-04-30
resources:
fixed_network:
type: "OS::Neutron::Net"
rg:
type: "OS::Heat::ResourceGroup"
properties:
count: 1
resource_def:
type: nested.yaml
properties:
fixed_network_id: {get_resource: fixed_network}
'''
nested_template = '''
heat_template_version: 2015-04-30
parameters:
fixed_network_id:
type: string
resources:
port:
type: "OS::Neutron::Port"
properties:
network_id:
get_param: fixed_network_id
'''
stack_name = self._stack_rand_name()
result = self.client.stacks.preview(
disable_rollback=True,
stack_name=stack_name,
template=main_template,
files={'nested.yaml': nested_template}).to_dict()
resource_names = []
def get_resource_names(resources):
for item in resources:
if isinstance(item, dict):
resource_names.append(item['resource_name'])
else:
get_resource_names(item)
get_resource_names(result['resources'])
# ensure that fixed network and port here
self.assertIn('fixed_network', resource_names)
self.assertIn('port', resource_names)

View File

@ -1,50 +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 heat_integrationtests.functional import functional_base
test_template_depend = {
'heat_template_version': '2013-05-23',
'resources': {
'test1': {
'type': 'OS::Heat::TestResource',
'properties': {
'value': 'Test1',
}
},
'test2': {
'type': 'OS::Heat::TestResource',
'depends_on': ['test1'],
'properties': {
'value': 'Test2',
}
}
}
}
class ResourcesList(functional_base.FunctionalTestsBase):
def test_filtering_with_depend(self):
stack_identifier = self.stack_create(template=test_template_depend)
[test2] = self.client.resources.list(stack_identifier,
filters={'name': 'test2'})
self.assertEqual('CREATE_COMPLETE', test2.resource_status)
def test_required_by(self):
stack_identifier = self.stack_create(template=test_template_depend)
[test1] = self.client.resources.list(stack_identifier,
filters={'name': 'test1'})
self.assertEqual(['test2'], test1.required_by)

View File

@ -12,174 +12,17 @@
import json
import os
import requests
import subprocess
import sys
import tempfile
import time
import yaml
from oslo_utils import timeutils
from heat_integrationtests.common import exceptions
from heat_integrationtests.common import test
from heat_integrationtests.functional import functional_base
class ParallelDeploymentsTest(functional_base.FunctionalTestsBase):
server_template = '''
heat_template_version: "2013-05-23"
parameters:
flavor:
type: string
image:
type: string
network:
type: string
resources:
server:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
user_data_format: SOFTWARE_CONFIG
networks: [{network: {get_param: network}}]
outputs:
server:
value: {get_resource: server}
'''
config_template = '''
heat_template_version: "2013-05-23"
parameters:
server:
type: string
resources:
config:
type: OS::Heat::SoftwareConfig
properties:
'''
deployment_snippet = '''
type: OS::Heat::SoftwareDeployments
properties:
config: {get_resource: config}
servers: {'0': {get_param: server}}
'''
enable_cleanup = True
def test_deployments_metadata(self):
parms = {'flavor': self.conf.minimal_instance_type,
'network': self.conf.fixed_network_name,
'image': self.conf.minimal_image_ref}
stack_identifier = self.stack_create(
parameters=parms,
template=self.server_template,
enable_cleanup=self.enable_cleanup)
server_stack = self.client.stacks.get(stack_identifier)
server = server_stack.outputs[0]['output_value']
config_stacks = []
# add up to 3 stacks each with up to 3 deployments
deploy_count = 0
deploy_count = self.deploy_many_configs(
stack_identifier,
server,
config_stacks,
2,
5,
deploy_count)
self.deploy_many_configs(
stack_identifier,
server,
config_stacks,
3,
3,
deploy_count)
self.signal_deployments(stack_identifier)
for config_stack in config_stacks:
self._wait_for_stack_status(config_stack, 'CREATE_COMPLETE')
def test_deployments_timeout_failed(self):
parms = {'flavor': self.conf.minimal_instance_type,
'network': self.conf.fixed_network_name,
'image': self.conf.minimal_image_ref}
stack_identifier = self.stack_create(
parameters=parms,
template=self.server_template,
enable_cleanup=self.enable_cleanup)
server_stack = self.client.stacks.get(stack_identifier)
server = server_stack.outputs[0]['output_value']
config_stack = self.deploy_config(server, 3, 1)
self._wait_for_stack_status(config_stack, 'CREATE_FAILED')
kwargs = {'server_id': server}
def check_deployment_status():
sd_list = self.client.software_deployments.list(**kwargs)
for sd in sd_list:
if sd.status != 'FAILED':
return False
return True
self.assertTrue(test.call_until_true(
20, 0, check_deployment_status))
def deploy_many_configs(self, stack, server, config_stacks,
stack_count, deploys_per_stack,
deploy_count_start):
for a in range(stack_count):
config_stacks.append(
self.deploy_config(server, deploys_per_stack))
new_count = deploy_count_start + stack_count * deploys_per_stack
self.wait_for_deploy_metadata_set(stack, new_count)
return new_count
def deploy_config(self, server, deploy_count, timeout=None):
parms = {'server': server}
template = yaml.safe_load(self.config_template)
resources = template['resources']
resources['config']['properties'] = {'config': 'x' * 10000}
for a in range(deploy_count):
resources['dep_%s' % a] = yaml.safe_load(self.deployment_snippet)
return self.stack_create(
parameters=parms,
template=template,
enable_cleanup=self.enable_cleanup,
expected_status=None,
timeout=timeout)
def wait_for_deploy_metadata_set(self, stack, deploy_count):
build_timeout = self.conf.build_timeout
build_interval = self.conf.build_interval
start = timeutils.utcnow()
while timeutils.delta_seconds(start,
timeutils.utcnow()) < build_timeout:
server_metadata = self.client.resources.metadata(
stack, 'server')
if len(server_metadata['deployments']) == deploy_count:
return
time.sleep(build_interval)
message = ('Deployment resources failed to be created within '
'the required time (%s s).' %
(build_timeout))
raise exceptions.TimeoutException(message)
def signal_deployments(self, stack_identifier):
server_metadata = self.client.resources.metadata(
stack_identifier, 'server')
for dep in server_metadata['deployments']:
iv = dict((i['name'], i['value']) for i in dep['inputs'])
sigurl = iv.get('deploy_signal_id')
requests.post(sigurl, data='{}',
headers={'content-type': 'application/json'},
verify=self.verify_cert)
class ZaqarSignalTransportTest(functional_base.FunctionalTestsBase):
server_template = '''
heat_template_version: "2013-05-23"

View File

@ -1,109 +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 heat_integrationtests.functional import functional_base
class StackEventsTest(functional_base.FunctionalTestsBase):
template = '''
heat_template_version: 2014-10-16
parameters:
resources:
test_resource:
type: OS::Heat::TestResource
properties:
value: 'test1'
fail: False
update_replace: False
wait_secs: 0
outputs:
resource_id:
description: 'ID of resource'
value: { get_resource: test_resource }
'''
def _verify_event_fields(self, event, event_characteristics):
self.assertIsNotNone(event_characteristics)
self.assertIsNotNone(event.event_time)
self.assertIsNotNone(event.links)
self.assertIsNotNone(event.logical_resource_id)
self.assertIsNotNone(event.resource_status)
self.assertIn(event.resource_status, event_characteristics[1])
self.assertIsNotNone(event.resource_status_reason)
self.assertIsNotNone(event.id)
def test_event(self):
parameters = {}
test_stack_name = self._stack_rand_name()
stack_identifier = self.stack_create(
stack_name=test_stack_name,
template=self.template,
parameters=parameters
)
expected_status = ['CREATE_IN_PROGRESS', 'CREATE_COMPLETE']
event_characteristics = {
test_stack_name: ('OS::Heat::Stack', expected_status),
'test_resource': ('OS::Heat::TestResource', expected_status)}
# List stack events
# API: GET /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/events
stack_events = self.client.events.list(stack_identifier)
for stack_event in stack_events:
# Key on an expected/valid resource name
self._verify_event_fields(
stack_event,
event_characteristics[stack_event.resource_name])
# Test the event filtering API based on this resource_name
# /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}/events
resource_events = self.client.events.list(
stack_identifier,
stack_event.resource_name)
# Resource events are a subset of the original stack event list
self.assertLess(len(resource_events), len(stack_events))
# Get the event details for each resource event
for resource_event in resource_events:
# A resource_event should be in the original stack event list
self.assertIn(resource_event, stack_events)
# Given a filtered list, the resource names should be identical
self.assertEqual(
resource_event.resource_name,
stack_event.resource_name)
# Verify all fields, keying off the resource_name
self._verify_event_fields(
resource_event,
event_characteristics[resource_event.resource_name])
# Exercise the event details API
# /v1/{tenant_id}/stacks/{stack_name}/{stack_id}/resources/{resource_name}/events/{event_id}
event_details = self.client.events.get(
stack_identifier,
resource_event.resource_name,
resource_event.id)
self._verify_event_fields(
event_details,
event_characteristics[event_details.resource_name])
# The names should be identical to the non-detailed event
self.assertEqual(
resource_event.resource_name,
event_details.resource_name)
# Verify the extra field in the detail results
self.assertIsNotNone(event_details.resource_type)
self.assertEqual(
event_characteristics[event_details.resource_name][0],
event_details.resource_type)

View File

@ -1,155 +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 heat_integrationtests.functional import functional_base
class StackOutputsTest(functional_base.FunctionalTestsBase):
template = '''
heat_template_version: 2015-10-15
resources:
test_resource_a:
type: OS::Heat::TestResource
properties:
value: 'a'
test_resource_b:
type: OS::Heat::TestResource
properties:
value: 'b'
outputs:
resource_output_a:
description: 'Output of resource a'
value: { get_attr: [test_resource_a, output] }
resource_output_b:
description: 'Output of resource b'
value: { get_attr: [test_resource_b, output] }
'''
def test_outputs(self):
stack_identifier = self.stack_create(
template=self.template
)
expected_list = [{u'output_key': u'resource_output_a',
u'description': u'Output of resource a'},
{u'output_key': u'resource_output_b',
u'description': u'Output of resource b'}]
actual_list = self.client.stacks.output_list(
stack_identifier)['outputs']
sorted_actual_list = sorted(actual_list, key=lambda x: x['output_key'])
self.assertEqual(expected_list, sorted_actual_list)
expected_output_a = {
u'output_value': u'a', u'output_key': u'resource_output_a',
u'description': u'Output of resource a'}
expected_output_b = {
u'output_value': u'b', u'output_key': u'resource_output_b',
u'description': u'Output of resource b'}
actual_output_a = self.client.stacks.output_show(
stack_identifier, 'resource_output_a')['output']
actual_output_b = self.client.stacks.output_show(
stack_identifier, 'resource_output_b')['output']
self.assertEqual(expected_output_a, actual_output_a)
self.assertEqual(expected_output_b, actual_output_b)
before_template = '''
heat_template_version: 2015-10-15
resources:
test_resource_a:
type: OS::Heat::TestResource
properties:
value: 'foo'
outputs:
'''
after_template = '''
heat_template_version: 2015-10-15
resources:
test_resource_a:
type: OS::Heat::TestResource
properties:
value: 'foo'
test_resource_b:
type: OS::Heat::TestResource
properties:
value: {get_attr: [test_resource_a, output]}
outputs:
output_value:
description: 'Output of resource b'
value: {get_attr: [test_resource_b, output]}
'''
def test_outputs_update_new_resource(self):
stack_identifier = self.stack_create(template=self.before_template)
self.update_stack(stack_identifier, template=self.after_template)
expected_output_value = {
u'output_value': u'foo', u'output_key': u'output_value',
u'description': u'Output of resource b'}
actual_output_value = self.client.stacks.output_show(
stack_identifier, 'output_value')['output']
self.assertEqual(expected_output_value, actual_output_value)
nested_template = '''
heat_template_version: 2015-10-15
resources:
parent:
type: 1.yaml
outputs:
resource_output_a:
value: { get_attr: [parent, resource_output_a] }
description: 'parent a'
resource_output_b:
value: { get_attr: [parent, resource_output_b] }
description: 'parent b'
'''
error_template = '''
heat_template_version: 2015-10-15
resources:
test_resource_a:
type: OS::Heat::TestResource
properties:
value: 'a'
test_resource_b:
type: OS::Heat::TestResource
properties:
value: 'b'
outputs:
resource_output_a:
description: 'Output of resource a'
value: { get_attr: [test_resource_a, output] }
resource_output_b:
description: 'Output of resource b'
value: { get_param: foo }
'''
def test_output_error_nested(self):
stack_identifier = self.stack_create(
template=self.nested_template,
files={'1.yaml': self.error_template}
)
self.update_stack(stack_identifier, template=self.nested_template,
files={'1.yaml': self.error_template})
expected_list = [{u'output_key': u'resource_output_a',
u'output_value': u'a',
u'description': u'parent a'},
{u'output_key': u'resource_output_b',
u'output_value': None,
u'output_error': u'Error in parent output '
u'resource_output_b: The Parameter'
u' (foo) was not provided.',
u'description': u'parent b'}]
actual_list = self.client.stacks.get(stack_identifier).outputs
sorted_actual_list = sorted(actual_list, key=lambda x: x['output_key'])
self.assertEqual(expected_list, sorted_actual_list)

View File

@ -1,77 +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 heat_integrationtests.functional import functional_base
class StackTagTest(functional_base.FunctionalTestsBase):
template = '''
heat_template_version: 2014-10-16
description:
foo
parameters:
input:
type: string
default: test
resources:
not-used:
type: OS::Heat::TestResource
properties:
wait_secs: 1
value: {get_param: input}
'''
def test_stack_tag(self):
# Stack create with stack tags
tags = 'foo,bar'
stack_identifier = self.stack_create(
template=self.template,
tags=tags
)
# Ensure property tag is populated and matches given tags
stack = self.client.stacks.get(stack_identifier)
self.assertEqual(['foo', 'bar'], stack.tags)
# Update tags
updated_tags = 'tag1,tag2'
self.update_stack(
stack_identifier,
template=self.template,
tags=updated_tags,
parameters={'input': 'next'})
# Ensure property tag is populated and matches updated tags
updated_stack = self.client.stacks.get(stack_identifier)
self.assertEqual(['tag1', 'tag2'], updated_stack.tags)
# Delete tags
self.update_stack(
stack_identifier,
template=self.template,
parameters={'input': 'none'}
)
# Ensure property tag is not populated
empty_tags_stack = self.client.stacks.get(stack_identifier)
self.assertIsNone(empty_tags_stack.tags)
def test_hidden_stack(self):
# Stack create with hidden stack tag
tags = 'foo,hidden'
self.stack_create(
template=self.template,
tags=tags)
# Ensure stack does not exist when we do a stack list
for stack in self.client.stacks.list():
self.assertNotIn('hidden', stack.tags, "Hidden stack can be seen")

View File

@ -1,292 +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 six
from heatclient import exc
from heat_integrationtests.functional import functional_base
class StackTemplateValidateTest(functional_base.FunctionalTestsBase):
random_template = '''
heat_template_version: 2014-10-16
description: the stack description
parameters:
aparam:
type: number
default: 10
description: the param description
resources:
myres:
type: OS::Heat::RandomString
properties:
length: {get_param: aparam}
'''
parent_template = '''
heat_template_version: 2014-10-16
description: the parent template
parameters:
pparam:
type: number
default: 5
description: the param description
resources:
nres:
type: mynested.yaml
properties:
aparam: {get_param: pparam}
'''
parent_template_noprop = '''
heat_template_version: 2014-10-16
description: the parent template
resources:
nres:
type: mynested.yaml
'''
random_template_groups = '''
heat_template_version: 2014-10-16
description: the stack description
parameters:
aparam:
type: number
default: 10
description: the param description
bparam:
type: string
default: foo
cparam:
type: string
default: secret
hidden: true
parameter_groups:
- label: str_params
description: The string params
parameters:
- bparam
- cparam
resources:
myres:
type: OS::Heat::RandomString
properties:
length: {get_param: aparam}
'''
def test_template_validate_basic(self):
ret = self.client.stacks.validate(template=self.random_template)
expected = {'Description': 'the stack description',
'Parameters': {
'aparam': {'Default': 10,
'Description': 'the param description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_override_default(self):
env = {'parameters': {'aparam': 5}}
ret = self.client.stacks.validate(template=self.random_template,
environment=env)
expected = {'Description': 'the stack description',
'Parameters': {
'aparam': {'Default': 10,
'Value': 5,
'Description': 'the param description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {'aparam': 5},
'resource_registry': {u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_override_none(self):
env = {'resource_registry': {
'OS::Heat::RandomString': 'OS::Heat::None'}}
ret = self.client.stacks.validate(template=self.random_template,
environment=env)
expected = {'Description': 'the stack description',
'Parameters': {
'aparam': {'Default': 10,
'Description': 'the param description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {
'OS::Heat::RandomString': 'OS::Heat::None',
u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_basic_required_param(self):
tmpl = self.random_template.replace('default: 10', '')
ret = self.client.stacks.validate(template=tmpl)
expected = {'Description': 'the stack description',
'Parameters': {
'aparam': {'Description': 'the param description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_fail_version(self):
fail_template = self.random_template.replace('2014-10-16', 'invalid')
ex = self.assertRaises(exc.HTTPBadRequest,
self.client.stacks.validate,
template=fail_template)
self.assertIn('The template version is invalid', six.text_type(ex))
def test_template_validate_parameter_groups(self):
ret = self.client.stacks.validate(template=self.random_template_groups)
expected = {'Description': 'the stack description',
'ParameterGroups':
[{'description': 'The string params',
'label': 'str_params',
'parameters': ['bparam', 'cparam']}],
'Parameters':
{'aparam':
{'Default': 10,
'Description': 'the param description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'},
'bparam':
{'Default': 'foo',
'Description': '',
'Label': 'bparam',
'NoEcho': 'false',
'Type': 'String'},
'cparam':
{'Default': 'secret',
'Description': '',
'Label': 'cparam',
'NoEcho': 'true',
'Type': 'String'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_nested_off(self):
files = {'mynested.yaml': self.random_template}
ret = self.client.stacks.validate(template=self.parent_template,
files=files)
expected = {'Description': 'the parent template',
'Parameters': {
'pparam': {'Default': 5,
'Description': 'the param description',
'Label': 'pparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {
u'mynested.yaml': u'mynested.yaml',
u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_nested_on(self):
files = {'mynested.yaml': self.random_template}
ret = self.client.stacks.validate(template=self.parent_template_noprop,
files=files,
show_nested=True)
expected = {'Description': 'the parent template',
'Parameters': {},
'NestedParameters': {
'nres': {'Description': 'the stack description',
'Parameters': {'aparam': {'Default': 10,
'Description':
'the param '
'description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Type': 'mynested.yaml'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {
u'mynested.yaml': u'mynested.yaml',
u'resources': {}}}}
self.assertEqual(expected, ret)
def test_template_validate_nested_on_multiple(self):
# parent_template -> nested_template -> random_template
nested_template = self.random_template.replace(
'OS::Heat::RandomString', 'mynested2.yaml')
files = {'mynested.yaml': nested_template,
'mynested2.yaml': self.random_template}
ret = self.client.stacks.validate(template=self.parent_template,
files=files,
show_nested=True)
n_param2 = {'myres': {'Description': 'the stack description',
'Parameters': {'aparam': {'Default': 10,
'Description':
'the param '
'description',
'Label': 'aparam',
'NoEcho': 'false',
'Type': 'Number'}},
'Type': 'mynested2.yaml'}}
expected = {'Description': 'the parent template',
'Parameters': {
'pparam': {'Default': 5,
'Description': 'the param description',
'Label': 'pparam',
'NoEcho': 'false',
'Type': 'Number'}},
'NestedParameters': {
'nres': {'Description': 'the stack description',
'Parameters': {'aparam': {'Default': 10,
'Description':
'the param '
'description',
'Label': 'aparam',
'Value': 5,
'NoEcho': 'false',
'Type': 'Number'}},
'NestedParameters': n_param2,
'Type': 'mynested.yaml'}},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {
u'mynested.yaml': u'mynested.yaml',
'resources': {}}}}
self.assertEqual(expected, ret)

View File

@ -0,0 +1,31 @@
# 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 heat_integrationtests.functional import functional_base
class TemplateVersionTest(functional_base.FunctionalTestsBase):
"""This will test list template versions"""
def test_template_version(self):
template_versions = self.client.template_versions.list()
supported_template_versions = ["2013-05-23", "2014-10-16",
"2015-04-30", "2015-10-15",
"2012-12-12", "2010-09-09",
"2016-04-08", "2016-10-14", "newton",
"2017-02-24", "ocata",
"2017-09-01", "pike",
"2018-03-02", "queens"]
for template in template_versions:
self.assertIn(template.version.split(".")[1],
supported_template_versions)

View File

@ -1,72 +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 heat_integrationtests.functional import functional_base
class TemplateAPITest(functional_base.FunctionalTestsBase):
"""This will test the following template calls:
1. Get the template content for the specific stack
2. List template versions
3. List resource types
4. Show resource details for OS::Heat::TestResource
"""
template = {
'heat_template_version': '2014-10-16',
'description': 'Test Template APIs',
'resources': {
'test1': {
'type': 'OS::Heat::TestResource',
'properties': {
'update_replace': False,
'wait_secs': 0,
'value': 'Test1',
'fail': False,
}
}
}
}
def test_get_stack_template(self):
stack_identifier = self.stack_create(
template=self.template
)
template_from_client = self.client.stacks.template(stack_identifier)
self.assertEqual(self.template, template_from_client)
def test_template_version(self):
template_versions = self.client.template_versions.list()
supported_template_versions = ["2013-05-23", "2014-10-16",
"2015-04-30", "2015-10-15",
"2012-12-12", "2010-09-09",
"2016-04-08", "2016-10-14", "newton",
"2017-02-24", "ocata",
"2017-09-01", "pike",
"2018-03-02", "queens"]
for template in template_versions:
self.assertIn(template.version.split(".")[1],
supported_template_versions)
def test_resource_types(self):
resource_types = self.client.resource_types.list()
self.assertTrue(any(resource.resource_type == "OS::Heat::TestResource"
for resource in resource_types))
def test_show_resource_template(self):
resource_details = self.client.resource_types.get(
resource_type="OS::Heat::TestResource"
)
self.assertEqual("OS::Heat::TestResource",
resource_details['resource_type'])

View File

@ -1,122 +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 heat_integrationtests.functional import functional_base
class StackUnicodeTemplateTest(functional_base.FunctionalTestsBase):
random_template = u'''
heat_template_version: 2014-10-16
description: \u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0
parameters:
\u53c2\u6570:
type: number
default: 10
label: \u6807\u7b7e
description: \u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0
resources:
\u8d44\u6e90:
type: OS::Heat::RandomString
properties:
length: {get_param: \u53c2\u6570}
outputs:
\u8f93\u51fa:
description: \u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0
value: {get_attr: [\u8d44\u6e90, value]}
'''
def _assert_results(self, result):
self.assertTrue(result['disable_rollback'])
self.assertIsNone(result['parent'])
self.assertEqual(u'\u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0',
result['template_description'])
self.assertEqual(u'10', result['parameters'][u'\u53c2\u6570'])
def _assert_preview_results(self, result):
self._assert_results(result)
res = result['resources'][0]
self.assertEqual('/resources/%s' % res['resource_name'],
res['resource_identity']['path'])
def _assert_create_results(self, result):
self._assert_results(result)
output = result['outputs'][0]
self.assertEqual(u'\u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0',
output['description'])
self.assertEqual(u'\u8f93\u51fa', output['output_key'])
self.assertIsNotNone(output['output_value'])
def _assert_resource_results(self, result):
self.assertEqual(u'\u8d44\u6e90', result['resource_name'])
self.assertEqual('OS::Heat::RandomString',
result['resource_type'])
def test_template_validate_basic(self):
ret = self.client.stacks.validate(template=self.random_template)
expected = {
'Description': u'\u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0',
'Parameters': {
u'\u53c2\u6570': {
'Default': 10,
'Description': u'\u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0',
'Label': u'\u6807\u7b7e',
'NoEcho': 'false',
'Type': 'Number'}
},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {},
'resource_registry': {u'resources': {}}
}
}
self.assertEqual(expected, ret)
def test_template_validate_override_default(self):
env = {'parameters': {u'\u53c2\u6570': 5}}
ret = self.client.stacks.validate(template=self.random_template,
environment=env)
expected = {
'Description': u'\u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0',
'Parameters': {
u'\u53c2\u6570': {
'Default': 10,
'Value': 5,
'Description': u'\u8fd9\u662f\u4e00\u4e2a\u63cf\u8ff0',
'Label': u'\u6807\u7b7e',
'NoEcho': 'false',
'Type': 'Number'}
},
'Environment': {
'event_sinks': [],
'parameter_defaults': {},
'parameters': {u'\u53c2\u6570': 5},
'resource_registry': {u'resources': {}}
}
}
self.assertEqual(expected, ret)
def test_stack_preview(self):
result = self.client.stacks.preview(
template=self.random_template,
stack_name=self._stack_rand_name(),
disable_rollback=True).to_dict()
self._assert_preview_results(result)
def test_create_stack(self):
stack_identifier = self.stack_create(template=self.random_template)
stack = self.client.stacks.get(stack_identifier)
self._assert_create_results(stack.to_dict())
rl = self.client.resources.list(stack_identifier)
self.assertEqual(1, len(rl))
self._assert_resource_results(rl[0].to_dict())

View File

@ -21,6 +21,6 @@ sudo -E $DEST/heat/heat_integrationtests/prepare_test_env.sh
sudo -E $DEST/heat/heat_integrationtests/prepare_test_network.sh
cd $DEST/tempest
sudo tox -evenv-tempest -- stestr --test-path=$DEST/heat/heat_integrationtests --top-dir=$DEST/heat --group_regex='heat_(?:tempest_plugin\.tests|integrationtests)\.api\.test_heat_api[._]([^_]+)' run
sudo tox -evenv-tempest -- stestr --test-path=$DEST/heat/heat_integrationtests --top-dir=$DEST/heat --group_regex='heat_tempest_plugin\.tests\.api\.test_heat_api[._]([^_]+)' run
sudo -E $DEST/heat/heat_integrationtests/cleanup_test_env.sh

View File

@ -1,110 +0,0 @@
heat_template_version: 2014-10-16
description: >
This HOT template that just defines a single server.
Contains just base features to verify base heat support.
parameters:
key_name:
type: string
default: key-01
description: Name of an existing key pair to use for the server
flavor:
type: string
description: Flavor for the server to be created
default: m1.small
constraints:
- custom_constraint: nova.flavor
image:
type: string
description: Image ID or image name to use for the server
constraints:
- custom_constraint: glance.image
vol_size:
type: number
description: The size of the Cinder volume
default: 1
private_net_name:
type: string
default: private-net-01
description: Name of private network to be created
private_net_cidr:
type: string
default: 192.168.101.0/24
description: Private network address (CIDR notation)
private_net_gateway:
type: string
default: 192.168.101.1
description: Private network gateway address
private_net_pool_start:
type: string
default: 192.168.101.2
description: Start of private network IP address allocation pool
private_net_pool_end:
type: string
default: 192.168.101.127
description: End of private network IP address allocation pool
echo_foo:
default: fooooo
type: string
resources:
private_net:
type: OS::Neutron::Net
properties:
name: { get_param: private_net_name }
private_subnet:
type: OS::Neutron::Subnet
properties:
network_id: { get_resource: private_net }
cidr: { get_param: private_net_cidr }
gateway_ip: { get_param: private_net_gateway }
allocation_pools:
- start: { get_param: private_net_pool_start }
end: { get_param: private_net_pool_end }
server_port:
type: OS::Neutron::Port
properties:
network_id: { get_resource: private_net }
fixed_ips:
- subnet_id: { get_resource: private_subnet }
key:
type: OS::Nova::KeyPair
properties:
name: { get_param: key_name }
server:
type: OS::Nova::Server
properties:
key_name: { get_resource: key }
image: { get_param: image }
flavor: { get_param: flavor }
networks:
- port: { get_resource: server_port }
user_data:
str_replace:
template: |
#!/bin/bash
echo echo_foo
params:
echo_foo: { get_param: echo_foo }
vol:
type: OS::Cinder::Volume
properties:
size: { get_param: vol_size }
vol_att:
type: OS::Cinder::VolumeAttachment
properties:
instance_uuid: { get_resource: server }
volume_id: { get_resource: vol }
mountpoint: /dev/vdb
outputs:
server_networks:
description: The networks of the deployed server
value: { get_attr: [server, networks] }

View File

@ -1,73 +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 heat_integrationtests.common import test
from heat_integrationtests.scenario import scenario_base
from heatclient.common import template_utils
class BasicResourcesTest(scenario_base.ScenarioTestsBase):
def setUp(self):
super(BasicResourcesTest, self).setUp()
if not self.conf.image_ref:
raise self.skipException("No image configured to test")
if not self.conf.instance_type:
raise self.skipException("No flavor configured to test")
def check_stack(self):
sid = self.stack_identifier
# Check that stack were created
self._wait_for_stack_status(sid, 'CREATE_COMPLETE')
server_resource = self.client.resources.get(sid, 'server')
server_id = server_resource.physical_resource_id
server = self.compute_client.servers.get(server_id)
self.assertEqual(server.id, server_id)
stack = self.client.stacks.get(sid)
server_networks = self._stack_output(stack, 'server_networks')
self.assertIn(self.private_net_name, server_networks)
def test_base_resources_integration(self):
"""Define test for base resources interation from core porjects
The alternative scenario is the following:
1. Create a stack with basic resources from core projects.
2. Check that all stack resources are created successfully.
3. Wait for deployment.
4. Check that stack was created.
5. Check stack outputs.
"""
self.private_net_name = test.rand_name('heat-net')
parameters = {
'key_name': test.rand_name('heat-key'),
'flavor': self.conf.instance_type,
'image': self.conf.image_ref,
'vol_size': self.conf.volume_size,
'private_net_name': self.private_net_name
}
env_files, env = template_utils.process_environment_and_files(
self.conf.boot_config_env)
# Launch stack
self.stack_identifier = self.launch_stack(
template_name='test_base_resources.yaml',
parameters=parameters,
expected_status=None,
environment=env
)
# Check stack
self.check_stack()

View File

@ -27,4 +27,3 @@ reno>=2.5.0 # Apache-2.0
os-collect-config>=5.0.0 # Apache-2.0
paramiko>=2.0.0 # LGPLv2.1+
tempest>=17.1.0 # Apache-2.0
gabbi>=1.35.0 # Apache-2.0