blob: 2631f360884a2ba9871179b39d76e76096b4bbfd [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
Rich Laned7b0ffa2013-03-08 15:53:42 -080023import ofp
Dan Talayco942f5302012-04-12 22:32:34 -070024import oftest.dataplane as dataplane
Dan Talayco942f5302012-04-12 22:32:34 -070025import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070026import oftest.base_tests as base_tests
Dan Talayco942f5302012-04-12 22:32:34 -070027import time
28
Rich Laneda3b5ad2012-10-03 09:05:32 -070029from oftest.testutils import *
Dan Talayco942f5302012-04-12 22:32:34 -070030
Rich Lane0a4f6372013-01-02 14:40:22 -080031@nonstandard
Rich Laneb90a1c42012-10-05 09:16:05 -070032class LoadBarrier(base_tests.SimpleProtocol):
Dan Talayco942f5302012-04-12 22:32:34 -070033 """
34 Test barrier under load with loopback
35
36 This test assumes there is a pair of ports on the switch with
37 a loopback cable connected and that spanning tree is disabled.
38 A flow is installed to cause a storm of packet-in messages
39 when a packet is sent to the loopbacked interface. After causing
40 this storm, a barrier request is sent.
41
42 The test succeeds if the barrier response is received. Otherwise
43 the test fails.
44 """
Rich Laned1d9c282012-10-04 22:07:10 -070045
Dan Talayco942f5302012-04-12 22:32:34 -070046 def runTest(self):
47 # Set up flow to send from port 1 to port 2 and copy to CPU
48 # Test parameter gives LB port base (assumes consecutive)
Rich Lane2014f9b2012-10-05 15:29:40 -070049 lb_port = test_param_get('lb_port', default=1)
50 barrier_count = test_param_get('barrier_count',
Dan Talayco942f5302012-04-12 22:32:34 -070051 default=10)
52
53 # Set controller to filter packet ins
54 self.controller.filter_packet_in = True
55 self.controller.pkt_in_filter_limit = 10
56
57 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -070058 match = packet_to_flow_match(self, pkt)
Dan Talayco942f5302012-04-12 22:32:34 -070059 match.wildcards &= ~ofp.OFPFW_IN_PORT
60 match.in_port = lb_port
Rich Lane9d3cc6b2013-03-08 16:33:08 -080061 act = ofp.action.output()
Dan Talayco942f5302012-04-12 22:32:34 -070062 act.port = lb_port + 1
63
Rich Laneba3f0e22013-03-11 16:43:57 -070064 request = ofp.message.flow_add()
Dan Talayco942f5302012-04-12 22:32:34 -070065 request.match = match
66 request.hard_timeout = 2 * barrier_count
67
68 request.buffer_id = 0xffffffff
Rich Lanec495d9e2013-03-08 17:43:36 -080069 request.actions.append(act)
Dan Talayco942f5302012-04-12 22:32:34 -070070
Rich Lane9d3cc6b2013-03-08 16:33:08 -080071 act = ofp.action.output()
Dan Talayco942f5302012-04-12 22:32:34 -070072 act.port = ofp.OFPP_CONTROLLER
Rich Lanec495d9e2013-03-08 17:43:36 -080073 request.actions.append(act)
Dan Talayco942f5302012-04-12 22:32:34 -070074
Rich Lane5c3151c2013-01-03 17:15:41 -080075 self.controller.message_send(request)
Rich Lane3a261d52013-01-03 17:45:08 -080076 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070077
78 # Create packet out and send to port lb_port + 1
Rich Lane28fa9272013-03-08 16:00:25 -080079 msg = ofp.message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -080080 msg.in_port = lb_port
Dan Talayco942f5302012-04-12 22:32:34 -070081 msg.data = str(pkt)
Rich Laneea8c4722013-04-04 15:30:20 -070082 msg.buffer_id = 0xffffffff
Rich Lane9d3cc6b2013-03-08 16:33:08 -080083 act = ofp.action.output()
Dan Talayco942f5302012-04-12 22:32:34 -070084 act.port = lb_port + 1
Rich Lanec495d9e2013-03-08 17:43:36 -080085 msg.actions.append(act)
Rich Lane9a003812012-10-04 17:17:59 -070086 logging.info("Sleeping before starting storm")
Dan Talayco942f5302012-04-12 22:32:34 -070087 time.sleep(1) # Root causing issue with fast disconnects
Rich Lane9a003812012-10-04 17:17:59 -070088 logging.info("Sending packet out to %d" % (lb_port + 1))
Rich Lane5c3151c2013-01-03 17:15:41 -080089 self.controller.message_send(msg)
Dan Talayco942f5302012-04-12 22:32:34 -070090
91 for idx in range(0, barrier_count):
Rich Lane3a261d52013-01-03 17:45:08 -080092 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070093 # To do: Add some interesting functionality here
Rich Lane9a003812012-10-04 17:17:59 -070094 logging.info("Barrier %d completed" % idx)
Dan Talayco942f5302012-04-12 22:32:34 -070095
96 # Clear the flow table when done
Rich Lane9a003812012-10-04 17:17:59 -070097 logging.debug("Deleting all flows from switch")
Rich Lane32bf9482013-01-03 17:26:30 -080098 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -070099
100class PacketInLoad(base_tests.SimpleDataPlane):
101 """
102 Generate lots of packet-in messages
103
104 Test packet-in function by sending lots of packets to the dataplane.
105 This test tracks the number of pkt-ins received but does not enforce
106 any requirements about the number received.
107 """
108 def runTest(self):
109 # Construct packet to send to dataplane
110 # Send packet to dataplane, once to each port
111 # Poll controller with expect message type packet in
112
Rich Lane32bf9482013-01-03 17:26:30 -0800113 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800114 do_barrier(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700115 out_count = 0
116 in_count = 0
117
118 of_ports = config["port_map"].keys()
119 for of_port in of_ports:
120 for pkt, pt in [
121 (simple_tcp_packet(), "simple TCP packet"),
122 (simple_tcp_packet(dl_vlan_enable=True,pktlen=108),
123 "simple tagged TCP packet"),
124 (simple_eth_packet(), "simple Ethernet packet"),
125 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
126
127 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
128 for count in range(100):
129 out_count += 1
130 self.dataplane.send(of_port, str(pkt))
Dan Talaycod0832852012-10-10 09:49:53 -0700131 while True:
Ed Swierka9e12ab2013-01-16 07:35:25 -0800132 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Dan Talaycod0832852012-10-10 09:49:53 -0700133 if not response:
134 break
135 in_count += 1
136 logging.info("PacketInLoad Sent %d. Got %d." % (out_count, in_count))
137
138
139
140class PacketOutLoad(base_tests.SimpleDataPlane):
141 """
142 Generate lots of packet-out messages
143
144 Test packet-out function by sending lots of packet-out msgs
145 to the switch. This test tracks the number of packets received in
146 the dataplane, but does not enforce any requirements about the
147 number received.
148 """
149 def runTest(self):
150 # Construct packet to send to dataplane
151 # Send packet to dataplane
152 # Poll controller with expect message type packet in
153
Rich Lane32bf9482013-01-03 17:26:30 -0800154 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700155
156 # These will get put into function
157 of_ports = config["port_map"].keys()
158 of_ports.sort()
159 out_count = 0
160 in_count = 0
161 xid = 100
162 for dp_port in of_ports:
163 for outpkt, opt in [
164 (simple_tcp_packet(), "simple TCP packet"),
165 (simple_eth_packet(), "simple Ethernet packet"),
166 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
167
168 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
Rich Lane28fa9272013-03-08 16:00:25 -0800169 msg = ofp.message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800170 msg.in_port = ofp.OFPP_NONE
Dan Talaycod0832852012-10-10 09:49:53 -0700171 msg.data = str(outpkt)
Rich Lane9d3cc6b2013-03-08 16:33:08 -0800172 act = ofp.action.output()
Dan Talaycod0832852012-10-10 09:49:53 -0700173 act.port = dp_port
Rich Lanec495d9e2013-03-08 17:43:36 -0800174 msg.actions.append(act)
Rich Laneea8c4722013-04-04 15:30:20 -0700175 msg.buffer_id = 0xffffffff
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):
Rich Lane28fa9272013-03-08 16:00:25 -0800196 msg, pkt = self.controller.transact(ofp.message.barrier_request(), timeout=60)
Ed Swierke6fca642012-11-30 12:00:54 -0800197 self.assertNotEqual(msg, None, "Barrier failed")
198 while self.controller.packets:
199 msg = self.controller.packets.pop(0)[0]
Rich Lanef9f6b512013-03-11 22:35:28 -0700200 self.assertNotEqual(msg.type, ofp.OFPT_ERROR, "Error received")
Ed Swierke6fca642012-11-30 12:00:54 -0800201
202 def runTest(self):
Rich Lane28fa9272013-03-08 16:00:25 -0800203 msg, pkt = self.controller.transact(ofp.message.table_stats_request())
Rich Lane30ca70c2012-12-31 16:53:55 -0800204
205 # Some switches report an extremely high max_entries that would cause
206 # us to run out of memory attempting to create all the flow-mods.
Rich Lane5fd6faf2013-03-11 13:30:20 -0700207 num_flows = min(msg.entries[0].max_entries, 32678)
Rich Lane30ca70c2012-12-31 16:53:55 -0800208
209 logging.info("Creating %d flow-mods messages", num_flows)
Ed Swierke6fca642012-11-30 12:00:54 -0800210
211 requests = []
212 for i in range(num_flows):
Rich Lane0237baf2013-03-11 22:34:59 -0700213 match = ofp.match()
Ed Swierke6fca642012-11-30 12:00:54 -0800214 match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST
Rich Laned0478ff2013-03-11 12:46:58 -0700215 match.vlan_vid = ofp.OFP_VLAN_NONE
216 match.eth_dst = [0, 1, 2, 3, i / 256, i % 256]
Rich Lane9d3cc6b2013-03-08 16:33:08 -0800217 act = ofp.action.output()
Ed Swierke6fca642012-11-30 12:00:54 -0800218 act.port = ofp.OFPP_CONTROLLER
Rich Laneba3f0e22013-03-11 16:43:57 -0700219 request = ofp.message.flow_add()
Ed Swierke6fca642012-11-30 12:00:54 -0800220 request.buffer_id = 0xffffffff
221 request.priority = num_flows - i
222 request.out_port = ofp.OFPP_NONE
223 request.match = match
Rich Lanec495d9e2013-03-08 17:43:36 -0800224 request.actions.append(act)
Ed Swierke6fca642012-11-30 12:00:54 -0800225 requests.append(request)
226
Rich Lane82c35e82012-12-31 10:59:36 -0800227 for i in range(3):
Ed Swierke6fca642012-11-30 12:00:54 -0800228 logging.info("Iteration %d: delete all flows" % i)
Rich Lane32bf9482013-01-03 17:26:30 -0800229 delete_all_flows(self.controller)
Ed Swierke6fca642012-11-30 12:00:54 -0800230 self.checkBarrier()
231
232 logging.info("Iteration %d: add %s flows" % (i, num_flows))
Rich Laned9ef7c32012-12-31 11:00:30 -0800233 random.shuffle(requests)
Ed Swierke6fca642012-11-30 12:00:54 -0800234 for request in requests:
235 self.assertNotEqual(self.controller.message_send(request), -1,
236 "Error installing flow mod")
237 self.checkBarrier()