Skip to content

Commit

Permalink
Release ipdb and iproute to avoid resource exhaustion in tests (#226) (
Browse files Browse the repository at this point in the history
…#49)

DESCRIPTION: fix an issue in the test suite that was limiting the amount of virtual nodes that could be created.

The test suite had a flaw where only 55 virtual nodes could be created. This caused added tests to fail 'randomly' while succeeding in isolation. By correctly closing both the uses of IPDB and IPRoute we can now create upto 168 virtual nodes before running into the same flaw again.

It is unclear what the current limitation is, but this gives us enough headroom for the foreseeable future to keep adding tests.

Special thanks to Hadi for finding the missing release calls.
  • Loading branch information
mtuncer committed Jul 31, 2019
1 parent 4822ccb commit 61d47ff
Showing 1 changed file with 34 additions and 33 deletions.
67 changes: 34 additions & 33 deletions tests/network.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,13 @@ def _add_bridge(self, name, address, prefixLen):
"""
_remove_interface_if_exists(name)

ipr = IPRoute()
ipr.link('add', ifname=name, kind='bridge')
with IPRoute() as ipr:
ipr.link('add', ifname=name, kind='bridge')

ipdb = IPDB()
with ipdb.interfaces[name] as bridge:
bridge.add_ip('%s/%d' % (address, prefixLen, ))
bridge.up()
with IPDB() as ipdb:
with ipdb.interfaces[name] as bridge:
bridge.add_ip('%s/%d' % (address, prefixLen, ))
bridge.up()

def _add_interface_to_bridge(self, bridge, interface):
"""
Expand All @@ -90,11 +90,11 @@ def _add_interface_to_bridge(self, bridge, interface):
network namespace, in which case after calling this function the namespace
will be able to communicate with the other nodes in the virtual network.
"""
ipr = IPRoute()
bridge_idx = ipr.link_lookup(ifname=bridge)[0]
interface_idx = ipr.link_lookup(ifname=interface)[0]
ipr.link('set', index=interface_idx, master=bridge_idx)
ipr.link('set', index=interface_idx, state='up')
with IPRoute() as ipr:
bridge_idx = ipr.link_lookup(ifname=bridge)[0]
interface_idx = ipr.link_lookup(ifname=interface)[0]
ipr.link('set', index=interface_idx, master=bridge_idx)
ipr.link('set', index=interface_idx, state='up')

class VirtualNode:
"""
Expand All @@ -113,6 +113,7 @@ def destroy(self):
"""
Removes all objects created for the virtual node.
"""
_remove_interface_if_exists(self.vethPeer)
try:
netns.remove(self.namespace)
except:
Expand Down Expand Up @@ -146,20 +147,20 @@ def _add_namespace(self, name, address, netmaskLength):
_remove_interface_if_exists(self.vethPeer)

# Create the veth pair and set one endpoint to the namespace.
ipr = IPRoute()
ipr.link('add', ifname=veth_name, kind='veth', peer=self.vethPeer)
idx = ipr.link_lookup(ifname=veth_name)[0]
ipr.link('set', index=idx, net_ns_fd=name)
with IPRoute() as ipr:
ipr.link('add', ifname=veth_name, kind='veth', peer=self.vethPeer)
idx = ipr.link_lookup(ifname=veth_name)[0]
ipr.link('set', index=idx, net_ns_fd=name)

# Assign address to the veth interface and bring it up.
ipdb = IPDB(nl=NetNS(name))
with ipdb.interfaces[veth_name] as veth:
veth.add_ip('%s/%d' % (address, netmaskLength, ))
veth.up()
with IPDB(nl=NetNS(name)) as ipdb:
with ipdb.interfaces[veth_name] as veth:
veth.add_ip('%s/%d' % (address, netmaskLength, ))
veth.up()

# Bring the loopback interface up.
with ipdb.interfaces['lo'] as lo:
lo.up()
# Bring the loopback interface up.
with ipdb.interfaces['lo'] as lo:
lo.up()

def _remove_namespace_if_exists(self, name):
"""
Expand All @@ -178,14 +179,14 @@ def _remove_interface_if_exists(name):
just returns silently. A bridge is also an interface, so this can be
used for removing bridges too.
"""
ipr = IPRoute()
# bring it down
try:
ipr.link('set', ifname=name, state='down')
except netlink.exceptions.NetlinkError:
pass
# remove it
try:
ipr.link('del', ifname=name)
except netlink.exceptions.NetlinkError:
pass
with IPRoute() as ipr:
# bring it down
try:
ipr.link('set', ifname=name, state='down')
except netlink.exceptions.NetlinkError:
pass
# remove it
try:
ipr.link('del', ifname=name)
except netlink.exceptions.NetlinkError:
pass

0 comments on commit 61d47ff

Please sign in to comment.