blob: 1146cf1db5d717982502fd7881678952a9086fcb [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
28def test_set_init(config):
29 """
30 Set up function for caps test classes
31
32 @param config The configuration dictionary; see oft
33 """
34
35 global caps_port_map
36 global caps_logger
37 global caps_config
38
39 caps_logger = logging.getLogger("caps")
40 caps_logger.info("Initializing caps test set")
41 caps_port_map = config["port_map"]
42 caps_config = config
43
44
45def flow_caps_common(obj, is_exact=True):
46 """
47 The common function for
48
49 @param obj The calling object
50 @param is_exact If True, checking exact match; else wildcard
51 """
52
53 global caps_port_map
54 of_ports = caps_port_map.keys()
55 of_ports.sort()
56
57 rv = delete_all_flows(obj.controller, caps_logger)
58 obj.assertEqual(rv, 0, "Failed to delete all flows")
59
60 pkt = simple_tcp_packet()
61 match = parse.packet_to_flow_match(pkt)
62 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
63 for port in of_ports:
64 break;
65 match.in_port = port
66 match.nw_src = 1
67 request = message.flow_mod()
68 count_check = 101 # fixme: better way to determine this.
69 if is_exact:
70 match.wildcards = 0
71 else:
72 match.wildcards |= ofp.OFPFW_DL_SRC
73
74 request.match = match
75 caps_logger.info(request.show())
76
77 tstats = message.table_stats_request()
78 try: # Determine the table index to check (or "all")
79 table_idx = caps_config["caps_table_idx"]
80 except:
81 table_idx = -1 # Accumulate all table counts
82
83 # Make sure we can install at least one flow
84 caps_logger.info("Inserting initial flow")
85 rv = obj.controller.message_send(request)
86 obj.assertTrue(rv != -1, "Error installing flow mod")
87 do_barrier(obj.controller)
88 flow_count = 1
89
90 caps_logger.info("Table idx: " + str(table_idx))
91 caps_logger.info("Check every " + str(count_check) + " inserts")
92
93 while True:
94 request.match.nw_src += 1
95 rv = obj.controller.message_send(request)
96 do_barrier(obj.controller)
97 flow_count += 1
98 if flow_count % count_check == 0:
99 response, pkt = obj.controller.transact(tstats, timeout=2)
100 obj.assertTrue(response is not None, "Get tab stats failed")
101 caps_logger.info(response.show())
102 if table_idx == -1: # Accumulate for all tables
103 active_flows = 0
104 for stats in response.stats:
105 active_flows += stats.active_count
106 else: # Table index to use specified in config
107 active_flows = response.stats[table_idx].active_count
108 if active_flows != flow_count:
109 break
110
111 caps_logger.error("RESULT: " + str(flow_count) + " flows inserted")
112 caps_logger.error("RESULT: " + str(active_flows) + " flows reported")
113
114
115class FillTableExact(basic.SimpleProtocol):
116 """
117 Fill the flow table with exact matches
118
119 Fill table until no more flows can be added. Report result.
120 Increment the source IP address. Assume the flow table will
121 fill in less than 4 billion inserts
122
123 To check the number of flows in the tables is expensive, so
124 it's only done periodically. This is controlled by the
125 count_check variable.
126
127 A switch may have multiple tables. The default behaviour
128 is to count all the flows in all the tables. By setting
129 the parameter "caps_table_idx" in the configuration array,
130 you can control which table to check.
131 """
132 def runTest(self):
133 caps_logger.info("Running " + str(self))
134 flow_caps_common(self)
135
136
137class FillTableWC(basic.SimpleProtocol):
138 """
139 Fill the flow table with wildcard matches
140
141 Fill table using wildcard entries until no more flows can be
142 added. Report result.
143 Increment the source IP address. Assume the flow table will
144 fill in less than 4 billion inserts
145
146 To check the number of flows in the tables is expensive, so
147 it's only done periodically. This is controlled by the
148 count_check variable.
149
150 A switch may have multiple tables. The default behaviour
151 is to count all the flows in all the tables. By setting
152 the parameter "caps_table_idx" in the configuration array,
153 you can control which table to check.
154
155 """
156 def runTest(self):
157 caps_logger.info("Running " + str(self))
158 flow_caps_common(self, is_exact=False)