network tests pass

This commit is contained in:
Vishvananda Ishaya
2010-08-18 02:07:04 -07:00
parent f1ba62e867
commit 8c2e381cf4
3 changed files with 146 additions and 124 deletions

View File

@@ -81,13 +81,17 @@ def main():
LOG_FILENAME = 'example.log' LOG_FILENAME = 'example.log'
logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG) logging.basicConfig(filename=LOG_FILENAME,level=logging.DEBUG)
logging.debug("this is a test") logging.debug("this is a test")
sqlfile = os.environ.get('SQL_DB', '')
if int(os.environ.get('TESTING', '0')): if int(os.environ.get('TESTING', '0')):
logging.debug("fake rabbit is true")
FLAGS.fake_rabbit = True FLAGS.fake_rabbit = True
FLAGS.redis_db = 8 FLAGS.redis_db = 8
FLAGS.network_size = 32 FLAGS.network_size = 16
FLAGS.connection_type = 'fake' FLAGS.connection_type = 'fake'
FLAGS.fake_network = True FLAGS.fake_network = True
FLAGS.auth_driver = 'nova.auth.ldapdriver.FakeLdapDriver' FLAGS.auth_driver = 'nova.auth.ldapdriver.FakeLdapDriver'
FLAGS.num_networks = 5
FLAGS.sql_connection = 'sqlite:///%s' % sqlfile
action = argv[1] action = argv[1]
if action in ['add', 'del', 'old']: if action in ['add', 'del', 'old']:
mac = argv[2] mac = argv[2]

View File

@@ -573,9 +573,10 @@ class AuthManager(object):
# FIXME(vish): this shouldn't be messing with the datamodel directly # FIXME(vish): this shouldn't be messing with the datamodel directly
if not isinstance(project, Project): if not isinstance(project, Project):
project = self.get_project(project) project = self.get_project(project)
if not project.network: if not project.network.vpn_public_port:
raise exception.NotFound('project network data has not been set') raise exception.NotFound('project network data has not been set')
return (project.network.vpn_ip_str, project.network.vpn_port) return (project.network.vpn_public_ip_str,
project.network.vpn_public_port)
def delete_project(self, project): def delete_project(self, project):
"""Deletes a project""" """Deletes a project"""

View File

