Skip to content

Commit c6765b6

Browse files
committed
Improve the vstest according to review comments
- Very the profile in ASIC_DB when possible: in case of a new profile is created, we can get the OID of the profile by comparing SAI OID set before and after the creation - Add function which can switch buffer model dynamically - Add testcases for mtu update and non-default alpha Signed-off-by: Stephen Sun <stephens@nvidia.com>
1 parent 3aae098 commit c6765b6

File tree

3 files changed

+233
-13
lines changed

3 files changed

+233
-13
lines changed

tests/buffer_model.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
import pytest
2+
import re
3+
import time
4+
5+
lossless_profile_name_pattern = 'pg_lossless_([1-9][0-9]*000)_([1-9][0-9]*m)_profile'
6+
def enable_dynamic_buffer(config_db, cmd_runner):
7+
# check whether it's already running dynamic mode
8+
device_meta = config_db.get_entry('DEVICE_METADATA', 'localhost')
9+
if device_meta['buffer_model'] == 'dynamic':
10+
return
11+
12+
device_meta['buffer_model'] = 'dynamic'
13+
config_db.update_entry('DEVICE_METADATA', 'localhost', device_meta)
14+
15+
# stop the buffermgrd in order to avoid it copying tables to appl db
16+
cmd_runner("supervisorctl stop buffermgrd")
17+
18+
# update lossless PGs from BUFFER_PG table
19+
pgs = config_db.get_keys('BUFFER_PG')
20+
for key in pgs:
21+
pg = config_db.get_entry('BUFFER_PG', key)
22+
if re.search(lossless_profile_name_pattern, pg['profile']):
23+
pg['profile'] = 'NULL'
24+
config_db.update_entry('BUFFER_PG', key, pg)
25+
26+
# Remove the dynamically generated profiles
27+
profiles = config_db.get_keys('BUFFER_PROFILE')
28+
for key in profiles:
29+
if re.search(lossless_profile_name_pattern, key):
30+
config_db.delete_entry('BUFFER_PROFILE', key)
31+
32+
profiles = config_db.get_keys('BUFFER_PROFILE')
33+
for key in profiles:
34+
if re.search(lossless_profile_name_pattern, key):
35+
assert False, "dynamically generated profile still exists"
36+
37+
# restart daemon
38+
cmd_runner("supervisorctl restart buffermgrd")
39+
# make sure dynamic buffer manager fully starts
40+
time.sleep(20)
41+
42+
43+
def disable_dynamic_buffer(config_db, cmd_runner):
44+
device_meta = config_db.get_entry('DEVICE_METADATA', 'localhost')
45+
if device_meta['buffer_model'] == 'traditional':
46+
return
47+
48+
device_meta['buffer_model'] = 'traditional'
49+
config_db.update_entry('DEVICE_METADATA', 'localhost', device_meta)
50+
51+
# Remove all the PGs referencing the lossless profiles
52+
pgs = config_db.get_keys('BUFFER_PG')
53+
for key in pgs:
54+
pg = config_db.get_entry('BUFFER_PG', key)
55+
if pg['profile'] != '[BUFFER_PROFILE|ingress_lossy_profile]':
56+
config_db.delete_entry('BUFFER_PG', key)
57+
58+
# Remove all the non-default profiles
59+
profiles = config_db.get_keys('BUFFER_PROFILE')
60+
for key in profiles:
61+
if re.search(lossless_profile_name_pattern, key):
62+
config_db.delete_entry('BUFFER_PROFILE', key)
63+
64+
# wait a sufficient amount of time to make sure all tables are removed from APPL_DB
65+
time.sleep(20)
66+
67+
# restart daemon
68+
cmd_runner("supervisorctl restart buffermgrd")
69+
70+
time.sleep(20)

tests/test_buffer.py tests/test_buffer_dynamic.py

+149-13
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,23 @@
22
import json
33
import redis
44
import pytest
5+
import re
6+
import buffer_model
57

