blob: 3b72f724e49c3fa5f5f4bef4ba700d783d14283e [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 Lane28fa9272013-03-08 16:00:25 -080064 request = ofp.message.flow_mod()
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 Lane9d3cc6b2013-03-08 16:33:08 -080082 act = ofp.action.output()
Dan Talayco942f5302012-04-12 22:32:34 -070083 act.port = lb_port + 1
Rich Lanec495d9e2013-03-08 17:43:36 -080084 msg.actions.append(act)
Rich Lane9a003812012-10-04 17:17:59 -070085 logging.info("Sleeping before starting storm")
Dan Talayco942f5302012-04-12 22:32:34 -070086 time.sleep(1) # Root causing issue with fast disconnects
Rich Lane9a003812012-10-04 17:17:59 -070087 logging.info("Sending packet out to %d" % (lb_port + 1))
Rich Lane5c3151c2013-01-03 17:15:41 -080088 self.controller.message_send(msg)
Dan Talayco942f5302012-04-12 22:32:34 -070089
90 for idx in range(0, barrier_count):
Rich Lane3a261d52013-01-03 17:45:08 -080091 do_barrier(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -070092 # To do: Add some interesting functionality here
Rich Lane9a003812012-10-04 17:17:59 -070093 logging.info("Barrier %d completed" % idx)
Dan Talayco942f5302012-04-12 22:32:34 -070094
95 # Clear the flow table when done
Rich Lane9a003812012-10-04 17:17:59 -070096 logging.debug("Deleting all flows from switch")
Rich Lane32bf9482013-01-03 17:26:30 -080097 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -070098
99class PacketInLoad(base_tests.SimpleDataPlane):
100 """
101 Generate lots of packet-in messages
102
103 Test packet-in function by sending lots of packets to the dataplane.
104 This test tracks the number of pkt-ins received but does not enforce
105 any requirements about the number received.
106 """
107 def runTest(self):
108 # Construct packet to send to dataplane
109 # Send packet to dataplane, once to each port
110 # Poll controller with expect message type packet in
111
Rich Lane32bf9482013-01-03 17:26:30 -0800112 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800113 do_barrier(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700114 out_count = 0
115 in_count = 0
116
117 of_ports = config["port_map"].keys()
118 for of_port in of_ports:
119 for pkt, pt in [
120 (simple_tcp_packet(), "simple TCP packet"),
121 (simple_tcp_packet(dl_vlan_enable=True,pktlen=108),
122 "simple tagged TCP packet"),
123 (simple_eth_packet(), "simple Ethernet packet"),
124 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
125
126 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
127 for count in range(100):
128 out_count += 1
129 self.dataplane.send(of_port, str(pkt))
Dan Talaycod0832852012-10-10 09:49:53 -0700130 while True:
Ed Swierka9e12ab2013-01-16 07:35:25 -0800131 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Dan Talaycod0832852012-10-10 09:49:53 -0700132 if not response:
133 break
134 in_count += 1
135 logging.info("PacketInLoad Sent %d. Got %d." % (out_count, in_count))
136
137
138
139class PacketOutLoad(base_tests.SimpleDataPlane):
140 """
141 Generate lots of packet-out messages
142
143 Test packet-out function by sending lots of packet-out msgs
144 to the switch. This test tracks the number of packets received in
145 the dataplane, but does not enforce any requirements about the
146 number received.
147 """
148 def runTest(self):
149 # Construct packet to send to dataplane
150 # Send packet to dataplane
151 # Poll controller with expect message type packet in
152
Rich Lane32bf9482013-01-03 17:26:30 -0800153 delete_all_flows(self.controller)
Dan Talaycod0832852012-10-10 09:49:53 -0700154
155 # These will get put into function
156 of_ports = config["port_map"].keys()
157 of_ports.sort()
158 out_count = 0
159 in_count = 0
160 xid = 100
161 for dp_port in of_ports:
162 for outpkt, opt in [
163 (simple_tcp_packet(), "simple TCP packet"),
164 (simple_eth_packet(), "simple Ethernet packet"),
165 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
166
167 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
Rich Lane28fa9272013-03-08 16:00:25 -0800168 msg = ofp.message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800169 msg.in_port = ofp.OFPP_NONE
Dan Talaycod0832852012-10-10 09:49:53 -0700170 msg.data = str(outpkt)
Rich Lane9d3cc6b2013-03-08 16:33:08 -0800171 act = ofp.action.output()
Dan Talaycod0832852012-10-10 09:49:53 -0700172 act.port = dp_port
Rich Lanec495d9e2013-03-08 17:43:36 -0800173 msg.actions.append(act)
Dan Talaycod0832852012-10-10 09:49:53 -0700174
175 logging.info("PacketOutLoad to: " + str(dp_port))
176 for count in range(100):
177 msg.xid = xid
178 xid += 1
Rich Lane5c3151c2013-01-03 17:15:41 -0800179 self.controller.message_send(msg)
Dan Talaycod0832852012-10-10 09:49:53 -0700180 out_count += 1
181
182 exp_pkt_arg = None
183 exp_port = None
Dan Talaycod0832852012-10-10 09:49:53 -0700184 while True:
Ed Swierka9e12ab2013-01-16 07:35:25 -0800185 (of_port, pkt, pkt_time) = self.dataplane.poll()
Dan Talaycod0832852012-10-10 09:49:53 -0700186 if pkt is None:
187 break
188 in_count += 1
189 logging.info("PacketOutLoad Sent %d. Got %d." % (out_count, in_count))
Ed Swierke6fca642012-11-30 12:00:54 -0800190
191class FlowModLoad(base_tests.SimpleProtocol):
192
193 def checkBarrier(self):
Rich Lane28fa9272013-03-08 16:00:25 -0800194 msg, pkt = self.controller.transact(ofp.message.barrier_request(), timeout=60)
Ed Swierke6fca642012-11-30 12:00:54 -0800195 self.assertNotEqual(msg, None, "Barrier failed")
196 while self.controller.packets:
197 msg = self.controller.packets.pop(0)[0]
Rich Lane28fa9272013-03-08 16:00:25 -0800198 self.assertNotEqual(msg.header.type, ofp.message.OFPT_ERROR,
Ed Swierke6fca642012-11-30 12:00:54 -0800199 "Error received")
200
201 def runTest(self):
Rich Lane28fa9272013-03-08 16:00:25 -0800202 msg, pkt = self.controller.transact(ofp.message.table_stats_request())
Rich Lane30ca70c2012-12-31 16:53:55 -0800203
204 # Some switches report an extremely high max_entries that would cause
205 # us to run out of memory attempting to create all the flow-mods.
Rich Lane5fd6faf2013-03-11 13:30:20 -0700206 num_flows = min(msg.entries[0].max_entries, 32678)
Rich Lane30ca70c2012-12-31 16:53:55 -0800207
208 logging.info("Creating %d flow-mods messages", num_flows)
Ed Swierke6fca642012-11-30 12:00:54 -0800209
210 requests = []
211 for i in range(num_flows):
212 match = ofp.ofp_match()
213 match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST
Rich Laned0478ff2013-03-11 12:46:58 -0700214 match.vlan_vid = ofp.OFP_VLAN_NONE
215 match.eth_dst = [0, 1, 2, 3, i / 256, i % 256]
Rich Lane9d3cc6b2013-03-08 16:33:08 -0800216 act = ofp.action.output()
Ed Swierke6fca642012-11-30 12:00:54 -0800217 act.port = ofp.OFPP_CONTROLLER
Rich Lane28fa9272013-03-08 16:00:25 -0800218 request = ofp.message.flow_mod()
Ed Swierke6fca642012-11-30 12:00:54 -0800219 request.command = ofp.OFPFC_ADD
220 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()