blob: 48567db49f56b8e022b82db6249fa5c164cb5790 [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Rich Lane0f4c77c2014-03-23 16:02:56 -070017"""
18Latency tests
19
20These tests are mostly helpful for finding an optimal value for the
21--default-negative-timeout option. If this value is too large it will
22unnecessarily some down testing, but if it is too small then tests
23may pass when they should have failed.
24
25Most of this latency is caused by OFTest. Actual switch latency should be just
26a few microseconds, but OFTest can add milliseconds on top of that.
27"""
28
29import logging
30import unittest
31import time
32
33from oftest import config
34import ofp
35import oftest.base_tests as base_tests
36
37from oftest.testutils import *
38
39class DataplaneLatency(base_tests.SimpleDataPlane):
40 """
41 Measure and assert dataplane latency
42
43 All packets must arrive within the default timeout, and 90% must
44 arrive within the default negative timeout.
45 """
46 def runTest(self):
47 in_port, out_port = openflow_ports(2)
48
49 delete_all_flows(self.controller)
50
51 pkt = str(simple_tcp_packet())
52
53 request = ofp.message.flow_add(
54 match=ofp.match(wildcards=ofp.OFPFW_ALL),
55 buffer_id=0xffffffff,
56 actions=[ofp.action.output(out_port)])
57
58 self.controller.message_send(request)
59 do_barrier(self.controller)
60
61 latencies = []
62 for i in xrange(0, 1000):
63 start_time = time.time()
64 self.dataplane.send(in_port, pkt)
65 verify_packet(self, pkt, out_port)
66 end_time = time.time()
67 latencies.append(end_time - start_time)
68
69 latencies.sort()
70
71 latency_min = latencies[0]
72 latency_90 = latencies[int(len(latencies)*0.9)]
73 latency_max = latencies[-1]
74
75 logging.debug("Minimum latency: %f ms", latency_min * 1000.0)
76 logging.debug("90%% latency: %f ms", latency_90 * 1000.0)
77 logging.debug("Maximum latency: %f ms", latency_max * 1000.0)
78
79 self.assertGreater(config["default_timeout"], latency_max)
80 self.assertGreater(config["default_negative_timeout"], latency_90)
81
82class PktinLatency(base_tests.SimpleDataPlane):
83 """
84 Measure and assert packet-in latency
85
86 All packet-ins must arrive within the default timeout, and 90% must
87 arrive within the default negative timeout.
88 """
89 def runTest(self):
90 in_port, = openflow_ports(1)
91
92 delete_all_flows(self.controller)
93
94 pkt = str(simple_tcp_packet())
95
96 request = ofp.message.flow_add(
97 match=ofp.match(wildcards=ofp.OFPFW_ALL),
98 buffer_id=0xffffffff,
99 actions=[ofp.action.output(ofp.OFPP_CONTROLLER)])
100
101 self.controller.message_send(request)
102 do_barrier(self.controller)
103
104 latencies = []
105 for i in xrange(0, 1000):
106 start_time = time.time()
107 self.dataplane.send(in_port, pkt)
108 verify_packet_in(self, pkt, in_port, ofp.OFPR_ACTION)
109 end_time = time.time()
110 latencies.append(end_time - start_time)
111
112 latencies.sort()
113
114 latency_min = latencies[0]
115 latency_90 = latencies[int(len(latencies)*0.9)]
116 latency_max = latencies[-1]
117
118 logging.debug("Minimum latency: %f ms", latency_min * 1000.0)
119 logging.debug("90%% latency: %f ms", latency_90 * 1000.0)
120 logging.debug("Maximum latency: %f ms", latency_max * 1000.0)
121
122 self.assertGreater(config["default_timeout"], latency_max)
123 self.assertGreater(config["default_negative_timeout"], latency_90)