Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dynamic port configuration - add port buffer cfg to the port ref counter #2194

Merged
merged 6 commits into from
Aug 29, 2022
Merged
81 changes: 69 additions & 12 deletions tests/test_port_add_remove.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import pytest
import time
import buffer_model
from dvslib.dvs_common import PollingConfig

# the port to be removed and add
Expand All @@ -8,30 +9,50 @@

"""
DELETE_CREATE_ITERATIONS defines the number of iteration of delete and create to ports,
we add different timeouts between delete/create to catch potential race condition that can lead to system crush.
we add different timeouts between delete/create to catch potential race condition that can lead to system crush

Add \ Remove of Buffers can be done only when the model is dynamic.
"""
DELETE_CREATE_ITERATIONS = 10

@pytest.yield_fixture
def dynamic_buffer(dvs):
buffer_model.enable_dynamic_buffer(dvs.get_config_db(), dvs.runcmd)
yield
buffer_model.disable_dynamic_buffer(dvs.get_config_db(), dvs.runcmd)

@pytest.mark.usefixtures('dvs_port_manager')
@pytest.mark.usefixtures("dynamic_buffer")
class TestPortAddRemove(object):

def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
config_db = dvs.get_config_db()
asic_db = dvs.get_asic_db()
state_db = dvs.get_state_db()
app_db = dvs.get_app_db()

# set mmu size
fvs = {"mmu_size": "12766208"}
state_db.create_entry("BUFFER_MAX_PARAM_TABLE", "global", fvs)
bufferMaxParameter = state_db.wait_for_entry("BUFFER_MAX_PARAM_TABLE", PORT_A)
dprital marked this conversation as resolved.
Show resolved Hide resolved

# Startup interface
dvs.port_admin_set(PORT_A, 'up')

# get port info
port_info = config_db.get_entry("PORT", PORT_A)

# get the number of ports before removal
num_of_ports = len(asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT"))

# remove buffer pg cfg for the port
# record the buffer pgs before removing them
# remove buffer pg cfg for the port (record the buffer pgs before removing them)
pgs = config_db.get_keys('BUFFER_PG')
buffer_pgs = {}
for key in pgs:
if PORT_A in key:
buffer_pgs[key] = config_db.get_entry('BUFFER_PG', key)
config_db.delete_entry('BUFFER_PG', key)
app_db.wait_for_deleted_entry("BUFFER_PG_TABLE", key)

# modify buffer queue entry to egress_lossless_profile instead of egress_lossy_profile
config_db.update_entry("BUFFER_QUEUE", "%s|0-2"%PORT_A, {"profile": "egress_lossless_profile"})
Expand All @@ -43,7 +64,11 @@ def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
if PORT_A in key:
buffer_queues[key] = config_db.get_entry('BUFFER_QUEUE', key)
config_db.delete_entry('BUFFER_QUEUE', key)
app_db.wait_for_deleted_entry('BUFFER_QUEUE_TABLE', key)

# Shutdown interface
dvs.port_admin_set(PORT_A, 'down')

# try to remove this port
config_db.delete_entry('PORT', PORT_A)
num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
Expand All @@ -53,7 +78,9 @@ def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
# verify that the port was removed properly since all buffer configuration was removed also
assert len(num) == num_of_ports - 1

config_db.create_entry("PORT", PORT_A, port_info)
# set back the port
config_db.update_entry("PORT", PORT_A, port_info)

# verify that the port has been readded
num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
num_of_ports,
Expand All @@ -68,6 +95,8 @@ def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
for key, queue in buffer_queues.items():
config_db.update_entry("BUFFER_QUEUE", key, queue)

time.sleep(5)

# Remove the port with buffer configuration
config_db.delete_entry('PORT', PORT_A)
num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
Expand All @@ -80,6 +109,7 @@ def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
# Remove buffer pgs
for key in buffer_pgs.keys():
config_db.delete_entry('BUFFER_PG', key)
app_db.wait_for_deleted_entry("BUFFER_PG_TABLE", key)

num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
num_of_ports-1,
Expand All @@ -91,6 +121,7 @@ def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
# Remove buffer queue
for key in buffer_queues.keys():
config_db.delete_entry('BUFFER_QUEUE', key)
app_db.wait_for_deleted_entry('BUFFER_QUEUE_TABLE', key)

num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
num_of_ports-1,
Expand All @@ -99,13 +130,18 @@ def test_remove_add_remove_port_with_buffer_cfg(self, dvs, testlog):
# verify that the port wasn't removed since we still have buffer cfg
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

incorrect comment. at this point the port is expected to be removed

assert len(num) == num_of_ports - 1

# set back the port as it is required for next test
config_db.update_entry("PORT", PORT_A, port_info)



@pytest.mark.parametrize("scenario", ["one_port", "all_ports"])
def test_add_remove_all_the_ports(self, dvs, testlog, scenario):
config_db = dvs.get_config_db()
state_db = dvs.get_state_db()
asic_db = dvs.get_asic_db()

app_db = dvs.get_app_db()

# get the number of ports before removal
num_of_ports = len(asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT"))

Expand All @@ -117,20 +153,38 @@ def test_add_remove_all_the_ports(self, dvs, testlog, scenario):
else:
assert False

# delete all PGs and QUEUEs from the relevant ports
pgs = config_db.get_keys('BUFFER_PG')
queues = config_db.get_keys('BUFFER_QUEUE')

for port in ports:
for key in pgs:
if port in key:
config_db.delete_entry('BUFFER_PG', key)
app_db.wait_for_deleted_entry('BUFFER_PG_TABLE', key)

for key in queues:
if port in key:
config_db.delete_entry('BUFFER_QUEUE', key)
app_db.wait_for_deleted_entry('BUFFER_QUEUE_TABLE', key)

ports_info = {}


for key in ports:
# read port info and save it
ports_info[key] = config_db.get_entry("PORT", key)


for i in range(DELETE_CREATE_ITERATIONS):
# remove ports
for key in ports:
# read port info and save it
ports_info[key] = config_db.get_entry("PORT", key)

# remove a port
self.dvs_port.remove_port(key)
config_db.delete_entry('PORT',key)
app_db.wait_for_deleted_entry("PORT_TABLE", key)

# verify remove port
num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
num_of_ports-len(ports))

assert len(num) == num_of_ports-len(ports)

# add port
Expand All @@ -140,17 +194,20 @@ def test_add_remove_all_the_ports(self, dvs, testlog, scenario):
"""
time.sleep(i%3)
for key in ports:
config_db.create_entry("PORT", key, ports_info[key])
config_db.update_entry("PORT", key, ports_info[key])
app_db.wait_for_entry('PORT_TABLE',key)

# verify add port
num = asic_db.wait_for_n_keys("ASIC_STATE:SAI_OBJECT_TYPE_PORT",
num_of_ports)

assert len(num) == num_of_ports

time.sleep((i%2)+1)

# run ping
dvs.setup_db()

dvs.create_vlan("6")
dvs.create_vlan_member("6", PORT_A)
dvs.create_vlan_member("6", PORT_B)
Expand Down