blob: 6e0e4d0d250cb8321a0cb26f208e25e39de44276 [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
Dan Talayco2c0dba32010-03-06 22:47:06 -080024import oftest.dataplane as dataplane
Rich Laneb90a1c42012-10-05 09:16:05 -070025import oftest.base_tests as base_tests
Rich Laneaecd7162013-01-11 11:33:00 -080026import ofp
Dan Talayco2c0dba32010-03-06 22:47:06 -080027
Dan Talaycoe605b1b2012-09-18 06:56:20 -070028import oftest.illegal_message as illegal_message
29
Rich Laneda3b5ad2012-10-03 09:05:32 -070030from oftest.testutils import *
Dan Talayco6ce963a2010-03-07 21:58:13 -080031
Ken Chiangaeb23d62012-08-23 21:20:07 -070032TEST_VID_DEFAULT = 2
33
Rich Lane97e99652013-01-02 17:23:20 -080034@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -070035class Echo(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080036 """
37 Test echo response with no data
38 """
39 def runTest(self):
Rich Laneaecd7162013-01-11 11:33:00 -080040 request = ofp.message.echo_request()
Dan Talaycoe226eb12010-02-18 23:06:30 -080041 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070042 self.assertTrue(response is not None,
43 "Did not get echo reply")
Rich Laneb73808c2013-03-11 15:22:23 -070044 self.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080045 'response is not echo_reply')
Rich Laneb73808c2013-03-11 15:22:23 -070046 self.assertEqual(request.xid, response.xid,
Dan Talaycodba244e2010-02-15 14:08:53 -080047 'response xid != request xid')
48 self.assertEqual(len(response.data), 0, 'response data non-empty')
49
Rich Laneb90a1c42012-10-05 09:16:05 -070050class EchoWithData(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080051 """
52 Test echo response with short string data
53 """
54 def runTest(self):
Rich Laneaecd7162013-01-11 11:33:00 -080055 request = ofp.message.echo_request(data='OpenFlow Will Rule The World')
Dan Talaycoe226eb12010-02-18 23:06:30 -080056 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070057 self.assertTrue(response is not None,
58 "Did not get echo reply (with data)")
Rich Laneb73808c2013-03-11 15:22:23 -070059 self.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080060 'response is not echo_reply')
Rich Laneb73808c2013-03-11 15:22:23 -070061 self.assertEqual(request.xid, response.xid,
Dan Talaycodba244e2010-02-15 14:08:53 -080062 'response xid != request xid')
63 self.assertEqual(request.data, response.data,
64 'response data does not match request')
65
Rich Lane97e99652013-01-02 17:23:20 -080066@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -070067class PacketIn(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -080068 """
69 Test packet in function
Dan Talayco6ce963a2010-03-07 21:58:13 -080070
71 Send a packet to each dataplane port and verify that a packet
72 in message is received from the controller for each
Dan Talaycodba244e2010-02-15 14:08:53 -080073 """
74 def runTest(self):
75 # Construct packet to send to dataplane
Dan Talaycoe226eb12010-02-18 23:06:30 -080076 # Send packet to dataplane, once to each port
Dan Talaycodba244e2010-02-15 14:08:53 -080077 # Poll controller with expect message type packet in
Dan Talaycoe226eb12010-02-18 23:06:30 -080078
Rich Lane32bf9482013-01-03 17:26:30 -080079 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -080080 do_barrier(self.controller)
Dan Talayco6ce963a2010-03-07 21:58:13 -080081
Rich Lane2014f9b2012-10-05 15:29:40 -070082 vid = test_param_get('vid', default=TEST_VID_DEFAULT)
Ken Chiangaeb23d62012-08-23 21:20:07 -070083
Rich Lane477f4812012-10-04 22:49:00 -070084 for of_port in config["port_map"].keys():
Ed Swierk0aeff8c2012-03-23 20:27:18 -070085 for pkt, pt in [
86 (simple_tcp_packet(), "simple TCP packet"),
Rich Laned0478ff2013-03-11 12:46:58 -070087 (simple_tcp_packet(dl_vlan_enable=True,vlan_vid=vid,pktlen=108),
Ken Chiangaeb23d62012-08-23 21:20:07 -070088 "simple tagged TCP packet"),
Ed Swierk0aeff8c2012-03-23 20:27:18 -070089 (simple_eth_packet(), "simple Ethernet packet"),
90 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -080091
Rich Lane9a003812012-10-04 17:17:59 -070092 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -070093 self.dataplane.send(of_port, str(pkt))
Rich Lane4c504f32013-06-07 17:24:14 -070094 verify_packet_in(self, str(pkt), of_port, ofp.OFPR_NO_MATCH)
Dan Talaycodba244e2010-02-15 14:08:53 -080095
Rich Laneb90a1c42012-10-05 09:16:05 -070096class PacketInBroadcastCheck(base_tests.SimpleDataPlane):
Dan Talayco1f648cb2012-05-03 09:37:56 -070097 """
98 Check if bcast pkts leak when no flows are present
99
100 Clear the flow table
101 Send in a broadcast pkt
102 Look for the packet on other dataplane ports.
103 """
Rich Laned1d9c282012-10-04 22:07:10 -0700104
Dan Talayco1f648cb2012-05-03 09:37:56 -0700105 def runTest(self):
106 # Need at least two ports
Rich Lane477f4812012-10-04 22:49:00 -0700107 self.assertTrue(len(config["port_map"]) > 1, "Too few ports for test")
Dan Talayco1f648cb2012-05-03 09:37:56 -0700108
Rich Lane32bf9482013-01-03 17:26:30 -0800109 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800110 do_barrier(self.controller)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700111
Rich Lane477f4812012-10-04 22:49:00 -0700112 of_ports = config["port_map"].keys()
Dan Talayco1f648cb2012-05-03 09:37:56 -0700113 d_port = of_ports[0]
Rich Laned0478ff2013-03-11 12:46:58 -0700114 pkt = simple_eth_packet(eth_dst='ff:ff:ff:ff:ff:ff')
Dan Talayco1f648cb2012-05-03 09:37:56 -0700115
Rich Lane9a003812012-10-04 17:17:59 -0700116 logging.info("BCast Leak Test, send to port %s" % d_port)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700117 self.dataplane.send(d_port, str(pkt))
118
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700119 (of_port, pkt_in, pkt_time) = self.dataplane.poll(exp_pkt=pkt)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700120 self.assertTrue(pkt_in is None,
121 'BCast packet received on port ' + str(of_port))
122
Rich Lane97e99652013-01-02 17:23:20 -0800123@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700124class PacketOut(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -0800125 """
126 Test packet out function
Dan Talayco6ce963a2010-03-07 21:58:13 -0800127
128 Send packet out message to controller for each dataplane port and
129 verify the packet appears on the appropriate dataplane port
Dan Talaycodba244e2010-02-15 14:08:53 -0800130 """
131 def runTest(self):
132 # Construct packet to send to dataplane
133 # Send packet to dataplane
134 # Poll controller with expect message type packet in
Dan Talayco41eae8b2010-03-10 13:57:06 -0800135
Rich Lane32bf9482013-01-03 17:26:30 -0800136 delete_all_flows(self.controller)
Dan Talaycodba244e2010-02-15 14:08:53 -0800137
138 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700139 of_ports = config["port_map"].keys()
Dan Talayco48370102010-03-03 15:17:33 -0800140 of_ports.sort()
141 for dp_port in of_ports:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700142 for outpkt, opt in [
143 (simple_tcp_packet(), "simple TCP packet"),
144 (simple_eth_packet(), "simple Ethernet packet"),
145 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -0800146
Rich Lane9a003812012-10-04 17:17:59 -0700147 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
Rich Laneaecd7162013-01-11 11:33:00 -0800148 msg = ofp.message.packet_out(in_port=ofp.OFPP_NONE,
Rich Lane0f0adc92013-01-04 15:13:02 -0800149 data=str(outpkt),
Rich Laneea8c4722013-04-04 15:30:20 -0700150 actions=[ofp.action.output(port=dp_port)],
151 buffer_id=0xffffffff)
Dan Talaycodba244e2010-02-15 14:08:53 -0800152
Rich Lane9a003812012-10-04 17:17:59 -0700153 logging.info("PacketOut to: " + str(dp_port))
Rich Lane5c3151c2013-01-03 17:15:41 -0800154 self.controller.message_send(msg)
Dan Talaycodba244e2010-02-15 14:08:53 -0800155
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700156 exp_pkt_arg = None
157 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -0700158 if config["relax"]:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700159 exp_pkt_arg = outpkt
160 exp_port = dp_port
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700161 (of_port, pkt, pkt_time) = self.dataplane.poll(port_number=exp_port,
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700162 exp_pkt=exp_pkt_arg)
163
164 self.assertTrue(pkt is not None, 'Packet not received')
Rich Lane9a003812012-10-04 17:17:59 -0700165 logging.info("PacketOut: got pkt from " + str(of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700166 if of_port is not None:
167 self.assertEqual(of_port, dp_port, "Unexpected receive port")
Ed Swierk506614a2012-03-29 08:16:59 -0700168 if not dataplane.match_exp_pkt(outpkt, pkt):
Rich Lane9a003812012-10-04 17:17:59 -0700169 logging.debug("Sent %s" % format_packet(outpkt))
170 logging.debug("Resp %s" % format_packet(
Dan Talayco2baf8b52012-03-30 09:55:42 -0700171 str(pkt)[:len(str(outpkt))]))
Dan Talaycodc6fca32012-03-30 10:05:49 -0700172 self.assertEqual(str(outpkt), str(pkt)[:len(str(outpkt))],
173 'Response packet does not match send packet')
Dan Talaycodba244e2010-02-15 14:08:53 -0800174
Rich Laneb90a1c42012-10-05 09:16:05 -0700175class PacketOutMC(base_tests.SimpleDataPlane):
Ken Chiang1bf01602012-04-04 10:48:23 -0700176 """
177 Test packet out to multiple output ports
178
179 Send packet out message to controller for 1 to N dataplane ports and
180 verify the packet appears on the appropriate ports
181 """
182 def runTest(self):
183 # Construct packet to send to dataplane
184 # Send packet to dataplane
185 # Poll controller with expect message type packet in
186
Rich Lane32bf9482013-01-03 17:26:30 -0800187 delete_all_flows(self.controller)
Ken Chiang1bf01602012-04-04 10:48:23 -0700188
189 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700190 of_ports = config["port_map"].keys()
Ken Chiang1bf01602012-04-04 10:48:23 -0700191 random.shuffle(of_ports)
192 for num_ports in range(1,len(of_ports)+1):
193 for outpkt, opt in [
194 (simple_tcp_packet(), "simple TCP packet"),
195 (simple_eth_packet(), "simple Ethernet packet"),
196 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
197
198 dp_ports = of_ports[0:num_ports]
Rich Lane9a003812012-10-04 17:17:59 -0700199 logging.info("PKT OUT test with " + opt +
Ken Chiang1bf01602012-04-04 10:48:23 -0700200 ", ports " + str(dp_ports))
Rich Laneaecd7162013-01-11 11:33:00 -0800201 actions = [ofp.action.output(port=port) for port in dp_ports]
202 msg = ofp.message.packet_out(in_port=ofp.OFPP_NONE,
Rich Lane0f0adc92013-01-04 15:13:02 -0800203 data=str(outpkt),
Rich Laneea8c4722013-04-04 15:30:20 -0700204 actions=actions,
205 buffer_id=0xffffffff)
Ken Chiang1bf01602012-04-04 10:48:23 -0700206
Rich Lane9a003812012-10-04 17:17:59 -0700207 logging.info("PacketOut to: " + str(dp_ports))
Rich Lane5c3151c2013-01-03 17:15:41 -0800208 self.controller.message_send(msg)
Ken Chiang1bf01602012-04-04 10:48:23 -0700209
210 receive_pkt_check(self.dataplane, outpkt, dp_ports,
211 set(of_ports).difference(dp_ports),
Rich Lane2014f9b2012-10-05 15:29:40 -0700212 self)
Ken Chiang1bf01602012-04-04 10:48:23 -0700213
Rich Laneb90a1c42012-10-05 09:16:05 -0700214class FlowStatsGet(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800215 """
216 Get stats
Dan Talayco2c0dba32010-03-06 22:47:06 -0800217
Dan Talayco6ce963a2010-03-07 21:58:13 -0800218 Simply verify stats get transaction
219 """
Rich Laned1d9c282012-10-04 22:07:10 -0700220
Dan Talayco6ce963a2010-03-07 21:58:13 -0800221 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700222 logging.info("Running StatsGet")
223 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700224 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800225 self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800226
Rich Lane9a003812012-10-04 17:17:59 -0700227 logging.info("Sending flow request")
Rich Laneaecd7162013-01-11 11:33:00 -0800228 request = ofp.message.flow_stats_request(out_port=ofp.OFPP_NONE,
Rich Lanec3c2ae12013-01-04 10:13:17 -0800229 table_id=0xff)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800230 request.match.wildcards = 0 # ofp.OFPFW_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700231 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700232 self.assertTrue(response is not None,
233 "Did not get response for flow stats")
Rich Lane9a003812012-10-04 17:17:59 -0700234 logging.debug(response.show())
Dan Talayco6ce963a2010-03-07 21:58:13 -0800235
Rich Laneb90a1c42012-10-05 09:16:05 -0700236class TableStatsGet(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700237 """
238 Get table stats
239
240 Simply verify table stats get transaction
241 """
242 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700243 logging.info("Running TableStatsGet")
244 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700245 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800246 self.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700247
Rich Lane9a003812012-10-04 17:17:59 -0700248 logging.info("Sending table stats request")
Rich Laneaecd7162013-01-11 11:33:00 -0800249 request = ofp.message.table_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700250 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700251 self.assertTrue(response is not None,
252 "Did not get reply for table stats")
Rich Lane9a003812012-10-04 17:17:59 -0700253 logging.debug(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700254
Rich Laneb90a1c42012-10-05 09:16:05 -0700255class DescStatsGet(base_tests.SimpleProtocol):
Ed Swierkae74c362012-04-02 08:21:41 -0700256 """
257 Get stats
258
259 Simply verify stats get transaction
260 """
261 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700262 logging.info("Running DescStatsGet")
Ed Swierkae74c362012-04-02 08:21:41 -0700263
Rich Lane9a003812012-10-04 17:17:59 -0700264 logging.info("Sending stats request")
Rich Laneaecd7162013-01-11 11:33:00 -0800265 request = ofp.message.desc_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700266 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700267 self.assertTrue(response is not None,
268 "Did not get reply for desc stats")
Rich Lane9a003812012-10-04 17:17:59 -0700269 logging.debug(response.show())
Ed Swierkae74c362012-04-02 08:21:41 -0700270
Rich Laneb90a1c42012-10-05 09:16:05 -0700271class FlowMod(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800272 """
273 Insert a flow
274
275 Simple verification of a flow mod transaction
276 """
277
278 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700279 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700280 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800281 self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800282
Rich Lane97e99652013-01-02 17:23:20 -0800283@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700284class PortConfigMod(base_tests.SimpleProtocol):
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700285 """
286 Modify a bit in port config and verify changed
287
288 Get the switch configuration, modify the port configuration
289 and write it back; get the config again and verify changed.
290 Then set it back to the way it was.
291 """
292
293 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700294 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700295 for of_port, ifname in config["port_map"].items(): # Grab first port
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700296 break
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700297
Rich Lane477f4812012-10-04 22:49:00 -0700298 (hw_addr, port_config, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700299 port_config_get(self.controller, of_port)
Rich Lane477f4812012-10-04 22:49:00 -0700300 self.assertTrue(port_config is not None, "Did not get port config")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700301
Rich Lane9a003812012-10-04 17:17:59 -0700302 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700303 str(port_config & ofp.OFPPC_NO_FLOOD))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700304
305 rv = port_config_set(self.controller, of_port,
Rich Lane477f4812012-10-04 22:49:00 -0700306 port_config ^ ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700307 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lane3a261d52013-01-03 17:45:08 -0800308 do_barrier(self.controller)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700309
310 # Verify change took place with same feature request
Rich Lane477f4812012-10-04 22:49:00 -0700311 (hw_addr, port_config2, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700312 port_config_get(self.controller, of_port)
313 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700314 str(port_config2 & ofp.OFPPC_NO_FLOOD))
315 self.assertTrue(port_config2 is not None, "Did not get port config2")
316 self.assertTrue(port_config2 & ofp.OFPPC_NO_FLOOD !=
317 port_config & ofp.OFPPC_NO_FLOOD,
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700318 "Bit change did not take")
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700319 # Set it back
Rich Lane477f4812012-10-04 22:49:00 -0700320 rv = port_config_set(self.controller, of_port, port_config,
Rich Lane9a003812012-10-04 17:17:59 -0700321 ofp.OFPPC_NO_FLOOD)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700322 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lane3a261d52013-01-03 17:45:08 -0800323 do_barrier(self.controller)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700324
Rich Laneb90a1c42012-10-05 09:16:05 -0700325class PortConfigModErr(base_tests.SimpleProtocol):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700326 """
327 Modify a bit in port config on an invalid port and verify
328 error message is received.
329 """
330
331 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700332 logging.info("Running " + str(self))
Ken Chiangaeb23d62012-08-23 21:20:07 -0700333
334 # pick a random bad port number
335 bad_port = random.randint(1, ofp.OFPP_MAX)
336 count = 0
Rich Lane477f4812012-10-04 22:49:00 -0700337 while (count < 50) and (bad_port in config["port_map"].keys()):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700338 bad_port = random.randint(1, ofp.OFPP_MAX)
339 count = count + 1
340 self.assertTrue(count < 50, "Error selecting bad port")
Rich Lane9a003812012-10-04 17:17:59 -0700341 logging.info("Select " + str(bad_port) + " as invalid port")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700342
343 rv = port_config_set(self.controller, bad_port,
Rich Lane9a003812012-10-04 17:17:59 -0700344 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700345 self.assertTrue(rv != -1, "Error sending port mod")
346
347 # poll for error message
348 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700349 (response, raw) = self.controller.poll(ofp.OFPT_ERROR)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700350 if not response: # Timeout
351 break
352 if response.code == ofp.OFPPMFC_BAD_PORT:
Rich Lane9a003812012-10-04 17:17:59 -0700353 logging.info("Received error message with OFPPMFC_BAD_PORT code")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700354 break
Rich Lane477f4812012-10-04 22:49:00 -0700355 if not config["relax"]: # Only one attempt to match
Ken Chiangaeb23d62012-08-23 21:20:07 -0700356 break
357 count += 1
358 if count > 10: # Too many tries
359 break
360
361 self.assertTrue(response is not None, 'Did not receive error message')
362
Rich Lane97e99652013-01-02 17:23:20 -0800363@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700364class BadMessage(base_tests.SimpleProtocol):
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700365 """
366 Send a message with a bad type and verify an error is returned
367 """
368
369 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700370 logging.info("Running " + str(self))
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700371 request = illegal_message.illegal_message_type()
372
Dan Talaycoc689a792012-09-28 14:22:53 -0700373 reply, pkt = self.controller.transact(request)
Rich Laneb73808c2013-03-11 15:22:23 -0700374 logging.info(repr(pkt))
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700375 self.assertTrue(reply is not None, "Did not get response to bad req")
Rich Laneb73808c2013-03-11 15:22:23 -0700376 self.assertTrue(reply.type == ofp.OFPT_ERROR,
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700377 "reply not an error message")
Rich Laneb73808c2013-03-11 15:22:23 -0700378 logging.info(reply.err_type)
Rich Lane4e361bb2013-03-11 13:57:31 -0700379 self.assertTrue(reply.err_type == ofp.OFPET_BAD_REQUEST,
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700380 "reply error type is not bad request")
381 self.assertTrue(reply.code == ofp.OFPBRC_BAD_TYPE,
382 "reply error code is not bad type")
383
Rich Lane5a9a1922013-01-11 14:29:30 -0800384@group('smoke')
385@version('1.1+')
386class TableModConfig(base_tests.SimpleProtocol):
387 """
388 Simple table modification
389
390 Mostly to make sure the switch correctly responds to these messages.
391 More complicated tests in the multi-tables.py tests
392 """
393 def runTest(self):
394 # First table should always exist
395 table_id = 0
396
397 def get_table_config():
398 request = ofp.message.table_stats_request()
399 response, _ = self.controller.transact(request)
400 try:
Rich Lane5fd6faf2013-03-11 13:30:20 -0700401 table_stats = [x for x in response.entries if x.table_id == table_id][0]
Rich Lane5a9a1922013-01-11 14:29:30 -0800402 except IndexError:
403 raise AssertionError("table id %d not found" % table_id)
404 return table_stats.config
405
406 # Get current configuration
407 orig_table_config = get_table_config()
408
409 # Change the configuration
410 if orig_table_config == ofp.OFPTC_TABLE_MISS_CONTROLLER:
411 new_table_config = ofp.OFPTC_TABLE_MISS_DROP
412 else:
413 new_table_config = ofp.OFPTC_TABLE_MISS_CONTROLLER
414 request = ofp.message.table_mod(table_id=table_id, config=new_table_config)
415 self.controller.message_send(request)
416 self.controller.transact(ofp.message.barrier_request())
417
418 # Check the configuration took
419 self.assertEqual(get_table_config(), new_table_config)
420
421 # Change the configuration back
422 request = ofp.message.table_mod(table_id=table_id, config=orig_table_config)
423 self.controller.message_send(request)
424 self.controller.transact(ofp.message.barrier_request())
425
Dan Talaycodba244e2010-02-15 14:08:53 -0800426if __name__ == "__main__":
Dan Talayco2c0dba32010-03-06 22:47:06 -0800427 print "Please run through oft script: ./oft --test_spec=basic"