Add UT for LBaaS HAProxy driver
fixes bug 1137386 Change-Id: I791d09fc472fd8555f4030cfd1964e70ab9f2771
This commit is contained in:
parent
e4dd4f78cd
commit
193dbf6d1c
@ -17,12 +17,143 @@
|
||||
#
|
||||
# @author: Oleg Bondarev (obondarev@mirantis.com)
|
||||
|
||||
import contextlib
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from oslo.config import cfg as config
|
||||
|
||||
from quantum.plugins.services.agent_loadbalancer.drivers.haproxy import cfg
|
||||
|
||||
|
||||
class TestHaproxyCfg(testtools.TestCase):
|
||||
def test_save_config(self):
|
||||
with contextlib.nested(
|
||||
mock.patch('quantum.plugins.services.agent_loadbalancer.'
|
||||
'drivers.haproxy.cfg._build_global'),
|
||||
mock.patch('quantum.plugins.services.agent_loadbalancer.'
|
||||
'drivers.haproxy.cfg._build_defaults'),
|
||||
mock.patch('quantum.plugins.services.agent_loadbalancer.'
|
||||
'drivers.haproxy.cfg._build_frontend'),
|
||||
mock.patch('quantum.plugins.services.agent_loadbalancer.'
|
||||
'drivers.haproxy.cfg._build_backend'),
|
||||
mock.patch('quantum.agent.linux.utils.replace_file')
|
||||
) as (b_g, b_d, b_f, b_b, replace):
|
||||
test_config = ['globals', 'defaults', 'frontend', 'backend']
|
||||
b_g.return_value = [test_config[0]]
|
||||
b_d.return_value = [test_config[1]]
|
||||
b_f.return_value = [test_config[2]]
|
||||
b_b.return_value = [test_config[3]]
|
||||
|
||||
cfg.save_config('test_path', mock.Mock())
|
||||
replace.assert_called_once_with('test_path',
|
||||
'\n'.join(test_config))
|
||||
|
||||
def test_build_global(self):
|
||||
config.CONF.register_opt(config.StrOpt('user_group'))
|
||||
config.CONF.set_override('user_group', 'test_group')
|
||||
expected_opts = ['global',
|
||||
'\tdaemon',
|
||||
'\tuser nobody',
|
||||
'\tgroup test_group',
|
||||
'\tlog /dev/log local0',
|
||||
'\tlog /dev/log local1 notice',
|
||||
'\tstats socket test_path mode 0666 level user']
|
||||
opts = cfg._build_global(mock.Mock(), 'test_path')
|
||||
self.assertEqual(expected_opts, list(opts))
|
||||
config.CONF.reset()
|
||||
|
||||
def test_build_defaults(self):
|
||||
expected_opts = ['defaults',
|
||||
'\tlog global',
|
||||
'\tretries 3',
|
||||
'\toption redispatch',
|
||||
'\ttimeout connect 5000',
|
||||
'\ttimeout client 50000',
|
||||
'\ttimeout server 50000']
|
||||
opts = cfg._build_defaults(mock.Mock())
|
||||
self.assertEqual(expected_opts, list(opts))
|
||||
config.CONF.reset()
|
||||
|
||||
def test_build_frontend(self):
|
||||
test_config = {'vip': {'id': 'vip_id',
|
||||
'protocol': 'HTTP',
|
||||
'port': {'fixed_ips': [
|
||||
{'ip_address': '10.0.0.2'}]
|
||||
},
|
||||
'protocol_port': 80,
|
||||
'connection_limit': 2000,
|
||||
},
|
||||
'pool': {'id': 'pool_id'}}
|
||||
expected_opts = ['frontend vip_id',
|
||||
'\toption tcplog',
|
||||
'\tbind 10.0.0.2:80',
|
||||
'\tmode http',
|
||||
'\tdefault_backend pool_id',
|
||||
'\tmaxconn 2000',
|
||||
'\toption forwardfor']
|
||||
opts = cfg._build_frontend(test_config)
|
||||
self.assertEqual(expected_opts, list(opts))
|
||||
|
||||
test_config['vip']['connection_limit'] = -1
|
||||
expected_opts.remove('\tmaxconn 2000')
|
||||
opts = cfg._build_frontend(test_config)
|
||||
self.assertEqual(expected_opts, list(opts))
|
||||
|
||||
def test_build_backend(self):
|
||||
test_config = {'pool': {'id': 'pool_id',
|
||||
'protocol': 'HTTP',
|
||||
'lb_method': 'ROUND_ROBIN'},
|
||||
'members': [{'status': 'ACTIVE',
|
||||
'admin_state_up': True,
|
||||
'id': 'member1_id',
|
||||
'address': '10.0.0.3',
|
||||
'protocol_port': 80,
|
||||
'weight': 1}],
|
||||
'healthmonitors': [{'status': 'ACTIVE',
|
||||
'admin_state_up': True,
|
||||
'delay': 3,
|
||||
'max_retries': 4,
|
||||
'timeout': 2,
|
||||
'type': 'TCP'}],
|
||||
'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}}
|
||||
expected_opts = ['backend pool_id',
|
||||
'\tmode http',
|
||||
'\tbalance roundrobin',
|
||||
'\toption forwardfor',
|
||||
'\ttimeout check 2s',
|
||||
'\tcookie SRV insert indirect nocache',
|
||||
'\tserver member1_id 10.0.0.3:80 weight 1 '
|
||||
'check inter 3s fall 4 cookie 0']
|
||||
opts = cfg._build_backend(test_config)
|
||||
self.assertEqual(expected_opts, list(opts))
|
||||
|
||||
def test_get_server_health_option(self):
|
||||
test_config = {'healthmonitors': [{'status': 'ERROR',
|
||||
'admin_state_up': False,
|
||||
'delay': 3,
|
||||
'max_retries': 4,
|
||||
'timeout': 2,
|
||||
'type': 'TCP',
|
||||
'http_method': 'GET',
|
||||
'url_path': '/',
|
||||
'expected_codes': '200'}]}
|
||||
self.assertEqual(('', []), cfg._get_server_health_option(test_config))
|
||||
|
||||
test_config['healthmonitors'][0]['status'] = 'ACTIVE'
|
||||
self.assertEqual(('', []), cfg._get_server_health_option(test_config))
|
||||
|
||||
test_config['healthmonitors'][0]['admin_state_up'] = True
|
||||
expected = (' check inter 3s fall 4', ['timeout check 2s'])
|
||||
self.assertEqual(expected, cfg._get_server_health_option(test_config))
|
||||
|
||||
test_config['healthmonitors'][0]['type'] = 'HTTPS'
|
||||
expected = (' check inter 3s fall 4',
|
||||
['timeout check 2s',
|
||||
'option httpchk GET /',
|
||||
'http-check expect rstatus 200',
|
||||
'option ssl-hello-chk'])
|
||||
self.assertEqual(expected, cfg._get_server_health_option(test_config))
|
||||
|
||||
def test_has_http_cookie_persistence(self):
|
||||
config = {'vip': {'session_persistence': {'type': 'HTTP_COOKIE'}}}
|
||||
@ -53,3 +184,29 @@ class TestHaproxyCfg(testtools.TestCase):
|
||||
|
||||
config = {'vip': {'session_persistence': {'type': 'UNSUPPORTED'}}}
|
||||
self.assertEqual(cfg._get_session_persistence(config), [])
|
||||
|
||||
def test_expand_expected_codes(self):
|
||||
exp_codes = ''
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes), set([]))
|
||||
exp_codes = '200'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes), set(['200']))
|
||||
exp_codes = '200, 201'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes),
|
||||
set(['200', '201']))
|
||||
exp_codes = '200, 201,202'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes),
|
||||
set(['200', '201', '202']))
|
||||
exp_codes = '200-202'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes),
|
||||
set(['200', '201', '202']))
|
||||
exp_codes = '200-202, 205'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes),
|
||||
set(['200', '201', '202', '205']))
|
||||
exp_codes = '200, 201-203'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes),
|
||||
set(['200', '201', '202', '203']))
|
||||
exp_codes = '200, 201-203, 205'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes),
|
||||
set(['200', '201', '202', '203', '205']))
|
||||
exp_codes = '201-200, 205'
|
||||
self.assertEqual(cfg._expand_expected_codes(exp_codes), set(['205']))
|
||||
|
@ -20,6 +20,7 @@ import contextlib
|
||||
import mock
|
||||
import testtools
|
||||
|
||||
from quantum.common import exceptions
|
||||
from quantum.plugins.services.agent_loadbalancer.drivers.haproxy import (
|
||||
namespace_driver
|
||||
)
|
||||
@ -179,3 +180,70 @@ class TestHaproxyNSDriver(testtools.TestCase):
|
||||
socket.reset_mock()
|
||||
self.assertEqual({}, self.driver.get_stats('pool_id'))
|
||||
self.assertFalse(socket.called)
|
||||
|
||||
def test_plug(self):
|
||||
test_port = {'id': 'port_id',
|
||||
'network_id': 'net_id',
|
||||
'mac_address': 'mac_addr',
|
||||
'fixed_ips': [{'ip_address': '10.0.0.2',
|
||||
'subnet': {'cidr': 'cidr'}}]}
|
||||
with contextlib.nested(
|
||||
mock.patch('quantum.agent.linux.ip_lib.device_exists'),
|
||||
mock.patch('netaddr.IPNetwork'),
|
||||
) as (dev_exists, ip_net):
|
||||
self.vif_driver.get_device_name.return_value = 'test_interface'
|
||||
dev_exists.return_value = False
|
||||
ip_net.return_value = ip_net
|
||||
ip_net.prefixlen = 24
|
||||
|
||||
self.driver._plug('test_ns', test_port)
|
||||
self.vip_plug_callback.assert_called_once_with('plug', test_port)
|
||||
self.assertTrue(dev_exists.called)
|
||||
self.vif_driver.plug.assert_called_once_with('net_id', 'port_id',
|
||||
'test_interface',
|
||||
'mac_addr',
|
||||
namespace='test_ns')
|
||||
self.vif_driver.init_l3.assert_called_once_with('test_interface',
|
||||
['10.0.0.2/24'],
|
||||
namespace=
|
||||
'test_ns')
|
||||
|
||||
dev_exists.return_value = True
|
||||
self.assertRaises(exceptions.PreexistingDeviceFailure,
|
||||
self.driver._plug, 'test_ns', test_port, False)
|
||||
|
||||
def test_unplug(self):
|
||||
self.vif_driver.get_device_name.return_value = 'test_interface'
|
||||
|
||||
self.driver._unplug('test_ns', 'port_id')
|
||||
self.vip_plug_callback.assert_called_once_with('unplug',
|
||||
{'id': 'port_id'})
|
||||
self.vif_driver.unplug('test_interface', namespace='test_ns')
|
||||
|
||||
def test_kill_pids_in_file(self):
|
||||
with contextlib.nested(
|
||||
mock.patch('os.path.exists'),
|
||||
mock.patch('__builtin__.open')
|
||||
) as (path_exists, mock_open):
|
||||
file_mock = mock.MagicMock()
|
||||
mock_open.return_value = file_mock
|
||||
file_mock.__enter__.return_value = file_mock
|
||||
file_mock.__iter__.return_value = iter(['123'])
|
||||
ns_wrapper = mock.Mock()
|
||||
|
||||
path_exists.return_value = False
|
||||
namespace_driver.kill_pids_in_file(ns_wrapper, 'test_path')
|
||||
path_exists.assert_called_once_with('test_path')
|
||||
self.assertFalse(mock_open.called)
|
||||
|
||||
path_exists.return_value = True
|
||||
ns_wrapper.netns.execute.side_effect = RuntimeError
|
||||
namespace_driver.kill_pids_in_file(ns_wrapper, 'test_path')
|
||||
ns_wrapper.netns.execute.assert_called_once_with(['kill', '-9',
|
||||
'123'])
|
||||
|
||||
def test_get_state_file_path(self):
|
||||
with mock.patch('os.makedirs') as mkdir:
|
||||
path = self.driver._get_state_file_path('pool_id', 'conf')
|
||||
self.assertEqual('/the/path/pool_id/conf', path)
|
||||
mkdir.assert_called_once_with('/the/path/pool_id', 0755)
|
||||
|
Loading…
Reference in New Issue
Block a user