blob: 14d616f330452afde7da4a4459d18c86069dc0a6 [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
78 caps_logger.info(request.show())
79
80 tstats = message.table_stats_request()
81 try: # Determine the table index to check (or "all")
82 table_idx = caps_config["caps_table_idx"]
83 except:
84 table_idx = -1 # Accumulate all table counts
85
86 # Make sure we can install at least one flow
87 caps_logger.info("Inserting initial flow")
88 rv = obj.controller.message_send(request)
89 obj.assertTrue(rv != -1, "Error installing flow mod")
90 do_barrier(obj.controller)
91 flow_count = 1
92
93 caps_logger.info("Table idx: " + str(table_idx))
94 caps_logger.info("Check every " + str(count_check) + " inserts")
95
96 while True:
97 request.match.nw_src += 1
98 rv = obj.controller.message_send(request)
Dan Talaycoc24aaae2010-07-08 14:05:24 -070099# do_barrier(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700100 flow_count += 1
101 if flow_count % count_check == 0:
102 response, pkt = obj.controller.transact(tstats, timeout=2)
103 obj.assertTrue(response is not None, "Get tab stats failed")
104 caps_logger.info(response.show())
105 if table_idx == -1: # Accumulate for all tables
106 active_flows = 0
107 for stats in response.stats:
108 active_flows += stats.active_count
109 else: # Table index to use specified in config
110 active_flows = response.stats[table_idx].active_count
111 if active_flows != flow_count:
112 break
113
114 caps_logger.error("RESULT: " + str(flow_count) + " flows inserted")
115 caps_logger.error("RESULT: " + str(active_flows) + " flows reported")
116
117
118class FillTableExact(basic.SimpleProtocol):
119 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -0700120 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700121
122 Fill table until no more flows can be added. Report result.
123 Increment the source IP address. Assume the flow table will
124 fill in less than 4 billion inserts
125
126 To check the number of flows in the tables is expensive, so
127 it's only done periodically. This is controlled by the
128 count_check variable.
129
130 A switch may have multiple tables. The default behaviour
131 is to count all the flows in all the tables. By setting
132 the parameter "caps_table_idx" in the configuration array,
133 you can control which table to check.
134 """
135 def runTest(self):
136 caps_logger.info("Running " + str(self))
137 flow_caps_common(self)
138
Dan Talaycoc24aaae2010-07-08 14:05:24 -0700139test_prio["FillTableExact"] = -1
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700140
141class FillTableWC(basic.SimpleProtocol):
142 """
143 Fill the flow table with wildcard matches
144
145 Fill table using wildcard entries until no more flows can be
146 added. Report result.
147 Increment the source IP address. Assume the flow table will
148 fill in less than 4 billion inserts
149
150 To check the number of flows in the tables is expensive, so
151 it's only done periodically. This is controlled by the
152 count_check variable.
153
154 A switch may have multiple tables. The default behaviour
155 is to count all the flows in all the tables. By setting
156 the parameter "caps_table_idx" in the configuration array,
157 you can control which table to check.
158
159 """
160 def runTest(self):
161 caps_logger.info("Running " + str(self))
162 flow_caps_common(self, is_exact=False)