diff --git a/test/case/containers/internal_link/test.py b/test/case/containers/internal_link/test.py index 24ea7e1f1..21a119995 100755 --- a/test/case/containers/internal_link/test.py +++ b/test/case/containers/internal_link/test.py @@ -19,7 +19,7 @@ """ import infamy -from infamy.util import until +from infamy.util import parallel, until # Regression test for #941: previously, when both ends of a pair were # assigned to a container, neither side created the pair. @@ -30,8 +30,8 @@ with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) if not target.has_model("infix-containers"): test.skip() diff --git a/test/case/containers/upgrade/test.py b/test/case/containers/upgrade/test.py index 5e13ba982..a5b72354a 100755 --- a/test/case/containers/upgrade/test.py +++ b/test/case/containers/upgrade/test.py @@ -14,7 +14,7 @@ import time import infamy import infamy.file_server as srv -from infamy.util import until +from infamy.util import parallel, until SRVPORT = 8008 SRVDIR = "/srv" @@ -24,8 +24,8 @@ with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) if not target.has_model("infix-containers"): test.skip() diff --git a/test/case/containers/volume/test.py b/test/case/containers/volume/test.py index b4c752f2e..599713177 100755 --- a/test/case/containers/volume/test.py +++ b/test/case/containers/volume/test.py @@ -7,7 +7,7 @@ """ import infamy -from infamy.util import until, curl +from infamy.util import curl, parallel, until with infamy.Test() as test: NAME = "web-volume" @@ -16,8 +16,8 @@ with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) addr = target.get_mgmt_ip() URL = f"http://[{addr}]:{PORT}/index.html" diff --git a/test/case/dhcp/client6_basic/test.py b/test/case/dhcp/client6_basic/test.py index e06b011f1..45818bf0a 100755 --- a/test/case/dhcp/client6_basic/test.py +++ b/test/case/dhcp/client6_basic/test.py @@ -7,6 +7,7 @@ """ import infamy +from infamy.util import parallel import infamy.dhcp import infamy.iface as iface import infamy.route as route @@ -33,8 +34,8 @@ def check_dns_resolution(): with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - client = env.attach("client", "mgmt") - tgtssh = env.attach("client", "mgmt", "ssh") + client, tgtssh = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("client", "mgmt", "ssh")) _, host = env.ltop.xlate("host", "data") _, port = env.ltop.xlate("client", "data") diff --git a/test/case/dhcp/client6_prefix_delegation/test.py b/test/case/dhcp/client6_prefix_delegation/test.py index 3eb1d23d9..c89cb287e 100755 --- a/test/case/dhcp/client6_prefix_delegation/test.py +++ b/test/case/dhcp/client6_prefix_delegation/test.py @@ -9,7 +9,7 @@ import infamy, infamy.dhcp import infamy.iface as iface -from infamy.util import until +from infamy.util import parallel, until import time @@ -38,8 +38,8 @@ def checklog(dut): with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - client = env.attach("client", "mgmt") - tgtssh = env.attach("client", "mgmt", "ssh") + client, tgtssh = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("client", "mgmt", "ssh")) _, host = env.ltop.xlate("host", "data") _, port = env.ltop.xlate("client", "data") diff --git a/test/case/dhcp/client6_slaac_ra/test.py b/test/case/dhcp/client6_slaac_ra/test.py index 09385d8a1..c90ffddcf 100755 --- a/test/case/dhcp/client6_slaac_ra/test.py +++ b/test/case/dhcp/client6_slaac_ra/test.py @@ -17,7 +17,7 @@ import infamy import infamy.dhcp import infamy.iface as iface -from infamy.util import until +from infamy.util import parallel, until def checkrun(dut): @@ -47,8 +47,8 @@ def check_slaac_address(): with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - client = env.attach("client", "mgmt") - tgtssh = env.attach("client", "mgmt", "ssh") + client, tgtssh = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("client", "mgmt", "ssh")) _, host = env.ltop.xlate("host", "data") _, port = env.ltop.xlate("client", "data") diff --git a/test/case/dhcp/client_hostname_resend/test.py b/test/case/dhcp/client_hostname_resend/test.py index dceb89cc2..bd346d83b 100755 --- a/test/case/dhcp/client_hostname_resend/test.py +++ b/test/case/dhcp/client_hostname_resend/test.py @@ -13,7 +13,7 @@ """ import infamy -from infamy.util import until +from infamy.util import parallel, until def udhcpc_cmdline(ssh, ifname): @@ -40,8 +40,8 @@ def running_hostname(ssh, ifname): with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - client = env.attach("client", "mgmt") - clissh = env.attach("client", "mgmt", "ssh") + client, clissh = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("client", "mgmt", "ssh")) _, port = env.ltop.xlate("client", "mgmt") with test.step(f"Configure initial hostname '{HOSTNM_A}'"): diff --git a/test/case/dhcp/server_basic/test.py b/test/case/dhcp/server_basic/test.py index 094f9c86d..b9d1d66ff 100755 --- a/test/case/dhcp/server_basic/test.py +++ b/test/case/dhcp/server_basic/test.py @@ -11,7 +11,7 @@ import infamy import infamy.iface as iface import infamy.route as route -from infamy.util import until +from infamy.util import parallel, until def verify_hostname(dut, hostname): @@ -30,47 +30,48 @@ def verify_hostname(dut, hostname): HOSTNM2 = 'client' with test.step("Set up topology and attach to client and server DUTs"): env = infamy.Env() - client = env.attach("client", "mgmt") - server = env.attach("server", "mgmt") + client, server = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("server", "mgmt")) with test.step("Configure DHCP server and client's hostname"): - server.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": server["link"], - "ipv4": { - "address": [{ - "ip": "192.168.2.1", - "prefix-length": 24 - }] - } - }] - } - }, - "infix-dhcp-server": { - "dhcp-server": { - "subnet": [{ - "subnet": "192.168.2.0/24", - "option": [{ - "id": "hostname", - "name": HOSTNM2 - }], - "pool": { - "start-address": ADDRESS, - "end-address": ADDRESS, - } - }] - } - }, - "ietf-system": { - "system": {"hostname": "server.example.com"} - }}) - - client.put_config_dicts({ - "ietf-system": { - "system": {"hostname": HOSTNM1} - }}) + parallel( + lambda: server.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": server["link"], + "ipv4": { + "address": [{ + "ip": "192.168.2.1", + "prefix-length": 24 + }] + } + }] + } + }, + "infix-dhcp-server": { + "dhcp-server": { + "subnet": [{ + "subnet": "192.168.2.0/24", + "option": [{ + "id": "hostname", + "name": HOSTNM2 + }], + "pool": { + "start-address": ADDRESS, + "end-address": ADDRESS, + } + }] + } + }, + "ietf-system": { + "system": {"hostname": "server.example.com"} + }}), + lambda: client.put_config_dicts({ + "ietf-system": { + "system": {"hostname": HOSTNM1} + }}), + ) with test.step("Verify DHCP client's original hostname"): until(lambda: verify_hostname(client, HOSTNM1)) diff --git a/test/case/dhcp/server_host/test.py b/test/case/dhcp/server_host/test.py index 03187716a..73b6c8124 100755 --- a/test/case/dhcp/server_host/test.py +++ b/test/case/dhcp/server_host/test.py @@ -9,7 +9,7 @@ import infamy import infamy.iface as iface import infamy.route as route -from infamy.util import until +from infamy.util import parallel, until with infamy.Test() as test: @@ -28,134 +28,134 @@ with test.step("Set up topology and attach to client and server DUTs"): env = infamy.Env() - server = env.attach("server", "mgmt") - client1 = env.attach("client1", "mgmt") - client2 = env.attach("client2", "mgmt") + server, client1, client2 = parallel(lambda: env.attach("server", "mgmt"), + lambda: env.attach("client1", "mgmt"), + lambda: env.attach("client2", "mgmt")) with test.step("Configure DHCP client and server DUTs"): - server.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": server["link1"], - "ipv4": { - "address": [{ - "ip": "192.168.1.1", - "prefix-length": 24 - }] - } - }, { - "name": server["link2"], - "ipv4": { - "address": [{ - "ip": "192.168.2.1", - "prefix-length": 24 - }] - } - }, - ] - } - }, - "infix-dhcp-server": { - "dhcp-server": { - "option": [{ - "id": "router", "address": "auto" - }], - "subnet": [ - { - "subnet": "192.168.1.0/24", - "pool": { - "start-address": POOL1, - "end-address": POOL1 + parallel( + lambda: server.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": server["link1"], + "ipv4": { + "address": [{ + "ip": "192.168.1.1", + "prefix-length": 24 + }] + } + }, { + "name": server["link2"], + "ipv4": { + "address": [{ + "ip": "192.168.2.1", + "prefix-length": 24 + }] + } }, - "host": [{ - "address": ADDRESS1, - "match": { - "client-id": {"hex": HOSTCID1} + ] + } + }, + "infix-dhcp-server": { + "dhcp-server": { + "option": [{ + "id": "router", "address": "auto" + }], + "subnet": [ + { + "subnet": "192.168.1.0/24", + "pool": { + "start-address": POOL1, + "end-address": POOL1 }, - "option": [ - { - "id": "hostname", - "name": HOSTNM11 - }, { - "id": "classless-static-route", - "static-route": [{ - "destination": "0.0.0.0/0", - "next-hop": GW1 - }] - } - ] - }] - }, { - "subnet": "192.168.2.0/24", - "pool": { - "start-address": POOL2, - "end-address": POOL2 - }, - "host": [{ - "address": ADDRESS2, - "match": { - "client-id": {"str": HOSTCID2} + "host": [{ + "address": ADDRESS1, + "match": { + "client-id": {"hex": HOSTCID1} + }, + "option": [ + { + "id": "hostname", + "name": HOSTNM11 + }, { + "id": "classless-static-route", + "static-route": [{ + "destination": "0.0.0.0/0", + "next-hop": GW1 + }] + } + ] + }] + }, { + "subnet": "192.168.2.0/24", + "pool": { + "start-address": POOL2, + "end-address": POOL2 }, - "option": [ - { - "id": "hostname", - "name": HOSTNM22 - } - ], - "lease-time": "infinite" - }] - }, - ] - } - }}) - - # We request hostname option just to ensure we don't get it. - client1.put_config_dicts({ - "ietf-system": { - "system": {"hostname": HOSTNM1} - }, - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client1["link"], - "ipv4": { - "infix-dhcp-client:dhcp": { - "option": [ - {"id": "router"}, - {"id": "client-id", "hex": HOSTCID1}, - {"id": 121} - ] + "host": [{ + "address": ADDRESS2, + "match": { + "client-id": {"str": HOSTCID2} + }, + "option": [ + { + "id": "hostname", + "name": HOSTNM22 + } + ], + "lease-time": "infinite" + }] + }, + ] + } + }}), + # We request hostname option just to ensure we don't get it. + lambda: client1.put_config_dicts({ + "ietf-system": { + "system": {"hostname": HOSTNM1} + }, + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client1["link"], + "ipv4": { + "infix-dhcp-client:dhcp": { + "option": [ + {"id": "router"}, + {"id": "client-id", "hex": HOSTCID1}, + {"id": 121} + ] + } } - } - }] - } - }, - }) - - client2.put_config_dicts({ - "ietf-system": { - "system": {"hostname": HOSTNM2} - }, - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client2["link"], - "ipv4": { - "infix-dhcp-client:dhcp": { - "client-id": HOSTCID2, - "option": [ - {"id": "router"}, - {"id": "hostname"}, - {"id": 121} - ] + }] + } + }, + }), + lambda: client2.put_config_dicts({ + "ietf-system": { + "system": {"hostname": HOSTNM2} + }, + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client2["link"], + "ipv4": { + "infix-dhcp-client:dhcp": { + "client-id": HOSTCID2, + "option": [ + {"id": "router"}, + {"id": "hostname"}, + {"id": 121} + ] + } } - } - }] - } - }, - }) + }] + } + }, + }), + ) with test.step("Verify DHCP client1 static lease"): until(lambda: iface.address_exist(client1, client1["link"], ADDRESS1)) diff --git a/test/case/dhcp/server_subnets/test.adoc b/test/case/dhcp/server_subnets/test.adoc index 6075f4c6f..3af5d0a47 100644 --- a/test/case/dhcp/server_subnets/test.adoc +++ b/test/case/dhcp/server_subnets/test.adoc @@ -30,8 +30,7 @@ image::topology.svg[DHCP Server Multiple Subnets topology, align=center, scaledw ==== Sequence . Set up topology and attach to client and server DUTs -. Configure DHCP server -. Configure client hostnames +. Configure DHCP server and client hostnames . Configure DHCP clients . Verify DHCP client1 get correct lease . Verify DHCP client1 has default route via server diff --git a/test/case/dhcp/server_subnets/test.py b/test/case/dhcp/server_subnets/test.py index ce0647636..561e8ea9d 100755 --- a/test/case/dhcp/server_subnets/test.py +++ b/test/case/dhcp/server_subnets/test.py @@ -24,7 +24,7 @@ import infamy import infamy.iface as iface import infamy.route as route -from infamy.util import until +from infamy.util import parallel, until def has_dns_server(data, dns_servers): @@ -83,140 +83,138 @@ def has_system_servers(dut, dns, ntp=None): with test.step("Set up topology and attach to client and server DUTs"): env = infamy.Env() - server = env.attach("server", "mgmt") - client1 = env.attach("client1", "mgmt") - client2 = env.attach("client2", "mgmt") - client3 = env.attach("client3", "mgmt") - - with test.step("Configure DHCP server"): - server.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": server["client1"], - "ipv4": { - "address": [{ - "ip": SERVER1, - "prefix-length": 24 - }] - } - }, { - "name": "br0", - "type": "infix-if-type:bridge", - "ipv4": { - "address": [{ - "ip": SERVER2, - "prefix-length": 24, - }] - } - }, { - "name": server["client2"], - "infix-interfaces:bridge-port": { - "bridge": "br0" - } - }, { - "name": server["client3"], - "infix-interfaces:bridge-port": { - "bridge": "br0" - } - }, - ] - } - }, - "infix-dhcp-server": { - "dhcp-server": { - "option": [ - { - "id": "dns-server", - "address": "auto" - }, - ], - # No client should get the static host lease on this - # subnet. Only a pool address and global options. - "subnet": [ - { - "subnet": "192.168.1.0/24", - "option": [{ - "id": "router", + server, client1, client2, client3 = parallel(lambda: env.attach("server", "mgmt"), + lambda: env.attach("client1", "mgmt"), + lambda: env.attach("client2", "mgmt"), + lambda: env.attach("client3", "mgmt")) + + with test.step("Configure DHCP server and client hostnames"): + # Set hostnames first, before enabling DHCP clients + parallel( + lambda: server.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": server["client1"], + "ipv4": { + "address": [{ + "ip": SERVER1, + "prefix-length": 24 + }] + } + }, { + "name": "br0", + "type": "infix-if-type:bridge", + "ipv4": { + "address": [{ + "ip": SERVER2, + "prefix-length": 24, + }] + } + }, { + "name": server["client2"], + "infix-interfaces:bridge-port": { + "bridge": "br0" + } + }, { + "name": server["client3"], + "infix-interfaces:bridge-port": { + "bridge": "br0" + } + }, + ] + } + }, + "infix-dhcp-server": { + "dhcp-server": { + "option": [ + { + "id": "dns-server", "address": "auto" - }], - "pool": { - "start-address": POOL1, - "end-address": POOL1 }, - # Decoy, client2 should not get this lease! - "host": [{ - "address": ADDR1, - "match": { - "hostname": HOSTNM2 - }, + ], + # No client should get the static host lease on this + # subnet. Only a pool address and global options. + "subnet": [ + { + "subnet": "192.168.1.0/24", "option": [{ - "id": "classless-static-route", - "static-route": [{ - "destination": "0.0.0.0/0", - "next-hop": GW1 - }] - }] - }] - }, - { - "subnet": "192.168.2.0/24", - "option": [ - { - "id": "ntp-server", - "address": "auto" - }, { - # Verify correct option selection in - # client: option 3 < option 121 "id": "router", "address": "auto" - } - ], - "pool": { - "start-address": POOL2, - "end-address": POOL2 + }], + "pool": { + "start-address": POOL1, + "end-address": POOL1 + }, + # Decoy, client2 should not get this lease! + "host": [{ + "address": ADDR1, + "match": { + "hostname": HOSTNM2 + }, + "option": [{ + "id": "classless-static-route", + "static-route": [{ + "destination": "0.0.0.0/0", + "next-hop": GW1 + }] + }] + }] }, - "host": [{ - "address": ADDR2, - "match": { - "hostname": HOSTNM2 + { + "subnet": "192.168.2.0/24", + "option": [ + { + "id": "ntp-server", + "address": "auto" + }, { + # Verify correct option selection in + # client: option 3 < option 121 + "id": "router", + "address": "auto" + } + ], + "pool": { + "start-address": POOL2, + "end-address": POOL2 }, - "option": [{ - "id": "classless-static-route", - "static-route": [{ - "destination": "0.0.0.0/0", - "next-hop": GW2 + "host": [{ + "address": ADDR2, + "match": { + "hostname": HOSTNM2 + }, + "option": [{ + "id": "classless-static-route", + "static-route": [{ + "destination": "0.0.0.0/0", + "next-hop": GW2 + }] }] }] - }] - }, - ] - } - }}) - - with test.step("Configure client hostnames"): - # Set hostnames first, before enabling DHCP clients - client1.put_config_dicts({ - "ietf-system": { - "system": { - "hostname": HOSTNM1, - } - }}) - - client2.put_config_dicts({ - "ietf-system": { - "system": { - "hostname": HOSTNM2, - } - }}) - - client3.put_config_dicts({ - "ietf-system": { - "system": { - "hostname": HOSTNM3, - } - }}) + }, + ] + } + }}), + lambda: client1.put_config_dicts({ + "ietf-system": { + "system": { + "hostname": HOSTNM1, + } + }}), + lambda: client2.put_config_dicts({ + "ietf-system": { + "system": { + "hostname": HOSTNM2, + } + }}), + lambda: client3.put_config_dicts({ + "ietf-system": { + "system": { + "hostname": HOSTNM3, + } + }}), + ) # Wait for hostnames to be applied in operational datastore print("Waiting for client hostnames to take ...") @@ -233,98 +231,98 @@ def has_system_servers(dut, dns, ntp=None): # the server is behaving correctly. print("Enable DHCP clients ...") - client1.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client1["server"], - "ipv4": { - "infix-dhcp-client:dhcp": { - "option": [ - {"id": "hostname", "value": "auto"}, - {"id": "router"}, - {"id": "dns-server"}, - {"id": "ntp-server"}, - {"id": 121} - ] + parallel( + lambda: client1.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client1["server"], + "ipv4": { + "infix-dhcp-client:dhcp": { + "option": [ + {"id": "hostname", "value": "auto"}, + {"id": "router"}, + {"id": "dns-server"}, + {"id": "ntp-server"}, + {"id": 121} + ] + } } - } - }] - } - }, - "ietf-system": { - "system": { - "ntp": {"enabled": True}, - } - }}) - - client2.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client2["server"], - "ipv4": { - "infix-dhcp-client:dhcp": { - "option": [ - {"id": "hostname", "value": "auto"}, - {"id": "router"}, - {"id": "dns-server"}, - {"id": "ntp-server"}, - {"id": 121} - ] + }] + } + }, + "ietf-system": { + "system": { + "ntp": {"enabled": True}, + } + }}), + lambda: client2.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client2["server"], + "ipv4": { + "infix-dhcp-client:dhcp": { + "option": [ + {"id": "hostname", "value": "auto"}, + {"id": "router"}, + {"id": "dns-server"}, + {"id": "ntp-server"}, + {"id": 121} + ] + } } - } - }] - } - }, - "ietf-system": { - "system": { - "ntp": {"enabled": True}, - } - }}) - - client3.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client3["server"], - "ipv4": { - "infix-dhcp-client:dhcp": { - "option": [ - {"id": "hostname", "value": "auto"}, - {"id": "router"}, - {"id": "dns-server"}, - {"id": "ntp-server"}, - {"id": 121} - ] + }] + } + }, + "ietf-system": { + "system": { + "ntp": {"enabled": True}, + } + }}), + lambda: client3.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client3["server"], + "ipv4": { + "infix-dhcp-client:dhcp": { + "option": [ + {"id": "hostname", "value": "auto"}, + {"id": "router"}, + {"id": "dns-server"}, + {"id": "ntp-server"}, + {"id": 121} + ] + } } - } - }] - } - }, - "ietf-system": { - "system": { - "ntp": {"enabled": True}, - "dns-resolver": { - "search": [ - "example.com", - "kernelkit.org" - ], - "server": [ - { - "name": "static", - "udp-and-tcp": { - "address": "1.2.3.4" + }] + } + }, + "ietf-system": { + "system": { + "ntp": {"enabled": True}, + "dns-resolver": { + "search": [ + "example.com", + "kernelkit.org" + ], + "server": [ + { + "name": "static", + "udp-and-tcp": { + "address": "1.2.3.4" + } + } + ], + "options": { + "timeout": 3, + "attempts": 5 } - } - ], - "options": { - "timeout": 3, - "attempts": 5 - } - }, - } - }}) + }, + } + }}), + ) with test.step("Verify DHCP client1 get correct lease"): until(lambda: iface.address_exist(client1, client1["server"], POOL1)) diff --git a/test/case/hardware/watchdog/test.py b/test/case/hardware/watchdog/test.py index b88545362..3c4d66dff 100755 --- a/test/case/hardware/watchdog/test.py +++ b/test/case/hardware/watchdog/test.py @@ -12,6 +12,7 @@ """ import base64 import infamy +from infamy.util import parallel import json import subprocess import time @@ -19,8 +20,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Verify the presence of a watchdog device"): wctl = tgtssh.run(["watchdogctl"], stdout=subprocess.PIPE) diff --git a/test/case/interfaces/bridge_fwd_dual_dut/test.py b/test/case/interfaces/bridge_fwd_dual_dut/test.py index 2f0f82142..7a15a260b 100755 --- a/test/case/interfaces/bridge_fwd_dual_dut/test.py +++ b/test/case/interfaces/bridge_fwd_dual_dut/test.py @@ -27,12 +27,13 @@ """ import infamy +from infamy.util import parallel with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - dut1 = env.attach("dut1", "mgmt") - dut2 = env.attach("dut2", "mgmt") + dut1, dut2 = parallel(lambda: env.attach("dut1", "mgmt"), + lambda: env.attach("dut2", "mgmt")) with test.step("Configure a bridge with triple physical port"): _, tport11 = env.ltop.xlate("dut1", "data1") @@ -41,89 +42,90 @@ _, tport22 = env.ltop.xlate("dut2", "data2") _, tport2_link = env.ltop.xlate("dut2", "link") - dut1.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": "br0", - "type": "infix-if-type:bridge", - "enabled": True, - "bridge": { - "vlans": { - "vlan": [ - { - "vid": 10, - "untagged": [ tport11 ], - "tagged": [ "br0", tport1_link ] - } - ] + parallel( + lambda: dut1.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": "br0", + "type": "infix-if-type:bridge", + "enabled": True, + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 10, + "untagged": [ tport11 ], + "tagged": [ "br0", tport1_link ] + } + ] + } } - } - }, - { - "name": tport11, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - }, - { - "name": tport1_link, - "enabled": True, - "infix-interfaces:bridge-port": { - "bridge": "br0", - } - } - ] - } - }}) - - dut2.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": "br0", - "type": "infix-if-type:bridge", - "enabled": True, - "bridge": { - "vlans": { - "vlan": [ - { - "vid": 10, - "untagged": [ tport21, tport22 ], - "tagged": [ "br0", tport2_link ] - } - ] + }, + { + "name": tport11, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } + }, + { + "name": tport1_link, + "enabled": True, + "infix-interfaces:bridge-port": { + "bridge": "br0", } } - }, - { - "name": tport21, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - }, - { - "name": tport22, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - }, - { - "name": tport2_link, - "enabled": True, - "infix-interfaces:bridge-port": { - "bridge": "br0", + ] + } + }}), + lambda: dut2.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": "br0", + "type": "infix-if-type:bridge", + "enabled": True, + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 10, + "untagged": [ tport21, tport22 ], + "tagged": [ "br0", tport2_link ] + } + ] + } + } + }, + { + "name": tport21, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } + }, + { + "name": tport22, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } + }, + { + "name": tport2_link, + "enabled": True, + "infix-interfaces:bridge-port": { + "bridge": "br0", + } } - } - ] - } - }}) + ] + } + }}), + ) with test.step("Verify ping 10.0.0.3 and 10.0.0.4 from host:data11"): diff --git a/test/case/interfaces/bridge_vlan/test.py b/test/case/interfaces/bridge_vlan/test.py index 2b325f5b4..b60300d7b 100755 --- a/test/case/interfaces/bridge_vlan/test.py +++ b/test/case/interfaces/bridge_vlan/test.py @@ -10,93 +10,95 @@ """ import infamy +from infamy.util import parallel with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - dut1 = env.attach("dut1", "mgmt") - dut2 = env.attach("dut2", "mgmt") + dut1, dut2 = parallel(lambda: env.attach("dut1", "mgmt"), + lambda: env.attach("dut2", "mgmt")) with test.step("Configure DUTs"): - dut1.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": "br0", - "type": "infix-if-type:bridge", - "bridge": { - "vlans": { - "vlan": [ + parallel( + lambda: dut1.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": "br0", + "type": "infix-if-type:bridge", + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 10, + "untagged": [dut1["data"]], + "tagged": [dut1["link"], "br0"] + } + ] + } + } + }, { + "name": "vlan10", + "type": "infix-if-type:vlan", + "vlan": { + "lower-layer-if": "br0", + "id": 10, + }, + "ipv4": { + "address": [ { - "vid": 10, - "untagged": [dut1["data"]], - "tagged": [dut1["link"], "br0"] + "ip": "10.0.0.2", + "prefix-length": 24, } ] } + }, { + "name": dut1["data"], + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } + }, { + "name": dut1["link"], + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } } - }, { - "name": "vlan10", - "type": "infix-if-type:vlan", - "vlan": { - "lower-layer-if": "br0", - "id": 10, - }, - "ipv4": { - "address": [ - { - "ip": "10.0.0.2", - "prefix-length": 24, - } - ] - } - }, { - "name": dut1["data"], - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - }, { - "name": dut1["link"], - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - } - ] - } - }}) - - dut2.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": "br0", - "type": "infix-if-type:bridge", - "ipv4": { - "address": [ - { - "ip": "10.0.0.3", - "prefix-length": 24, - } - ] - } - }, { - "name": dut2["link"], - }, { - "name": "e0.10", - "type": "infix-if-type:vlan", - "vlan": { - "lower-layer-if": dut2["link"], - "id": 10, - }, - "infix-interfaces:bridge-port": { - "bridge": "br0" + ] + } + }}), + lambda: dut2.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": "br0", + "type": "infix-if-type:bridge", + "ipv4": { + "address": [ + { + "ip": "10.0.0.3", + "prefix-length": 24, + } + ] + } + }, { + "name": dut2["link"], + }, { + "name": "e0.10", + "type": "infix-if-type:vlan", + "vlan": { + "lower-layer-if": dut2["link"], + "id": 10, + }, + "infix-interfaces:bridge-port": { + "bridge": "br0" + } } - } - ] - } - }}) + ] + } + }}), + ) with test.step("Verify ping from host:data to 10.0.0.2 and 10.0.0.3"): _, hport = env.ltop.xlate("host", "data") diff --git a/test/case/interfaces/bridge_vlan_separation/test.py b/test/case/interfaces/bridge_vlan_separation/test.py index fd7272c1e..b63bfadae 100755 --- a/test/case/interfaces/bridge_vlan_separation/test.py +++ b/test/case/interfaces/bridge_vlan_separation/test.py @@ -24,13 +24,14 @@ .... """ import infamy +from infamy.util import parallel import subprocess with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - dut1 = env.attach("dut1", "mgmt") - dut2 = env.attach("dut2", "mgmt") + dut1, dut2 = parallel(lambda: env.attach("dut1", "mgmt"), + lambda: env.attach("dut2", "mgmt")) with test.step("Configure DUTs"): _, tport10 = env.ltop.xlate("dut1", "data1") @@ -40,107 +41,108 @@ _, tport21 = env.ltop.xlate("dut2", "data2") _, tport22 = env.ltop.xlate("dut2", "link") - dut1.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": "br0", - "type": "infix-if-type:bridge", - "enabled": True, - "bridge": { - "vlans": { - "vlan": [ - { - "vid": 10, - "untagged": [ tport10 ], - "tagged": [ "br0", tport12 ] - }, - { - "vid": 20, - "untagged": [ tport11 ], - "tagged": [ "br0", tport12 ] - } - ] + parallel( + lambda: dut1.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": "br0", + "type": "infix-if-type:bridge", + "enabled": True, + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 10, + "untagged": [ tport10 ], + "tagged": [ "br0", tport12 ] + }, + { + "vid": 20, + "untagged": [ tport11 ], + "tagged": [ "br0", tport12 ] + } + ] + } } - } - }, - { - "name": tport10, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - }, - { - "name": tport11, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 20, - "bridge": "br0" - } - }, - { - "name": tport12, - "enabled": True, - "infix-interfaces:bridge-port": { - "bridge": "br0", - } - } - ] - } - }}) - - dut2.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": "br0", - "type": "infix-if-type:bridge", - "enabled": True, - "bridge": { - "vlans": { - "vlan": [ - { - "vid": 10, - "untagged": [ tport20 ], - "tagged": [ "br0", tport22 ] - }, - { - "vid": 20, - "untagged": [ tport21 ], - "tagged": [ "br0", tport22 ] - } - ] + }, + { + "name": tport10, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } + }, + { + "name": tport11, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 20, + "bridge": "br0" + } + }, + { + "name": tport12, + "enabled": True, + "infix-interfaces:bridge-port": { + "bridge": "br0", } } - }, - { - "name": tport20, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 10, - "bridge": "br0" - } - }, - { - "name": tport21, - "enabled": True, - "infix-interfaces:bridge-port": { - "pvid": 20, - "bridge": "br0" - } - }, - { - "name": tport22, - "enabled": True, - "infix-interfaces:bridge-port": { - "bridge": "br0", + ] + } + }}), + lambda: dut2.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": "br0", + "type": "infix-if-type:bridge", + "enabled": True, + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 10, + "untagged": [ tport20 ], + "tagged": [ "br0", tport22 ] + }, + { + "vid": 20, + "untagged": [ tport21 ], + "tagged": [ "br0", tport22 ] + } + ] + } + } + }, + { + "name": tport20, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 10, + "bridge": "br0" + } + }, + { + "name": tport21, + "enabled": True, + "infix-interfaces:bridge-port": { + "pvid": 20, + "bridge": "br0" + } + }, + { + "name": tport22, + "enabled": True, + "infix-interfaces:bridge-port": { + "bridge": "br0", + } } - } - ] - } - }}) + ] + } + }}), + ) _, hport10 = env.ltop.xlate("host", "data10") diff --git a/test/case/interfaces/iface_enable_disable/test.py b/test/case/interfaces/iface_enable_disable/test.py index a1ea3d18d..def6c8728 100755 --- a/test/case/interfaces/iface_enable_disable/test.py +++ b/test/case/interfaces/iface_enable_disable/test.py @@ -9,9 +9,9 @@ """ import infamy +from infamy.util import parallel, until import infamy.iface as iface -from infamy import until def print_error_message(iface, param, exp_val, act_val): return f"'{param}' failure for interface '{iface}'. Expected '{exp_val}', Actual: '{act_val}'" @@ -65,8 +65,8 @@ def configure_interface(target, iface_name, iface_type=None, enabled=True, ip_ad with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - target1 = env.attach("target1", "mgmt") - target2 = env.attach("target2", "mgmt") + target1, target2 = parallel(lambda: env.attach("target1", "mgmt"), + lambda: env.attach("target2", "mgmt")) _, data1 = env.ltop.xlate("target1", "data") _, link1 = env.ltop.xlate("target1", "link") diff --git a/test/case/interfaces/igmp_vlan/test.py b/test/case/interfaces/igmp_vlan/test.py index 46c27b7d9..6edcb96a4 100755 --- a/test/case/interfaces/igmp_vlan/test.py +++ b/test/case/interfaces/igmp_vlan/test.py @@ -24,11 +24,11 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - dut1 = env.attach("dut1", "mgmt") + dut1, dut2 = parallel(lambda: env.attach("dut1", "mgmt"), + lambda: env.attach("dut2", "mgmt")) _, d1send = env.ltop.xlate("dut1", "data1") _, d1receiver = env.ltop.xlate("dut1", "data2") _, d1trunk = env.ltop.xlate("dut1", "link") - dut2 = env.attach("dut2", "mgmt") _, d2receive = env.ltop.xlate("dut2", "data1") _, d2sender = env.ltop.xlate("dut2", "data2") _, d2trunk = env.ltop.xlate("dut2", "link") @@ -40,211 +40,212 @@ with test.step("Configure device"): - dut1.put_config_dicts( - { - "ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": d1send, - "enabled": True, - "bridge-port": { - "bridge": "br0", - "pvid": 55 + parallel( + lambda: dut1.put_config_dicts( + { + "ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": d1send, + "enabled": True, + "bridge-port": { + "bridge": "br0", + "pvid": 55 - } - }, - { - "name": d1receiver, - "enabled": True, - "bridge-port": { - "bridge": "br0", - "pvid": 77 - } - }, - { - "name": d1trunk, - "enabled": True, - "bridge-port": { - "bridge": "br0" - } - }, - { - "name": "vlan55", - "enabled": True, - "type": "infix-if-type:vlan", - "ipv4": { - "address": [ - { - "ip": "10.0.1.1", - "prefix-length": 24 - } - ] + } }, - "vlan": { - "id": 55, - "lower-layer-if": "br0" - } - - }, - { - "name": "vlan77", - "enabled": True, - "type": "infix-if-type:vlan", - "ipv4": { - "address": [ - { - "ip": "10.0.2.1", - "prefix-length": 24 - } - ] + { + "name": d1receiver, + "enabled": True, + "bridge-port": { + "bridge": "br0", + "pvid": 77 + } }, - "vlan": { - "id": 77, - "lower-layer-if": "br0" - } - - }, - { - "name": "br0", - "enabled": True, - "type": "infix-if-type:bridge", - - "bridge": { - "vlans": { - "vlan": [ + { + "name": d1trunk, + "enabled": True, + "bridge-port": { + "bridge": "br0" + } + }, + { + "name": "vlan55", + "enabled": True, + "type": "infix-if-type:vlan", + "ipv4": { + "address": [ { - "vid": 55, - "untagged": [ d1send ], - "tagged": [ d1trunk, "br0" ], - "multicast": { - "snooping": True - } - }, + "ip": "10.0.1.1", + "prefix-length": 24 + } + ] + }, + "vlan": { + "id": 55, + "lower-layer-if": "br0" + } + + }, + { + "name": "vlan77", + "enabled": True, + "type": "infix-if-type:vlan", + "ipv4": { + "address": [ { - "vid": 77, - "untagged": [ d1receiver ], - "tagged": [ d1trunk, "br0" ], - "multicast": { - "snooping": True - } + "ip": "10.0.2.1", + "prefix-length": 24 } ] + }, + "vlan": { + "id": 77, + "lower-layer-if": "br0" } - } - } - ] - } - }, - "ietf-system": { - "system": { - "hostname": "dut1" - } - } - } - ) - dut2.put_config_dicts( - { - "ietf-interfaces": { - "interfaces": { - "interface": [ - { - "name": d2receive, - "enabled": True, - "bridge-port": { - "bridge": "br0", - "pvid": 55 - } - }, - { - "name": d2sender, - "enabled": True, - "bridge-port": { - "bridge": "br0", - "pvid": 77 - } - }, - { - "name": d2trunk, - "enabled": True, - "bridge-port": { - "bridge": "br0" - } - }, - { - "name": "vlan55", - "enabled": True, - "type": "infix-if-type:vlan", - "ipv4": { - "address": [ - { - "ip": "10.0.1.2", - "prefix-length": 24 - } - ] }, - "vlan": { - "id": 55, - "lower-layer-if": "br0" - } + { + "name": "br0", + "enabled": True, + "type": "infix-if-type:bridge", - }, - { - "name": "vlan77", - "enabled": True, - "type": "infix-if-type:vlan", - "ipv4": { - "address": [ - { - "ip": "10.0.2.2", - "prefix-length": 24 + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 55, + "untagged": [ d1send ], + "tagged": [ d1trunk, "br0" ], + "multicast": { + "snooping": True + } + }, + { + "vid": 77, + "untagged": [ d1receiver ], + "tagged": [ d1trunk, "br0" ], + "multicast": { + "snooping": True + } + } + ] } - ] - }, - "vlan": { - "id": 77, - "lower-layer-if": "br0" + } } - - }, - { - "name": "br0", - "enabled": True, - "type": "infix-if-type:bridge", - - "bridge": { - "vlans": { - "vlan": [ + ] + } + }, + "ietf-system": { + "system": { + "hostname": "dut1" + } + } + } + ), + lambda: dut2.put_config_dicts( + { + "ietf-interfaces": { + "interfaces": { + "interface": [ + { + "name": d2receive, + "enabled": True, + "bridge-port": { + "bridge": "br0", + "pvid": 55 + } + }, + { + "name": d2sender, + "enabled": True, + "bridge-port": { + "bridge": "br0", + "pvid": 77 + } + }, + { + "name": d2trunk, + "enabled": True, + "bridge-port": { + "bridge": "br0" + } + }, + { + "name": "vlan55", + "enabled": True, + "type": "infix-if-type:vlan", + "ipv4": { + "address": [ { - "vid": 55, - "untagged": [ d2receive ], - "tagged": [ d2trunk, "br0" ], - "multicast": { - "snooping": True - } - }, + "ip": "10.0.1.2", + "prefix-length": 24 + } + ] + }, + "vlan": { + "id": 55, + "lower-layer-if": "br0" + } + + }, + { + "name": "vlan77", + "enabled": True, + "type": "infix-if-type:vlan", + "ipv4": { + "address": [ { - "vid": 77, - "untagged": [ d2sender ], - "tagged": [ d2trunk, "br0" ], - "multicast": { - "snooping": True - } + "ip": "10.0.2.2", + "prefix-length": 24 } ] + }, + "vlan": { + "id": 77, + "lower-layer-if": "br0" + } + + }, + { + "name": "br0", + "enabled": True, + "type": "infix-if-type:bridge", + + "bridge": { + "vlans": { + "vlan": [ + { + "vid": 55, + "untagged": [ d2receive ], + "tagged": [ d2trunk, "br0" ], + "multicast": { + "snooping": True + } + }, + { + "vid": 77, + "untagged": [ d2sender ], + "tagged": [ d2trunk, "br0" ], + "multicast": { + "snooping": True + } + } + ] + } } } - } - ] + ] + } + }, + "ietf-system": { + "system": { + "hostname": "dut2" + } } - }, - "ietf-system": { - "system": { - "hostname": "dut2" - } - } - }) + }), + ) with infamy.IsolatedMacVlan(hsendd1) as d1send_ns, \ infamy.IsolatedMacVlan(hreceived1) as d1receive_ns, \ @@ -266,18 +267,18 @@ with test.step("Verify group 224.1.1.1 is flooded to host:data12"): d2receive_ns.must_receive("ip dst 224.1.1.1") with test.step("Verify group 224.2.2.2 on host:data11, 224.1.1.1 on host:data21, 224.2.2.2 on host:data12 and 224.1.1.1 on host:data22 is not received"): - parallel(d1send_ns.must_not_receive("host 224.2.2.2"), - d1receive_ns.must_not_receive("host 224.1.1.1"), - d2receive_ns.must_not_receive("host 224.2.2.2"), - d2send_ns.must_not_receive("host 224.1.1.1")) + parallel(lambda: d1send_ns.must_not_receive("host 224.2.2.2"), + lambda: d1receive_ns.must_not_receive("host 224.1.1.1"), + lambda: d2receive_ns.must_not_receive("host 224.2.2.2"), + lambda: d2send_ns.must_not_receive("host 224.1.1.1")) with test.step("Join multicast group 224.2.2.2 on host:data21"): vlan55_receiver = mcast.MCastReceiver(d1receive_ns, "224.2.2.2") with vlan55_receiver: with test.step("Verify group 224.2.2.2 on host:data11, 224.1.1.1 on host:data21, 224.2.2.2 on host:data12 and 224.1.1.1 on host:data22 is not received"): - parallel(d1send_ns.must_not_receive("host 224.2.2.2"), - d1receive_ns.must_not_receive("host 224.1.1.1"), - d1send_ns.must_not_receive("host 224.2.2.2"), - d2send_ns.must_not_receive("host 224.1.1.1")) + parallel(lambda: d1send_ns.must_not_receive("host 224.2.2.2"), + lambda: d1receive_ns.must_not_receive("host 224.1.1.1"), + lambda: d1send_ns.must_not_receive("host 224.2.2.2"), + lambda: d2send_ns.must_not_receive("host 224.1.1.1")) with test.step("Verify group 224.2.2.2 is forwarded to host:data21"): d1receive_ns.must_receive("host 224.2.2.2") with test.step("Verify group 224.1.1.1 is forwarded to host:data12"): diff --git a/test/case/interfaces/ipv6_address/test.py b/test/case/interfaces/ipv6_address/test.py index f3372e847..2c4d42f49 100755 --- a/test/case/interfaces/ipv6_address/test.py +++ b/test/case/interfaces/ipv6_address/test.py @@ -6,13 +6,13 @@ See issue #473 for details. """ import infamy -from infamy.util import until +from infamy.util import parallel, until with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Setting up bridge with IPv6 SLAAC for global prefix on target:data"): _, tport = env.ltop.xlate("target", "data") diff --git a/test/case/interfaces/lag_basic/test.py b/test/case/interfaces/lag_basic/test.py index e4f8ddba9..3610e7bd7 100755 --- a/test/case/interfaces/lag_basic/test.py +++ b/test/case/interfaces/lag_basic/test.py @@ -24,9 +24,9 @@ def __init__(self, sys, dut, netns): self.env = sys self.dut = dut self.net = netns - self.tgt = {} - for i, (name, _) in dut.items(): - self.tgt[i] = env.attach(name, "mgmt", "ssh") + self.tgt = dict(zip(dut.keys(), + parallel(*(lambda n=name: env.attach(n, "mgmt", "ssh") + for name, _ in dut.values())))) def set_link(self, link, updown): """Set link up or down, verify before returning.""" @@ -136,8 +136,8 @@ def dut_init(dut, mode, addr): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env(edge_mappings=infamy.lag.edge_mappings) - dut1 = env.attach("dut1", "mgmt") - dut2 = env.attach("dut2", "mgmt") + dut1, dut2 = parallel(lambda: env.attach("dut1", "mgmt"), + lambda: env.attach("dut2", "mgmt")) _, mon = env.ltop.xlate("host", "mon") with infamy.IsolatedMacVlan(mon) as ns: diff --git a/test/case/interfaces/lag_failure/test.py b/test/case/interfaces/lag_failure/test.py index 124ffebfe..c397d138a 100755 --- a/test/case/interfaces/lag_failure/test.py +++ b/test/case/interfaces/lag_failure/test.py @@ -122,8 +122,8 @@ def dut_init(dut, addr, peer): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env(edge_mappings=infamy.lag.edge_mappings) - dut1 = env.attach("dut1") - dut2 = env.attach("dut2") + dut1, dut2 = parallel(lambda: env.attach("dut1"), + lambda: env.attach("dut2")) _, mon = env.ltop.xlate("host", "mon") with infamy.IsolatedMacVlan(mon) as ns: diff --git a/test/case/interfaces/tunnel_basic/test.py b/test/case/interfaces/tunnel_basic/test.py index 576ffcd2d..69a4bcd38 100755 --- a/test/case/interfaces/tunnel_basic/test.py +++ b/test/case/interfaces/tunnel_basic/test.py @@ -12,6 +12,7 @@ """ import infamy +from infamy.util import parallel class ArgumentParser(infamy.ArgumentParser): @@ -25,8 +26,8 @@ def __init__(self): arg = ArgumentParser() env = infamy.Env(args=arg) tunnel = env.args.tunnel - left = env.attach("left", "mgmt") - right = env.attach("right", "mgmt") + left, right = parallel(lambda: env.attach("left", "mgmt"), + lambda: env.attach("right", "mgmt")) with test.step(f"Configure DUTs with tunnel {tunnel}"): container_left4 = { @@ -63,137 +64,138 @@ def __init__(self): "vni": 6 }) - left.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": left["link"], - "ipv4": { - "address": [{ - "ip": "192.168.50.1", - "prefix-length": 24 - }], - "forwarding": True - }, - "ipv6": { - "address": [{ - "ip": "2001:db8:3c4d:50::1", - "prefix-length": 64 - }], - "forwarding": True - } - }, { - "name": left["data"], - "ipv4": { - "address": [{ - "ip": "192.168.10.1", - "prefix-length": 24 - }], - "forwarding": True - }, - "ipv6": { - "address": [{ - "ip": "2001:db8:3c4d:10::1", - "prefix-length": 64 - }], - "forwarding": True - } - }, { - "name": f"{tunnel}4", - "type": f"infix-if-type:{tunnel}", - "ipv4": { - "address": [{ - "ip": "192.168.30.1", - "prefix-length": 24 - }], - "forwarding": True - }, - CONTAINER_TYPE: container_left4 - }, { - "name": f"{tunnel}6", - "type": f"infix-if-type:{tunnel}", - "ipv6": { - "address": [{ - "ip": "2001:db8:3c4d:30::1", - "prefix-length": 64 - }], - "forwarding": True - }, - CONTAINER_TYPE: container_left6 - }] - } - }}) - - right.put_config_dicts({ - "ietf-interfaces": { + parallel( + lambda: left.put_config_dicts({"ietf-interfaces": { "interfaces": { "interface": [{ - "name": right["link"], + "name": left["link"], "ipv4": { "address": [{ - "ip": "192.168.50.2", + "ip": "192.168.50.1", "prefix-length": 24 }], "forwarding": True }, "ipv6": { "address": [{ - "ip": "2001:db8:3c4d:50::2", + "ip": "2001:db8:3c4d:50::1", "prefix-length": 64 - }] + }], + "forwarding": True + } + }, { + "name": left["data"], + "ipv4": { + "address": [{ + "ip": "192.168.10.1", + "prefix-length": 24 + }], + "forwarding": True + }, + "ipv6": { + "address": [{ + "ip": "2001:db8:3c4d:10::1", + "prefix-length": 64 + }], + "forwarding": True } }, { "name": f"{tunnel}4", "type": f"infix-if-type:{tunnel}", "ipv4": { "address": [{ - "ip": "192.168.30.2", + "ip": "192.168.30.1", "prefix-length": 24 }], "forwarding": True }, - CONTAINER_TYPE: container_right4 + CONTAINER_TYPE: container_left4 }, { - "name": f"{tunnel}", + "name": f"{tunnel}6", "type": f"infix-if-type:{tunnel}", "ipv6": { "address": [{ - "ip": "2001:db8:3c4d:30::2", + "ip": "2001:db8:3c4d:30::1", "prefix-length": 64 - }] + }], + "forwarding": True }, - CONTAINER_TYPE: container_right6 + CONTAINER_TYPE: container_left6 }] } - }, - "ietf-routing": { - "routing": { - "control-plane-protocols": { - "control-plane-protocol": [{ - "type": "infix-routing:static", - "name": "default", - "static-routes": { - "ipv4": { - "route": [{ - "destination-prefix": "192.168.10.0/24", - "next-hop": { - "next-hop-address": "192.168.30.1" - } - }] - }, - "ipv6": { - "route": [{ - "destination-prefix": "2001:db8:3c4d:10::/64", - "next-hop": { - "next-hop-address": "2001:db8:3c4d:30::1" - } - }] - } + }}), + lambda: right.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": right["link"], + "ipv4": { + "address": [{ + "ip": "192.168.50.2", + "prefix-length": 24 + }], + "forwarding": True + }, + "ipv6": { + "address": [{ + "ip": "2001:db8:3c4d:50::2", + "prefix-length": 64 + }] } + }, { + "name": f"{tunnel}4", + "type": f"infix-if-type:{tunnel}", + "ipv4": { + "address": [{ + "ip": "192.168.30.2", + "prefix-length": 24 + }], + "forwarding": True + }, + CONTAINER_TYPE: container_right4 + }, { + "name": f"{tunnel}", + "type": f"infix-if-type:{tunnel}", + "ipv6": { + "address": [{ + "ip": "2001:db8:3c4d:30::2", + "prefix-length": 64 + }] + }, + CONTAINER_TYPE: container_right6 }] } + }, + "ietf-routing": { + "routing": { + "control-plane-protocols": { + "control-plane-protocol": [{ + "type": "infix-routing:static", + "name": "default", + "static-routes": { + "ipv4": { + "route": [{ + "destination-prefix": "192.168.10.0/24", + "next-hop": { + "next-hop-address": "192.168.30.1" + } + }] + }, + "ipv6": { + "route": [{ + "destination-prefix": "2001:db8:3c4d:10::/64", + "next-hop": { + "next-hop-address": "2001:db8:3c4d:30::1" + } + }] + } + } + }] + } + } } - } - }) + }), + ) _, hport = env.ltop.xlate("host", "data") with test.step("Verify connectivity host:data to 10.0.0.2"): diff --git a/test/case/interfaces/tunnel_bridged/test.py b/test/case/interfaces/tunnel_bridged/test.py index 15b283222..36ed22831 100755 --- a/test/case/interfaces/tunnel_bridged/test.py +++ b/test/case/interfaces/tunnel_bridged/test.py @@ -11,6 +11,7 @@ """ import infamy +from infamy.util import parallel class ArgumentParser(infamy.ArgumentParser): @@ -23,8 +24,8 @@ def __init__(self): with test.step("Set up topology and attach to target DUTs"): arg = ArgumentParser() env = infamy.Env(args=arg) - left = env.attach("left", "mgmt") - right = env.attach("right", "mgmt") + left, right = parallel(lambda: env.attach("left", "mgmt"), + lambda: env.attach("right", "mgmt")) tunnel = env.args.tunnel with test.step("Configure DUTs with tunnel {tunnel}"): @@ -48,70 +49,71 @@ def __init__(self): "vni": 4 }) - left.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": left["link"], - "ipv4": { - "address": [{ - "ip": "192.168.50.1", - "prefix-length": 24 - }], - "forwarding": True - } - }, { - "name": left["data"], - "bridge-port": { - "bridge": "br0" - } - }, { - "name": "br0", - "type": "infix-if-type:bridge" - }, { - "name": f"{tunnel}0", - "type": f"infix-if-type:{tunnel}", - CONTAINER_TYPE: container_left, - "bridge-port": { - "bridge": "br0" - } - - }] - } - }}) - - right.put_config_dicts({ - "ietf-interfaces": { + parallel( + lambda: left.put_config_dicts({"ietf-interfaces": { "interfaces": { "interface": [{ - "name": right["link"], + "name": left["link"], "ipv4": { "address": [{ - "ip": "192.168.50.2", + "ip": "192.168.50.1", "prefix-length": 24 }], "forwarding": True - }, - "ipv6": { - "address": [{ - "ip": "2001:db8:3c4d:50::2", - "prefix-length": 64 - }] } + }, { + "name": left["data"], + "bridge-port": { + "bridge": "br0" + } + }, { + "name": "br0", + "type": "infix-if-type:bridge" }, { "name": f"{tunnel}0", "type": f"infix-if-type:{tunnel}", - "ipv4": { - "address": [{ - "ip": "192.168.10.2", - "prefix-length": 24 - }], - "forwarding": True - }, - CONTAINER_TYPE: container_right, + CONTAINER_TYPE: container_left, + "bridge-port": { + "bridge": "br0" + } + }] } - } - }) + }}), + lambda: right.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": right["link"], + "ipv4": { + "address": [{ + "ip": "192.168.50.2", + "prefix-length": 24 + }], + "forwarding": True + }, + "ipv6": { + "address": [{ + "ip": "2001:db8:3c4d:50::2", + "prefix-length": 64 + }] + } + }, { + "name": f"{tunnel}0", + "type": f"infix-if-type:{tunnel}", + "ipv4": { + "address": [{ + "ip": "192.168.10.2", + "prefix-length": 24 + }], + "forwarding": True + }, + CONTAINER_TYPE: container_right, + }] + } + } + }), + ) _, hport = env.ltop.xlate("host", "data") with test.step(f"Test connectivity host:data to right:{tunnel}0 at 192.168.10.2"): diff --git a/test/case/interfaces/tunnel_ttl/gre.adoc b/test/case/interfaces/tunnel_ttl/gre.adoc index 10f47106d..4cf913966 100644 --- a/test/case/interfaces/tunnel_ttl/gre.adoc +++ b/test/case/interfaces/tunnel_ttl/gre.adoc @@ -23,9 +23,7 @@ image::topology.svg[GRE Tunnel TTL Verification topology, align=center, scaledwi ==== Sequence . Set up topology and attach to target DUTs -. Configure R1 with gre tunnel to R3 -. Configure R2 as intermediate router (underlay forwarding) -. Configure R3 with gre tunnel to R1 +. Configure gre tunnel from R1 to R3, with R2 as intermediate router . Send ping from PC:west to PC:east with low TTL . Verify packets arrived at PC:east diff --git a/test/case/interfaces/tunnel_ttl/test.py b/test/case/interfaces/tunnel_ttl/test.py index 7cab666d5..068c5dbaa 100755 --- a/test/case/interfaces/tunnel_ttl/test.py +++ b/test/case/interfaces/tunnel_ttl/test.py @@ -16,6 +16,7 @@ """ import infamy +from infamy.util import parallel class ArgumentParser(infamy.ArgumentParser): @@ -65,11 +66,11 @@ def __init__(self): arg = ArgumentParser() env = infamy.Env(args=arg) tunnel = env.args.tunnel - r1 = env.attach("R1", "mgmt") - r2 = env.attach("R2", "mgmt") - r3 = env.attach("R3", "mgmt") + r1, r2, r3 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt")) - with test.step(f"Configure R1 with {tunnel} tunnel to R3"): + with test.step(f"Configure {tunnel} tunnel from R1 to R3, with R2 as intermediate router"): # R1: Entry point, west facing PC, east facing R2, tunnel to R3 # Build tunnel container configs @@ -87,151 +88,149 @@ def __init__(self): container_r1["vni"] = VNI container_r3["vni"] = VNI - r1.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": r1["west"], - "ipv4": { - "address": [{ - "ip": PC_WEST_R1, - "prefix-length": PREFIX_24 - }], - "forwarding": True - } - }, { - "name": r1["east"], - "ipv4": { - "address": [{ - "ip": R1_R2_R1, - "prefix-length": PREFIX_24 - }], - "forwarding": True - } - }, { - "name": f"{tunnel}0", - "type": f"infix-if-type:{tunnel}", - "ipv4": { - "address": [{ - "ip": TUNNEL_R1, - "prefix-length": PREFIX_30 - }], - "forwarding": True - }, - CONTAINER_TYPE: container_r1 - }] - } - }, "ietf-routing": { - "routing": { - "control-plane-protocols": { - "control-plane-protocol": [{ - "type": "infix-routing:static", - "name": "default", - "static-routes": { - "ipv4": { - "route": [{ - "destination-prefix": R2_R3_NET, - "next-hop": { - "next-hop-address": R1_R2_R2 - } - }, { - "destination-prefix": PC_EAST_NET, - "next-hop": { - "next-hop-address": TUNNEL_R3 - } - }] - } + parallel( + lambda: r1.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": r1["west"], + "ipv4": { + "address": [{ + "ip": PC_WEST_R1, + "prefix-length": PREFIX_24 + }], + "forwarding": True } + }, { + "name": r1["east"], + "ipv4": { + "address": [{ + "ip": R1_R2_R1, + "prefix-length": PREFIX_24 + }], + "forwarding": True + } + }, { + "name": f"{tunnel}0", + "type": f"infix-if-type:{tunnel}", + "ipv4": { + "address": [{ + "ip": TUNNEL_R1, + "prefix-length": PREFIX_30 + }], + "forwarding": True + }, + CONTAINER_TYPE: container_r1 }] } - } - }}) - - with test.step("Configure R2 as intermediate router (underlay forwarding)"): - # R2: Intermediate router, just forwards packets between west and east - r2.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": r2["west"], - "ipv4": { - "address": [{ - "ip": R1_R2_R2, - "prefix-length": PREFIX_24 - }], - "forwarding": True - } - }, { - "name": r2["east"], - "ipv4": { - "address": [{ - "ip": R2_R3_R2, - "prefix-length": PREFIX_24 - }], - "forwarding": True - } - }] - } - }}) - - with test.step(f"Configure R3 with {tunnel} tunnel to R1"): - # R3: Exit point, west facing R2, east facing PC, tunnel to R1 - r3.put_config_dicts({"ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": r3["west"], - "ipv4": { - "address": [{ - "ip": R2_R3_R3, - "prefix-length": PREFIX_24 - }], - "forwarding": True - } - }, { - "name": r3["east"], - "ipv4": { - "address": [{ - "ip": PC_EAST_R3, - "prefix-length": PREFIX_24 - }], - "forwarding": True - } - }, { - "name": f"{tunnel}0", - "type": f"infix-if-type:{tunnel}", - "ipv4": { - "address": [{ - "ip": TUNNEL_R3, - "prefix-length": PREFIX_30 - }], - "forwarding": True - }, - CONTAINER_TYPE: container_r3 - }] - } - }, "ietf-routing": { - "routing": { - "control-plane-protocols": { - "control-plane-protocol": [{ - "type": "infix-routing:static", - "name": "default", - "static-routes": { - "ipv4": { - "route": [{ - "destination-prefix": R1_R2_NET, - "next-hop": { - "next-hop-address": R2_R3_R2 - } - }, { - "destination-prefix": PC_WEST_NET, - "next-hop": { - "next-hop-address": TUNNEL_R1 - } - }] + }, "ietf-routing": { + "routing": { + "control-plane-protocols": { + "control-plane-protocol": [{ + "type": "infix-routing:static", + "name": "default", + "static-routes": { + "ipv4": { + "route": [{ + "destination-prefix": R2_R3_NET, + "next-hop": { + "next-hop-address": R1_R2_R2 + } + }, { + "destination-prefix": PC_EAST_NET, + "next-hop": { + "next-hop-address": TUNNEL_R3 + } + }] + } } + }] + } + } + }}), + # R2: Intermediate router, just forwards packets between west and east + lambda: r2.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": r2["west"], + "ipv4": { + "address": [{ + "ip": R1_R2_R2, + "prefix-length": PREFIX_24 + }], + "forwarding": True + } + }, { + "name": r2["east"], + "ipv4": { + "address": [{ + "ip": R2_R3_R2, + "prefix-length": PREFIX_24 + }], + "forwarding": True + } + }] + } + }}), + # R3: Exit point, west facing R2, east facing PC, tunnel to R1 + lambda: r3.put_config_dicts({"ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": r3["west"], + "ipv4": { + "address": [{ + "ip": R2_R3_R3, + "prefix-length": PREFIX_24 + }], + "forwarding": True + } + }, { + "name": r3["east"], + "ipv4": { + "address": [{ + "ip": PC_EAST_R3, + "prefix-length": PREFIX_24 + }], + "forwarding": True } + }, { + "name": f"{tunnel}0", + "type": f"infix-if-type:{tunnel}", + "ipv4": { + "address": [{ + "ip": TUNNEL_R3, + "prefix-length": PREFIX_30 + }], + "forwarding": True + }, + CONTAINER_TYPE: container_r3 }] } - } - }}) + }, "ietf-routing": { + "routing": { + "control-plane-protocols": { + "control-plane-protocol": [{ + "type": "infix-routing:static", + "name": "default", + "static-routes": { + "ipv4": { + "route": [{ + "destination-prefix": R1_R2_NET, + "next-hop": { + "next-hop-address": R2_R3_R2 + } + }, { + "destination-prefix": PC_WEST_NET, + "next-hop": { + "next-hop-address": TUNNEL_R1 + } + }] + } + } + }] + } + } + }}), + ) with test.step("Send ping from PC:west to PC:east with low TTL"): _, pc_east = env.ltop.xlate("PC", "east") diff --git a/test/case/interfaces/tunnel_ttl/vxlan.adoc b/test/case/interfaces/tunnel_ttl/vxlan.adoc index ca2f5a6f8..44626fb97 100644 --- a/test/case/interfaces/tunnel_ttl/vxlan.adoc +++ b/test/case/interfaces/tunnel_ttl/vxlan.adoc @@ -23,9 +23,7 @@ image::topology.svg[VXLAN Tunnel TTL Verification topology, align=center, scaled ==== Sequence . Set up topology and attach to target DUTs -. Configure R1 with vxlan tunnel to R3 -. Configure R2 as intermediate router (underlay forwarding) -. Configure R3 with vxlan tunnel to R1 +. Configure vxlan tunnel from R1 to R3, with R2 as intermediate router . Send ping from PC:west to PC:east with low TTL . Verify packets arrived at PC:east diff --git a/test/case/interfaces/wifi_ap_multi_station/test.adoc b/test/case/interfaces/wifi_ap_multi_station/test.adoc index 5c0f1706e..4bc8ca085 100644 --- a/test/case/interfaces/wifi_ap_multi_station/test.adoc +++ b/test/case/interfaces/wifi_ap_multi_station/test.adoc @@ -38,7 +38,7 @@ image::topology.svg[WiFi Access Point serving three Stations topology, align=cen . Set up topology and attach to the ap and three stations . Configure the ap as an Access Point on radio0 -. Configure the station on radio0 +. Configure the stations on radio0 . Verify the station associates to the ap over the wifi link . Verify the station's wifi0 operational status is up . Verify the station leases an address from the ap over wifi diff --git a/test/case/interfaces/wifi_ap_multi_station/test.py b/test/case/interfaces/wifi_ap_multi_station/test.py index 61e0ff839..6d2bb6e88 100755 --- a/test/case/interfaces/wifi_ap_multi_station/test.py +++ b/test/case/interfaces/wifi_ap_multi_station/test.py @@ -96,9 +96,8 @@ def leased(dut): }]}}, }) - for name, mac, dut in stations: - with test.step("Configure the station on radio0"): - print(f"Configuring {name}") + with test.step("Configure the stations on radio0"): + def configure_station(mac, dut): dut.put_config_dicts({ "ietf-hardware": {"hardware": {"component": [wifi.radio("radio0")]}}, "ietf-keystore": wifi.keystore({"wifi": PSK}), @@ -113,6 +112,9 @@ def leased(dut): ]}}, }) + parallel(*[lambda mac=mac, dut=dut: configure_station(mac, dut) + for _name, mac, dut in stations]) + for name, _mac, dut in stations: with test.step("Verify the station associates to the ap over the wifi link"): print(f"Verifying {name}") diff --git a/test/case/interfaces/wifi_ap_station_2dut/test.adoc b/test/case/interfaces/wifi_ap_station_2dut/test.adoc index 85e77f88b..f7b300e94 100644 --- a/test/case/interfaces/wifi_ap_station_2dut/test.adoc +++ b/test/case/interfaces/wifi_ap_station_2dut/test.adoc @@ -34,8 +34,7 @@ image::topology.svg[WiFi AP and Station Association across two DUTs topology, al ==== Sequence . Set up topology and attach to the ap and the station -. Configure the ap as an Access Point on radio0 -. Configure the station on radio0 +. Configure the ap as an Access Point and the station on radio0 . Verify the station associates to the ap over the wifi link . Verify the station's wifi0 operational status is up . Verify the station leases its address from the ap over wifi diff --git a/test/case/interfaces/wifi_ap_station_2dut/test.py b/test/case/interfaces/wifi_ap_station_2dut/test.py index b216a92a1..8a596f501 100755 --- a/test/case/interfaces/wifi_ap_station_2dut/test.py +++ b/test/case/interfaces/wifi_ap_station_2dut/test.py @@ -50,43 +50,43 @@ ) wifi.skip_unless_supported(test, ap, station) - with test.step("Configure the ap as an Access Point on radio0"): - ap.put_config_dicts({ - "ietf-hardware": {"hardware": {"component": [ - wifi.radio("radio0", band="2.4GHz", channel=1)]}}, - "ietf-keystore": wifi.keystore({"wifi": PSK}), - "ietf-interfaces": {"interfaces": {"interface": [ - # hwsim defaults every radio0 to 02:00:00:00:00:00, so the AP - # and the station would otherwise share a MAC -- give each a - # unique address. - wifi.iface("wifi0", "02:00:00:00:00:01", { - "radio": "radio0", - "access-point": { - "ssid": SSID, - "security": {"mode": "wpa2-wpa3-personal", "secret": "wifi"}, - }, - }, ipv4={"address": [{"ip": AP_IP, "prefix-length": 24}]}), - ]}}, - "infix-dhcp-server": {"dhcp-server": {"subnet": [{ - "subnet": SUBNET, - "pool": {"start-address": LEASE, "end-address": LEASE}, - }]}}, - }) - - with test.step("Configure the station on radio0"): - station.put_config_dicts({ - "ietf-hardware": {"hardware": {"component": [wifi.radio("radio0")]}}, - "ietf-keystore": wifi.keystore({"wifi": PSK}), - "ietf-interfaces": {"interfaces": {"interface": [ - wifi.iface("wifi0", "02:00:00:00:00:02", { - "radio": "radio0", - "station": { - "ssid": SSID, - "security": {"mode": "auto", "secret": "wifi"}, - }, - }, ipv4={"infix-dhcp-client:dhcp": {}}), - ]}}, - }) + with test.step("Configure the ap as an Access Point and the station on radio0"): + parallel( + lambda: ap.put_config_dicts({ + "ietf-hardware": {"hardware": {"component": [ + wifi.radio("radio0", band="2.4GHz", channel=1)]}}, + "ietf-keystore": wifi.keystore({"wifi": PSK}), + "ietf-interfaces": {"interfaces": {"interface": [ + # hwsim defaults every radio0 to 02:00:00:00:00:00, so the AP + # and the station would otherwise share a MAC -- give each a + # unique address. + wifi.iface("wifi0", "02:00:00:00:00:01", { + "radio": "radio0", + "access-point": { + "ssid": SSID, + "security": {"mode": "wpa2-wpa3-personal", "secret": "wifi"}, + }, + }, ipv4={"address": [{"ip": AP_IP, "prefix-length": 24}]}), + ]}}, + "infix-dhcp-server": {"dhcp-server": {"subnet": [{ + "subnet": SUBNET, + "pool": {"start-address": LEASE, "end-address": LEASE}, + }]}}, + }), + lambda: station.put_config_dicts({ + "ietf-hardware": {"hardware": {"component": [wifi.radio("radio0")]}}, + "ietf-keystore": wifi.keystore({"wifi": PSK}), + "ietf-interfaces": {"interfaces": {"interface": [ + wifi.iface("wifi0", "02:00:00:00:00:02", { + "radio": "radio0", + "station": { + "ssid": SSID, + "security": {"mode": "auto", "secret": "wifi"}, + }, + }, ipv4={"infix-dhcp-client:dhcp": {}}), + ]}}, + }), + ) with test.step("Verify the station associates to the ap over the wifi link"): until(lambda: wifi.associated(station, SSID), attempts=60, interval=2) diff --git a/test/case/interfaces/wifi_band_steering/test.adoc b/test/case/interfaces/wifi_band_steering/test.adoc index 20d45f0b5..af7edd2dd 100644 --- a/test/case/interfaces/wifi_band_steering/test.adoc +++ b/test/case/interfaces/wifi_band_steering/test.adoc @@ -41,8 +41,7 @@ image::topology.svg[WiFi Band Steering across a dual-band Access Point topology, ==== Sequence . Set up topology and attach to the ap and the client -. Configure the dual-band AP: one BSS on 2.4GHz, one on 5GHz -. Configure the client with a single dual-band station radio +. Configure the dual-band AP and the client with a single dual-band station radio . Verify the client associates to the 'campus' SSID . Verify band steering put the client on the 5GHz BSS . Verify the client leases an address over 5GHz diff --git a/test/case/interfaces/wifi_band_steering/test.py b/test/case/interfaces/wifi_band_steering/test.py index 6b9f564b6..3eab7d0f5 100755 --- a/test/case/interfaces/wifi_band_steering/test.py +++ b/test/case/interfaces/wifi_band_steering/test.py @@ -78,45 +78,45 @@ def ap_bss(name, radio_name, bssid): ) wifi.skip_unless_supported(test, ap, client) - with test.step("Configure the dual-band AP: one BSS on 2.4GHz, one on 5GHz"): + with test.step("Configure the dual-band AP and the client with a single dual-band station radio"): # radio2 and radio3 are dut1's two extra radios, both wired to the # dedicated band-steering cell (cell2) in test/virt/quad. - ap.put_config_dicts({ - "ietf-hardware": {"hardware": {"component": [ - wifi.radio("radio2", band="2.4GHz", channel=1), - wifi.radio("radio3", band="5GHz", channel=36), - ]}}, - "ietf-keystore": wifi.keystore({"wifi": PSK}), - "ietf-interfaces": {"interfaces": {"interface": [ - {"name": "br0", "type": "infix-if-type:bridge", "enabled": True, - "ietf-ip:ipv4": {"address": [ - {"ip": AP_IP, "prefix-length": 24}]}}, - ap_bss("wifi0", "radio2", AP_BSSID_24), - ap_bss("wifi1", "radio3", AP_BSSID_5), - ]}}, - "infix-dhcp-server": {"dhcp-server": {"subnet": [{ - "subnet": SUBNET, - "pool": {"start-address": POOL_START, "end-address": POOL_END}, - }]}}, - }) - - with test.step("Configure the client with a single dual-band station radio"): - # radio2 is the client DUT's extra radio on the band-steering cell - # (cell2). No band/channel pinned: the one radio scans both bands and - # lets band steering decide where it lands. - client.put_config_dicts({ - "ietf-hardware": {"hardware": {"component": [wifi.radio("radio2")]}}, - "ietf-keystore": wifi.keystore({"wifi": PSK}), - "ietf-interfaces": {"interfaces": {"interface": [ - wifi.iface("wifi0", CLIENT_MAC, { - "radio": "radio2", - "station": { - "ssid": SSID, - "security": {"mode": "auto", "secret": "wifi"}, - }, - }, ipv4={"infix-dhcp-client:dhcp": {}}), - ]}}, - }) + parallel( + lambda: ap.put_config_dicts({ + "ietf-hardware": {"hardware": {"component": [ + wifi.radio("radio2", band="2.4GHz", channel=1), + wifi.radio("radio3", band="5GHz", channel=36), + ]}}, + "ietf-keystore": wifi.keystore({"wifi": PSK}), + "ietf-interfaces": {"interfaces": {"interface": [ + {"name": "br0", "type": "infix-if-type:bridge", "enabled": True, + "ietf-ip:ipv4": {"address": [ + {"ip": AP_IP, "prefix-length": 24}]}}, + ap_bss("wifi0", "radio2", AP_BSSID_24), + ap_bss("wifi1", "radio3", AP_BSSID_5), + ]}}, + "infix-dhcp-server": {"dhcp-server": {"subnet": [{ + "subnet": SUBNET, + "pool": {"start-address": POOL_START, "end-address": POOL_END}, + }]}}, + }), + # radio2 is the client DUT's extra radio on the band-steering cell + # (cell2). No band/channel pinned: the one radio scans both bands and + # lets band steering decide where it lands. + lambda: client.put_config_dicts({ + "ietf-hardware": {"hardware": {"component": [wifi.radio("radio2")]}}, + "ietf-keystore": wifi.keystore({"wifi": PSK}), + "ietf-interfaces": {"interfaces": {"interface": [ + wifi.iface("wifi0", CLIENT_MAC, { + "radio": "radio2", + "station": { + "ssid": SSID, + "security": {"mode": "auto", "secret": "wifi"}, + }, + }, ipv4={"infix-dhcp-client:dhcp": {}}), + ]}}, + }), + ) with test.step("Verify the client associates to the 'campus' SSID"): until(lambda: wifi.associated(client, SSID), attempts=60, interval=2) diff --git a/test/case/interfaces/wifi_mesh_roaming/test.py b/test/case/interfaces/wifi_mesh_roaming/test.py index 0b1257ecc..2e959aa5d 100755 --- a/test/case/interfaces/wifi_mesh_roaming/test.py +++ b/test/case/interfaces/wifi_mesh_roaming/test.py @@ -123,9 +123,10 @@ def gw_config(mesh_mac, ap_mac, uplink=None): with test.step("Configure gw1, gw2, gw3 as mesh nodes with a roaming AP"): _, gw1_uplink = env.ltop.xlate("gw1", "uplink") - for name, dut, mesh_mac, ap_mac in gws: - dut.put_config_dicts(gw_config(mesh_mac, ap_mac, - uplink=gw1_uplink if name == "gw1" else None)) + parallel(*[lambda name=name, dut=dut, mesh_mac=mesh_mac, ap_mac=ap_mac: + dut.put_config_dicts(gw_config(mesh_mac, ap_mac, + uplink=gw1_uplink if name == "gw1" else None)) + for name, dut, mesh_mac, ap_mac in gws]) with test.step("Configure the client as a station for the 'campus' SSID"): # The client joins the gw APs, which run on radio1 (2.4GHz). In the diff --git a/test/case/interfaces/wireguard_multipoint/test.py b/test/case/interfaces/wireguard_multipoint/test.py index c790ae520..0562fee58 100755 --- a/test/case/interfaces/wireguard_multipoint/test.py +++ b/test/case/interfaces/wireguard_multipoint/test.py @@ -464,15 +464,15 @@ def configure_client2(dut): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - server = env.attach("server", "mgmt") - client1 = env.attach("client1", "mgmt") - client2 = env.attach("client2", "mgmt") + server, client1, client2 = util.parallel(lambda: env.attach("server", "mgmt"), + lambda: env.attach("client1", "mgmt"), + lambda: env.attach("client2", "mgmt")) _, hclient1 = env.ltop.xlate("host", "data1") _, hserver = env.ltop.xlate("host", "data2") with test.step("Configure server, client1 and client2"): - util.parallel(configure_server(server), configure_client1(client1), configure_client2(client2)) + util.parallel(lambda: configure_server(server), lambda: configure_client1(client1), lambda: configure_client2(client2)) with infamy.IsolatedMacVlan(hserver) as nsserver, infamy.IsolatedMacVlan(hclient1) as nsclient1: nsserver.addip("192.168.0.1") @@ -485,25 +485,25 @@ def configure_client2(dut): nsclient1.addroute("default", "2001:db8:3c4d:01::2", proto="ipv6") with test.step("Verify IPv4 connectivity with ping 10.0.0.1, 10.0.0.2 and 10.0.0.3 from host:data1"): - util.parallel(nsclient1.must_reach("10.0.0.1"), - nsclient1.must_reach("10.0.0.2"), - nsclient1.must_reach("10.0.0.3")) + util.parallel(lambda: nsclient1.must_reach("10.0.0.1"), + lambda: nsclient1.must_reach("10.0.0.2"), + lambda: nsclient1.must_reach("10.0.0.3")) with test.step("Verify IPv4 connectivity with ping 10.0.0.1 and 10.0.0.2 from host:data2"): - util.parallel(nsserver.must_reach("10.0.0.1"), - nsserver.must_reach("10.0.0.2")) + util.parallel(lambda: nsserver.must_reach("10.0.0.1"), + lambda: nsserver.must_reach("10.0.0.2")) with test.step("Verify host:data2 can not ping 10.0.0.3"): nsserver.must_not_reach("10.0.0.3") # Not in allowed IPs with test.step("Verify IPv6 connectivity with ping fd00:0::1, fd00:0::2 and fd00:0::3 from host:data1"): - util.parallel(nsclient1.must_reach("fd00:0::1"), - nsclient1.must_reach("fd00:0::2"), - nsclient1.must_reach("fd00:0::3")) + util.parallel(lambda: nsclient1.must_reach("fd00:0::1"), + lambda: nsclient1.must_reach("fd00:0::2"), + lambda: nsclient1.must_reach("fd00:0::3")) with test.step("Verify IPv6 connectivity with ping fd00:0:1 and fd00:0:2 from host:data2"): - util.parallel(nsserver.must_reach("fd00:0::1"), - nsserver.must_reach("fd00:0::2")) + util.parallel(lambda: nsserver.must_reach("fd00:0::1"), + lambda: nsserver.must_reach("fd00:0::2")) with test.step("Verify host:data2 can not ping fd00:0::3"): nsserver.must_not_reach("fd00:0::3") # Not in allowed IPs diff --git a/test/case/interfaces/wireguard_p2p/test.py b/test/case/interfaces/wireguard_p2p/test.py index 33081e288..516a4a56e 100755 --- a/test/case/interfaces/wireguard_p2p/test.py +++ b/test/case/interfaces/wireguard_p2p/test.py @@ -43,11 +43,11 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - left = env.attach("left", "mgmt") - right = env.attach("right", "mgmt") + left, right = util.parallel(lambda: env.attach("left", "mgmt"), + lambda: env.attach("right", "mgmt")) with test.step("Configure WireGuard tunnel on DUTs"): - util.parallel(left.put_config_dicts({ + util.parallel(lambda: left.put_config_dicts({ "ietf-keystore": { "keystore": { "asymmetric-keys": { @@ -140,7 +140,7 @@ } } }), - right.put_config_dicts({ + lambda: right.put_config_dicts({ "ietf-keystore": { "keystore": { "asymmetric-keys": { diff --git a/test/case/interfaces/wireguard_roadwarrior/test.py b/test/case/interfaces/wireguard_roadwarrior/test.py index 4ed4b7e0d..232cfdcf1 100755 --- a/test/case/interfaces/wireguard_roadwarrior/test.py +++ b/test/case/interfaces/wireguard_roadwarrior/test.py @@ -317,10 +317,10 @@ def configure_client(client, client_num, private_key, public_key, server_pubkey) with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - server = env.attach("server", "mgmt") - router = env.attach("router", "mgmt") - client1 = env.attach("client1", "mgmt") - client2 = env.attach("client2", "mgmt") + server, router, client1, client2 = util.parallel(lambda: env.attach("server", "mgmt"), + lambda: env.attach("router", "mgmt"), + lambda: env.attach("client1", "mgmt"), + lambda: env.attach("client2", "mgmt")) _, hport_server = env.ltop.xlate("host", "data") _, hport_client1 = env.ltop.xlate("host", "data1") diff --git a/test/case/misc/start_from_startup/test.py b/test/case/misc/start_from_startup/test.py index 386886789..fb95924f2 100755 --- a/test/case/misc/start_from_startup/test.py +++ b/test/case/misc/start_from_startup/test.py @@ -1,7 +1,7 @@ #!/usr/bin/env python3 import infamy -from infamy.util import wait_boot +from infamy.util import parallel, wait_boot with infamy.Test() as test: with test.step("Initialize"): @@ -17,8 +17,8 @@ target.reboot() if not wait_boot(target, env): test.fail() - target = env.attach("target", "mgmt", test_reset=False) - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt", test_reset=False), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Verify user admin is now in wheel group"): if not tgtssh.runsh("grep wheel /etc/group | grep 'admin'"): diff --git a/test/case/misc/support_collect/test.py b/test/case/misc/support_collect/test.py index e1399288a..abb799314 100755 --- a/test/case/misc/support_collect/test.py +++ b/test/case/misc/support_collect/test.py @@ -12,13 +12,14 @@ import tarfile import tempfile import infamy +from infamy.util import parallel import infamy.ssh as ssh with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Check for GPG availability on target"): result = tgtssh.run("command -v gpg >/dev/null 2>&1", check=False) diff --git a/test/case/ntp/client_stratum_selection/test.py b/test/case/ntp/client_stratum_selection/test.py index f52be5461..42424d2f1 100755 --- a/test/case/ntp/client_stratum_selection/test.py +++ b/test/case/ntp/client_stratum_selection/test.py @@ -18,7 +18,7 @@ """ import infamy -from infamy import until +from infamy.util import parallel, until import infamy.ntp as ntp import infamy.ntp_server as ntp_server @@ -32,8 +32,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to devices"): env = infamy.Env() - srv2 = env.attach("srv2", "mgmt") - client = env.attach("client", "mgmt") + srv2, client = parallel(lambda: env.attach("srv2", "mgmt"), + lambda: env.attach("client", "mgmt")) _, swp1 = env.ltop.xlate("srv2", "swp1") _, swp2 = env.ltop.xlate("srv2", "swp2") diff --git a/test/case/ntp/server_client/test.adoc b/test/case/ntp/server_client/test.adoc index 0f271de6b..38a48f05b 100644 --- a/test/case/ntp/server_client/test.adoc +++ b/test/case/ntp/server_client/test.adoc @@ -19,8 +19,7 @@ image::topology.svg[NTP Server and Client Interoperability topology, align=cente ==== Sequence . Set up topology and attach to devices -. Configure NTP server using ietf-ntp model -. Configure NTP client using ietf-system:ntp model +. Configure NTP server using ietf-ntp model and NTP client using ietf-system:ntp model . Verify NTP server has received packets . Verify NTP client has synchronized diff --git a/test/case/ntp/server_client/test.py b/test/case/ntp/server_client/test.py index fd3de100b..bb7c68a74 100755 --- a/test/case/ntp/server_client/test.py +++ b/test/case/ntp/server_client/test.py @@ -11,80 +11,80 @@ """ import infamy -from infamy import until +from infamy.util import parallel, until import infamy.ntp as ntp with infamy.Test() as test: with test.step("Set up topology and attach to devices"): env = infamy.Env() - server = env.attach("server", "mgmt") - client = env.attach("client", "mgmt") + server, client = parallel(lambda: env.attach("server", "mgmt"), + lambda: env.attach("client", "mgmt")) _, server_data = env.ltop.xlate("server", "data") _, client_data = env.ltop.xlate("client", "data") - with test.step("Configure NTP server using ietf-ntp model"): - server.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": server_data, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "192.168.3.1", - "prefix-length": 24 - }] + with test.step("Configure NTP server using ietf-ntp model and NTP client using ietf-system:ntp model"): + parallel( + lambda: server.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": server_data, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "192.168.3.1", + "prefix-length": 24 + }] + } + }] + } + }, + "ietf-ntp": { + "ntp": { + "refclock-master": { + "master-stratum": 8 + }, + "interfaces": { + "interface": [ + {"name": server_data} + ] } - }] + } } - }, - "ietf-ntp": { - "ntp": { - "refclock-master": { - "master-stratum": 8 - }, + }), + lambda: client.put_config_dicts({ + "ietf-interfaces": { "interfaces": { - "interface": [ - {"name": server_data} - ] + "interface": [{ + "name": client_data, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "192.168.3.2", + "prefix-length": 24 + }] + } + }] } - } - } - }) - - with test.step("Configure NTP client using ietf-system:ntp model"): - client.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client_data, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "192.168.3.2", - "prefix-length": 24 + }, + "ietf-system": { + "system": { + "ntp": { + "enabled": True, + "server": [{ + "name": "ntp-server", + "udp": { + "address": "192.168.3.1" + }, + "iburst": True }] } - }] - } - }, - "ietf-system": { - "system": { - "ntp": { - "enabled": True, - "server": [{ - "name": "ntp-server", - "udp": { - "address": "192.168.3.1" - }, - "iburst": True - }] } } - } - }) + }), + ) with test.step("Verify NTP server has received packets"): until(lambda: ntp.server_has_received_packets(server), attempts=30) diff --git a/test/case/ntp/server_mode_peer/test.py b/test/case/ntp/server_mode_peer/test.py index 68f024487..4a6f789a7 100755 --- a/test/case/ntp/server_mode_peer/test.py +++ b/test/case/ntp/server_mode_peer/test.py @@ -20,7 +20,7 @@ """ import infamy -from infamy import until +from infamy.util import parallel, until import infamy.ntp as ntp @@ -79,8 +79,8 @@ def has_selected_peer(peers): with infamy.Test() as test: with test.step("Set up topology and attach to devices"): env = infamy.Env() - peer1 = env.attach("peer1", "mgmt") - peer2 = env.attach("peer2", "mgmt") + peer1, peer2 = parallel(lambda: env.attach("peer1", "mgmt"), + lambda: env.attach("peer2", "mgmt")) _, if1 = env.ltop.xlate("peer1", "data") _, if2 = env.ltop.xlate("peer2", "data") diff --git a/test/case/ntp/server_mode_server/test.adoc b/test/case/ntp/server_mode_server/test.adoc index 0169a2e82..fcaf3f23a 100644 --- a/test/case/ntp/server_mode_server/test.adoc +++ b/test/case/ntp/server_mode_server/test.adoc @@ -23,8 +23,7 @@ image::topology.svg[NTP Server Mode topology, align=center, scaledwidth=75%] ==== Sequence . Set up topology and attach to devices -. Configure upstream NTP server with local reference clock -. Configure downstream NTP server syncing from upstream +. Configure upstream NTP server with local reference clock and downstream NTP server syncing from upstream . Verify network connectivity with upstream NTP server . Query time from upstream NTP server . Verify upstream NTP server statistics diff --git a/test/case/ntp/server_mode_server/test.py b/test/case/ntp/server_mode_server/test.py index 46ccbe2c6..5d201470d 100755 --- a/test/case/ntp/server_mode_server/test.py +++ b/test/case/ntp/server_mode_server/test.py @@ -16,15 +16,15 @@ """ import infamy -from infamy import until +from infamy.util import parallel, until import infamy.ntp as ntp with infamy.Test() as test: with test.step("Set up topology and attach to devices"): env = infamy.Env() - upstream = env.attach("upstream", "mgmt") - downstream = env.attach("downstream", "mgmt") + upstream, downstream = parallel(lambda: env.attach("upstream", "mgmt"), + lambda: env.attach("downstream", "mgmt")) # Get interface names for each device _, upstream_data1 = env.ltop.xlate("upstream", "data1") @@ -35,78 +35,78 @@ _, downstream_conn = env.ltop.xlate("downstream", "conn") _, hport2 = env.ltop.xlate("host", "data2") - with test.step("Configure upstream NTP server with local reference clock"): - upstream.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": upstream_data1, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "192.168.1.1", - "prefix-length": 24 - }] - } - }, { - "name": upstream_conn, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "192.168.3.1", - "prefix-length": 24 - }] + with test.step("Configure upstream NTP server with local reference clock and downstream NTP server syncing from upstream"): + parallel( + lambda: upstream.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": upstream_data1, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "192.168.1.1", + "prefix-length": 24 + }] + } + }, { + "name": upstream_conn, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "192.168.3.1", + "prefix-length": 24 + }] + } + }] + } + }, + "ietf-ntp": { + "ntp": { + "refclock-master": { + "master-stratum": 8 } - }] - } - }, - "ietf-ntp": { - "ntp": { - "refclock-master": { - "master-stratum": 8 } } - } - }) - - with test.step("Configure downstream NTP server syncing from upstream"): - downstream.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": downstream_data2, - "enabled": True, - "ipv4": { + }), + lambda: downstream.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": downstream_data2, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "192.168.2.1", + "prefix-length": 24 + }] + } + }, { + "name": downstream_conn, + "enabled": True, + "ipv4": { "address": [{ - "ip": "192.168.2.1", + "ip": "192.168.3.2", "prefix-length": 24 }] - } - }, { - "name": downstream_conn, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "192.168.3.2", - "prefix-length": 24 + } }] + } + }, + "ietf-ntp": { + "ntp": { + "unicast-configuration": [{ + "address": "192.168.3.1", + "type": "uc-server", + "iburst": True + }], + "refclock-master": { + "master-stratum": 10 } - }] - } - }, - "ietf-ntp": { - "ntp": { - "unicast-configuration": [{ - "address": "192.168.3.1", - "type": "uc-server", - "iburst": True - }], - "refclock-master": { - "master-stratum": 10 } } - } - }) + }), + ) with infamy.IsolatedMacVlan(hport1) as ns1: ns1.addip("192.168.1.2") diff --git a/test/case/ptp/basic/test.py b/test/case/ptp/basic/test.py index 6d8b50b41..a42bab643 100755 --- a/test/case/ptp/basic/test.py +++ b/test/case/ptp/basic/test.py @@ -14,8 +14,7 @@ import infamy import infamy.ptp as ptp -from infamy import until -from infamy.util import parallel +from infamy.util import parallel, until class ArgumentParser(infamy.ArgumentParser): @@ -82,20 +81,22 @@ def configure_oc(iface, priority1, client_only, profile, ip=None): arg = ArgumentParser() env = infamy.Env(args=arg) profile = env.args.profile - gm = env.attach("gm", "mgmt") - receiver = env.attach("receiver", "mgmt") + gm, receiver = parallel(lambda: env.attach("gm", "mgmt"), + lambda: env.attach("receiver", "mgmt")) _, gm_iface = env.ltop.xlate("gm", "data") _, receiver_iface = env.ltop.xlate("receiver", "data") threshold_ns = env.args.threshold_ns or ptp.default_threshold(env, "receiver") with test.step(f"Configure grandmaster (OC, {profile}, priority1=1) and time receiver ({profile}, priority1=128, client-only)"): - gm.put_config_dicts(configure_oc(gm_iface, priority1=1, - client_only=False, profile=profile, - ip="192.168.100.1")) - receiver.put_config_dicts(configure_oc(receiver_iface, priority1=128, - client_only=True, profile=profile, - ip="192.168.100.2")) + parallel( + lambda: gm.put_config_dicts(configure_oc(gm_iface, priority1=1, + client_only=False, profile=profile, + ip="192.168.100.1")), + lambda: receiver.put_config_dicts(configure_oc(receiver_iface, priority1=128, + client_only=True, profile=profile, + ip="192.168.100.2")), + ) with test.step("Wait for grandmaster and time receiver ports to reach active states"): parallel(lambda: until(lambda: ptp.is_time_transmitter(gm), attempts=60), diff --git a/test/case/ptp/bmca/test.py b/test/case/ptp/bmca/test.py index 615ee60f4..d952fa7f5 100755 --- a/test/case/ptp/bmca/test.py +++ b/test/case/ptp/bmca/test.py @@ -23,8 +23,7 @@ import infamy import infamy.ptp as ptp -from infamy import until -from infamy.util import parallel +from infamy.util import parallel, until class ArgumentParser(infamy.ArgumentParser): @@ -83,17 +82,19 @@ def configure_oc(iface, priority1, profile, ip=None): arg = ArgumentParser() env = infamy.Env(args=arg) profile = env.args.profile - alpha = env.attach("alpha", "mgmt") - beta = env.attach("beta", "mgmt") + alpha, beta = parallel(lambda: env.attach("alpha", "mgmt"), + lambda: env.attach("beta", "mgmt")) _, if_alpha = env.ltop.xlate("alpha", "data") _, if_beta = env.ltop.xlate("beta", "data") with test.step(f"Configure both DUTs ({profile}); alpha has lower priority1"): - alpha.put_config_dicts(configure_oc(if_alpha, priority1=1, - profile=profile, ip="192.168.100.1")) - beta.put_config_dicts(configure_oc(if_beta, priority1=128, - profile=profile, ip="192.168.100.2")) + parallel( + lambda: alpha.put_config_dicts(configure_oc(if_alpha, priority1=1, + profile=profile, ip="192.168.100.1")), + lambda: beta.put_config_dicts(configure_oc(if_beta, priority1=128, + profile=profile, ip="192.168.100.2")), + ) with test.step("Verify initial election: alpha is grandmaster, beta is time receiver"): parallel(lambda: until(lambda: ptp.is_own_gm(alpha), attempts=60), diff --git a/test/case/ptp/boundary_clock/test.py b/test/case/ptp/boundary_clock/test.py index 552051a3e..ce738d637 100755 --- a/test/case/ptp/boundary_clock/test.py +++ b/test/case/ptp/boundary_clock/test.py @@ -21,8 +21,8 @@ """ import infamy +from infamy.util import parallel, until import infamy.ptp as ptp -from infamy import until class ArgumentParser(infamy.ArgumentParser): @@ -135,9 +135,9 @@ def configure_bc(uplink_iface, dnlink_iface, profile, arg = ArgumentParser() env = infamy.Env(args=arg) profile = env.args.profile - gm = env.attach("gm", "mgmt") - bc = env.attach("bc", "mgmt") - receiver = env.attach("receiver", "mgmt") + gm, bc, receiver = parallel(lambda: env.attach("gm", "mgmt"), + lambda: env.attach("bc", "mgmt"), + lambda: env.attach("receiver", "mgmt")) _, gm_iface = env.ltop.xlate("gm", "data") _, bc_uplink = env.ltop.xlate("bc", "uplink") @@ -146,11 +146,13 @@ def configure_bc(uplink_iface, dnlink_iface, profile, threshold_ns = env.args.threshold_ns or ptp.default_threshold(env, "receiver", hops=2) with test.step(f"Configure grandmaster (OC, {profile}, priority1=1) and boundary clock (BC, {profile}, priority1=64, two ports)"): - gm.put_config_dicts(configure_oc(gm_iface, priority1=1, - profile=profile, ip="192.168.100.1")) - bc.put_config_dicts(configure_bc(bc_uplink, bc_dnlink, profile=profile, - uplink_ip="192.168.100.2", - dnlink_ip="192.168.101.1")) + parallel( + lambda: gm.put_config_dicts(configure_oc(gm_iface, priority1=1, + profile=profile, ip="192.168.100.1")), + lambda: bc.put_config_dicts(configure_bc(bc_uplink, bc_dnlink, profile=profile, + uplink_ip="192.168.100.2", + dnlink_ip="192.168.101.1")), + ) with test.step("Wait for BC uplink port to become time-receiver"): until(lambda: ptp.is_time_receiver(bc, port_idx=1), attempts=60) diff --git a/test/case/ptp/port_recovery/test.py b/test/case/ptp/port_recovery/test.py index 49f820ad6..364b9adfc 100755 --- a/test/case/ptp/port_recovery/test.py +++ b/test/case/ptp/port_recovery/test.py @@ -13,8 +13,8 @@ """ import infamy +from infamy.util import parallel, until import infamy.ptp as ptp -from infamy import until def configure_oc(iface, ip, priority1, client_only, dm="e2e"): @@ -85,18 +85,20 @@ def __init__(self): with test.step("Set up topology and attach to DUTs"): arg = ArgumentParser() env = infamy.Env(args=arg) - gm = env.attach("gm", "mgmt") - receiver = env.attach("receiver", "mgmt") + gm, receiver = parallel(lambda: env.attach("gm", "mgmt"), + lambda: env.attach("receiver", "mgmt")) _, gm_iface = env.ltop.xlate("gm", "data") _, receiver_iface = env.ltop.xlate("receiver", "data") threshold_ns = env.args.threshold_ns or ptp.default_threshold(env, "receiver") with test.step("Configure grandmaster (priority1=1) and time receiver (client-only)"): - gm.put_config_dicts(configure_oc(gm_iface, "192.168.100.1", - priority1=1, client_only=False)) - receiver.put_config_dicts(configure_oc(receiver_iface, "192.168.100.2", - priority1=128, client_only=True)) + parallel( + lambda: gm.put_config_dicts(configure_oc(gm_iface, "192.168.100.1", + priority1=1, client_only=False)), + lambda: receiver.put_config_dicts(configure_oc(receiver_iface, "192.168.100.2", + priority1=128, client_only=True)), + ) with test.step("Wait for initial convergence"): until(lambda: ptp.is_time_receiver(receiver) and ptp.has_converged(receiver, threshold_ns), diff --git a/test/case/ptp/servo/test.py b/test/case/ptp/servo/test.py index 27576fb2d..bd60fddf2 100755 --- a/test/case/ptp/servo/test.py +++ b/test/case/ptp/servo/test.py @@ -27,8 +27,7 @@ import infamy import infamy.ptp as ptp -from infamy import until -from infamy.util import parallel +from infamy.util import parallel, until STEP_SEC = 10 @@ -104,18 +103,20 @@ def step_clock(ssh, iface, seconds): with test.step("Set up topology and attach to DUTs"): arg = ArgumentParser() env = infamy.Env(args=arg) - gm = env.attach("gm", "mgmt") - receiver = env.attach("receiver", "mgmt") + gm, receiver = parallel(lambda: env.attach("gm", "mgmt"), + lambda: env.attach("receiver", "mgmt")) _, gm_iface = env.ltop.xlate("gm", "data") _, receiver_iface = env.ltop.xlate("receiver", "data") threshold_ns = env.args.threshold_ns or ptp.default_threshold(env, "receiver") with test.step("Configure grandmaster (OC, IEEE 1588, priority1=1) and time receiver"): - gm.put_config_dicts(configure_oc(gm_iface, priority1=1, - client=False, ip="192.168.100.1")) - receiver.put_config_dicts(configure_oc(receiver_iface, priority1=128, - client=True, ip="192.168.100.2")) + parallel( + lambda: gm.put_config_dicts(configure_oc(gm_iface, priority1=1, + client=False, ip="192.168.100.1")), + lambda: receiver.put_config_dicts(configure_oc(receiver_iface, priority1=128, + client=True, ip="192.168.100.2")), + ) with test.step("Wait for grandmaster and time receiver ports to reach active states"): def gm_ready(): diff --git a/test/case/ptp/transparent_clock/e2e.adoc b/test/case/ptp/transparent_clock/e2e.adoc index 5346f9070..1ad6afbac 100644 --- a/test/case/ptp/transparent_clock/e2e.adoc +++ b/test/case/ptp/transparent_clock/e2e.adoc @@ -32,9 +32,7 @@ image::topology.svg[PTP transparent clock (E2E) topology, align=center, scaledwi ==== Sequence . Set up topology and attach to DUTs -. Configure grandmaster (OC, priority1=1, {dm}) -. Configure transparent clock ({dm}-tc, {profile}) -. Configure time receiver (OC, priority1=128, client-only) +. Configure grandmaster (OC, priority1=1, {dm}), transparent clock ({dm}-tc, {profile}) and time receiver (OC, priority1=128, client-only) . Wait for grandmaster port to become time-transmitter . Wait for time receiver to reach time-receiver state . Verify time receiver steps-removed equals 1 diff --git a/test/case/ptp/transparent_clock/ieee802dot1as.adoc b/test/case/ptp/transparent_clock/ieee802dot1as.adoc index 68d64b802..bf05a993c 100644 --- a/test/case/ptp/transparent_clock/ieee802dot1as.adoc +++ b/test/case/ptp/transparent_clock/ieee802dot1as.adoc @@ -32,9 +32,7 @@ image::topology.svg[PTP transparent clock (IEEE 802.1AS) topology, align=center, ==== Sequence . Set up topology and attach to DUTs -. Configure grandmaster (OC, priority1=1, {dm}) -. Configure transparent clock ({dm}-tc, ieee802-dot1as) -. Configure time receiver (OC, priority1=128, client-only) +. Configure grandmaster (OC, priority1=1, {dm}), transparent clock ({dm}-tc, ieee802-dot1as) and time receiver (OC, priority1=128, client-only) . Wait for grandmaster port to become time-transmitter . Wait for time receiver to reach time-receiver state . Verify time receiver steps-removed equals 1 diff --git a/test/case/ptp/transparent_clock/p2p.adoc b/test/case/ptp/transparent_clock/p2p.adoc index cacdb4499..dd463d7dd 100644 --- a/test/case/ptp/transparent_clock/p2p.adoc +++ b/test/case/ptp/transparent_clock/p2p.adoc @@ -32,9 +32,7 @@ image::topology.svg[PTP transparent clock (P2P) topology, align=center, scaledwi ==== Sequence . Set up topology and attach to DUTs -. Configure grandmaster (OC, priority1=1, {dm}) -. Configure transparent clock ({dm}-tc, {profile}) -. Configure time receiver (OC, priority1=128, client-only) +. Configure grandmaster (OC, priority1=1, {dm}), transparent clock ({dm}-tc, {profile}) and time receiver (OC, priority1=128, client-only) . Wait for grandmaster port to become time-transmitter . Wait for time receiver to reach time-receiver state . Verify time receiver steps-removed equals 1 diff --git a/test/case/ptp/transparent_clock/test.py b/test/case/ptp/transparent_clock/test.py index f309e89db..75cddd0ef 100755 --- a/test/case/ptp/transparent_clock/test.py +++ b/test/case/ptp/transparent_clock/test.py @@ -24,8 +24,8 @@ """ import infamy +from infamy.util import parallel, until import infamy.ptp as ptp -from infamy import until class ArgumentParser(infamy.ArgumentParser): @@ -136,9 +136,9 @@ def configure_tc(uplink_iface, dnlink_iface, profile, dm="e2e", env = infamy.Env(args=arg) profile = env.args.profile dm = "p2p" if profile == "ieee802-dot1as" else env.args.delay_mechanism - gm = env.attach("gm", "mgmt") - tc = env.attach("tc", "mgmt") - receiver = env.attach("receiver", "mgmt") + gm, tc, receiver = parallel(lambda: env.attach("gm", "mgmt"), + lambda: env.attach("tc", "mgmt"), + lambda: env.attach("receiver", "mgmt")) gm_iface = gm["data"] tc_uplink = tc["uplink"] @@ -146,19 +146,17 @@ def configure_tc(uplink_iface, dnlink_iface, profile, dm="e2e", receiver_iface = receiver["data"] threshold_ns = env.args.threshold_ns or ptp.default_threshold(env, "tc") - with test.step(f"Configure grandmaster (OC, priority1=1, {dm})"): - gm.put_config_dicts(configure_oc(gm_iface, priority1=1, - profile=profile, ip="192.168.100.1", dm=dm)) - - with test.step(f"Configure transparent clock ({dm}-tc, {profile})"): - tc.put_config_dicts(configure_tc(tc_uplink, tc_dnlink, profile=profile, dm=dm, - uplink_ip="192.168.100.2", - dnlink_ip="192.168.101.1")) - - with test.step("Configure time receiver (OC, priority1=128, client-only)"): - receiver.put_config_dicts(configure_oc(receiver_iface, priority1=128, - profile=profile, client_only=True, - ip="192.168.101.2", dm=dm)) + with test.step(f"Configure grandmaster (OC, priority1=1, {dm}), transparent clock ({dm}-tc, {profile}) and time receiver (OC, priority1=128, client-only)"): + parallel( + lambda: gm.put_config_dicts(configure_oc(gm_iface, priority1=1, + profile=profile, ip="192.168.100.1", dm=dm)), + lambda: tc.put_config_dicts(configure_tc(tc_uplink, tc_dnlink, profile=profile, dm=dm, + uplink_ip="192.168.100.2", + dnlink_ip="192.168.101.1")), + lambda: receiver.put_config_dicts(configure_oc(receiver_iface, priority1=128, + profile=profile, client_only=True, + ip="192.168.101.2", dm=dm)), + ) with test.step("Wait for grandmaster port to become time-transmitter"): until(lambda: ptp.is_time_transmitter(gm), attempts=60) diff --git a/test/case/routing/ospf_basic/test.py b/test/case/routing/ospf_basic/test.py index 405abd531..eae9d04f0 100755 --- a/test/case/routing/ospf_basic/test.py +++ b/test/case/routing/ospf_basic/test.py @@ -198,9 +198,9 @@ def config_host(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - HOST = env.attach("HOST", "mgmt") + R1, R2, HOST = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("HOST", "mgmt")) with test.step("Configure targets"): _, R1data = env.ltop.xlate("R1", "data") @@ -209,9 +209,9 @@ def config_host(target, link): _, R2data = env.ltop.xlate("R2", "data") _, HOSTlink = env.ltop.xlate("HOST", "link") - parallel(config_target1(R1, R1data, R1link), - config_target2(R2, R2link, R2data), - config_host(HOST, HOSTlink)) + parallel(lambda: config_target1(R1, R1data, R1link), + lambda: config_target2(R2, R2link, R2data), + lambda: config_host(HOST, HOSTlink)) with test.step("Wait for OSPF routes"): until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32", proto="ietf-ospf:ospfv2"), attempts=200) until(lambda: route.ipv4_route_exist(R2, "192.168.100.1/32", proto="ietf-ospf:ospfv2"), attempts=200) diff --git a/test/case/routing/ospf_bfd/test.py b/test/case/routing/ospf_bfd/test.py index fc743a9a9..62dc655d3 100755 --- a/test/case/routing/ospf_bfd/test.py +++ b/test/case/routing/ospf_bfd/test.py @@ -105,8 +105,8 @@ def ifconfig(name, addr, plen): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Setup TPMR between R1fast and R2fast"): breaker = TPMR(env.ltop.xlate("PC", "R1fast")[1], diff --git a/test/case/routing/ospf_debug/test.py b/test/case/routing/ospf_debug/test.py index d61dbc7f6..8166235fd 100755 --- a/test/case/routing/ospf_debug/test.py +++ b/test/case/routing/ospf_debug/test.py @@ -220,9 +220,9 @@ def config_target2(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R1ssh = env.attach("R1", "mgmt", "ssh") - R2 = env.attach("R2", "mgmt") + R1, R1ssh, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R1", "mgmt", "ssh"), + lambda: env.attach("R2", "mgmt")) with test.step("Clean up old log files from previous test runs"): R1ssh.runsh("sudo rm -f /var/log/ospf-debug") @@ -231,8 +231,8 @@ def config_target2(target, link): _, R1link = env.ltop.xlate("R1", "link") _, R2link = env.ltop.xlate("R2", "link") - parallel(config_target1(R1, R1link, enable_debug=False), - config_target2(R2, R2link)) + parallel(lambda: config_target1(R1, R1link, enable_debug=False), + lambda: config_target2(R2, R2link)) with test.step("Wait for OSPF adjacency to form"): until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32", proto="ietf-ospf:ospfv2"), attempts=200) diff --git a/test/case/routing/ospf_default_route_advertise/test.py b/test/case/routing/ospf_default_route_advertise/test.py index 8cb055f9f..1767336fd 100755 --- a/test/case/routing/ospf_default_route_advertise/test.py +++ b/test/case/routing/ospf_default_route_advertise/test.py @@ -260,8 +260,8 @@ def set_redistribute_default_always(target): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Configure targets"): _, R1data = env.ltop.xlate("R1", "data") @@ -269,8 +269,8 @@ def set_redistribute_default_always(target): _, R2link = env.ltop.xlate("R2", "link") _, R1link= env.ltop.xlate("R1", "link") - parallel(config_target1(R1, R1data, R1link), - config_target2(R2, R2data, R2link)) + parallel(lambda: config_target1(R1, R1data, R1link), + lambda: config_target2(R2, R2data, R2link)) with test.step("Verify R2 has a default route and 192.168.100.1/32 from OSPF"): print("Waiting for OSPF routes...") until(lambda: route.ipv4_route_exist(R2, "0.0.0.0/0", proto="ietf-ospf:ospfv2"), attempts=200) diff --git a/test/case/routing/ospf_multiarea/test.py b/test/case/routing/ospf_multiarea/test.py index df0f3cf4e..65a588a93 100755 --- a/test/case/routing/ospf_multiarea/test.py +++ b/test/case/routing/ospf_multiarea/test.py @@ -573,10 +573,10 @@ def disable_link(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - R3 = env.attach("R3", "mgmt") - R4 = env.attach("R4", "mgmt") + R1, R2, R3, R4 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt"), + lambda: env.attach("R4", "mgmt")) _, R1ring1 = env.ltop.xlate("R1", "ring1") _, R1ring2 = env.ltop.xlate("R1", "ring2") @@ -594,10 +594,10 @@ def disable_link(target, link): _, R4cross = env.ltop.xlate("R4", "cross") with test.step("Configure targets"): - parallel(config_target1(R1, R1ring1, R1ring2, R1cross), - config_target2(R2, R2ring1, R2ring2, R2cross), - config_target3(R3, R3ring2, R3cross, R3data), - config_target4(R4, R4ring1, R4cross, R4data)) + parallel(lambda: config_target1(R1, R1ring1, R1ring2, R1cross), + lambda: config_target2(R2, R2ring1, R2ring2, R2cross), + lambda: config_target3(R3, R3ring2, R3cross, R3data), + lambda: config_target4(R4, R4ring1, R4cross, R4data)) with test.step("Wait for all neighbors to peer"): print("Waiting for neighbors to peer") diff --git a/test/case/routing/ospf_point_to_multipoint/test.py b/test/case/routing/ospf_point_to_multipoint/test.py index 48c2ab630..57293d1b1 100755 --- a/test/case/routing/ospf_point_to_multipoint/test.py +++ b/test/case/routing/ospf_point_to_multipoint/test.py @@ -293,9 +293,9 @@ def config_target3(target, link, data): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - R3 = env.attach("R3", "mgmt") + R1, R2, R3 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt")) with test.step("Configure targets"): @@ -306,9 +306,9 @@ def config_target3(target, link, data): _, R3link = env.ltop.xlate("R3", "link") _, R3data = env.ltop.xlate("R3", "data") - parallel(config_target1(R1, R1link, R1data), - config_target2(R2, R2link1, R2link2), - config_target3(R3, R3link, R3data)) + parallel(lambda: config_target1(R1, R1link, R1data), + lambda: config_target2(R2, R2link1, R2link2), + lambda: config_target3(R3, R3link, R3data)) with test.step("Wait for OSPF routes"): print("Waiting for OSPF routes from all routers") diff --git a/test/case/routing/ospf_point_to_multipoint_hybrid/test.py b/test/case/routing/ospf_point_to_multipoint_hybrid/test.py index f067ad832..f48fc0fa6 100755 --- a/test/case/routing/ospf_point_to_multipoint_hybrid/test.py +++ b/test/case/routing/ospf_point_to_multipoint_hybrid/test.py @@ -287,9 +287,9 @@ def config_target3(target, link, data): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - R3 = env.attach("R3", "mgmt") + R1, R2, R3 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt")) with test.step("Configure targets"): _, R1link = env.ltop.xlate("R1", "link") @@ -299,9 +299,9 @@ def config_target3(target, link, data): _, R3link = env.ltop.xlate("R3", "link") _, R3data = env.ltop.xlate("R3", "data") - parallel(config_target1(R1, R1link, R1data), - config_target2(R2, R2link1, R2link2), - config_target3(R3, R3link, R3data)) + parallel(lambda: config_target1(R1, R1link, R1data), + lambda: config_target2(R2, R2link1, R2link2), + lambda: config_target3(R3, R3link, R3data)) with test.step("Wait for OSPF routes"): print("Waiting for OSPF routes to converge") diff --git a/test/case/routing/ospf_unnumbered_interface/test.py b/test/case/routing/ospf_unnumbered_interface/test.py index 895801a02..aa86ca290 100755 --- a/test/case/routing/ospf_unnumbered_interface/test.py +++ b/test/case/routing/ospf_unnumbered_interface/test.py @@ -157,8 +157,8 @@ def config_target2(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) _, R1data = env.ltop.xlate("R1", "data") _, R2link = env.ltop.xlate("R2", "link") diff --git a/test/case/routing/rip_basic/test.py b/test/case/routing/rip_basic/test.py index 9189d76bb..b7981afcf 100755 --- a/test/case/routing/rip_basic/test.py +++ b/test/case/routing/rip_basic/test.py @@ -177,8 +177,8 @@ def config_target2(target, link, data): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Configure targets"): _, R1data = env.ltop.xlate("R1", "data") diff --git a/test/case/routing/rip_multihop/test.py b/test/case/routing/rip_multihop/test.py index 527e67d43..1380d72ea 100755 --- a/test/case/routing/rip_multihop/test.py +++ b/test/case/routing/rip_multihop/test.py @@ -234,9 +234,9 @@ def config_r3(target, link, data): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - R3 = env.attach("R3", "mgmt") + R1, R2, R3 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt")) with test.step("Configure routers"): _, R1data = env.ltop.xlate("R1", "data") diff --git a/test/case/routing/rip_passive_interface/test.py b/test/case/routing/rip_passive_interface/test.py index 4761578b4..89ac6df5e 100755 --- a/test/case/routing/rip_passive_interface/test.py +++ b/test/case/routing/rip_passive_interface/test.py @@ -128,16 +128,16 @@ def config_target2(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Configure targets"): _, R1data = env.ltop.xlate("R1", "data") _, R2link = env.ltop.xlate("R2", "link") _, R1link = env.ltop.xlate("R1", "link") - parallel(config_target1(R1, R1data, R1link), - config_target2(R2, R2link)) + parallel(lambda: config_target1(R1, R1data, R1link), + lambda: config_target2(R2, R2link)) with test.step("Wait for RIP to exchange routes"): print("Waiting for RIP routes to propagate...") diff --git a/test/case/routing/rip_redistribute/test.py b/test/case/routing/rip_redistribute/test.py index ad66c594b..e10d4bb2d 100755 --- a/test/case/routing/rip_redistribute/test.py +++ b/test/case/routing/rip_redistribute/test.py @@ -245,9 +245,9 @@ def config_r3_ospf(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - R3 = env.attach("R3", "mgmt") + R1, R2, R3 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt")) with test.step("Configure routers"): _, R1rip = env.ltop.xlate("R1", "rip") @@ -255,9 +255,9 @@ def config_r3_ospf(target, link): _, R2link = env.ltop.xlate("R2", "link") _, R3link = env.ltop.xlate("R3", "link") - parallel(config_r1_gateway(R1, R1rip, R1ospf), - config_r2_rip(R2, R2link), - config_r3_ospf(R3, R3link)) + parallel(lambda: config_r1_gateway(R1, R1rip, R1ospf), + lambda: config_r2_rip(R2, R2link), + lambda: config_r3_ospf(R3, R3link)) with test.step("Wait for OSPF to converge on R1-R3 link"): print("Waiting for OSPF convergence...") diff --git a/test/case/routing/route_pref_255/test.py b/test/case/routing/route_pref_255/test.py index df949358d..ec1eb8c5a 100755 --- a/test/case/routing/route_pref_255/test.py +++ b/test/case/routing/route_pref_255/test.py @@ -95,8 +95,8 @@ def config_target2(target, data, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Configure targets with active static route"): _, R1data = env.ltop.xlate("R1", "data") @@ -104,7 +104,7 @@ def config_target2(target, data, link): _, R2data = env.ltop.xlate("R2", "data") _, R2link = env.ltop.xlate("R2", "link") - parallel(config_target1_initial(R1, R1data, R1link), config_target2(R2, R2data, R2link)) + parallel(lambda: config_target1_initial(R1, R1data, R1link), lambda: config_target2(R2, R2data, R2link)) with test.step("Verify that static route with preference 254 is active"): until(lambda: route.ipv4_route_exist(R1, "192.168.20.0/24", proto="ietf-routing:static", active_check=True)) diff --git a/test/case/routing/route_pref_dhcp/test.py b/test/case/routing/route_pref_dhcp/test.py index 70a53ec2c..d2324d9c5 100755 --- a/test/case/routing/route_pref_dhcp/test.py +++ b/test/case/routing/route_pref_dhcp/test.py @@ -113,8 +113,8 @@ def config_target2(target, data, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Configure targets. Assign higher priority to the dhcp route"): _, R1data1 = env.ltop.xlate("R1", "data1") @@ -123,8 +123,8 @@ def config_target2(target, data, link): _, R2data = env.ltop.xlate("R2", "data") _, R2link = env.ltop.xlate("R2", "link") - parallel(config_target1(R1, R1data1, R1data2, R1link), - config_target2(R2, R2data, R2link)) + parallel(lambda: config_target1(R1, R1data1, R1data2, R1link), + lambda: config_target2(R2, R2data, R2link)) _, hport_data12 = env.ltop.xlate("PC", "data12") ns0 = infamy.IsolatedMacVlan(hport_data12).start() diff --git a/test/case/routing/route_pref_ospf/test.py b/test/case/routing/route_pref_ospf/test.py index b27b979f5..634a790ed 100755 --- a/test/case/routing/route_pref_ospf/test.py +++ b/test/case/routing/route_pref_ospf/test.py @@ -139,8 +139,8 @@ def config_target2(target, data, link, ospf): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) with test.step("Set up TPMR between R1ospf and R2ospf"): ospf_breaker = TPMR(env.ltop.xlate("PC", "R1_ospf")[1], env.ltop.xlate("PC", "R2_ospf")[1]).start() @@ -153,7 +153,7 @@ def config_target2(target, data, link, ospf): _, R2link = env.ltop.xlate("R2", "link") _, R2ospf = env.ltop.xlate("R2", "ospf") - parallel(config_target1(R1, R1data, R1link, R1ospf), config_target2(R2, R2data, R2link, R2ospf)) + parallel(lambda: config_target1(R1, R1data, R1link, R1ospf), lambda: config_target2(R2, R2data, R2link, R2ospf)) with test.step("Set up persistent MacVlan namespaces"): _, hport_data1 = env.ltop.xlate("PC", "data1") diff --git a/test/case/routing/static_routing/test.py b/test/case/routing/static_routing/test.py index bcf14f3d8..08b11abb0 100755 --- a/test/case/routing/static_routing/test.py +++ b/test/case/routing/static_routing/test.py @@ -195,16 +195,16 @@ def config_target2(target, link): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") + R1, R2 = parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt")) _, R1data = env.ltop.xlate("R1", "data") _, R2link = env.ltop.xlate("R2", "link") _, R1link = env.ltop.xlate("R1", "link") with test.step("Configure targets"): - parallel(config_target1(R1, R1data, R1link), - config_target2(R2, R2link)) + parallel(lambda: config_target1(R1, R1data, R1link), + lambda: config_target2(R2, R2link)) with test.step("Wait for routes"): until(lambda: route.ipv4_route_exist(R1, "192.168.200.1/32")) @@ -232,7 +232,7 @@ def config_target2(target, link): lambda: until(lambda: route.ipv6_route_exist(R1, "2001:db8:3c4d:200::1/128") is False)) with test.step("Verify R2 is no longer reachable on either IPv4 or IPv6 from PC:data"): - infamy.parallel(ns0.must_not_reach("192.168.200.1"), - ns0.must_not_reach("2001:db8:3c4d:200::1")) + infamy.parallel(lambda: ns0.must_not_reach("192.168.200.1"), + lambda: ns0.must_not_reach("2001:db8:3c4d:200::1")) test.succeed() diff --git a/test/case/syslog/advanced_compare/test.py b/test/case/syslog/advanced_compare/test.py index fe049cf95..41ee70fd9 100755 --- a/test/case/syslog/advanced_compare/test.py +++ b/test/case/syslog/advanced_compare/test.py @@ -8,7 +8,7 @@ """ import infamy -from infamy.util import until +from infamy.util import parallel, until TEST_MESSAGES = [ ("daemon.emerg", "Emergency: system is unusable"), @@ -24,8 +24,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Clean up old log files from previous test runs"): tgtssh.runsh("sudo rm -f /var/log/{exact-errors,no-debug,baseline}") diff --git a/test/case/syslog/basic/test.py b/test/case/syslog/basic/test.py index 785d06849..972804696 100755 --- a/test/case/syslog/basic/test.py +++ b/test/case/syslog/basic/test.py @@ -9,13 +9,14 @@ """ import infamy +from infamy.util import parallel import infamy.ssh as ssh with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) factory = env.get_password("target") address = target.get_mgmt_ip() diff --git a/test/case/syslog/hostname_filter/test.py b/test/case/syslog/hostname_filter/test.py index 78ebf480a..6bbbb684c 100755 --- a/test/case/syslog/hostname_filter/test.py +++ b/test/case/syslog/hostname_filter/test.py @@ -7,8 +7,8 @@ """ import infamy +from infamy.util import parallel, until import infamy.iface as iface -from infamy import until TEST_MESSAGES = [ ("router1", "Message from router1"), @@ -41,10 +41,10 @@ def check_log(): with infamy.Test() as test: with test.step("Set up topology and attach to DUTs"): env = infamy.Env() - client = env.attach("client", "mgmt") - server = env.attach("server", "mgmt") - clientssh = env.attach("client", "mgmt", "ssh") - serverssh = env.attach("server", "mgmt", "ssh") + client, server, clientssh, serverssh = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("server", "mgmt"), + lambda: env.attach("client", "mgmt", "ssh"), + lambda: env.attach("server", "mgmt", "ssh")) with test.step("Clean up old log files on server"): serverssh.runsh("sudo rm -f /var/log/{router1,router2,all-hosts}") diff --git a/test/case/syslog/pattern_match/test.py b/test/case/syslog/pattern_match/test.py index 4291951e8..2171bc288 100755 --- a/test/case/syslog/pattern_match/test.py +++ b/test/case/syslog/pattern_match/test.py @@ -8,6 +8,7 @@ """ import infamy +from infamy.util import parallel import time TEST_MESSAGES = [ @@ -22,8 +23,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Clean up old log files from previous test runs"): tgtssh.runsh("sudo rm -f /var/log/{errors,routers,all-messages}") diff --git a/test/case/syslog/property_filter/test.py b/test/case/syslog/property_filter/test.py index 9ba0b0e8b..9ca9d81b8 100755 --- a/test/case/syslog/property_filter/test.py +++ b/test/case/syslog/property_filter/test.py @@ -7,7 +7,7 @@ """ import infamy -from infamy.util import until +from infamy.util import parallel, until TEST_MESSAGES = [ ("myapp", "Application startup"), @@ -22,8 +22,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Clean up old log files"): tgtssh.runsh("sudo rm -f /var/log/{myapp,not-error,case-test,baseline}") diff --git a/test/case/syslog/remote/test.py b/test/case/syslog/remote/test.py index b9c1794b9..d3cd3fe39 100755 --- a/test/case/syslog/remote/test.py +++ b/test/case/syslog/remote/test.py @@ -5,6 +5,7 @@ Verify logging to remote, acting as a remote, and RFC5424 log format. """ import infamy +from infamy.util import parallel def syslog_check(clientssh, serverssh): clientssh.runsh("logger -t test -m client -p security.notice TestMessage") @@ -14,117 +15,118 @@ def syslog_check(clientssh, serverssh): with infamy.Test() as test: with test.step("Set up topology and attach to client and server DUTs"): env = infamy.Env() - client = env.attach("client", "mgmt") - server = env.attach("server", "mgmt") - clientssh = env.attach("client", "mgmt", "ssh") - serverssh = env.attach("server", "mgmt", "ssh") + client, server, clientssh, serverssh = parallel(lambda: env.attach("client", "mgmt"), + lambda: env.attach("server", "mgmt"), + lambda: env.attach("client", "mgmt", "ssh"), + lambda: env.attach("server", "mgmt", "ssh")) with test.step("Configure client DUT as syslog client with server DUT as remote, and configure server DUT as syslog server"): _, client_link = env.ltop.xlate("client", "link") _, server_link = env.ltop.xlate("server", "link") - client.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client_link, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "10.0.0.2", - "prefix-length": 24, - }] - } - }] - } - }, - "ietf-syslog": { - "syslog": { - "actions": { - "file": { - "log-file": [{ - "name": "file:security", - "facility-filter": { - "facility-list": [{ - "facility": "auth", - "severity": "all" - }, { - "facility": "audit", - "severity": "all" - }] - }, - "infix-syslog:log-format": "rfc5424" - }] - }, - "remote": { - "destination": [{ - "name": "server", - "udp": { - "address": "10.0.0.1" - }, - "facility-filter": { - "facility-list": [{ - "facility": "audit", - "severity": "all" - }, { - "facility": "auth", - "severity": "all" - }] - }, - "infix-syslog:log-format": "rfc5424" - }] - } - } - } - } - }) - - server.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": server_link, - "enabled": True, - "ipv4": { - "address": [{ - "ip": "10.0.0.1", - "prefix-length": 24, + parallel( + lambda: client.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client_link, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "10.0.0.2", + "prefix-length": 24, + }] + } }] } - }] - } - }, - "ietf-syslog": { - "syslog": { - "actions": { - "file": { - "log-file": [{ - "name": "file:security", - "facility-filter": { - "facility-list": [{ - "facility": "auth", - "severity": "all" - }, { - "facility": "audit", - "severity": "all" + }, + "ietf-syslog": { + "syslog": { + "actions": { + "file": { + "log-file": [{ + "name": "file:security", + "facility-filter": { + "facility-list": [{ + "facility": "auth", + "severity": "all" + }, { + "facility": "audit", + "severity": "all" + }] + }, + "infix-syslog:log-format": "rfc5424" }] }, - "infix-syslog:log-format": "rfc5424" + "remote": { + "destination": [{ + "name": "server", + "udp": { + "address": "10.0.0.1" + }, + "facility-filter": { + "facility-list": [{ + "facility": "audit", + "severity": "all" + }, { + "facility": "auth", + "severity": "all" + }] + }, + "infix-syslog:log-format": "rfc5424" + }] + } + } + } + } + }), + lambda: server.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": server_link, + "enabled": True, + "ipv4": { + "address": [{ + "ip": "10.0.0.1", + "prefix-length": 24, + }] + } }] } }, - "infix-syslog:server": { - "enabled": True, - "listen": { - "udp": [{ - "port": 514, - "address": "10.0.0.1" - }] + "ietf-syslog": { + "syslog": { + "actions": { + "file": { + "log-file": [{ + "name": "file:security", + "facility-filter": { + "facility-list": [{ + "facility": "auth", + "severity": "all" + }, { + "facility": "audit", + "severity": "all" + }] + }, + "infix-syslog:log-format": "rfc5424" + }] + } + }, + "infix-syslog:server": { + "enabled": True, + "listen": { + "udp": [{ + "port": 514, + "address": "10.0.0.1" + }] + } + } } } - } - } - }) + }), + ) with test.step("Send security:notice log message from client and verify reception of client log message, incl. sorting to /log/security on server"): infamy.until(lambda: syslog_check(clientssh, serverssh) == True) diff --git a/test/case/system/add_delete_user/test.py b/test/case/system/add_delete_user/test.py index 448df181c..a5be02605 100755 --- a/test/case/system/add_delete_user/test.py +++ b/test/case/system/add_delete_user/test.py @@ -19,8 +19,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = util.parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Add new user 'newuser01' with password 'newuser01password'"): target.put_config_dicts({ diff --git a/test/case/system/factory_config/test.py b/test/case/system/factory_config/test.py index 8d5a7ac3f..ecbfb7593 100755 --- a/test/case/system/factory_config/test.py +++ b/test/case/system/factory_config/test.py @@ -10,7 +10,7 @@ import json import infamy -from infamy.util import wait_boot +from infamy.util import parallel, wait_boot STARTUP = "/cfg/startup-config.cfg" FACTORY = "/etc/factory-config.cfg" @@ -32,8 +32,8 @@ def cleanup(env): with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) with test.step("Determine factory-config hostname"): expected = factory_hostname(tgtssh) diff --git a/test/case/system/hostname/test.py b/test/case/system/hostname/test.py index 9c57f2653..6da450bf6 100755 --- a/test/case/system/hostname/test.py +++ b/test/case/system/hostname/test.py @@ -9,12 +9,13 @@ """ import re import infamy +from infamy.util import parallel with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) FMT = "%h-%m" NEW = "h0stn4m3" diff --git a/test/case/system/user_admin/test.py b/test/case/system/user_admin/test.py index d6b39ffb6..41dbb595a 100755 --- a/test/case/system/user_admin/test.py +++ b/test/case/system/user_admin/test.py @@ -14,8 +14,8 @@ with infamy.Test() as test: with test.step("Set up topology and attach to target DUT"): env = infamy.Env() - target = env.attach("target", "mgmt") - tgtssh = env.attach("target", "mgmt", "ssh") + target, tgtssh = util.parallel(lambda: env.attach("target", "mgmt"), + lambda: env.attach("target", "mgmt", "ssh")) factory = env.get_password("target") address = target.get_mgmt_ip() diff --git a/test/case/use_case/dhcp_ntp_dns_combination/test.py b/test/case/use_case/dhcp_ntp_dns_combination/test.py index 8c841dbbc..e6f3d489f 100755 --- a/test/case/use_case/dhcp_ntp_dns_combination/test.py +++ b/test/case/use_case/dhcp_ntp_dns_combination/test.py @@ -7,7 +7,7 @@ """ import infamy import infamy.iface as iface -from infamy.util import until +from infamy.util import parallel, until def any_dhcp_address(target, iface_name): try: @@ -61,48 +61,49 @@ def has_system_servers(target, dns, ntp_list): with test.step("Set up topology and configure static IP on client"): env = infamy.Env() - server = env.attach("server", "mgmt") - client = env.attach("client", "mgmt") + server, client = parallel(lambda: env.attach("server", "mgmt"), + lambda: env.attach("client", "mgmt")) client_data = client["server"] server_data = server["client"] # Configure server with static IP and NTP server - server.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": server_data, - "type": "infix-if-type:ethernet", - "enabled": True, - "ipv4": { - "address": [{"ip": SERVER_IP, "prefix-length": 24}] - } - }] - } - }, - "ietf-ntp": { - "ntp": { - "refclock-master": {"master-stratum": 8} + parallel( + lambda: server.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": server_data, + "type": "infix-if-type:ethernet", + "enabled": True, + "ipv4": { + "address": [{"ip": SERVER_IP, "prefix-length": 24}] + } + }] + } + }, + "ietf-ntp": { + "ntp": { + "refclock-master": {"master-stratum": 8} + } } - } - }) - - # Configure client with static IP - client.put_config_dicts({ - "ietf-interfaces": { - "interfaces": { - "interface": [{ - "name": client_data, - "type": "infix-if-type:ethernet", - "enabled": True, - "ipv4": { - "address": [{"ip": CLIENT_STATIC_IP, "prefix-length": 24}] - } - }] + }), + # Configure client with static IP + lambda: client.put_config_dicts({ + "ietf-interfaces": { + "interfaces": { + "interface": [{ + "name": client_data, + "type": "infix-if-type:ethernet", + "enabled": True, + "ipv4": { + "address": [{"ip": CLIENT_STATIC_IP, "prefix-length": 24}] + } + }] + } } - } - }) + }), + ) until(lambda: iface.address_exist(client, client_data, CLIENT_STATIC_IP, proto="static")) print("Initial IP connectivity established") diff --git a/test/case/use_case/ospf_container/test.py b/test/case/use_case/ospf_container/test.py index 968f37e28..3815b6840 100755 --- a/test/case/use_case/ospf_container/test.py +++ b/test/case/use_case/ospf_container/test.py @@ -574,10 +574,10 @@ def config_abr(target, data, link1, link2, link3): with infamy.Test() as test: with test.step("Set up topology and attach to target DUTs"): env = infamy.Env() - R1 = env.attach("R1", "mgmt") - R2 = env.attach("R2", "mgmt") - R3 = env.attach("R3", "mgmt") - ABR = env.attach("ABR", "mgmt") + R1, R2, R3, ABR = util.parallel(lambda: env.attach("R1", "mgmt"), + lambda: env.attach("R2", "mgmt"), + lambda: env.attach("R3", "mgmt"), + lambda: env.attach("ABR", "mgmt")) if not R1.has_model("infix-containers"): test.skip() if not R2.has_model("infix-containers"):