tests : convert test_template_format to test-local templates

test_template_format is different from all other tests, in that
we don't want to use the most minimal template possible, we
actually want to test conversion works with maximal/non-trivial
templates, so copy the two templates used by this test into a
local tests/templates directory, with a README caution that
in general inline-minimal templates are preferred.

Change-Id: Ib5421545103728385992625884f86f2667ee2465
This commit is contained in:
Steven Hardy 2013-05-07 15:59:49 +01:00
parent 5e2a562fc4
commit 04aa1215a1
6 changed files with 499 additions and 25 deletions

View File

@ -0,0 +1,100 @@
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "Template to test Quantum resources",
"Parameters" : {
},
"Resources" : {
"network": {
"Type": "OS::Quantum::Net",
"Properties": {
"name": "the_network"
}
},
"unnamed_network": {
"Type": "OS::Quantum::Net"
},
"admin_down_network": {
"Type": "OS::Quantum::Net",
"Properties": {
"admin_state_up": false
}
},
"subnet": {
"Type": "OS::Quantum::Subnet",
"Properties": {
"network_id": { "Ref" : "network" },
"ip_version": 4,
"cidr": "10.0.3.0/24",
"allocation_pools": [{"start": "10.0.3.20", "end": "10.0.3.150"}]
}
},
"port": {
"Type": "OS::Quantum::Port",
"Properties": {
"device_id": "d6b4d3a5-c700-476f-b609-1493dd9dadc0",
"name": "port1",
"network_id": { "Ref" : "network" },
"fixed_ips": [{
"subnet_id": { "Ref" : "subnet" },
"ip_address": "10.0.3.21"
}]
}
},
"router": {
"Type": "OS::Quantum::Router"
},
"router_interface": {
"Type": "OS::Quantum::RouterInterface",
"Properties": {
"router_id": { "Ref" : "router" },
"subnet_id": { "Ref" : "subnet" }
}
}
},
"Outputs" : {
"the_network_status" : {
"Value" : { "Fn::GetAtt" : [ "network", "status" ]},
"Description" : "Status of network"
},
"port_device_owner" : {
"Value" : { "Fn::GetAtt" : [ "port", "device_owner" ]},
"Description" : "Device owner of the port"
},
"port_fixed_ips" : {
"Value" : { "Fn::GetAtt" : [ "port", "fixed_ips" ]},
"Description" : "Fixed IPs of the port"
},
"port_mac_address" : {
"Value" : { "Fn::GetAtt" : [ "port", "mac_address" ]},
"Description" : "MAC address of the port"
},
"port_status" : {
"Value" : { "Fn::GetAtt" : [ "port", "status" ]},
"Description" : "Status of the port"
},
"port_show" : {
"Value" : { "Fn::GetAtt" : [ "port", "show" ]},
"Description" : "All attributes for port"
},
"subnet_show" : {
"Value" : { "Fn::GetAtt" : [ "subnet", "show" ]},
"Description" : "All attributes for subnet"
},
"network_show" : {
"Value" : { "Fn::GetAtt" : [ "network", "show" ]},
"Description" : "All attributes for network"
},
"router_show" : {
"Value" : { "Fn::GetAtt" : [ "router", "show" ]},
"Description" : "All attributes for router"
}
}
}

View File

