1+ import ipaddress
12import logging
3+ import sys
4+ import re
25import pytest
36
7+ from tests .common .helpers .assertions import pytest_assert
48from tests .generic_config_updater .gu_utils import apply_patch , expect_op_success , expect_op_failure
59from tests .generic_config_updater .gu_utils import generate_tmpfile , delete_tmpfile
610from tests .generic_config_updater .gu_utils import create_checkpoint , delete_checkpoint , rollback_or_reload
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
1626pytestmark = [
1727 pytest .mark .topology ('t0' , 'm0' ),
1828]
1929
2030logger = 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
295409def test_vlan_interface_tc2_incremental_change (rand_selected_dut ):
0 commit comments