Skip to content

Commit c4a62f4

Browse files
authored
[gcu] Refactor generic_config_updater/test_vlan_interface.py (#6496)
What is the motivation for this PR? Fix this case failed in M0 topo caused by hard codes about vlan ip. How did you do it? Get vlan ip based on current topo config. How did you verify/test it? Run test.
1 parent 9701ac3 commit c4a62f4

1 file changed

Lines changed: 151 additions & 37 deletions

File tree

tests/generic_config_updater/test_vlan_interface.py

Lines changed: 151 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
import ipaddress
12
import logging
3+
import sys
4+
import re
25
import pytest
36

7+
from tests.common.helpers.assertions import pytest_assert
48
from tests.generic_config_updater.gu_utils import apply_patch, expect_op_success, expect_op_failure
59
from tests.generic_config_updater.gu_utils import generate_tmpfile, delete_tmpfile
610
from tests.generic_config_updater.gu_utils import create_checkpoint, delete_checkpoint, rollback_or_reload
@@ -12,16 +16,83 @@
1216
# "Vlan1000|192.168.0.1/21": {},
1317
# "Vlan1000|fc02:1000::1/64": {}
1418
# }
19+
# Test on m0 topo to verify functionality and to choose predefined variable
20+
# "VLAN_INTERFACE": {
21+
# "Vlan1000": {},
22+
# "Vlan1000|192.168.0.1/24": {},
23+
# "Vlan1000|fc02:1000::1/64": {}
24+
# }
1525

1626
pytestmark = [
1727
pytest.mark.topology('t0', 'm0'),
1828
]
1929

2030
logger = logging.getLogger(__name__)
2131

32+
if sys.version_info.major == 3:
33+
UNICODE_TYPE = str
34+
else:
35+
UNICODE_TYPE = unicode
36+
37+
38+
def get_vlan_info(intf):
39+
"""
40+
Sample output
41+
{
42+
"name": "Vlan1000",
43+
"prefix": "192.168.0.1/24"
44+
}
45+
"""
46+
info = {
47+
"name": intf["attachto"],
48+
"prefix": "{}/{}".format(intf["addr"], intf["prefixlen"])
49+
}
50+
return info
51+
52+
53+
@pytest.fixture()
54+
def vlan_info(duthost, tbinfo):
55+
"""
56+
Fixture of getting ipv4/ipv6 vlan info
57+
Args:
58+
duthost: DUT host
59+
tbinfo: fixture provides information about testbed
60+
Return:
61+
Name and prefix of ipv4/ipv6 vlans
62+
Sample output
63+
{
64+
"v4": {
65+
"name": "Vlan1000",
66+
"prefix": "192.168.0.1/24"
67+
},
68+
"v6": {
69+
"name": "Vlan1000",
70+
"prefix": "fc02:1000::1/64"
71+
}
72+
}
73+
"""
74+
mg_facts = duthost.get_extended_minigraph_facts(tbinfo)
75+
vlan_intf = mg_facts['minigraph_vlan_interfaces']
76+
vlan_v4_info = None
77+
vlan_v6_info = None
78+
for intf in vlan_intf:
79+
if vlan_v4_info is None and ipaddress.ip_address(intf["addr"]).version == 4:
80+
vlan_v4_info = get_vlan_info(intf)
81+
82+
if vlan_v6_info is None and ipaddress.ip_address(intf["addr"]).version == 6:
83+
vlan_v6_info = get_vlan_info(intf)
84+
85+
pytest_assert(vlan_v4_info is not None, "Not ipv4 vlan")
86+
pytest_assert(vlan_v6_info is not None, "Not ipv6 vlan")
87+
88+
yield {
89+
"v4": vlan_v4_info,
90+
"v6": vlan_v6_info
91+
}
92+
2293

2394
@pytest.fixture(autouse=True)
24-
def cleanup_test_env(duthosts, rand_one_dut_hostname):
95+
def cleanup_test_env(duthosts, rand_one_dut_hostname, vlan_info):
2596
"""
2697
Setup/teardown fixture for VLAN interface config
2798
Args:
@@ -36,15 +107,15 @@ def cleanup_test_env(duthosts, rand_one_dut_hostname):
36107
try:
37108
logger.info("Rolled back to original checkpoint")
38109
rollback_or_reload(duthost)
39-
check_show_ip_intf(duthost, "Vlan1000", ["192.168.0.1/21"],
110+
check_show_ip_intf(duthost, vlan_info["v4"]["name"], [vlan_info["v4"]["prefix"]],
40111
[], is_ipv4=True)
41-
check_show_ip_intf(duthost, "Vlan1000", ["fc02:1000::1/64"],
112+
check_show_ip_intf(duthost, vlan_info["v6"]["name"], [vlan_info["v6"]["prefix"]],
42113
[], is_ipv4=False)
43114
finally:
44115
delete_checkpoint(duthost)
45116

46117

47-
def vlan_interface_tc1_add_duplicate(duthost):
118+
def vlan_interface_tc1_add_duplicate(duthost, vlan_info):
48119
""" Add duplicate v4 and v6 lo intf to config
49120
50121
Sample output
@@ -58,13 +129,13 @@ def vlan_interface_tc1_add_duplicate(duthost):
58129
{
59130
"op": "add",
60131
"path": create_path(["VLAN_INTERFACE",
61-
"Vlan1000|192.168.0.1/21"]),
132+
"{}|{}".format(vlan_info["v4"]["name"], vlan_info["v4"]["prefix"])]),
62133
"value": {}
63134
},
64135
{
65136
"op": "add",
66137
"path": create_path(["VLAN_INTERFACE",
67-
"Vlan1000|fc02:1000::1/64"]),
138+
"{}|{}".format(vlan_info["v6"]["name"], vlan_info["v6"]["prefix"])]),
68139
"value": {}
69140
}
70141
]
@@ -78,27 +149,62 @@ def vlan_interface_tc1_add_duplicate(duthost):
78149
output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile)
79150
expect_op_success(duthost, output)
80151