@ -0,0 +1,72 @@
HeatTemplateFormatVersion: '2012-12-12'
Description: Template to test Quantum resources
Resources:
network:
Type: OS::Quantum::Net
Properties: {name: the_network}
unnamed_network:
Type: 'OS::Quantum::Net'
admin_down_network:
Type: OS::Quantum::Net
Properties: {admin_state_up: false}
subnet:
Type: OS::Quantum::Subnet
Properties:
network_id: {Ref: network}
ip_version: 4
cidr: 10.0.3.0/24
allocation_pools:
- {end: 10.0.3.150, start: 10.0.3.20}
port:
Type: OS::Quantum::Port
Properties:
device_id: d6b4d3a5-c700-476f-b609-1493dd9dadc0
name: port1
network_id: {Ref: network}
fixed_ips:
- subnet_id: {Ref: subnet}
ip_address: 10.0.3.21
router:
Type: 'OS::Quantum::Router'
router_interface:
Type: OS::Quantum::RouterInterface
Properties:
router_id: {Ref: router}
subnet_id: {Ref: subnet}
Outputs:
the_network_status:
Value:
Fn::GetAtt: [network, status]
Description: Status of network
port_device_owner:
Value:
Fn::GetAtt: [port, device_owner]
Description: Device owner of the port
port_fixed_ips:
Value:
Fn::GetAtt: [port, fixed_ips]
Description: Fixed IPs of the port
port_mac_address:
Value:
Fn::GetAtt: [port, mac_address]
Description: MAC address of the port
port_status:
Value:
Fn::GetAtt: [port, status]
Description: Status of the port
port_show:
Value:
Fn::GetAtt: [port, show]
Description: All attributes for port
subnet_show:
Value:
Fn::GetAtt: [subnet, show]
Description: All attributes for subnet
network_show:
Value:
Fn::GetAtt: [network, show]
Description: All attributes for network
router_show:
Value:
Fn::GetAtt: [router, show]
Description: All attributes for router

View File

@ -0,0 +1,6 @@
These templates are required by test_template_format, where we don't want to
use a minimal template snippet (we want ideally to test the maximum possible
syntax to prove the format conversion works)
In general, tests should not depend on these templates, inline minimal
template snippets are preferred.

View File

