summaryrefslogtreecommitdiffhomepage
path: root/test
diff options
context:
space:
mode:
Diffstat (limited to 'test')
-rw-r--r--test/lib/bagpipe.py12
-rw-r--r--test/lib/base.py85
-rw-r--r--test/lib/bird.py15
-rw-r--r--test/lib/exabgp.py17
-rw-r--r--test/lib/gobgp.py122
-rw-r--r--test/lib/quagga.py27
6 files changed, 178 insertions, 100 deletions
diff --git a/test/lib/bagpipe.py b/test/lib/bagpipe.py
index c73b6472..efca1c4e 100644
--- a/test/lib/bagpipe.py
+++ b/test/lib/bagpipe.py
@@ -13,7 +13,15 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from base import *
+from __future__ import absolute_import
+
+from fabric import colors
+from fabric.api import local
+
+from lib.base import (
+ BGPContainer,
+ CmdBuffer,
+)
class BagpipeContainer(BGPContainer):
@@ -41,7 +49,7 @@ class BagpipeContainer(BGPContainer):
c << '[BGP]'
if len(self.ip_addrs) > 0:
c << 'local_address={0}'.format(self.ip_addrs[0][1].split('/')[0])
- for peer, info in self.peers.iteritems():
+ for info in self.peers.values():
c << 'peers={0}'.format(info['neigh_addr'].split('/')[0])
c << 'my_as={0}'.format(self.asn)
c << 'enable_rtc=True'
diff --git a/test/lib/base.py b/test/lib/base.py
index cbbb764f..b6e77118 100644
--- a/test/lib/base.py
+++ b/test/lib/base.py
@@ -13,18 +13,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+from __future__ import absolute_import
+
+import os
+import time
+import itertools
+
from fabric.api import local, lcd
from fabric import colors
-from fabric.utils import indent
from fabric.state import env, output
try:
from docker import Client
except ImportError:
from docker import APIClient as Client
import netaddr
-import os
-import time
-import itertools
DEFAULT_TEST_PREFIX = ''
DEFAULT_TEST_BASE_DIR = '/tmp/gobgp'
@@ -49,6 +51,7 @@ BGP_ATTR_TYPE_EXTENDED_COMMUNITIES = 16
env.abort_exception = RuntimeError
output.stderr = False
+
def wait_for_completion(f, timeout=120):
interval = 1
count = 0
@@ -63,8 +66,8 @@ def wait_for_completion(f, timeout=120):
def try_several_times(f, t=3, s=1):
- e = None
- for i in range(t):
+ e = Exception
+ for _ in range(t):
try:
r = f()
except RuntimeError as e:
@@ -75,11 +78,11 @@ def try_several_times(f, t=3, s=1):
def get_bridges():
- return try_several_times(lambda : local("docker network ls | awk 'NR > 1{print $2}'", capture=True)).split('\n')
+ return try_several_times(lambda: local("docker network ls | awk 'NR > 1{print $2}'", capture=True)).split('\n')
def get_containers():
- return try_several_times(lambda : local("docker ps -a | awk 'NR > 1 {print $NF}'", capture=True)).split('\n')
+ return try_several_times(lambda: local("docker ps -a | awk 'NR > 1 {print $NF}'", capture=True)).split('\n')
class CmdBuffer(list):
@@ -126,10 +129,10 @@ class Bridge(object):
if with_ip:
self.subnet = netaddr.IPNetwork(subnet)
- def f():
+ def _f():
for host in self.subnet:
yield host
- self._ip_generator = f()
+ self._ip_generator = _f()
# throw away first network address
self.next_ip_address()
@@ -145,7 +148,7 @@ class Bridge(object):
self.self_ip = self_ip
if self_ip:
self.ip_addr = self.next_ip_address()
- try_several_times(lambda :local("ip addr add {0} dev {1}".format(self.ip_addr, self.name)))
+ try_several_times(lambda: local("ip addr add {0} dev {1}".format(self.ip_addr, self.name)))
self.ctns = []
def next_ip_address(self):
@@ -153,7 +156,7 @@ class Bridge(object):
self.subnet.prefixlen)
def addif(self, ctn):
- name = ctn.next_if_name()
+ _name = ctn.next_if_name()
self.ctns.append(ctn)
local("docker network connect {0} {1}".format(self.name, ctn.docker_name()))
i = [x for x in Client(timeout=60, version='auto').inspect_network(self.id)['Containers'].values() if x['Name'] == ctn.docker_name()][0]
@@ -164,7 +167,7 @@ class Bridge(object):
ctn.ip_addrs.append(('eth1', addr, self.name))
def delete(self):
- try_several_times(lambda : local("docker network rm {0}".format(self.name)))
+ try_several_times(lambda: local("docker network rm {0}".format(self.name)))
class Container(object):
@@ -187,7 +190,7 @@ class Container(object):
return '{0}_{1}'.format(TEST_PREFIX, self.name)
def next_if_name(self):
- name = 'eth{0}'.format(len(self.eths)+1)
+ name = 'eth{0}'.format(len(self.eths) + 1)
self.eths.append(name)
return name
@@ -197,7 +200,7 @@ class Container(object):
for sv in self.shared_volumes:
c << "-v {0}:{1}".format(sv[0], sv[1])
c << "--name {0} -id {1}".format(self.docker_name(), self.image)
- self.id = try_several_times(lambda : local(str(c), capture=True))
+ self.id = try_several_times(lambda: local(str(c), capture=True))
self.is_running = True
self.local("ip li set up dev lo")
for line in self.local("ip a show dev eth0", capture=True).split('\n'):
@@ -210,12 +213,12 @@ class Container(object):
return 0
def stop(self):
- ret = try_several_times(lambda : local("docker stop -t 0 " + self.docker_name(), capture=True))
+ ret = try_several_times(lambda: local("docker stop -t 0 " + self.docker_name(), capture=True))
self.is_running = False
return ret
def remove(self):
- ret = try_several_times(lambda : local("docker rm -f " + self.docker_name(), capture=True))
+ ret = try_several_times(lambda: local("docker rm -f " + self.docker_name(), capture=True))
self.is_running = False
return ret
@@ -232,7 +235,7 @@ class Container(object):
intf_name = "eth1"
c << "{0} {1}".format(self.docker_name(), ip_addr)
self.ip_addrs.append((intf_name, ip_addr, bridge.name))
- try_several_times(lambda :local(str(c)))
+ try_several_times(lambda: local(str(c)))
def local(self, cmd, capture=False, stream=False, detach=False, tty=True):
if stream:
@@ -283,7 +286,7 @@ class BGPContainer(Container):
super(BGPContainer, self).__init__(name, ctn_image_name)
def __repr__(self):
- return str({'name':self.name, 'asn':self.asn, 'router_id':self.router_id})
+ return str({'name': self.name, 'asn': self.asn, 'router_id': self.router_id})
def run(self):
self.create_config()
@@ -368,7 +371,7 @@ class BGPContainer(Container):
'local-pref': local_pref,
'extended-community': extendedcommunity,
'matchs': matchs,
- 'thens' : thens}
+ 'thens': thens}
if self.is_running and reload_config:
self.create_config()
self.reload_config()
@@ -410,27 +413,27 @@ class BGPContainer(Container):
raise Exception('implement get_neighbor() method')
def get_reachablily(self, prefix, timeout=20):
- version = netaddr.IPNetwork(prefix).version
- addr = prefix.split('/')[0]
- if version == 4:
- ping_cmd = 'ping'
- elif version == 6:
- ping_cmd = 'ping6'
- else:
- raise Exception('unsupported route family: {0}'.format(version))
- cmd = '/bin/bash -c "/bin/{0} -c 1 -w 1 {1} | xargs echo"'.format(ping_cmd, addr)
- interval = 1
- count = 0
- while True:
- res = self.local(cmd, capture=True)
- print colors.yellow(res)
- if '1 packets received' in res and '0% packet loss':
- break
- time.sleep(interval)
- count += interval
- if count >= timeout:
- raise Exception('timeout')
- return True
+ version = netaddr.IPNetwork(prefix).version
+ addr = prefix.split('/')[0]
+ if version == 4:
+ ping_cmd = 'ping'
+ elif version == 6:
+ ping_cmd = 'ping6'
+ else:
+ raise Exception('unsupported route family: {0}'.format(version))
+ cmd = '/bin/bash -c "/bin/{0} -c 1 -w 1 {1} | xargs echo"'.format(ping_cmd, addr)
+ interval = 1
+ count = 0
+ while True:
+ res = self.local(cmd, capture=True)
+ print colors.yellow(res)
+ if '1 packets received' in res and '0% packet loss':
+ break
+ time.sleep(interval)
+ count += interval
+ if count >= timeout:
+ raise Exception('timeout')
+ return True
def wait_for(self, expected_state, peer, timeout=120):
interval = 1
diff --git a/test/lib/bird.py b/test/lib/bird.py
index 598276bc..c728d986 100644
--- a/test/lib/bird.py
+++ b/test/lib/bird.py
@@ -13,7 +13,20 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from base import *
+from __future__ import absolute_import
+
+import time
+
+from fabric import colors
+from fabric.api import local
+from fabric.utils import indent
+
+from lib.base import (
+ BGPContainer,
+ CmdBuffer,
+ try_several_times,
+)
+
class BirdContainer(BGPContainer):
diff --git a/test/lib/exabgp.py b/test/lib/exabgp.py
index e3934c79..511a7890 100644
--- a/test/lib/exabgp.py
+++ b/test/lib/exabgp.py
@@ -13,8 +13,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from base import *
-from itertools import chain
+from __future__ import absolute_import
+
+import time
+
+from fabric import colors
+from fabric.api import local
+
+from lib.base import (
+ BGPContainer,
+ CmdBuffer,
+ try_several_times,
+)
+
class ExaBGPContainer(BGPContainer):
@@ -46,7 +57,7 @@ class ExaBGPContainer(BGPContainer):
c << 'cp {0}/etc/exabgp/exabgp.env {1}'.format(remotepath, self.SHARED_VOLUME)
c << 'sed -i -e \'s/all = false/all = true/g\' {0}/exabgp.env'.format(self.SHARED_VOLUME)
c << 'cp -r {0}/exabgp {1}'.format(self.SHARED_VOLUME,
- remotepath[:-1*len('exabgp')])
+ remotepath[:-1 * len('exabgp')])
c << 'cp {0}/exabgp.env {1}/etc/exabgp/'.format(self.SHARED_VOLUME, remotepath)
cmd = 'echo "{0:s}" > {1}/update.sh'.format(c, self.config_dir)
local(cmd, capture=True)
diff --git a/test/lib/gobgp.py b/test/lib/gobgp.py
index 8c0d9cdd..468bd0ae 100644
--- a/test/lib/gobgp.py
+++ b/test/lib/gobgp.py
@@ -13,22 +13,39 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from base import *
+from __future__ import absolute_import
+
import json
-import toml
-import yaml
from itertools import chain
from threading import Thread
-import socket
import subprocess
import os
+from fabric import colors
+from fabric.api import local
+from fabric.utils import indent
+import netaddr
+import toml
+import yaml
+
+from lib.base import (
+ BGPContainer,
+ CmdBuffer,
+ BGP_ATTR_TYPE_AS_PATH,
+ BGP_ATTR_TYPE_NEXT_HOP,
+ BGP_ATTR_TYPE_MULTI_EXIT_DISC,
+ BGP_ATTR_TYPE_LOCAL_PREF,
+ BGP_ATTR_TYPE_MP_REACH_NLRI,
+)
+
+
def extract_path_attribute(path, typ):
for a in path['attrs']:
if a['type'] == typ:
return a
return None
+
class GoBGPContainer(BGPContainer):
SHARED_VOLUME = '/root/shared_volume'
@@ -45,6 +62,7 @@ class GoBGPContainer(BGPContainer):
self.prefix_set = None
self.neighbor_set = None
self.bgp_set = None
+ self.statements = None
self.default_policy = None
self.zebra = zebra
self.zapi_version = zapi_version
@@ -81,26 +99,29 @@ class GoBGPContainer(BGPContainer):
self._start_gobgp()
return self.WAIT_FOR_BOOT
- def _get_as_path(self, path):
- asps = (p['as_paths'] for p in path['attrs'] if
- p['type'] == BGP_ATTR_TYPE_AS_PATH and 'as_paths' in p
- and p['as_paths'] != None)
+ @staticmethod
+ def _get_as_path(path):
+ asps = (p['as_paths'] for p in path['attrs']
+ if p['type'] == BGP_ATTR_TYPE_AS_PATH and 'as_paths' in p and p['as_paths'] is not None)
asps = chain.from_iterable(asps)
asns = (asp['asns'] for asp in asps)
return list(chain.from_iterable(asns))
- def _get_nexthop(self, path):
+ @staticmethod
+ def _get_nexthop(path):
for p in path['attrs']:
if p['type'] == BGP_ATTR_TYPE_NEXT_HOP or p['type'] == BGP_ATTR_TYPE_MP_REACH_NLRI:
return p['nexthop']
- def _get_local_pref(self, path):
+ @staticmethod
+ def _get_local_pref(path):
for p in path['attrs']:
if p['type'] == BGP_ATTR_TYPE_LOCAL_PREF:
return p['value']
return None
- def _get_med(self, path):
+ @staticmethod
+ def _get_med(path):
for p in path['attrs']:
if p['type'] == BGP_ATTR_TYPE_MULTI_EXIT_DISC:
return p['metric']
@@ -222,7 +243,7 @@ class GoBGPContainer(BGPContainer):
self.statements = []
def set_prefix_set(self, ps):
- if type(ps) is not list:
+ if not isinstance(ps, list):
ps = [ps]
self.prefix_set = ps
@@ -232,7 +253,7 @@ class GoBGPContainer(BGPContainer):
self.prefix_set.append(ps)
def set_neighbor_set(self, ns):
- if type(ns) is not list:
+ if not isinstance(ns, list):
ns = [ns]
self.neighbor_set = ns
@@ -250,13 +271,20 @@ class GoBGPContainer(BGPContainer):
self._create_config_zebra()
def _create_config_bgp(self):
- config = {'global': {'config': {'as': self.asn, 'router-id': self.router_id},
- 'route-selection-options':{
+ config = {
+ 'global': {
+ 'config': {
+ 'as': self.asn,
+ 'router-id': self.router_id,
+ },
+ 'route-selection-options': {
'config': {
'external-compare-router-id': True,
},
},
- }}
+ },
+ 'neighbors': [],
+ }
if self.zebra and self.zapi_version == 2:
config['global']['use-multiple-paths'] = {'config': {'enabled': True}}
@@ -265,9 +293,9 @@ class GoBGPContainer(BGPContainer):
afi_safi_list = []
version = netaddr.IPNetwork(info['neigh_addr']).version
if version == 4:
- afi_safi_list.append({'config':{'afi-safi-name': 'ipv4-unicast'}})
+ afi_safi_list.append({'config': {'afi-safi-name': 'ipv4-unicast'}})
elif version == 6:
- afi_safi_list.append({'config':{'afi-safi-name': 'ipv6-unicast'}})
+ afi_safi_list.append({'config': {'afi-safi-name': 'ipv6-unicast'}})
else:
Exception('invalid ip address version. {0}'.format(version))
@@ -283,18 +311,23 @@ class GoBGPContainer(BGPContainer):
afi_safi_list.append({'config': {'afi-safi-name': 'ipv6-flowspec'}})
afi_safi_list.append({'config': {'afi-safi-name': 'l3vpn-ipv6-flowspec'}})
- n = {'config':
- {'neighbor-address': info['neigh_addr'].split('/')[0],
- 'peer-as': peer.asn,
- 'auth-password': info['passwd'],
- 'vrf': info['vrf'],
- },
- 'afi-safis': afi_safi_list,
- 'timers': {'config': {
- 'connect-retry': 10,
- }},
- 'transport': {'config': {}},
- }
+ n = {
+ 'config': {
+ 'neighbor-address': info['neigh_addr'].split('/')[0],
+ 'peer-as': peer.asn,
+ 'auth-password': info['passwd'],
+ 'vrf': info['vrf'],
+ },
+ 'afi-safis': afi_safi_list,
+ 'timers': {
+ 'config': {
+ 'connect-retry': 10,
+ },
+ },
+ 'transport': {
+ 'config': {},
+ },
+ }
if ':' in info['local_addr']:
n['transport']['config']['local-address'] = info['local_addr'].split('/')[0]
@@ -310,7 +343,7 @@ class GoBGPContainer(BGPContainer):
if info['prefix_limit']:
for v in afi_safi_list:
- v['prefix-limit'] = {'config': {'max-prefixes': info['prefix_limit'], 'shutdown-threshold-pct': 80 }}
+ v['prefix-limit'] = {'config': {'max-prefixes': info['prefix_limit'], 'shutdown-threshold-pct': 80}}
if info['graceful_restart'] is not None:
n['graceful-restart'] = {'config': {'enabled': True, 'restart-time': 20}}
@@ -324,11 +357,11 @@ class GoBGPContainer(BGPContainer):
afi_safi['long-lived-graceful-restart'] = {'config': {'enabled': True, 'restart-time': 30}}
if info['is_rr_client']:
- clusterId = self.router_id
+ cluster_id = self.router_id
if 'cluster_id' in info and info['cluster_id'] is not None:
- clusterId = info['cluster_id']
- n['route-reflector'] = {'config' : {'route-reflector-client': True,
- 'route-reflector-cluster-id': clusterId}}
+ cluster_id = info['cluster_id']
+ n['route-reflector'] = {'config': {'route-reflector-client': True,
+ 'route-reflector-cluster-id': cluster_id}}
if len(info.get('default-policy', [])) + len(info.get('policies', [])) > 0:
n['apply-policy'] = {'config': {}}
@@ -336,7 +369,7 @@ class GoBGPContainer(BGPContainer):
for typ, p in info.get('policies', {}).iteritems():
n['apply-policy']['config']['{0}-policy-list'.format(typ)] = [p['name']]
- def f(v):
+ def _f(v):
if v == 'reject':
return 'reject-route'
elif v == 'accept':
@@ -344,10 +377,7 @@ class GoBGPContainer(BGPContainer):
raise Exception('invalid default policy type {0}'.format(v))
for typ, d in info.get('default-policy', {}).iteritems():
- n['apply-policy']['config']['default-{0}-policy'.format(typ)] = f(d)
-
- if 'neighbors' not in config:
- config['neighbors'] = []
+ n['apply-policy']['config']['default-{0}-policy'.format(typ)] = _f(d)
config['neighbors'].append(n)
@@ -372,9 +402,9 @@ class GoBGPContainer(BGPContainer):
config['policy-definitions'] = policy_list
if self.zebra:
- config['zebra'] = {'config':{'enabled': True,
- 'redistribute-route-type-list':['connect'],
- 'version': self.zapi_version}}
+ config['zebra'] = {'config': {'enabled': True,
+ 'redistribute-route-type-list': ['connect'],
+ 'version': self.zapi_version}}
with open('{0}/gobgpd.conf'.format(self.config_dir), 'w') as f:
print colors.yellow('[{0}\'s new config]'.format(self.name))
@@ -405,8 +435,7 @@ class GoBGPContainer(BGPContainer):
f.writelines(str(c))
def reload_config(self):
- daemon = []
- daemon.append('gobgpd')
+ daemon = ['gobgpd']
if self.zebra:
daemon.append('zebra')
for d in daemon:
@@ -428,7 +457,7 @@ class GoBGPContainer(BGPContainer):
cmd = 'gobgp global '\
'rib add match {0} then {1} -a {2}'.format(' '.join(v['matchs']), ' '.join(v['thens']), v['rf'])
else:
- raise Exception('unsupported route faily: {0}'.format(rf))
+ raise Exception('unsupported route faily: {0}'.format(v['rf']))
self.local(cmd)
@@ -449,6 +478,7 @@ class RawGoBGPContainer(GoBGPContainer):
super(RawGoBGPContainer, self).__init__(name, asn, router_id,
ctn_image_name, log_level,
zebra, config_format)
+
def create_config(self):
with open('{0}/gobgpd.conf'.format(self.config_dir), 'w') as f:
print colors.yellow('[{0}\'s new config]'.format(self.name))
diff --git a/test/lib/quagga.py b/test/lib/quagga.py
index 1f0d4d3b..ce3f9e84 100644
--- a/test/lib/quagga.py
+++ b/test/lib/quagga.py
@@ -13,8 +13,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-from base import *
-from nsenter import Namespace
+from __future__ import absolute_import
+
+from fabric import colors
+from fabric.utils import indent
+import netaddr
+
+from lib.base import (
+ BGPContainer,
+ CmdBuffer,
+ BGP_FSM_IDLE,
+ BGP_FSM_ACTIVE,
+ BGP_FSM_ESTABLISHED,
+ BGP_ATTR_TYPE_MULTI_EXIT_DISC,
+ BGP_ATTR_TYPE_LOCAL_PREF,
+)
class QuaggaBGPContainer(BGPContainer):
@@ -44,6 +57,7 @@ class QuaggaBGPContainer(BGPContainer):
read_next = False
for line in out.split('\n'):
+ ibgp = False
if line[:2] == '*>':
line = line[2:]
ibgp = False
@@ -121,10 +135,10 @@ class QuaggaBGPContainer(BGPContainer):
idx1 = info[0].index('BGP neighbor is ')
idx2 = info[0].index(',')
- n_addr = info[0][idx1+len('BGP neighbor is '):idx2]
+ n_addr = info[0][idx1 + len('BGP neighbor is '):idx2]
if n_addr == neigh_addr:
idx1 = info[2].index('= ')
- state = info[2][idx1+len('= '):]
+ state = info[2][idx1 + len('= '):]
if state.startswith('Idle'):
return BGP_FSM_IDLE
elif state.startswith('Active'):
@@ -228,7 +242,7 @@ class QuaggaBGPContainer(BGPContainer):
f.writelines(str(c))
def vtysh(self, cmd, config=True):
- if type(cmd) is not list:
+ if not isinstance(cmd, list):
cmd = [cmd]
cmd = ' '.join("-c '{0}'".format(c) for c in cmd)
if config:
@@ -237,8 +251,7 @@ class QuaggaBGPContainer(BGPContainer):
return self.local("vtysh -d bgpd {0}".format(cmd), capture=True)
def reload_config(self):
- daemon = []
- daemon.append('bgpd')
+ daemon = ['bgpd']
if self.zebra:
daemon.append('zebra')
for d in daemon: