blob: 93403ea8d1de222ec12e4d044bf839ed21f7adff [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
Rich Laneda3b5ad2012-10-03 09:05:32 -070018from oftest.testutils import *
Dan Talayco79c6c4d2010-06-08 14:01:53 -070019
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
Ed Swierk6ccbb072012-03-19 14:48:40 -070038 basic.test_set_init(config)
39
Dan Talayco79c6c4d2010-06-08 14:01:53 -070040 global caps_port_map
41 global caps_logger
42 global caps_config
43
44 caps_logger = logging.getLogger("caps")
45 caps_logger.info("Initializing caps test set")
46 caps_port_map = config["port_map"]
47 caps_config = config
48
49
50def flow_caps_common(obj, is_exact=True):
51 """
52 The common function for
53
54 @param obj The calling object
55 @param is_exact If True, checking exact match; else wildcard
56 """
57
58 global caps_port_map
59 of_ports = caps_port_map.keys()
60 of_ports.sort()
61
62 rv = delete_all_flows(obj.controller, caps_logger)
63 obj.assertEqual(rv, 0, "Failed to delete all flows")
64
65 pkt = simple_tcp_packet()
Ed Swierk6192e512012-08-22 11:41:40 -070066 match = packet_to_flow_match(obj, pkt)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070067 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
68 for port in of_ports:
69 break;
70 match.in_port = port
71 match.nw_src = 1
72 request = message.flow_mod()
73 count_check = 101 # fixme: better way to determine this.
74 if is_exact:
75 match.wildcards = 0
76 else:
77 match.wildcards |= ofp.OFPFW_DL_SRC
78
79 request.match = match
Rob Sherwood9130bcd2012-03-07 12:23:50 -080080 request.buffer_id = 0xffffffff # set to NONE
Dan Talayco79c6c4d2010-06-08 14:01:53 -070081 caps_logger.info(request.show())
82
83 tstats = message.table_stats_request()
84 try: # Determine the table index to check (or "all")
85 table_idx = caps_config["caps_table_idx"]
86 except:
87 table_idx = -1 # Accumulate all table counts
88
89 # Make sure we can install at least one flow
90 caps_logger.info("Inserting initial flow")
91 rv = obj.controller.message_send(request)
92 obj.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco2757e0a2012-05-02 09:28:52 -070093 obj.assertEqual(do_barrier(obj.controller), 0, "Barrier failed")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070094 flow_count = 1
95
96 caps_logger.info("Table idx: " + str(table_idx))
97 caps_logger.info("Check every " + str(count_check) + " inserts")
98
99 while True:
100 request.match.nw_src += 1
101 rv = obj.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700102 flow_count += 1
103 if flow_count % count_check == 0:
Dan Talayco2757e0a2012-05-02 09:28:52 -0700104 obj.assertEqual(do_barrier(obj.controller), 0, "Barrier failed")
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700105 response, pkt = obj.controller.transact(tstats)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700106 obj.assertTrue(response is not None, "Get tab stats failed")
107 caps_logger.info(response.show())
108 if table_idx == -1: # Accumulate for all tables
109 active_flows = 0
110 for stats in response.stats:
111 active_flows += stats.active_count
112 else: # Table index to use specified in config
113 active_flows = response.stats[table_idx].active_count
114 if active_flows != flow_count:
115 break
116
117 caps_logger.error("RESULT: " + str(flow_count) + " flows inserted")
118 caps_logger.error("RESULT: " + str(active_flows) + " flows reported")
119
120
121class FillTableExact(basic.SimpleProtocol):
122 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -0700123 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700124
125 Fill table until no more flows can be added. Report result.
126 Increment the source IP address. Assume the flow table will
127 fill in less than 4 billion inserts
128
129 To check the number of flows in the tables is expensive, so
130 it's only done periodically. This is controlled by the
131 count_check variable.
132
133 A switch may have multiple tables. The default behaviour
134 is to count all the flows in all the tables. By setting
135 the parameter "caps_table_idx" in the configuration array,
136 you can control which table to check.
137 """
138 def runTest(self):
139 caps_logger.info("Running " + str(self))
140 flow_caps_common(self)
141
Dan Talaycoc24aaae2010-07-08 14:05:24 -0700142test_prio["FillTableExact"] = -1
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700143
144class FillTableWC(basic.SimpleProtocol):
145 """
146 Fill the flow table with wildcard matches
147
148 Fill table using wildcard entries until no more flows can be
149 added. Report result.
150 Increment the source IP address. Assume the flow table will
151 fill in less than 4 billion inserts
152
153 To check the number of flows in the tables is expensive, so
154 it's only done periodically. This is controlled by the
155 count_check variable.
156
157 A switch may have multiple tables. The default behaviour
158 is to count all the flows in all the tables. By setting
159 the parameter "caps_table_idx" in the configuration array,
160 you can control which table to check.
161
162 """
163 def runTest(self):
164 caps_logger.info("Running " + str(self))
165 flow_caps_common(self, is_exact=False)
Dan Talayco3788a3d2011-08-23 22:50:07 -0700166
167test_prio["FillTableWC"] = -1