blob: d0bb2d0d5b9914b9b667490f2834d4a59ffe7b12 [file] [log] [blame]
Dan Talayco79c6c4d2010-06-08 14:01:53 -07001"""
2Basic capabilities and capacities tests
3
4"""
5
6import logging
7
8import unittest
9
10import oftest.controller as controller
11import oftest.cstruct as ofp
12import oftest.message as message
13import oftest.dataplane as dataplane
14import oftest.action as action
15import oftest.parse as parse
16import basic
17
18from testutils import *
19
20#@var caps_port_map Local copy of the configuration map from OF port
21# numbers to OS interfaces
22caps_port_map = None
23#@var caps_logger Local logger object
24caps_logger = None
25#@var caps_config Local copy of global configuration data
26caps_config = None
27
Dan Talaycoc24aaae2010-07-08 14:05:24 -070028# For test priority
29test_prio = {}
30
Dan Talayco79c6c4d2010-06-08 14:01:53 -070031def test_set_init(config):
32 """
33 Set up function for caps test classes
34
35 @param config The configuration dictionary; see oft
36 """
37
38 global caps_port_map
39 global caps_logger
40 global caps_config
41
42 caps_logger = logging.getLogger("caps")
43 caps_logger.info("Initializing caps test set")
44 caps_port_map = config["port_map"]
45 caps_config = config
46
47
48def flow_caps_common(obj, is_exact=True):
49 """
50 The common function for
51
52 @param obj The calling object
53 @param is_exact If True, checking exact match; else wildcard
54 """
55
56 global caps_port_map
57 of_ports = caps_port_map.keys()
58 of_ports.sort()
59
60 rv = delete_all_flows(obj.controller, caps_logger)
61 obj.assertEqual(rv, 0, "Failed to delete all flows")
62
63 pkt = simple_tcp_packet()
64 match = parse.packet_to_flow_match(pkt)
65 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
66 for port in of_ports:
67 break;
68 match.in_port = port
69 match.nw_src = 1
70 request = message.flow_mod()
71 count_check = 101 # fixme: better way to determine this.
72 if is_exact:
73 match.wildcards = 0
74 else:
75 match.wildcards |= ofp.OFPFW_DL_SRC
76
77 request.match = match
Rob Sherwood9130bcd2012-03-07 12:23:50 -080078 request.buffer_id = 0xffffffff # set to NONE
Dan Talayco79c6c4d2010-06-08 14:01:53 -070079 caps_logger.info(request.show())
80
81 tstats = message.table_stats_request()
82 try: # Determine the table index to check (or "all")
83 table_idx = caps_config["caps_table_idx"]
84 except:
85 table_idx = -1 # Accumulate all table counts
86
87 # Make sure we can install at least one flow
88 caps_logger.info("Inserting initial flow")
89 rv = obj.controller.message_send(request)
90 obj.assertTrue(rv != -1, "Error installing flow mod")
91 do_barrier(obj.controller)
92 flow_count = 1
93
94 caps_logger.info("Table idx: " + str(table_idx))
95 caps_logger.info("Check every " + str(count_check) + " inserts")
96
97 while True:
98 request.match.nw_src += 1
99 rv = obj.controller.message_send(request)
Dan Talaycoc24aaae2010-07-08 14:05:24 -0700100# do_barrier(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700101 flow_count += 1
102 if flow_count % count_check == 0:
103 response, pkt = obj.controller.transact(tstats, timeout=2)
104 obj.assertTrue(response is not None, "Get tab stats failed")
105 caps_logger.info(response.show())
106 if table_idx == -1: # Accumulate for all tables
107 active_flows = 0
108 for stats in response.stats:
109 active_flows += stats.active_count
110 else: # Table index to use specified in config
111 active_flows = response.stats[table_idx].active_count
112 if active_flows != flow_count:
113 break
114
115 caps_logger.error("RESULT: " + str(flow_count) + " flows inserted")
116 caps_logger.error("RESULT: " + str(active_flows) + " flows reported")
117
118
119class FillTableExact(basic.SimpleProtocol):
120 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -0700121 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700122
123 Fill table until no more flows can be added. Report result.
124 Increment the source IP address. Assume the flow table will
125 fill in less than 4 billion inserts
126
127 To check the number of flows in the tables is expensive, so
128 it's only done periodically. This is controlled by the
129 count_check variable.
130
131 A switch may have multiple tables. The default behaviour
132 is to count all the flows in all the tables. By setting
133 the parameter "caps_table_idx" in the configuration array,
134 you can control which table to check.
135 """
136 def runTest(self):
137 caps_logger.info("Running " + str(self))
138 flow_caps_common(self)
139
Dan Talaycoc24aaae2010-07-08 14:05:24 -0700140test_prio["FillTableExact"] = -1
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700141
142class FillTableWC(basic.SimpleProtocol):
143 """
144 Fill the flow table with wildcard matches
145
146 Fill table using wildcard entries until no more flows can be
147 added. Report result.
148 Increment the source IP address. Assume the flow table will
149 fill in less than 4 billion inserts
150
151 To check the number of flows in the tables is expensive, so
152 it's only done periodically. This is controlled by the
153 count_check variable.
154
155 A switch may have multiple tables. The default behaviour
156 is to count all the flows in all the tables. By setting
157 the parameter "caps_table_idx" in the configuration array,
158 you can control which table to check.
159
160 """
161 def runTest(self):
162 caps_logger.info("Running " + str(self))
163 flow_caps_common(self, is_exact=False)