blob: 0ad14e9cac450327394bcfa642be2bc5f22c0089 [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))
132 time.sleep(2)
133 while True:
134 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,
135 timeout=0)
136 if not response:
137 break
138 in_count += 1
139 logging.info("PacketInLoad Sent %d. Got %d." % (out_count, in_count))
140
141
142
143class PacketOutLoad(base_tests.SimpleDataPlane):
144 """
145 Generate lots of packet-out messages
146
147 Test packet-out function by sending lots of packet-out msgs
148 to the switch. This test tracks the number of packets received in
149 the dataplane, but does not enforce any requirements about the
150 number received.
151 """
152 def runTest(self):
153 # Construct packet to send to dataplane
154 # Send packet to dataplane
155 # Poll controller with expect message type packet in
156
Rich Lane32bf9482013-01-03 17:26:30 -0800157 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700158
159 # These will get put into function
160 of_ports = config["port_map"].keys()
161 of_ports.sort()
162 out_count = 0
163 in_count = 0
164 xid = 100
165 for dp_port in of_ports:
166 for outpkt, opt in [
167 (simple_tcp_packet(), "simple TCP packet"),
168 (simple_eth_packet(), "simple Ethernet packet"),
169 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
170
171 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
172 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800173 msg.in_port = ofp.OFPP_NONE
Dan Talaycod0832852012-10-10 09:49:53 -0700174 msg.data = str(outpkt)
175 act = action.action_output()
176 act.port = dp_port
Rich Lanee30455b2013-01-03 16:24:44 -0800177 msg.actions.add(act)
Dan Talaycod0832852012-10-10 09:49:53 -0700178
179 logging.info("PacketOutLoad to: " + str(dp_port))
180 for count in range(100):
181 msg.xid = xid
182 xid += 1
Rich Lane5c3151c2013-01-03 17:15:41 -0800183 self.controller.message_send(msg)
Dan Talaycod0832852012-10-10 09:49:53 -0700184 out_count += 1
185
186 exp_pkt_arg = None
187 exp_port = None
188 time.sleep(2)
189 while True:
190 (of_port, pkt, pkt_time) = self.dataplane.poll(timeout=0)
191 if pkt is None:
192 break
193 in_count += 1
194 logging.info("PacketOutLoad Sent %d. Got %d." % (out_count, in_count))
Ed Swierke6fca642012-11-30 12:00:54 -0800195
196class FlowModLoad(base_tests.SimpleProtocol):
197
198 def checkBarrier(self):
199 msg, pkt = self.controller.transact(message.barrier_request(), timeout=60)
200 self.assertNotEqual(msg, None, "Barrier failed")
201 while self.controller.packets:
202 msg = self.controller.packets.pop(0)[0]
203 self.assertNotEqual(msg.header.type, message.OFPT_ERROR,
204 "Error received")
205
206 def runTest(self):
207 msg, pkt = self.controller.transact(message.table_stats_request())
Rich Lane30ca70c2012-12-31 16:53:55 -0800208
209 # Some switches report an extremely high max_entries that would cause
210 # us to run out of memory attempting to create all the flow-mods.
211 num_flows = min(msg.stats[0].max_entries, 32678)
212
213 logging.info("Creating %d flow-mods messages", num_flows)
Ed Swierke6fca642012-11-30 12:00:54 -0800214
215 requests = []
216 for i in range(num_flows):
217 match = ofp.ofp_match()
218 match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST
219 match.dl_vlan = ofp.OFP_VLAN_NONE
220 match.dl_dst = [0, 1, 2, 3, i / 256, i % 256]
221 act = action.action_output()
222 act.port = ofp.OFPP_CONTROLLER
223 request = message.flow_mod()
224 request.command = ofp.OFPFC_ADD
225 request.buffer_id = 0xffffffff
226 request.priority = num_flows - i
227 request.out_port = ofp.OFPP_NONE
228 request.match = match
229 request.actions.add(act)
230 requests.append(request)
231
Rich Lane82c35e82012-12-31 10:59:36 -0800232 for i in range(3):
Ed Swierke6fca642012-11-30 12:00:54 -0800233 logging.info("Iteration %d: delete all flows" % i)
Rich Lane32bf9482013-01-03 17:26:30 -0800234 delete_all_flows(self.controller)
Ed Swierke6fca642012-11-30 12:00:54 -0800235 self.checkBarrier()
236
237 logging.info("Iteration %d: add %s flows" % (i, num_flows))
Rich Laned9ef7c32012-12-31 11:00:30 -0800238 random.shuffle(requests)
Ed Swierke6fca642012-11-30 12:00:54 -0800239 for request in requests:
240 self.assertNotEqual(self.controller.message_send(request), -1,
241 "Error installing flow mod")
242 self.checkBarrier()