blob: 544c2c3d0de7dfb013700aaa11071da209096438 [file] [log] [blame]
Matteo Scandoloa229eca2017-08-08 13:05:28 -07001
2# Copyright 2017-present Open Networking Foundation
3#
4# Licensed under the Apache License, Version 2.0 (the "License");
5# you may not use this file except in compliance with the License.
6# You may obtain a copy of the License at
7#
8# http://www.apache.org/licenses/LICENSE-2.0
9#
10# Unless required by applicable law or agreed to in writing, software
11# distributed under the License is distributed on an "AS IS" BASIS,
12# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13# See the License for the specific language governing permissions and
14# limitations under the License.
15
16
Dan Talaycodba244e2010-02-15 14:08:53 -080017"""
Dan Talayco79f36082010-03-11 16:53:53 -080018Basic protocol and dataplane test cases
Dan Talaycodba244e2010-02-15 14:08:53 -080019
Dan Talayco48370102010-03-03 15:17:33 -080020It is recommended that these definitions be kept in their own
21namespace as different groups of tests will likely define
22similar identifiers.
23
Dan Talaycodba244e2010-02-15 14:08:53 -080024Current Assumptions:
25
Dan Talaycodba244e2010-02-15 14:08:53 -080026 The switch is actively attempting to contact the controller at the address
Rich Lane477f4812012-10-04 22:49:00 -070027indicated in oftest.config.
Dan Talaycodba244e2010-02-15 14:08:53 -080028
29"""
30
Dan Talaycodba244e2010-02-15 14:08:53 -080031import time
32import sys
Dan Talayco48370102010-03-03 15:17:33 -080033import logging
Dan Talaycodba244e2010-02-15 14:08:53 -080034
Dan Talayco2c0dba32010-03-06 22:47:06 -080035import unittest
Ken Chiang1bf01602012-04-04 10:48:23 -070036import random
Dan Talayco2c0dba32010-03-06 22:47:06 -080037
Rich Lane477f4812012-10-04 22:49:00 -070038from oftest import config
Dan Talayco2c0dba32010-03-06 22:47:06 -080039import oftest.controller as controller
Dan Talayco2c0dba32010-03-06 22:47:06 -080040import oftest.dataplane as dataplane
Rich Laneb90a1c42012-10-05 09:16:05 -070041import oftest.base_tests as base_tests
Rich Laneaecd7162013-01-11 11:33:00 -080042import ofp
Dan Talayco2c0dba32010-03-06 22:47:06 -080043
Dan Talaycoe605b1b2012-09-18 06:56:20 -070044import oftest.illegal_message as illegal_message
45
Rich Laneda3b5ad2012-10-03 09:05:32 -070046from oftest.testutils import *
Dan Talayco6ce963a2010-03-07 21:58:13 -080047
Ken Chiangaeb23d62012-08-23 21:20:07 -070048TEST_VID_DEFAULT = 2
49
Rich Lane97e99652013-01-02 17:23:20 -080050@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -070051class Echo(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080052 """
53 Test echo response with no data
54 """
55 def runTest(self):
Rich Laneaecd7162013-01-11 11:33:00 -080056 request = ofp.message.echo_request()
Dan Talaycoe226eb12010-02-18 23:06:30 -080057 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070058 self.assertTrue(response is not None,
59 "Did not get echo reply")
Rich Laneb73808c2013-03-11 15:22:23 -070060 self.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080061 'response is not echo_reply')
Rich Laneb73808c2013-03-11 15:22:23 -070062 self.assertEqual(request.xid, response.xid,
Dan Talaycodba244e2010-02-15 14:08:53 -080063 'response xid != request xid')
64 self.assertEqual(len(response.data), 0, 'response data non-empty')
65
Rich Laneb90a1c42012-10-05 09:16:05 -070066class EchoWithData(base_tests.SimpleProtocol):
Dan Talaycodba244e2010-02-15 14:08:53 -080067 """
68 Test echo response with short string data
69 """
70 def runTest(self):
Rich Laneaecd7162013-01-11 11:33:00 -080071 request = ofp.message.echo_request(data='OpenFlow Will Rule The World')
Dan Talaycoe226eb12010-02-18 23:06:30 -080072 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -070073 self.assertTrue(response is not None,
74 "Did not get echo reply (with data)")
Rich Laneb73808c2013-03-11 15:22:23 -070075 self.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,
Dan Talaycoa92e75b2010-02-16 20:53:56 -080076 'response is not echo_reply')
Rich Laneb73808c2013-03-11 15:22:23 -070077 self.assertEqual(request.xid, response.xid,
Dan Talaycodba244e2010-02-15 14:08:53 -080078 'response xid != request xid')
79 self.assertEqual(request.data, response.data,
80 'response data does not match request')
81
Rich Lane97e99652013-01-02 17:23:20 -080082@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -070083class PacketIn(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -080084 """
85 Test packet in function
Dan Talayco6ce963a2010-03-07 21:58:13 -080086
87 Send a packet to each dataplane port and verify that a packet
88 in message is received from the controller for each
Dan Talaycodba244e2010-02-15 14:08:53 -080089 """
90 def runTest(self):
91 # Construct packet to send to dataplane
Dan Talaycoe226eb12010-02-18 23:06:30 -080092 # Send packet to dataplane, once to each port
Dan Talaycodba244e2010-02-15 14:08:53 -080093 # Poll controller with expect message type packet in
Dan Talaycoe226eb12010-02-18 23:06:30 -080094
Rich Lane32bf9482013-01-03 17:26:30 -080095 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -080096 do_barrier(self.controller)
Dan Talayco6ce963a2010-03-07 21:58:13 -080097
Rich Lane2014f9b2012-10-05 15:29:40 -070098 vid = test_param_get('vid', default=TEST_VID_DEFAULT)
Ken Chiangaeb23d62012-08-23 21:20:07 -070099
Rich Lane477f4812012-10-04 22:49:00 -0700100 for of_port in config["port_map"].keys():
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700101 for pkt, pt in [
102 (simple_tcp_packet(), "simple TCP packet"),
Rich Laned0478ff2013-03-11 12:46:58 -0700103 (simple_tcp_packet(dl_vlan_enable=True,vlan_vid=vid,pktlen=108),
Ken Chiangaeb23d62012-08-23 21:20:07 -0700104 "simple tagged TCP packet"),
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700105 (simple_eth_packet(), "simple Ethernet packet"),
106 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -0800107
Rich Lane9a003812012-10-04 17:17:59 -0700108 logging.info("PKT IN test with %s, port %s" % (pt, of_port))
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700109 self.dataplane.send(of_port, str(pkt))
Rich Lane4c504f32013-06-07 17:24:14 -0700110 verify_packet_in(self, str(pkt), of_port, ofp.OFPR_NO_MATCH)
Dan Talaycodba244e2010-02-15 14:08:53 -0800111
Rich Laneb90a1c42012-10-05 09:16:05 -0700112class PacketInBroadcastCheck(base_tests.SimpleDataPlane):
Dan Talayco1f648cb2012-05-03 09:37:56 -0700113 """
114 Check if bcast pkts leak when no flows are present
115
116 Clear the flow table
117 Send in a broadcast pkt
118 Look for the packet on other dataplane ports.
119 """
Rich Laned1d9c282012-10-04 22:07:10 -0700120
Dan Talayco1f648cb2012-05-03 09:37:56 -0700121 def runTest(self):
122 # Need at least two ports
Rich Lane477f4812012-10-04 22:49:00 -0700123 self.assertTrue(len(config["port_map"]) > 1, "Too few ports for test")
Dan Talayco1f648cb2012-05-03 09:37:56 -0700124
Rich Lane32bf9482013-01-03 17:26:30 -0800125 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800126 do_barrier(self.controller)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700127
Rich Lane477f4812012-10-04 22:49:00 -0700128 of_ports = config["port_map"].keys()
Dan Talayco1f648cb2012-05-03 09:37:56 -0700129 d_port = of_ports[0]
Rich Laned0478ff2013-03-11 12:46:58 -0700130 pkt = simple_eth_packet(eth_dst='ff:ff:ff:ff:ff:ff')
Dan Talayco1f648cb2012-05-03 09:37:56 -0700131
Rich Lane9a003812012-10-04 17:17:59 -0700132 logging.info("BCast Leak Test, send to port %s" % d_port)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700133 self.dataplane.send(d_port, str(pkt))
134
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700135 (of_port, pkt_in, pkt_time) = self.dataplane.poll(exp_pkt=pkt)
Dan Talayco1f648cb2012-05-03 09:37:56 -0700136 self.assertTrue(pkt_in is None,
137 'BCast packet received on port ' + str(of_port))
138
Rich Lane97e99652013-01-02 17:23:20 -0800139@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700140class PacketOut(base_tests.SimpleDataPlane):
Dan Talaycodba244e2010-02-15 14:08:53 -0800141 """
142 Test packet out function
Dan Talayco6ce963a2010-03-07 21:58:13 -0800143
144 Send packet out message to controller for each dataplane port and
145 verify the packet appears on the appropriate dataplane port
Dan Talaycodba244e2010-02-15 14:08:53 -0800146 """
147 def runTest(self):
148 # Construct packet to send to dataplane
149 # Send packet to dataplane
150 # Poll controller with expect message type packet in
Dan Talayco41eae8b2010-03-10 13:57:06 -0800151
Rich Lane32bf9482013-01-03 17:26:30 -0800152 delete_all_flows(self.controller)
Dan Talaycodba244e2010-02-15 14:08:53 -0800153
154 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700155 of_ports = config["port_map"].keys()
Dan Talayco48370102010-03-03 15:17:33 -0800156 of_ports.sort()
157 for dp_port in of_ports:
Ed Swierk0aeff8c2012-03-23 20:27:18 -0700158 for outpkt, opt in [
159 (simple_tcp_packet(), "simple TCP packet"),
160 (simple_eth_packet(), "simple Ethernet packet"),
161 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
Dan Talaycodba244e2010-02-15 14:08:53 -0800162
Rich Lane9a003812012-10-04 17:17:59 -0700163 logging.info("PKT OUT test with %s, port %s" % (opt, dp_port))
Rich Laneaecd7162013-01-11 11:33:00 -0800164 msg = ofp.message.packet_out(in_port=ofp.OFPP_NONE,
Rich Lane0f0adc92013-01-04 15:13:02 -0800165 data=str(outpkt),
Rich Laneea8c4722013-04-04 15:30:20 -0700166 actions=[ofp.action.output(port=dp_port)],
167 buffer_id=0xffffffff)
Dan Talaycodba244e2010-02-15 14:08:53 -0800168
Rich Lane9a003812012-10-04 17:17:59 -0700169 logging.info("PacketOut to: " + str(dp_port))
Rich Lane5c3151c2013-01-03 17:15:41 -0800170 self.controller.message_send(msg)
Dan Talaycodba244e2010-02-15 14:08:53 -0800171
Rich Lanee4b384d2013-09-13 14:33:40 -0700172 verify_packets(self, outpkt, [dp_port])
Dan Talaycodba244e2010-02-15 14:08:53 -0800173
Rich Laneb90a1c42012-10-05 09:16:05 -0700174class PacketOutMC(base_tests.SimpleDataPlane):
Ken Chiang1bf01602012-04-04 10:48:23 -0700175 """
176 Test packet out to multiple output ports
177
178 Send packet out message to controller for 1 to N dataplane ports and
179 verify the packet appears on the appropriate ports
180 """
181 def runTest(self):
182 # Construct packet to send to dataplane
183 # Send packet to dataplane
184 # Poll controller with expect message type packet in
185
Rich Lane32bf9482013-01-03 17:26:30 -0800186 delete_all_flows(self.controller)
Ken Chiang1bf01602012-04-04 10:48:23 -0700187
188 # These will get put into function
Rich Lane477f4812012-10-04 22:49:00 -0700189 of_ports = config["port_map"].keys()
Ken Chiang1bf01602012-04-04 10:48:23 -0700190 random.shuffle(of_ports)
191 for num_ports in range(1,len(of_ports)+1):
192 for outpkt, opt in [
193 (simple_tcp_packet(), "simple TCP packet"),
194 (simple_eth_packet(), "simple Ethernet packet"),
195 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
196
197 dp_ports = of_ports[0:num_ports]
Rich Lane9a003812012-10-04 17:17:59 -0700198 logging.info("PKT OUT test with " + opt +
Ken Chiang1bf01602012-04-04 10:48:23 -0700199 ", ports " + str(dp_ports))
Rich Laneaecd7162013-01-11 11:33:00 -0800200 actions = [ofp.action.output(port=port) for port in dp_ports]
201 msg = ofp.message.packet_out(in_port=ofp.OFPP_NONE,
Rich Lane0f0adc92013-01-04 15:13:02 -0800202 data=str(outpkt),
Rich Laneea8c4722013-04-04 15:30:20 -0700203 actions=actions,
204 buffer_id=0xffffffff)
Ken Chiang1bf01602012-04-04 10:48:23 -0700205
Rich Lane9a003812012-10-04 17:17:59 -0700206 logging.info("PacketOut to: " + str(dp_ports))
Rich Lane5c3151c2013-01-03 17:15:41 -0800207 self.controller.message_send(msg)
Ken Chiang1bf01602012-04-04 10:48:23 -0700208
Rich Lanee4b384d2013-09-13 14:33:40 -0700209 verify_packets(self, outpkt, dp_ports)
Ken Chiang1bf01602012-04-04 10:48:23 -0700210
Rich Laneb90a1c42012-10-05 09:16:05 -0700211class FlowStatsGet(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800212 """
213 Get stats
Dan Talayco2c0dba32010-03-06 22:47:06 -0800214
Dan Talayco6ce963a2010-03-07 21:58:13 -0800215 Simply verify stats get transaction
216 """
Rich Laned1d9c282012-10-04 22:07:10 -0700217
Dan Talayco6ce963a2010-03-07 21:58:13 -0800218 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700219 logging.info("Running StatsGet")
220 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700221 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800222 self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800223
Rich Lane9a003812012-10-04 17:17:59 -0700224 logging.info("Sending flow request")
Rich Laneaecd7162013-01-11 11:33:00 -0800225 request = ofp.message.flow_stats_request(out_port=ofp.OFPP_NONE,
Rich Lanec3c2ae12013-01-04 10:13:17 -0800226 table_id=0xff)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800227 request.match.wildcards = 0 # ofp.OFPFW_ALL
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700228 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700229 self.assertTrue(response is not None,
230 "Did not get response for flow stats")
Rich Lane9a003812012-10-04 17:17:59 -0700231 logging.debug(response.show())
Dan Talayco6ce963a2010-03-07 21:58:13 -0800232
Rich Laneb90a1c42012-10-05 09:16:05 -0700233class TableStatsGet(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700234 """
235 Get table stats
236
237 Simply verify table stats get transaction
238 """
239 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700240 logging.info("Running TableStatsGet")
241 logging.info("Inserting trial flow")
Rich Lane477f4812012-10-04 22:49:00 -0700242 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800243 self.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700244
Rich Lane9a003812012-10-04 17:17:59 -0700245 logging.info("Sending table stats request")
Rich Laneaecd7162013-01-11 11:33:00 -0800246 request = ofp.message.table_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700247 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700248 self.assertTrue(response is not None,
249 "Did not get reply for table stats")
Rich Lane9a003812012-10-04 17:17:59 -0700250 logging.debug(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700251
Rich Laneb90a1c42012-10-05 09:16:05 -0700252class DescStatsGet(base_tests.SimpleProtocol):
Ed Swierkae74c362012-04-02 08:21:41 -0700253 """
254 Get stats
255
256 Simply verify stats get transaction
257 """
258 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700259 logging.info("Running DescStatsGet")
Ed Swierkae74c362012-04-02 08:21:41 -0700260
Rich Lane9a003812012-10-04 17:17:59 -0700261 logging.info("Sending stats request")
Rich Laneaecd7162013-01-11 11:33:00 -0800262 request = ofp.message.desc_stats_request()
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700263 response, pkt = self.controller.transact(request)
Dan Talayco97d4f362012-09-18 03:22:09 -0700264 self.assertTrue(response is not None,
265 "Did not get reply for desc stats")
Rich Lane9a003812012-10-04 17:17:59 -0700266 logging.debug(response.show())
Ed Swierkae74c362012-04-02 08:21:41 -0700267
Rich Laneb90a1c42012-10-05 09:16:05 -0700268class FlowMod(base_tests.SimpleProtocol):
Dan Talayco6ce963a2010-03-07 21:58:13 -0800269 """
270 Insert a flow
271
272 Simple verification of a flow mod transaction
273 """
274
275 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700276 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700277 request = flow_mod_gen(config["port_map"], True)
Rich Lane5c3151c2013-01-03 17:15:41 -0800278 self.controller.message_send(request)
Dan Talayco41eae8b2010-03-10 13:57:06 -0800279
Rich Lane97e99652013-01-02 17:23:20 -0800280@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700281class PortConfigMod(base_tests.SimpleProtocol):
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700282 """
283 Modify a bit in port config and verify changed
284
285 Get the switch configuration, modify the port configuration
286 and write it back; get the config again and verify changed.
287 Then set it back to the way it was.
288 """
289
290 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700291 logging.info("Running " + str(self))
Rich Lane477f4812012-10-04 22:49:00 -0700292 for of_port, ifname in config["port_map"].items(): # Grab first port
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700293 break
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700294
Rich Lane477f4812012-10-04 22:49:00 -0700295 (hw_addr, port_config, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700296 port_config_get(self.controller, of_port)
Rich Lane477f4812012-10-04 22:49:00 -0700297 self.assertTrue(port_config is not None, "Did not get port config")
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700298
Rich Lane9a003812012-10-04 17:17:59 -0700299 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700300 str(port_config & ofp.OFPPC_NO_FLOOD))
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700301
302 rv = port_config_set(self.controller, of_port,
Rich Lane477f4812012-10-04 22:49:00 -0700303 port_config ^ ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700304 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lane3a261d52013-01-03 17:45:08 -0800305 do_barrier(self.controller)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700306
307 # Verify change took place with same feature request
Rich Lane477f4812012-10-04 22:49:00 -0700308 (hw_addr, port_config2, advert) = \
Rich Lane9a003812012-10-04 17:17:59 -0700309 port_config_get(self.controller, of_port)
310 logging.debug("No flood bit port " + str(of_port) + " is now " +
Rich Lane477f4812012-10-04 22:49:00 -0700311 str(port_config2 & ofp.OFPPC_NO_FLOOD))
312 self.assertTrue(port_config2 is not None, "Did not get port config2")
313 self.assertTrue(port_config2 & ofp.OFPPC_NO_FLOOD !=
314 port_config & ofp.OFPPC_NO_FLOOD,
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700315 "Bit change did not take")
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700316 # Set it back
Rich Lane477f4812012-10-04 22:49:00 -0700317 rv = port_config_set(self.controller, of_port, port_config,
Rich Lane9a003812012-10-04 17:17:59 -0700318 ofp.OFPPC_NO_FLOOD)
Dan Talayco9f47f4d2010-06-03 13:54:37 -0700319 self.assertTrue(rv != -1, "Error sending port mod")
Rich Lane3a261d52013-01-03 17:45:08 -0800320 do_barrier(self.controller)
Dan Talaycob3f43fe2010-05-13 14:24:20 -0700321
Rich Laneb90a1c42012-10-05 09:16:05 -0700322class PortConfigModErr(base_tests.SimpleProtocol):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700323 """
324 Modify a bit in port config on an invalid port and verify
325 error message is received.
326 """
327
328 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700329 logging.info("Running " + str(self))
Ken Chiangaeb23d62012-08-23 21:20:07 -0700330
331 # pick a random bad port number
332 bad_port = random.randint(1, ofp.OFPP_MAX)
333 count = 0
Rich Lane477f4812012-10-04 22:49:00 -0700334 while (count < 50) and (bad_port in config["port_map"].keys()):
Ken Chiangaeb23d62012-08-23 21:20:07 -0700335 bad_port = random.randint(1, ofp.OFPP_MAX)
336 count = count + 1
337 self.assertTrue(count < 50, "Error selecting bad port")
Rich Lane9a003812012-10-04 17:17:59 -0700338 logging.info("Select " + str(bad_port) + " as invalid port")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700339
340 rv = port_config_set(self.controller, bad_port,
Rich Lane9a003812012-10-04 17:17:59 -0700341 ofp.OFPPC_NO_FLOOD, ofp.OFPPC_NO_FLOOD)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700342 self.assertTrue(rv != -1, "Error sending port mod")
343
344 # poll for error message
345 while True:
Dan Talaycoc689a792012-09-28 14:22:53 -0700346 (response, raw) = self.controller.poll(ofp.OFPT_ERROR)
Ken Chiangaeb23d62012-08-23 21:20:07 -0700347 if not response: # Timeout
348 break
349 if response.code == ofp.OFPPMFC_BAD_PORT:
Rich Lane9a003812012-10-04 17:17:59 -0700350 logging.info("Received error message with OFPPMFC_BAD_PORT code")
Ken Chiangaeb23d62012-08-23 21:20:07 -0700351 break
Rich Lane477f4812012-10-04 22:49:00 -0700352 if not config["relax"]: # Only one attempt to match
Ken Chiangaeb23d62012-08-23 21:20:07 -0700353 break
354 count += 1
355 if count > 10: # Too many tries
356 break
357
358 self.assertTrue(response is not None, 'Did not receive error message')
359
Rich Lane97e99652013-01-02 17:23:20 -0800360@group('smoke')
Rich Laneb90a1c42012-10-05 09:16:05 -0700361class BadMessage(base_tests.SimpleProtocol):
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700362 """
363 Send a message with a bad type and verify an error is returned
364 """
365
366 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700367 logging.info("Running " + str(self))
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700368 request = illegal_message.illegal_message_type()
369
Dan Talaycoc689a792012-09-28 14:22:53 -0700370 reply, pkt = self.controller.transact(request)
Rich Laneb73808c2013-03-11 15:22:23 -0700371 logging.info(repr(pkt))
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700372 self.assertTrue(reply is not None, "Did not get response to bad req")
Rich Laneb73808c2013-03-11 15:22:23 -0700373 self.assertTrue(reply.type == ofp.OFPT_ERROR,
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700374 "reply not an error message")
Rich Laneb73808c2013-03-11 15:22:23 -0700375 logging.info(reply.err_type)
Rich Lane4e361bb2013-03-11 13:57:31 -0700376 self.assertTrue(reply.err_type == ofp.OFPET_BAD_REQUEST,
Dan Talaycoe605b1b2012-09-18 06:56:20 -0700377 "reply error type is not bad request")
378 self.assertTrue(reply.code == ofp.OFPBRC_BAD_TYPE,
379 "reply error code is not bad type")
380
Rich Lane5a9a1922013-01-11 14:29:30 -0800381@group('smoke')
382@version('1.1+')
383class TableModConfig(base_tests.SimpleProtocol):
384 """
385 Simple table modification
386
387 Mostly to make sure the switch correctly responds to these messages.
388 More complicated tests in the multi-tables.py tests
389 """
390 def runTest(self):
391 # First table should always exist
392 table_id = 0
393
394 def get_table_config():
395 request = ofp.message.table_stats_request()
396 response, _ = self.controller.transact(request)
397 try:
Rich Lane5fd6faf2013-03-11 13:30:20 -0700398 table_stats = [x for x in response.entries if x.table_id == table_id][0]
Rich Lane5a9a1922013-01-11 14:29:30 -0800399 except IndexError:
400 raise AssertionError("table id %d not found" % table_id)
401 return table_stats.config
402
403 # Get current configuration
404 orig_table_config = get_table_config()
405
406 # Change the configuration
407 if orig_table_config == ofp.OFPTC_TABLE_MISS_CONTROLLER:
408 new_table_config = ofp.OFPTC_TABLE_MISS_DROP
409 else:
410 new_table_config = ofp.OFPTC_TABLE_MISS_CONTROLLER
411 request = ofp.message.table_mod(table_id=table_id, config=new_table_config)
412 self.controller.message_send(request)
413 self.controller.transact(ofp.message.barrier_request())
414
415 # Check the configuration took
416 self.assertEqual(get_table_config(), new_table_config)
417
418 # Change the configuration back
419 request = ofp.message.table_mod(table_id=table_id, config=orig_table_config)
420 self.controller.message_send(request)
421 self.controller.transact(ofp.message.barrier_request())
422
Dan Talaycodba244e2010-02-15 14:08:53 -0800423if __name__ == "__main__":
Dan Talayco2c0dba32010-03-06 22:47:06 -0800424 print "Please run through oft script: ./oft --test_spec=basic"