blob: c2f90138bf3347b8d0f0d7a3a3d69d4c07346687 [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
17
18import logging
19
20import unittest
21
Rich Lane477f4812012-10-04 22:49:00 -070022from oftest import config
Dan Talayco942f5302012-04-12 22:32:34 -070023import oftest.controller as controller
24import oftest.cstruct as ofp
25import oftest.message as message
26import oftest.dataplane as dataplane
27import oftest.action as action
28import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070029import oftest.base_tests as base_tests
Dan Talayco942f5302012-04-12 22:32:34 -070030import time
31
Rich Laneda3b5ad2012-10-03 09:05:32 -070032from oftest.testutils import *
Dan Talayco942f5302012-04-12 22:32:34 -070033
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
48 priority = -1
49
Dan Talayco942f5302012-04-12 22:32:34 -070050 def runTest(self):
51 # Set up flow to send from port 1 to port 2 and copy to CPU
52 # Test parameter gives LB port base (assumes consecutive)
Rich Lane2014f9b2012-10-05 15:29:40 -070053 lb_port = test_param_get('lb_port', default=1)
54 barrier_count = test_param_get('barrier_count',
Dan Talayco942f5302012-04-12 22:32:34 -070055 default=10)
56
57 # Set controller to filter packet ins
58 self.controller.filter_packet_in = True
59 self.controller.pkt_in_filter_limit = 10
60
61 pkt = simple_tcp_packet()
Ed Swierk99a74de2012-08-22 06:40:54 -070062 match = packet_to_flow_match(self, pkt)
Dan Talayco942f5302012-04-12 22:32:34 -070063 match.wildcards &= ~ofp.OFPFW_IN_PORT
64 match.in_port = lb_port
65 act = action.action_output()
66 act.port = lb_port + 1
67
68 request = message.flow_mod()
69 request.match = match
70 request.hard_timeout = 2 * barrier_count
71
72 request.buffer_id = 0xffffffff
73 self.assertTrue(request.actions.add(act), "Could not add action")
74
75 act = action.action_output()
76 act.port = ofp.OFPP_CONTROLLER
77 self.assertTrue(request.actions.add(act), "Could not add action")
78
79 rv = self.controller.message_send(request)
80 self.assertTrue(rv != -1, "Error installing flow mod")
81 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
82
83 # Create packet out and send to port lb_port + 1
84 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -080085 msg.in_port = lb_port
Dan Talayco942f5302012-04-12 22:32:34 -070086 msg.data = str(pkt)
87 act = action.action_output()
88 act.port = lb_port + 1
89 self.assertTrue(msg.actions.add(act), 'Could not add action to msg')
Rich Lane9a003812012-10-04 17:17:59 -070090 logging.info("Sleeping before starting storm")
Dan Talayco942f5302012-04-12 22:32:34 -070091 time.sleep(1) # Root causing issue with fast disconnects
Rich Lane9a003812012-10-04 17:17:59 -070092 logging.info("Sending packet out to %d" % (lb_port + 1))
Dan Talayco942f5302012-04-12 22:32:34 -070093 rv = self.controller.message_send(msg)
94 self.assertTrue(rv == 0, "Error sending out message")
95
96 for idx in range(0, barrier_count):
97 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
98 # To do: Add some interesting functionality here
Rich Lane9a003812012-10-04 17:17:59 -070099 logging.info("Barrier %d completed" % idx)
Dan Talayco942f5302012-04-12 22:32:34 -0700100
101 # Clear the flow table when done
Rich Lane9a003812012-10-04 17:17:59 -0700102 logging.debug("Deleting all flows from switch")
103 rc = delete_all_flows(self.controller)
Dan Talayco942f5302012-04-12 22:32:34 -0700104 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talaycod0832852012-10-10 09:49:53 -0700105
106class PacketInLoad(base_tests.SimpleDataPlane):
107 """
108 Generate lots of packet-in messages
109
110 Test packet-in function by sending lots of packets to the dataplane.
111 This test tracks the number of pkt-ins received but does not enforce
112 any requirements about the number received.
113 """
114 def runTest(self):
115 # Construct packet to send to dataplane
116 # Send packet to dataplane, once to each port
117 # Poll controller with expect message type packet in
118
119 rc = delete_all_flows(self.controller)
120 self.assertEqual(rc, 0, "Failed to delete all flows")
121 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
122 out_count = 0
123 in_count = 0
124
125 of_ports = config["port_map"].keys()
126 for of_port in of_ports:
127 for pkt, pt in [
128 (simple_tcp_packet(), "simple TCP packet"),
129 (simple_tcp_packet(dl_vlan_enable=True,pktlen=108),
130 "simple tagged TCP packet"),
131 (simple_eth_packet(), "simple Ethernet packet"),
132 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
133
134 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
135 for count in range(100):
136 out_count += 1
137 self.dataplane.send(of_port, str(pkt))
138 time.sleep(2)
139 while True:
140 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN,
141 timeout=0)
142 if not response:
143 break
144 in_count += 1
145 logging.info("PacketInLoad Sent %d. Got %d." % (out_count, in_count))
146
147
148
149class PacketOutLoad(base_tests.SimpleDataPlane):
150 """
151 Generate lots of packet-out messages
152
153 Test packet-out function by sending lots of packet-out msgs
154 to the switch. This test tracks the number of packets received in
155 the dataplane, but does not enforce any requirements about the
156 number received.
157 """
158 def runTest(self):
159 # Construct packet to send to dataplane
160 # Send packet to dataplane
161 # Poll controller with expect message type packet in
162
163 rc = delete_all_flows(self.controller)
164 self.assertEqual(rc, 0, "Failed to delete all flows")
165
166 # These will get put into function
167 of_ports = config["port_map"].keys()
168 of_ports.sort()
169 out_count = 0
170 in_count = 0
171 xid = 100
172 for dp_port in of_ports:
173 for outpkt, opt in [
174 (simple_tcp_packet(), "simple TCP packet"),
175 (simple_eth_packet(), "simple Ethernet packet"),
176 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
177
178 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
179 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800180 msg.in_port = ofp.OFPP_NONE
Dan Talaycod0832852012-10-10 09:49:53 -0700181 msg.data = str(outpkt)
182 act = action.action_output()
183 act.port = dp_port
184 self.assertTrue(msg.actions.add(act), 'Could not add action to msg')
185
186 logging.info("PacketOutLoad to: " + str(dp_port))
187 for count in range(100):
188 msg.xid = xid
189 xid += 1
190 rv = self.controller.message_send(msg)
191 self.assertTrue(rv == 0, "Error sending out message")
192 out_count += 1
193
194 exp_pkt_arg = None
195 exp_port = None
196 time.sleep(2)
197 while True:
198 (of_port, pkt, pkt_time) = self.dataplane.poll(timeout=0)
199 if pkt is None:
200 break
201 in_count += 1
202 logging.info("PacketOutLoad Sent %d. Got %d." % (out_count, in_count))
Ed Swierke6fca642012-11-30 12:00:54 -0800203
204class FlowModLoad(base_tests.SimpleProtocol):
205
206 def checkBarrier(self):
207 msg, pkt = self.controller.transact(message.barrier_request(), timeout=60)
208 self.assertNotEqual(msg, None, "Barrier failed")
209 while self.controller.packets:
210 msg = self.controller.packets.pop(0)[0]
211 self.assertNotEqual(msg.header.type, message.OFPT_ERROR,
212 "Error received")
213
214 def runTest(self):
215 msg, pkt = self.controller.transact(message.table_stats_request())
216 num_flows = msg.stats[0].max_entries
217
218 requests = []
219 for i in range(num_flows):
220 match = ofp.ofp_match()
221 match.wildcards = ofp.OFPFW_ALL & ~ofp.OFPFW_DL_VLAN & ~ofp.OFPFW_DL_DST
222 match.dl_vlan = ofp.OFP_VLAN_NONE
223 match.dl_dst = [0, 1, 2, 3, i / 256, i % 256]
224 act = action.action_output()
225 act.port = ofp.OFPP_CONTROLLER
226 request = message.flow_mod()
227 request.command = ofp.OFPFC_ADD
228 request.buffer_id = 0xffffffff
229 request.priority = num_flows - i
230 request.out_port = ofp.OFPP_NONE
231 request.match = match
232 request.actions.add(act)
233 requests.append(request)
234
235 for i in range(5):
236 logging.info("Iteration %d: delete all flows" % i)
237 self.assertEqual(delete_all_flows(self.controller), 0,
238 "Failed to delete all flows")
239 self.checkBarrier()
240
241 logging.info("Iteration %d: add %s flows" % (i, num_flows))
242 for request in requests:
243 self.assertNotEqual(self.controller.message_send(request), -1,
244 "Error installing flow mod")
245 self.checkBarrier()