]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
Unit test for load balancer resource type.
authorSteve Baker <sbaker@redhat.com>
Wed, 10 Oct 2012 19:18:04 +0000 (08:18 +1300)
committerSteve Baker <sbaker@redhat.com>
Wed, 10 Oct 2012 19:19:00 +0000 (08:19 +1300)
Change-Id: I2386419563f02bcb509a8547fd587b9af6285c5c

heat/tests/test_loadbalancer.py [new file with mode: 0644]
heat/tests/v1_1/fakes.py

diff --git a/heat/tests/test_loadbalancer.py b/heat/tests/test_loadbalancer.py
new file mode 100644 (file)
index 0000000..bc60458
--- /dev/null
@@ -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()
index 55013ef7a8d1c39826904fab43362b9274a1680b..d5ce979ecde26396e0207e7776edf43e5a15829b 100644 (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": {},
             }
         ]})