test: simplify integrated OVS test suite

This patch simplifies integrated OVS test suite. Currently, we wait
for a barrier response before moving to the next test. However, we
don't need. The logic works like the following:

sending a flow mod (deleting all the flows)
sending a barrier
sending a flow mod (set up a flow to test)
sending a barrier
sending a flow stats

Then the reply handler for flow stats verifies the result and move to
the next.

You can run a test suite like:

$ ryu-manager ~/git/ryu/ryu/tests/integrated/test_add_flow_v12_actions.py

We can try two more suites:

ryu/tests/integrated/test_add_flow_v10.py
ryu/tests/integrated/test_add_flow_v12_matches.py

Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
FUJITA Tomonori 2012-07-28 10:24:46 +09:00
parent dfa4ab185a
commit 8c1978942d
5 changed files with 1041 additions and 3279 deletions

View File

@ -32,7 +32,6 @@ from ryu import utils
from ryu.app import wsgi from ryu.app import wsgi
from ryu.base.app_manager import AppManager from ryu.base.app_manager import AppManager
from ryu.controller import controller from ryu.controller import controller
from ryu.tests.integrated import tester
FLAGS = gflags.FLAGS FLAGS = gflags.FLAGS

View File

@ -17,691 +17,245 @@
import logging import logging
from ryu.controller import handler
from ryu.controller.handler import set_ev_cls
from ryu.tests.integrated import tester from ryu.tests.integrated import tester
from ryu.ofproto import nx_match from ryu.ofproto import nx_match
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
_target = 'br-tester'
class RunTest(tester.TestFlowBase):
""" Test case for add flows of1.0
"""
class RunTest(tester.RunTestBase): def __init__(self, *args, **kwargs):
super(RunTest, self).__init__(*args, **kwargs)
self._verify = []
def __init__(self): def add_action(self, dp, action):
super(RunTest, self).__init__() rule = nx_match.ClsRule()
self.send_flow_mod(
dp, rule, 0, dp.ofproto.OFPFC_ADD, 0, 0, None,
0xffffffff, None, dp.ofproto.OFPFF_SEND_FLOW_REM, action)
def send_flow_mod(self, rule, cookie, command, idle_timeout, hard_timeout, def add_rule(self, dp, rule):
priority=None, buffer_id=0xffffffff, self.send_flow_mod(
dp, rule, 0, dp.ofproto.OFPFC_ADD, 0, 0, None,
0xffffffff, None, dp.ofproto.OFPFF_SEND_FLOW_REM, [])
def send_flow_mod(self, dp, rule, cookie, command, idle_timeout,
hard_timeout, priority=None, buffer_id=0xffffffff,
out_port=None, flags=0, actions=None): out_port=None, flags=0, actions=None):
if priority is None: if priority is None:
priority = self.ofproto.OFP_DEFAULT_PRIORITY priority = dp.ofproto.OFP_DEFAULT_PRIORITY
if out_port is None: if out_port is None:
out_port = self.ofproto.OFPP_NONE out_port = dp.ofproto.OFPP_NONE
match_tuple = rule.match_tuple() match_tuple = rule.match_tuple()
match = self.ofproto_parser.OFPMatch(*match_tuple) match = dp.ofproto_parser.OFPMatch(*match_tuple)
flow_mod = self.ofproto_parser.OFPFlowMod(
self.datapath, match, cookie, command, idle_timeout, hard_timeout, m = dp.ofproto_parser.OFPFlowMod(
dp, match, cookie, command, idle_timeout, hard_timeout,
priority, buffer_id, out_port, flags, actions) priority, buffer_id, out_port, flags, actions)
self.datapath.send_msg(flow_mod) dp.send_msg(m)
def test_action_output(self):
datapath = self.datapath
ofproto = self.ofproto
out_port = 2
self.set_val('out_port', out_port)
actions = [
datapath.ofproto_parser.OFPActionOutput(out_port),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_output(self):
ovs_actions = {}
out_port = self.get_val('out_port')
def _verify_action(self, actions, type_, name, value):
try: try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions'] action = actions[0]
ovs_out_port = ovs_actions['output'] if action.cls_action_type != type_:
except (KeyError, IndexError): return "Action type error. send:%s, val:%s" \
ovs_out_port = '' % (type_, action.cls_action_type)
except IndexError:
if ovs_out_port == '' or int(ovs_out_port) != out_port: return "Action is not setting."
err = 'send_actions=[output:%s] ovs_actions=[%s]' \
% (out_port, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_vlan_vid(self):
datapath = self.datapath
ofproto = self.ofproto
vlan_vid = 3
self.set_val('vlan_vid', vlan_vid)
actions = [
datapath.ofproto_parser.OFPActionVlanVid(vlan_vid),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_vlan_vid(self):
ovs_actions = {}
vlan_vid = self.get_val('vlan_vid')
f_value = None
if name:
try: try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions'] if isinstance(name, list):
ovs_vlan_vid = ovs_actions['mod_vlan_vid'] f_value = [getattr(action, n) for n in name]
except (KeyError, IndexError): else:
ovs_vlan_vid = '' f_value = getattr(action, name)
except AttributeError:
if ovs_vlan_vid == '' or int(ovs_vlan_vid) != vlan_vid:
err = 'send_actions=[vlan_vid:%s] ovs_actions=[%s]' \
% (vlan_vid, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_vlan_pcp(self):
datapath = self.datapath
ofproto = self.ofproto
vlan_pcp = 4
self.set_val('vlan_pcp', vlan_pcp)
actions = [
datapath.ofproto_parser.OFPActionVlanPcp(vlan_pcp),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_vlan_pcp(self):
ovs_actions = {}
vlan_pcp = self.get_val('vlan_pcp')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_vlan_pcp = ovs_actions['mod_vlan_pcp']
except (KeyError, IndexError):
ovs_vlan_pcp = ''
if ovs_vlan_pcp == '' or int(ovs_vlan_pcp) != vlan_pcp:
err = 'send_actions=[vlan_vid:%s] ovs_actions=[%s]' \
% (vlan_pcp, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_strip_vlan(self):
datapath = self.datapath
ofproto = self.ofproto
actions = [
datapath.ofproto_parser.OFPActionStripVlan(),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_strip_vlan(self):
ovs_actions = {}
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
except (KeyError, IndexError):
pass pass
if not 'strip_vlan' in ovs_actions: if f_value != value:
err = 'send_actions=[strip_vlan] ovs_actions=[%s]' \ return "Value error. send:%s=%s val:%s" \
% (self.cnv_txt(ovs_actions)) % (name, value, f_value)
self.results(ret=False, msg=err) return True
return
self.results()
def test_action_set_dl_src(self): def _verify_rule(self, rule, name, value):
datapath = self.datapath f_value = getattr(rule, name)
ofproto = self.ofproto if f_value != value:
return "Value error. send:%s=%s val:%s" \
% (name, value, f_value)
return True
dl_src = '56:b3:42:04:b2:7a' def verify_default(self, dp, stats):
self.set_val('dl_src', dl_src) verify = self._verify
self._verify = []
match = stats[0].match
actions = stats[0].actions
dl_src_bin = self.haddr_to_bin(dl_src) if len(verify) == 2:
actions = [ return self._verify_rule(match, *verify)
datapath.ofproto_parser.OFPActionSetDlSrc(dl_src_bin), elif len(verify) == 3:
] return self._verify_action(actions, *verify)
else:
return "self._verify is invalid."
rule = nx_match.ClsRule() # Test of Actions
self.send_flow_mod( def test_action_output(self, dp):
rule=rule, cookie=0, command=ofproto.OFPFC_ADD, out_port = 2
idle_timeout=0, hard_timeout=0, self._verify = [dp.ofproto.OFPAT_OUTPUT,
priority=ofproto.OFP_DEFAULT_PRIORITY, 'port', out_port]
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions) action = dp.ofproto_parser.OFPActionOutput(out_port)
self.add_action(dp, [action, ])
def check_action_set_dl_src(self):
ovs_actions = {}
dl_src = self.get_val('dl_src')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_dl_src = ovs_actions['mod_dl_src']
except (KeyError, IndexError):
ovs_dl_src = ''
if ovs_dl_src == '' or ovs_dl_src != dl_src:
err = 'send_actions=[dl_src:%s] ovs_actions=[%s]' \
% (dl_src, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_set_dl_dst(self):
datapath = self.datapath
ofproto = self.ofproto
dl_dst = 'c2:93:a2:fb:d0:f4'
self.set_val('dl_dst', dl_dst)
dl_dst_bin = self.haddr_to_bin(dl_dst)
actions = [
datapath.ofproto_parser.OFPActionSetDlDst(dl_dst_bin),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_set_dl_dst(self):
ovs_actions = {}
dl_dst = self.get_val('dl_dst')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_dl_dst = ovs_actions['mod_dl_dst']
except (KeyError, IndexError):
ovs_dl_dst = ''
if ovs_dl_dst == '' or ovs_dl_dst != dl_dst:
err = 'send_actions=[dl_dst:%s] ovs_actions=[%s]' \
% (dl_dst, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_set_nw_src(self):
datapath = self.datapath
ofproto = self.ofproto
nw_src = '216.132.81.105'
self.set_val('nw_src', nw_src)
nw_src_int = self.ipv4_to_int(nw_src)
actions = [
datapath.ofproto_parser.OFPActionSetNwSrc(nw_src_int),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_set_nw_src(self):
ovs_actions = {}
nw_src = self.get_val('nw_src')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_nw_src = ovs_actions['mod_nw_src']
except (KeyError, IndexError):
ovs_nw_src = ''
if ovs_nw_src == '' or ovs_nw_src != nw_src:
err = 'send_actions=[nw_src:%s] ovs_actions=[%s]' \
% (nw_src, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_set_nw_dst(self):
datapath = self.datapath
ofproto = self.ofproto
nw_dst = '223.201.206.3'
self.set_val('nw_dst', nw_dst)
nw_dst_int = self.ipv4_to_int(nw_dst)
actions = [
datapath.ofproto_parser.OFPActionSetNwDst(nw_dst_int),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_set_nw_dst(self):
ovs_actions = {}
nw_dst = self.get_val('nw_dst')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_nw_dst = ovs_actions['mod_nw_dst']
except (KeyError, IndexError):
ovs_nw_dst = ''
if ovs_nw_dst == '' or ovs_nw_dst != nw_dst:
err = 'send_actions=[nw_dst:%s] ovs_actions=[%s]' \
% (nw_dst, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_set_nw_tos(self):
datapath = self.datapath
ofproto = self.ofproto
nw_tos = 111
self.set_val('nw_tos', nw_tos)
actions = [
datapath.ofproto_parser.OFPActionSetNwTos(nw_tos),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_set_nw_tos(self):
ovs_actions = {}
nw_tos = self.get_val('nw_tos')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_nw_tos = ovs_actions['mod_nw_tos']
except (KeyError, IndexError):
ovs_nw_tos = ''
if ovs_nw_tos == '' or int(ovs_nw_tos) != nw_tos:
err = 'send_actions=[nw_tos:%s] ovs_actions=[%s]' \
% (nw_tos, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_set_tp_src(self):
datapath = self.datapath
ofproto = self.ofproto
tp_src = 55420
self.set_val('tp_src', tp_src)
actions = [
datapath.ofproto_parser.OFPActionSetTpSrc(tp_src),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_set_tp_src(self):
ovs_actions = {}
tp_src = self.get_val('tp_src')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_tp_src = ovs_actions['mod_tp_src']
except (KeyError, IndexError):
ovs_tp_src = ''
if ovs_tp_src == '' or int(ovs_tp_src) != tp_src:
err = 'send_actions=[tp_src:%s] ovs_actions=[%s]' \
% (tp_src, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_set_tp_dst(self):
datapath = self.datapath
ofproto = self.ofproto
tp_dst = 15430
self.set_val('tp_dst', tp_dst)
actions = [
datapath.ofproto_parser.OFPActionSetTpDst(tp_dst),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_set_tp_dst(self):
ovs_actions = {}
tp_dst = self.get_val('tp_dst')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_tp_dst = ovs_actions['mod_tp_dst']
except (KeyError, IndexError):
ovs_tp_dst = ''
if ovs_tp_dst == '' or int(ovs_tp_dst) != tp_dst:
err = 'send_actions=[tp_src:%s] ovs_actions=[%s]' \
% (tp_dst, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_action_enqueue(self):
datapath = self.datapath
ofproto = self.ofproto
port = 207
queue_id = 4287508753
self.set_val('enqueue', str(port) + 'q' + str(queue_id))
actions = [
datapath.ofproto_parser.OFPActionEnqueue(port, queue_id),
]
rule = nx_match.ClsRule()
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_action_enqueue(self):
ovs_actions = {}
enqueue = self.get_val('enqueue')
try:
ovs_actions = self.get_ovs_flows(_target)[0]['actions']
ovs_enqueue = ovs_actions['enqueue']
except (KeyError, IndexError):
ovs_enqueue = ''
if ovs_enqueue == '' or ovs_enqueue != enqueue:
err = 'send_actions=[enqueue:%s] ovs_actions=[%s]' \
% (enqueue, self.cnv_txt(ovs_actions))
self.results(ret=False, msg=err)
return
self.results()
def test_rule_set_in_port(self):
datapath = self.datapath
ofproto = self.ofproto
def test_rule_set_in_port(self, dp):
in_port = 32 in_port = 32
self.set_val('in_port', in_port) self._verify = ['in_port', in_port]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_in_port(in_port) rule.set_in_port(in_port)
self.send_flow_mod( self.add_rule(dp, rule)
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_in_port(self): def test_action_vlan_vid(self, dp):
ovs_rules = {} vlan_vid = 2
in_port = self.get_val('in_port') self._verify = [dp.ofproto.OFPAT_SET_VLAN_VID,
'vlan_vid', vlan_vid]
action = dp.ofproto_parser.OFPActionVlanVid(vlan_vid)
self.add_action(dp, [action, ])
try: def test_action_vlan_pcp(self, dp):
ovs_rules = self.get_ovs_flows(_target)[0]['rules'] vlan_pcp = 4
ovs_in_port = ovs_rules['in_port'] self._verify = [dp.ofproto.OFPAT_SET_VLAN_PCP,
except (KeyError, IndexError): 'vlan_pcp', vlan_pcp]
ovs_in_port = '' action = dp.ofproto_parser.OFPActionVlanPcp(vlan_pcp)
self.add_action(dp, [action, ])
if ovs_in_port == '' or int(ovs_in_port) != in_port: def test_action_strip_vlan(self, dp):
err = 'send_rules=[in_port:%s] ovs_rules=[%s]' \ vlan_pcp = 4
% (in_port, self.cnv_txt(ovs_rules)) self._verify = [dp.ofproto.OFPAT_STRIP_VLAN,
self.results(ret=False, msg=err) None, None]
return action = dp.ofproto_parser.OFPActionStripVlan()
self.results() self.add_action(dp, [action, ])
def test_rule_set_dl_src(self):
datapath = self.datapath
ofproto = self.ofproto
dl_src = 'b8:a1:94:51:78:83'
self.set_val('dl_src', dl_src)
def test_action_set_dl_src(self, dp):
dl_src = '56:b3:42:04:b2:7a'
dl_src_bin = self.haddr_to_bin(dl_src) dl_src_bin = self.haddr_to_bin(dl_src)
self._verify = [dp.ofproto.OFPAT_SET_DL_SRC,
'dl_addr', dl_src_bin]
action = dp.ofproto_parser.OFPActionSetDlSrc(dl_src_bin)
self.add_action(dp, [action, ])
def test_action_set_dl_dst(self, dp):
dl_dst = 'c2:93:a2:fb:d0:f4'
dl_dst_bin = self.haddr_to_bin(dl_dst)
self._verify = [dp.ofproto.OFPAT_SET_DL_DST,
'dl_addr', dl_dst_bin]
action = dp.ofproto_parser.OFPActionSetDlDst(dl_dst_bin)
self.add_action(dp, [action, ])
def test_action_set_nw_src(self, dp):
nw_src = '216.132.81.105'
nw_src_int = self.ipv4_to_int(nw_src)
self._verify = [dp.ofproto.OFPAT_SET_NW_SRC,
'nw_addr', nw_src_int]
action = dp.ofproto_parser.OFPActionSetNwSrc(nw_src_int)
self.add_action(dp, [action, ])
def test_action_set_nw_dst(self, dp):
nw_dst = '223.201.206.3'
nw_dst_int = self.ipv4_to_int(nw_dst)
self._verify = [dp.ofproto.OFPAT_SET_NW_DST,
'nw_addr', nw_dst_int]
action = dp.ofproto_parser.OFPActionSetNwDst(nw_dst_int)
self.add_action(dp, [action, ])
def test_action_set_nw_tos(self, dp):
nw_tos = 111
self._verify = [dp.ofproto.OFPAT_SET_NW_TOS,
'tos', nw_tos]
action = dp.ofproto_parser.OFPActionSetNwTos(nw_tos)
self.add_action(dp, [action, ])
def test_action_set_tp_src(self, dp):
tp_src = 55420
self._verify = [dp.ofproto.OFPAT_SET_TP_SRC,
'tp', tp_src]
action = dp.ofproto_parser.OFPActionSetTpSrc(tp_src)
self.add_action(dp, [action, ])
def test_action_set_tp_dst(self, dp):
tp_dst = 15430
self._verify = [dp.ofproto.OFPAT_SET_TP_DST,
'tp', tp_dst]
action = dp.ofproto_parser.OFPActionSetTpDst(tp_dst)
self.add_action(dp, [action, ])
def test_action_enqueue(self, dp):
port = 207
queue_id = 4287508753
self._verify = [dp.ofproto.OFPAT_ENQUEUE,
['port', 'queue_id'], [port, queue_id]]
action = dp.ofproto_parser.OFPActionEnqueue(port, queue_id)
self.add_action(dp, [action, ])
# Test of Rules
def test_rule_set_in_port(self, dp):
in_port = 32
self._verify = ['in_port', in_port]
rule = nx_match.ClsRule()
rule.set_in_port(in_port)
self.add_rule(dp, rule)
def test_rule_set_dl_src(self, dp):
dl_src = 'b8:a1:94:51:78:83'
dl_src_bin = self.haddr_to_bin(dl_src)
self._verify = ['dl_src', dl_src_bin]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_dl_src(dl_src_bin) rule.set_dl_src(dl_src_bin)
self.add_rule(dp, rule)
self.send_flow_mod( def test_rule_set_dl_type_ip(self, dp):
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_dl_src(self):
ovs_rules = {}
dl_src = self.get_val('dl_src')
try:
ovs_rules = self.get_ovs_flows(_target)[0]['rules']
ovs_dl_src = ovs_rules['dl_src']
except (KeyError, IndexError):
ovs_dl_src = ''
if ovs_dl_src == '' or ovs_dl_src != dl_src:
err = 'send_rules=[dl_src:%s] ovs_rules=[%s]' \
% (dl_src, self.cnv_txt(ovs_rules))
self.results(ret=False, msg=err)
return
self.results()
def test_rule_set_dl_type_ip(self):
datapath = self.datapath
ofproto = self.ofproto
dl_type = nx_match.ETH_TYPE_IP dl_type = nx_match.ETH_TYPE_IP
self.set_val('dl_type', 'ip') self._verify = ['dl_type', dl_type]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_dl_type(dl_type) rule.set_dl_type(dl_type)
self.add_rule(dp, rule)
self.send_flow_mod( def test_rule_set_dl_type_arp(self, dp):
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_dl_type_ip(self):
ovs_rules = {}
dl_type = self.get_val('dl_type')
try:
ovs_rules = self.get_ovs_flows(_target)[0]['rules']
except (KeyError, IndexError):
pass
if not dl_type in ovs_rules:
err = 'send_rules=[dl_type:%s] ovs_rules=[%s]' \
% (dl_type, self.cnv_txt(ovs_rules))
self.results(ret=False, msg=err)
return
self.results()
def test_rule_set_dl_type_arp(self):
datapath = self.datapath
ofproto = self.ofproto
dl_type = nx_match.ETH_TYPE_ARP dl_type = nx_match.ETH_TYPE_ARP
self.set_val('dl_type', 'arp') self._verify = ['dl_type', dl_type]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_dl_type(dl_type) rule.set_dl_type(dl_type)
self.add_rule(dp, rule)
self.send_flow_mod( def test_rule_set_dl_type_vlan(self, dp):
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_dl_type_arp(self):
ovs_rules = {}
dl_type = self.get_val('dl_type')
try:
ovs_rules = self.get_ovs_flows(_target)[0]['rules']
except (KeyError, IndexError):
pass
if not dl_type in ovs_rules:
err = 'send_rules=[dl_type:%s] ovs_rules=[%s]' \
% (dl_type, self.cnv_txt(ovs_rules))
self.results(ret=False, msg=err)
return
self.results()
def test_rule_set_dl_type_vlan(self):
datapath = self.datapath
ofproto = self.ofproto
dl_type = nx_match.ETH_TYPE_VLAN dl_type = nx_match.ETH_TYPE_VLAN
self.set_val('dl_type', nx_match.ETH_TYPE_VLAN) self._verify = ['dl_type', dl_type]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_dl_type(dl_type) rule.set_dl_type(dl_type)
self.add_rule(dp, rule)
self.send_flow_mod( def test_rule_set_dl_type_ipv6(self, dp):
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_dl_type_vlan(self):
ovs_rules = {}
dl_type = self.get_val('dl_type')
try:
ovs_rules = self.get_ovs_flows(_target)[0]['rules']
ovs_dl_type = ovs_rules['dl_type']
except (KeyError, IndexError):
ovs_dl_type = ''
if ovs_dl_type == '' or int(ovs_dl_type, 16) != dl_type:
err = 'send_rules=[dl_src:%s] ovs_rules=[%s]' \
% (dl_type, self.cnv_txt(ovs_rules))
self.results(ret=False, msg=err)
return
self.results()
def test_rule_set_dl_type_ipv6(self):
datapath = self.datapath
ofproto = self.ofproto
dl_type = nx_match.ETH_TYPE_IPV6 dl_type = nx_match.ETH_TYPE_IPV6
self.set_val('dl_type', 'ipv6') self._verify = ['dl_type', dl_type]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_dl_type(dl_type) rule.set_dl_type(dl_type)
self.add_rule(dp, rule)
self.send_flow_mod( def test_rule_set_dl_type_lacp(self, dp):
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_dl_type_ipv6(self):
ovs_rules = {}
dl_type = self.get_val('dl_type')
try:
ovs_rules = self.get_ovs_flows(_target)[0]['rules']
except (KeyError, IndexError):
pass
if not dl_type in ovs_rules:
err = 'send_rules=[dl_type:%s] ovs_rules=[%s]' \
% (dl_type, self.cnv_txt(ovs_rules))
self.results(ret=False, msg=err)
return
self.results()
def test_rule_set_dl_type_lacp(self):
datapath = self.datapath
ofproto = self.ofproto
dl_type = nx_match.ETH_TYPE_LACP dl_type = nx_match.ETH_TYPE_LACP
self.set_val('dl_type', nx_match.ETH_TYPE_LACP) self._verify = ['dl_type', dl_type]
actions = []
rule = nx_match.ClsRule() rule = nx_match.ClsRule()
rule.set_dl_type(dl_type) rule.set_dl_type(dl_type)
self.add_rule(dp, rule)
self.send_flow_mod(
rule=rule, cookie=0, command=ofproto.OFPFC_ADD,
idle_timeout=0, hard_timeout=0,
priority=ofproto.OFP_DEFAULT_PRIORITY,
flags=ofproto.OFPFF_SEND_FLOW_REM, actions=actions)
def check_rule_set_dl_type_lacp(self):
ovs_rules = {}
dl_type = self.get_val('dl_type')
try:
ovs_rules = self.get_ovs_flows(_target)[0]['rules']
ovs_dl_type = ovs_rules['dl_type']
except (KeyError, IndexError):
ovs_dl_type = ''
if ovs_dl_type == '' or int(ovs_dl_type, 16) != dl_type:
err = 'send_rules=[dl_src:%s] ovs_rules=[%s]' \
% (dl_type, self.cnv_txt(ovs_rules))
self.results(ret=False, msg=err)
return
self.results()

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -16,136 +16,57 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4 # vim: tabstop=4 shiftwidth=4 softtabstop=4
import sys import sys
import gflags
import logging import logging
import subprocess
import traceback
from ryu import utils from ryu import utils
from ryu.lib import mac from ryu.lib import mac
from ryu.base import app_manager from ryu.base import app_manager
from ryu.controller import ofp_event from ryu.controller import ofp_event
from ryu.controller import dispatcher
from ryu.controller import event
from ryu.controller import handler from ryu.controller import handler
from ryu.controller import dpset
from ryu.controller.handler import MAIN_DISPATCHER from ryu.controller.handler import MAIN_DISPATCHER
from ryu.controller.handler import CONFIG_DISPATCHER from ryu.controller.handler import CONFIG_DISPATCHER
from ryu.controller.handler import set_ev_cls from ryu.controller.handler import set_ev_cls
from ryu.ofproto import nx_match
from ryu.ofproto import ofproto_v1_0 from ryu.ofproto import ofproto_v1_0
from ryu.ofproto import ofproto_v1_2 from ryu.ofproto import ofproto_v1_2
LOG = logging.getLogger(__name__) LOG = logging.getLogger(__name__)
FLAGS = gflags.FLAGS
gflags.DEFINE_string('run_test_mod', '', 'Test run the module name.')
class EventRunTest(event.EventBase):
def __init__(self, datapath):
super(EventRunTest, self).__init__()
self.datapath = datapath
QUEUE_NAME_RUN_TEST_EV = 'run_test_event'
DISPATCHER_NAME_RUN_TEST_EV = 'run_test_event'
RUN_TEST_EV_DISPATCHER = dispatcher.EventDispatcher(
DISPATCHER_NAME_RUN_TEST_EV)
LOG_TEST_START = 'TEST_START: %s' LOG_TEST_START = 'TEST_START: %s'
LOG_TEST_RESULTS = 'TEST_RESULTS:' LOG_TEST_RESULTS = 'TEST_RESULTS:'
LOG_TEST_FINISH = 'TEST_FINISHED: Completed=[%s], OK=[%s], NG=[%s]' LOG_TEST_FINISH = 'TEST_FINISHED: Completed=[%s]'
class Tester(app_manager.RyuApp): class TestFlowBase(app_manager.RyuApp):
"""
To run the tests is required for the following pair of functions.
1. test_<test name>()
To send flows to switch.
2. verify_<test name>() or _verify_default()
To check flows of switch.
"""
_CONTEXTS = {
'dpset': dpset.DPSet,
}
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(Tester, self).__init__() super(TestFlowBase, self).__init__(*args, **kwargs)
self.ev_q = dispatcher.EventQueue(QUEUE_NAME_RUN_TEST_EV, self.pending = []
RUN_TEST_EV_DISPATCHER) self.results = {}
self.current = None
self.unclear = 0
run_test_mod = utils.import_module(FLAGS.run_test_mod) for t in dir(self):
LOG.debug('import run_test_mod.[%s]', run_test_mod.__name__) if t.startswith("test_"):
self.pending.append(t)
self.unclear = len(self.pending)
self.run_test = run_test_mod.RunTest(*args, **kwargs) def delete_all_flows(self, dp):
handler.register_instance(self.run_test) if dp.ofproto == ofproto_v1_0:
@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)
def switch_features_handler(self, ev):
msg = ev.msg
datapath = msg.datapath
send_delete_all_flows(datapath)
datapath.send_barrier()
@set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER)
def barrier_replay_handler(self, ev):
self.ev_q.queue(EventRunTest(ev.msg.datapath))
@set_ev_cls(EventRunTest, RUN_TEST_EV_DISPATCHER)
def run_test_halder(self, ev):
dp = ev.datapath
t = self.run_test
if not t._test_started():
t._test_init(dp)
if not self._run_test(t):
# run_test was throwing exception.
LOG.info(LOG_TEST_FINISH, False, t._RESULTS_OK, t._RESULTS_NG)
return
if not t._test_completed():
t.datapath.send_barrier()
return
# Completed all tests.
LOG.info(LOG_TEST_FINISH, True, t._RESULTS_OK, t._RESULTS_NG)
def _run_test(self, t):
running = t._running()
if len(running) == 0:
# next test
name = t._pop_test()
LOG.info(LOG_TEST_START, name)
try:
getattr(t, name)()
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value,
exc_traceback, file=sys.stdout)
send_delete_all_flows(t.datapath)
return False
else:
# check
name = 'check_' + running[5:]
if not name in dir(t):
name = '_check_default'
err = 0
try:
# LOG.debug('_run_test: CHECK_TEST = [%s]', name)
getattr(t, name)()
except Exception:
exc_type, exc_value, exc_traceback = sys.exc_info()
traceback.print_exception(exc_type, exc_value,
exc_traceback, file=sys.stdout)
err = 1
finally:
send_delete_all_flows(t.datapath)
if err:
return False
t._check_run()
return True
def _send_delete_all_flows_v10(dp):
rule = nx_match.ClsRule()
match = dp.ofproto_parser.OFPMatch(dp.ofproto.OFPFW_ALL, match = dp.ofproto_parser.OFPMatch(dp.ofproto.OFPFW_ALL,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0) 0, 0, 0, 0, 0, 0, 0)
@ -154,181 +75,86 @@ def _send_delete_all_flows_v10(dp):
dp.ofproto.OFPFC_DELETE, dp.ofproto.OFPFC_DELETE,
0, 0, 0, 0, 0, 0, 0, 0,
dp.ofproto.OFPP_NONE, 0, None) dp.ofproto.OFPP_NONE, 0, None)
dp.send_msg(m) elif dp.ofproto == ofproto_v1_2:
def _send_delete_all_flows_v12(dp):
match = dp.ofproto_parser.OFPMatch() match = dp.ofproto_parser.OFPMatch()
inst = []
m = dp.ofproto_parser.OFPFlowMod(dp, 0, 0, 0, m = dp.ofproto_parser.OFPFlowMod(dp, 0, 0, 0,
dp.ofproto.OFPFC_DELETE, dp.ofproto.OFPFC_DELETE,
0, 0, 0, 0, 0, 0, 0, 0xffffffff,
dp.ofproto.OFPP_ANY, 0xffffffff, dp.ofproto.OFPP_ANY, 0xffffffff,
0, match, inst) 0, match, [])
dp.send_msg(m) dp.send_msg(m)
def send_flow_stats(self, dp):
def send_delete_all_flows(dp):
assert dp.ofproto in (ofproto_v1_0, ofproto_v1_2)
if dp.ofproto == ofproto_v1_0: if dp.ofproto == ofproto_v1_0:
_send_delete_all_flows_v10(dp) match = dp.ofproto_parser.OFPMatch(dp.ofproto.OFPFW_ALL,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0)
m = dp.ofproto_parser.OFPFlowStatsRequest(
dp, 0, match,
0, dp.ofproto.OFPP_NONE)
elif dp.ofproto == ofproto_v1_2: elif dp.ofproto == ofproto_v1_2:
_send_delete_all_flows_v12(dp) match = dp.ofproto_parser.OFPMatch()
m = dp.ofproto_parser.OFPFlowStatsRequest(dp, 0,
dp.ofproto.OFPP_ANY,
dp.ofproto.OFPG_ANY,
0, 0, match)
dp.send_msg(m)
def verify_default(self, dp, stats):
return 'function %s() is not found.' % ("verify" + self.current[4:], )
def start_next_test(self, dp):
self.delete_all_flows(dp)
dp.send_barrier()
if len(self.pending):
t = self.pending.pop()
LOG.info(LOG_TEST_START, t)
self.current = t
getattr(self, t)(dp)
dp.send_barrier()
self.send_flow_stats(dp)
else: else:
# this function will be remove. LOG.info("TEST_RESULTS:")
dp.send_delete_all_flows() for t, r in self.results.items():
LOG.info(" %s: %s", t, r)
LOG.info(LOG_TEST_FINISH, self.unclear == 0)
@handler.set_ev_cls(ofp_event.EventOFPFlowStatsReply,
handler.MAIN_DISPATCHER)
def flow_reply_handler(self, ev):
self.run_verify(ev)
def run_command(cmd, redirect_output=True, check_exit_code=True, env=None): @handler.set_ev_cls(ofp_event.EventOFPStatsReply,
if redirect_output: handler.MAIN_DISPATCHER)
stdout = subprocess.PIPE def stats_reply_handler(self, ev):
else: self.run_verify(ev)
stdout = None
proc = subprocess.Popen(cmd, stdout=stdout, def run_verify(self, ev):
stderr=subprocess.STDOUT, env=env) msg = ev.msg
output = proc.communicate()[0] dp = msg.datapath
LOG.debug('Exec command "%s" \n%s', ' '.join(cmd), output) verify_func = self.verify_default
if check_exit_code and proc.returncode != 0: v = "verify" + self.current[4:]
raise Exception('Command "%s" failed.\n%s' % (' '.join(cmd), output)) if v in dir(self):
return output verify_func = getattr(self, v)
result = verify_func(dp, msg.body)
if result == True:
self.unclear -= 1
class RunTestBase(object): self.results[self.current] = result
""" self.start_next_test(dp)
To run the tests is required for the following pair of functions.
1. test_<test name>()
To send flows to switch.
2. check_<test name>() or _check_default() @handler.set_ev_cls(dpset.EventDP, dpset.DPSET_EV_DISPATCHER)
To check flows of switch. def handler_datapath(self, ev):
if ev.enter:
self.start_next_test(ev.dp)
To deal common values to the functions(test_ and check_) @set_ev_cls(ofp_event.EventOFPBarrierReply, MAIN_DISPATCHER)
can use `set_val('name', val)` and `get_val('name')`. def barrier_replay_handler(self, ev):
This values is initialized before the next tests. pass
"""
def __init__(self):
super(RunTestBase, self).__init__()
self._TEST_STARTED = False
self._TESTS = []
self._RUNNING = ''
self._RESULTS_OK = 0
self._RESULTS_NG = 0
self._CHECK = {}
def _test_started(self):
return self._TEST_STARTED
def _test_init(self, dp):
self.datapath = dp
self.ofproto = dp.ofproto
self.ofproto_parser = dp.ofproto_parser
for name in dir(self):
if name.startswith("test_"):
self._TESTS.append(name)
self._TEST_STARTED = True
def _test_completed(self):
if self._TEST_STARTED:
if len(self._RUNNING) + len(self._TESTS) == 0:
return True
return False
def _pop_test(self):
self._RUNNING = self._TESTS.pop()
return self._RUNNING
def _running(self):
return self._RUNNING
def _check_run(self):
self._RUNNING = ''
def _check_default(self):
err = 'function %s() is not found.' % (self._RUNNING, )
self.results(ret=False, msg=err)
def results(self, name=None, ret=True, msg=''):
if not name:
name = self._RUNNING
if ret:
res = 'OK'
self._RESULTS_OK += 1
else:
res = 'NG'
self._RESULTS_NG += 1
LOG.info('%s %s [%s] %s', LOG_TEST_RESULTS, name, res, '\n' + msg)
def set_val(self, name, val):
self._CHECK[name] = val
def get_val(self, name):
return self._CHECK[name]
def del_val(self, name):
del self._CHECK[name]
def del_val_all(self):
self._CHECK.clear()
def get_ovs_flows(self, target):
# flows (return):
# [flow1, flow2,...]
# flow:
# {'actions': actions, 'rules': rules}
# or {'apply_actions': actions, 'rules': rules}
# or {'write_actions': actions, 'rules': rules}
# or {'clear_actions': actions, 'rules': rules}
# actions, rules:
# {'<name>': <val>}
cmd = ('sudo', 'ovs-ofctl', 'dump-flows', target)
output = run_command(cmd)
flows = []
for line in output.splitlines():
if line.startswith(" "):
flow = {}
rules, actions = line.split('actions=')
rules = self.cnv_list(rules, '=')
if actions.startswith("apply_actions"):
a_name = 'apply_actions'
actions = actions[len(a_name) + 1:-1]
elif actions.startswith("write_actions"):
a_name = 'write_actions'
actions = actions[len(a_name) + 1:-1]
elif actions.startswith("clear_actions"):
a_name = 'clear_actions'
actions = actions[len(a_name) + 1:-1]
else:
a_name = 'actions'
actions = self.cnv_list(actions, ':')
flows.append({'rules': rules, a_name: actions, })
return flows
def cnv_list(self, tmp, sep):
list_ = {}
for p in tmp.split(','):
if len(p.strip()) == 0:
continue
if p.find(sep) > 0:
name, val = p.strip().split(sep, 1)
else:
name = val = p.strip()
list_[name] = val
return list_
def cnv_txt(self, tmp, sep='='):
return ",".join([(str(x) + sep + str(tmp[x])) for x in tmp if x >= 0])
def haddr_to_str(self, addr): def haddr_to_str(self, addr):
return mac.haddr_to_str(addr) return mac.haddr_to_str(addr)