blob: 7fceeaf8b3564ec80d0ab75f06a145f311bf6f59 [file] [log] [blame]
Dan Talayco79c6c4d2010-06-08 14:01:53 -07001"""
2Basic capabilities and capacities tests
3
4"""
5
6import logging
Rich Lane4f508052013-01-28 10:49:46 -08007import time
Dan Talayco79c6c4d2010-06-08 14:01:53 -07008import unittest
9
Rich Lane477f4812012-10-04 22:49:00 -070010from oftest import config
Dan Talayco79c6c4d2010-06-08 14:01:53 -070011import oftest.controller as controller
Rich Laned7b0ffa2013-03-08 15:53:42 -080012import ofp
Dan Talayco79c6c4d2010-06-08 14:01:53 -070013import oftest.dataplane as dataplane
Dan Talayco79c6c4d2010-06-08 14:01:53 -070014import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070015import oftest.base_tests as base_tests
Dan Talayco79c6c4d2010-06-08 14:01:53 -070016
Rich Laneda3b5ad2012-10-03 09:05:32 -070017from oftest.testutils import *
Dan Talayco79c6c4d2010-06-08 14:01:53 -070018
Dan Talayco79c6c4d2010-06-08 14:01:53 -070019def flow_caps_common(obj, is_exact=True):
20 """
21 The common function for
22
23 @param obj The calling object
24 @param is_exact If True, checking exact match; else wildcard
25 """
26
Rich Lane477f4812012-10-04 22:49:00 -070027 of_ports = config["port_map"].keys()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070028 of_ports.sort()
29
Rich Lane32bf9482013-01-03 17:26:30 -080030 delete_all_flows(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070031
32 pkt = simple_tcp_packet()
Ed Swierk6192e512012-08-22 11:41:40 -070033 match = packet_to_flow_match(obj, pkt)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070034 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
35 for port in of_ports:
36 break;
37 match.in_port = port
Rich Laned0478ff2013-03-11 12:46:58 -070038 match.ipv4_src = 1
Rich Laneba3f0e22013-03-11 16:43:57 -070039 request = ofp.message.flow_add()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070040 count_check = 101 # fixme: better way to determine this.
41 if is_exact:
42 match.wildcards = 0
43 else:
44 match.wildcards |= ofp.OFPFW_DL_SRC
45
46 request.match = match
Rob Sherwood9130bcd2012-03-07 12:23:50 -080047 request.buffer_id = 0xffffffff # set to NONE
Rich Lane9a003812012-10-04 17:17:59 -070048 logging.info(request.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070049
Rich Lane28fa9272013-03-08 16:00:25 -080050 tstats = ofp.message.table_stats_request()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070051 try: # Determine the table index to check (or "all")
Rich Lane477f4812012-10-04 22:49:00 -070052 table_idx = config["caps_table_idx"]
Dan Talayco79c6c4d2010-06-08 14:01:53 -070053 except:
54 table_idx = -1 # Accumulate all table counts
55
56 # Make sure we can install at least one flow
Rich Lane9a003812012-10-04 17:17:59 -070057 logging.info("Inserting initial flow")
Rich Lane5c3151c2013-01-03 17:15:41 -080058 obj.controller.message_send(request)
Rich Lane3a261d52013-01-03 17:45:08 -080059 do_barrier(obj.controller, timeout=10)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070060 flow_count = 1
61
Rich Lane9a003812012-10-04 17:17:59 -070062 logging.info("Table idx: " + str(table_idx))
63 logging.info("Check every " + str(count_check) + " inserts")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070064
65 while True:
Rich Laned0478ff2013-03-11 12:46:58 -070066 request.match.ipv4_src += 1
Rich Lane5c3151c2013-01-03 17:15:41 -080067 obj.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070068 flow_count += 1
69 if flow_count % count_check == 0:
Rich Lane3a261d52013-01-03 17:45:08 -080070 do_barrier(obj.controller, timeout=10)
Rich Lanec8aaa3e2012-07-26 19:28:02 -070071 response, pkt = obj.controller.transact(tstats)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070072 obj.assertTrue(response is not None, "Get tab stats failed")
Rich Lane9a003812012-10-04 17:17:59 -070073 logging.info(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070074 if table_idx == -1: # Accumulate for all tables
75 active_flows = 0
Rich Lane5fd6faf2013-03-11 13:30:20 -070076 for stats in response.entries:
Dan Talayco79c6c4d2010-06-08 14:01:53 -070077 active_flows += stats.active_count
78 else: # Table index to use specified in config
Rich Lane5fd6faf2013-03-11 13:30:20 -070079 active_flows = response.entries[table_idx].active_count
Dan Talayco79c6c4d2010-06-08 14:01:53 -070080 if active_flows != flow_count:
81 break
82
Rich Lane9a003812012-10-04 17:17:59 -070083 logging.error("RESULT: " + str(flow_count) + " flows inserted")
84 logging.error("RESULT: " + str(active_flows) + " flows reported")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070085
Shudong Zhoud71c4a72012-11-18 14:37:43 -080086 # clean up and wait a bit in case the table is really big
Rich Lane32bf9482013-01-03 17:26:30 -080087 delete_all_flows(obj.controller)
Shudong Zhoud71c4a72012-11-18 14:37:43 -080088 time.sleep(flow_count / 100)
89
90
Rich Lane0a4f6372013-01-02 14:40:22 -080091@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -070092class FillTableExact(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -070093 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -070094 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -070095
96 Fill table until no more flows can be added. Report result.
97 Increment the source IP address. Assume the flow table will
98 fill in less than 4 billion inserts
99
100 To check the number of flows in the tables is expensive, so
101 it's only done periodically. This is controlled by the
102 count_check variable.
103
104 A switch may have multiple tables. The default behaviour
105 is to count all the flows in all the tables. By setting
106 the parameter "caps_table_idx" in the configuration array,
107 you can control which table to check.
108 """
Rich Laned1d9c282012-10-04 22:07:10 -0700109
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700110 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700111 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700112 flow_caps_common(self)
113
Rich Lane0a4f6372013-01-02 14:40:22 -0800114@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -0700115class FillTableWC(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700116 """
117 Fill the flow table with wildcard matches
118
119 Fill table using wildcard entries until no more flows can be
120 added. Report result.
121 Increment the source IP address. Assume the flow table will
122 fill in less than 4 billion inserts
123
124 To check the number of flows in the tables is expensive, so
125 it's only done periodically. This is controlled by the
126 count_check variable.
127
128 A switch may have multiple tables. The default behaviour
129 is to count all the flows in all the tables. By setting
130 the parameter "caps_table_idx" in the configuration array,
131 you can control which table to check.
132
133 """
Rich Laned1d9c282012-10-04 22:07:10 -0700134
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700135 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700136 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700137 flow_caps_common(self, is_exact=False)