diff options
author | Minoru TAKAHASHI <takahashi.minoru7@gmail.com> | 2016-05-10 14:29:48 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2016-05-13 22:26:13 +0900 |
commit | e30eebbc42a68521aa927075cf4a7da3c29953bc (patch) | |
tree | 05e42d212ec2a949c49c53ff7406b1497ba77357 | |
parent | 4bec6aca3d4b8201cc21296ff47448fce4580689 (diff) |
test_ofctl_rest: Add unit tests for ofctl_rest
Signed-off-by: Minoru TAKAHASHI <takahashi.minoru7@gmail.com>
Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/tests/unit/app/ofctl_rest_json/of10.json | 101 | ||||
-rw-r--r-- | ryu/tests/unit/app/ofctl_rest_json/of12.json | 150 | ||||
-rw-r--r-- | ryu/tests/unit/app/ofctl_rest_json/of13.json | 191 | ||||
-rw-r--r-- | ryu/tests/unit/app/ofctl_rest_json/of14.json | 195 | ||||
-rw-r--r-- | ryu/tests/unit/app/ofctl_rest_json/of15.json | 203 | ||||
-rw-r--r-- | ryu/tests/unit/app/test_ofctl_rest.py | 137 |
6 files changed, 977 insertions, 0 deletions
diff --git a/ryu/tests/unit/app/ofctl_rest_json/of10.json b/ryu/tests/unit/app/ofctl_rest_json/of10.json new file mode 100644 index 00000000..266eb80c --- /dev/null +++ b/ryu/tests/unit/app/ofctl_rest_json/of10.json @@ -0,0 +1,101 @@ +[ + { + "method": "GET", + "path": "/stats/switches" + }, + { + "method": "GET", + "path": "/stats/desc/1" + }, + { + "method": "GET", + "path": "/stats/flow/1" + }, + { + "method": "POST", + "path": "/stats/flow/1" + }, + { + "method": "GET", + "path": "/stats/aggregateflow/1" + }, + { + "method": "POST", + "path": "/stats/aggregateflow/1" + }, + { + "method": "GET", + "path": "/stats/port/1" + }, + { + "method": "GET", + "path": "/stats/port/1/1" + }, + { + "method": "GET", + "path": "/stats/portdesc/1" + }, + { + "method": "GET", + "path": "/stats/queue/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1/1" + }, + { + "method": "GET", + "path": "/stats/table/1" + }, + { + "method": "POST", + "path": "/stats/flowentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "DELETE", + "path": "/stats/flowentry/clear/1" + }, + { + "method": "POST", + "path": "/stats/portdesc/modify", + "body": { + "dpid": 1, + "port_no": 1 + } + } +] diff --git a/ryu/tests/unit/app/ofctl_rest_json/of12.json b/ryu/tests/unit/app/ofctl_rest_json/of12.json new file mode 100644 index 00000000..89a81919 --- /dev/null +++ b/ryu/tests/unit/app/ofctl_rest_json/of12.json @@ -0,0 +1,150 @@ +[ + { + "method": "GET", + "path": "/stats/switches" + }, + { + "method": "GET", + "path": "/stats/desc/1" + }, + { + "method": "GET", + "path": "/stats/flow/1" + }, + { + "method": "POST", + "path": "/stats/flow/1" + }, + { + "method": "GET", + "path": "/stats/aggregateflow/1" + }, + { + "method": "POST", + "path": "/stats/aggregateflow/1" + }, + { + "method": "GET", + "path": "/stats/port/1" + }, + { + "method": "GET", + "path": "/stats/port/1/1" + }, + { + "method": "GET", + "path": "/stats/portdesc/1" + }, + { + "method": "GET", + "path": "/stats/queue/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1/1" + }, + { + "method": "GET", + "path": "/stats/queueconfig/1" + }, + { + "method": "GET", + "path": "/stats/queueconfig/1/1" + }, + { + "method": "GET", + "path": "/stats/group/1" + }, + { + "method": "GET", + "path": "/stats/group/1/1" + }, + { + "method": "GET", + "path": "/stats/groupdesc/1" + }, + { + "method": "GET", + "path": "/stats/groupfeatures/1" + }, + { + "method": "GET", + "path": "/stats/table/1" + }, + { + "method": "POST", + "path": "/stats/flowentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "DELETE", + "path": "/stats/flowentry/clear/1" + }, + { + "method": "POST", + "path": "/stats/groupentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/portdesc/modify", + "body": { + "dpid": 1, + "port_no": 1 + } + }, + { + "method": "POST", + "path": "/stats/experimenter/1" + } +] diff --git a/ryu/tests/unit/app/ofctl_rest_json/of13.json b/ryu/tests/unit/app/ofctl_rest_json/of13.json new file mode 100644 index 00000000..d515f628 --- /dev/null +++ b/ryu/tests/unit/app/ofctl_rest_json/of13.json @@ -0,0 +1,191 @@ +[ + { + "method": "GET", + "path": "/stats/switches" + }, + { + "method": "GET", + "path": "/stats/desc/1" + }, + { + "method": "GET", + "path": "/stats/flow/1" + }, + { + "method": "POST", + "path": "/stats/flow/1" + }, + { + "method": "GET", + "path": "/stats/aggregateflow/1" + }, + { + "method": "POST", + "path": "/stats/aggregateflow/1" + }, + { + "method": "GET", + "path": "/stats/port/1" + }, + { + "method": "GET", + "path": "/stats/port/1/1" + }, + { + "method": "GET", + "path": "/stats/portdesc/1" + }, + { + "method": "GET", + "path": "/stats/queue/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1/1" + }, + { + "method": "GET", + "path": "/stats/queueconfig/1" + }, + { + "method": "GET", + "path": "/stats/queueconfig/1/1" + }, + { + "method": "GET", + "path": "/stats/group/1" + }, + { + "method": "GET", + "path": "/stats/group/1/1" + }, + { + "method": "GET", + "path": "/stats/groupdesc/1" + }, + { + "method": "GET", + "path": "/stats/groupfeatures/1" + }, + { + "method": "GET", + "path": "/stats/meter/1" + }, + { + "method": "GET", + "path": "/stats/meter/1/1" + }, + { + "method": "GET", + "path": "/stats/meterconfig/1" + }, + { + "method": "GET", + "path": "/stats/meterconfig/1/1" + }, + { + "method": "GET", + "path": "/stats/meterfeatures/1" + }, + { + "method": "GET", + "path": "/stats/table/1" + }, + { + "method": "POST", + "path": "/stats/flowentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "DELETE", + "path": "/stats/flowentry/clear/1" + }, + { + "method": "POST", + "path": "/stats/groupentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/portdesc/modify", + "body": { + "dpid": 1, + "port_no": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/experimenter/1" + } +] diff --git a/ryu/tests/unit/app/ofctl_rest_json/of14.json b/ryu/tests/unit/app/ofctl_rest_json/of14.json new file mode 100644 index 00000000..0cc4eb6c --- /dev/null +++ b/ryu/tests/unit/app/ofctl_rest_json/of14.json @@ -0,0 +1,195 @@ +[ + { + "method": "GET", + "path": "/stats/switches" + }, + { + "method": "GET", + "path": "/stats/desc/1" + }, + { + "method": "GET", + "path": "/stats/flow/1" + }, + { + "method": "POST", + "path": "/stats/flow/1" + }, + { + "method": "GET", + "path": "/stats/aggregateflow/1" + }, + { + "method": "POST", + "path": "/stats/aggregateflow/1" + }, + { + "method": "GET", + "path": "/stats/port/1" + }, + { + "method": "GET", + "path": "/stats/port/1/1" + }, + { + "method": "GET", + "path": "/stats/portdesc/1" + }, + { + "method": "GET", + "path": "/stats/queue/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1/1" + }, + { + "method": "GET", + "path": "/stats/queuedesc/1" + }, + { + "method": "GET", + "path": "/stats/queuedesc/1/1" + }, + { + "method": "GET", + "path": "/stats/queuedesc/1/1/1" + }, + { + "method": "GET", + "path": "/stats/group/1" + }, + { + "method": "GET", + "path": "/stats/group/1/1" + }, + { + "method": "GET", + "path": "/stats/groupdesc/1" + }, + { + "method": "GET", + "path": "/stats/groupfeatures/1" + }, + { + "method": "GET", + "path": "/stats/meter/1" + }, + { + "method": "GET", + "path": "/stats/meter/1/1" + }, + { + "method": "GET", + "path": "/stats/meterconfig/1" + }, + { + "method": "GET", + "path": "/stats/meterconfig/1/1" + }, + { + "method": "GET", + "path": "/stats/meterfeatures/1" + }, + { + "method": "GET", + "path": "/stats/table/1" + }, + { + "method": "POST", + "path": "/stats/flowentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "DELETE", + "path": "/stats/flowentry/clear/1" + }, + { + "method": "POST", + "path": "/stats/groupentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/portdesc/modify", + "body": { + "dpid": 1, + "port_no": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/experimenter/1" + } +] diff --git a/ryu/tests/unit/app/ofctl_rest_json/of15.json b/ryu/tests/unit/app/ofctl_rest_json/of15.json new file mode 100644 index 00000000..a7569223 --- /dev/null +++ b/ryu/tests/unit/app/ofctl_rest_json/of15.json @@ -0,0 +1,203 @@ +[ + { + "method": "GET", + "path": "/stats/switches" + }, + { + "method": "GET", + "path": "/stats/desc/1" + }, + { + "method": "GET", + "path": "/stats/flow/1" + }, + { + "method": "POST", + "path": "/stats/flow/1" + }, + { + "method": "GET", + "path": "/stats/aggregateflow/1" + }, + { + "method": "POST", + "path": "/stats/aggregateflow/1" + }, + { + "method": "GET", + "path": "/stats/port/1" + }, + { + "method": "GET", + "path": "/stats/port/1/1" + }, + { + "method": "GET", + "path": "/stats/portdesc/1" + }, + { + "method": "GET", + "path": "/stats/portdesc/1/1" + }, + { + "method": "GET", + "path": "/stats/queue/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1" + }, + { + "method": "GET", + "path": "/stats/queue/1/1/1" + }, + { + "method": "GET", + "path": "/stats/queuedesc/1" + }, + { + "method": "GET", + "path": "/stats/queuedesc/1/1" + }, + { + "method": "GET", + "path": "/stats/queuedesc/1/1/1" + }, + { + "method": "GET", + "path": "/stats/group/1" + }, + { + "method": "GET", + "path": "/stats/group/1/1" + }, + { + "method": "GET", + "path": "/stats/groupdesc/1" + }, + { + "method": "GET", + "path": "/stats/groupdesc/1/1" + }, + { + "method": "GET", + "path": "/stats/groupfeatures/1" + }, + { + "method": "GET", + "path": "/stats/meter/1" + }, + { + "method": "GET", + "path": "/stats/meter/1/1" + }, + { + "method": "GET", + "path": "/stats/meterdesc/1" + }, + { + "method": "GET", + "path": "/stats/meterdesc/1/1" + }, + { + "method": "GET", + "path": "/stats/meterfeatures/1" + }, + { + "method": "GET", + "path": "/stats/table/1" + }, + { + "method": "POST", + "path": "/stats/flowentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/modify_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/flowentry/delete_strict", + "body": { + "dpid": 1 + } + }, + { + "method": "DELETE", + "path": "/stats/flowentry/clear/1" + }, + { + "method": "POST", + "path": "/stats/groupentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/groupentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/portdesc/modify", + "body": { + "dpid": 1, + "port_no": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/add", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/modify", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/meterentry/delete", + "body": { + "dpid": 1 + } + }, + { + "method": "POST", + "path": "/stats/experimenter/1" + } +] diff --git a/ryu/tests/unit/app/test_ofctl_rest.py b/ryu/tests/unit/app/test_ofctl_rest.py new file mode 100644 index 00000000..095924ad --- /dev/null +++ b/ryu/tests/unit/app/test_ofctl_rest.py @@ -0,0 +1,137 @@ +# Copyright (C) 2016 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 functools +import json +import logging +from nose.tools import eq_ +import os +import sys +import unittest +from webob.request import Request +try: + import mock # Python 2 +except ImportError: + from unittest import mock # Python 3 + +from ryu.app import ofctl_rest +from ryu.app.wsgi import WSGIApplication +from ryu.controller.dpset import DPSet +from ryu.ofproto import ofproto_protocol +from ryu.ofproto import ofproto_v1_0 +from ryu.ofproto import ofproto_v1_2 +from ryu.ofproto import ofproto_v1_3 +from ryu.ofproto import ofproto_v1_4 +from ryu.ofproto import ofproto_v1_5 +from ryu.tests import test_lib + + +LOG = logging.getLogger(__name__) + + +class DummyDatapath(ofproto_protocol.ProtocolDesc): + + def __init__(self, version): + super(DummyDatapath, self).__init__(version) + self.id = 1 + _kw = {'port_no': 1, 'hw_addr': 'aa:bb:cc:dd:ee:ff', + 'name': 's1-eth1', 'config': 1, 'state': 1} + # for OpenFlow 1.0 + if version in [ofproto_v1_0.OFP_VERSION]: + _kw.update( + {'curr': 2112, 'advertised': 0, 'supported': 0, 'peer': 0}) + port_info = self.ofproto_parser.OFPPhyPort(**_kw) + # for OpenFlow 1.2 or 1.3 + elif version in [ofproto_v1_2.OFP_VERSION, ofproto_v1_3.OFP_VERSION]: + _kw.update( + {'curr': 2112, 'advertised': 0, 'supported': 0, 'peer': 0, + 'curr_speed': 10000000, 'max_speed': 0}) + port_info = self.ofproto_parser.OFPPort(**_kw) + # for OpenFlow 1.4+ + else: + _kw.update({'properties': []}) + port_info = self.ofproto_parser.OFPPort(**_kw) + self.ports = {1: port_info} + + +class Test_ofctl_rest(unittest.TestCase): + + def _test(self, name, dp, method, path, body): + print('processing %s ...' % name) + + dpset = DPSet() + dpset._register(dp) + wsgi = WSGIApplication() + contexts = { + 'dpset': dpset, + 'wsgi': wsgi, + } + ofctl_rest.RestStatsApi(**contexts) + + req = Request.blank(path) + req.body = json.dumps(body).encode('utf-8') + req.method = method + + with mock.patch('ryu.lib.ofctl_utils.send_stats_request'),\ + mock.patch('ryu.lib.ofctl_utils.send_msg'): + res = req.get_response(wsgi) + eq_(res.status, '200 OK') + + +def _add_tests(): + _ofp_vers = { + 'of10': ofproto_v1_0.OFP_VERSION, + 'of12': ofproto_v1_2.OFP_VERSION, + 'of13': ofproto_v1_3.OFP_VERSION, + 'of14': ofproto_v1_4.OFP_VERSION, + 'of15': ofproto_v1_5.OFP_VERSION, + } + + this_dir = os.path.dirname(sys.modules[__name__].__file__) + ofctl_rest_json_dir = os.path.join(this_dir, 'ofctl_rest_json/') + + for ofp_ver in _ofp_vers.keys(): + # read a json file + json_path = os.path.join(ofctl_rest_json_dir, ofp_ver + '.json') + if os.path.exists(json_path): + _test_cases = json.load(open(json_path)) + else: + print("Skip to load test cases for %s" % ofp_ver) + continue + + # add test + for test in _test_cases: + method = test['method'] + path = test['path'] + body = test.get('body', {}) + + name = 'test_ofctl_rest_' + method + '_' + ofp_ver + '_' + path + print('adding %s ...' % name) + f = functools.partial( + Test_ofctl_rest._test, + name=name, + dp=DummyDatapath(_ofp_vers[ofp_ver]), + method=test['method'], + path=test['path'], + body=body + ) + test_lib.add_method(Test_ofctl_rest, name, f) + +_add_tests() + +if __name__ == "__main__": + unittest.main() |