summaryrefslogtreecommitdiffhomepage
path: root/test/scenario_test
diff options
context:
space:
mode:
Diffstat (limited to 'test/scenario_test')
-rw-r--r--test/scenario_test/ci-scripts/jenkins-build-script.sh45
-rw-r--r--test/scenario_test/flow_spec_test.py85
-rw-r--r--test/scenario_test/lib/base.py10
-rw-r--r--test/scenario_test/lib/exabgp.py71
-rw-r--r--test/scenario_test/lib/gobgp.py13
-rw-r--r--test/scenario_test/lib/quagga.py14
-rw-r--r--test/scenario_test/route_server_ipv4_v6_test.py2
7 files changed, 191 insertions, 49 deletions
diff --git a/test/scenario_test/ci-scripts/jenkins-build-script.sh b/test/scenario_test/ci-scripts/jenkins-build-script.sh
index 13ae6f9a..e4f8d3e2 100644
--- a/test/scenario_test/ci-scripts/jenkins-build-script.sh
+++ b/test/scenario_test/ci-scripts/jenkins-build-script.sh
@@ -28,45 +28,50 @@ set +e
sudo -E pip install -r pip-requires.txt
# route server test
-sudo -E python route_server_test.py --gobgp-image $GOBGP_IMAGE --go-path $GOROOT/bin -s --with-xunit
+sudo -E python route_server_test.py --gobgp-image $GOBGP_IMAGE --test-prefix rs -s --with-xunit --xunit-file=${WS}/nosetest.xml
RET1=$?
-mv nosetests.xml ${WS}/nosetest.xml
# route server ipv4 ipv6 test
-sudo -E python route_server_ipv4_v6_test.py --gobgp-image $GOBGP_IMAGE --go-path $GOROOT/bin -s --with-xunit
+sudo -E python route_server_ipv4_v6_test.py --gobgp-image $GOBGP_IMAGE --test-prefix v6 -s --with-xunit --xunit-file=${WS}/nosetest_ip.xml
RET2=$?
-mv nosetests.xml ${WS}/nosetest_ip.xml
# route server malformed message test
-sudo -E python route_server_malformed_test.py --gobgp-image $GOBGP_IMAGE --go-path $GOROOT/bin -s --with-xunit
+sudo -E python route_server_malformed_test.py --gobgp-image $GOBGP_IMAGE --go-path $GOROOT/bin -s --with-xunit --xunit-file=${WS}/nosetest_malformed.xml
RET3=$?
-mv nosetests.xml ${WS}/nosetest_malformed.xml
# route server policy test
-sudo -E python route_server_policy_test.py --gobgp-image $GOBGP_IMAGE --go-path $GOROOT/bin -s --with-xunit
+sudo -E python route_server_policy_test.py --gobgp-image $GOBGP_IMAGE --go-path $GOROOT/bin -s --with-xunit --xunit-file=${WS}/nosetest_policy.xml
RET4=$?
-mv nosetests.xml ${WS}/nosetest_policy.xml
+
+if [ $RET1 != 0 ] || [ $RET2 != 0 ] || [ $RET3 != 0 ] || [ $RET4 != 0 ]; then
+ exit 1
+fi
+
+PIDS=()
# bgp router test
sudo -E python bgp_router_test.py --gobgp-image $GOBGP_IMAGE --test-prefix bgp -s -x --with-xunit --xunit-file=${WS}/nosetest_bgp.xml &
-PID5=$!
+PIDS=("${PIDS[@]}" $!)
# ibgp router test
sudo -E python ibgp_router_test.py --gobgp-image $GOBGP_IMAGE --test-prefix ibgp -s -x --with-xunit --xunit-file=${WS}/nosetest_ibgp.xml &
-PID6=$!
+PIDS=("${PIDS[@]}" $!)
# evpn test
sudo -E python evpn_test.py --gobgp-image $GOBGP_IMAGE --test-prefix evpn -s -x --with-xunit --xunit-file=${WS}/nosetest_evpn.xml&
-PID7=$!
+PIDS=("${PIDS[@]}" $!)
-wait $PID5
-RET5=$?
-wait $PID6
-RET6=$?
-wait $PID7
-RET7=$?
+# flowspec test
+sudo -E python flow_spec_test.py --gobgp-image $GOBGP_IMAGE --test-prefix flow -s -x --with-xunit --xunit-file=${WS}/nosetest_flow.xml&
+PIDS=("${PIDS[@]}" $!)
-if [ $RET1 != 0 ] || [ $RET2 != 0 ] || [ $RET3 != 0 ] || [ $RET4 != 0 ] || [ $RET5 != 0 ] || [ $RET6 != 0 ] || [ $RET7 != 0 ]; then
- exit 1
-fi
+for (( i = 0; i < ${#PIDS[@]}; ++i ))
+do
+ wait ${PIDS[$i]}
+ if [ $? != 0 ]; then
+ exit 1
+ fi
+done
+
+echo 'all tests passed successfully'
exit 0
diff --git a/test/scenario_test/flow_spec_test.py b/test/scenario_test/flow_spec_test.py
new file mode 100644
index 00000000..e29f9c91
--- /dev/null
+++ b/test/scenario_test/flow_spec_test.py
@@ -0,0 +1,85 @@
+# Copyright (C) 2015 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import unittest
+from fabric.api import local
+from lib import base
+from lib.gobgp import *
+from lib.exabgp import *
+import sys
+import os
+import time
+import nose
+from noseplugin import OptionParser, parser_option
+from itertools import combinations
+
+
+class GoBGPTestBase(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ gobgp_ctn_image_name = parser_option.gobgp_image
+ base.TEST_PREFIX = parser_option.test_prefix
+
+ g1 = GoBGPContainer(name='g1', asn=65000, router_id='192.168.0.1',
+ ctn_image_name=gobgp_ctn_image_name,
+ log_level=parser_option.gobgp_log_level)
+ e1 = ExaBGPContainer(name='e1', asn=65000, router_id='192.168.0.2')
+
+ ctns = [g1, e1]
+
+ # advertise a route from q1, q2
+ matchs = ['destination 10.0.0.0/24', 'source 20.0.0.0/24']
+ thens = ['discard']
+ e1.add_route(route='flow1', rf='ipv4-flowspec', matchs=matchs, thens=thens)
+ matchs2 = ['tcp-flags syn', 'protocol tcp udp', "packet-length '>1000&<2000'"]
+ thens2 = ['rate-limit 9600', 'redirect 0.10:100', 'mark 20', 'action sample']
+ g1.add_route(route='flow1', rf='ipv4-flowspec', matchs=matchs2, thens=thens2)
+
+ initial_wait_time = max(ctn.run() for ctn in ctns)
+
+ time.sleep(initial_wait_time)
+
+ br01 = Bridge(name='br01', subnet='192.168.10.0/24', self_ip=True)
+ [br01.addif(ctn) for ctn in ctns]
+
+ # ibgp peer. loop topology
+ for a, b in combinations(ctns, 2):
+ a.add_peer(b, flowspec=True)
+ b.add_peer(a, flowspec=True)
+
+ cls.gobgp = g1
+ cls.exabgp = e1
+ cls.bridges = {'br01': br01}
+
+ # test each neighbor state is turned establish
+ def test_01_neighbor_established(self):
+ self.gobgp.wait_for(expected_state=BGP_FSM_ESTABLISHED, peer=self.exabgp)
+
+ def test_02_check_gobgp_global_rib(self):
+ self.assertTrue(len(self.gobgp.get_global_rib(rf='ipv4-flowspec')) == 2)
+
+
+if __name__ == '__main__':
+ if os.geteuid() is not 0:
+ print "you are not root."
+ sys.exit(1)
+ output = local("which docker 2>&1 > /dev/null ; echo $?", capture=True)
+ if int(output) is not 0:
+ print "docker not found"
+ sys.exit(1)
+
+ nose.main(argv=sys.argv, addplugins=[OptionParser()],
+ defaultTest=sys.argv[0])
diff --git a/test/scenario_test/lib/base.py b/test/scenario_test/lib/base.py
index a9bc1b09..f9bdae12 100644
--- a/test/scenario_test/lib/base.py
+++ b/test/scenario_test/lib/base.py
@@ -218,7 +218,8 @@ class BGPContainer(Container):
def add_peer(self, peer, passwd='', evpn=False, is_rs_client=False,
policies=None, passive=False,
- is_rr_client=False, cluster_id=''):
+ is_rr_client=False, cluster_id='',
+ flowspec=False):
neigh_addr = ''
local_addr = ''
for me, you in itertools.product(self.ip_addrs, peer.ip_addrs):
@@ -235,6 +236,7 @@ class BGPContainer(Container):
self.peers[peer] = {'neigh_addr': neigh_addr,
'passwd': passwd,
'evpn': evpn,
+ 'flowspec': flowspec,
'is_rs_client': is_rs_client,
'is_rr_client': is_rr_client,
'cluster_id': cluster_id,
@@ -257,10 +259,12 @@ class BGPContainer(Container):
def enable_peer(self, peer):
raise Exception('implement enable_peer() method')
- def add_route(self, route, rf='ipv4', attribute=''):
+ def add_route(self, route, rf='ipv4', attribute=None, matchs=None, thens=None):
self.routes[route] = {'prefix': route,
'rf': rf,
- 'attr': attribute}
+ 'attr': attribute,
+ 'matchs': matchs,
+ 'thens' : thens}
if self.is_running:
self.create_config()
self.reload_config()
diff --git a/test/scenario_test/lib/exabgp.py b/test/scenario_test/lib/exabgp.py
index 91919101..9d211342 100644
--- a/test/scenario_test/lib/exabgp.py
+++ b/test/scenario_test/lib/exabgp.py
@@ -29,10 +29,9 @@ class ExaBGPContainer(BGPContainer):
def _start_exabgp(self):
cmd = CmdBuffer(' ')
- cmd << 'docker exec -d {0}'.format(self.name)
cmd << 'env exabgp.log.destination={0}/exabgpd.log'.format(self.SHARED_VOLUME)
cmd << './exabgp/sbin/exabgp {0}/exabgpd.conf'.format(self.SHARED_VOLUME)
- local(str(cmd), capture=True)
+ self.local(str(cmd), flag='-d')
def _update_exabgp(self):
c = CmdBuffer()
@@ -51,9 +50,8 @@ class ExaBGPContainer(BGPContainer):
local(cmd, capture=True)
cmd = 'chmod 755 {0}/update.sh'.format(self.config_dir)
local(cmd, capture=True)
- cmd = 'docker exec {0} {1}/update.sh'.format(self.name,
- self.SHARED_VOLUME)
- local(cmd, capture=True)
+ cmd = '{0}/update.sh'.format(self.SHARED_VOLUME)
+ self.local(cmd)
def run(self):
super(ExaBGPContainer, self).run()
@@ -78,13 +76,48 @@ class ExaBGPContainer(BGPContainer):
cmd << ' local-as {0};'.format(self.asn)
cmd << ' peer-as {0};'.format(peer.asn)
- cmd << ' static {'
- for route, attr in self.routes.iteritems():
- if attr == '':
- cmd << ' route {0} next-hop {1};'.format(route, local_addr)
- else:
- cmd << ' route {0} next-hop {1} attribute {2};'.format(route, local_addr, attr)
- cmd << ' }'
+ routes = [r for r in self.routes.values() if r['rf'] == 'ipv4']
+
+ if len(routes) > 0:
+ cmd << ' static {'
+ for route in routes:
+ if route['attr']:
+ cmd << ' route {0} next-hop {1};'.format(route['prefix'], local_addr)
+ else:
+ cmd << ' route {0} next-hop {1} attribute {2};'.format(route['prefix'], local_addr, attr)
+ cmd << ' }'
+
+ routes = [r for r in self.routes.values() if r['rf'] == 'ipv4-flowspec']
+
+ if len(routes) > 0:
+ cmd << ' flow {'
+ for route in routes:
+ cmd << ' route {0}{{'.format(route['prefix'])
+ cmd << ' match {'
+ for match in route['matchs']:
+ cmd << ' {0};'.format(match)
+# cmd << ' source {0};'.format(route['prefix'])
+# cmd << ' destination 192.168.0.1/32;'
+# cmd << ' destination-port =3128 >8080&<8088;'
+# cmd << ' source-port >1024;'
+# cmd << ' port =14 =15 >10&<156;'
+# cmd << ' protocol udp;' # how to specify multiple ip protocols
+# cmd << ' packet-length >1000&<2000;'
+# cmd << ' tcp-flags !syn;'
+ cmd << ' }'
+ cmd << ' then {'
+ for then in route['thens']:
+ cmd << ' {0};'.format(then)
+# cmd << ' accept;'
+# cmd << ' discard;'
+# cmd << ' rate-limit 9600;'
+# cmd << ' redirect 1.2.3.4:100;'
+# cmd << ' redirect 100:100;'
+# cmd << ' mark 10;'
+# cmd << ' action sample-terminal;'
+ cmd << ' }'
+ cmd << ' }'
+ cmd << ' }'
cmd << '}'
with open('{0}/exabgpd.conf'.format(self.config_dir), 'w') as f:
@@ -92,8 +125,12 @@ class ExaBGPContainer(BGPContainer):
f.write(str(cmd))
def reload_config(self):
- cmd = 'docker exec {0} /usr/bin/pkill exabgp -SIGALRM'.format(self.name)
- try:
- local(cmd, capture=True)
- except:
- self._start_exabgp()
+ ps = self.local('ps', capture=True)
+ running = False
+ for line in ps.split('\n')[1:]:
+ if 'python' in line:
+ running = True
+ if running:
+ self.local('/usr/bin/pkill python -SIGUSR1')
+ else:
+ self._start_exabgp()
diff --git a/test/scenario_test/lib/gobgp.py b/test/scenario_test/lib/gobgp.py
index e1da72c8..63f65928 100644
--- a/test/scenario_test/lib/gobgp.py
+++ b/test/scenario_test/lib/gobgp.py
@@ -148,6 +148,9 @@ class GoBGPContainer(BGPContainer):
afi_safi_list.append({'AfiSafiName': 'encap'})
afi_safi_list.append({'AfiSafiName': 'rtc'})
+ if info['flowspec']:
+ afi_safi_list.append({'AfiSafiName': 'ipv4-flowspec'})
+
n = {'NeighborConfig':
{'NeighborAddress': info['neigh_addr'].split('/')[0],
'PeerAs': peer.asn,
@@ -182,6 +185,12 @@ class GoBGPContainer(BGPContainer):
cmd = '/usr/bin/pkill gobgpd -SIGHUP'
self.local(cmd)
for v in self.routes.itervalues():
- cmd = 'gobgp global '\
- 'rib add {0} -a {1}'.format(v['prefix'], v['rf'])
+ if v['rf'] == 'ipv4' or v['rf'] == 'ipv6':
+ cmd = 'gobgp global '\
+ 'rib add {0} -a {1}'.format(v['prefix'], v['rf'])
+ elif v['rf']== 'ipv4-flowspec':
+ 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))
self.local(cmd)
diff --git a/test/scenario_test/lib/quagga.py b/test/scenario_test/lib/quagga.py
index 1099866a..e4de3ef1 100644
--- a/test/scenario_test/lib/quagga.py
+++ b/test/scenario_test/lib/quagga.py
@@ -161,14 +161,16 @@ class QuaggaBGPContainer(BGPContainer):
c << 'neighbor {0} activate'.format(n_addr)
c << 'exit-address-family'
- for route in self.routes.iterkeys():
- version = netaddr.IPNetwork(route).version
- if version == 4:
- c << 'network {0}'.format(route)
- elif version == 6:
+ for route in self.routes.itervalues():
+ if route['rf'] == 'ipv4':
+ c << 'network {0}'.format(route['prefix'])
+ elif route['rf'] == 'ipv6':
c << 'address-family ipv6 unicast'
- c << 'network {0}'.format(route)
+ c << 'network {0}'.format(route['prefix'])
c << 'exit-address-family'
+ else:
+ raise Exception('unsupported route faily: {0}'.format(route['rf']))
+
for name, policy in self.policies.iteritems():
c << 'access-list {0} {1} {2}'.format(name, policy['type'],
diff --git a/test/scenario_test/route_server_ipv4_v6_test.py b/test/scenario_test/route_server_ipv4_v6_test.py
index 03033260..d05874f5 100644
--- a/test/scenario_test/route_server_ipv4_v6_test.py
+++ b/test/scenario_test/route_server_ipv4_v6_test.py
@@ -53,7 +53,7 @@ class GoBGPIPv6Test(unittest.TestCase):
for idx, q in enumerate(v6):
route = '2001:{0}::/96'.format(idx+1)
- q.add_route(route)
+ q.add_route(route, rf='ipv6')
initial_wait_time = max(ctn.run() for ctn in ctns)