test: add mininet-test suite
This patch adds a test framework using mininet. The following tests can be performed. - Set the flow for the OVS-switch from Ryu-app, we test the actual packet is to be handled properly in accordance with the flow; The packet that generated by "mz" or replayed by "tcpreplay" is routed through the ovs-switch, are processed according to the flow, then compare test conditions and the results captured by "tshark". - Create a packet with ryu using the packet-lib, we test the packet and response are correct; to compare test conditions and the results captured by "tshark". $ ./run_mnet-test.sh [OPTION] [TEST DIR or FILE]... $ ./run_mnet-test.sh l2 l3/icmp packet_lib/arp/ARP_gratuitous.mn $ ./run_mnet-test.sh --help Requirements package: - mininet: git://github.com/mininet/mininet.git - openvswitch: git://openvswitch.org/openvswitch - Mausezahn 0.40: http://www.perihel.at/sec/mz/ - TShark 1.6.2: http://www.wireshark.org/ - tcpreplay 3.4: http://tcpreplay.synfin.net/ Signed-off-by: HIYAMA Manabu <hiyama.manabu@po.ntts.co.jp> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
7d5b4960a8
commit
24d894bc95
6
ryu/tests/mininet/l2/mpls/PopMPLS_mpls.mn
Normal file
6
ryu/tests/mininet/l2/mpls/PopMPLS_mpls.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=MPLS-PopMPLS
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_mpls
|
||||
PCAP_MZ="-t tcp -M 80 -P $TEST_NAME -c 3 -r"
|
||||
PCAP_FILTER="! mpls && ip.proto==TCP"
|
6
ryu/tests/mininet/l2/mpls/PushMPLS_ip.mn
Normal file
6
ryu/tests/mininet/l2/mpls/PushMPLS_ip.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=IP-PushMPLS
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_mpls
|
||||
PCAP_MZ="-t tcp -P $TEST_NAME -c 3 -b 00:00:00:00:00:02"
|
||||
PCAP_FILTER="mpls && ip.proto==TCP"
|
6
ryu/tests/mininet/l2/mpls/PushMPLS_mpls.mn
Normal file
6
ryu/tests/mininet/l2/mpls/PushMPLS_mpls.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=MPLS-PushMPLS
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_mpls
|
||||
PCAP_MZ="-t tcp -M 100 -P $TEST_NAME -c 3 -r"
|
||||
PCAP_FILTER="mpls.label==100 && mpls.label==200 && ip.proto==TCP"
|
128
ryu/tests/mininet/l2/mpls/test_mpls.py
Normal file
128
ryu/tests/mininet/l2/mpls/test_mpls.py
Normal file
@ -0,0 +1,128 @@
|
||||
# Copyright (C) 2012 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 logging
|
||||
import struct
|
||||
|
||||
from ryu.base import app_manager
|
||||
from ryu.controller import ofp_event
|
||||
from ryu.controller import dpset
|
||||
from ryu.controller.handler import MAIN_DISPATCHER
|
||||
from ryu.controller.handler import set_ev_cls
|
||||
from ryu.ofproto import ofproto_v1_2
|
||||
from ryu.ofproto import ether
|
||||
from ryu.lib.mac import haddr_to_str
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RunTestMininet(app_manager.RyuApp):
|
||||
|
||||
_CONTEXTS = {'dpset': dpset.DPSet}
|
||||
OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RunTestMininet, self).__init__(*args, **kwargs)
|
||||
self.mac_to_port = {}
|
||||
|
||||
def _add_flow(self, dp, match, actions):
|
||||
inst = [dp.ofproto_parser.OFPInstructionActions(
|
||||
dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
||||
|
||||
mod = dp.ofproto_parser.OFPFlowMod(
|
||||
dp, cookie=0, cookie_mask=0, table_id=0,
|
||||
command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
|
||||
priority=0xff, buffer_id=0xffffffff,
|
||||
out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY,
|
||||
flags=0, match=match, instructions=inst)
|
||||
|
||||
dp.send_msg(mod)
|
||||
|
||||
def _define_flow(self, dp):
|
||||
in_port = 1
|
||||
out_port = 2
|
||||
|
||||
eth_IP = ether.ETH_TYPE_IP
|
||||
eth_MPLS = ether.ETH_TYPE_MPLS
|
||||
|
||||
# MPLS(80) -> PopMPLS
|
||||
LOG.debug("--- add_flow PopMPLS")
|
||||
m_label = 80
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_MPLS)
|
||||
match.set_mpls_label(m_label)
|
||||
actions = [dp.ofproto_parser.OFPActionPopMpls(eth_IP),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
# IP -> PushMPLS(90)
|
||||
LOG.debug("--- add_flow PushMPLS")
|
||||
s_label = 90
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_IP)
|
||||
f = dp.ofproto_parser.OFPMatchField.make(
|
||||
dp.ofproto.OXM_OF_MPLS_LABEL, s_label)
|
||||
actions = [dp.ofproto_parser.OFPActionPushMpls(eth_MPLS),
|
||||
dp.ofproto_parser.OFPActionSetField(f),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
# MPLS(100) -> PushMPLS(200)
|
||||
LOG.debug("--- add_flow PushMPLS")
|
||||
m_label = 100
|
||||
s_label = 200
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_MPLS)
|
||||
match.set_mpls_label(m_label)
|
||||
f = dp.ofproto_parser.OFPMatchField.make(
|
||||
dp.ofproto.OXM_OF_MPLS_LABEL, s_label)
|
||||
actions = [dp.ofproto_parser.OFPActionPushMpls(eth_MPLS),
|
||||
dp.ofproto_parser.OFPActionSetField(f),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
# MPLS(1000):MPLS -> PopMPLS
|
||||
# LOG.debug("--- add_flow PopMPLS")
|
||||
# SKIP: ovs not supported
|
||||
m_label = 1000
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_MPLS)
|
||||
match.set_mpls_label(m_label)
|
||||
actions = [dp.ofproto_parser.OFPActionPopMpls(eth_MPLS),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
# self._add_flow(dp, match, actions)
|
||||
|
||||
@set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
|
||||
def handler_datapath(self, ev):
|
||||
if ev.enter:
|
||||
self._define_flow(ev.dp)
|
||||
|
||||
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
|
||||
def packet_in_handler(self, ev):
|
||||
msg = ev.msg
|
||||
dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
|
||||
in_port = msg.match.fields[0].value
|
||||
|
||||
LOG.info("----------------------------------------")
|
||||
LOG.info("* PacketIn")
|
||||
LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
|
||||
LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
|
||||
LOG.info("packet in datapath_id=%s src=%s dst=%s",
|
||||
msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))
|
6
ryu/tests/mininet/l2/vlan/PopVLAN_vlan.mn
Normal file
6
ryu/tests/mininet/l2/vlan/PopVLAN_vlan.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=VLAN-PopVLAN
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_vlan
|
||||
PCAP_MZ="-t tcp -Q 8 -P $TEST_NAME -c 3 -r"
|
||||
PCAP_FILTER="! vlan && ip.proto==TCP"
|
6
ryu/tests/mininet/l2/vlan/PopVLAN_vlanvlan.mn
Normal file
6
ryu/tests/mininet/l2/vlan/PopVLAN_vlanvlan.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=VLAN:VLAN-PopVLAN
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_vlan
|
||||
PCAP_MZ="-t tcp -Q 100,99 -P $TEST_NAME -c 3 -r"
|
||||
PCAP_FILTER="vlan.id!=100 && vlan.id==99 && ip.proto==TCP"
|
6
ryu/tests/mininet/l2/vlan/PushVLAN_icmp.mn
Normal file
6
ryu/tests/mininet/l2/vlan/PushVLAN_icmp.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=ICMP-PushVLAN
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_vlan
|
||||
PCAP_MZ="-t icmp ping -P $TEST_NAME -c 3 -r -b 00:00:00:00:00:02"
|
||||
PCAP_FILTER="vlan && icmp.type==8"
|
131
ryu/tests/mininet/l2/vlan/test_vlan.py
Normal file
131
ryu/tests/mininet/l2/vlan/test_vlan.py
Normal file
@ -0,0 +1,131 @@
|
||||
# Copyright (C) 2012 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 logging
|
||||
import struct
|
||||
|
||||
from ryu.base import app_manager
|
||||
from ryu.controller import ofp_event
|
||||
from ryu.controller import dpset
|
||||
from ryu.controller.handler import MAIN_DISPATCHER
|
||||
from ryu.controller.handler import set_ev_cls
|
||||
from ryu.ofproto import ofproto_v1_2
|
||||
from ryu.ofproto import ether
|
||||
from ryu.ofproto import inet
|
||||
from ryu.lib.mac import haddr_to_str
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RunTestMininet(app_manager.RyuApp):
|
||||
|
||||
_CONTEXTS = {'dpset': dpset.DPSet}
|
||||
OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RunTestMininet, self).__init__(*args, **kwargs)
|
||||
self.mac_to_port = {}
|
||||
|
||||
def _add_flow(self, dp, match, actions):
|
||||
inst = [dp.ofproto_parser.OFPInstructionActions(
|
||||
dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
||||
|
||||
mod = dp.ofproto_parser.OFPFlowMod(
|
||||
dp, cookie=0, cookie_mask=0, table_id=0,
|
||||
command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
|
||||
priority=0xff, buffer_id=0xffffffff,
|
||||
out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY,
|
||||
flags=0, match=match, instructions=inst)
|
||||
|
||||
dp.send_msg(mod)
|
||||
|
||||
def _define_flow(self, dp):
|
||||
in_port = 1
|
||||
out_port = 2
|
||||
|
||||
eth_IP = ether.ETH_TYPE_IP
|
||||
eth_VLAN = ether.ETH_TYPE_8021Q
|
||||
ip_ICMP = inet.IPPROTO_ICMP
|
||||
|
||||
# VLAN(8) -> PopVLAN
|
||||
LOG.debug("--- add_flow VLAN(8) to PopVLAN")
|
||||
m_vid = 8
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_IP)
|
||||
match.set_vlan_vid(m_vid)
|
||||
actions = [dp.ofproto_parser.OFPActionPopVlan(),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
# ICMP -> PushVLAN(9)
|
||||
LOG.debug("--- add_flow ICMP to PushVLAN(9)")
|
||||
s_vid = 9
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_IP)
|
||||
match.set_ip_proto(ip_ICMP)
|
||||
f = dp.ofproto_parser.OFPMatchField.make(
|
||||
dp.ofproto.OXM_OF_VLAN_VID, s_vid)
|
||||
actions = [dp.ofproto_parser.OFPActionPushVlan(eth_VLAN),
|
||||
dp.ofproto_parser.OFPActionSetField(f),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
# VLAN(10) -> PushVLAN(20)
|
||||
# LOG.debug("--- add_flow VLAN(10) to PushVLAN(100)")
|
||||
# SKIP: ovs not supported
|
||||
m_vid = 10
|
||||
s_vid = 20
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_IP)
|
||||
match.set_vlan_vid(m_vid)
|
||||
f = dp.ofproto_parser.OFPMatchField.make(
|
||||
dp.ofproto.OXM_OF_VLAN_VID, s_vid)
|
||||
actions = [dp.ofproto_parser.OFPActionPushVlan(eth_VLAN),
|
||||
dp.ofproto_parser.OFPActionSetField(f),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
# self._add_flow(dp, match, actions)
|
||||
|
||||
# VLAN(100):VLAN -> PopVLAN
|
||||
LOG.debug("--- add_flow VLAN(100):VLAN to PopVLAN")
|
||||
m_vid = 100
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_VLAN)
|
||||
match.set_vlan_vid(m_vid)
|
||||
actions = [dp.ofproto_parser.OFPActionPopVlan(),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
@set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
|
||||
def handler_datapath(self, ev):
|
||||
if ev.enter:
|
||||
self._define_flow(ev.dp)
|
||||
|
||||
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
|
||||
def packet_in_handler(self, ev):
|
||||
msg = ev.msg
|
||||
dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
|
||||
in_port = msg.match.fields[0].value
|
||||
|
||||
LOG.info("----------------------------------------")
|
||||
LOG.info("* PacketIn")
|
||||
LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
|
||||
LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
|
||||
LOG.info("packet in datapath_id=%s src=%s dst=%s",
|
||||
msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))
|
6
ryu/tests/mininet/l3/icmp/ICMP_ping.mn
Normal file
6
ryu/tests/mininet/l3/icmp/ICMP_ping.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=ICMP-Req
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_icmp
|
||||
PCAP_MZ="-t icmp ping -c 3 -r -b 00:00:00:00:00:00"
|
||||
PCAP_FILTER="icmp.type==8"
|
6
ryu/tests/mininet/l3/icmp/ICMP_reply.mn
Normal file
6
ryu/tests/mininet/l3/icmp/ICMP_reply.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=ICMP-Reply
|
||||
DUMP_HOST=h1
|
||||
DUMP_IF=h1-eth0
|
||||
RYU_APP=test_icmp
|
||||
PCAP_MZ="-t icmp ping -c 3 -r -B h2"
|
||||
PCAP_FILTER="icmp.type==0"
|
85
ryu/tests/mininet/l3/icmp/test_icmp.py
Normal file
85
ryu/tests/mininet/l3/icmp/test_icmp.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Copyright (C) 2012 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 logging
|
||||
import struct
|
||||
|
||||
from ryu.base import app_manager
|
||||
from ryu.controller import ofp_event
|
||||
from ryu.controller import dpset
|
||||
from ryu.controller.handler import MAIN_DISPATCHER
|
||||
from ryu.controller.handler import set_ev_cls
|
||||
from ryu.ofproto import ofproto_v1_2
|
||||
from ryu.lib.mac import haddr_to_str
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RunTestMininet(app_manager.RyuApp):
|
||||
|
||||
_CONTEXTS = {'dpset': dpset.DPSet}
|
||||
OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RunTestMininet, self).__init__(*args, **kwargs)
|
||||
self.mac_to_port = {}
|
||||
|
||||
def _add_flow(self, dp, match, actions):
|
||||
inst = [dp.ofproto_parser.OFPInstructionActions(
|
||||
dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
||||
|
||||
mod = dp.ofproto_parser.OFPFlowMod(
|
||||
dp, cookie=0, cookie_mask=0, table_id=0,
|
||||
command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
|
||||
priority=0xff, buffer_id=0xffffffff,
|
||||
out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY,
|
||||
flags=0, match=match, instructions=inst)
|
||||
|
||||
dp.send_msg(mod)
|
||||
|
||||
def _define_flow(self, dp):
|
||||
in_port = 1
|
||||
out_port = 2
|
||||
|
||||
# port:1 -> port:2
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
actions = [dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
# port:1 -> port:2
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(out_port)
|
||||
actions = [dp.ofproto_parser.OFPActionOutput(in_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
@set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
|
||||
def handler_datapath(self, ev):
|
||||
if ev.enter:
|
||||
self._define_flow(ev.dp)
|
||||
|
||||
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
|
||||
def packet_in_handler(self, ev):
|
||||
msg = ev.msg
|
||||
dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
|
||||
in_port = msg.match.fields[0].value
|
||||
|
||||
LOG.info("----------------------------------------")
|
||||
LOG.info("* PacketIn")
|
||||
LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
|
||||
LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
|
||||
LOG.info("packet in datapath_id=%s src=%s dst=%s",
|
||||
msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))
|
6
ryu/tests/mininet/l3/ip_ttl/DecNwTtl.mn
Normal file
6
ryu/tests/mininet/l3/ip_ttl/DecNwTtl.mn
Normal file
@ -0,0 +1,6 @@
|
||||
TEST_NAME=DecNwTtl
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
RYU_APP=test_ip_ttl
|
||||
PCAP_MZ="-t icmp ttl=64 -P $TEST_NAME -c 3 -b 00:00:00:00:00:02"
|
||||
PCAP_FILTER="icmp && ip.ttl==63"
|
85
ryu/tests/mininet/l3/ip_ttl/test_ip_ttl.py
Normal file
85
ryu/tests/mininet/l3/ip_ttl/test_ip_ttl.py
Normal file
@ -0,0 +1,85 @@
|
||||
# Copyright (C) 2012 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 logging
|
||||
import struct
|
||||
|
||||
from ryu.base import app_manager
|
||||
from ryu.controller import ofp_event
|
||||
from ryu.controller import dpset
|
||||
from ryu.controller.handler import MAIN_DISPATCHER
|
||||
from ryu.controller.handler import set_ev_cls
|
||||
from ryu.ofproto import ofproto_v1_2
|
||||
from ryu.ofproto import ether
|
||||
from ryu.lib.mac import haddr_to_str
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RunTestMininet(app_manager.RyuApp):
|
||||
|
||||
_CONTEXTS = {'dpset': dpset.DPSet}
|
||||
OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RunTestMininet, self).__init__(*args, **kwargs)
|
||||
self.mac_to_port = {}
|
||||
|
||||
def _add_flow(self, dp, match, actions):
|
||||
inst = [dp.ofproto_parser.OFPInstructionActions(
|
||||
dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
||||
|
||||
mod = dp.ofproto_parser.OFPFlowMod(
|
||||
dp, cookie=0, cookie_mask=0, table_id=0,
|
||||
command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
|
||||
priority=0xff, buffer_id=0xffffffff,
|
||||
out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY,
|
||||
flags=0, match=match, instructions=inst)
|
||||
|
||||
dp.send_msg(mod)
|
||||
|
||||
def _define_flow(self, dp):
|
||||
in_port = 1
|
||||
out_port = 2
|
||||
|
||||
eth_IP = ether.ETH_TYPE_IP
|
||||
|
||||
# ICMP -> DecNwTtl
|
||||
LOG.debug("--- add_flow DecNwTtl")
|
||||
match = dp.ofproto_parser.OFPMatch()
|
||||
match.set_in_port(in_port)
|
||||
match.set_dl_type(eth_IP)
|
||||
actions = [dp.ofproto_parser.OFPActionDecNwTtl(),
|
||||
dp.ofproto_parser.OFPActionOutput(out_port, 0)]
|
||||
self._add_flow(dp, match, actions)
|
||||
|
||||
@set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
|
||||
def handler_datapath(self, ev):
|
||||
if ev.enter:
|
||||
self._define_flow(ev.dp)
|
||||
|
||||
@set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)
|
||||
def packet_in_handler(self, ev):
|
||||
msg = ev.msg
|
||||
dst, src, eth_type = struct.unpack_from('!6s6sH', buffer(msg.data), 0)
|
||||
in_port = msg.match.fields[0].value
|
||||
|
||||
LOG.info("----------------------------------------")
|
||||
LOG.info("* PacketIn")
|
||||
LOG.info("in_port=%d, eth_type: %s", in_port, hex(eth_type))
|
||||
LOG.info("packet reason=%d buffer_id=%d", msg.reason, msg.buffer_id)
|
||||
LOG.info("packet in datapath_id=%s src=%s dst=%s",
|
||||
msg.datapath.id, haddr_to_str(src), haddr_to_str(dst))
|
7
ryu/tests/mininet/packet_lib/arp/ARP_gratuitous.mn
Normal file
7
ryu/tests/mininet/packet_lib/arp/ARP_gratuitous.mn
Normal file
@ -0,0 +1,7 @@
|
||||
# test-GratuitousARP-request
|
||||
TEST_NAME=GARP-Request
|
||||
DUMP_HOST=h1
|
||||
DUMP_IF=h1-eth0
|
||||
RYU_APP=test_arp
|
||||
PCAP_MZ="-S"
|
||||
PCAP_FILTER="arp.isgratuitous && arp.src.proto_ipv4==10.0.0.100 && arp.src.hw_mac==fe:ee:ee:ee:ee:ef"
|
7
ryu/tests/mininet/packet_lib/arp/ARP_reply.mn
Normal file
7
ryu/tests/mininet/packet_lib/arp/ARP_reply.mn
Normal file
@ -0,0 +1,7 @@
|
||||
# test-ARP-reply
|
||||
TEST_NAME=ARP-Reply
|
||||
DUMP_HOST=h1
|
||||
DUMP_IF=h1-eth0
|
||||
RYU_APP=test_arp
|
||||
PCAP_MZ="-t arp request,targetip=10.0.0.100 -c 3 -r"
|
||||
PCAP_FILTER="arp.opcode==reply && arp.src.proto_ipv4==10.0.0.100 && arp.src.hw_mac==fe:ee:ee:ee:ee:ef"
|
7
ryu/tests/mininet/packet_lib/arp/ARP_request.mn
Normal file
7
ryu/tests/mininet/packet_lib/arp/ARP_request.mn
Normal file
@ -0,0 +1,7 @@
|
||||
# test-ARP-request
|
||||
TEST_NAME=ARP-Request
|
||||
DUMP_HOST=h1
|
||||
DUMP_IF=h1-eth0
|
||||
RYU_APP=test_arp
|
||||
PCAP_MZ="-t arp request,targetip=10.0.0.1"
|
||||
PCAP_FILTER="arp.opcode==request && arp.src.proto_ipv4==10.0.0.100 && arp.dst.proto_ipv4==10.0.0.1 && arp.src.hw_mac==fe:ee:ee:ee:ee:ef"
|
199
ryu/tests/mininet/packet_lib/arp/test_arp.py
Normal file
199
ryu/tests/mininet/packet_lib/arp/test_arp.py
Normal file
@ -0,0 +1,199 @@
|
||||
# Copyright (C) 2012 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.
|
||||
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
import logging
|
||||
import array
|
||||
import netaddr
|
||||
|
||||
from ryu.base import app_manager
|
||||
from ryu.controller import dpset
|
||||
from ryu.controller import ofp_event
|
||||
from ryu.controller import handler
|
||||
from ryu.ofproto import ofproto_v1_2
|
||||
from ryu.ofproto import ether
|
||||
from ryu.ofproto import inet
|
||||
from ryu.lib import mac
|
||||
from ryu.lib.packet import packet
|
||||
from ryu.lib.packet import ethernet
|
||||
from ryu.lib.packet import arp
|
||||
from ryu.lib.packet import ipv4
|
||||
from ryu.lib.packet import icmp
|
||||
|
||||
|
||||
LOG = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RunTestMininet(app_manager.RyuApp):
|
||||
|
||||
_CONTEXTS = {'dpset': dpset.DPSet}
|
||||
OFP_VERSIONS = [ofproto_v1_2.OFP_VERSION]
|
||||
|
||||
ZERO_MAC = mac.haddr_to_bin('00:00:00:00:00:00')
|
||||
BROADCAST_MAC = mac.haddr_to_bin('ff:ff:ff:ff:ff:ff')
|
||||
RYU_MAC = mac.haddr_to_bin('fe:ee:ee:ee:ee:ef')
|
||||
HOST_MAC = mac.haddr_to_bin('00:00:00:00:00:01')
|
||||
RYU_IP = int(netaddr.IPAddress('10.0.0.100'))
|
||||
HOST_IP = int(netaddr.IPAddress('10.0.0.1'))
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(RunTestMininet, self).__init__(*args, **kwargs)
|
||||
|
||||
def _send_msg(self, dp, data):
|
||||
buffer_id = 0xffffffff
|
||||
in_port = dp.ofproto.OFPP_LOCAL
|
||||
actions = [dp.ofproto_parser.OFPActionOutput(1, 0)]
|
||||
msg = dp.ofproto_parser.OFPPacketOut(
|
||||
dp, buffer_id, in_port, actions, data)
|
||||
dp.send_msg(msg)
|
||||
|
||||
def _add_flow(self, dp, match, actions):
|
||||
inst = [dp.ofproto_parser.OFPInstructionActions(
|
||||
dp.ofproto.OFPIT_APPLY_ACTIONS, actions)]
|
||||
mod = dp.ofproto_parser.OFPFlowMod(
|
||||
dp, cookie=0, cookie_mask=0, table_id=0,
|
||||
command=dp.ofproto.OFPFC_ADD, idle_timeout=0, hard_timeout=0,
|
||||
priority=0xff, buffer_id=0xffffffff,
|
||||
out_port=dp.ofproto.OFPP_ANY, out_group=dp.ofproto.OFPG_ANY,
|
||||
flags=0, match=match, instructions=inst)
|
||||
dp.send_msg(mod)
|
||||
|
||||
def _find_protocol(self, pkt, name):
|
||||
for p in pkt.protocols:
|
||||
if hasattr(p, 'protocol_name'):
|
||||
if p.protocol_name == name:
|
||||
return p
|
||||
|
||||
def _get_protocols(self, pkt):
|
||||
protocols = {}
|
||||
for p in pkt:
|
||||
if hasattr(p, 'protocol_name'):
|
||||
protocols[p.protocol_name] = p
|
||||
else:
|
||||
protocols['payload'] = p
|
||||
return protocols
|
||||
|
||||
def _build_ether(self, ethertype, dst_mac=HOST_MAC):
|
||||
e = ethernet.ethernet(dst_mac, self.RYU_MAC, ethertype)
|
||||
return e
|
||||
|
||||
def _build_arp(self, opcode, dst_ip=HOST_IP):
|
||||
if opcode == arp.ARP_REQUEST:
|
||||
_eth_dst_mac = self.BROADCAST_MAC
|
||||
_arp_dst_mac = self.ZERO_MAC
|
||||
elif opcode == arp.ARP_REPLY:
|
||||
_eth_dst_mac = self.HOST_MAC
|
||||
_arp_dst_mac = self.HOST_MAC
|
||||
|
||||
e = self._build_ether(ether.ETH_TYPE_ARP, _eth_dst_mac)
|
||||
a = arp.arp(hwtype=1, proto=ether.ETH_TYPE_IP, hlen=6, plen=4,
|
||||
opcode=opcode, src_mac=self.RYU_MAC, src_ip=self.RYU_IP,
|
||||
dst_mac=_arp_dst_mac, dst_ip=dst_ip)
|
||||
p = packet.Packet()
|
||||
p.add_protocol(e)
|
||||
p.add_protocol(a)
|
||||
p.serialize()
|
||||
|
||||
return p
|
||||
|
||||
def _build_echo(self, _type, echo):
|
||||
e = self._build_ether(ether.ETH_TYPE_IP)
|
||||
ip = ipv4.ipv4(version=4, header_length=5, tos=0, total_length=84,
|
||||
identification=0, flags=0, offset=0, ttl=64,
|
||||
proto=inet.IPPROTO_ICMP, csum=0,
|
||||
src=self.RYU_IP, dst=self.HOST_IP)
|
||||
ping = icmp.icmp(_type, code=0, csum=0, data=echo)
|
||||
|
||||
p = packet.Packet()
|
||||
p.add_protocol(e)
|
||||
p.add_protocol(ip)
|
||||
p.add_protocol(ping)
|
||||
p.serialize()
|
||||
return p
|
||||
|
||||
def _garp(self):
|
||||
p = self._build_arp(arp.ARP_REQUEST, self.RYU_IP)
|
||||
return p.data
|
||||
|
||||
def _arp_request(self):
|
||||
p = self._build_arp(arp.ARP_REQUEST, self.HOST_IP)
|
||||
return p.data
|
||||
|
||||
def _arp_reply(self):
|
||||
p = self._build_arp(arp.ARP_REPLY, self.HOST_IP)
|
||||
return p.data
|
||||
|
||||
def _echo_request(self, echo):
|
||||
p = self._build_echo(icmp.ICMP_ECHO_REQUEST, echo)
|
||||
return p.data
|
||||
|
||||
def _echo_reply(self, echo):
|
||||
p = self._build_echo(icmp.ICMP_ECHO_REPLY, echo)
|
||||
return p.data
|
||||
|
||||
@handler.set_ev_cls(ofp_event.EventOFPPacketIn, handler.MAIN_DISPATCHER)
|
||||
def packet_in_handler(self, ev):
|
||||
msg = ev.msg
|
||||
dp = msg.datapath
|
||||
|
||||
pkt = packet.Packet(array.array('B', msg.data))
|
||||
p_arp = self._find_protocol(pkt, "arp")
|
||||
p_icmp = self._find_protocol(pkt, "icmp")
|
||||
p_ipv4 = self._find_protocol(pkt, "ipv4")
|
||||
|
||||
if p_arp:
|
||||
src_ip = str(netaddr.IPAddress(p_arp.src_ip))
|
||||
dst_ip = str(netaddr.IPAddress(p_arp.dst_ip))
|
||||
if p_arp.opcode == arp.ARP_REQUEST:
|
||||
LOG.debug("--- PacketIn: ARP_Request: %s->%s", src_ip, dst_ip)
|
||||
if p_arp.dst_ip == self.RYU_IP:
|
||||
LOG.debug("--- send Pkt: ARP_Reply")
|
||||
data = self._arp_reply()
|
||||
self._send_msg(dp, data)
|
||||
elif p_arp.dst_ip == self.HOST_IP:
|
||||
LOG.debug(" PacketIn: GARP")
|
||||
LOG.debug("--- send Pkt: ARP_Request")
|
||||
data = self._arp_request()
|
||||
self._send_msg(dp, data)
|
||||
elif p_arp.opcode == arp.ARP_REPLY:
|
||||
LOG.debug("--- PacketIn: ARP_Reply: %s->%s", src_ip, dst_ip)
|
||||
LOG.debug("--- send Pkt: Echo_Request")
|
||||
echo = icmp.echo(id_=66, seq=1)
|
||||
data = self._echo_request(echo)
|
||||
self._send_msg(dp, data)
|
||||
|
||||
if p_icmp:
|
||||
src = str(netaddr.IPAddress(p_ipv4.src))
|
||||
dst = str(netaddr.IPAddress(p_ipv4.dst))
|
||||
if p_icmp.type == icmp.ICMP_ECHO_REQUEST:
|
||||
LOG.debug("--- PacketIn: Echo_Request: %s->%s", src, dst)
|
||||
if p_ipv4.dst == self.RYU_IP:
|
||||
LOG.debug("--- send Pkt: Echo_Reply")
|
||||
echo = p_icmp.data
|
||||
echo.data = bytearray(echo.data)
|
||||
data = self._echo_reply(echo)
|
||||
self._send_msg(dp, data)
|
||||
elif p_icmp.type == icmp.ICMP_ECHO_REPLY:
|
||||
LOG.debug("--- PacketIn: Echo_Reply: %s->%s", src, dst)
|
||||
|
||||
@handler.set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
|
||||
def handler_datapath(self, ev):
|
||||
if ev.enter:
|
||||
dp = ev.dp
|
||||
|
||||
LOG.debug("--- send Pkt: Gratuitous ARP_Request")
|
||||
data = self._garp()
|
||||
self._send_msg(dp, data)
|
274
ryu/tests/mininet/run_mnet-test.sh
Executable file
274
ryu/tests/mininet/run_mnet-test.sh
Executable file
@ -0,0 +1,274 @@
|
||||
#!/bin/sh
|
||||
|
||||
RUN_DIR=`dirname $0`
|
||||
CMD_NAME=`basename $0 .sh`
|
||||
CMD_PATH=`readlink -f $0`
|
||||
CMD_DIR=`dirname $CMD_PATH`
|
||||
DUMP_SEC=10
|
||||
DUMP_DELAY=2
|
||||
DUMP_DIR=/tmp/test-mn/dump
|
||||
TEST_LIST=
|
||||
TEST_SUFFIX=.mn
|
||||
MN_PRE_FILE=/tmp/test-mn/mn-pre
|
||||
MN_POST_FILE=/tmp/test-mn/mn-post
|
||||
PKG_LIST="tshark tcpreplay mz"
|
||||
RTN=0
|
||||
|
||||
# usage
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTION] [TEST DIR or FILE]..."
|
||||
echo ""
|
||||
echo "Run Ryu's test in mininet"
|
||||
echo "ex.) $ $0 l2 l3/icmp/ICMP_ping.mn"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help show this help message and exit"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# set default environment
|
||||
set_env() {
|
||||
POST_IF=h1-eth0
|
||||
DUMP_HOST=h2
|
||||
DUMP_IF=h2-eth0
|
||||
TEST_NAME=
|
||||
DUMP_FILE=
|
||||
RYU_APP=
|
||||
RYU_LOG=
|
||||
PCAP_MZ=
|
||||
PCAP_FILE=
|
||||
PCAP_FILTER=
|
||||
PCAP_COM=
|
||||
CACHE_HIT=
|
||||
}
|
||||
|
||||
# making mininet-test-pre-file
|
||||
mn_pre() {
|
||||
exec 3>&1
|
||||
exec >$MN_PRE_FILE
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "sh echo '(pre) mininet topology dump.'"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "dump"
|
||||
echo "net"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "sh echo '(pre) tshark start.'"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "$DUMP_HOST tshark -i $DUMP_IF -a duration:$DUMP_SEC -w $DUMP_FILE &"
|
||||
echo "sh sleep $DUMP_DELAY"
|
||||
echo "sh echo '----------------------------------'"
|
||||
exec 1>&3
|
||||
}
|
||||
|
||||
# making mininet-test-post-file
|
||||
mn_post() {
|
||||
exec 3>&1
|
||||
exec >$MN_POST_FILE
|
||||
echo "sh ovs-vsctl del-controller s1"
|
||||
echo "sh ovs-vsctl set bridge s1 protocols='[OpenFlow10,OpenFlow12]'"
|
||||
echo "sh ovs-vsctl set-controller s1 tcp:127.0.0.1"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "sh echo '(post) packet sending...'"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo $PCAP_COM
|
||||
echo "sh sleep 1"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "sh echo '(post) dump flows.'"
|
||||
echo "sh echo '----------------------------------'"
|
||||
echo "sh ovs-ofctl dump-flows s1"
|
||||
echo "sh echo '----------------------------------'"
|
||||
exec 1>&3
|
||||
}
|
||||
|
||||
# ovs cache-hit incremental check
|
||||
ovs_cache_hit() {
|
||||
expr `sudo ovs-dpctl show|sed -n 's|lookups: hit:||gp'|awk '{print $1}'` - ${1:-0}
|
||||
}
|
||||
|
||||
# starting ryu-manager
|
||||
run_ryu() {
|
||||
ERRSTAT=0
|
||||
ERRTAG="run_ryu() :"
|
||||
|
||||
echo "Inf: RYU_APP=$RYU_APP"
|
||||
echo "Inf: ryu-manager starting..."
|
||||
ryu-manager --verbose $RYU_APP 2>$DUMP_DIR/$RYU_LOG &
|
||||
PID_RYU=$!
|
||||
sleep 1
|
||||
[ -d /proc/$PID_RYU ] || err $ERRTAG "failed to start ryu-manager."
|
||||
|
||||
return $ERRSTAT
|
||||
}
|
||||
|
||||
# starting mininet and test-script
|
||||
run_mn() {
|
||||
echo "Info: mininet starting..."
|
||||
sudo mn --mac --test none --pre $MN_PRE_FILE --post $MN_POST_FILE \
|
||||
--controller remote 127.0.0.1
|
||||
}
|
||||
|
||||
# cleaning after mininet
|
||||
clean_mn() {
|
||||
wait_ryu
|
||||
rm -f $MN_PRE_FILE $MN_POST_FILE
|
||||
}
|
||||
|
||||
# check packet and chache-hit
|
||||
check() {
|
||||
PACKET=`tshark -r $DUMP_FILE -R "$PCAP_FILTER" 2>/dev/null`
|
||||
if [ ! "$PACKET" ]; then
|
||||
RESULT=NG
|
||||
REASON="(unmatched packet. please check $DUMP_FILE)"
|
||||
elif [ "$CACHE_HIT" ] && [ `ovs_cache_hit $CACHE_HIT` -eq 0 ]; then
|
||||
RESULT=NG
|
||||
REASON="(ovs cache hit miss.)"
|
||||
else
|
||||
RESULT=OK; REASON=
|
||||
fi
|
||||
echo
|
||||
echo "TEST ${TEST_NAME} : $RESULT $REASON"
|
||||
}
|
||||
|
||||
# stoping ryu-manager
|
||||
wait_ryu() {
|
||||
kill -2 $PID_RYU
|
||||
wait $PID_RYU
|
||||
}
|
||||
|
||||
# test-main
|
||||
test_mn() {
|
||||
DUMP_FILE=$DUMP_DIR/$DUMP_FILE
|
||||
touch $DUMP_FILE
|
||||
sudo chmod o+w $DUMP_FILE
|
||||
[ "$CACHE_HIT" ] && CACHE_HIT=`ovs_cache_hit 0`
|
||||
mn_pre
|
||||
mn_post
|
||||
run_ryu; [ $? -ne 0 ] && return 1
|
||||
run_mn; [ $? -ne 0 ] && return 1
|
||||
check
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
err() {
|
||||
echo Error: $*
|
||||
ERRSTAT=1
|
||||
}
|
||||
|
||||
mnfile_check() {
|
||||
test=`basename $1 $TEST_SUFFIX`
|
||||
file=`readlink -f $1`
|
||||
TEST_DIR=`dirname $file`
|
||||
ERRSTAT=0
|
||||
ERRTAG="mnfile_check() :"
|
||||
|
||||
# test-file check
|
||||
if [ ! -r $file ]; then
|
||||
err $ERRTAG "cannot open the file: $file"
|
||||
return $ERRSTAT
|
||||
fi
|
||||
|
||||
. $file || err $ERRTAG "failed to include $file"
|
||||
|
||||
# parameter check
|
||||
[ "$RYU_APP" ] || err $ERRTAG: "RYU_APP is not defined"
|
||||
[ "$PCAP_FILE" -o "$PCAP_MZ" ] || err $ERRTAG: "PCAP_FILE or PCAP_MZ is not defined"
|
||||
[ "$PCAP_FILTER" ] || err $ERRTAG "PCAP_FILTER is not defined"
|
||||
[ "$TEST_NAME" ] || TEST_NAME=$test
|
||||
[ "$DUMP_FILE" ] || DUMP_FILE=$test.dump
|
||||
[ "$RYU_LOG" ] || RYU_LOG=ryu-manager.$test.log
|
||||
[ $ERRSTAT -ne 0 ] && return $ERRSTAT
|
||||
|
||||
# pcap check (pcap-file or mz-option)
|
||||
if [ "$PCAP_FILE" ]; then
|
||||
PCAP_FILE=$TEST_DIR/$PCAP_FILE
|
||||
[ -r $PCAP_FILE ] || err $ERRTAG "PCAP_FILE[$PCAP_FILE] cannot read"
|
||||
PCAP_COM="h1 tcpreplay -l 3 -i $POST_IF $PCAP_FILE"
|
||||
elif [ "$PCAP_MZ" ]; then
|
||||
PCAP_COM="h1 mz $POST_IF $PCAP_MZ"
|
||||
fi
|
||||
[ $ERRSTAT -ne 0 ] && return $ERRSTAT
|
||||
|
||||
# ryu-app check
|
||||
[ -r $TEST_DIR/$RYU_APP -o -r $TEST_DIR/${RYU_APP}.py ] && RYU_APP=$TEST_DIR/$RYU_APP
|
||||
|
||||
return $ERRSTAT
|
||||
}
|
||||
|
||||
arg_check() {
|
||||
ARGLIST=
|
||||
ERRTAG="argcheck() :"
|
||||
|
||||
case "$1" in
|
||||
-h|--help) usage;;
|
||||
esac
|
||||
|
||||
if [ $# -ne 0 ]; then
|
||||
ARGLIST=$*
|
||||
else
|
||||
ARGLIST=`find . -type f -name "*$TEST_SUFFIX"`
|
||||
fi
|
||||
|
||||
for arg in $ARGLIST; do
|
||||
if [ -d $arg ]; then
|
||||
file=`find $arg -type f -name "*$TEST_SUFFIX"`
|
||||
elif [ -f $arg ]; then
|
||||
file=$arg
|
||||
else
|
||||
err $ERRTAG "$arg is not found"
|
||||
file=
|
||||
fi
|
||||
|
||||
TEST_LIST="$TEST_LIST $file"
|
||||
done
|
||||
}
|
||||
|
||||
pkg_check() {
|
||||
no_pkg=
|
||||
for pkg in $PKG_LIST; do
|
||||
[ ! `which $pkg` ] && no_pkg="$no_pkg $pkg"
|
||||
done
|
||||
for pkg in $no_pkg; do
|
||||
echo "Error: Package [ $pkg ] is not found. Please install."
|
||||
done
|
||||
[ "$no_pkg" ] && exit 1
|
||||
}
|
||||
|
||||
### main
|
||||
[ -d $DUMP_DIR ] || mkdir -p $DUMP_DIR
|
||||
|
||||
pkg_check
|
||||
arg_check $*
|
||||
echo "\n---------- test target ----------"
|
||||
for testfile in $TEST_LIST; do echo $testfile; done
|
||||
|
||||
count=0
|
||||
for testfile in $TEST_LIST; do
|
||||
echo "\n---------- test [$testfile] start ----------"
|
||||
set_env
|
||||
mnfile_check $testfile && test_mn
|
||||
case $? in
|
||||
0) msg="finished : $RESULT" ;;
|
||||
*) msg="skipped with error"; RESULT="skip" ;;
|
||||
esac
|
||||
eval RESULT_${count}=\$RESULT
|
||||
eval REASON_${count}=\$REASON
|
||||
count=`expr $count + 1`
|
||||
num=`eval echo \\${num_$RESULT:-0}`
|
||||
eval num_${RESULT}=`expr $num + 1`
|
||||
[ "$RESULT" != "OK" ] && RTN=1
|
||||
clean_mn
|
||||
echo "\n---------- test [$testfile] $msg ----------"
|
||||
done
|
||||
|
||||
# output summary results
|
||||
echo "\n---------- test results ----------"
|
||||
count=0
|
||||
for testfile in $TEST_LIST; do
|
||||
eval echo \$testfile : \$RESULT_${count} \$REASON_${count}
|
||||
count=`expr $count + 1`
|
||||
done
|
||||
echo "----------------------------------"
|
||||
echo "Ran $count tests. Result: ${num_OK:+OK=}$num_OK ${num_NG:+NG=}$num_NG ${num_skip:+skip=}$num_skip"
|
||||
|
||||
exit $RTN
|
Loading…
Reference in New Issue
Block a user