@ -0,0 +1,149 @@
{
"AWSTemplateFormatVersion" : "2010-09-09",
"Description" : "AWS CloudFormation Sample Template WordPress_Single_Instance: WordPress is web software you can use to create a beautiful website or blog. This template installs a single-instance WordPress deployment using a local MySQL database to store the data.",
"Parameters" : {
"KeyName" : {
"Description" : "Name of an existing EC2 KeyPair to enable SSH access to the instances",
"Type" : "String"
},
"InstanceType" : {
"Description" : "WebServer EC2 instance type",
"Type" : "String",
"Default" : "m1.large",
"AllowedValues" : [ "t1.micro", "m1.small", "m1.large", "m1.xlarge", "m2.xlarge", "m2.2xlarge", "m2.4xlarge", "c1.medium", "c1.xlarge", "cc1.4xlarge" ],
"ConstraintDescription" : "must be a valid EC2 instance type."
},
"DBName": {
"Default": "wordpress",
"Description" : "The WordPress database name",
"Type": "String",
"MinLength": "1",
"MaxLength": "64",
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
"ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
},
"DBUsername": {
"Default": "admin",
"NoEcho": "true",
"Description" : "The WordPress database admin account username",
"Type": "String",
"MinLength": "1",
"MaxLength": "16",
"AllowedPattern" : "[a-zA-Z][a-zA-Z0-9]*",
"ConstraintDescription" : "must begin with a letter and contain only alphanumeric characters."
},
"DBPassword": {
"Default": "admin",
"NoEcho": "true",
"Description" : "The WordPress database admin account password",
"Type": "String",
"MinLength": "1",
"MaxLength": "41",
"AllowedPattern" : "[a-zA-Z0-9]*",
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"DBRootPassword": {
"Default": "admin",
"NoEcho": "true",
"Description" : "Root password for MySQL",
"Type": "String",
"MinLength": "1",
"MaxLength": "41",
"AllowedPattern" : "[a-zA-Z0-9]*",
"ConstraintDescription" : "must contain only alphanumeric characters."
},
"LinuxDistribution": {
"Default": "F17",
"Description" : "Distribution of choice",
"Type": "String",
"AllowedValues" : [ "F18", "F17", "U10", "RHEL-6.1", "RHEL-6.2", "RHEL-6.3" ]
}
},
"Mappings" : {
"AWSInstanceType2Arch" : {
"t1.micro" : { "Arch" : "32" },
"m1.small" : { "Arch" : "32" },
"m1.large" : { "Arch" : "64" },
"m1.xlarge" : { "Arch" : "64" },
"m2.xlarge" : { "Arch" : "64" },
"m2.2xlarge" : { "Arch" : "64" },
"m2.4xlarge" : { "Arch" : "64" },
"c1.medium" : { "Arch" : "32" },
"c1.xlarge" : { "Arch" : "64" },
"cc1.4xlarge" : { "Arch" : "64" }
},
"DistroArch2AMI": {
"F18" : { "32" : "F18-i386-cfntools", "64" : "F18-x86_64-cfntools" },
"F17" : { "32" : "F17-i386-cfntools", "64" : "F17-x86_64-cfntools" },
"U10" : { "32" : "U10-i386-cfntools", "64" : "U10-x86_64-cfntools" },
"RHEL-6.1" : { "32" : "rhel61-i386-cfntools", "64" : "rhel61-x86_64-cfntools" },
"RHEL-6.2" : { "32" : "rhel62-i386-cfntools", "64" : "rhel62-x86_64-cfntools" },
"RHEL-6.3" : { "32" : "rhel63-i386-cfntools", "64" : "rhel63-x86_64-cfntools" }
}
},
"Resources" : {
"WikiDatabase": {
"Type": "AWS::EC2::Instance",
"Metadata" : {
"AWS::CloudFormation::Init" : {
"config" : {
"packages" : {
"yum" : {
"mysql" : [],
"mysql-server" : [],
"httpd" : [],
"wordpress" : []
}
},
"services" : {
"systemd" : {
"mysqld" : { "enabled" : "true", "ensureRunning" : "true" },
"httpd" : { "enabled" : "true", "ensureRunning" : "true" }
}
}
}
}
},
"Properties": {
"ImageId" : { "Fn::FindInMap" : [ "DistroArch2AMI", { "Ref" : "LinuxDistribution" },
{ "Fn::FindInMap" : [ "AWSInstanceType2Arch", { "Ref" : "InstanceType" }, "Arch" ] } ] },
"InstanceType" : { "Ref" : "InstanceType" },
"KeyName" : { "Ref" : "KeyName" },
"UserData" : { "Fn::Base64" : { "Fn::Join" : ["", [
"#!/bin/bash -v\n",
"/opt/aws/bin/cfn-init\n",
"# Setup MySQL root password and create a user\n",
"mysqladmin -u root password '", { "Ref" : "DBRootPassword" }, "'\n",
"cat << EOF | mysql -u root --password='", { "Ref" : "DBRootPassword" }, "'\n",
"CREATE DATABASE ", { "Ref" : "DBName" }, ";\n",
"GRANT ALL PRIVILEGES ON ", { "Ref" : "DBName" }, ".* TO \"", { "Ref" : "DBUsername" }, "\"@\"localhost\"\n",
"IDENTIFIED BY \"", { "Ref" : "DBPassword" }, "\";\n",
"FLUSH PRIVILEGES;\n",
"EXIT\n",
"EOF\n",
"sed -i \"/Deny from All/d\" /etc/httpd/conf.d/wordpress.conf\n",
"sed -i \"s/Require local/Require all granted/\" /etc/httpd/conf.d/wordpress.conf\n",
"sed --in-place --e s/database_name_here/", { "Ref" : "DBName" }, "/ --e s/username_here/", { "Ref" : "DBUsername" }, "/ --e s/password_here/", { "Ref" : "DBPassword" }, "/ /usr/share/wordpress/wp-config.php\n",
"systemctl restart httpd.service\n"
]]}}
}
}
},
"Outputs" : {
"WebsiteURL" : {
"Value" : { "Fn::Join" : ["", ["http://", { "Fn::GetAtt" : [ "WikiDatabase", "PublicIp" ]}, "/wordpress"]] },
"Description" : "URL for Wordpress wiki"
}
}
}

View File

@ -0,0 +1,161 @@
HeatTemplateFormatVersion: '2012-12-12'
Description: 'AWS CloudFormation Sample Template WordPress_Single_Instance:
WordPress is web software you can use to create a beautiful website or blog. This
template installs a single-instance WordPress deployment using a local MySQL database
to store the data.'
Parameters:
KeyName: {Description: Name of an existing EC2 KeyPair
to enable SSH access to the instances, Type: String}
InstanceType:
Description: WebServer EC2 instance type
Type: String
Default: m1.large
AllowedValues: [t1.micro, m1.small, m1.large, m1.xlarge, m2.xlarge,
m2.2xlarge, m2.4xlarge, c1.medium, c1.xlarge, cc1.4xlarge]
ConstraintDescription: must be a valid EC2 instance type.
DBName: {Default: wordpress, Description: The
WordPress database name, Type: String, MinLength: '1',
MaxLength: '64', AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*',
ConstraintDescription: must begin with a letter and contain only
alphanumeric characters.}
DBUsername: {Default: admin, NoEcho: 'true',
Description: The WordPress database admin account username, Type: String,
MinLength: '1', MaxLength: '16', AllowedPattern: '[a-zA-Z][a-zA-Z0-9]*',
ConstraintDescription: must begin with a letter and contain only
alphanumeric characters.}
DBPassword: {Default: admin, NoEcho: 'true',
Description: The WordPress database admin account password, Type: String,
MinLength: '1', MaxLength: '41', AllowedPattern: '[a-zA-Z0-9]*',
ConstraintDescription: must contain only alphanumeric characters.}
DBRootPassword: {Default: admin, NoEcho: 'true',
Description: Root password for MySQL, Type: String,
MinLength: '1', MaxLength: '41', AllowedPattern: '[a-zA-Z0-9]*',
ConstraintDescription: must contain only alphanumeric characters.}
LinuxDistribution:
Default: F17
Description: Distribution of choice
Type: String
AllowedValues: [F18, F17, U10, RHEL-6.1, RHEL-6.2, RHEL-6.3]
Mappings:
AWSInstanceType2Arch:
t1.micro: {Arch: '32'}
m1.small: {Arch: '32'}
m1.large: {Arch: '64'}
m1.xlarge: {Arch: '64'}
m2.xlarge: {Arch: '64'}
m2.2xlarge: {Arch: '64'}
m2.4xlarge: {Arch: '64'}
c1.medium: {Arch: '32'}
c1.xlarge: {Arch: '64'}
cc1.4xlarge: {Arch: '64'}
DistroArch2AMI:
F18: {'32': F18-i386-cfntools, '64': F18-x86_64-cfntools}
F17: {'32': F17-i386-cfntools, '64': F17-x86_64-cfntools}
U10: {'32': U10-i386-cfntools, '64': U10-x86_64-cfntools}
RHEL-6.1: {'32': rhel61-i386-cfntools, '64': rhel61-x86_64-cfntools}
RHEL-6.2: {'32': rhel62-i386-cfntools, '64': rhel62-x86_64-cfntools}
RHEL-6.3: {'32': rhel63-i386-cfntools, '64': rhel63-x86_64-cfntools}
Resources:
WikiDatabase:
Type: AWS::EC2::Instance
Metadata:
AWS::CloudFormation::Init:
config:
packages:
yum:
mysql: []
mysql-server: []
httpd: []
wordpress: []
services:
systemd:
mysqld: {enabled: 'true', ensureRunning: 'true'}
httpd: {enabled: 'true', ensureRunning: 'true'}
Properties:
ImageId:
Fn::FindInMap:
- DistroArch2AMI
- {Ref: LinuxDistribution}
- Fn::FindInMap:
- AWSInstanceType2Arch
- {Ref: InstanceType}
- Arch
InstanceType: {Ref: InstanceType}
KeyName: {Ref: KeyName}
UserData:
Fn::Base64:
Fn::Join:
- ''
- - '#!/bin/bash -v
'
- '/opt/aws/bin/cfn-init
'
- '# Setup MySQL root password and create a user
'
- mysqladmin -u root password '
- {Ref: DBRootPassword}
- '''
'
- cat << EOF | mysql -u root --password='
- {Ref: DBRootPassword}
- '''
'
- 'CREATE DATABASE '
- {Ref: DBName}
- ';
'
- 'GRANT ALL PRIVILEGES ON '
- {Ref: DBName}
- .* TO "
- {Ref: DBUsername}
- '"@"localhost"
'
- IDENTIFIED BY "
- {Ref: DBPassword}
- '";
'
- 'FLUSH PRIVILEGES;
'
- 'EXIT
'
- 'EOF
'
- 'sed -i "/Deny from All/d" /etc/httpd/conf.d/wordpress.conf
'
- 'sed -i "s/Require local/Require all granted/" /etc/httpd/conf.d/wordpress.conf
'
- sed --in-place --e s/database_name_here/
- {Ref: DBName}
- / --e s/username_here/
- {Ref: DBUsername}
- / --e s/password_here/
- {Ref: DBPassword}
- '/ /usr/share/wordpress/wp-config.php
'
- 'systemctl restart httpd.service
'
Outputs:
WebsiteURL:
Value:
Fn::Join:
- ''
- - http://
- Fn::GetAtt: [WikiDatabase, PublicIp]
- /wordpress
Description: URL for Wordpress wiki

View File

@ -16,24 +16,23 @@ from testtools import skipIf
import os
from heat.engine import clients
from heat.common import context
from heat.common import template_format
from heat.engine import parser
from heat.tests.common import HeatTestCase
from heat.tests.utils import setup_dummy_db
from heat.tests.utils import parse_stack
class JsonToYamlTest(HeatTestCase):
def setUp(self):
super(JsonToYamlTest, self).setUp()
self.expected_test_count = 10
self.expected_test_count = 2
self.longMessage = True
self.maxDiff = None
def test_convert_all_templates(self):
path = os.path.dirname(os.path.realpath(__file__)).\
replace('heat/tests', 'templates')
path = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'templates')
template_test_count = 0
for (json_str,
@ -46,8 +45,8 @@ class JsonToYamlTest(HeatTestCase):
break
self.assertTrue(template_test_count >= self.expected_test_count,
'Expected at least %d templates to be tested' %
self.expected_test_count)
'Expected at least %d templates to be tested, not %d' %
(self.expected_test_count, template_test_count))
def compare_json_vs_yaml(self, json_str, yml_str, file_name):
yml = template_format.parse(yml_str)
@ -101,26 +100,13 @@ class JsonYamlResolvedCompareTest(HeatTestCase):
setup_dummy_db()
def load_template(self, file_name):
self.path = os.path.dirname(os.path.realpath(__file__)).\
replace('heat/tests', 'templates')
f = open("%s/%s" % (self.path, file_name))
filepath = os.path.join(os.path.dirname(os.path.realpath(__file__)),
'templates', file_name)
f = open(filepath)
t = template_format.parse(f.read())
f.close()
return t
def parse_stack(self, t, parameters):
ctx = context.RequestContext.from_dict({
'tenant': 'test_tenant',
'username': 'test_username',
'password': 'password',
'auth_url': 'http://localhost:5000/v2.0'})
stack_name = 'test_stack'
template = parser.Template(t)
params = parser.Parameters(stack_name, template, parameters)
stack = parser.Stack(ctx, stack_name, parser.Template(t), params)
return stack
def compare_stacks(self, json_file, yaml_file, parameters):
t1 = self.load_template(json_file)
template_format.default_for_missing(t1, 'AWSTemplateFormatVersion',
@ -130,8 +116,8 @@ class JsonYamlResolvedCompareTest(HeatTestCase):
t2 = self.load_template(yaml_file)
del(t2[u'HeatTemplateFormatVersion'])
stack1 = self.parse_stack(t1, parameters)
stack2 = self.parse_stack(t2, parameters)
stack1 = parse_stack(t1, parameters)
stack2 = parse_stack(t2, parameters)
# compare resources separately so that resolved static data
# is compared