Skip to content

Commit 2d1e00e

Browse files
authored
[ecnconfig] Fix exception seen during display and add unit tests (#1784) (#1789)
This is to backport #1784 #### How to verify it Ecn tests have passed in the PR build run
1 parent 7041400 commit 2d1e00e

File tree

4 files changed

+880
-17
lines changed

4 files changed

+880
-17
lines changed

scripts/ecnconfig

+18-4
Original file line numberDiff line numberDiff line change
@@ -197,10 +197,11 @@ class EcnQ(object):
197197
"""
198198
Process ecn on/off on queues
199199
"""
200-
def __init__(self, queues, verbose):
200+
def __init__(self, queues, filename, verbose):
201201
self.ports_key = []
202202
self.queues = queues.split(',')
203203
self.validate_queues()
204+
self.filename = filename
204205
self.verbose = verbose
205206

206207
# Set up db connections
@@ -220,14 +221,20 @@ class EcnQ(object):
220221
def gen_ports_key(self):
221222
if self.ports_key is not None:
222223
port_table = self.config_db.get_table(DEVICE_NEIGHBOR_TABLE_NAME)
223-
self.ports_key = port_table.keys()
224+
self.ports_key = list(port_table.keys())
224225

225226
# In multi-ASIC platforms backend ethernet ports are identified as
226227
# 'Ethernet-BPxy'. Add 1024 to sort backend ports to the end.
227228
self.ports_key.sort(
228229
key = lambda k: int(k[8:]) if "BP" not in k else int(k[11:]) + 1024
229230
)
230231

232+
def dump_table_info(self):
233+
if self.filename is not None:
234+
q_table = self.config_db.get_table(QUEUE_TABLE_NAME)
235+
with open(self.filename, "w") as fd:
236+
json.dump({repr(x):y for x, y in q_table.items()}, fd)
237+
231238
def set(self, enable):
232239
chk_exec_privilege()
233240

@@ -237,6 +244,7 @@ class EcnQ(object):
237244
for port_key in self.ports_key:
238245
key = '|'.join([port_key, queue])
239246
self.config_db.mod_entry(QUEUE_TABLE_NAME, key, {FIELD: ON if enable else OFF})
247+
self.dump_table_info()
240248

241249
def get(self):
242250
print("ECN status:")
@@ -254,6 +262,7 @@ class EcnQ(object):
254262
print("%s: on" % (out))
255263
else:
256264
print("%s: off" % (out))
265+
self.dump_table_info()
257266

258267
def main():
259268
parser = argparse.ArgumentParser(description='Show and change:\n'
@@ -355,10 +364,15 @@ def main():
355364
prof_cfg.set_wred_prob(args.profile, "rdrop", args.red_drop_prob)
356365

357366
elif args.queue:
358-
if len(sys.argv) < (4 if args.verbose else 3):
367+
arg_len_min = 3
368+
if args.filename:
369+
arg_len_min += 1
370+
if args.verbose:
371+
arg_len_min += 1
372+
if len(sys.argv) < arg_len_min:
359373
raise Exception("Input arguments error. Specify at least one queue by index")
360374

361-
q_ecn = EcnQ(args.queue, args.verbose)
375+
q_ecn = EcnQ(args.queue, args.filename, args.verbose)
362376
if not args.command:
363377
q_ecn.get()
364378
else:

tests/ecn_input/ecn_test_vectors.py

+105-1
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,22 @@
2424
'rc' : 0,
2525
'rc_output': ecn_show_config_output
2626
},
27+
'ecn_show_config_verbose' : {'cmd' : ['q_cmd'],
28+
'args' : ['-l', '-vv'],
29+
'rc' : 0,
30+
'rc_output': ecn_show_config_output + 'Total profiles: 1\n'
31+
},
2732
'ecn_cfg_gmin' : {'cmd' : ['config'],
2833
'args' : ['-profile', 'AZURE_LOSSLESS', '-gmin', '1048600'],
2934
'rc' : 0,
3035
'cmp_args' : ['AZURE_LOSSLESS,green_min_threshold,1048600']
3136
},
37+
'ecn_cfg_gmin_verbose' : {'cmd' : ['config'],
38+
'args' : ['-profile', 'AZURE_LOSSLESS', '-gmin', '1048600', '-vv'],
39+
'rc' : 0,
40+
'cmp_args' : ['AZURE_LOSSLESS,green_min_threshold,1048600'],
41+
'rc_output' : 'Running command: ecnconfig -p AZURE_LOSSLESS -gmin 1048600 -vv\nSetting green_min_threshold value to 1048600\n'
42+
},
3243
'ecn_cfg_gmax' : {'cmd' : ['config'],
3344
'args' : ['-profile', 'AZURE_LOSSLESS', '-gmax', '2097153'],
3445
'rc' : 0,
@@ -69,6 +80,12 @@
6980
'rc' : 0,
7081
'cmp_args' : ['AZURE_LOSSLESS,green_drop_probability,12']
7182
},
83+
'ecn_cfg_gdrop_verbose' : {'cmd' : ['config'],
84+
'args' : ['-profile', 'AZURE_LOSSLESS', '-gdrop', '12', '-vv'],
85+
'rc' : 0,
86+
'cmp_args' : ['AZURE_LOSSLESS,green_drop_probability,12'],
87+
'rc_output' : 'Running command: ecnconfig -p AZURE_LOSSLESS -gdrop 12 -vv\nSetting green_drop_probability value to 12%\n'
88+
},
7289
'ecn_cfg_multi_set' : {'cmd' : ['config'],
7390
'args' : ['-profile', 'AZURE_LOSSLESS', '-gdrop', '12', '-gmax', '2097153'],
7491
'rc' : 0,
@@ -100,6 +117,93 @@
100117
'args' : ['-profile', 'AZURE_LOSSLESS', '-rdrop', '105'],
101118
'rc' : 1,
102119
'rc_msg' : 'Invalid value for "-rdrop": 105 is not in the valid range of 0 to 100'
120+
},
121+
'ecn_q_get' : {'cmd' : ['q_cmd'],
122+
'args' : ['-q', '3'],
123+
'rc' : 0,
124+
'rc_msg' : 'ECN status:\nqueue 3: on\n',
125+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
126+
'cmp_q_args' : ['3', '4']
127+
},
128+
'ecn_q_get_verbose' : {'cmd' : ['q_cmd'],
129+
'args' : ['-q', '3', '-vv'],
130+
'rc' : 0,
131+
'rc_msg' : 'ECN status:\n{0} queue 3: on\n',
132+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
133+
'cmp_q_args' : ['3', '4'],
134+
'db_table' : 'DEVICE_NEIGHBOR'
135+
},
136+
'ecn_q_all_get_verbose' : {'cmd' : ['q_cmd'],
137+
'args' : ['-q', '3,4', '-vv'],
138+
'rc' : 0,
139+
'rc_msg' : 'ECN status:\n{0} queue 3: on\n{0} queue 4: on\n',
140+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
141+
'cmp_q_args' : ['3', '4'],
142+
'db_table' : 'DEVICE_NEIGHBOR'
143+
},
144+
'ecn_q_all_get' : {'cmd' : ['q_cmd'],
145+
'args' : ['-q', '3,4'],
146+
'rc' : 0,
147+
'rc_msg' : 'ECN status:\nqueue 3: on\nqueue 4: on\n',
148+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
149+
'cmp_q_args' : ['3', '4']
150+
},
151+
'ecn_cfg_q_all_off' : {'cmd' : ['q_cmd'],
152+
'args' : ['-q', '3,4', 'off'],
153+
'rc' : 0,
154+
'cmp_args' : ['wred_profile,[]'],
155+
'cmp_q_args' : ['3', '4']
156+
},
157+
'ecn_cfg_q_all_off_verbose' : {'cmd' : ['q_cmd'],
158+
'args' : ['-q', '3,4', 'off', '-vv'],
159+
'rc' : 0,
160+
'cmp_args' : ['wred_profile,[]'],
161+
'cmp_q_args' : ['3', '4'],
162+
'db_table' : 'DEVICE_NEIGHBOR',
163+
'rc_msg' : 'Disable ECN on {0} queue 3\nDisable ECN on {0} queue 4'
164+
},
165+
'ecn_cfg_q_off' : {'cmd' : ['q_cmd'],
166+
'args' : ['-q', '3', 'off'],
167+
'rc' : 0,
168+
'cmp_args' : ['wred_profile,[]', 'wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
169+
'cmp_q_args' : ['3'],
170+
'other_q' : ['4']
171+
},
172+
'ecn_cfg_q_off_verbose' : {'cmd' : ['q_cmd'],
173+
'args' : ['-q', '3', 'off', '-vv'],
174+
'rc' : 0,
175+
'cmp_args' : ['wred_profile,[]', 'wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
176+
'cmp_q_args' : ['3'],
177+
'other_q' : ['4'],
178+
'db_table' : 'DEVICE_NEIGHBOR',
179+
'rc_msg' : 'Disable ECN on {0} queue 3'
180+
},
181+
'ecn_cfg_q_all_on' : {'cmd' : ['q_cmd'],
182+
'args' : ['-q', '3,4', 'on'],
183+
'rc' : 0,
184+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
185+
'cmp_q_args' : ['3', '4']
186+
},
187+
'ecn_cfg_q_all_on_verbose' : {'cmd' : ['q_cmd'],
188+
'args' : ['-q', '3,4', 'on', '-vv'],
189+
'rc' : 0,
190+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
191+
'cmp_q_args' : ['3', '4'],
192+
'db_table' : 'DEVICE_NEIGHBOR',
193+
'rc_msg' : 'Enable ECN on {0} queue 3\nEnable ECN on {0} queue 4'
194+
},
195+
'ecn_cfg_q_on' : {'cmd' : ['q_cmd'],
196+
'args' : ['-q', '4', 'on'],
197+
'rc' : 0,
198+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
199+
'cmp_q_args' : ['3', '4']
200+
},
201+
'ecn_cfg_q_on_verbose' : {'cmd' : ['q_cmd'],
202+
'args' : ['-q', '4', 'on', '-vv'],
203+
'rc' : 0,
204+
'cmp_args' : ['wred_profile,[WRED_PROFILE|AZURE_LOSSLESS]'],
205+
'cmp_q_args' : ['3', '4'],
206+
'db_table' : 'DEVICE_NEIGHBOR',
207+
'rc_msg' : 'Enable ECN on {0} queue 4'
103208
}
104-
105209
}

tests/ecn_test.py

+82-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import ast
12
import json
23
import os
34
import sys
@@ -6,6 +7,8 @@
67

78
import config.main as config
89
from .ecn_input.ecn_test_vectors import *
10+
from .utils import get_result_and_return_code
11+
from utilities_common.db import Db
912
import show.main as show
1013

1114
test_path = os.path.dirname(os.path.abspath(__file__))
@@ -25,9 +28,15 @@ def setup_class(cls):
2528
def test_ecn_show_config(self):
2629
self.executor(testData['ecn_show_config'])
2730

31+
def test_ecn_show_config_verbose(self):
32+
self.executor(testData['ecn_show_config_verbose'])
33+
2834
def test_ecn_config_gmin(self):
2935
self.executor(testData['ecn_cfg_gmin'])
3036

37+
def test_ecn_config_gmin_verbose(self):
38+
self.executor(testData['ecn_cfg_gmin_verbose'])
39+
3140
def test_ecn_config_gmax(self):
3241
self.executor(testData['ecn_cfg_gmax'])
3342

@@ -46,6 +55,9 @@ def test_ecn_config_rmax(self):
4655
def test_ecn_config_gdrop(self):
4756
self.executor(testData['ecn_cfg_gdrop'])
4857

58+
def test_ecn_config_gdrop_verbose(self):
59+
self.executor(testData['ecn_cfg_gdrop_verbose'])
60+
4961
def test_ecn_config_ydrop(self):
5062
self.executor(testData['ecn_cfg_ydrop'])
5163

@@ -70,37 +82,95 @@ def test_ecn_config_rmax_invalid(self):
7082
def test_ecn_config_rdrop_invalid(self):
7183
self.executor(testData['ecn_cfg_rdrop_invalid'])
7284

85+
def test_ecn_queue_get(self):
86+
self.executor(testData['ecn_q_get'])
87+
88+
def test_ecn_queue_get_verbose(self):
89+
self.executor(testData['ecn_q_get_verbose'])
90+
91+
def test_ecn_all_queue_get(self):
92+
self.executor(testData['ecn_q_all_get'])
93+
94+
def test_ecn_queue_all_get_verbose(self):
95+
self.executor(testData['ecn_q_all_get_verbose'])
96+
97+
def test_ecn_queue_set_q_off(self):
98+
self.executor(testData['ecn_cfg_q_off'])
99+
100+
def test_ecn_queue_set_q_off_verbose(self):
101+
self.executor(testData['ecn_cfg_q_off_verbose'])
102+
103+
def test_ecn_queue_set_all_off(self):
104+
self.executor(testData['ecn_cfg_q_all_off'])
105+
106+
def test_ecn_queue_set_all_off_verbose(self):
107+
self.executor(testData['ecn_cfg_q_all_off_verbose'])
108+
109+
def test_ecn_queue_set_q_on(self):
110+
self.executor(testData['ecn_cfg_q_on'])
111+
112+
def test_ecn_queue_set_q_on_verbose(self):
113+
self.executor(testData['ecn_cfg_q_on_verbose'])
114+
115+
def test_ecn_queue_set_all_on(self):
116+
self.executor(testData['ecn_cfg_q_all_on'])
117+
118+
def test_ecn_queue_set_all_on_verbose(self):
119+
self.executor(testData['ecn_cfg_q_all_on_verbose'])
120+
73121
def executor(self, input):
74122
runner = CliRunner()
75123

124+
if 'db_table' in input:
125+
db = Db()
126+
data_list = list(db.cfgdb.get_table(input['db_table']))
127+
input['rc_msg'] = input['rc_msg'].format(",".join(data_list))
128+
76129
if 'show' in input['cmd']:
77130
exec_cmd = show.cli.commands["ecn"]
131+
result = runner.invoke(exec_cmd, input['args'])
132+
exit_code = result.exit_code
133+
output = result.output
134+
elif 'q_cmd' in input['cmd'] :
135+
exit_code, output = get_result_and_return_code("ecnconfig {}".format(" ".join(input['args'])))
78136
else:
79137
exec_cmd = config.config.commands["ecn"]
138+
result = runner.invoke(exec_cmd, input['args'])
139+
exit_code = result.exit_code
140+
output = result.output
80141

81-
result = runner.invoke(exec_cmd, input['args'])
82-
83-
print(result.exit_code)
84-
print(result.output)
142+
print(exit_code)
143+
print(output)
85144

86145
if input['rc'] == 0:
87-
assert result.exit_code == 0
146+
assert exit_code == 0
88147
else:
89-
assert result.exit_code != 0
148+
assert exit_code != 0
90149

91150
if 'cmp_args' in input:
92151
fd = open('/tmp/ecnconfig', 'r')
93-
prof_data = json.load(fd)
94-
for args in input['cmp_args']:
95-
profile, name, value = args.split(',')
96-
assert(prof_data[profile][name] == value)
152+
cmp_data = json.load(fd)
153+
154+
if 'cmp_q_args' in input:
155+
if 'other_q' in input:
156+
profile1, value1 = input['cmp_args'][-1].split(',')
157+
profile, value = input['cmp_args'][0].split(',')
158+
for key in cmp_data:
159+
if ast.literal_eval(key)[-1] in input['cmp_q_args']:
160+
assert(cmp_data[key][profile] == value)
161+
if 'other_q' in input and ast.literal_eval(key)[-1] in input['other_q']:
162+
assert(cmp_data[key][profile1] == value1)
163+
else:
164+
for args in input['cmp_args']:
165+
profile, name, value = args.split(',')
166+
assert(cmp_data[profile][name] == value)
97167
fd.close()
98168

99169
if 'rc_msg' in input:
100-
assert input['rc_msg'] in result.output
170+
assert input['rc_msg'] in output
101171

102172
if 'rc_output' in input:
103-
assert result.output == input['rc_output']
173+
assert output == input['rc_output']
104174

105175
@classmethod
106176
def teardown_class(cls):

0 commit comments

Comments
 (0)