blob: d78f2ffd11eb1a145875dbf2d66fd4888738090b [file] [log] [blame]
Dan Talaycodba244e2010-02-15 14:08:53 -08001"""
Dan Talayco79f36082010-03-11 16:53:53 -08002Basic protocol and dataplane test cases
Dan Talaycodba244e2010-02-15 14:08:53 -08003
Dan Talayco48370102010-03-03 15:17:33 -08004It is recommended that these definitions be kept in their own
5namespace as different groups of tests will likely define
6similar identifiers.
7
Dan Talaycodba244e2010-02-15 14:08:53 -08008Current Assumptions:
9
Dan Talaycodba244e2010-02-15 14:08:53 -080010 The switch is actively attempting to contact the controller at the address
Rich Lane477f4812012-10-04 22:49:00 -070011indicated in oftest.config.
Dan Talaycodba244e2010-02-15 14:08:53 -080012
13"""
14
Dan Talaycodba244e2010-02-15 14:08:53 -080015import time
16import sys
Dan Talayco48370102010-03-03 15:17:33 -080017import logging
Dan Talaycodba244e2010-02-15 14:08:53 -080018
Dan Talayco2c0dba32010-03-06 22:47:06 -080019import unittest
Ken Chiang1bf01602012-04-04 10:48:23 -070020import random
Dan Talayco2c0dba32010-03-06 22:47:06 -080021
Rich Lane477f4812012-10-04 22:49:00 -070022from oftest import config
Dan Talayco2c0dba32010-03-06 22:47:06 -080023import oftest.controller as controller
24import oftest.cstruct as ofp
25import oftest.message as message
26import oftest.dataplane as dataplane
27import oftest.action as action
Rich Laneb90a1c42012-10-05 09:16:05 -070028import oftest.base_tests as base_tests
Dan Talayco2c0dba32010-03-06 22:47:06 -080029
Dan Talaycoe605b1b2012-09-18 06:56:20 -070030import oftest.illegal_message as illegal_message
31
Rich Laneda3b5ad2012-10-03 09:05:32 -070032from oftest.testutils import *
Dan Talayco6ce963a2010-03-07 21:58:13 -080033
Ken Chiangaeb23d62012-08-23 21:20:07 -070034TEST_VID_DEFAULT = 2
35
Rich Lane97e99652013-01-02 17:23:20 -080036@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -070037class Echo(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080038 """
39 Test echo response with no data
40 """
41 def runTest(self):
Dan Talayco2c0dba32010-03-06 22:47:06 -080042 request = message.echo_request()
Dan Talaycoe226eb12010-02-18 23:06:30 -080043 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070044 self.assertTrue(response is not None,
45 "Did not get echo reply")
Dan Talayco2c0dba32010-03-06 22:47:06 -080046 self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080047 'response is not echo_reply')
Dan Talaycodba244e2010-02-15 14:08:53 -080048 self.assertEqual(request.header.xid, response.header.xid,
49 'response xid != request xid')
50 self.assertEqual(len(response.data), 0, 'response data non-empty')
51
Rich Laneb90a1c42012-10-05 09:16:05 -070052class EchoWithData(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080053 """
54 Test echo response with short string data
55 """
56 def runTest(self):
Dan Talayco2c0dba32010-03-06 22:47:06 -080057 request = message.echo_request()
Dan Talaycodba244e2010-02-15 14:08:53 -080058 request.data = 'OpenFlow Will Rule The World'
Dan Talaycoe226eb12010-02-18 23:06:30 -080059 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070060 self.assertTrue(response is not None,
61 "Did not get echo reply (with data)")
Dan Talayco2c0dba32010-03-06 22:47:06 -080062 self.assertEqual(response.header.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080063 'response is not echo_reply')
Dan Talaycodba244e2010-02-15 14:08:53 -080064 self.assertEqual(request.header.xid, response.header.xid,
65 'response xid != request xid')
66 self.assertEqual(request.data, response.data,
67 'response data does not match request')
68
Rich Lane97e99652013-01-02 17:23:20 -080069@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -070070class PacketIn(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -080071 """
72 Test packet in function
Dan Talayco6ce963a2010-03-07 21:58:13 -080073
74 Send a packet to each dataplane port and verify that a packet
75 in message is received from the controller for each
Dan Talaycodba244e2010-02-15 14:08:53 -080076 """
77 def runTest(self):
78 # Construct packet to send to dataplane
Dan Talaycoe226eb12010-02-18 23:06:30 -080079 # Send packet to dataplane, once to each port
Dan Talaycodba244e2010-02-15 14:08:53 -080080 # Poll controller with expect message type packet in
Dan Talaycoe226eb12010-02-18 23:06:30 -080081
Rich Lane9a003812012-10-04 17:17:59 -070082 rc = delete_all_flows(self.controller)
Dan Talayco6ce963a2010-03-07 21:58:13 -080083 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talayco0fc08bd2012-04-09 16:56:18 -070084 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talayco6ce963a2010-03-07 21:58:13 -080085
Rich Lane2014f9b2012-10-05 15:29:40 -070086 vid = test_param_get('vid', default=TEST_VID_DEFAULT)
Ken Chiangaeb23d62012-08-23 21:20:07 -070087
Rich Lane477f4812012-10-04 22:49:00 -070088 for of_port in config["port_map"].keys():
Ed Swierk0aeff8c2012-03-23 20:27:18 -070089 for pkt, pt in [
90 (simple_tcp_packet(), "simple TCP packet"),
Ken Chiangaeb23d62012-08-23 21:20:07 -070091 (simple_tcp_packet(dl_vlan_enable=True,dl_vlan=vid,pktlen=108),
92 "simple tagged TCP packet"),
Ed Swierk0aeff8c2012-03-23 20:27:18 -070093 (simple_eth_packet(), "simple Ethernet packet"),
94 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -080095
Rich Lane9a003812012-10-04 17:17:59 -070096 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -070097 self.dataplane.send(of_port, str(pkt))
98 #@todo Check for unexpected messages?
99 count = 0
100 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700101 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700102 if not response: # Timeout
103 break
Ed Swierk506614a2012-03-29 08:16:59 -0700104 if dataplane.match_exp_pkt(pkt, response.data): # Got match
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700105 break
Rich Lane477f4812012-10-04 22:49:00 -0700106 if not config["relax"]: # Only one attempt to match
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700107 break
108 count += 1
109 if count > 10: # Too many tries
110 break
Dan Talayco48370102010-03-03 15:17:33 -0800111
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700112 self.assertTrue(response is not None,
113 'Packet in message not received on port ' +
114 str(of_port))
Ed Swierk506614a2012-03-29 08:16:59 -0700115 if not dataplane.match_exp_pkt(pkt, response.data):
Rich Lane9a003812012-10-04 17:17:59 -0700116 logging.debug("Sent %s" % format_packet(pkt))
117 logging.debug("Resp %s" % format_packet(response.data))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700118 self.assertTrue(False,
119 'Response packet does not match send packet' +
120 ' for port ' + str(of_port))
Dan Talaycodba244e2010-02-15 14:08:53 -0800121
Rich Lane0a4f6372013-01-02 14:40:22 -0800122@nonstandard
Rich Laneb90a1c42012-10-05 09:16:05 -0700123class PacketInDefaultDrop(base_tests.SimpleDataPlane):
Ed Swierk3ae7f712012-08-22 06:45:25 -0700124 """
125 Test packet in function
126
127 Send a packet to each dataplane port and verify that a packet
128 in message is received from the controller for each
129 """
Rich Laned1d9c282012-10-04 22:07:10 -0700130
Ed Swierk3ae7f712012-08-22 06:45:25 -0700131 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700132 rc = delete_all_flows(self.controller)
Ed Swierk3ae7f712012-08-22 06:45:25 -0700133 self.assertEqual(rc, 0, "Failed to delete all flows")
134 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
135
Rich Lane477f4812012-10-04 22:49:00 -0700136 for of_port in config["port_map"].keys():
Ed Swierk3ae7f712012-08-22 06:45:25 -0700137 pkt = simple_tcp_packet()
138 self.dataplane.send(of_port, str(pkt))
139 count = 0
140 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700141 (response, raw) = self.controller.poll(ofp.OFPT_PACKET_IN)
Ed Swierk3ae7f712012-08-22 06:45:25 -0700142 if not response: # Timeout
143 break
144 if dataplane.match_exp_pkt(pkt, response.data): # Got match
145 break
Rich Lane477f4812012-10-04 22:49:00 -0700146 if not config["relax"]: # Only one attempt to match
Ed Swierk3ae7f712012-08-22 06:45:25 -0700147 break
148 count += 1
149 if count > 10: # Too many tries
150 break
151
152 self.assertTrue(response is None,
153 'Packet in message received on port ' +
154 str(of_port))
155
Rich Lane0a4f6372013-01-02 14:40:22 -0800156@nonstandard
Rich Laneb90a1c42012-10-05 09:16:05 -0700157class PacketInBroadcastCheck(base_tests.SimpleDataPlane):
Dan Talayco1f648cb2012-05-03 09:37:56 -0700158 """
159 Check if bcast pkts leak when no flows are present
160
161 Clear the flow table
162 Send in a broadcast pkt
163 Look for the packet on other dataplane ports.
164 """
Rich Laned1d9c282012-10-04 22:07:10 -0700165
Dan Talayco1f648cb2012-05-03 09:37:56 -0700166 def runTest(self):
167 # Need at least two ports
Rich Lane477f4812012-10-04 22:49:00 -0700168 self.assertTrue(len(config["port_map"]) > 1, "Too few ports for test")
Dan Talayco1f648cb2012-05-03 09:37:56 -0700169
Rich Lane9a003812012-10-04 17:17:59 -0700170 rc = delete_all_flows(self.controller)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700171 self.assertEqual(rc, 0, "Failed to delete all flows")
172 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
173
Rich Lane477f4812012-10-04 22:49:00 -0700174 of_ports = config["port_map"].keys()
Dan Talayco1f648cb2012-05-03 09:37:56 -0700175 d_port = of_ports[0]
176 pkt = simple_eth_packet(dl_dst='ff:ff:ff:ff:ff:ff')
177
Rich Lane9a003812012-10-04 17:17:59 -0700178 logging.info("BCast Leak Test, send to port %s" % d_port)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700179 self.dataplane.send(d_port, str(pkt))
180
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700181 (of_port, pkt_in, pkt_time) = self.dataplane.poll(exp_pkt=pkt)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700182 self.assertTrue(pkt_in is None,
183 'BCast packet received on port ' + str(of_port))
184
Rich Lane97e99652013-01-02 17:23:20 -0800185@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700186class PacketOut(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -0800187 """
188 Test packet out function
Dan Talayco6ce963a2010-03-07 21:58:13 -0800189
190 Send packet out message to controller for each dataplane port and
191 verify the packet appears on the appropriate dataplane port
Dan Talaycodba244e2010-02-15 14:08:53 -0800192 """
193 def runTest(self):
194 # Construct packet to send to dataplane
195 # Send packet to dataplane
196 # Poll controller with expect message type packet in
Dan Talayco41eae8b2010-03-10 13:57:06 -0800197
Rich Lane9a003812012-10-04 17:17:59 -0700198 rc = delete_all_flows(self.controller)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800199 self.assertEqual(rc, 0, "Failed to delete all flows")
Dan Talaycodba244e2010-02-15 14:08:53 -0800200
201 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700202 of_ports = config["port_map"].keys()
Dan Talayco48370102010-03-03 15:17:33 -0800203 of_ports.sort()
204 for dp_port in of_ports:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700205 for outpkt, opt in [
206 (simple_tcp_packet(), "simple TCP packet"),
207 (simple_eth_packet(), "simple Ethernet packet"),
208 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -0800209
Rich Lane9a003812012-10-04 17:17:59 -0700210 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700211 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800212 msg.in_port = ofp.OFPP_NONE
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700213 msg.data = str(outpkt)
214 act = action.action_output()
215 act.port = dp_port
216 self.assertTrue(msg.actions.add(act), 'Could not add action to msg')
Dan Talaycodba244e2010-02-15 14:08:53 -0800217
Rich Lane9a003812012-10-04 17:17:59 -0700218 logging.info("PacketOut to: " + str(dp_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700219 rv = self.controller.message_send(msg)
220 self.assertTrue(rv == 0, "Error sending out message")
Dan Talaycodba244e2010-02-15 14:08:53 -0800221
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700222 exp_pkt_arg = None
223 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -0700224 if config["relax"]:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700225 exp_pkt_arg = outpkt
226 exp_port = dp_port
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700227 (of_port, pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700228 exp_pkt=exp_pkt_arg)
229
230 self.assertTrue(pkt is not None, 'Packet not received')
Rich Lane9a003812012-10-04 17:17:59 -0700231 logging.info("PacketOut: got pkt from " + str(of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700232 if of_port is not None:
233 self.assertEqual(of_port, dp_port, "Unexpected receive port")
Ed Swierk506614a2012-03-29 08:16:59 -0700234 if not dataplane.match_exp_pkt(outpkt, pkt):
Rich Lane9a003812012-10-04 17:17:59 -0700235 logging.debug("Sent %s" % format_packet(outpkt))
236 logging.debug("Resp %s" % format_packet(
Dan Talayco2baf8b52012-03-30 09:55:42 -0700237 str(pkt)[:len(str(outpkt))]))
Dan Talaycodc6fca32012-03-30 10:05:49 -0700238 self.assertEqual(str(outpkt), str(pkt)[:len(str(outpkt))],
239 'Response packet does not match send packet')
Dan Talaycodba244e2010-02-15 14:08:53 -0800240
Rich Laneb90a1c42012-10-05 09:16:05 -0700241class PacketOutMC(base_tests.SimpleDataPlane):
Ken Chiang1bf01602012-04-04 10:48:23 -0700242 """
243 Test packet out to multiple output ports
244
245 Send packet out message to controller for 1 to N dataplane ports and
246 verify the packet appears on the appropriate ports
247 """
248 def runTest(self):
249 # Construct packet to send to dataplane
250 # Send packet to dataplane
251 # Poll controller with expect message type packet in
252
Rich Lane9a003812012-10-04 17:17:59 -0700253 rc = delete_all_flows(self.controller)
Ken Chiang1bf01602012-04-04 10:48:23 -0700254 self.assertEqual(rc, 0, "Failed to delete all flows")
255
256 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700257 of_ports = config["port_map"].keys()
Ken Chiang1bf01602012-04-04 10:48:23 -0700258 random.shuffle(of_ports)
259 for num_ports in range(1,len(of_ports)+1):
260 for outpkt, opt in [
261 (simple_tcp_packet(), "simple TCP packet"),
262 (simple_eth_packet(), "simple Ethernet packet"),
263 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
264
265 dp_ports = of_ports[0:num_ports]
Rich Lane9a003812012-10-04 17:17:59 -0700266 logging.info("PKT OUT test with " + opt +
Ken Chiang1bf01602012-04-04 10:48:23 -0700267 ", ports " + str(dp_ports))
268 msg = message.packet_out()
Rich Laneafcf4672012-11-14 13:19:27 -0800269 msg.in_port = ofp.OFPP_NONE
Ken Chiang1bf01602012-04-04 10:48:23 -0700270 msg.data = str(outpkt)
271 act = action.action_output()
272 for i in range(0,num_ports):
273 act.port = dp_ports[i]
274 self.assertTrue(msg.actions.add(act),
275 'Could not add action to msg')
276
Rich Lane9a003812012-10-04 17:17:59 -0700277 logging.info("PacketOut to: " + str(dp_ports))
Ken Chiang1bf01602012-04-04 10:48:23 -0700278 rv = self.controller.message_send(msg)
279 self.assertTrue(rv == 0, "Error sending out message")
280
281 receive_pkt_check(self.dataplane, outpkt, dp_ports,
282 set(of_ports).difference(dp_ports),
Rich Lane2014f9b2012-10-05 15:29:40 -0700283 self)
Ken Chiang1bf01602012-04-04 10:48:23 -0700284
Rich Lane0a4f6372013-01-02 14:40:22 -0800285@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -0700286class FlowStatsGet(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800287 """
288 Get stats
Dan Talayco2c0dba32010-03-06 22:47:06 -0800289
Dan Talayco6ce963a2010-03-07 21:58:13 -0800290 Simply verify stats get transaction
291 """
Rich Laned1d9c282012-10-04 22:07:10 -0700292
Dan Talayco6ce963a2010-03-07 21:58:13 -0800293 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700294 logging.info("Running StatsGet")
295 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700296 request = flow_mod_gen(config["port_map"], True)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800297 rv = self.controller.message_send(request)
298 self.assertTrue(rv != -1, "Failed to insert test flow")
299
Rich Lane9a003812012-10-04 17:17:59 -0700300 logging.info("Sending flow request")
Dan Talayco6ce963a2010-03-07 21:58:13 -0800301 request = message.flow_stats_request()
302 request.out_port = ofp.OFPP_NONE
Dan Talayco41eae8b2010-03-10 13:57:06 -0800303 request.table_id = 0xff
304 request.match.wildcards = 0 # ofp.OFPFW_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700305 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700306 self.assertTrue(response is not None,
307 "Did not get response for flow stats")
Rich Lane9a003812012-10-04 17:17:59 -0700308 logging.debug(response.show())
Dan Talayco6ce963a2010-03-07 21:58:13 -0800309
Rich Laneb90a1c42012-10-05 09:16:05 -0700310class TableStatsGet(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700311 """
312 Get table stats
313
314 Simply verify table stats get transaction
315 """
316 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700317 logging.info("Running TableStatsGet")
318 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700319 request = flow_mod_gen(config["port_map"], True)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700320 rv = self.controller.message_send(request)
321 self.assertTrue(rv != -1, "Failed to insert test flow")
322
Rich Lane9a003812012-10-04 17:17:59 -0700323 logging.info("Sending table stats request")
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700324 request = message.table_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700325 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700326 self.assertTrue(response is not None,
327 "Did not get reply for table stats")
Rich Lane9a003812012-10-04 17:17:59 -0700328 logging.debug(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700329
Rich Laneb90a1c42012-10-05 09:16:05 -0700330class DescStatsGet(base_tests.SimpleProtocol):
Ed Swierkae74c362012-04-02 08:21:41 -0700331 """
332 Get stats
333
334 Simply verify stats get transaction
335 """
336 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700337 logging.info("Running DescStatsGet")
Ed Swierkae74c362012-04-02 08:21:41 -0700338
Rich Lane9a003812012-10-04 17:17:59 -0700339 logging.info("Sending stats request")
Ed Swierkae74c362012-04-02 08:21:41 -0700340 request = message.desc_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700341 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700342 self.assertTrue(response is not None,
343 "Did not get reply for desc stats")
Rich Lane9a003812012-10-04 17:17:59 -0700344 logging.debug(response.show())
Ed Swierkae74c362012-04-02 08:21:41 -0700345
Rich Laneb90a1c42012-10-05 09:16:05 -0700346class FlowMod(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800347 """
348 Insert a flow
349
350 Simple verification of a flow mod transaction
351 """
352
353 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700354 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700355 request = flow_mod_gen(config["port_map"], True)
Dan Talayco6ce963a2010-03-07 21:58:13 -0800356 rv = self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800357 self.assertTrue(rv != -1, "Error installing flow mod")
358
Rich Lane97e99652013-01-02 17:23:20 -0800359@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700360class PortConfigMod(base_tests.SimpleProtocol):
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700361 """
362 Modify a bit in port config and verify changed
363
364 Get the switch configuration, modify the port configuration
365 and write it back; get the config again and verify changed.
366 Then set it back to the way it was.
367 """
368
369 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700370 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700371 for of_port, ifname in config["port_map"].items(): # Grab first port
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700372 break
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700373
Rich Lane477f4812012-10-04 22:49:00 -0700374 (hw_addr, port_config, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700375 port_config_get(self.controller, of_port)
Rich Lane477f4812012-10-04 22:49:00 -0700376 self.assertTrue(port_config is not None, "Did not get port config")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700377
Rich Lane9a003812012-10-04 17:17:59 -0700378 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700379 str(port_config & ofp.OFPPC_NO_FLOOD))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700380
381 rv = port_config_set(self.controller, of_port,
Rich Lane477f4812012-10-04 22:49:00 -0700382 port_config ^ ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700383 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lanebbd4cf92012-10-11 23:44:42 -0700384 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700385
386 # Verify change took place with same feature request
Rich Lane477f4812012-10-04 22:49:00 -0700387 (hw_addr, port_config2, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700388 port_config_get(self.controller, of_port)
389 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700390 str(port_config2 & ofp.OFPPC_NO_FLOOD))
391 self.assertTrue(port_config2 is not None, "Did not get port config2")
392 self.assertTrue(port_config2 & ofp.OFPPC_NO_FLOOD !=
393 port_config & ofp.OFPPC_NO_FLOOD,
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700394 "Bit change did not take")
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700395 # Set it back
Rich Lane477f4812012-10-04 22:49:00 -0700396 rv = port_config_set(self.controller, of_port, port_config,
Rich Lane9a003812012-10-04 17:17:59 -0700397 ofp.OFPPC_NO_FLOOD)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700398 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lanebbd4cf92012-10-11 23:44:42 -0700399 self.assertEqual(do_barrier(self.controller), 0, "Barrier failed")
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700400
Rich Laneb90a1c42012-10-05 09:16:05 -0700401class PortConfigModErr(base_tests.SimpleProtocol):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700402 """
403 Modify a bit in port config on an invalid port and verify
404 error message is received.
405 """
406
407 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700408 logging.info("Running " + str(self))
Ken Chiangaeb23d62012-08-23 21:20:07 -0700409
410 # pick a random bad port number
411 bad_port = random.randint(1, ofp.OFPP_MAX)
412 count = 0
Rich Lane477f4812012-10-04 22:49:00 -0700413 while (count < 50) and (bad_port in config["port_map"].keys()):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700414 bad_port = random.randint(1, ofp.OFPP_MAX)
415 count = count + 1
416 self.assertTrue(count < 50, "Error selecting bad port")
Rich Lane9a003812012-10-04 17:17:59 -0700417 logging.info("Select " + str(bad_port) + " as invalid port")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700418
419 rv = port_config_set(self.controller, bad_port,
Rich Lane9a003812012-10-04 17:17:59 -0700420 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700421 self.assertTrue(rv != -1, "Error sending port mod")
422
423 # poll for error message
424 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700425 (response, raw) = self.controller.poll(ofp.OFPT_ERROR)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700426 if not response: # Timeout
427 break
428 if response.code == ofp.OFPPMFC_BAD_PORT:
Rich Lane9a003812012-10-04 17:17:59 -0700429 logging.info("Received error message with OFPPMFC_BAD_PORT code")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700430 break
Rich Lane477f4812012-10-04 22:49:00 -0700431 if not config["relax"]: # Only one attempt to match
Ken Chiangaeb23d62012-08-23 21:20:07 -0700432 break
433 count += 1
434 if count > 10: # Too many tries
435 break
436
437 self.assertTrue(response is not None, 'Did not receive error message')
438
Rich Lane97e99652013-01-02 17:23:20 -0800439@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700440class BadMessage(base_tests.SimpleProtocol):
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700441 """
442 Send a message with a bad type and verify an error is returned
443 """
444
445 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700446 logging.info("Running " + str(self))
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700447 request = illegal_message.illegal_message_type()
448
Dan Talaycoc689a792012-09-28 14:22:53 -0700449 reply, pkt = self.controller.transact(request)
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700450 self.assertTrue(reply is not None, "Did not get response to bad req")
451 self.assertTrue(reply.header.type == ofp.OFPT_ERROR,
452 "reply not an error message")
453 self.assertTrue(reply.type == ofp.OFPET_BAD_REQUEST,
454 "reply error type is not bad request")
455 self.assertTrue(reply.code == ofp.OFPBRC_BAD_TYPE,
456 "reply error code is not bad type")
457
Dan Talaycodba244e2010-02-15 14:08:53 -0800458if __name__ == "__main__":
Dan Talayco2c0dba32010-03-06 22:47:06 -0800459 print "Please run through oft script: ./oft --test_spec=basic"