blob: ded727e5782eaf8df61643e2b5695b3bcd914346 [file] [log] [blame]
ShreyaPandita9306c772012-09-28 12:21:40 -04001"""These tests fall under Conformance Test-Suite (OF-SWITCH-1.0.0 TestCases).
2 Refer Documentation -- Detailed testing methodology
3 <Some of test-cases are directly taken from oftest> """
4
5"Test Suite 2 --> Openflow Protocol messages"
6
7
8import logging
9
10import unittest
11import random
12
Rich Lane477f4812012-10-04 22:49:00 -070013from oftest import config
ShreyaPandita9306c772012-09-28 12:21:40 -040014import oftest.controller as controller
Rich Laned7b0ffa2013-03-08 15:53:42 -080015import ofp
ShreyaPandita9306c772012-09-28 12:21:40 -040016import oftest.dataplane as dataplane
ShreyaPandita9306c772012-09-28 12:21:40 -040017import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070018import oftest.base_tests as base_tests
ShreyaPandita9306c772012-09-28 12:21:40 -040019
Rich Laneda3b5ad2012-10-03 09:05:32 -070020from oftest.testutils import *
ShreyaPandita9306c772012-09-28 12:21:40 -040021from time import sleep
22from FuncUtils import *
23
Rich Laneb90a1c42012-10-05 09:16:05 -070024class FeaturesRequest(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -040025
26 """Verify Features_Request-Reply is implemented
27 a) Send OFPT_FEATURES_REQUEST
28 b) Verify OFPT_FEATURES_REPLY is received without errors"""
29
30 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -070031 logging.info("Running Features_Request test")
ShreyaPandita9306c772012-09-28 12:21:40 -040032
Rich Lane477f4812012-10-04 22:49:00 -070033 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -040034 of_ports.sort()
35
36 #Clear switch state
Rich Lane32bf9482013-01-03 17:26:30 -080037 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -040038
Rich Lane9a003812012-10-04 17:17:59 -070039 logging.info("Sending Features_Request")
40 logging.info("Expecting Features_Reply")
ShreyaPandita9306c772012-09-28 12:21:40 -040041
Rich Lane28fa9272013-03-08 16:00:25 -080042 request = ofp.message.features_request()
Rich Lane5c3151c2013-01-03 17:15:41 -080043 self.controller.message_send(request)
ShreyaPandita9306c772012-09-28 12:21:40 -040044
45 (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_FEATURES_REPLY,
46 timeout=2)
47 self.assertTrue(response is not None,
48 'Did not receive Features Reply')
49
50
Rich Laneb90a1c42012-10-05 09:16:05 -070051class ConfigurationRequest(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -040052
53 """Check basic Get Config request is implemented
54 a) Send OFPT_GET_CONFIG_REQUEST
55 b) Verify OFPT_GET_CONFIG_REPLY is received without errors"""
56
57 def runTest(self):
58
Rich Lane9a003812012-10-04 17:17:59 -070059 logging.info("Running Configuration_Request test ")
ShreyaPandita9306c772012-09-28 12:21:40 -040060
Rich Lane477f4812012-10-04 22:49:00 -070061 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -040062 of_ports.sort()
63
64 #Clear switch state
Rich Lane32bf9482013-01-03 17:26:30 -080065 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -040066
Rich Lane9a003812012-10-04 17:17:59 -070067 logging.info("Sending OFPT_GET_CONFIG_REQUEST ")
68 logging.info("Expecting OFPT_GET_CONFIG_REPLY ")
ShreyaPandita9306c772012-09-28 12:21:40 -040069
Rich Lane28fa9272013-03-08 16:00:25 -080070 request = ofp.message.get_config_request()
Rich Lane5c3151c2013-01-03 17:15:41 -080071 self.controller.message_send(request)
ShreyaPandita9306c772012-09-28 12:21:40 -040072
73 (response, pkt) = self.controller.poll(exp_msg=ofp.OFPT_GET_CONFIG_REPLY,
74 timeout=2)
75 self.assertTrue(response is not None,
76 'Did not receive OFPT_GET_CONFIG_REPLY')
77
Rich Laneb90a1c42012-10-05 09:16:05 -070078class ModifyStateAdd(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -040079
80 """Check basic Flow Add request is implemented
81 a) Send OFPT_FLOW_MOD , command = OFPFC_ADD
82 c) Send ofp_table_stats request , verify active_count=1 in reply"""
83
84 def runTest(self):
85
Rich Lane9a003812012-10-04 17:17:59 -070086 logging.info("Running Modify_State_Add test")
ShreyaPandita9306c772012-09-28 12:21:40 -040087
Rich Lane477f4812012-10-04 22:49:00 -070088 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -040089 of_ports.sort()
90
91 #Clear switch state
Rich Lane32bf9482013-01-03 17:26:30 -080092 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -040093
Rich Lane9a003812012-10-04 17:17:59 -070094 logging.info("Inserting a flow entry")
95 logging.info("Expecting active_count=1 in table_stats_reply")
ShreyaPandita9306c772012-09-28 12:21:40 -040096
97 #Insert a flow entry matching on ingress_port
ShreyaPandita8dab4662012-11-02 13:40:14 -040098 (pkt,match) = wildcard_all_except_ingress(self,of_ports)
ShreyaPandita9306c772012-09-28 12:21:40 -040099
100 # Send Table_Stats_Request and verify flow gets inserted.
ShreyaPandita8dab4662012-11-02 13:40:14 -0400101 verify_tablestats(self,expect_active=1)
ShreyaPandita9306c772012-09-28 12:21:40 -0400102
103
Rich Laneb90a1c42012-10-05 09:16:05 -0700104class ModifyStateDelete(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -0400105
106 """Check Basic Flow Delete request is implemented
107 a) Send OFPT_FLOW_MOD, command = OFPFC_ADD
108 b) Send ofp_table_stats request , verify active_count=1 in reply
109 c) Send OFPT_FLOW_MOD, command = OFPFC_DELETE
110 c) Send ofp_table_stats request , verify active_count=0 in reply"""
111
112 def runTest(self):
113
Rich Lane9a003812012-10-04 17:17:59 -0700114 logging.info("Running Modify_State_Delete test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400115
Rich Lane477f4812012-10-04 22:49:00 -0700116 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -0400117 of_ports.sort()
118
119 #Clear switch state
Rich Lane32bf9482013-01-03 17:26:30 -0800120 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -0400121
Rich Lane9a003812012-10-04 17:17:59 -0700122 logging.info("Inserting a flow entry and then deleting it")
123 logging.info("Expecting the active_count=0 in table_stats_reply")
ShreyaPandita9306c772012-09-28 12:21:40 -0400124
125 #Insert a flow matching on ingress_port
ShreyaPandita8dab4662012-11-02 13:40:14 -0400126 (pkt,match) = wildcard_all_except_ingress(self,of_ports)
ShreyaPandita9306c772012-09-28 12:21:40 -0400127
128 #Verify Flow inserted.
ShreyaPandita8dab4662012-11-02 13:40:14 -0400129 verify_tablestats(self,expect_active=1)
ShreyaPandita9306c772012-09-28 12:21:40 -0400130
131 #Delete the flow
ShreyaPandita8dab4662012-11-02 13:40:14 -0400132 nonstrict_delete(self,match)
ShreyaPandita9306c772012-09-28 12:21:40 -0400133
134 # Send Table_Stats_Request and verify flow deleted.
ShreyaPandita8dab4662012-11-02 13:40:14 -0400135 verify_tablestats(self,expect_active=0)
ShreyaPandita9306c772012-09-28 12:21:40 -0400136
137
138
Rich Laneb90a1c42012-10-05 09:16:05 -0700139class ModifyStateModify(base_tests.SimpleDataPlane):
ShreyaPandita9306c772012-09-28 12:21:40 -0400140
141 """Verify basic Flow Modify request is implemented
142 a) Send OFPT_FLOW_MOD, command = OFPFC_ADD, Action A
143 b) Send OFPT_FLOW_MOD, command = OFPFC_MODIFY , with output action A'
144 c) Send a packet matching the flow, verify packet implements action A' """
145
146 def runTest(self):
147
Rich Lane9a003812012-10-04 17:17:59 -0700148 logging.info("Running Modify_State_Modify test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400149
Rich Lane477f4812012-10-04 22:49:00 -0700150 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -0400151 of_ports.sort()
152
153 #Clear switch state
Rich Lane32bf9482013-01-03 17:26:30 -0800154 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -0400155
Rich Lane9a003812012-10-04 17:17:59 -0700156 logging.info("Inserting a flow entry and then modifying it")
157 logging.info("Expecting the Test Packet to implement the modified action")
ShreyaPandita9306c772012-09-28 12:21:40 -0400158
159 # Insert a flow matching on ingress_port with action A (output to of_port[1])
ShreyaPandita8dab4662012-11-02 13:40:14 -0400160 (pkt,match) = wildcard_all_except_ingress(self,of_ports)
ShreyaPandita9306c772012-09-28 12:21:40 -0400161
162 # Modify the flow action (output to of_port[2])
ShreyaPandita8dab4662012-11-02 13:40:14 -0400163 modify_flow_action(self,of_ports,match)
ShreyaPandita9306c772012-09-28 12:21:40 -0400164
165 # Send the Test Packet and verify action implemented is A' (output to of_port[2])
ShreyaPandita8dab4662012-11-02 13:40:14 -0400166 send_packet(self,pkt,of_ports[0],of_ports[2])
ShreyaPandita9306c772012-09-28 12:21:40 -0400167
168
Rich Laneb90a1c42012-10-05 09:16:05 -0700169class ReadState(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -0400170
171 """Test that a basic Read state request (like flow_stats_get request) does not generate an error
172 a) Send OFPT_FLOW_MOD, command = OFPFC_ADD
173 b) Send ofp_flow_stats request
174 b) Verify switch replies without errors"""
175
176 def runTest(self):
177
Rich Lane9a003812012-10-04 17:17:59 -0700178 logging.info("Running Read_State test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400179
Rich Lane477f4812012-10-04 22:49:00 -0700180 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -0400181 of_ports.sort()
182
183 #Clear switch state
Rich Lane32bf9482013-01-03 17:26:30 -0800184 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -0400185
Rich Lane9a003812012-10-04 17:17:59 -0700186 logging.info("Inserting a flow entry and then sending flow_stats request")
187 logging.info("Expecting the a flow_stats_reply without errors")
ShreyaPandita9306c772012-09-28 12:21:40 -0400188
189 # Insert a flow with match on ingress_port
ShreyaPandita8dab4662012-11-02 13:40:14 -0400190 (pkt,match ) = wildcard_all_except_ingress(self,of_ports)
ShreyaPandita9306c772012-09-28 12:21:40 -0400191
192 #Verify Flow_Stats request does not generate errors
ShreyaPandita8dab4662012-11-02 13:40:14 -0400193 get_flowstats(self,match)
ShreyaPandita9306c772012-09-28 12:21:40 -0400194
Rich Laneb90a1c42012-10-05 09:16:05 -0700195class PacketOut(base_tests.SimpleDataPlane):
ShreyaPandita9306c772012-09-28 12:21:40 -0400196
197 """Test packet out function
198 a) Send packet out message for each dataplane port.
199 b) Verify the packet appears on the appropriate dataplane port"""
200
201 def runTest(self):
202
Rich Lane9a003812012-10-04 17:17:59 -0700203 logging.info("Running Packet_Out test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400204
Rich Lane477f4812012-10-04 22:49:00 -0700205 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -0400206 of_ports.sort()
207
208 #Clear Switch state
Rich Lane32bf9482013-01-03 17:26:30 -0800209 delete_all_flows(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -0400210
Rich Lane9a003812012-10-04 17:17:59 -0700211 logging.info("Sending a packet-out for each dataplane port")
212 logging.info("Expecting the packet on appropriate dataplane port")
ShreyaPandita9306c772012-09-28 12:21:40 -0400213
214 for dp_port in of_ports:
215 for outpkt, opt in [
216 (simple_tcp_packet(), "simple TCP packet"),
217 (simple_eth_packet(), "simple Ethernet packet"),
218 (simple_eth_packet(pktlen=40), "tiny Ethernet packet")]:
219
Rich Lane28fa9272013-03-08 16:00:25 -0800220 msg = ofp.message.packet_out()
ShreyaPandita9306c772012-09-28 12:21:40 -0400221 msg.data = str(outpkt)
Rich Lane9d3cc6b2013-03-08 16:33:08 -0800222 act = ofp.action.output()
ShreyaPandita9306c772012-09-28 12:21:40 -0400223 act.port = dp_port
Rich Lanec495d9e2013-03-08 17:43:36 -0800224 msg.actions.append(act)
Rich Laneea8c4722013-04-04 15:30:20 -0700225 msg.buffer_id = 0xffffffff
ShreyaPandita9306c772012-09-28 12:21:40 -0400226
Rich Lane9a003812012-10-04 17:17:59 -0700227 logging.info("PacketOut to: " + str(dp_port))
Rich Lane5c3151c2013-01-03 17:15:41 -0800228 self.controller.message_send(msg)
ShreyaPandita9306c772012-09-28 12:21:40 -0400229
230 exp_pkt_arg = None
231 exp_port = None
Rich Lane477f4812012-10-04 22:49:00 -0700232 if config["relax"]:
ShreyaPandita9306c772012-09-28 12:21:40 -0400233 exp_pkt_arg = outpkt
234 exp_port = dp_port
235 (of_port, pkt, pkt_time) = self.dataplane.poll(timeout=2,
236 port_number=exp_port,
237 exp_pkt=exp_pkt_arg)
238
239 self.assertTrue(pkt is not None, 'Packet not received')
Rich Lane9a003812012-10-04 17:17:59 -0700240 logging.info("PacketOut: got pkt from " + str(of_port))
ShreyaPandita9306c772012-09-28 12:21:40 -0400241 if of_port is not None:
242 self.assertEqual(of_port, dp_port, "Unexpected receive port")
243 if not dataplane.match_exp_pkt(outpkt, pkt):
Rich Lane9a003812012-10-04 17:17:59 -0700244 logging.debug("Sent %s" % format_packet(outpkt))
245 logging.debug("Resp %s" % format_packet(
ShreyaPandita9306c772012-09-28 12:21:40 -0400246 str(pkt)[:len(str(outpkt))]))
247 self.assertEqual(str(outpkt), str(pkt)[:len(str(outpkt))],
248 'Response packet does not match send packet')
249
250
Rich Laneb90a1c42012-10-05 09:16:05 -0700251class PacketIn(base_tests.SimpleDataPlane):
ShreyaPandita9306c772012-09-28 12:21:40 -0400252
253 """Test basic packet_in function
254 a) Send a simple tcp packet to a dataplane port, without any flow-entry
255 b) Verify that a packet_in event is sent to the controller"""
256
257 def runTest(self):
258
Rich Lane9a003812012-10-04 17:17:59 -0700259 logging.info("Running Packet_In test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400260
Rich Lane477f4812012-10-04 22:49:00 -0700261 of_ports = config["port_map"].keys()
ShreyaPandita9306c772012-09-28 12:21:40 -0400262 of_ports.sort()
263 ingress_port = of_ports[0]
264
265 #Clear Switch state
Rich Lane32bf9482013-01-03 17:26:30 -0800266 delete_all_flows(self.controller)
Rich Lane3a261d52013-01-03 17:45:08 -0800267 do_barrier(self.controller)
ShreyaPandita9306c772012-09-28 12:21:40 -0400268
Rich Lane9a003812012-10-04 17:17:59 -0700269 logging.info("Sending a Simple tcp packet a dataplane port")
270 logging.info("Expecting a packet_in event on the control plane")
ShreyaPandita9306c772012-09-28 12:21:40 -0400271
272 # Send packet on dataplane port and verify packet_in event gets generated.
273 pkt = simple_tcp_packet()
274 self.dataplane.send(ingress_port, str(pkt))
Rich Lane9a003812012-10-04 17:17:59 -0700275 logging.info("Sending packet to dp port " + str(ingress_port) +
ShreyaPandita9306c772012-09-28 12:21:40 -0400276 ", expecting packet_in on control plane" )
277
Rich Lane4c504f32013-06-07 17:24:14 -0700278 verify_packet_in(self, str(pkt), ingress_port, ofp.OFPR_NO_MATCH)
ShreyaPandita9306c772012-09-28 12:21:40 -0400279
280
Rich Laneb90a1c42012-10-05 09:16:05 -0700281class EchoWithoutBody(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -0400282
283 """Test basic echo-reply is implemented
284 a) Send echo-request from the controller side, note echo body is empty here.
285 b) Verify switch responds back with echo-reply with same xid """
286
287 def runTest(self):
288
Rich Lane9a003812012-10-04 17:17:59 -0700289 logging.info("Running Echo_Without_Body test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400290
Rich Lane9a003812012-10-04 17:17:59 -0700291 logging.info("Sending Echo Request")
292 logging.info("Expecting a Echo Reply with version--1.0.0 and same xid")
ShreyaPandita9306c772012-09-28 12:21:40 -0400293
294 # Send echo_request
Rich Lane28fa9272013-03-08 16:00:25 -0800295 request = ofp.message.echo_request()
ShreyaPandita9306c772012-09-28 12:21:40 -0400296 (response, pkt) = self.controller.transact(request)
Rich Laneb73808c2013-03-11 15:22:23 -0700297 self.assertEqual(response.type, ofp.OFPT_ECHO_REPLY,'response is not echo_reply')
298 self.assertEqual(request.xid, response.xid,
ShreyaPandita9306c772012-09-28 12:21:40 -0400299 'response xid != request xid')
Rich Laneb73808c2013-03-11 15:22:23 -0700300 self.assertTrue(response.version == 0x01, 'switch openflow-version field is not 1.0.1')
ShreyaPandita9306c772012-09-28 12:21:40 -0400301 self.assertEqual(len(response.data), 0, 'response data non-empty')
302
303
Rich Laneb90a1c42012-10-05 09:16:05 -0700304class BarrierRequestReply(base_tests.SimpleProtocol):
ShreyaPandita9306c772012-09-28 12:21:40 -0400305
306 """ Check basic Barrier request is implemented
307 a) Send OFPT_BARRIER_REQUEST
308 c) Verify OFPT_BARRIER_REPLY is recieved"""
309
310 def runTest(self):
311
Rich Lane9a003812012-10-04 17:17:59 -0700312 logging.info("Running Barrier_Request_Reply test")
ShreyaPandita9306c772012-09-28 12:21:40 -0400313
Rich Lane9a003812012-10-04 17:17:59 -0700314 logging.info("Sending Barrier Request")
315 logging.info("Expecting a Barrier Reply with same xid")
ShreyaPandita9306c772012-09-28 12:21:40 -0400316
317 #Send Barrier Request
Rich Lane28fa9272013-03-08 16:00:25 -0800318 request = ofp.message.barrier_request()
ShreyaPandita8dab4662012-11-02 13:40:14 -0400319 (response,pkt) = self.controller.transact(request)
Rich Laneb73808c2013-03-11 15:22:23 -0700320 self.assertEqual(response.type, ofp.OFPT_BARRIER_REPLY,'response is not barrier_reply')
321 self.assertEqual(request.xid, response.xid,
ShreyaPandita9306c772012-09-28 12:21:40 -0400322 'response xid != request xid')
323
324
325
326
327