81-
check_show_ip_intf(duthost, "Vlan1000", ["192.168.0.1/21"],
152+
check_show_ip_intf(duthost, vlan_info["v4"]["name"], [vlan_info["v4"]["prefix"]],
82153
[], is_ipv4=True)
83-
check_show_ip_intf(duthost, "Vlan1000", ["fc02:1000::1/64"],
154+
check_show_ip_intf(duthost, vlan_info["v6"]["name"], [vlan_info["v6"]["prefix"]],
84155
[], is_ipv4=False)
85156
finally:
86157
delete_tmpfile(duthost, tmpfile)
87158

88159

89-
def vlan_interface_tc1_xfail(duthost):
90-
""" Test expect fail testcase
160+
def reg_replace(str, reg, replace_str):
161+
"""
162+
Replace str by regex
163+
"""
164+
regex = re.compile(reg)
165+
return regex.sub(replace_str, str)
91166

92-
("add", "Vlan1000", "587.168.0.1/21", "fc02:1000::1/64"), ADD Invalid IPv4 address
93-
("add", "Vlan1000", "192.168.0.1/21", "fc02:1000::xyz/64"), ADD Invalid IPv6 address
94-
("remove", "Vlan1000", "192.168.0.2/21", "fc02:1000::1/64"), REMOVE Unexist IPv4 address
95-
("remove", "Vlan1000", "192.168.0.1/21", "fc02:1000::2/64") REMOVE Unexist IPv6 address
167+
168+
def vlan_interface_tc1_xfail(duthost, vlan_info):
96169
"""
170+
Get invalid IPv4/IPv6 address and unexist IPv4/IPv6 address by vlan_info and then add/remove them.
171+
172+
For example:
173+
vlan_info = {
174+
"v4": {
175+
"name": "Vlan1000",
176+
"prefix": "192.168.0.1/24"
177+
},
178+
"v6": {
179+
"name": "Vlan1000",
180+
"prefix": "fc02:1000::1/64"
181+
}
182+
}
183+
184+
then we can get:
185+
invalid_ipv4_address = "587.168.0.1/24" (Replace "192" with "587" in "192.168.0.1/24")
186+
invalid_ipv6_address = "fc02:1000::xyz/64" (Replace last "1" with "xyz" in "fc02:1000::1/64")
187+
unexist_ipv4_address = "192.168.0.2/24" (Next ip address behind 192.168.0.1/24)
188+
unexist_ipv6_address = "fc02:1000::2/64" (Next ip address behind fc02:1000::1/64)
189+
190+
and then construct xfail_input:
191+
xfail_input = [
192+
("add", "Vlan1000", "587.168.0.1/24", "fc02:1000::1/64"), # Add invalid IPv4 address
193+
("add", "Vlan1000", "192.168.0.1/24", "fc02:1000::xyz/64"), # Add invalid IPv6 address
194+
("remove", "Vlan1000", "192.168.0.2/24", "fc02:1000::1/64"), # Remove unexist IPv4 address
195+
("remove", "Vlan1000", "192.168.0.1/24", "fc02:1000::2/64") # Remove unexist IPv6 address
196+
]
197+
"""
198+
invalid_ipv4_address = reg_replace(vlan_info["v4"]["prefix"], r"^\d*", "587")
199+
invalid_ipv6_address = reg_replace(vlan_info["v6"]["prefix"], r":\d*/", ":xyz/")
200+
unexist_ipv4_address = ipaddr_plus(vlan_info["v4"]["prefix"])
201+
unexist_ipv6_address = ipaddr_plus(vlan_info["v6"]["prefix"])
202+
97203
xfail_input = [
98-
("add", "Vlan1000", "587.168.0.1/21", "fc02:1000::1/64"),
99-
("add", "Vlan1000", "192.168.0.1/21", "fc02:1000::xyz/64"),
100-
("remove", "Vlan1000", "192.168.0.2/21", "fc02:1000::1/64"),
101-
("remove", "Vlan1000", "192.168.0.1/21", "fc02:1000::2/64")
204+
("add", vlan_info["v4"]["name"], invalid_ipv4_address, vlan_info["v6"]["prefix"]),
205+
("add", vlan_info["v4"]["name"], vlan_info["v4"]["prefix"], invalid_ipv6_address),
206+
("remove", vlan_info["v4"]["name"], unexist_ipv4_address, vlan_info["v6"]["prefix"]),
207+
("remove", vlan_info["v4"]["name"], vlan_info["v4"]["prefix"], unexist_ipv6_address)
102208
]
103209
for op, name, ip, ipv6 in xfail_input:
104210
dummy_vlan_interface_v4 = name + "|" + ip
@@ -205,7 +311,15 @@ def vlan_interface_tc1_add_new(duthost):
205311
delete_tmpfile(duthost, tmpfile)
206312

207313

208-
def vlan_interface_tc1_replace(duthost):
314+
def ipaddr_plus(ipaddr):
315+
"""
316+
Get next ip address of ipaddr
317+
"""
318+
splits = ipaddr.split("/")
319+
return "{}/{}".format(ipaddress.ip_address(UNICODE_TYPE(splits[0])) + 1, splits[1])
320+
321+
322+
def vlan_interface_tc1_replace(duthost, vlan_info):
209323
""" Test replace testcase
210324
211325
Expected output
@@ -219,23 +333,23 @@ def vlan_interface_tc1_replace(duthost):
219333
{
220334
"op": "remove",
221335
"path": create_path(["VLAN_INTERFACE",
222-
"Vlan1000|fc02:1000::1/64"]),
336+
"{}|{}".format(vlan_info["v6"]["name"], vlan_info["v6"]["prefix"])]),
223337
},
224338
{
225339
"op": "remove",
226340
"path": create_path(["VLAN_INTERFACE",
227-
"Vlan1000|192.168.0.1/21"]),
341+
"{}|{}".format(vlan_info["v4"]["name"], vlan_info["v4"]["prefix"])]),
228342
},
229343
{
230344
"op": "add",
231345
"path": create_path(["VLAN_INTERFACE",
232-
"Vlan1000|192.168.0.2/21"]),
346+
"{}|{}".format(vlan_info["v4"]["name"], ipaddr_plus(vlan_info["v4"]["prefix"]))]),
233347
"value": {}
234348
},
235349
{
236350
"op": "add",
237351
"path": create_path(["VLAN_INTERFACE",
238-
"Vlan1000|fc02:1000::2/64"]),
352+
"{}|{}".format(vlan_info["v6"]["name"], ipaddr_plus(vlan_info["v6"]["prefix"]))]),
239353
"value": {}
240354
}
241355
]
@@ -247,15 +361,15 @@ def vlan_interface_tc1_replace(duthost):
247361
output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile)
248362
expect_op_success(duthost, output)
249363