68
from pprint import pprint
79
from swsscommon import swsscommon
10+
from dvslib.dvs_common import PollingConfig
811

12+
@pytest.yield_fixture
13+
def dynamic_buffer(dvs):
14+
buffer_model.enable_dynamic_buffer(dvs.get_config_db(), dvs.runcmd)
15+
yield
16+
buffer_model.disable_dynamic_buffer(dvs.get_config_db(), dvs.runcmd)
917

18+
19+
@pytest.mark.usefixtures("dynamic_buffer")
1020
class TestBufferMgrDyn(object):
21+
DEFAULT_POLLING_CONFIG = PollingConfig(polling_interval=0.01, timeout=40, strict=True)
1122
def setup_db(self, dvs):
1223
self.initialized = False
1324
self.cableLenTest1 = "15m"
@@ -16,6 +27,7 @@ def setup_db(self, dvs):
1627
self.speedToTest2 = "10000"
1728

1829
self.app_db = dvs.get_app_db()
30+
self.asic_db = dvs.get_asic_db()
1931
self.config_db = dvs.get_config_db()
2032
self.state_db = dvs.get_state_db()
2133

@@ -28,7 +40,7 @@ def setup_db(self, dvs):
2840
elif self.originalSpeed == "":
2941
self.originalSpeed = "100000"
3042

31-
# Check whether cabel length has been configured
43+
# Check whether cable length has been configured
3244
fvs = self.config_db.wait_for_entry("CABLE_LENGTH", "AZURE")
3345
self.originalCableLen = fvs["Ethernet0"]
3446
if self.originalCableLen == self.cableLenTest1:
@@ -39,12 +51,65 @@ def setup_db(self, dvs):
3951
fvs = {"mmu_size": "12766208"}
4052
self.state_db.create_entry("BUFFER_MAX_PARAM_TABLE", "global", fvs)
4153

54+
# The default lossless priority group will be removed ahead of staring test
55+
# By doing so all the dynamically generated profiles will be removed and
56+
# it's easy to identify the SAI OID of the new profile once it's created by
57+
# comparing the new set of ASIC_STATE:BUFFER_PROFILE table against the initial one
58+
pgs = self.config_db.get_keys('BUFFER_PG')
59+
for key in pgs:
60+
pg = self.config_db.get_entry('BUFFER_PG', key)
61+
if pg['profile'] == 'NULL':
62+
self.config_db.delete_entry('BUFFER_PG', key)
63+
64+
self.setup_asic_db(dvs)
65+
4266
self.initialized = True
4367

44-
def make_lossless_profile_name(self, speed, cable_length):
45-
return "pg_lossless_" + speed + "_" + cable_length + "_profile"
68+
def setup_asic_db(self, dvs):
69+
buffer_pool_set = set(self.asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_POOL"))
70+
self.initProfileSet = set(self.asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_PROFILE"))
71+
self.initPGSet = set(self.asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_INGRESS_PRIORITY_GROUP"))
72+
73+
ingress_lossless_pool = self.app_db.get_entry("BUFFER_POOL_TABLE", "ingress_lossless_pool")
74+
self.ingress_lossless_pool_asic = None
75+
76+
for key in buffer_pool_set:
77+
bufferpool = self.asic_db.get_entry("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_POOL", key)
78+
if bufferpool["SAI_BUFFER_POOL_ATTR_TYPE"] == "SAI_BUFFER_POOL_TYPE_INGRESS":
79+
if ingress_lossless_pool["size"] == bufferpool["SAI_BUFFER_POOL_ATTR_SIZE"]:
80+
self.ingress_lossless_pool_asic = bufferpool
81+
self.ingress_lossless_pool_oid = key
82+
83+
def check_new_profile_in_asic_db(self, dvs, profile):
84+
diff = set(self.asic_db.get_keys("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_PROFILE")) - self.initProfileSet
85+
if len(diff) == 1:
86+
self.newProfileInAsicDb = diff.pop()
87+
# in case diff is empty, we just treat the newProfileInAsicDb cached the latest one
88+
fvs = self.app_db.get_entry("BUFFER_PROFILE_TABLE", profile)
89+
if fvs.get('dynamic_th'):
90+
sai_threshold_value = fvs['dynamic_th']
91+
sai_threshold_mode = 'SAI_BUFFER_PROFILE_THRESHOLD_MODE_DYNAMIC'
92+
else:
93+
sai_threshold_value = fvs['static_th']
94+
sai_threshold_mode = 'SAI_BUFFER_PROFILE_THRESHOLD_MODE_STATIC'
95+
self.asic_db.wait_for_field_match("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_PROFILE", self.newProfileInAsicDb,
96+
{'SAI_BUFFER_PROFILE_ATTR_XON_TH': fvs['xon'],
97+
'SAI_BUFFER_PROFILE_ATTR_XOFF_TH': fvs['xoff'],
98+
'SAI_BUFFER_PROFILE_ATTR_RESERVED_BUFFER_SIZE': fvs['size'],
99+
'SAI_BUFFER_PROFILE_ATTR_POOL_ID': self.ingress_lossless_pool_oid,
100+
'SAI_BUFFER_PROFILE_ATTR_THRESHOLD_MODE': sai_threshold_mode,
101+
'SAI_BUFFER_PROFILE_ATTR_SHARED_DYNAMIC_TH': sai_threshold_value},
102+
self.DEFAULT_POLLING_CONFIG)
103+
104+
def make_lossless_profile_name(self, speed, cable_length, mtu = None, dynamic_th = None):
105+
extra = ""
106+
if mtu:
107+
extra += "_mtu" + mtu
108+
if dynamic_th:
109+
extra += "_th" + dynamic_th
110+
111+
return "pg_lossless_" + speed + "_" + cable_length + extra + "_profile"
46112

47-
@pytest.mark.skip(reason="Traditional buffer model runs on VS image currently.")
48113
def test_changeSpeed(self, dvs, testlog):
49114
self.setup_db(dvs)
50115

@@ -86,7 +151,6 @@ def test_changeSpeed(self, dvs, testlog):
86151
# remove lossless PG 3-4 on interface
87152
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 3-4")
88153

89-
@pytest.mark.skip(reason="Traditional buffer model runs on VS image currently.")
90154
def test_changeCableLen(self, dvs, testlog):
91155
self.setup_db(dvs)
92156

@@ -97,6 +161,7 @@ def test_changeCableLen(self, dvs, testlog):
97161
dvs.runcmd("config interface cable-length Ethernet0 " + self.cableLenTest1)
98162
expectedProfile = self.make_lossless_profile_name(self.originalSpeed, self.cableLenTest1)
99163
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile)
164+
self.check_new_profile_in_asic_db(dvs, expectedProfile)
100165
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
101166

102167
# Remove the lossless PGs
@@ -113,19 +178,21 @@ def test_changeCableLen(self, dvs, testlog):
113178
expectedProfile = self.make_lossless_profile_name(self.originalSpeed, self.cableLenTest2)
114179
# Check the BUFFER_PROFILE_TABLE and BUFFER_PG_TABLE
115180
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile)
181+
self.check_new_profile_in_asic_db(dvs, expectedProfile)
116182
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
117183

118184
# Revert the cable length
119185
dvs.runcmd("config interface cable-length Ethernet0 " + self.originalCableLen)
120186
# Check the BUFFER_PROFILE_TABLE and BUFFER_PG_TABLE
121187
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", expectedProfile)
188+
self.asic_db.wait_for_deleted_entry("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_PROFILE", self.newProfileInAsicDb)
122189
expectedProfile = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen)
190+
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile)
123191
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
124192

125193
# remove lossless PG 3-4 on interface
126194
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 3-4")
127195

128-
@pytest.mark.skip(reason="Traditional buffer model runs on VS image currently.")
129196
def test_MultipleLosslessPg(self, dvs, testlog):
130197
self.setup_db(dvs)
131198

