blob: 8800705f0fd2620b6c01f5e757810cca6fdedb6e [file] [log] [blame]
# Copyright 2017-present Open Networking Foundation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""
Basic capabilities and capacities tests
"""
import logging
import time
import unittest
from oftest import config
import oftest.controller as controller
import ofp
import oftest.dataplane as dataplane
import oftest.parse as parse
import oftest.base_tests as base_tests
from oftest.testutils import *
def flow_caps_common(obj, is_exact=True):
"""
The common function for
@param obj The calling object
@param is_exact If True, checking exact match; else wildcard
"""
of_ports = config["port_map"].keys()
of_ports.sort()
delete_all_flows(obj.controller)
pkt = simple_tcp_packet()
match = packet_to_flow_match(obj, pkt)
obj.assertTrue(match is not None, "Could not generate flow match from pkt")
for port in of_ports:
break;
match.in_port = port
match.ipv4_src = 1
request = ofp.message.flow_add()
count_check = 101 # fixme: better way to determine this.
if is_exact:
match.wildcards = 0
else:
match.wildcards |= ofp.OFPFW_DL_SRC
request.match = match
request.buffer_id = 0xffffffff # set to NONE
logging.info(request.show())
tstats = ofp.message.table_stats_request()
try: # Determine the table index to check (or "all")
table_idx = config["caps_table_idx"]
except:
table_idx = -1 # Accumulate all table counts
# Make sure we can install at least one flow
logging.info("Inserting initial flow")
obj.controller.message_send(request)
do_barrier(obj.controller, timeout=10)
flow_count = 1
logging.info("Table idx: " + str(table_idx))
logging.info("Check every " + str(count_check) + " inserts")
while True:
request.match.ipv4_src += 1
obj.controller.message_send(request)
flow_count += 1
if flow_count % count_check == 0:
do_barrier(obj.controller, timeout=10)
response, pkt = obj.controller.transact(tstats)
obj.assertTrue(response is not None, "Get tab stats failed")
logging.info(response.show())
if table_idx == -1: # Accumulate for all tables
active_flows = 0
for stats in response.entries:
active_flows += stats.active_count
else: # Table index to use specified in config
active_flows = response.entries[table_idx].active_count
if active_flows != flow_count:
break
logging.error("RESULT: " + str(flow_count) + " flows inserted")
logging.error("RESULT: " + str(active_flows) + " flows reported")
# clean up and wait a bit in case the table is really big
delete_all_flows(obj.controller)
time.sleep(flow_count / 100)
@disabled
class FillTableExact(base_tests.SimpleProtocol):
"""
Fill the flow table with exact matches; can take a while
Fill table until no more flows can be added. Report result.
Increment the source IP address. Assume the flow table will
fill in less than 4 billion inserts
To check the number of flows in the tables is expensive, so
it's only done periodically. This is controlled by the
count_check variable.
A switch may have multiple tables. The default behaviour
is to count all the flows in all the tables. By setting
the parameter "caps_table_idx" in the configuration array,
you can control which table to check.
"""
def runTest(self):
logging.info("Running " + str(self))
flow_caps_common(self)
@disabled
class FillTableWC(base_tests.SimpleProtocol):
"""
Fill the flow table with wildcard matches
Fill table using wildcard entries until no more flows can be
added. Report result.
Increment the source IP address. Assume the flow table will
fill in less than 4 billion inserts
To check the number of flows in the tables is expensive, so
it's only done periodically. This is controlled by the
count_check variable.
A switch may have multiple tables. The default behaviour
is to count all the flows in all the tables. By setting
the parameter "caps_table_idx" in the configuration array,
you can control which table to check.
"""
def runTest(self):
logging.info("Running " + str(self))
flow_caps_common(self, is_exact=False)