250-
check_show_ip_intf(duthost, "Vlan1000", ["192.168.0.2/21"],
251-
["192.168.0.1/21"], is_ipv4=True)
252-
check_show_ip_intf(duthost, "Vlan1000", ["fc02:1000::2/64"],
253-
["fc02:1000::1/64"], is_ipv4=False)
364+
check_show_ip_intf(duthost, vlan_info["v4"]["name"], [ipaddr_plus(vlan_info["v4"]["prefix"])],
365+
[], is_ipv4=True)
366+
check_show_ip_intf(duthost, vlan_info["v6"]["name"], [ipaddr_plus(vlan_info["v6"]["prefix"])],
367+
[], is_ipv4=False)
254368
finally:
255369
delete_tmpfile(duthost, tmpfile)
256370

257371

258-
def vlan_interface_tc1_remove(duthost):
372+
def vlan_interface_tc1_remove(duthost, vlan_info):
259373
""" Remove all VLAN intf
260374
"""
261375
json_patch = [
@@ -272,10 +386,10 @@ def vlan_interface_tc1_remove(duthost):
272386
output = apply_patch(duthost, json_data=json_patch, dest_file=tmpfile)
273387
expect_op_success(duthost, output)
274388

275-
check_show_ip_intf(duthost, "Vlan1000", [],
276-
["192.168.0.2/21", ], is_ipv4=True)
277-
check_show_ip_intf(duthost, "Vlan1000", [],
278-
["fc02:1000::2/64"], is_ipv4=False)
389+
check_show_ip_intf(duthost, vlan_info["v4"]["name"], [],
390+
[ipaddr_plus(vlan_info["v4"]["prefix"])], is_ipv4=True)
391+
check_show_ip_intf(duthost, vlan_info["v6"]["name"], [],
392+
[ipaddr_plus(vlan_info["v6"]["prefix"])], is_ipv4=False)
279393
check_show_ip_intf(duthost, "Vlan2000", [],
280394
["192.168.8.1/21"], is_ipv4=True)
281395
check_show_ip_intf(duthost, "Vlan2000", [],
@@ -284,12 +398,12 @@ def vlan_interface_tc1_remove(duthost):
284398
delete_tmpfile(duthost, tmpfile)
285399

286400

287-
def test_vlan_interface_tc1_suite(rand_selected_dut):
288-
vlan_interface_tc1_add_duplicate(rand_selected_dut)
289-
vlan_interface_tc1_xfail(rand_selected_dut)
401+
def test_vlan_interface_tc1_suite(rand_selected_dut, vlan_info):
402+
vlan_interface_tc1_add_duplicate(rand_selected_dut, vlan_info)
403+
vlan_interface_tc1_xfail(rand_selected_dut, vlan_info)
290404
vlan_interface_tc1_add_new(rand_selected_dut)
291-
vlan_interface_tc1_replace(rand_selected_dut)
292-
vlan_interface_tc1_remove(rand_selected_dut)
405+
vlan_interface_tc1_replace(rand_selected_dut, vlan_info)
406+
vlan_interface_tc1_remove(rand_selected_dut, vlan_info)
293407

294408

295409
def test_vlan_interface_tc2_incremental_change(rand_selected_dut):

0 commit comments

Comments
 (0)