Merge "FunctionalTests don't run non-test check_skip_test"
diff --git a/common/config.py b/common/config.py
index c715c88..9ad6337 100644
--- a/common/config.py
+++ b/common/config.py
@@ -120,7 +120,10 @@
cfg.IntOpt('sighup_timeout',
default=30,
help="Timeout in seconds to wait for adding or removing child"
- "process after receiving of sighup signal")
+ "process after receiving of sighup signal"),
+ cfg.StrOpt('heat-config-notify-script',
+ default=('heat-config-notify'),
+ help="Path to the script heat-config-notify"),
]
diff --git a/functional/test_create_update.py b/functional/test_create_update.py
index c9b8add..8c78951 100644
--- a/functional/test_create_update.py
+++ b/functional/test_create_update.py
@@ -520,10 +520,8 @@
'image': self.conf.minimal_image_ref,
'network': self.conf.fixed_network_name,
'user_data': ''}
- name = self._stack_rand_name()
stack_identifier = self.stack_create(
- stack_name=name,
template=self.update_userdata_template,
parameters=parms
)
diff --git a/functional/test_nova_server_networks.py b/functional/test_nova_server_networks.py
new file mode 100644
index 0000000..99311d0
--- /dev/null
+++ b/functional/test_nova_server_networks.py
@@ -0,0 +1,66 @@
+# 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
+
+
+server_with_sub_fixed_ip_template = '''
+heat_template_version: 2016-04-08
+description: Test template to test nova server with subnet and fixed_ip.
+parameters:
+ flavor:
+ type: string
+ image:
+ type: string
+resources:
+ net:
+ type: OS::Neutron::Net
+ properties:
+ name: my_net
+ subnet:
+ type: OS::Neutron::Subnet
+ properties:
+ network: {get_resource: net}
+ cidr: 11.11.11.0/24
+ server:
+ type: OS::Nova::Server
+ properties:
+ image: {get_param: image}
+ flavor: {get_param: flavor}
+ networks:
+ - subnet: {get_resource: subnet}
+ fixed_ip: 11.11.11.11
+outputs:
+ networks:
+ value: {get_attr: [server, networks]}
+'''
+
+
+class CreateServerTest(functional_base.FunctionalTestsBase):
+
+ def setUp(self):
+ super(CreateServerTest, self).setUp()
+
+ def get_outputs(self, stack_identifier, output_key):
+ stack = self.client.stacks.get(stack_identifier)
+ output = self._stack_output(stack, output_key)
+ return output
+
+ def test_create_server_with_subnet_fixed_ip(self):
+ parms = {'flavor': self.conf.minimal_instance_type,
+ 'image': self.conf.minimal_image_ref}
+ stack_identifier = self.stack_create(
+ template=server_with_sub_fixed_ip_template,
+ stack_name='server_with_sub_ip',
+ parameters=parms)
+ networks = self.get_outputs(stack_identifier, 'networks')
+ self.assertEqual(['11.11.11.11'], networks['my_net'])
diff --git a/functional/test_preview_update.py b/functional/test_preview_update.py
index 85306de..0e39bc9 100644
--- a/functional/test_preview_update.py
+++ b/functional/test_preview_update.py
@@ -10,7 +10,6 @@
# License for the specific language governing permissions and limitations
# under the License.
-
from heat_integrationtests.functional import functional_base
test_template_one_resource = {
@@ -57,12 +56,9 @@
class UpdatePreviewStackTest(functional_base.FunctionalTestsBase):
- def setUp(self):
- super(UpdatePreviewStackTest, self).setUp()
+ def test_add_resource(self):
self.stack_identifier = self.stack_create(
template=test_template_one_resource)
-
- def test_add_resource(self):
result = self.preview_update_stack(self.stack_identifier,
test_template_two_resource)
changes = result['resource_changes']
@@ -78,6 +74,8 @@
self.assertEqual([], changes[section])
def test_no_change(self):
+ self.stack_identifier = self.stack_create(
+ template=test_template_one_resource)
result = self.preview_update_stack(self.stack_identifier,
test_template_one_resource)
changes = result['resource_changes']
@@ -90,6 +88,8 @@
self.assertEqual([], changes[section])
def test_update_resource(self):
+ self.stack_identifier = self.stack_create(
+ template=test_template_one_resource)
test_template_updated_resource = {
'heat_template_version': '2013-05-23',
'description': 'Test template to create one instance.',
@@ -118,19 +118,8 @@
self.assertEqual([], changes[section])
def test_replaced_resource(self):
- orig_template = {
- 'heat_template_version': '2013-05-23',
- 'description': 'Test template to create one instance.',
- 'resources': {
- 'test1': {
- 'type': 'OS::Heat::TestResource',
- 'properties': {
- 'update_replace': False,
- }
- }
- }
- }
-
+ self.stack_identifier = self.stack_create(
+ template=test_template_one_resource)
new_template = {
'heat_template_version': '2013-05-23',
'description': 'Test template to create one instance.',
@@ -144,8 +133,7 @@
}
}
- stack_identifier = self.stack_create(template=orig_template)
- result = self.preview_update_stack(stack_identifier, new_template)
+ result = self.preview_update_stack(self.stack_identifier, new_template)
changes = result['resource_changes']
replaced = changes['replaced'][0]['resource_name']
@@ -156,9 +144,9 @@
self.assertEqual([], changes[section])
def test_delete_resource(self):
- stack_identifier = self.stack_create(
+ self.stack_identifier = self.stack_create(
template=test_template_two_resource)
- result = self.preview_update_stack(stack_identifier,
+ result = self.preview_update_stack(self.stack_identifier,
test_template_one_resource)
changes = result['resource_changes']
diff --git a/functional/test_remote_stack.py b/functional/test_remote_stack.py
index 91a165c..96306ac 100644
--- a/functional/test_remote_stack.py
+++ b/functional/test_remote_stack.py
@@ -78,11 +78,9 @@
self.assertEqual(remote_resources, self.list_resources(remote_id))
def test_stack_create_bad_region(self):
- stack_name = self._stack_rand_name()
tmpl_bad_region = self.template.replace('RegionOne', 'DARKHOLE')
files = {'remote_stack.yaml': self.remote_template}
kwargs = {
- 'stack_name': stack_name,
'template': tmpl_bad_region,
'files': files
}
@@ -94,10 +92,9 @@
self.assertEqual(error_msg, six.text_type(ex))
def test_stack_resource_validation_fail(self):
- stack_name = self._stack_rand_name()
tmpl_bad_format = self.remote_template.replace('resources', 'resource')
files = {'remote_stack.yaml': tmpl_bad_format}
- kwargs = {'stack_name': stack_name, 'files': files}
+ kwargs = {'files': files}
ex = self.assertRaises(exc.HTTPBadRequest, self.stack_create, **kwargs)
error_msg = ('ERROR: Failed validating stack template using Heat '
diff --git a/functional/test_software_config.py b/functional/test_software_config.py
index af7d671..20d38d8 100644
--- a/functional/test_software_config.py
+++ b/functional/test_software_config.py
@@ -10,11 +10,16 @@
# License for the specific language governing permissions and limitations
# under the License.
-from oslo_utils import timeutils
+import json
+import os
import requests
+import subprocess
+import tempfile
import time
import yaml
+from oslo_utils import timeutils
+
from heat_integrationtests.common import exceptions
from heat_integrationtests.functional import functional_base
@@ -145,3 +150,104 @@
sigurl = iv.get('deploy_signal_id')
requests.post(sigurl, data='{}',
headers={'content-type': None})
+
+
+class ZaqarSignalTransportTest(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
+ software_config_transport: ZAQAR_MESSAGE
+ networks: [{network: {get_param: network}}]
+ config:
+ type: OS::Heat::SoftwareConfig
+ properties:
+ config: echo 'foo'
+ deployment:
+ type: OS::Heat::SoftwareDeployment
+ properties:
+ config: {get_resource: config}
+ server: {get_resource: server}
+ signal_transport: ZAQAR_SIGNAL
+
+outputs:
+ data:
+ value: {get_attr: [deployment, deploy_stdout]}
+'''
+
+ conf_template = '''
+[zaqar]
+user_id = %(user_id)s
+password = %(password)s
+project_id = %(project_id)s
+auth_url = %(auth_url)s
+queue_id = %(queue_id)s
+ '''
+
+ def test_signal_queues(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,
+ expected_status=None)
+ metadata = self.wait_for_deploy_metadata_set(stack_identifier)
+ config = metadata['os-collect-config']['zaqar']
+ conf_content = self.conf_template % config
+ fd, temp_path = tempfile.mkstemp()
+ os.write(fd, conf_content)
+ os.close(fd)
+ cmd = ['os-collect-config', '--one-time',
+ '--config-file=%s' % temp_path, 'zaqar']
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ stdout_value = proc.communicate()[0]
+ data = json.loads(stdout_value)
+ self.assertEqual(config, data['zaqar']['os-collect-config']['zaqar'])
+ proc = subprocess.Popen(cmd, stdout=subprocess.PIPE)
+ stdout_value = proc.communicate()[0]
+ data = json.loads(stdout_value)
+
+ fd, temp_path = tempfile.mkstemp()
+ os.write(fd, json.dumps(data['zaqar']['deployments'][0]))
+ os.close(fd)
+ cmd = ['python', self.conf.heat_config_notify_script, temp_path]
+ proc = subprocess.Popen(cmd,
+ stderr=subprocess.PIPE,
+ stdin=subprocess.PIPE)
+ proc.communicate(json.dumps({'deploy_stdout': 'here!'}))
+ self._wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
+ stack = self.client.stacks.get(stack_identifier)
+ self.assertEqual('here!', stack.outputs[0]['output_value'])
+
+ def wait_for_deploy_metadata_set(self, stack):
+ 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 server_metadata.get('deployments'):
+ return server_metadata
+ time.sleep(build_interval)
+
+ message = ('Deployment resources failed to be created within '
+ 'the required time (%s s).' %
+ (build_timeout))
+ raise exceptions.TimeoutException(message)
diff --git a/functional/test_stack_outputs.py b/functional/test_stack_outputs.py
new file mode 100644
index 0000000..4bb67db
--- /dev/null
+++ b/functional/test_stack_outputs.py
@@ -0,0 +1,62 @@
+# 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']
+ self.assertEqual(expected_list, 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)
diff --git a/scenario/test_server_software_config.py b/scenario/test_server_software_config.py
index ad76763..75de02e 100644
--- a/scenario/test_server_software_config.py
+++ b/scenario/test_server_software_config.py
@@ -37,15 +37,12 @@
mode => 0644,
content => "The file /tmp/$::bar contains $::foo for server \
$::deploy_server_id during $::deploy_action",
-}'''
+}
+'''
class SoftwareConfigIntegrationTest(scenario_base.ScenarioTestsBase):
- def setUp(self):
- super(SoftwareConfigIntegrationTest, self).setUp()
- self.stack_name = self._stack_rand_name()
-
def check_stack(self):
sid = self.stack_identifier
# Check that all stack resources were created
@@ -160,7 +157,6 @@
# Launch stack
self.stack_identifier = self.launch_stack(
- stack_name=self.stack_name,
template_name='test_server_software_config.yaml',
parameters=parameters,
files=dict(list(files.items()) + list(env_files.items())),