@@ -149,13 +216,15 @@ def test_MultipleLosslessPg(self, dvs, testlog):
149216
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", expectedProfile)
150217
expectedProfile = self.make_lossless_profile_name(self.speedToTest1, self.cableLenTest1)
151218
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile)
219+
self.check_new_profile_in_asic_db(dvs, expectedProfile)
152220
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
153221
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:6", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
154222

155223
# revert the speed and cable length and check
156224
dvs.runcmd("config interface cable-length Ethernet0 " + self.originalCableLen)
157225
dvs.runcmd("config interface speed Ethernet0 " + self.originalSpeed)
158226
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", expectedProfile)
227+
self.asic_db.wait_for_deleted_entry("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_PROFILE", self.newProfileInAsicDb)
159228
expectedProfile = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen)
160229
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile)
161230
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
@@ -165,22 +234,23 @@ def test_MultipleLosslessPg(self, dvs, testlog):
165234
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 3-4")
166235
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 6")
167236

168-
@pytest.mark.skip(reason="Traditional buffer model runs on VS image currently.")
169237
def test_headroomOverride(self, dvs, testlog):
170238
self.setup_db(dvs)
171239

172-
# configure lossless PG 3-4 on interface
173-
dvs.runcmd("config interface buffer priority-group lossless add Ethernet0 3-4")
174-
175240
# Configure static profile
176241
dvs.runcmd("config buffer profile add test --xon 18432 --xoff 16384")
242+
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", "test")
177243
self.app_db.wait_for_exact_match("BUFFER_PROFILE_TABLE", "test",
178244
{ "pool" : "[BUFFER_POOL_TABLE:ingress_lossless_pool]",
179245
"xon" : "18432",
180246
"xoff" : "16384",
181247
"size" : "34816",
182248
"dynamic_th" : "0"
183249
})
250+
self.check_new_profile_in_asic_db(dvs, "test")
251+
252+
# configure lossless PG 3-4 on interface
253+
dvs.runcmd("config interface buffer priority-group lossless add Ethernet0 3-4")
184254

185255
dvs.runcmd("config interface cable-length Ethernet0 " + self.cableLenTest1)
186256
expectedProfile = self.make_lossless_profile_name(self.originalSpeed, self.cableLenTest1)
@@ -192,13 +262,28 @@ def test_headroomOverride(self, dvs, testlog):
192262
dvs.runcmd("config interface buffer priority-group lossless add Ethernet0 6 test")
193263
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:6", {"profile": "[BUFFER_PROFILE_TABLE:test]"})
194264

265+
# update the profile
266+
dvs.runcmd("config buffer profile set test --xon 18432 --xoff 18432")
267+
self.app_db.wait_for_exact_match("BUFFER_PROFILE_TABLE", "test",
268+
{ "pool" : "[BUFFER_POOL_TABLE:ingress_lossless_pool]",
269+
"xon" : "18432",
270+
"xoff" : "18432",
271+
"size" : "36864",
272+
"dynamic_th" : "0"
273+
})
274+
self.check_new_profile_in_asic_db(dvs, "test")
275+
195276
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0")
196277
self.app_db.wait_for_deleted_entry("BUFFER_PG_TABLE", "Ethernet0:3-4")
197278
self.app_db.wait_for_deleted_entry("BUFFER_PG_TABLE", "Ethernet0:6")
198279

199280
dvs.runcmd("config interface buffer priority-group lossless add Ethernet0 3-4")
200281
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile + "]"})
201282

283+
dvs.runcmd("config buffer profile remove test")
284+
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", "test")
285+
self.asic_db.wait_for_deleted_entry("ASIC_STATE:SAI_OBJECT_TYPE_BUFFER_PROFILE", self.newProfileInAsicDb)
286+
202287
dvs.runcmd("config interface cable-length Ethernet0 " + self.originalCableLen)
203288
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", expectedProfile)
204289
expectedProfile = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen)
@@ -208,8 +293,59 @@ def test_headroomOverride(self, dvs, testlog):
208293
# remove lossless PG 3-4 on interface
209294
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 3-4")
210295

