blob: 830aeed510522c666b009c2e014d4518c7f1064a [file] [log] [blame]
Dan Talayco942f5302012-04-12 22:32:34 -07001"""
2Prototype test cases related to operation under load
3
4It is recommended that these definitions be kept in their own
5namespace as different groups of tests will likely define
6similar identifiers.
7
Rich Lane477f4812012-10-04 22:49:00 -07008The switch is actively attempting to contact the controller at the address
9indicated in config.
Dan Talayco942f5302012-04-12 22:32:34 -070010
11In general these test cases make some assumption about the external
12configuration of the switch under test. For now, the assumption is
13that the first two OF ports are connected by a loopback cable.
14"""
15
16import copy
Rich Laned9ef7c32012-12-31 11:00:30 -080017import random
Dan Talayco942f5302012-04-12 22:32:34 -070018import logging
Dan Talayco942f5302012-04-12 22:32:34 -070019import unittest
20
Rich Lane477f4812012-10-04 22:49:00 -070021from oftest import config
Dan Talayco942f5302012-04-12 22:32:34 -070022import oftest.controller as controller
23import oftest.cstruct as ofp
24import oftest.message as message
25import oftest.dataplane as dataplane
26import oftest.action as action
27import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070028import oftest.base_tests as base_tests
Dan Talayco942f5302012-04-12 22:32:34 -070029import time
30
Rich Laneda3b5ad2012-10-03 09:05:32 -070031from oftest.testutils import *
Dan Talayco942f5302012-04-12 22:32:34 -070032
Rich Lane0a4f6372013-01-02 14:40:22 -080033@nonstandard
Rich Laneb90a1c42012-10-05 09:16:05 -070034class LoadBarrier(base_tests.SimpleProtocol):
Dan Talayco942f5302012-04-12 22:32:34 -070035 """
36 Test barrier under load with loopback
37
38 This test assumes there is a pair of ports on the switch with
39 a loopback cable connected and that spanning tree is disabled.
40 A flow is installed to cause a storm of packet-in messages
41 when a packet is sent to the loopbacked interface. After causing
42 this storm, a barrier request is sent.
43
44 The test succeeds if the barrier response is received. Otherwise
45 the test fails.
46 """
Rich Laned1d9c282012-10-04 22:07:10 -070047
Dan Talayco942f5302012-04-12 22:32:34 -070048 def runTest(self):
49 # Set up flow to send from port 1 to port 2 and copy to CPU
50 # Test parameter gives LB port base (assumes consecutive)
Rich Lane2014f9b2012-10-05 15:29:40 -070051 lb_port = test_param_get('lb_port', default=1)
52 barrier_count = test_param_get('barrier_count',
Dan Talayco942f5302012-04-12 22:32:34 -070053 default=10)
54
55 # Set controller to filter packet ins
56 self.controller.filter_packet_in = True
57 self.controller.pkt_in_filter_limit = 10
58
59 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -070060 match = packet_to_flow_match(self, pkt)
Dan Talayco942f5302012-04-12 22:32:34 -070061 match.wildcards &= ~ofp.OFPFW_IN_PORT
62 match.in_port = lb_port
63 act = action.action_output()
64 act.port = lb_port + 1
65
66 request = message.flow_mod()
67 request.match = match
68 request.hard_timeout = 2 * barrier_count
69
70 request.buffer_id = 0xffffffff
Rich Lanee30455b2013-01-03 16:24:44 -080071 request.actions.add(act)
Dan Talayco942f5302012-04-12 22:32:34 -070072
73 act = action.action_output()
74 act.port = ofp.OFPP_CONTROLLER
Rich Lanee30455b2013-01-03 16:24:44 -080075 request.actions.add(act)
Dan Talayco942f5302012-04-12 22:32:34 -070076
Rich Lane5c3151c2013-01-03 17:15:41 -080077 self.controller.message_send(request)
Rich Lane3a261d52013-01-03 17:45:08 -080078 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070079
80 # Create packet out and send to port lb_port + 1
81 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -080082 msg.in_port = lb_port
Dan Talayco942f5302012-04-12 22:32:34 -070083 msg.data = str(pkt)
84 act = action.action_output()
85 act.port = lb_port + 1
Rich Lanee30455b2013-01-03 16:24:44 -080086 msg.actions.add(act)
Rich Lane9a003812012-10-04 17:17:59 -070087 logging.info("Sleeping before starting storm")
Dan Talayco942f5302012-04-12 22:32:34 -070088 time.sleep(1) # Root causing issue with fast disconnects
Rich Lane9a003812012-10-04 17:17:59 -070089 logging.info("Sending packet out to %d" % (lb_port + 1))
Rich Lane5c3151c2013-01-03 17:15:41 -080090 self.controller.message_send(msg)
Dan Talayco942f5302012-04-12 22:32:34 -070091
92 for idx in range(0, barrier_count):
Rich Lane3a261d52013-01-03 17:45:08 -080093 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070094 # To do: Add some interesting functionality here
Rich Lane9a003812012-10-04 17:17:59 -070095 logging.info("Barrier %d completed" % idx)
Dan Talayco942f5302012-04-12 22:32:34 -070096
97 # Clear the flow table when done
Rich Lane9a003812012-10-04 17:17:59 -070098 logging.debug("Deleting all flows from switch")
Rich Lane32bf9482013-01-03 17:26:30 -080099 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700100
101class PacketInLoad(base_tests.SimpleDataPlane):
102 """
103 Generate lots of packet-in messages
104
105 Test packet-in function by sending lots of packets to the dataplane.
106 This test tracks the number of pkt-ins received but does not enforce
107 any requirements about the number received.
108 """
109 def runTest(self):
110 # Construct packet to send to dataplane
111 # Send packet to dataplane, once to each port
112 # Poll controller with expect message type packet in
113
Rich Lane32bf9482013-01-03 17:26:30 -0800114 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800115 do_barrier(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700116 out_count = 0
117 in_count = 0
118
119 of_ports = config["port_map"].keys()
120 for of_port in of_ports:
121 for pkt, pt in [
122 (simple_tcp_packet(), "simple TCP packet"),
123 (simple_tcp_packet(dl_vlan_enable=True,pktlen=108),
124 "simple tagged TCP packet"),
125 (simple_eth_packet(), "simple Ethernet packet"),
126 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
127
128 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
129 for count in range(100):
130 out_count += 1
131 self.dataplane.send(of_port, str(pkt))
Dan Talaycod0832852012-10-10 09:49:53 -0700132 while True:
Ed Swierka9e12ab2013-01-16 07:35:25 -0800133 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Dan Talaycod0832852012-10-10 09:49:53 -0700134 if not response:
135 break
136 in_count += 1
137 logging.info("PacketInLoad Sent %d. Got %d." % (out_count, in_count))
138
139
140
141class PacketOutLoad(base_tests.SimpleDataPlane):
142 """
143 Generate lots of packet-out messages
144
145 Test packet-out function by sending lots of packet-out msgs
146 to the switch. This test tracks the number of packets received in
147 the dataplane, but does not enforce any requirements about the
148 number received.
149 """
150 def runTest(self):
151 # Construct packet to send to dataplane
152 # Send packet to dataplane
153 # Poll controller with expect message type packet in
154
Rich Lane32bf9482013-01-03 17:26:30 -0800155 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700156
157 # These will get put into function
158 of_ports = config["port_map"].keys()
159 of_ports.sort()
160 out_count = 0
161 in_count = 0
162 xid = 100
163 for dp_port in of_ports:
164 for outpkt, opt in [
165 (simple_tcp_packet(), "simple TCP packet"),
166 (simple_eth_packet(), "simple Ethernet packet"),
167 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
168
169 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
170 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800171 msg.in_port = ofp.OFPP_NONE
Dan Talaycod0832852012-10-10 09:49:53 -0700172 msg.data = str(outpkt)
173 act = action.action_output()
174 act.port = dp_port
Rich Lanee30455b2013-01-03 16:24:44 -0800175 msg.actions.add(act)
Dan Talaycod0832852012-10-10 09:49:53 -0700176
177 logging.info("PacketOutLoad to: " + str(dp_port))
178 for count in range(100):
179 msg.xid = xid
180 xid += 1
Rich Lane5c3151c2013-01-03 17:15:41 -0800181 self.controller.message_send(msg)
Dan Talaycod0832852012-10-10 09:49:53 -0700182 out_count += 1
183
184 exp_pkt_arg = None
185 exp_port = None
Dan Talaycod0832852012-10-10 09:49:53 -0700186 while True:
Ed Swierka9e12ab2013-01-16 07:35:25 -0800187 (of_port, pkt, pkt_time) = self.dataplane.poll()
Dan Talaycod0832852012-10-10 09:49:53 -0700188 if pkt is None:
189 break
190 in_count += 1
191 logging.info("PacketOutLoad Sent %d. Got %d." % (out_count, in_count))
Ed Swierke6fca642012-11-30 12:00:54 -0800192
193class FlowModLoad(base_tests.SimpleProtocol):
194
195 def checkBarrier(self):
196 msg, pkt = self.controller.transact(message.barrier_request(), timeout=60)
197 self.assertNotEqual(msg, None, "Barrier failed")
198 while self.controller.packets:
199 msg = self.controller.packets.pop(0)[0]
200 self.assertNotEqual(msg.header.type, message.OFPT_ERROR,
201 "Error received")
202
203 def runTest(self):
204 msg, pkt = self.controller.transact(message.table_stats_request())
Rich Lane30ca70c2012-12-31 16:53:55 -0800205
206 # Some switches report an extremely high max_entries that would cause
207 # us to run out of memory attempting to create all the flow-mods.
208 num_flows = min(msg.stats[0].max_entries, 32678)
209
210 logging.info("Creating %d flow-mods messages", num_flows)
Ed Swierke6fca642012-11-30 12:00:54 -0800211
212 requests = []
213 for i in range(num_flows):
214 match = ofp.ofp_match()
215 match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST
216 match.dl_vlan = ofp.OFP_VLAN_NONE
217 match.dl_dst = [0, 1, 2, 3, i / 256, i % 256]
218 act = action.action_output()
219 act.port = ofp.OFPP_CONTROLLER
220 request = message.flow_mod()
221 request.command = ofp.OFPFC_ADD
222 request.buffer_id = 0xffffffff
223 request.priority = num_flows - i
224 request.out_port = ofp.OFPP_NONE
225 request.match = match
226 request.actions.add(act)
227 requests.append(request)
228
Rich Lane82c35e82012-12-31 10:59:36 -0800229 for i in range(3):
Ed Swierke6fca642012-11-30 12:00:54 -0800230 logging.info("Iteration %d: delete all flows" % i)
Rich Lane32bf9482013-01-03 17:26:30 -0800231 delete_all_flows(self.controller)
Ed Swierke6fca642012-11-30 12:00:54 -0800232 self.checkBarrier()
233
234 logging.info("Iteration %d: add %s flows" % (i, num_flows))
Rich Laned9ef7c32012-12-31 11:00:30 -0800235 random.shuffle(requests)
Ed Swierke6fca642012-11-30 12:00:54 -0800236 for request in requests:
237 self.assertNotEqual(self.controller.message_send(request), -1,
238 "Error installing flow mod")
239 self.checkBarrier()