Unit test for load balancer resource type.

Change-Id: I2386419563f02bcb509a8547fd587b9af6285c5c
This commit is contained in:
Steve Baker 2012-10-11 08:18:04 +13:00
parent abafede828
commit a7babbd61f
2 changed files with 191 additions and 3 deletions

View File

@ -0,0 +1,165 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# 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 re
import sys
import os
import nose
import unittest
import mox
import json
from nose.plugins.attrib import attr
from heat.common import exception
from heat.engine import instance
from heat.engine import loadbalancer as lb
from heat.engine import parser
from heat.engine import resources
from heat.engine import stack
from heat.tests.v1_1 import fakes
@attr(tag=['unit', 'resource'])
@attr(speed='fast')
class LoadBalancerTest(unittest.TestCase):
def setUp(self):
self.m = mox.Mox()
self.fc = fakes.FakeClient()
self.m.StubOutWithMock(parser.Stack, 'store')
self.m.StubOutWithMock(lb.LoadBalancer, 'nova')
self.m.StubOutWithMock(instance.Instance, 'nova')
self.m.StubOutWithMock(self.fc.servers, 'create')
self.m.StubOutWithMock(resources.Metadata, '__set__')
def tearDown(self):
self.m.UnsetStubs()
print "LoadBalancerTest teardown complete"
def load_template(self):
self.path = os.path.dirname(os.path.realpath(__file__)).\
replace('heat/tests', 'templates')
f = open("%s/WordPress_With_LB.template" % self.path)
t = json.loads(f.read())
f.close()
return t
def parse_stack(self, t):
class DummyContext():
tenant = 'test_tenant'
tenant_id = '1234abcd'
username = 'test_username'
password = 'password'
auth_url = 'http://localhost:5000/v2.0'
t['Parameters']['KeyName']['Value'] = 'test'
t['Parameters']['KeyName']['Value'] = 'test'
stack = parser.Stack(DummyContext(), 'test_stack', parser.Template(t),
stack_id=-1)
return stack
def create_loadbalancer(self, t, stack, resource_name):
resource = lb.LoadBalancer(resource_name,
t['Resources'][resource_name],
stack)
self.assertEqual(None, resource.validate())
self.assertEqual(None, resource.create())
self.assertEqual(lb.LoadBalancer.CREATE_COMPLETE, resource.state)
return resource
def test_loadbalancer(self):
lb.LoadBalancer.nova().AndReturn(self.fc)
parser.Stack.store(mox.IgnoreArg()).AndReturn('5678')
instance.Instance.nova().MultipleTimes().AndReturn(self.fc)
self.fc.servers.create(flavor=2, image=745, key_name='test',
meta=None, name=u'test_stack.LoadBalancer.LB_instance',
scheduler_hints=None, userdata=mox.IgnoreArg(),
security_groups=None).AndReturn(self.fc.servers.list()[1])
#stack.Stack.create_with_template(mox.IgnoreArg()).AndReturn(None)
resources.Metadata.__set__(mox.IgnoreArg(),
mox.IgnoreArg()).AndReturn(None)
lb.LoadBalancer.nova().MultipleTimes().AndReturn(self.fc)
self.m.ReplayAll()
t = self.load_template()
s = self.parse_stack(t)
resource = self.create_loadbalancer(t, s, 'LoadBalancer')
hc = {
'Target': 'HTTP:80/',
'HealthyThreshold': '3',
'UnhealthyThreshold': '5',
'Interval': '30',
'Timeout': '5'}
resource.properties['HealthCheck'] = hc
self.assertEqual(None, resource.validate())
hc['Timeout'] = 35
self.assertEqual({'Error':
'Interval must be larger than Timeout'},
resource.validate())
hc['Timeout'] = 5
self.assertEqual('LoadBalancer', resource.FnGetRefId())
templ = json.loads(lb.lb_template)
ha_cfg = resource._haproxy_config(templ)
self.assertRegexpMatches(ha_cfg, 'bind \*:80')
self.assertRegexpMatches(ha_cfg, 'server server1 1\.2\.3\.4:80 '
'check inter 30s fall 5 rise 3')
self.assertRegexpMatches(ha_cfg, 'timeout check 5s')
id_list = []
for inst_name in ['WikiServerOne1', 'WikiServerOne2']:
inst = instance.Instance(inst_name,
s.t['Resources']['WikiServerOne'],
s)
id_list.append(inst.FnGetRefId())
resource.nested().create()
resource.reload(id_list)
self.assertEqual('4.5.6.7', resource.FnGetAtt('DNSName'))
self.assertEqual('', resource.FnGetAtt('SourceSecurityGroupName'))
try:
resource.FnGetAtt('Foo')
raise Exception('Expected InvalidTemplateAttribute')
except exception.InvalidTemplateAttribute:
pass
self.assertEqual(lb.LoadBalancer.UPDATE_REPLACE,
resource.handle_update())
self.m.VerifyAll()
def assertRegexpMatches(self, text, expected_regexp, msg=None):
"""Fail the test unless the text matches the regular expression."""
if isinstance(expected_regexp, basestring):
expected_regexp = re.compile(expected_regexp)
if not expected_regexp.search(text):
msg = msg or "Regexp didn't match"
msg = '%s: %r not found in %r' % (msg,
expected_regexp.pattern, text)
raise self.failureException(msg)
# allows testing of the test directly, shown below
if __name__ == '__main__':
sys.argv.append(__file__)
nose.main()

