99import socket
1010import subprocess
1111import time
12+ from collections .abc import Generator
1213from concurrent .futures import Future
1314from concurrent .futures import ThreadPoolExecutor
15+ from re import Match
1416
1517import netifaces
1618import paramiko # type: ignore
@@ -273,28 +275,38 @@ def send_brcast_msg_endnode_to_host(endnode: EndnodeSsh, host_brcast_ip: str, te
273275 return nc_host_out
274276
275277
276- @pytest .mark .eth_w5500
277- @pytest .mark .parametrize (
278- 'config' ,
279- [
280- 'w5500' ,
281- ],
282- indirect = True ,
283- )
284- @idf_parametrize ('target' , ['esp32' ], indirect = ['target' ])
285- def test_esp_eth_bridge (dut : Dut , dev_user : str , dev_password : str ) -> None :
286- # ------------------------------ #
287- # Pre-test testbed configuration #
288- # ------------------------------ #
289- # Get switch configuration info from the hostname
278+ def get_legacy_host_name_match () -> Match [str ] | None :
290279 host_name = socket .gethostname ()
291280 regex = r'ethVM-(\d+)-(\d+)'
292- sw_info = re .search (regex , host_name , re .DOTALL )
293- if sw_info is None :
294- raise RuntimeError ('Unexpected hostname' )
281+ host_name_match = re .search (regex , host_name , re .DOTALL )
282+ return host_name_match
295283
296- sw_num = int (sw_info .group (1 ))
297- port_num = int (sw_info .group (2 ))
284+
285+ def get_host_info () -> tuple [int , int ]:
286+ # Get switch configuration info from the hostname (legacy runners)
287+ sw_info = get_legacy_host_name_match ()
288+ if sw_info is not None :
289+ sw_num = int (sw_info .group (1 ))
290+ port_num = int (sw_info .group (2 ))
291+ return sw_num , port_num
292+ else :
293+ # Get switch configuration info from the IP address of the `switch` interface (new runners)
294+ switch_if_ip = get_host_ip_by_interface ('switch' , netifaces .AF_INET )
295+ # Parse IP address: x.y.<sw_num>.<port_num>
296+ ip_parts = switch_if_ip .split ('.' )
297+ if len (ip_parts ) == 4 :
298+ sw_num = int (ip_parts [2 ])
299+ port_num = int (ip_parts [3 ])
300+ return sw_num , port_num
301+ else :
302+ raise RuntimeError ('Unexpected switch IP address' )
303+
304+
305+ def eth_bridge_test (dut : Dut , dev_user : str , dev_password : str ) -> None :
306+ # ------------------------------ #
307+ # Pre-test testbed configuration #
308+ # ------------------------------ #
309+ sw_num , port_num = get_host_info ()
298310 port_num_endnode = int (port_num ) + 1 # endnode address is always + 1 to the host
299311
300312 endnode = EndnodeSsh (f'10.10.{ sw_num } .{ port_num_endnode } ' , ETHVM_ENDNODE_USER )
@@ -330,7 +342,10 @@ def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None:
330342 host_ip = get_host_ip_by_interface (host_if , netifaces .AF_INET )
331343 logging .info ('Host IP %s' , host_ip )
332344
333- endnode_if = host_if # endnode is a clone of the host
345+ if get_legacy_host_name_match () is not None :
346+ endnode_if = host_if # endnode is a clone of the host (legacy runners)
347+ else :
348+ endnode_if = 'dut_p2' # interface name connected to the second port of the DUT (new runners)
334349 # Endnode MAC
335350 endnode_mac = get_endnode_mac_by_interface (endnode , endnode_if )
336351 logging .info ('Endnode MAC %s' , endnode_mac )
@@ -352,12 +367,12 @@ def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None:
352367 # TEST Objective 1: Ping the devices on the network
353368 # --------------------------------------------------
354369 # ping bridge
355- ping_test = subprocess .call (f 'ping { br_ip } -c 2 ' , shell = True )
370+ ping_test = subprocess .call ([ 'ping' , br_ip , '-c ' , '2' ] )
356371 if ping_test != 0 :
357372 raise RuntimeError ('ESP bridge is not reachable' )
358373
359374 # ping the end nodes of the network
360- ping_test = subprocess .call (f 'ping { endnode_ip } -c 2 ' , shell = True )
375+ ping_test = subprocess .call ([ 'ping' , endnode_ip , '-c ' , '2' ] )
361376 if ping_test != 0 :
362377 raise RuntimeError ('End node is not reachable' )
363378
@@ -526,13 +541,13 @@ def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None:
526541 logging .info ('Drop `Endnode` MAC' )
527542 dut .write ('add --addr=' + endnode_mac + ' -d' )
528543 dut .expect_exact ('Bridge Config OK!' )
529- ping_test = subprocess .call (f 'ping { endnode_ip } -c 2 ' , shell = True )
544+ ping_test = subprocess .call ([ 'ping' , endnode_ip , '-c ' , '2' ] )
530545 if ping_test == 0 :
531546 raise RuntimeError ('End node should not be reachable' )
532547 logging .info ('Remove Drop `Endnode` MAC entry' )
533548 dut .write ('remove --addr=' + endnode_mac )
534549 dut .expect_exact ('Bridge Config OK!' )
535- ping_test = subprocess .call (f 'ping { endnode_ip } -c 2 ' , shell = True )
550+ ping_test = subprocess .call ([ 'ping' , endnode_ip , '-c ' , '2' ] )
536551 if ping_test != 0 :
537552 raise RuntimeError ('End node is not reachable' )
538553
@@ -565,9 +580,9 @@ def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None:
565580
566581 # Remove ARP record from Test host computer. ARP is broadcasted, hence Bridge port does not reply to a request since
567582 # it does not receive it (no forward to Bridge port). As a result, Bridge is not pingable.
568- subprocess .call (f 'sudo arp -d { br_ip } ' , shell = True )
569- subprocess .call ('arp -a' , shell = True )
570- ping_test = subprocess .call (f 'ping { br_ip } -c 2 ' , shell = True )
583+ subprocess .call ([ 'sudo' , ' arp' , '-d ' , br_ip ] )
584+ subprocess .call ([ 'arp' , ' -a'] )
585+ ping_test = subprocess .call ([ 'ping' , br_ip , '-c ' , '2' ] )
571586 if ping_test == 0 :
572587 raise RuntimeError ('Bridge should not be reachable' )
573588
@@ -577,7 +592,7 @@ def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None:
577592 dut .expect_exact ('Bridge Config OK!' )
578593 dut .write ('add --addr=ff:ff:ff:ff:ff:ff -p 1 -c' )
579594 dut .expect_exact ('Bridge Config OK!' )
580- ping_test = subprocess .call (f 'ping { br_ip } -c 2 ' , shell = True )
595+ ping_test = subprocess .call ([ 'ping' , br_ip , '-c ' , '2' ] )
581596 if ping_test != 0 :
582597 raise RuntimeError ('Bridge is not reachable' )
583598
@@ -588,3 +603,28 @@ def test_esp_eth_bridge(dut: Dut, dev_user: str, dev_password: str) -> None:
588603
589604 endnode .close ()
590605 switch1 .close ()
606+
607+
608+ @pytest .fixture (scope = 'session' , autouse = True )
609+ def setup_test_environment () -> Generator [None , None , None ]:
610+ # Fixture code to run before any tests in the session
611+ # make sure dut_p2 is down (only for new runners)
612+ if get_legacy_host_name_match () is None :
613+ subprocess .call (['sudo' , 'ip' , 'link' , 'set' , 'down' , 'dev' , 'dut_p2' ])
614+
615+ yield # Tests run here
616+
617+ # Optional teardown after all tests...
618+
619+
620+ @pytest .mark .eth_w5500
621+ @pytest .mark .parametrize (
622+ 'config' ,
623+ [
624+ 'w5500' ,
625+ ],
626+ indirect = True ,
627+ )
628+ @idf_parametrize ('target' , ['esp32' ], indirect = ['target' ])
629+ def test_esp_eth_bridge (dut : Dut , dev_user : str , dev_password : str ) -> None :
630+ eth_bridge_test (dut , dev_user , dev_password )
0 commit comments