Unit test for load balancer resource type.
Change-Id: I2386419563f02bcb509a8547fd587b9af6285c5c
This commit is contained in:
parent
abafede828
commit
a7babbd61f
|
@ -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()
|
|
@ -249,6 +249,18 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||||
r = {'server': self.get_servers_detail()[1]['servers'][0]}
|
r = {'server': self.get_servers_detail()[1]['servers'][0]}
|
||||||
return (200, r)
|
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):
|
def get_servers_5678(self, **kw):
|
||||||
r = {'server': self.get_servers_detail()[1]['servers'][1]}
|
r = {'server': self.get_servers_detail()[1]['servers'][1]}
|
||||||
return (200, r)
|
return (200, r)
|
||||||
|
@ -427,7 +439,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||||
def get_flavors(self, **kw):
|
def get_flavors(self, **kw):
|
||||||
return (200, {'flavors': [
|
return (200, {'flavors': [
|
||||||
{'id': 1, 'name': '256 MB Server'},
|
{'id': 1, 'name': '256 MB Server'},
|
||||||
{'id': 2, 'name': '512 MB Server'},
|
{'id': 2, 'name': 'm1.small'},
|
||||||
{'id': 3, 'name': 'm1.large'}
|
{'id': 3, 'name': 'm1.large'}
|
||||||
]})
|
]})
|
||||||
|
|
||||||
|
@ -435,7 +447,7 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||||
return (200, {'flavors': [
|
return (200, {'flavors': [
|
||||||
{'id': 1, 'name': '256 MB Server', 'ram': 256, 'disk': 10,
|
{'id': 1, 'name': '256 MB Server', 'ram': 256, 'disk': 10,
|
||||||
'OS-FLV-EXT-DATA:ephemeral': 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},
|
'OS-FLV-EXT-DATA:ephemeral': 20},
|
||||||
{'id': 3, 'name': 'm1.large', 'ram': 512, 'disk': 20,
|
{'id': 3, 'name': 'm1.large', 'ram': 512, 'disk': 20,
|
||||||
'OS-FLV-EXT-DATA:ephemeral': 30}
|
'OS-FLV-EXT-DATA:ephemeral': 30}
|
||||||
|
@ -551,7 +563,8 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||||
return (200, {'images': [
|
return (200, {'images': [
|
||||||
{'id': 1, 'name': 'CentOS 5.2'},
|
{'id': 1, 'name': 'CentOS 5.2'},
|
||||||
{'id': 2, 'name': 'My Server Backup'},
|
{'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):
|
def get_images_detail(self, **kw):
|
||||||
|
@ -586,6 +599,16 @@ class FakeHTTPClient(base_client.HTTPClient):
|
||||||
"status": "SAVING",
|
"status": "SAVING",
|
||||||
"progress": 80,
|
"progress": 80,
|
||||||
"links": {},
|
"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": {},
|
||||||
}
|
}
|
||||||
]})
|
]})
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue