blob: 9977027dbcb1c55adfd6965b2ca6271a3ed6c93e [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 Laneb90a1c42012-10-05 09:16:05 -070033class LoadBarrier(base_tests.SimpleProtocol):
Dan Talayco942f5302012-04-12 22:32:34 -070034 """
35 Test barrier under load with loopback
36
37 This test assumes there is a pair of ports on the switch with
38 a loopback cable connected and that spanning tree is disabled.
39 A flow is installed to cause a storm of packet-in messages
40 when a packet is sent to the loopbacked interface. After causing
41 this storm, a barrier request is sent.
42
43 The test succeeds if the barrier response is received. Otherwise
44 the test fails.
45 """
Rich Laned1d9c282012-10-04 22:07:10 -070046
47 priority = -1
48
Dan Talayco942f5302012-04-12 22:32:34 -070049 def runTest(self):
50 # Set up flow to send from port 1 to port 2 and copy to CPU
51 # Test parameter gives LB port base (assumes consecutive)
Rich Lane2014f9b2012-10-05 15:29:40 -070052 lb_port = test_param_get('lb_port', default=1)
53 barrier_count = test_param_get('barrier_count',
Dan Talayco942f5302012-04-12 22:32:34 -070054 default=10)
55
56 # Set controller to filter packet ins
57 self.controller.filter_packet_in = True
58 self.controller.pkt_in_filter_limit = 10
59
60 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -070061 match = packet_to_flow_match(self, pkt)
Dan Talayco942f5302012-04-12 22:32:34 -070062 match.wildcards &= ~ofp.OFPFW_IN_PORT
63 match.in_port = lb_port
64 act = action.action_output()
65 act.port = lb_port + 1
66
67 request = message.flow_mod()
68 request.match = match
69 request.hard_timeout = 2 * barrier_count
70
71 request.buffer_id = 0xffffffff
Rich Lanee30455b2013-01-03 16:24:44 -080072 request.actions.add(act)
Dan Talayco942f5302012-04-12 22:32:34 -070073
74 act = action.action_output()
75 act.port = ofp.OFPP_CONTROLLER
Rich Lanee30455b2013-01-03 16:24:44 -080076 request.actions.add(act)
Dan Talayco942f5302012-04-12 22:32:34 -070077
Rich Lane5c3151c2013-01-03 17:15:41 -080078 self.controller.message_send(request)
Rich Lane3a261d52013-01-03 17:45:08 -080079 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070080
81 # Create packet out and send to port lb_port + 1
82 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -080083 msg.in_port = lb_port
Dan Talayco942f5302012-04-12 22:32:34 -070084 msg.data = str(pkt)
85 act = action.action_output()
86 act.port = lb_port + 1
Rich Lanee30455b2013-01-03 16:24:44 -080087 msg.actions.add(act)
Rich Lane9a003812012-10-04 17:17:59 -070088 logging.info("Sleeping before starting storm")
Dan Talayco942f5302012-04-12 22:32:34 -070089 time.sleep(1) # Root causing issue with fast disconnects
Rich Lane9a003812012-10-04 17:17:59 -070090 logging.info("Sending packet out to %d" % (lb_port + 1))
Rich Lane5c3151c2013-01-03 17:15:41 -080091 self.controller.message_send(msg)
Dan Talayco942f5302012-04-12 22:32:34 -070092
93 for idx in range(0, barrier_count):
Rich Lane3a261d52013-01-03 17:45:08 -080094 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070095 # To do: Add some interesting functionality here
Rich Lane9a003812012-10-04 17:17:59 -070096 logging.info("Barrier %d completed" % idx)
Dan Talayco942f5302012-04-12 22:32:34 -070097
98 # Clear the flow table when done
Rich Lane9a003812012-10-04 17:17:59 -070099 logging.debug("Deleting all flows from switch")
Rich Lane32bf9482013-01-03 17:26:30 -0800100 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700101
102class PacketInLoad(base_tests.SimpleDataPlane):
103 """
104 Generate lots of packet-in messages
105
106 Test packet-in function by sending lots of packets to the dataplane.
107 This test tracks the number of pkt-ins received but does not enforce
108 any requirements about the number received.
109 """
110 def runTest(self):
111 # Construct packet to send to dataplane
112 # Send packet to dataplane, once to each port
113 # Poll controller with expect message type packet in
114
Rich Lane32bf9482013-01-03 17:26:30 -0800115 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800116 do_barrier(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700117 out_count = 0
118 in_count = 0
119
120 of_ports = config["port_map"].keys()
121 for of_port in of_ports:
122 for pkt, pt in [
123 (simple_tcp_packet(), "simple TCP packet"),
124 (simple_tcp_packet(dl_vlan_enable=True,pktlen=108),
125 "simple tagged TCP packet"),
126 (simple_eth_packet(), "simple Ethernet packet"),
127 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
128
129 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
130 for count in range(100):
131 out_count += 1
132 self.dataplane.send(of_port, str(pkt))
133 time.sleep(2)
134 while True:
135 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,
136 timeout=0)
137 if not response:
138 break
139 in_count += 1
140 logging.info("PacketInLoad Sent %d. Got %d." % (out_count, in_count))
141
142
143
144class PacketOutLoad(base_tests.SimpleDataPlane):
145 """
146 Generate lots of packet-out messages
147
148 Test packet-out function by sending lots of packet-out msgs
149 to the switch. This test tracks the number of packets received in
150 the dataplane, but does not enforce any requirements about the
151 number received.
152 """
153 def runTest(self):
154 # Construct packet to send to dataplane
155 # Send packet to dataplane
156 # Poll controller with expect message type packet in
157
Rich Lane32bf9482013-01-03 17:26:30 -0800158 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700159
160 # These will get put into function
161 of_ports = config["port_map"].keys()
162 of_ports.sort()
163 out_count = 0
164 in_count = 0
165 xid = 100
166 for dp_port in of_ports:
167 for outpkt, opt in [
168 (simple_tcp_packet(), "simple TCP packet"),
169 (simple_eth_packet(), "simple Ethernet packet"),
170 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
171
172 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
173 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800174 msg.in_port = ofp.OFPP_NONE
Dan Talaycod0832852012-10-10 09:49:53 -0700175 msg.data = str(outpkt)
176 act = action.action_output()
177 act.port = dp_port
Rich Lanee30455b2013-01-03 16:24:44 -0800178 msg.actions.add(act)
Dan Talaycod0832852012-10-10 09:49:53 -0700179
180 logging.info("PacketOutLoad to: " + str(dp_port))
181 for count in range(100):
182 msg.xid = xid
183 xid += 1
Rich Lane5c3151c2013-01-03 17:15:41 -0800184 self.controller.message_send(msg)
Dan Talaycod0832852012-10-10 09:49:53 -0700185 out_count += 1
186
187 exp_pkt_arg = None
188 exp_port = None
189 time.sleep(2)
190 while True:
191 (of_port, pkt, pkt_time) = self.dataplane.poll(timeout=0)
192 if pkt is None:
193 break
194 in_count += 1
195 logging.info("PacketOutLoad Sent %d. Got %d." % (out_count, in_count))
Ed Swierke6fca642012-11-30 12:00:54 -0800196
197class FlowModLoad(base_tests.SimpleProtocol):
198
199 def checkBarrier(self):
200 msg, pkt = self.controller.transact(message.barrier_request(), timeout=60)
201 self.assertNotEqual(msg, None, "Barrier failed")
202 while self.controller.packets:
203 msg = self.controller.packets.pop(0)[0]
204 self.assertNotEqual(msg.header.type, message.OFPT_ERROR,
205 "Error received")
206
207 def runTest(self):
208 msg, pkt = self.controller.transact(message.table_stats_request())
Rich Lane30ca70c2012-12-31 16:53:55 -0800209
210 # Some switches report an extremely high max_entries that would cause
211 # us to run out of memory attempting to create all the flow-mods.
212 num_flows = min(msg.stats[0].max_entries, 32678)
213
214 logging.info("Creating %d flow-mods messages", num_flows)
Ed Swierke6fca642012-11-30 12:00:54 -0800215
216 requests = []
217 for i in range(num_flows):
218 match = ofp.ofp_match()
219 match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST
220 match.dl_vlan = ofp.OFP_VLAN_NONE
221 match.dl_dst = [0, 1, 2, 3, i / 256, i % 256]
222 act = action.action_output()
223 act.port = ofp.OFPP_CONTROLLER
224 request = message.flow_mod()
225 request.command = ofp.OFPFC_ADD
226 request.buffer_id = 0xffffffff
227 request.priority = num_flows - i
228 request.out_port = ofp.OFPP_NONE
229 request.match = match
230 request.actions.add(act)
231 requests.append(request)
232
Rich Lane82c35e82012-12-31 10:59:36 -0800233 for i in range(3):
Ed Swierke6fca642012-11-30 12:00:54 -0800234 logging.info("Iteration %d: delete all flows" % i)
Rich Lane32bf9482013-01-03 17:26:30 -0800235 delete_all_flows(self.controller)
Ed Swierke6fca642012-11-30 12:00:54 -0800236 self.checkBarrier()
237
238 logging.info("Iteration %d: add %s flows" % (i, num_flows))
Rich Laned9ef7c32012-12-31 11:00:30 -0800239 random.shuffle(requests)
Ed Swierke6fca642012-11-30 12:00:54 -0800240 for request in requests:
241 self.assertNotEqual(self.controller.message_send(request), -1,
242 "Error installing flow mod")
243 self.checkBarrier()