211-
def test_bufferModel(self, dvs, testlog):
296+
def test_mtuUpdate(self, dvs, testlog):
212297
self.setup_db(dvs)
213298

214-
metadata = self.config_db.get_entry("DEVICE_METADATA", "localhost")
215-
assert metadata["buffer_model"] == "traditional"
299+
test_mtu = '1500'
300+
default_mtu = '9100'
301+
expectedProfileMtu = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen, mtu = test_mtu)
302+
expectedProfileNormal = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen)
303+
304+
# update the mtu on the interface
305+
dvs.runcmd("config interface mtu Ethernet0 {}".format(test_mtu))
306+
307+
# configure lossless PG 3-4 on interface
308+
dvs.runcmd("config interface buffer priority-group lossless add Ethernet0 3-4")
309+
310+
self.app_db.wait_for_entry("BUFFER_PG_TABLE", "Ethernet0:3-4")
311+
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfileMtu)
312+
self.check_new_profile_in_asic_db(dvs, expectedProfileMtu)
313+
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:{}]".format(expectedProfileMtu)})
314+
315+
dvs.runcmd("config interface mtu Ethernet0 {}".format(default_mtu))
316+
317+
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", expectedProfileMtu)
318+
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfileNormal)
319+
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:{}]".format(expectedProfileNormal)})
320+
321+
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 3-4")
322+
323+
def test_nonDefaultAlpha(self, dvs, testlog):
324+
self.setup_db(dvs)
325+
326+
test_dynamic_th_1 = '1'
327+
expectedProfile_th1 = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen, dynamic_th = test_dynamic_th_1)
328+
test_dynamic_th_2 = '2'
329+
expectedProfile_th2 = self.make_lossless_profile_name(self.originalSpeed, self.originalCableLen, dynamic_th = test_dynamic_th_2)
330+
331+
dvs.runcmd("config buffer profile add non-default-dynamic --dynamic_th {}".format(test_dynamic_th_1))
332+
# add a profile with non-default dynamic_th
333+
dvs.runcmd("config buffer profile add non-default-dynamic --dynamic_th {}".format(test_dynamic_th_1))
334+
335+
# configure lossless PG 3-4 on interface
336+
dvs.runcmd("config interface buffer priority-group lossless add Ethernet0 3-4 non-default-dynamic")
337+
338+
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile_th1)
339+
self.check_new_profile_in_asic_db(dvs, expectedProfile_th1)
340+
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile_th1 + "]"})
341+
342+
# modify the profile to another dynamic_th
343+
dvs.runcmd("config buffer profile set non-default-dynamic --dynamic_th {}".format(test_dynamic_th_2))
344+
345+
self.app_db.wait_for_deleted_entry("BUFFER_PROFILE_TABLE", expectedProfile_th1)
346+
self.app_db.wait_for_entry("BUFFER_PROFILE_TABLE", expectedProfile_th2)
347+
self.check_new_profile_in_asic_db(dvs, expectedProfile_th2)
348+
self.app_db.wait_for_field_match("BUFFER_PG_TABLE", "Ethernet0:3-4", {"profile": "[BUFFER_PROFILE_TABLE:" + expectedProfile_th2 + "]"})
349+
350+
dvs.runcmd("config interface buffer priority-group lossless remove Ethernet0 3-4")
351+
dvs.runcmd("config buffer profile remove non-default-dynamic")

tests/test_buffer_mode.py

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import time
2+
import json
3+
import redis
4+
import pytest
5+
import re
6+
7+
from pprint import pprint
8+
from swsscommon import swsscommon
9+
10+
class TestBufferModel(object):
11+
def test_bufferModel(self, dvs, testlog):
12+
config_db = dvs.get_config_db()
13+
metadata = config_db.get_entry("DEVICE_METADATA", "localhost")
14+
assert metadata["buffer_model"] == "traditional"

0 commit comments

Comments
 (0)