blob: 823d55cecf99005dcf24a31767b468868957cce5 [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
Dan Talaycoc24aaae2010-07-08 14:05:24 -070026# For test priority
27test_prio = {}
28
Dan Talayco79c6c4d2010-06-08 14:01:53 -070029def test_set_init(config):
30 """
31 Set up function for caps test classes
32
33 @param config The configuration dictionary; see oft
34 """
35
Ed Swierk6ccbb072012-03-19 14:48:40 -070036 basic.test_set_init(config)
37
Dan Talayco79c6c4d2010-06-08 14:01:53 -070038 global caps_port_map
Dan Talayco79c6c4d2010-06-08 14:01:53 -070039 global caps_config
40
Dan Talayco79c6c4d2010-06-08 14:01:53 -070041 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
Rich Lane9a003812012-10-04 17:17:59 -070057 rv = delete_all_flows(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070058 obj.assertEqual(rv, 0, "Failed to delete all flows")
59
60 pkt = simple_tcp_packet()
Ed Swierk6192e512012-08-22 11:41:40 -070061 match = packet_to_flow_match(obj, pkt)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070062 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
Rob Sherwood9130bcd2012-03-07 12:23:50 -080075 request.buffer_id = 0xffffffff # set to NONE
Rich Lane9a003812012-10-04 17:17:59 -070076 logging.info(request.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070077
78 tstats = message.table_stats_request()
79 try: # Determine the table index to check (or "all")
80 table_idx = caps_config["caps_table_idx"]
81 except:
82 table_idx = -1 # Accumulate all table counts
83
84 # Make sure we can install at least one flow
Rich Lane9a003812012-10-04 17:17:59 -070085 logging.info("Inserting initial flow")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070086 rv = obj.controller.message_send(request)
87 obj.assertTrue(rv != -1, "Error installing flow mod")
Dan Talayco2757e0a2012-05-02 09:28:52 -070088 obj.assertEqual(do_barrier(obj.controller), 0, "Barrier failed")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070089 flow_count = 1
90
Rich Lane9a003812012-10-04 17:17:59 -070091 logging.info("Table idx: " + str(table_idx))
92 logging.info("Check every " + str(count_check) + " inserts")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070093
94 while True:
95 request.match.nw_src += 1
96 rv = obj.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070097 flow_count += 1
98 if flow_count % count_check == 0:
Dan Talayco2757e0a2012-05-02 09:28:52 -070099 obj.assertEqual(do_barrier(obj.controller), 0, "Barrier failed")
Rich Lanec8aaa3e2012-07-26 19:28:02 -0700100 response, pkt = obj.controller.transact(tstats)
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700101 obj.assertTrue(response is not None, "Get tab stats failed")
Rich Lane9a003812012-10-04 17:17:59 -0700102 logging.info(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700103 if table_idx == -1: # Accumulate for all tables
104 active_flows = 0
105 for stats in response.stats:
106 active_flows += stats.active_count
107 else: # Table index to use specified in config
108 active_flows = response.stats[table_idx].active_count
109 if active_flows != flow_count:
110 break
111
Rich Lane9a003812012-10-04 17:17:59 -0700112 logging.error("RESULT: " + str(flow_count) + " flows inserted")
113 logging.error("RESULT: " + str(active_flows) + " flows reported")
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700114
115
116class FillTableExact(basic.SimpleProtocol):
117 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -0700118 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700119
120 Fill table until no more flows can be added. Report result.
121 Increment the source IP address. Assume the flow table will
122 fill in less than 4 billion inserts
123
124 To check the number of flows in the tables is expensive, so
125 it's only done periodically. This is controlled by the
126 count_check variable.
127
128 A switch may have multiple tables. The default behaviour
129 is to count all the flows in all the tables. By setting
130 the parameter "caps_table_idx" in the configuration array,
131 you can control which table to check.
132 """
133 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 Talaycoc24aaae2010-07-08 14:05:24 -0700137test_prio["FillTableExact"] = -1
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700138
139class FillTableWC(basic.SimpleProtocol):
140 """
141 Fill the flow table with wildcard matches
142
143 Fill table using wildcard entries until no more flows can be
144 added. Report result.
145 Increment the source IP address. Assume the flow table will
146 fill in less than 4 billion inserts
147
148 To check the number of flows in the tables is expensive, so
149 it's only done periodically. This is controlled by the
150 count_check variable.
151
152 A switch may have multiple tables. The default behaviour
153 is to count all the flows in all the tables. By setting
154 the parameter "caps_table_idx" in the configuration array,
155 you can control which table to check.
156
157 """
158 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700159 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700160 flow_caps_common(self, is_exact=False)
Dan Talayco3788a3d2011-08-23 22:50:07 -0700161
162test_prio["FillTableWC"] = -1