summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYuichi Ito <ito.yuichi0@gmail.com>2014-03-28 13:25:25 +0900
committerFUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>2014-03-30 10:43:29 +0900
commit7e84cfac08bfb549648d7f23d4a4183ef77ac3bb (patch)
tree23430ee36e644cf121e58e515bf2df52dfb88dd2
parent1ff8957d70a95919c2a1b130c21124afbc075bb2 (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.py49
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. """