blob: 449fce6da926da1a4646f932ca556a4d9e7c35a9 [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
Dan Talayco79c6c4d2010-06-08 14:01:53 -070023#@var caps_config Local copy of global configuration data
24caps_config = None
25
26def test_set_init(config):
27 """
28 Set up function for caps test classes
29
30 @param config The configuration dictionary; see oft
31 """
32
Ed Swierk6ccbb072012-03-19 14:48:40 -070033 basic.test_set_init(config)
34
Dan Talayco79c6c4d2010-06-08 14:01:53 -070035 global caps_port_map
Dan Talayco79c6c4d2010-06-08 14:01:53 -070036 global caps_config
37
Dan Talayco79c6c4d2010-06-08 14:01:53 -070038 caps_port_map = config["port_map"]
39 caps_config = config
40
41
42def flow_caps_common(obj, is_exact=True):
43 """
44 The common function for
45
46 @param obj The calling object
47 @param is_exact If True, checking exact match; else wildcard
48 """
49
50 global caps_port_map
51 of_ports = caps_port_map.keys()
52 of_ports.sort()
53
Rich Lane9a003812012-10-04 17:17:59 -070054 rv = delete_all_flows(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070055 obj.assertEqual(rv, 0, "Failed to delete all flows")
56
57 pkt = simple_tcp_packet()
Ed Swierk6192e512012-08-22 11:41:40 -070058 match = packet_to_flow_match(obj, pkt)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070059 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
60 for port in of_ports:
61 break;
62 match.in_port = port
63 match.nw_src = 1
64 request = message.flow_mod()
65 count_check = 101 # fixme: better way to determine this.
66 if is_exact:
67 match.wildcards = 0
68 else:
69 match.wildcards |= ofp.OFPFW_DL_SRC
70
71 request.match = match
Rob Sherwood9130bcd2012-03-07 12:23:50 -080072 request.buffer_id = 0xffffffff # set to NONE
Rich Lane9a003812012-10-04 17:17:59 -070073 logging.info(request.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070074
75 tstats = message.table_stats_request()
76 try: # Determine the table index to check (or "all")
77 table_idx = caps_config["caps_table_idx"]
78 except:
79 table_idx = -1 # Accumulate all table counts
80
81 # Make sure we can install at least one flow
Rich Lane9a003812012-10-04 17:17:59 -070082 logging.info("Inserting initial flow")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070083 rv = obj.controller.message_send(request)
84 obj.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco2757e0a2012-05-02 09:28:52 -070085 obj.assertEqual(do_barrier(obj.controller), 0, "Barrier failed")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070086 flow_count = 1
87
Rich Lane9a003812012-10-04 17:17:59 -070088 logging.info("Table idx: " + str(table_idx))
89 logging.info("Check every " + str(count_check) + " inserts")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070090
91 while True:
92 request.match.nw_src += 1
93 rv = obj.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070094 flow_count += 1
95 if flow_count % count_check == 0:
Dan Talayco2757e0a2012-05-02 09:28:52 -070096 obj.assertEqual(do_barrier(obj.controller), 0, "Barrier failed")
Rich Lanec8aaa3e2012-07-26 19:28:02 -070097 response, pkt = obj.controller.transact(tstats)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070098 obj.assertTrue(response is not None, "Get tab stats failed")
Rich Lane9a003812012-10-04 17:17:59 -070099 logging.info(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700100 if table_idx == -1: # Accumulate for all tables
101 active_flows = 0
102 for stats in response.stats:
103 active_flows += stats.active_count
104 else: # Table index to use specified in config
105 active_flows = response.stats[table_idx].active_count
106 if active_flows != flow_count:
107 break
108
Rich Lane9a003812012-10-04 17:17:59 -0700109 logging.error("RESULT: " + str(flow_count) + " flows inserted")
110 logging.error("RESULT: " + str(active_flows) + " flows reported")
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700111
112
113class FillTableExact(basic.SimpleProtocol):
114 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -0700115 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700116
117 Fill table until no more flows can be added. Report result.
118 Increment the source IP address. Assume the flow table will
119 fill in less than 4 billion inserts
120
121 To check the number of flows in the tables is expensive, so
122 it's only done periodically. This is controlled by the
123 count_check variable.
124
125 A switch may have multiple tables. The default behaviour
126 is to count all the flows in all the tables. By setting
127 the parameter "caps_table_idx" in the configuration array,
128 you can control which table to check.
129 """
Rich Laned1d9c282012-10-04 22:07:10 -0700130
131 priority = -1
132
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700133 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700134 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700135 flow_caps_common(self)
136
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700137class 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 """
Rich Laned1d9c282012-10-04 22:07:10 -0700156
157 priority = -1
158
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700159 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700160 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700161 flow_caps_common(self, is_exact=False)