blob: c75bd5603dbcea29059c3a873755a5f399d4396d [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
Rich Lane477f4812012-10-04 22:49:00 -070010from oftest import config
Dan Talayco79c6c4d2010-06-08 14:01:53 -070011import oftest.controller as controller
12import oftest.cstruct as ofp
13import oftest.message as message
14import oftest.dataplane as dataplane
15import oftest.action as action
16import oftest.parse as parse
Rich Laneb90a1c42012-10-05 09:16:05 -070017import oftest.base_tests as base_tests
Dan Talayco79c6c4d2010-06-08 14:01:53 -070018
Rich Laneda3b5ad2012-10-03 09:05:32 -070019from oftest.testutils import *
Dan Talayco79c6c4d2010-06-08 14:01:53 -070020
Dan Talayco79c6c4d2010-06-08 14:01:53 -070021def flow_caps_common(obj, is_exact=True):
22 """
23 The common function for
24
25 @param obj The calling object
26 @param is_exact If True, checking exact match; else wildcard
27 """
28
Rich Lane477f4812012-10-04 22:49:00 -070029 of_ports = config["port_map"].keys()
Dan Talayco79c6c4d2010-06-08 14:01:53 -070030 of_ports.sort()
31
Rich Lane32bf9482013-01-03 17:26:30 -080032 delete_all_flows(obj.controller)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070033
34 pkt = simple_tcp_packet()
Ed Swierk6192e512012-08-22 11:41:40 -070035 match = packet_to_flow_match(obj, pkt)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070036 obj.assertTrue(match is not None, "Could not generate flow match from pkt")
37 for port in of_ports:
38 break;
39 match.in_port = port
40 match.nw_src = 1
41 request = message.flow_mod()
42 count_check = 101 # fixme: better way to determine this.
43 if is_exact:
44 match.wildcards = 0
45 else:
46 match.wildcards |= ofp.OFPFW_DL_SRC
47
48 request.match = match
Rob Sherwood9130bcd2012-03-07 12:23:50 -080049 request.buffer_id = 0xffffffff # set to NONE
Rich Lane9a003812012-10-04 17:17:59 -070050 logging.info(request.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070051
52 tstats = message.table_stats_request()
53 try: # Determine the table index to check (or "all")
Rich Lane477f4812012-10-04 22:49:00 -070054 table_idx = config["caps_table_idx"]
Dan Talayco79c6c4d2010-06-08 14:01:53 -070055 except:
56 table_idx = -1 # Accumulate all table counts
57
58 # Make sure we can install at least one flow
Rich Lane9a003812012-10-04 17:17:59 -070059 logging.info("Inserting initial flow")
Rich Lane5c3151c2013-01-03 17:15:41 -080060 obj.controller.message_send(request)
Rich Lane3a261d52013-01-03 17:45:08 -080061 do_barrier(obj.controller, timeout=10)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070062 flow_count = 1
63
Rich Lane9a003812012-10-04 17:17:59 -070064 logging.info("Table idx: " + str(table_idx))
65 logging.info("Check every " + str(count_check) + " inserts")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070066
67 while True:
68 request.match.nw_src += 1
Rich Lane5c3151c2013-01-03 17:15:41 -080069 obj.controller.message_send(request)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070070 flow_count += 1
71 if flow_count % count_check == 0:
Rich Lane3a261d52013-01-03 17:45:08 -080072 do_barrier(obj.controller, timeout=10)
Rich Lanec8aaa3e2012-07-26 19:28:02 -070073 response, pkt = obj.controller.transact(tstats)
Dan Talayco79c6c4d2010-06-08 14:01:53 -070074 obj.assertTrue(response is not None, "Get tab stats failed")
Rich Lane9a003812012-10-04 17:17:59 -070075 logging.info(response.show())
Dan Talayco79c6c4d2010-06-08 14:01:53 -070076 if table_idx == -1: # Accumulate for all tables
77 active_flows = 0
78 for stats in response.stats:
79 active_flows += stats.active_count
80 else: # Table index to use specified in config
81 active_flows = response.stats[table_idx].active_count
82 if active_flows != flow_count:
83 break
84
Rich Lane9a003812012-10-04 17:17:59 -070085 logging.error("RESULT: " + str(flow_count) + " flows inserted")
86 logging.error("RESULT: " + str(active_flows) + " flows reported")
Dan Talayco79c6c4d2010-06-08 14:01:53 -070087
Shudong Zhoud71c4a72012-11-18 14:37:43 -080088 # clean up and wait a bit in case the table is really big
Rich Lane32bf9482013-01-03 17:26:30 -080089 delete_all_flows(obj.controller)
Shudong Zhoud71c4a72012-11-18 14:37:43 -080090 time.sleep(flow_count / 100)
91
92
Rich Lane0a4f6372013-01-02 14:40:22 -080093@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -070094class FillTableExact(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -070095 """
Dan Talayco8f91a5b2010-07-20 14:07:21 -070096 Fill the flow table with exact matches; can take a while
Dan Talayco79c6c4d2010-06-08 14:01:53 -070097
98 Fill table until no more flows can be added. Report result.
99 Increment the source IP address. Assume the flow table will
100 fill in less than 4 billion inserts
101
102 To check the number of flows in the tables is expensive, so
103 it's only done periodically. This is controlled by the
104 count_check variable.
105
106 A switch may have multiple tables. The default behaviour
107 is to count all the flows in all the tables. By setting
108 the parameter "caps_table_idx" in the configuration array,
109 you can control which table to check.
110 """
Rich Laned1d9c282012-10-04 22:07:10 -0700111
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700112 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700113 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700114 flow_caps_common(self)
115
Rich Lane0a4f6372013-01-02 14:40:22 -0800116@disabled
Rich Laneb90a1c42012-10-05 09:16:05 -0700117class FillTableWC(base_tests.SimpleProtocol):
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700118 """
119 Fill the flow table with wildcard matches
120
121 Fill table using wildcard entries until no more flows can be
122 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 """
Rich Laned1d9c282012-10-04 22:07:10 -0700136
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700137 def runTest(self):
Rich Lane9a003812012-10-04 17:17:59 -0700138 logging.info("Running " + str(self))
Dan Talayco79c6c4d2010-06-08 14:01:53 -0700139 flow_caps_common(self, is_exact=False)