View File

@ -249,6 +249,18 @@ class FakeHTTPClient(base_client.HTTPClient):
r = {'server': self.get_servers_detail()[1]['servers'][0]}
return (200, r)
def get_servers_WikiServerOne(self, **kw):
r = {'server': self.get_servers_detail()[1]['servers'][0]}
return (200, r)
def get_servers_WikiServerOne1(self, **kw):
r = {'server': self.get_servers_detail()[1]['servers'][0]}
return (200, r)
def get_servers_WikiServerOne2(self, **kw):
r = {'server': self.get_servers_detail()[1]['servers'][0]}
return (200, r)
def get_servers_5678(self, **kw):
r = {'server': self.get_servers_detail()[1]['servers'][1]}
return (200, r)
@ -427,7 +439,7 @@ class FakeHTTPClient(base_client.HTTPClient):
def get_flavors(self, **kw):
return (200, {'flavors': [
{'id': 1, 'name': '256 MB Server'},
{'id': 2, 'name': '512 MB Server'},
{'id': 2, 'name': 'm1.small'},
{'id': 3, 'name': 'm1.large'}
]})
@ -435,7 +447,7 @@ class FakeHTTPClient(base_client.HTTPClient):
return (200, {'flavors': [
{'id': 1, 'name': '256 MB Server', 'ram': 256, 'disk': 10,
'OS-FLV-EXT-DATA:ephemeral': 10},
{'id': 2, 'name': '512 MB Server', 'ram': 512, 'disk': 20,
{'id': 2, 'name': 'm1.small', 'ram': 512, 'disk': 20,
'OS-FLV-EXT-DATA:ephemeral': 20},
{'id': 3, 'name': 'm1.large', 'ram': 512, 'disk': 20,
'OS-FLV-EXT-DATA:ephemeral': 30}
@ -551,7 +563,8 @@ class FakeHTTPClient(base_client.HTTPClient):
return (200, {'images': [
{'id': 1, 'name': 'CentOS 5.2'},
{'id': 2, 'name': 'My Server Backup'},
{'id': 3, 'name': 'F17-x86_64-gold'}
{'id': 3, 'name': 'F17-x86_64-gold'},
{'id': 4, 'name': 'F17-x86_64-cfntools'}
]})
def get_images_detail(self, **kw):
@ -586,6 +599,16 @@ class FakeHTTPClient(base_client.HTTPClient):
"status": "SAVING",
"progress": 80,
"links": {},
},
{
"id": 745,
"name": "F17-x86_64-cfntools",
"serverId": 9998,
"updated": "2010-10-10T12:00:00Z",
"created": "2010-08-10T12:00:00Z",
"status": "SAVING",
"progress": 80,
"links": {},
}
]})