diff options
author | Yuichi Ito <ito.yuichi0@gmail.com> | 2014-03-28 13:25:25 +0900 |
---|---|---|
committer | FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> | 2014-03-30 10:43:29 +0900 |
commit | 7e84cfac08bfb549648d7f23d4a4183ef77ac3bb (patch) | |
tree | 23430ee36e644cf121e58e515bf2df52dfb88dd2 | |
parent | 1ff8957d70a95919c2a1b130c21124afbc075bb2 (diff) |
sw test tool: Add support for throughput analysis
Signed-off-by: WATANABE Fumitaka <watanabe.fumitaka1@gmail.com>
Signed-off-by: Yuichi Ito <ito.yuichi0@gmail.com>
Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
-rw-r--r-- | ryu/tests/switch/tester.py | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/ryu/tests/switch/tester.py b/ryu/tests/switch/tester.py index 0e172a40..631412ad 100644 --- a/ryu/tests/switch/tester.py +++ b/ryu/tests/switch/tester.py @@ -16,6 +16,7 @@ import inspect import json import logging +import math import os import signal import sys @@ -86,6 +87,7 @@ CONTINUOUS_THREAD_INTVL = float(0.01) # sec CONTINUOUS_PROGRESS_SPAN = 3 # sec THROUGHPUT_PRIORITY = ofproto_v1_3.OFP_DEFAULT_PRIORITY+1 THROUGHPUT_COOKIE = THROUGHPUT_PRIORITY +THROUGHPUT_THRESHOLD = float(0.10) # expected throughput plus/minus 10 % # Default settings for 'ingress: packets' DEFAULT_DURATION_TIME = 30 @@ -127,6 +129,7 @@ STATE_INIT_THROUGHPUT_FLOW = 13 STATE_THROUGHPUT_FLOW_INSTALL = 14 STATE_THROUGHPUT_FLOW_EXIST_CHK = 15 STATE_GET_THROUGHPUT = 16 +STATE_THROUGHPUT_CHK = 17 STATE_DISCONNECTED = 99 @@ -200,6 +203,8 @@ MSG = {STATE_INIT_FLOW: STATE_GET_THROUGHPUT: {TIMEOUT: 'Failed to request flow stats: request timeout.', RCV_ERR: 'Failed to request flow stats: %(err_msg)s'}, + STATE_THROUGHPUT_CHK: + {FAILURE: 'Received unexpected throughput: %(detail)s'}, STATE_DISCONNECTED: {ERROR: 'Disconnected from switch'}} @@ -500,7 +505,8 @@ class OfTester(app_manager.RyuApp): STATE_GET_MATCH_COUNT: self._test_get_match_count, STATE_SEND_BARRIER: self._test_send_barrier, STATE_FLOW_UNMATCH_CHK: self._test_flow_unmatching_check, - STATE_GET_THROUGHPUT: self._test_get_throughput} + STATE_GET_THROUGHPUT: self._test_get_throughput, + STATE_THROUGHPUT_CHK: self._test_throughput_check} self.send_msg_xids = [] self.rcv_msgs = [] @@ -858,6 +864,47 @@ class OfTester(app_manager.RyuApp): result[str(stat.match)] = (stat.byte_count, stat.packet_count) return (time.time(), result) + def _test_throughput_check(self, throughputs, start, end): + msgs = [] + elapsed_sec = end[0] - start[0] + + for throughput in throughputs: + match = str(throughput[KEY_FLOW].match) + # get oxm_fields of OFPMatch + fields = dict(throughput[KEY_FLOW].match._fields2) + + if match not in start[1] or match not in end[1]: + raise TestError(self.state, match=match) + increased_bytes = end[1][match][0] - start[1][match][0] + increased_packets = end[1][match][1] - start[1][match][1] + + if throughput[KEY_PKTPS]: + key = KEY_PKTPS + conv = 1 + measured_value = increased_packets + unit = 'pktps' + elif throughput[KEY_KBPS]: + key = KEY_KBPS + conv = 1024 / 8 # Kilobits -> bytes + measured_value = increased_bytes + unit = 'kbps' + else: + raise RyuException( + 'An invalid key exists that is neither "%s" nor "%s".' + % (KEY_KBPS, KEY_PKTPS)) + + expected_value = throughput[key] * elapsed_sec * conv + margin = expected_value * THROUGHPUT_THRESHOLD + self.logger.debug("measured_value:[%s]", measured_value) + self.logger.debug("expected_value:[%s]", expected_value) + self.logger.debug("margin:[%s]", margin) + if math.fabs(measured_value - expected_value) > margin: + msgs.append('{0} {1:.2f}{2}'.format(fields, + measured_value / elapsed_sec / conv, unit)) + + if msgs: + raise TestFailure(self.state, detail=', '.join(msgs)) + def _wait(self): """ Wait until specific OFP message received or timer is exceeded. """ |