Merge "Integration test for software-config tools"

This commit is contained in:
Jenkins 2015-02-24 01:06:33 +00:00 committed by Gerrit Code Review
commit 69a3599767
5 changed files with 340 additions and 1 deletions

View File

@ -85,6 +85,9 @@ IntegrationTestGroup = [
cfg.IntOpt('tenant_network_mask_bits',
default=28,
help="The mask bits for tenant ipv4 subnets"),
cfg.BoolOpt('skip_software_config_tests',
default=True,
help="Skip software config deployment tests"),
cfg.IntOpt('volume_size',
default=1,
help='Default size in GB for volumes created by volumes tests'),

View File

@ -311,7 +311,8 @@ class HeatIntegrationTest(testscenarios.WithScenarios,
stack = self.client.stacks.get(name)
stack_identifier = '%s/%s' % (name, stack.id)
self._wait_for_stack_status(stack_identifier, expected_status)
if expected_status:
self._wait_for_stack_status(stack_identifier, expected_status)
return stack_identifier
def stack_adopt(self, stack_name=None, files=None,

View File

@ -67,6 +67,9 @@
# The mask bits for tenant ipv4 subnets (integer value)
#tenant_network_mask_bits = 28
# Skip software config deployment tests (boolean value)
#skip_software_config_tests = true
# Default size in GB for volumes created by volumes tests (integer value)
#volume_size = 1

View File

@ -0,0 +1,174 @@
heat_template_version: 2014-10-16
parameters:
key_name:
type: string
flavor:
type: string
image:
type: string
network:
type: string
signal_transport:
type: string
default: CFN_SIGNAL
dep1_foo:
default: fooooo
type: string
dep1_bar:
default: baaaaa
type: string
dep2a_bar:
type: string
default: barrr
dep3_foo:
default: fo
type: string
dep3_bar:
default: ba
type: string
resources:
the_sg:
type: OS::Neutron::SecurityGroup
properties:
name: the_sg
description: Ping and SSH
rules:
- protocol: icmp
- protocol: tcp
port_range_min: 22
port_range_max: 22
cfg1:
type: OS::Heat::SoftwareConfig
properties:
group: script
inputs:
- name: foo
- name: bar
outputs:
- name: result
config: {get_file: cfg1.sh}
cfg2a:
type: OS::Heat::StructuredConfig
properties:
group: cfn-init
inputs:
- name: bar
config:
config:
files:
/tmp/cfn-init-foo:
content:
get_input: bar
mode: '000644'
cfg2b:
type: OS::Heat::SoftwareConfig
properties:
group: script
outputs:
- name: result
config: |
#!/bin/sh
echo -n "The file /tmp/cfn-init-foo contains `cat /tmp/cfn-init-foo` for server $deploy_server_id during $deploy_action" > $heat_outputs_path.result
cfg3:
type: OS::Heat::SoftwareConfig
properties:
group: puppet
inputs:
- name: foo
- name: bar
outputs:
- name: result
config: {get_file: cfg3.pp}
dep1:
type: OS::Heat::SoftwareDeployment
properties:
config:
get_resource: cfg1
server:
get_resource: server
input_values:
foo: {get_param: dep1_foo}
bar: {get_param: dep1_bar}
signal_transport: {get_param: signal_transport}
dep2a:
type: OS::Heat::StructuredDeployment
properties:
name: 10_dep2a
signal_transport: NO_SIGNAL
config:
get_resource: cfg2a
server:
get_resource: server
input_values:
bar: {get_param: dep2a_bar}
dep2b:
type: OS::Heat::SoftwareDeployment
properties:
name: 20_dep2b
config:
get_resource: cfg2b
server:
get_resource: server
signal_transport: {get_param: signal_transport}
dep3:
type: OS::Heat::SoftwareDeployment
properties:
config:
get_resource: cfg3
server:
get_resource: server
input_values:
foo: {get_param: dep3_foo}
bar: {get_param: dep3_bar}
signal_transport: {get_param: signal_transport}
cfg_user_data:
type: OS::Heat::SoftwareConfig
properties:
config: |
#!/bin/sh
echo "user data script"
server:
type: OS::Nova::Server
properties:
image: {get_param: image}
flavor: {get_param: flavor}
key_name: {get_param: key_name}
security_groups:
- {get_resource: the_sg}
networks:
- network: {get_param: network}
user_data_format: SOFTWARE_CONFIG
software_config_transport: POLL_TEMP_URL
user_data: {get_resource: cfg_user_data}
outputs:
res1:
value:
result: {get_attr: [dep1, result]}
stdout: {get_attr: [dep1, deploy_stdout]}
stderr: {get_attr: [dep1, deploy_stderr]}
status_code: {get_attr: [dep1, deploy_status_code]}
res2:
value:
result: {get_attr: [dep2b, result]}
stdout: {get_attr: [dep2b, deploy_stdout]}
stderr: {get_attr: [dep2b, deploy_stderr]}
status_code: {get_attr: [dep2b, deploy_status_code]}
res3:
value:
result: {get_attr: [dep3, result]}
stdout: {get_attr: [dep3, deploy_stdout]}
stderr: {get_attr: [dep3, deploy_stderr]}
status_code: {get_attr: [dep3, deploy_status_code]}

View File

@ -0,0 +1,158 @@
# 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 heat_integrationtests.common import exceptions
from heat_integrationtests.common import test
CFG1_SH = '''#!/bin/sh
echo "Writing to /tmp/$bar"
echo $foo > /tmp/$bar
echo -n "The file /tmp/$bar contains `cat /tmp/$bar` for server \
$deploy_server_id during $deploy_action" > $heat_outputs_path.result
echo "Written to /tmp/$bar"
echo "Output to stderr" 1>&2
'''
CFG3_PP = '''file {'barfile':
ensure => file,
mode => 0644,
path => "/tmp/$::bar",
content => "$::foo",
}
file {'output_result':
ensure => file,
path => "$::heat_outputs_path.result",
mode => 0644,
content => "The file /tmp/$::bar contains $::foo for server \
$::deploy_server_id during $::deploy_action",
}'''
class SoftwareConfigIntegrationTest(test.HeatIntegrationTest):
def setUp(self):
super(SoftwareConfigIntegrationTest, self).setUp()
if self.conf.skip_software_config_tests:
self.skipTest('Testing software config disabled in conf, '
'skipping')
self.client = self.orchestration_client
self.template_name = 'test_server_software_config.yaml'
self.sub_dir = 'templates'
self.stack_name = self._stack_rand_name()
self.maxDiff = None
def launch_stack(self):
net = self._get_default_network()
self.parameters = {
'key_name': self.keypair_name,
'flavor': self.conf.instance_type,
'image': self.conf.image_ref,
'network': net['id']
}
# create the stack
self.template = self._load_template(__file__, self.template_name,
self.sub_dir)
self.stack_create(
stack_name=self.stack_name,
template=self.template,
parameters=self.parameters,
files={
'cfg1.sh': CFG1_SH,
'cfg3.pp': CFG3_PP
},
expected_status=None)
self.stack = self.client.stacks.get(self.stack_name)
self.stack_identifier = '%s/%s' % (self.stack_name, self.stack.id)
def check_stack(self):
sid = self.stack_identifier
for res in ('cfg2a', 'cfg2b', 'cfg1', 'cfg3', 'server'):
self._wait_for_resource_status(
sid, res, '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)
try:
# wait for each deployment to contribute their
# config to resource
for res in ('dep2b', 'dep1', 'dep3'):
self._wait_for_resource_status(
sid, res, 'CREATE_IN_PROGRESS')
server_metadata = self.client.resources.metadata(sid, 'server')
deployments = dict((d['name'], d) for d in
server_metadata['deployments'])
for res in ('dep2a', 'dep2b', 'dep1', 'dep3'):
self._wait_for_resource_status(
sid, res, 'CREATE_COMPLETE')
except (exceptions.StackResourceBuildErrorException,
exceptions.TimeoutException) as e:
self._log_console_output(servers=[server])
raise e
self._wait_for_stack_status(sid, 'CREATE_COMPLETE')
complete_server_metadata = self.client.resources.metadata(
sid, 'server')
# ensure any previously available deployments haven't changed so
# config isn't re-triggered
complete_deployments = dict((d['name'], d) for d in
complete_server_metadata['deployments'])
for k, v in six.iteritems(deployments):
self.assertEqual(v, complete_deployments[k])
stack = self.client.stacks.get(sid)
res1 = self._stack_output(stack, 'res1')
self.assertEqual(
'The file %s contains %s for server %s during %s' % (
'/tmp/baaaaa', 'fooooo', server_id, 'CREATE'),
res1['result'])
self.assertEqual(0, res1['status_code'])
self.assertEqual('Output to stderr\n', res1['stderr'])
self.assertTrue(len(res1['stdout']) > 0)
res2 = self._stack_output(stack, 'res2')
self.assertEqual(
'The file %s contains %s for server %s during %s' % (
'/tmp/cfn-init-foo', 'barrr', server_id, 'CREATE'),
res2['result'])
self.assertEqual(0, res2['status_code'])
self.assertEqual('', res2['stderr'])
self.assertEqual('', res2['stdout'])
res3 = self._stack_output(stack, 'res3')
self.assertEqual(
'The file %s contains %s for server %s during %s' % (
'/tmp/ba', 'fo', server_id, 'CREATE'),
res3['result'])
self.assertEqual(0, res3['status_code'])
self.assertEqual('', res3['stderr'])
self.assertTrue(len(res1['stdout']) > 0)
dep1_resource = self.client.resources.get(sid, 'dep1')
dep1_id = dep1_resource.physical_resource_id
dep1_dep = self.client.software_deployments.get(dep1_id)
self.assertIsNotNone(dep1_dep.updated_time)
self.assertNotEqual(dep1_dep.updated_time, dep1_dep.creation_time)
def test_server_software_config(self):
self.assign_keypair()
self.launch_stack()
self.check_stack()