blob: 51974469043d4d9a8945310864577bc5a7177eaf [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.
"""
Check README file
"""
from oftest import config
import logging
import oftest.base_tests as base_tests
import ofp
import os
import time
import json
from oftest.testutils import *
from accton_util import *
from oftest.utils import *
from oftest.ofdpa_utils import *
from accton_util import *
# Number of xconnections created per port
xcon_num = 64
# Number of seconds to wait after switch restart
rest_num = 300
#### Global variable # defined globally to check whether base_config was executed or not
BASE_RUN = False
#####
##Test cases assumes the ONOS controller is Running and Fabric SWitch is configured to use ONOS as the SDN Controller
## Test cases assumes ONOS controller is in a clean state
## Test cases assumes Fabric switch is in clean state without any flows or group entries from a previous configuration. Its a good idea to reload the Fabric switch before starting the test cases.
## Refer to the test plan for more details
class FabricSW_Scale_Base_TC_0005(base_tests.SimpleDataPlane):
"""
This Test case defines the base configuration which will serve as a pre-requisite on top of which other test cases are executed.
"""
### Read config parameters from JSON file 'global_vars.json'
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
with open(ROOT_DIR + '/' + 'global_vars.json') as f:
data = json.load(f)
onos_server_ip = data['onos_server_ip']
onos_user = data['onos_user']
onos_passwd = data['onos_passwd']
switch_ip = data['switch_ip']
switch_user = data['switch_user']
switch_passwd = data['switch_passwd']
def runTest(self):
global BASE_RUN
try:
if len(config[ "port_map" ]) < 4:
logging.info("Port count less than 4, can't run this case")
assert False, "Port count less than 4, can't run this case"
return
base_config(self)
onos_flow_group_dump(self)
switch_flow_group_dump(self)
time.sleep(2)
verify_traffic(self)
finally:
BASE_RUN = True
logging.info("End of Test")
class FabricSW_Scale_Base_TC_0010(base_tests.SimpleDataPlane):
"""
Verify that with scaled up flow configurations, rebooting the switch restores all flows and handles traffic as expected.
"""
### Read config parameters from JSON file 'global_vars.json'
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
with open(ROOT_DIR + '/' + 'global_vars.json') as f:
data = json.load(f)
switch_ip = data['switch_ip']
switch_user = data['switch_user']
switch_passwd = data['switch_passwd']
def runTest(self):
global BASE_RUN
try:
if len( config[ "port_map" ] ) < 4:
logging.info( "Port count less than 4, can't run this case")
assert False, "Port count less than 4, can't run this case"
return
if BASE_RUN == False:
logging.info("Test FabricSW_Scale_Base_TC_0010 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case,"
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0010")
assert False, "Test FabricSW_Scale_Base_TC_0010 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case," \
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0010"
return
# Reboot switch
logging.info("Restarting switch")
print("Restarting switch")
switch_restart(self)
logging.info("Switch is restarting, wait for 300 secs")
time.sleep(rest_num)
logging.info("Switch is restarted")
#Verify traffic after switch reboot
logging.info("Verify traffic")
verify_traffic(self)
time.sleep(2)
finally:
logging.info("End of Test")
class FabricSW_Scale_Base_TC_0015(base_tests.SimpleDataPlane):
"""
Verify that with scaled up flow configurations, after flapping the data port multiple times the switch restores all flows and handles traffic as expected.
"""
### Read config parameters from JSON file 'global_vars.json'
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
with open(ROOT_DIR + '/' + 'global_vars.json') as f:
data = json.load(f)
switch_ip = data['switch_ip']
switch_user = data['switch_user']
switch_passwd = data['switch_passwd']
def runTest(self):
global BASE_RUN
try:
if len( config[ "port_map" ] ) < 4:
logging.info( "Port count less than 4, can't run this case" )
assert False, "Port count less than 4, can't run this case"
return
if BASE_RUN == False:
logging.info("Test FabricSW_Scale_Base_TC_0015 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case,"
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0015")
assert False, "Test FabricSW_Scale_Base_TC_0015 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case," \
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0015"
return
ports = sorted(config["port_map"].keys())
# Flap port1 for 100 iterations
logging.info("Flap port1 for 100 iterations with an interval of '2' seconds")
for i in range(1, 100):
switch_port_enable(self, ports[0], False)
time.sleep(2)
switch_port_enable(self, ports[0], True)
time.sleep(2)
#Verify traffic after port flapping
logging.info("Verify traffic after port flapping")
time.sleep(20)
verify_traffic(self)
finally:
logging.info("End of Test")
class FabricSW_Scale_Base_TC_0020(base_tests.SimpleDataPlane):
"""
Verify that with scaled up flow configurations, after configuring and unconfiguring flows multiple times the switch is stable and handles traffic as expected.
"""
### Read config parameters from JSON file 'global_vars.json'
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
with open(ROOT_DIR + '/' + 'global_vars.json') as f:
data = json.load(f)
onos_server_ip = data['onos_server_ip']
onos_user = data['onos_user']
onos_passwd = data['onos_passwd']
onos_port = data['onos_port']
switch_ip = data['switch_ip']
switch_user = data['switch_user']
switch_passwd = data['switch_passwd']
def runTest(self):
global BASE_RUN
try:
if len( config[ "port_map" ] ) < 4:
logging.info( "Port count less than 4, can't run this case")
assert False, "Port count less than 4, can't run this case"
return
if BASE_RUN == False:
logging.info("Test FabricSW_Scale_Base_TC_0020 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case,"
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0020")
assert False, "Test FabricSW_Scale_Base_TC_0020 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case," \
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0020"
return
# Un-configure and re-configure of all 'vlan-cross-connect' pairs for 100 iterations with an interval of 5 seconds.
logging.info("Un-configure and re-configure of all 'vlan-cross-connect' pairs for 100 iterations with an interval of 5 seconds")
for i in range(1, 100):
print("Re-create config iteration: ", i)
logging.info("Re-create config iteration: {}".format(i))
remove_base_config(self)
time.sleep(5)
base_config(self)
#Verify traffic after config re-creation
logging.info("Verify traffic after config re-creation")
time.sleep(2)
verify_traffic(self)
finally:
logging.info("End of Test")
class FabricSW_Scale_Base_TC_0025(base_tests.SimpleDataPlane):
"""
Verify that with scaled up flow configurations, sending bursts of control traffic (resulting in "Packet_In" messages from switch to controller) the switch is stable and handles traffic as expected.
"""
### Read config parameters from JSON file 'global_vars.json'
ROOT_DIR = os.path.dirname(os.path.realpath(__file__))
with open(ROOT_DIR + '/' + 'global_vars.json') as f:
data = json.load(f)
switch_ip = data['switch_ip']
switch_user = data['switch_user']
switch_passwd = data['switch_passwd']
controller_ip = data['controller_ip']
controller_port = data['controller_port']
onos_server_ip = data['onos_server_ip']
onos_user = data['onos_user']
onos_passwd = data['onos_passwd']
onos_port = data['onos_port']
def runTest(self):
global BASE_RUN
try:
if len( config[ "port_map" ] ) < 4:
logging.info( "Port count less than 4, can't run this case" )
assert False, "Port count less than 4, can't run this case"
return
if BASE_RUN == False:
logging.info("Test FabricSW_Scale_Base_TC_0025 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case,"
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0025")
assert False, "Test FabricSW_Scale_Base_TC_0025 cannot be executed. FabricSW_Scale_Base_TC_0005 is a pre-requisite to this test case," \
" Please execute FabricSW_Scale_Base_TC_0005 before FabricSW_Scale_Base_TC_0025"
return
# create match
match = ofp.match()
match.oxm_list.append(ofp.oxm.eth_type(0x0800))
match.oxm_list.append(ofp.oxm.ip_proto(1))
request = ofp.message.flow_add(table_id=60, cookie=42, match=match, instructions=[
ofp.instruction.apply_actions(actions=[
ofp.action.output(port=ofp.OFPP_CONTROLLER, max_len=ofp.OFPCML_NO_BUFFER)]), ],
buffer_id=ofp.OFP_NO_BUFFER, priority=1)
logging.info("Add an ACL table entry to match ICMP packets and send to controller")
self.controller.message_send(request)
# Sent a burst of 64 ICMP packets to data ports 2, 3, and 4.
logging.info("Sent a burst of 64 ICMP packets to data ports 2, 3, and 4.")
ports = sorted(config["port_map"].keys())
# Send ICMP packets to port2
pair = [ports[0], ports[1]]
tmp_ports = list(pair)
tmp_ports.remove(pair[0])
logging.info("Creating ICMP packets for port2")
# change dest based on port number
mac_src = '00:12:34:56:78:%02X' % pair[1]
parsed_pkt = simple_icmp_packet(eth_src=mac_src)
pkt = str(parsed_pkt)
for i in range(64):
self.dataplane.send(pair[1], pkt)
print('ICMP to port1 iteration:', i)
verify_packet_in(self, pkt, ports[1], ofp.OFPR_ACTION)
# Send ICMP packets to port3
pair = [ports[0], ports[2]]
tmp_ports = list(pair)
tmp_ports.remove(pair[0])
logging.info("Creating ICMP packets for port3")
# change dest based on port number
mac_src = '00:12:34:56:78:%02X' % pair[1]
parsed_pkt = simple_icmp_packet(eth_src=mac_src)
pkt = str(parsed_pkt)
for i in range(64):
self.dataplane.send(pair[1], pkt)
print('ICMP to port2 iteration:', i)
verify_packet_in(self, pkt, ports[2], ofp.OFPR_ACTION)
# time.sleep(2)
# Send ICMP packets to port4
pair = [ports[0], ports[3]]
tmp_ports = list(pair)
tmp_ports.remove(pair[0])
logging.info("Creating ICMP packets for port4")
# change dest based on port number
mac_src = '00:12:34:56:78:%02X' % pair[1]
parsed_pkt = simple_icmp_packet(eth_src=mac_src)
pkt = str(parsed_pkt)
for i in range(64):
self.dataplane.send(pair[1], pkt)
print('ICMP to port3 iteration: ', i)
verify_packet_in(self, pkt, ports[3], ofp.OFPR_ACTION)
finally:
remove_base_config(self)
logging.info("End of Test")
def base_config(self):
ports = (config["port_map"].keys())
datapathid = get_datapathid(self)
l = []
start, end = 101, (101 + xcon_num)
l.extend(range(start, end))
# Create flows between port1 and port2
logging.info("Configure 64 vlan-cross-connect pair between data ports 1 and 2 for vlan101 to vlan164")
for i in l:
print('adding xconn port1-2', i)
add_onos_xconnect(self, datapathid, i, ports[0], ports[1])
# Create flows between port1 and port3
logging.info("Configure 64 vlan-cross-connect pair between data ports 1 and 3 for vlan201 to vlan264")
l = []
start, end = 201, (201 + xcon_num)
l.extend(range(start, end))
for i in l:
print('adding xconn port1-3', i)
add_onos_xconnect(self, datapathid, i, ports[0], ports[2])
# Create flows between port1 and port3
logging.info("Configure 64 vlan-cross-connect pair between data ports 1 and 4 for vlan301 to vlan364")
l = []
start, end = 301, (301 + xcon_num)
l.extend(range(start, end))
for i in l:
print('adding xconn port1-4', i)
add_onos_xconnect(self, datapathid, i, ports[0], ports[3])
def remove_base_config(self):
datapathid = get_datapathid(self)
l = []
start, end = 101, (101 + xcon_num)
l.extend(range(start, end))
# Remove flows vlan101 - vlan164 between ports 1 and 2
logging.info("Remove flows vlan101 - vlan164 between ports 1 and 2")
for i in l:
remove_onos_xconnect(self, datapathid, i)
#Removeflows vlan201 - vlan264 between ports 1 and 3
logging.info("Remove flows vlan201 - vlan264 between ports 1 and 3")
l = []
start, end = 201, (201 + xcon_num)
l.extend(range(start, end))
for i in l:
remove_onos_xconnect(self, datapathid, i)
# Remove flows vlan301 - vlan364 between ports 1 and 4
logging.info("Remove flows vlan301 - vlan364 between ports 1 and 4")
l = []
start, end = 301, (301 + xcon_num)
l.extend(range(start, end))
for i in l:
remove_onos_xconnect(self, datapathid, i)
def verify_traffic(self):
ports = sorted(config["port_map"].keys())
##### Reverse traffic verification. From BNG to OLT" ########
# # Create and send packets between port1 and port2
# pair = [ports[0], ports[1]]
# packets1 = []
# logging.info("Create double tagged vlan packets with outer vlan IDs 101 - 164 between port1 and port2")
# # change dest based on port number
# mac_src = '00:12:34:56:78:%02X' % ports[0]
# l = []
# start, end = 101, (101 + xcon_num)
# l.extend(range(start, end))
# for i in l:
# parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
# out_vlan_vid=i, in_dl_vlan_enable=True, in_vlan_vid=10,
# eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
#
# pkt = str(parsed_pkt)
# packets1.append(pkt)
#
# logging.info("Transmit double tagged vlan packets with outer vlan101 - vlan164 to data port1")
# logging.info("Verify packets are flooded out of data port 2")
# for i in packets1:
# self.dataplane.send(pair[0], i)
# print('verify port1-2, xcon: ', (packets1.index(i)+101))
# verify_packet(self, i, pair[1])
# verify_no_packet(self, i, pair[0])
# time.sleep(1)
##### Reverse traffic verification. From BNG to OLT" ########
# # Create and send packets between port1 and port3
# pair = [ports[0], ports[2]]
# packets2 = []
# logging.info("Create double tagged vlan packets with outer vlan IDs 201 - 264 between port1 and port3")
# # change dest based on port number
# mac_src = '00:12:34:56:78:%02X' % ports[0]
# l = []
# start, end = 201, (201 + xcon_num)
# l.extend(range(start, end))
# for i in l:
# parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
# out_vlan_vid=i, in_dl_vlan_enable=True, in_vlan_vid=10,
# eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
#
# pkt = str(parsed_pkt)
# packets2.append(pkt)
#
# logging.info("Transmit double tagged vlan packets with outer vlan201 - vlan264 to data port1")
# logging.info("Verify packets are flooded out of data port 3")
# for i in packets2:
# self.dataplane.send(pair[0], i)
# # verify traffic
# print('verify port1-3, xcon: ', packets2.index(i)+201)
# verify_packet(self, i, pair[1])
# verify_no_packet(self, i, pair[0])
#
# time.sleep(1)
##### Reverse traffic verification. From BNG to OLT" ########
# Create and send packets between port1 and port4
# pair = [ports[0], ports[3]]
# packets3 = []
# logging.info(
# "Create double tagged vlan packets with outer vlan IDs 301 - 364 between port1 and port4")
# # change dest based on port number
# mac_src = '00:12:34:56:78:%02X' % pair[0]
# l = []
# start, end = 301, (301 + xcon_num)
# l.extend(range(start, end))
# for i in l:
# parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
# out_vlan_vid=i, in_dl_vlan_enable=True, in_vlan_vid=10,
# eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
#
# pkt = str(parsed_pkt)
# packets3.append(pkt)
#
# logging.info("Transmit double tagged vlan packets with outer vlan301 - vlan364 to data port1")
# logging.info("Verify packets are flooded out of data port 4")
# for i in packets3:
# self.dataplane.send(pair[0], i)
# # verify traffic
# print('verify port1-4, xcon: ', packets3.index(i)+301)
# verify_packet(self, i, pair[1])
# verify_no_packet(self, i, pair[0])
#
# time.sleep(1)
# Create and send packets between port2 and port1
pair = [ports[0], ports[1]]
packets1 = []
logging.info("Create double tagged vlan packets with outer vlan IDs 101 - 164 between port2 and port1")
# change dest based on port number
mac_src = '00:12:34:56:78:%02X' % ports[1]
l = []
start, end = 101, (101 + xcon_num)
l.extend(range(start, end))
for i in l:
parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
out_vlan_vid=i, in_dl_vlan_enable=True, in_vlan_vid=10,
eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
pkt = str(parsed_pkt)
packets1.append(pkt)
logging.info("Transmit double tagged vlan packets with outer vlan101 - vlan164 to data port2")
logging.info("Verify packets are flooded out of data port 1")
for i in packets1:
logging.info("Transmitting packet {}".format(packets1.index(i) + 1))
self.dataplane.send(pair[1], i)
# verify traffic
print('verify port2-1, xcon: ', packets1.index(i)+101)
verify_packet(self, i, pair[0])
verify_no_packet(self, i, pair[1])
time.sleep(1)
# # Create and send packets between port3 and port1
pair = [ports[0], ports[2]]
packets2 = []
logging.info("Create double tagged vlan packets with outer vlan IDs 201 - 264 between port3 and port1")
# change dest based on port number
mac_src = '00:12:34:56:78:%02X' % ports[2]
l = []
start, end = 201, (201 + xcon_num)
l.extend(range(start, end))
for i in l:
parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
out_vlan_vid=i, in_dl_vlan_enable=True, in_vlan_vid=10,
eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
pkt = str(parsed_pkt)
packets2.append(pkt)
logging.info("Transmit double tagged vlan packets with outer vlan101 - vlan164 to data port3")
logging.info("Verify packets are flooded out of data port 1")
for i in packets2:
logging.info("Transmitting packet {}".format(packets2.index(i) + 1))
self.dataplane.send(pair[1], i)
# verify traffic
print('verify port3-1, xcon: ', packets2.index(i)+201)
verify_packet(self, i, pair[0])
verify_no_packet(self, i, pair[1])
time.sleep(1)
# Create and send packets between port4 and port1
pair = [ports[0], ports[3]]
packets3 = []
logging.info(
"Create double tagged vlan packets with outer vlan IDs 301 - 364 between port4 and port1")
# change dest based on port number
mac_src = '00:12:34:56:78:%02X' % ports[3]
l = []
start, end = 301, (301 + xcon_num)
l.extend(range(start, end))
for i in l:
parsed_pkt = simple_tcp_packet_two_vlan(pktlen=108, out_dl_vlan_enable=True,
out_vlan_vid=i, in_dl_vlan_enable=True, in_vlan_vid=10,
eth_dst='00:12:34:56:78:9a', eth_src=mac_src)
pkt = str(parsed_pkt)
packets3.append(pkt)
logging.info("Transmit double tagged vlan packets with outer vlan101 - vlan164 to data port4")
logging.info("Verify packets are flooded out of data port 1")
for i in packets3:
logging.info("Transmitting packet {}".format(packets3.index(i) + 1))
self.dataplane.send(pair[1], i)
# verify traffic
print('verify port4-1, xcon: ', packets3.index(i)+301)
verify_packet(self, i, pair[0])
verify_no_packet(self, i, pair[1])
def get_datapathid(self):
feature_reply = get_featureReplay(self)
str_datapath_id_f = "{:016x}".format(feature_reply.datapath_id)
return str_datapath_id_f
def onos_flow_group_dump(self, logfile_name="ONOS_flow_and_groups_dump.log"):
# Dump the created flows and groups from ONOS in a separate file
datapathid = get_datapathid(self)
log_path = (config["log_dir"])
log_file = logfile_name
logging.info(
"The configured flow and group entries from onos are dumped to " + log_path + '/' + log_file)
send_command_to_onos_cli(log_file, "flows -s any " + datapathid, self.onos_server_ip, self.onos_user,
self.onos_passwd, regexp='onos>')
send_command_to_onos_cli(log_file, "groups", self.onos_server_ip, self.onos_user, self.onos_passwd, regexp='onos>')
def switch_flow_group_dump(self, logfile_name="Switch_flow_and_groups_dump.log"):
# Dump the created flows and groups from Openflow Switch in a separate file
datapathid = get_datapathid(self)
log_path = (config["log_dir"])
log_file = logfile_name
logging.info(
"The configured flow and group entries from switch are dumped to " + log_path + '/' + log_file)
send_command_to_switch_cli(log_file, "client_flowtable_dump", self.switch_ip,
self.switch_user, self.switch_passwd, regexp='root@localhost:~#')
send_command_to_switch_cli(log_file, "client_grouptable_dump", self.switch_ip,
self.switch_user, self.switch_passwd, regexp='root@localhost:~#')