@@ -21,6 +21,7 @@ Unit Tests for network code
import IPy import IPy
import os import os
import logging import logging
import tempfile
from nova import flags from nova import flags
from nova import models from nova import models
@@ -28,7 +29,7 @@ from nova import test
from nova import utils from nova import utils
from nova.auth import manager from nova.auth import manager
from nova.network import service from nova.network import service
from nova.network.exception import NoMoreAddresses from nova.network.exception import NoMoreAddresses, NoMoreNetworks
FLAGS = flags.FLAGS FLAGS = flags.FLAGS
@@ -39,18 +40,21 @@ class NetworkTestCase(test.TrialTestCase):
super(NetworkTestCase, self).setUp() super(NetworkTestCase, self).setUp()
# NOTE(vish): if you change these flags, make sure to change the # NOTE(vish): if you change these flags, make sure to change the
# flags in the corresponding section in nova-dhcpbridge # flags in the corresponding section in nova-dhcpbridge
fd, sqlfile = tempfile.mkstemp()
self.sqlfile = os.path.abspath(sqlfile)
self.flags(connection_type='fake', self.flags(connection_type='fake',
sql_connection='sqlite:///%s' % self.sqlfile,
fake_storage=True, fake_storage=True,
fake_network=True, fake_network=True,
auth_driver='nova.auth.ldapdriver.FakeLdapDriver', auth_driver='nova.auth.ldapdriver.FakeLdapDriver',
network_size=32, network_size=16,
num_networks=10) num_networks=5)
logging.getLogger().setLevel(logging.DEBUG) logging.getLogger().setLevel(logging.DEBUG)
self.manager = manager.AuthManager() self.manager = manager.AuthManager()
self.user = self.manager.create_user('netuser', 'netuser', 'netuser') self.user = self.manager.create_user('netuser', 'netuser', 'netuser')
self.projects = [] self.projects = []
self.service = service.VlanNetworkService() self.service = service.VlanNetworkService()
for i in range(0, 6): for i in range(5):
name = 'project%s' % i name = 'project%s' % i
self.projects.append(self.manager.create_project(name, self.projects.append(self.manager.create_project(name,
'netuser', 'netuser',
@@ -62,149 +66,145 @@ class NetworkTestCase(test.TrialTestCase):
instance.hostname = 'fake' instance.hostname = 'fake'
instance.image_id = 'fake' instance.image_id = 'fake'
instance.save() instance.save()
self.instance = instance self.instance_id = instance.id
def tearDown(self): # pylint: disable=C0103 def tearDown(self): # pylint: disable=C0103
super(NetworkTestCase, self).tearDown() super(NetworkTestCase, self).tearDown()
for project in self.projects: for project in self.projects:
self.manager.delete_project(project) self.manager.delete_project(project)
self.manager.delete_user(self.user) self.manager.delete_user(self.user)
os.unlink(self.sqlfile)
def test_public_network_allocation(self): def test_public_network_association(self):
"""Makes sure that we can allocaate a public ip""" """Makes sure that we can allocaate a public ip"""
# FIXME better way of adding elastic ips
pubnet = IPy.IP(flags.FLAGS.public_range) pubnet = IPy.IP(flags.FLAGS.public_range)
address = self.service.allocate_elastic_ip(self.projects[0].id) elastic_ip = models.ElasticIp()
self.assertTrue(IPy.IP(address) in pubnet) elastic_ip.ip_str = str(pubnet[0])
elastic_ip.node_name = FLAGS.node_name
elastic_ip.save()
eaddress = self.service.allocate_elastic_ip(self.projects[0].id)
faddress = self.service.allocate_fixed_ip(self.projects[0].id,
self.instance_id)
self.assertEqual(eaddress, str(pubnet[0]))
self.service.associate_elastic_ip(eaddress, faddress)
# FIXME datamodel abstraction
self.assertEqual(elastic_ip.fixed_ip.ip_str, faddress)
self.service.disassociate_elastic_ip(eaddress)
self.assertEqual(elastic_ip.fixed_ip, None)
self.service.deallocate_elastic_ip(eaddress)
self.service.deallocate_fixed_ip(faddress)
def test_allocate_deallocate_fixed_ip(self): def test_allocate_deallocate_fixed_ip(self):
"""Makes sure that we can allocate and deallocate a fixed ip""" """Makes sure that we can allocate and deallocate a fixed ip"""
address = self.service.allocate_fixed_ip(self.projects[0].id, address = self.service.allocate_fixed_ip(self.projects[0].id,
self.instance.id) self.instance_id)
net = service.get_network_for_project(self.projects[0].id) net = service.get_network_for_project(self.projects[0].id)
self.assertEqual(True, is_allocated_in_project(address, self.projects[0].id)) self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
issue_ip(address, net.bridge) issue_ip(address, net.bridge, self.sqlfile)
self.service.deallocate_fixed_ip(address) self.service.deallocate_fixed_ip(address)
# Doesn't go away until it's dhcp released # Doesn't go away until it's dhcp released
self.assertEqual(True, is_allocated_in_project(address, self.projects[0].id)) self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
release_ip(address, net.bridge) release_ip(address, net.bridge, self.sqlfile)
self.assertEqual(False, is_allocated_in_project(address, self.projects[0].id)) self.assertFalse(is_allocated_in_project(address, self.projects[0].id))
def test_side_effects(self): def test_side_effects(self):
"""Ensures allocating and releasing has no side effects""" """Ensures allocating and releasing has no side effects"""
hostname = "side-effect-host" address = self.service.allocate_fixed_ip(self.projects[0].id,
result = self.service.allocate_fixed_ip( self.instance_id)
self.projects[0].id) address2 = self.service.allocate_fixed_ip(self.projects[1].id,
mac = result['mac_address'] self.instance_id)
address = result['private_dns_name']
result = self.service.allocate_fixed_ip(self.user,
self.projects[1].id)
secondmac = result['mac_address']
secondaddress = result['private_dns_name']
net = service.get_network_for_project(self.projects[0].id) net = service.get_network_for_project(self.projects[0].id)
secondnet = service.get_network_for_project(self.projects[1].id) net2 = service.get_network_for_project(self.projects[1].id)
self.assertEqual(True, is_allocated_in_project(address, self.projects[0].id)) self.assertTrue(is_allocated_in_project(address, self.projects[0].id))
self.assertEqual(True, is_allocated_in_project(secondaddress, self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
self.projects[1].id)) self.assertFalse(is_allocated_in_project(address, self.projects[1].id))
self.assertEqual(False, is_allocated_in_project(address, self.projects[1].id))
# Addresses are allocated before they're issued # Addresses are allocated before they're issued
issue_ip(mac, address, hostname, net.bridge_name) issue_ip(address, net.bridge, self.sqlfile)
issue_ip(secondmac, secondaddress, hostname, secondnet.bridge_name) issue_ip(address2, net2.bridge, self.sqlfile)
self.service.deallocate_fixed_ip(address) self.service.deallocate_fixed_ip(address)
release_ip(mac, address, hostname, net.bridge_name) release_ip(address, net.bridge, self.sqlfile)
self.assertEqual(False, is_allocated_in_project(address, self.projects[0].id)) self.assertFalse(is_allocated_in_project(address, self.projects[0].id))
# First address release shouldn't affect the second # First address release shouldn't affect the second
self.assertEqual(True, is_allocated_in_project(secondaddress, self.assertTrue(is_allocated_in_project(address2, self.projects[1].id))
self.projects[1].id))
self.service.deallocate_fixed_ip(secondaddress) self.service.deallocate_fixed_ip(address2)
release_ip(secondmac, secondaddress, hostname, secondnet.bridge_name) issue_ip(address2, net.bridge, self.sqlfile)
self.assertEqual(False, is_allocated_in_project(secondaddress, release_ip(address2, net2.bridge, self.sqlfile)
self.projects[1].id)) self.assertFalse(is_allocated_in_project(address2, self.projects[1].id))
def test_subnet_edge(self): def test_subnet_edge(self):
"""Makes sure that private ips don't overlap""" """Makes sure that private ips don't overlap"""
result = self.service.allocate_fixed_ip( first = self.service.allocate_fixed_ip(self.projects[0].id,
self.projects[0].id) self.instance_id)
firstaddress = result['private_dns_name']
hostname = "toomany-hosts"
for i in range(1, 5): for i in range(1, 5):
project_id = self.projects[i].id project_id = self.projects[i].id
result = self.service.allocate_fixed_ip( address = self.service.allocate_fixed_ip(project_id, self.instance_id)
self.user, project_id) address2 = self.service.allocate_fixed_ip(project_id, self.instance_id)
mac = result['mac_address'] address3 = self.service.allocate_fixed_ip(project_id, self.instance_id)
address = result['private_dns_name']
result = self.service.allocate_fixed_ip(
self.user, project_id)
mac2 = result['mac_address']
address2 = result['private_dns_name']
result = self.service.allocate_fixed_ip(
self.user, project_id)
mac3 = result['mac_address']
address3 = result['private_dns_name']
net = service.get_network_for_project(project_id) net = service.get_network_for_project(project_id)
issue_ip(mac, address, hostname, net.bridge_name) issue_ip(address, net.bridge, self.sqlfile)
issue_ip(mac2, address2, hostname, net.bridge_name) issue_ip(address2, net.bridge, self.sqlfile)
issue_ip(mac3, address3, hostname, net.bridge_name) issue_ip(address3, net.bridge, self.sqlfile)
self.assertEqual(False, is_allocated_in_project(address, self.assertFalse(is_allocated_in_project(address,
self.projects[0].id)) self.projects[0].id))
self.assertEqual(False, is_allocated_in_project(address2, self.assertFalse(is_allocated_in_project(address2,
self.projects[0].id)) self.projects[0].id))
self.assertEqual(False, is_allocated_in_project(address3, self.assertFalse(is_allocated_in_project(address3,
self.projects[0].id)) self.projects[0].id))
self.service.deallocate_fixed_ip(address) self.service.deallocate_fixed_ip(address)
self.service.deallocate_fixed_ip(address2) self.service.deallocate_fixed_ip(address2)
self.service.deallocate_fixed_ip(address3) self.service.deallocate_fixed_ip(address3)
release_ip(mac, address, hostname, net.bridge_name) release_ip(address, net.bridge, self.sqlfile)
release_ip(mac2, address2, hostname, net.bridge_name) release_ip(address2, net.bridge, self.sqlfile)
release_ip(mac3, address3, hostname, net.bridge_name) release_ip(address3, net.bridge, self.sqlfile)
net = service.get_network_for_project(self.projects[0].id) net = service.get_network_for_project(self.projects[0].id)
self.service.deallocate_fixed_ip(firstaddress) self.service.deallocate_fixed_ip(first)
release_ip(mac, firstaddress, hostname, net.bridge_name)
def test_vpn_ip_and_port_looks_valid(self): def test_vpn_ip_and_port_looks_valid(self):
"""Ensure the vpn ip and port are reasonable""" """Ensure the vpn ip and port are reasonable"""
self.assert_(self.projects[0].vpn_ip) self.assert_(self.projects[0].vpn_ip)
self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start_port) self.assert_(self.projects[0].vpn_port >= FLAGS.vpn_start)
self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_end_port) self.assert_(self.projects[0].vpn_port <= FLAGS.vpn_start +
FLAGS.num_networks)
def test_too_many_vpns(self): def test_too_many_networks(self):
"""Ensure error is raised if we run out of vpn ports""" """Ensure error is raised if we run out of vpn ports"""
vpns = [] projects = []
for i in xrange(vpn.NetworkData.num_ports_for_ip(FLAGS.vpn_ip)): networks_left = FLAGS.num_networks - len(self.projects)
vpns.append(vpn.NetworkData.create("vpnuser%s" % i)) for i in range(networks_left):
self.assertRaises(vpn.NoMorePorts, vpn.NetworkData.create, "boom") project = self.manager.create_project('many%s' % i, self.user)
for network_datum in vpns: self.service.set_network_host(project.id)
network_datum.destroy() projects.append(project)
project = self.manager.create_project('boom' , self.user)
self.assertRaises(NoMoreNetworks,
self.service.set_network_host,
project.id)
self.manager.delete_project(project)
for project in projects:
self.manager.delete_project(project)
def test_ips_are_reused(self): def test_ips_are_reused(self):
"""Makes sure that ip addresses that are deallocated get reused""" """Makes sure that ip addresses that are deallocated get reused"""
result = self.service.allocate_fixed_ip( address = self.service.allocate_fixed_ip(self.projects[0].id,
self.projects[0].id) self.instance_id)
mac = result['mac_address']
address = result['private_dns_name']
hostname = "reuse-host"
net = service.get_network_for_project(self.projects[0].id) net = service.get_network_for_project(self.projects[0].id)
issue_ip(address, net.bridge, self.sqlfile)
issue_ip(mac, address, hostname, net.bridge_name)
self.service.deallocate_fixed_ip(address) self.service.deallocate_fixed_ip(address)
release_ip(mac, address, hostname, net.bridge_name) release_ip(address, net.bridge, self.sqlfile)
result = self.service.allocate_fixed_ip( address2 = self.service.allocate_fixed_ip(self.projects[0].id,
self.user, self.projects[0].id) self.instance_id)
secondmac = result['mac_address'] self.assertEqual(address, address2)
secondaddress = result['private_dns_name'] self.service.deallocate_fixed_ip(address2)
self.assertEqual(address, secondaddress)
issue_ip(secondmac, secondaddress, hostname, net.bridge_name)
self.service.deallocate_fixed_ip(secondaddress)
release_ip(secondmac, secondaddress, hostname, net.bridge_name)
def test_available_ips(self): def test_available_ips(self):
"""Make sure the number of available ips for the network is correct """Make sure the number of available ips for the network is correct
@@ -217,50 +217,65 @@ class NetworkTestCase(test.TrialTestCase):
There are ips reserved at the bottom and top of the range. There are ips reserved at the bottom and top of the range.
services (network, gateway, CloudPipe, broadcast) services (network, gateway, CloudPipe, broadcast)
""" """
net = service.get_network_for_project(self.projects[0].id) network = service.get_network_for_project(self.projects[0].id)
num_preallocated_ips = len(net.assigned)
net_size = flags.FLAGS.network_size net_size = flags.FLAGS.network_size
num_available_ips = net_size - (net.num_bottom_reserved_ips + total_ips = (available_ips(network) +
num_preallocated_ips + reserved_ips(network) +
net.num_top_reserved_ips) allocated_ips(network))
self.assertEqual(num_available_ips, len(list(net.available))) self.assertEqual(total_ips, net_size)
def test_too_many_addresses(self): def test_too_many_addresses(self):
"""Test for a NoMoreAddresses exception when all fixed ips are used. """Test for a NoMoreAddresses exception when all fixed ips are used.
""" """
net = service.get_network_for_project(self.projects[0].id) network = service.get_network_for_project(self.projects[0].id)
hostname = "toomany-hosts"
macs = {}
addresses = {}
# Number of availaible ips is len of the available list # Number of availaible ips is len of the available list
num_available_ips = len(list(net.available))
for i in range(num_available_ips):
result = self.service.allocate_fixed_ip(
self.projects[0].id)
macs[i] = result['mac_address']
addresses[i] = result['private_dns_name']
issue_ip(macs[i], addresses[i], hostname, net.bridge_name)
self.assertEqual(len(list(net.available)), 0) num_available_ips = available_ips(network)
addresses = []
for i in range(num_available_ips):
project_id = self.projects[0].id
addresses.append(self.service.allocate_fixed_ip(project_id,
self.instance_id))
issue_ip(addresses[i],network.bridge, self.sqlfile)
self.assertEqual(available_ips(network), 0)
self.assertRaises(NoMoreAddresses, self.assertRaises(NoMoreAddresses,
self.service.allocate_fixed_ip, self.service.allocate_fixed_ip,
self.projects[0].id, self.projects[0].id,
0) self.instance_id)
for i in range(len(addresses)): for i in range(len(addresses)):
self.service.deallocate_fixed_ip(addresses[i]) self.service.deallocate_fixed_ip(addresses[i])
release_ip(macs[i], addresses[i], hostname, net.bridge_name) release_ip(addresses[i],network.bridge, self.sqlfile)
self.assertEqual(len(list(net.available)), num_available_ips) self.assertEqual(available_ips(network), num_available_ips)
# FIXME move these to abstraction layer
def available_ips(network):
session = models.NovaBase.get_session()
query = session.query(models.FixedIp).filter_by(network_id=network.id)
query = query.filter_by(allocated=False).filter_by(reserved=False)
return query.count()
def allocated_ips(network):
session = models.NovaBase.get_session()
query = session.query(models.FixedIp).filter_by(network_id=network.id)
query = query.filter_by(allocated=True)
return query.count()
def reserved_ips(network):
session = models.NovaBase.get_session()
query = session.query(models.FixedIp).filter_by(network_id=network.id)
query = query.filter_by(reserved=True)
return query.count()
def is_allocated_in_project(address, project_id): def is_allocated_in_project(address, project_id):
"""Returns true if address is in specified project""" """Returns true if address is in specified project"""
fixed_ip = models.FixedIp.find_by_ip_str(address) fixed_ip = models.FixedIp.find_by_ip_str(address)
project_net = service.get_network_for_project(project_id) project_net = service.get_network_for_project(project_id)
print fixed_ip.instance
# instance exists until release # instance exists until release
return fixed_ip.instance and project_net == fixed_ip.network return fixed_ip.instance is not None and fixed_ip.network == project_net
def binpath(script): def binpath(script):
@@ -268,20 +283,22 @@ def binpath(script):
return os.path.abspath(os.path.join(__file__, "../../../bin", script)) return os.path.abspath(os.path.join(__file__, "../../../bin", script))
def issue_ip(private_ip, interface): def issue_ip(private_ip, interface, sqlfile):
"""Run add command on dhcpbridge""" """Run add command on dhcpbridge"""
cmd = "%s add %s fake fake" % (binpath('nova-dhcpbridge'), private_ip) cmd = "%s add fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
env = {'DNSMASQ_INTERFACE': interface, env = {'DNSMASQ_INTERFACE': interface,
'TESTING': '1', 'TESTING': '1',
'SQL_DB': sqlfile,
'FLAGFILE': FLAGS.dhcpbridge_flagfile} 'FLAGFILE': FLAGS.dhcpbridge_flagfile}
(out, err) = utils.execute(cmd, addl_env=env) (out, err) = utils.execute(cmd, addl_env=env)
logging.debug("ISSUE_IP: %s, %s ", out, err) logging.debug("ISSUE_IP: %s, %s ", out, err)
def release_ip(private_ip, interface): def release_ip(private_ip, interface, sqlfile):
"""Run del command on dhcpbridge""" """Run del command on dhcpbridge"""
cmd = "%s del %s fake fake" % (binpath('nova-dhcpbridge'), private_ip) cmd = "%s del fake %s fake" % (binpath('nova-dhcpbridge'), private_ip)
env = {'DNSMASQ_INTERFACE': interface, env = {'DNSMASQ_INTERFACE': interface,
'SQL_DB': sqlfile,
'TESTING': '1', 'TESTING': '1',
'FLAGFILE': FLAGS.dhcpbridge_flagfile} 'FLAGFILE': FLAGS.dhcpbridge_flagfile}
(out, err) = utils.execute(cmd, addl_env=env) (out, err) = utils.execute(cmd, addl_env=env)