BigSwitch: Improves server manager UT coverage

Improves the unit test coverage for the Big Switch
server manager module (100%). Also reorganizes the
capabilities test to avoid duplicating a lot of
router tests that are already covered.

Closes-Bug: #1289027
Change-Id: Ib51e8160f8d95686e86430b0a9c9f54deeda0e84
This commit is contained in:
Kevin Benton 2014-03-06 20:51:11 -08:00
parent 130a3b2253
commit ac18ecadaa
9 changed files with 366 additions and 81 deletions

View File

@ -71,6 +71,9 @@ ORCHESTRATION_SERVICE_ID = 'Neutron v2.0'
HASH_MATCH_HEADER = 'X-BSN-BVS-HASH-MATCH'
# error messages
NXNETWORK = 'NXVNS'
# NOTE(kevinbenton): This following is to give mock a target that doesn't
# affect other users of httplib.HTTPConnection
HTTPConnection = httplib.HTTPConnection
class RemoteRestError(exceptions.NeutronException):
@ -168,7 +171,7 @@ class ServerProxy(object):
return 0, None, None, None
self.currentconn.combined_cert = self.combined_cert
else:
self.currentconn = httplib.HTTPConnection(
self.currentconn = HTTPConnection(
self.server, self.port, timeout=timeout)
if self.currentconn is None:
LOG.error(_('ServerProxy: Could not establish HTTP '

View File

@ -30,3 +30,4 @@ class BigSwitchDhcpAgentNotifierTestCase(
self.setup_config_files()
self.setup_patches()
super(BigSwitchDhcpAgentNotifierTestCase, self).setUp()
self.startHttpPatch()

View File

@ -30,8 +30,8 @@ NOTIFIER = 'neutron.plugins.bigswitch.plugin.AgentNotifierApi'
CALLBACKS = 'neutron.plugins.bigswitch.plugin.RestProxyCallbacks'
CERTFETCH = 'neutron.plugins.bigswitch.servermanager.ServerPool._fetch_cert'
SERVER_MANAGER = 'neutron.plugins.bigswitch.servermanager'
HTTPCON = 'httplib.HTTPConnection'
SPAWN = 'eventlet.GreenPool.spawn_n'
HTTPCON = 'neutron.plugins.bigswitch.servermanager.HTTPConnection'
SPAWN = 'neutron.plugins.bigswitch.plugin.eventlet.GreenPool.spawn_n'
CWATCH = SERVER_MANAGER + '.ServerPool._consistency_watchdog'
@ -53,8 +53,6 @@ class BigSwitchTestBase(object):
cfg.CONF.set_override('cache_connections', False, 'RESTPROXY')
def setup_patches(self):
self.httpPatch = mock.patch(HTTPCON, create=True,
new=fake_server.HTTPConnectionMock)
self.plugin_notifier_p = mock.patch(NOTIFIER)
self.callbacks_p = mock.patch(CALLBACKS)
self.spawn_p = mock.patch(SPAWN)
@ -62,6 +60,10 @@ class BigSwitchTestBase(object):
self.addCleanup(db.clear_db)
self.callbacks_p.start()
self.plugin_notifier_p.start()
self.httpPatch.start()
self.spawn_p.start()
self.watch_p.start()
def startHttpPatch(self):
self.httpPatch = mock.patch(HTTPCON,
new=fake_server.HTTPConnectionMock)
self.httpPatch.start()

View File

@ -26,9 +26,10 @@ PLUGIN = 'neutron.plugins.bigswitch.plugin'
SERVERMANAGER = PLUGIN + '.servermanager'
SERVERPOOL = SERVERMANAGER + '.ServerPool'
SERVERRESTCALL = SERVERMANAGER + '.ServerProxy.rest_call'
HTTPCON = SERVERMANAGER + '.HTTPConnection'
class CapabilitiesTests(test_router_db.RouterDBTestCase):
class CapabilitiesTests(test_router_db.RouterDBTestBase):
def test_floating_ip_capability(self):
with nested(
@ -63,3 +64,19 @@ class CapabilitiesTests(test_router_db.RouterDBTestCase):
all_floats = [f['floating_ip_address']
for floats in updates for f in floats]
self.assertIn(fip['floatingip']['floating_ip_address'], all_floats)
def test_keep_alive_capability(self):
with mock.patch(
SERVERRESTCALL, return_value=(200, None, None, '["keep-alive"]')
):
# perform a task to cause capabilities to be retrieved
with self.floatingip_with_assoc():
pass
# now mock HTTP class instead of REST so we can see headers
conmock = mock.patch(HTTPCON).start()
instance = conmock.return_value
instance.getresponse.return_value.getheader.return_value = 'HASHHEADER'
with self.network():
callheaders = instance.request.mock_calls[0][1][3]
self.assertIn('Connection', callheaders)
self.assertEqual(callheaders['Connection'], 'keep-alive')

View File

@ -31,6 +31,7 @@ import neutron.tests.unit.test_db_plugin as test_plugin
import neutron.tests.unit.test_extension_allowedaddresspairs as test_addr_pair
patch = mock.patch
HTTPCON = 'neutron.plugins.bigswitch.servermanager.HTTPConnection'
class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase,
@ -47,6 +48,7 @@ class BigSwitchProxyPluginV2TestCase(test_base.BigSwitchTestBase,
super(BigSwitchProxyPluginV2TestCase,
self).setUp(self._plugin_name)
self.port_create_status = 'BUILD'
self.startHttpPatch()
class TestBigSwitchProxyBasicGet(test_plugin.TestBasicGet,
@ -91,16 +93,20 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
def test_rollback_for_port_create(self):
plugin = NeutronManager.get_plugin()
with self.subnet() as s:
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.httpPatch.start()
kwargs = {'device_id': 'somedevid'}
# allow thread spawns for this patch
# stop normal patch
self.httpPatch.stop()
# allow thread spawns for this test
self.spawn_p.stop()
kwargs = {'device_id': 'somedevid'}
# put in a broken 'server'
httpPatch = patch(HTTPCON, new=fake_server.HTTPConnectionMock500)
httpPatch.start()
with self.port(subnet=s, **kwargs):
self.spawn_p.start()
# wait for async port create request to finish
plugin.evpool.waitall()
self.httpPatch.stop()
# put good 'server' back in
httpPatch.stop()
self.httpPatch.start()
ports = self._get_ports(s['subnet']['network_id'])
#failure to create should result in port in error state
self.assertEqual(ports[0]['status'], 'ERROR')
@ -111,13 +117,12 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
device_id='66') as port:
port = self._get_ports(n['network']['id'])[0]
data = {'port': {'name': 'aNewName', 'device_id': '99'}}
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.httpPatch.start()
self.new_update_request('ports',
data,
port['id']).get_response(self.api)
# stop normal patch
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self.new_update_request(
'ports', data, port['id']).get_response(self.api)
self.httpPatch.start()
uport = self._get_ports(n['network']['id'])[0]
# name should have stayed the same
self.assertEqual(port['name'], uport['name'])
@ -126,13 +131,13 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
with self.network() as n:
with self.port(network_id=n['network']['id'],
device_id='somedevid') as port:
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.httpPatch.start()
self._delete('ports', port['port']['id'],
expected_code=
webob.exc.HTTPInternalServerError.code)
# stop normal patch
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self._delete('ports', port['port']['id'],
expected_code=
webob.exc.HTTPInternalServerError.code)
self.httpPatch.start()
port = self._get_ports(n['network']['id'])[0]
self.assertEqual('BUILD', port['status'])
@ -165,7 +170,7 @@ class TestBigSwitchProxyPortsV2(test_plugin.TestPortsV2,
self.spawn_p.stop()
with nested(
self.subnet(),
patch('httplib.HTTPConnection', create=True,
patch(HTTPCON, create=True,
new=fake_server.HTTPConnectionMock404),
patch(test_base.RESTPROXY_PKG_PATH
+ '.NeutronRestProxyV2._send_all_data')
@ -244,34 +249,33 @@ class TestBigSwitchProxyNetworksV2(test_plugin.TestNetworksV2,
def test_rollback_on_network_create(self):
tid = test_api_v2._uuid()
kwargs = {'tenant_id': tid}
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.httpPatch.start()
self._create_network('json', 'netname', True, **kwargs)
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self._create_network('json', 'netname', True, **kwargs)
self.httpPatch.start()
self.assertFalse(self._get_networks(tid))
def test_rollback_on_network_update(self):
with self.network() as n:
data = {'network': {'name': 'aNewName'}}
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.httpPatch.start()
self.new_update_request('networks', data,
n['network']['id']).get_response(self.api)
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self.new_update_request(
'networks', data, n['network']['id']
).get_response(self.api)
self.httpPatch.start()
updatedn = self._get_networks(n['network']['tenant_id'])[0]
# name should have stayed the same due to failure
self.assertEqual(n['network']['name'], updatedn['name'])
def test_rollback_on_network_delete(self):
with self.network() as n:
self.httpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.httpPatch.start()
self._delete('networks', n['network']['id'],
expected_code=webob.exc.HTTPInternalServerError.code)
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self._delete(
'networks', n['network']['id'],
expected_code=webob.exc.HTTPInternalServerError.code)
self.httpPatch.start()
# network should still exist in db
self.assertEqual(n['network']['id'],
self._get_networks(n['network']['tenant_id']

View File

@ -39,6 +39,7 @@ from neutron.tests.unit import test_extension_extradhcpopts as test_extradhcp
from neutron.tests.unit import test_l3_plugin
HTTPCON = 'neutron.plugins.bigswitch.servermanager.httplib.HTTPConnection'
_uuid = uuidutils.generate_uuid
@ -64,24 +65,31 @@ class DHCPOptsTestCase(test_base.BigSwitchTestBase,
self.setup_config_files()
super(test_extradhcp.ExtraDhcpOptDBTestCase,
self).setUp(plugin=self._plugin_name)
self.startHttpPatch()
class RouterDBTestCase(test_base.BigSwitchTestBase,
test_l3_plugin.L3NatDBIntTestCase):
class RouterDBTestBase(test_base.BigSwitchTestBase,
test_l3_plugin.L3BaseForIntTests,
test_l3_plugin.L3NatTestCaseMixin):
def setUp(self):
self.setup_patches()
self.setup_config_files()
ext_mgr = RouterRulesTestExtensionManager()
super(RouterDBTestCase, self).setUp(plugin=self._plugin_name,
super(RouterDBTestBase, self).setUp(plugin=self._plugin_name,
ext_mgr=ext_mgr)
cfg.CONF.set_default('allow_overlapping_ips', False)
self.plugin_obj = NeutronManager.get_plugin()
self.startHttpPatch()
def tearDown(self):
super(RouterDBTestCase, self).tearDown()
super(RouterDBTestBase, self).tearDown()
del test_config['config_files']
class RouterDBTestCase(RouterDBTestBase,
test_l3_plugin.L3NatDBIntTestCase):
def test_router_remove_router_interface_wrong_subnet_returns_400(self):
with self.router() as r:
with self.subnet() as s:
@ -164,8 +172,7 @@ class RouterDBTestCase(test_base.BigSwitchTestBase,
port_id=p1['port']['id'],
tenant_id=tenant1_id)
multiFloatPatch = patch(
'httplib.HTTPConnection',
create=True,
HTTPCON,
new=fake_server.VerifyMultiTenantFloatingIP)
multiFloatPatch.start()
fl2 = self._make_floatingip_for_tenant_port(
@ -504,34 +511,30 @@ class RouterDBTestCase(test_base.BigSwitchTestBase,
def test_rollback_on_router_create(self):
tid = test_api_v2._uuid()
self.errhttpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.errhttpPatch.start()
self._create_router('json', tid)
self.errhttpPatch.stop()
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self._create_router('json', tid)
self.assertTrue(len(self._get_routers(tid)) == 0)
def test_rollback_on_router_update(self):
with self.router() as r:
data = {'router': {'name': 'aNewName'}}
self.errhttpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.errhttpPatch.start()
self.new_update_request('routers', data,
r['router']['id']).get_response(self.api)
self.errhttpPatch.stop()
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self.new_update_request(
'routers', data, r['router']['id']).get_response(self.api)
self.httpPatch.start()
updatedr = self._get_routers(r['router']['tenant_id'])[0]
# name should have stayed the same due to failure
self.assertEqual(r['router']['name'], updatedr['name'])
def test_rollback_on_router_delete(self):
with self.router() as r:
self.errhttpPatch = patch('httplib.HTTPConnection', create=True,
new=fake_server.HTTPConnectionMock500)
self.errhttpPatch.start()
self._delete('routers', r['router']['id'],
expected_code=exc.HTTPInternalServerError.code)
self.errhttpPatch.stop()
self.httpPatch.stop()
with patch(HTTPCON, new=fake_server.HTTPConnectionMock500):
self._delete('routers', r['router']['id'],
expected_code=exc.HTTPInternalServerError.code)
self.httpPatch.start()
self.assertEqual(r['router']['id'],
self._get_routers(r['router']['tenant_id']
)[0]['id'])

View File

@ -33,6 +33,7 @@ class RestProxySecurityGroupsTestCase(test_sg.SecurityGroupDBTestCase,
plugin = manager.NeutronManager.get_plugin()
self.notifier = plugin.notifier
self.rpc = plugin.callbacks
self.startHttpPatch()
class TestSecServerRpcCallBack(test_sg_rpc.SGServerRpcCallBackMixinTestCase,

View File

@ -14,31 +14,52 @@
#
# @author: Kevin Benton, kevin.benton@bigswitch.com
#
from contextlib import nested
import httplib
import socket
import ssl
from contextlib import nested
import mock
from oslo.config import cfg
from neutron.manager import NeutronManager
from neutron.openstack.common import importutils
from neutron.plugins.bigswitch import servermanager
from neutron.tests.unit.bigswitch import test_restproxy_plugin as test_rp
HTTPCON = 'httplib.HTTPConnection'
SERVERMANAGER = 'neutron.plugins.bigswitch.servermanager'
HTTPCON = SERVERMANAGER + '.HTTPConnection'
HTTPSCON = SERVERMANAGER + '.HTTPSConnectionWithValidation'
class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
def setUp(self):
self.socket_mock = mock.patch(
SERVERMANAGER + '.socket.create_connection').start()
self.wrap_mock = mock.patch(SERVERMANAGER + '.ssl.wrap_socket').start()
super(ServerManagerTests, self).setUp()
# http patch must not be running or it will mangle the servermanager
# import where the https connection classes are defined
self.httpPatch.stop()
self.sm = importutils.import_module(SERVERMANAGER)
def test_no_servers(self):
cfg.CONF.set_override('servers', [], 'RESTPROXY')
self.assertRaises(cfg.Error, servermanager.ServerPool)
def test_malformed_servers(self):
cfg.CONF.set_override('servers', ['a:b:c'], 'RESTPROXY')
cfg.CONF.set_override('servers', ['1.2.3.4', '1.1.1.1:a'], 'RESTPROXY')
self.assertRaises(cfg.Error, servermanager.ServerPool)
def test_ipv6_server_address(self):
cfg.CONF.set_override(
'servers', ['[ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]:80'],
'RESTPROXY')
s = servermanager.ServerPool()
self.assertEqual(s.servers[0].server,
'[ABCD:EF01:2345:6789:ABCD:EF01:2345:6789]')
def test_sticky_cert_fetch_fail(self):
pl = NeutronManager.get_plugin()
pl.servers.ssl = True
@ -73,6 +94,30 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
self.assertRaises(servermanager.RemoteRestError,
pl.servers._consistency_watchdog)
def test_consistency_hash_header(self):
# mock HTTP class instead of rest_call so we can see headers
with mock.patch(HTTPCON) as conmock:
rv = conmock.return_value
rv.getresponse.return_value.getheader.return_value = 'HASHHEADER'
with self.network():
callheaders = rv.request.mock_calls[0][1][3]
self.assertIn('X-BSN-BVS-HASH-MATCH', callheaders)
# first call will be False to indicate no previous state hash
self.assertEqual(callheaders['X-BSN-BVS-HASH-MATCH'], False)
# change the header that will be received on delete call
rv.getresponse.return_value.getheader.return_value = 'HASH2'
# net delete should have used header received on create
callheaders = rv.request.mock_calls[1][1][3]
self.assertEqual(callheaders['X-BSN-BVS-HASH-MATCH'], 'HASHHEADER')
# create again should now use header received from prev delete
with self.network():
callheaders = rv.request.mock_calls[2][1][3]
self.assertIn('X-BSN-BVS-HASH-MATCH', callheaders)
self.assertEqual(callheaders['X-BSN-BVS-HASH-MATCH'],
'HASH2')
def test_file_put_contents(self):
pl = NeutronManager.get_plugin()
with mock.patch(SERVERMANAGER + '.open', create=True) as omock:
@ -102,6 +147,60 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
mock.call.write('certdata')
])
def test_auth_header(self):
cfg.CONF.set_override('server_auth', 'username:pass', 'RESTPROXY')
sp = servermanager.ServerPool()
with mock.patch(HTTPCON) as conmock:
rv = conmock.return_value
rv.getresponse.return_value.getheader.return_value = 'HASHHEADER'
sp.rest_create_network('tenant', 'network')
callheaders = rv.request.mock_calls[0][1][3]
self.assertIn('Authorization', callheaders)
self.assertEqual(callheaders['Authorization'],
'Basic dXNlcm5hbWU6cGFzcw==')
def test_header_add(self):
sp = servermanager.ServerPool()
with mock.patch(HTTPCON) as conmock:
rv = conmock.return_value
rv.getresponse.return_value.getheader.return_value = 'HASHHEADER'
sp.servers[0].rest_call('GET', '/', headers={'EXTRA-HEADER': 'HI'})
callheaders = rv.request.mock_calls[0][1][3]
# verify normal headers weren't mangled
self.assertIn('Content-type', callheaders)
self.assertEqual(callheaders['Content-type'],
'application/json')
# verify new header made it in
self.assertIn('EXTRA-HEADER', callheaders)
self.assertEqual(callheaders['EXTRA-HEADER'], 'HI')
def test_reconnect_on_timeout_change(self):
sp = servermanager.ServerPool()
with mock.patch(HTTPCON) as conmock:
rv = conmock.return_value
rv.getresponse.return_value.getheader.return_value = 'HASHHEADER'
sp.servers[0].capabilities = ['keep-alive']
sp.servers[0].rest_call('GET', '/', timeout=10)
# even with keep-alive enabled, a change in timeout will trigger
# a reconnect
sp.servers[0].rest_call('GET', '/', timeout=75)
conmock.assert_has_calls([
mock.call('localhost', 9000, timeout=10),
mock.call('localhost', 9000, timeout=75),
], any_order=True)
def test_connect_failures(self):
sp = servermanager.ServerPool()
with mock.patch(HTTPCON, return_value=None):
resp = sp.servers[0].rest_call('GET', '/')
self.assertEqual(resp, (0, None, None, None))
# verify same behavior on ssl class
sp.servers[0].currentcon = False
sp.servers[0].ssl = True
with mock.patch(HTTPSCON, return_value=None):
resp = sp.servers[0].rest_call('GET', '/')
self.assertEqual(resp, (0, None, None, None))
def test_reconnect_cached_connection(self):
sp = servermanager.ServerPool()
with mock.patch(HTTPCON) as conmock:
@ -147,3 +246,159 @@ class ServerManagerTests(test_rp.BigSwitchProxyPluginV2TestCase):
conmock.return_value.request.side_effect = socket.timeout()
resp = sp.servers[0].rest_call('GET', '/')
self.assertEqual(resp, (0, None, None, None))
def test_cert_get_fail(self):
pl = NeutronManager.get_plugin()
pl.servers.ssl = True
with mock.patch('os.path.exists', return_value=False):
self.assertRaises(cfg.Error,
pl.servers._get_combined_cert_for_server,
*('example.org', 443))
def test_cert_make_dirs(self):
pl = NeutronManager.get_plugin()
pl.servers.ssl = True
cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
# pretend base dir exists, 3 children don't, and host cert does
with nested(
mock.patch('os.path.exists', side_effect=[True, False, False,
False, True]),
mock.patch('os.makedirs'),
mock.patch(SERVERMANAGER + '.ServerPool._combine_certs_to_file')
) as (exmock, makemock, combmock):
# will raise error because no certs found
self.assertIn(
'example.org',
pl.servers._get_combined_cert_for_server('example.org', 443)
)
base = cfg.CONF.RESTPROXY.ssl_cert_directory
hpath = base + '/host_certs/example.org.pem'
combpath = base + '/combined/example.org.pem'
combmock.assert_has_calls([mock.call([hpath], combpath)])
self.assertEqual(exmock.call_count, 5)
self.assertEqual(makemock.call_count, 3)
def test_no_cert_error(self):
pl = NeutronManager.get_plugin()
pl.servers.ssl = True
cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
# pretend base dir exists and 3 children do, but host cert doesn't
with mock.patch(
'os.path.exists',
side_effect=[True, True, True, True, False]
) as exmock:
# will raise error because no certs found
self.assertRaises(
cfg.Error,
pl.servers._get_combined_cert_for_server,
*('example.org', 443)
)
self.assertEqual(exmock.call_count, 5)
def test_action_success(self):
pl = NeutronManager.get_plugin()
self.assertTrue(pl.servers.action_success((200,)))
def test_server_failure(self):
pl = NeutronManager.get_plugin()
self.assertTrue(pl.servers.server_failure((404,)))
# server failure has an ignore codes option
self.assertFalse(pl.servers.server_failure((404,),
ignore_codes=[404]))
def test_conflict_triggers_sync(self):
pl = NeutronManager.get_plugin()
with mock.patch(
SERVERMANAGER + '.ServerProxy.rest_call',
return_value=(httplib.CONFLICT, 0, 0, 0)
) as srestmock:
# making a call should trigger a conflict sync
pl.servers.rest_call('GET', '/', '', None, [])
srestmock.assert_has_calls([
mock.call('GET', '/', '', None, False, reconnect=True),
mock.call('PUT', '/topology',
{'routers': [], 'networks': []},
timeout=None)
])
def test_conflict_sync_raises_error_without_topology(self):
pl = NeutronManager.get_plugin()
pl.servers.get_topo_function = None
with mock.patch(
SERVERMANAGER + '.ServerProxy.rest_call',
return_value=(httplib.CONFLICT, 0, 0, 0)
):
# making a call should trigger a conflict sync that will
# error without the topology function set
self.assertRaises(
cfg.Error,
pl.servers.rest_call,
*('GET', '/', '', None, [])
)
def test_floating_calls(self):
pl = NeutronManager.get_plugin()
with mock.patch(SERVERMANAGER + '.ServerPool.rest_action') as ramock:
pl.servers.rest_create_floatingip('tenant', {'id': 'somefloat'})
pl.servers.rest_update_floatingip('tenant', {'name': 'myfl'}, 'id')
pl.servers.rest_delete_floatingip('tenant', 'oldid')
ramock.assert_has_calls([
mock.call('PUT', '/tenants/tenant/floatingips/somefloat',
errstr=u'Unable to create floating IP: %s'),
mock.call('PUT', '/tenants/tenant/floatingips/id',
errstr=u'Unable to update floating IP: %s'),
mock.call('DELETE', '/tenants/tenant/floatingips/oldid',
errstr=u'Unable to delete floating IP: %s')
])
def test_HTTPSConnectionWithValidation_without_cert(self):
con = self.sm.HTTPSConnectionWithValidation(
'www.example.org', 443, timeout=90)
con.source_address = '127.0.0.1'
con.request("GET", "/")
self.socket_mock.assert_has_calls([mock.call(
('www.example.org', 443), 90, '127.0.0.1'
)])
self.wrap_mock.assert_has_calls([mock.call(
self.socket_mock(), None, None, cert_reqs=ssl.CERT_NONE
)])
self.assertEqual(con.sock, self.wrap_mock())
def test_HTTPSConnectionWithValidation_with_cert(self):
con = self.sm.HTTPSConnectionWithValidation(
'www.example.org', 443, timeout=90)
con.combined_cert = 'SOMECERTS.pem'
con.source_address = '127.0.0.1'
con.request("GET", "/")
self.socket_mock.assert_has_calls([mock.call(
('www.example.org', 443), 90, '127.0.0.1'
)])
self.wrap_mock.assert_has_calls([mock.call(
self.socket_mock(), None, None, ca_certs='SOMECERTS.pem',
cert_reqs=ssl.CERT_REQUIRED
)])
self.assertEqual(con.sock, self.wrap_mock())
def test_HTTPSConnectionWithValidation_tunnel(self):
tunnel_mock = mock.patch.object(
self.sm.HTTPSConnectionWithValidation,
'_tunnel').start()
con = self.sm.HTTPSConnectionWithValidation(
'www.example.org', 443, timeout=90)
con.source_address = '127.0.0.1'
if not hasattr(con, 'set_tunnel'):
# no tunnel support in py26
return
con.set_tunnel('myproxy.local', 3128)
con.request("GET", "/")
self.socket_mock.assert_has_calls([mock.call(
('www.example.org', 443), 90, '127.0.0.1'
)])
self.wrap_mock.assert_has_calls([mock.call(
self.socket_mock(), None, None, cert_reqs=ssl.CERT_NONE
)])
# _tunnel() doesn't take any args
tunnel_mock.assert_has_calls([mock.call()])
self.assertEqual(con._tunnel_host, 'myproxy.local')
self.assertEqual(con._tunnel_port, 3128)
self.assertEqual(con.sock, self.wrap_mock())

View File

@ -14,6 +14,7 @@
#
# @author: Kevin Benton, kevin.benton@bigswitch.com
#
from contextlib import nested
import os
import mock
@ -34,8 +35,8 @@ CERTCOMBINER = SERVERMANAGER + '.ServerPool._combine_certs_to_file'
FILEPUT = SERVERMANAGER + '.ServerPool._file_put_contents'
GETCACERTS = SERVERMANAGER + '.ServerPool._get_ca_cert_paths'
GETHOSTCERT = SERVERMANAGER + '.ServerPool._get_host_cert_path'
SSLGETCERT = SERVERMANAGER + '.ssl.get_server_certificate'
FAKECERTGET = 'neutron.tests.unit.bigswitch.fake_server.get_cert_contents'
SSLGETCERT = 'ssl.get_server_certificate'
class test_ssl_certificate_base(test_plugin.NeutronDbPluginV2TestCase,
@ -91,9 +92,6 @@ class TestSslSticky(test_ssl_certificate_base):
self.setup_config_files()
cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
cfg.CONF.set_override('ssl_sticky', True, 'RESTPROXY')
self.httpsPatch = mock.patch(HTTPS, create=True,
new=fake_server.HTTPSHostValidation)
self.httpsPatch.start()
self._setUp()
# Set fake HTTPS connection's expectation
self.fake_certget_m.return_value = self.host_cert_val
@ -103,7 +101,10 @@ class TestSslSticky(test_ssl_certificate_base):
def test_sticky_cert(self):
# SSL connection should be successful and cert should be cached
with self.network():
with nested(
mock.patch(HTTPS, new=fake_server.HTTPSHostValidation),
self.network()
):
# CA certs should have been checked for
self.getcacerts_m.assert_has_calls([mock.call(self.ca_certs_path)])
# cert should have been fetched via SSL lib
@ -189,9 +190,6 @@ class TestSslWrongHostCert(test_ssl_certificate_base):
self.setup_config_files()
cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
cfg.CONF.set_override('ssl_sticky', True, 'RESTPROXY')
self.httpsPatch = mock.patch(HTTPS, create=True,
new=fake_server.HTTPSHostValidation)
self.httpsPatch.start()
self._setUp()
# Set fake HTTPS connection's expectation to something wrong
@ -214,8 +212,9 @@ class TestSslWrongHostCert(test_ssl_certificate_base):
data = {}
data['network'] = {'tenant_id': tid, 'name': 'name',
'admin_state_up': True}
req = self.new_create_request('networks', data, 'json')
res = req.get_response(self.api)
with mock.patch(HTTPS, new=fake_server.HTTPSHostValidation):
req = self.new_create_request('networks', data, 'json')
res = req.get_response(self.api)
self.assertEqual(res.status_int,
webob.exc.HTTPInternalServerError.code)
self.hcertpath_p.assert_has_calls([
@ -236,16 +235,16 @@ class TestSslNoValidation(test_ssl_certificate_base):
cfg.CONF.set_override('server_ssl', True, 'RESTPROXY')
cfg.CONF.set_override('ssl_sticky', False, 'RESTPROXY')
cfg.CONF.set_override('no_ssl_validation', True, 'RESTPROXY')
self.httpsPatch = mock.patch(HTTPS, create=True,
new=fake_server.HTTPSNoValidation)
self.httpsPatch.start()
self._setUp()
super(TestSslNoValidation, self).setUp()
def test_validation_disabled(self):
# SSL connection should be successful without any certificates
# If not, attempting to create a network will raise an exception
with self.network():
with nested(
mock.patch(HTTPS, new=fake_server.HTTPSNoValidation),
self.network()
):
# no sticky grabbing and no cert combining with no enforcement
self.assertFalse(self.sslgetcert_m.call_count)
self.assertFalse(self.certcomb_m.call_count)