-
Notifications
You must be signed in to change notification settings - Fork 463
Testsuite: T3871: change testcase to use multiple NIC drivers #1253
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -82,6 +82,9 @@ tpm_folder = '/tmp/vyos_tpm_test' | |
| tpm_sock = f'{tpm_folder}/swtpm-sock' | ||
| qemu_name = 'VyOS-QEMU' | ||
|
|
||
| # RFC7042 section 2.1.2 MAC addresses used for documentation | ||
| macbase = '00:00:5E:00:53' | ||
|
|
||
| test_timeout = 5 *3600 # 5 hours (in seconds) to complete individual testcases | ||
|
|
||
| op_mode_prompt = r'vyos@vyos:~\$' | ||
|
|
@@ -137,6 +140,8 @@ parser.add_argument('--configtest', help='Execute load/commit config tests', | |
| action='store_true', default=False) | ||
| parser.add_argument('--tpmtest', help='Execute TPM encrypted config tests', | ||
| action='store_true', default=False) | ||
| parser.add_argument('--ifnametest', help='Execute interface naming/hw-id persistence tests', | ||
| action='store_true', default=False) | ||
| parser.add_argument('--sbtest', help='Execute Secure Boot tests', | ||
| action='store_true', default=False) | ||
| parser.add_argument('--cloud-init', help='Execute cloud-init tests', | ||
|
|
@@ -268,9 +273,6 @@ def get_qemu_cmd(name, enable_uefi, disk_img, raid=None, iso_img=None, tpm=False | |
| else: | ||
| nested_cdrom = f'{nested_cdrom} -device ide-cd,bus=achi0.1,{drive_settings}' | ||
|
|
||
| # RFC7042 section 2.1.2 MAC addresses used for documentation | ||
| macbase = '00:00:5E:00:53' | ||
|
|
||
| # Set QEmu disk image format - this differs if VyOS was installed via smoketest | ||
| # or we use an already ewxisting image | ||
| disk_format = 'qcow2' if args.disk.endswith('.qcow2') else 'raw' | ||
|
|
@@ -290,10 +292,10 @@ def get_qemu_cmd(name, enable_uefi, disk_img, raid=None, iso_img=None, tpm=False | |
| -netdev user,id=n1 -device virtio-net-pci,netdev=n1,mac={macbase}:01,romfile="",host_mtu=1500 \ | ||
| -netdev user,id=n2 -device virtio-net-pci,netdev=n2,mac={macbase}:02,romfile="",host_mtu=1500 \ | ||
| -netdev user,id=n3 -device virtio-net-pci,netdev=n3,mac={macbase}:03,romfile="",host_mtu=1500 \ | ||
| -netdev user,id=n4 -device virtio-net-pci,netdev=n4,mac={macbase}:04,romfile="" \ | ||
| -netdev user,id=n5 -device virtio-net-pci,netdev=n5,mac={macbase}:05,romfile="" \ | ||
| -netdev user,id=n6 -device virtio-net-pci,netdev=n6,mac={macbase}:06,romfile="" \ | ||
| -netdev user,id=n7 -device virtio-net-pci,netdev=n7,mac={macbase}:07,romfile="" \ | ||
| -netdev user,id=n4 -device e1000e,netdev=n4,mac={macbase}:04,romfile="" \ | ||
| -netdev user,id=n5 -device e1000e,netdev=n5,mac={macbase}:05,romfile="" \ | ||
| -netdev user,id=n6 -device vmxnet3,netdev=n6,mac={macbase}:06,romfile="" \ | ||
| -netdev user,id=n7 -device vmxnet3,netdev=n7,mac={macbase}:07,romfile="" \ | ||
| -device virtio-scsi-pci,id=scsi0 \ | ||
| {cdrom}{nested_cdrom} \ | ||
| -drive format={disk_format},file={disk_img},if=none,media=disk,id=drive-hd1,readonly=off \ | ||
|
|
@@ -387,6 +389,8 @@ if args.test_image_update: | |
| _primary_modes.append('--test-image-update') | ||
| if args.tpmtest: | ||
| _primary_modes.append('--tpmtest') | ||
| if args.ifnametest: | ||
| _primary_modes.append('--ifnametest') | ||
| if args.raid: | ||
| _primary_modes.append('--raid') | ||
| if args.smoketest: | ||
|
|
@@ -397,8 +401,8 @@ if args.sbtest: | |
| _primary_modes.append('--sbtest') | ||
| if len(_primary_modes) > 1: | ||
| log.error('Incompatible combination of testcase flags (%s): only one of ' | ||
| '--cloud-init, --test-image-update, --tpmtest, --raid, --smoketest, ' | ||
| '--configtest, --sbtest may be set.', ', '.join(_primary_modes)) | ||
| '--cloud-init, --test-image-update, --tpmtest, --ifnametest, --raid, ' | ||
| '--smoketest, --configtest, --sbtest may be set.', ', '.join(_primary_modes)) | ||
| sys.exit(1) | ||
|
|
||
| if args.no_interfaces and not args.smoketest: | ||
|
|
@@ -687,6 +691,31 @@ def basic_cli_tests(c): | |
| c.expect(f'set console_type="{console_type}"') | ||
| c.expect(op_mode_prompt) | ||
|
|
||
| def verify_eth_mac_mapping(c, log): | ||
| """ NICs are attached with a mix of drivers (virtio/e1000e/vmxnet3, see | ||
| get_qemu_cmd()) to cover different naming schemes. Regardless of | ||
| driver, udev must always enumerate them in ascending order: eth0 | ||
| carries mac0, eth1 mac1, ... up to eth7 mac7 - never scrambled. """ | ||
| log.info('Verify eth0..eth7 are enumerated in ascending MAC order') | ||
| c.sendline('ip -json link show | jq -r \'.[] | select(.ifname|test("^eth[0-9]+$")) | "\(.ifname) \(.address)"\'') | ||
| c.expect(op_mode_prompt) | ||
| lines = [l.strip() for l in c.before.decode(errors='replace').splitlines() if l.strip()] | ||
|
|
||
| macs = {} | ||
| for line in lines: | ||
| parts = line.split() | ||
| if len(parts) == 2 and re.fullmatch(r'eth\d+', parts[0]): | ||
| macs[parts[0]] = parts[1].lower() | ||
|
|
||
| for i in range(8): | ||
| ifname = f'eth{i}' | ||
| expected_mac = f'{macbase}:{i:02x}'.lower() | ||
| if ifname not in macs: | ||
| raise Exception(f'Interface {ifname} not found on installed system') | ||
| if macs[ifname] != expected_mac: | ||
| raise Exception(f'Interface {ifname} has MAC {macs[ifname]}, expected {expected_mac} - naming race?') | ||
| log.info('eth0..eth7 MAC mapping verified') | ||
|
|
||
| def _image_update_cli_sequence(c, log, new_image_name, server_bind_host='127.0.0.1', use_vrf=False): | ||
| """One add-system-image/delete cycle for nested ISO over HTTP (optional Linux VRF + VyOS vrf arg).""" | ||
| url = f'http://{server_bind_host}:{NESTED_HTTP_SERV_PORT}/{NESTED_INNER_ISO_NAME}' | ||
|
|
@@ -1067,6 +1096,11 @@ try: | |
| log.info('Basic CLI configuration mode test') | ||
| basic_cli_tests(c) | ||
|
|
||
| ################################################# | ||
| # Verify NIC driver mix did not scramble interface naming | ||
| ################################################# | ||
| verify_eth_mac_mapping(c, log) | ||
|
|
||
| ################################################# | ||
| # Verify /etc/os-release via lsb_release | ||
| ################################################# | ||
|
|
@@ -1274,6 +1308,48 @@ try: | |
| c.sendline('exit') | ||
| c.expect(op_mode_prompt) | ||
|
|
||
| elif args.ifnametest: | ||
| # A missing/deleted hw-id binding, or a fully deleted interface | ||
| # config, must not change the eth0..eth7 <-> MAC mapping after | ||
| # the next reboot (regression check for the boot-time naming race). | ||
| log.info('Running interface naming/hw-id persistence tests') | ||
| del_idx, hwid_idx = random.sample(range(8), 2) | ||
| log.info(f'Deleting eth{del_idx} entirely, removing hw-id only on eth{hwid_idx}') | ||
|
|
||
| c.sendline('configure') | ||
| c.expect(cfg_mode_prompt) | ||
| c.sendline(f'delete interfaces ethernet eth{del_idx}') | ||
| c.expect(cfg_mode_prompt) | ||
| c.sendline(f'delete interfaces ethernet eth{hwid_idx} hw-id') | ||
| c.expect(cfg_mode_prompt) | ||
| c.sendline('commit') | ||
| c.expect(cfg_mode_prompt) | ||
| c.sendline('save') | ||
| c.expect(cfg_mode_prompt) | ||
|
Comment on lines
+1319
to
+1328
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
# Inspect interface configuration setup and the ifnametest mutation path.
rg -n -C 8 \
'args\.ifnametest|set interfaces ethernet|delete interfaces ethernet|hw-id|show configuration commands' \
scripts/check-qemu-install
# Find other image/bootstrap code that creates Ethernet hw-id bindings.
rg -n -C 6 \
'set interfaces ethernet eth[0-7]|interfaces ethernet.*hw-id' \
. -g '!scripts/check-qemu-install'Repository: vyos/vyos-build Length of output: 5657 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- interface test function and reboot assertions ---'
sed -n '1180,1385p' scripts/check-qemu-install
printf '%s\n' '--- all interface configuration commands in this script ---'
rg -n -C 5 \
'interfaces ethernet|hw-id|ifname|eth0\.\.eth7|eth0\.\.eth7|random\.sample|reboot' \
scripts/check-qemu-install || true
printf '%s\n' '--- repository references to interface bootstrap configuration ---'
rg -n -C 4 \
'set interfaces ethernet|hw-id' . \
-g '!scripts/check-qemu-install' \
-g '!*.iso' -g '!*.qcow2' -g '!*.img' || trueRepository: vyos/vyos-build Length of output: 15033 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- interface test function and reboot assertions ---'
sed -n '1180,1385p' scripts/check-qemu-install
printf '%s\n' '--- all interface configuration commands in this script ---'
rg -n -C 5 \
'interfaces ethernet|hw-id|ifname|eth0\.\.eth7|random\.sample|reboot' \
scripts/check-qemu-install || true
printf '%s\n' '--- repository references to interface bootstrap configuration ---'
rg -n -C 4 \
'set interfaces ethernet|hw-id' . \
-g '!scripts/check-qemu-install' \
-g '!*.iso' -g '!*.qcow2' -g '!*.img' || trueRepository: vyos/vyos-build Length of output: 15033 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- interface and image setup ---'
sed -n '430,760p' scripts/check-qemu-install
printf '%s\n' '--- installation and initial boot flow ---'
sed -n '900,1125p' scripts/check-qemu-install
printf '%s\n' '--- configuration and interface-related symbols ---'
rg -n \
'macbase|mac[0-9]|get_qemu_cmd|install|config\.boot|verify_eth_mac_mapping|interfaces ethernet|hw-id' \
scripts/check-qemu-install
printf '%s\n' '--- current change summary ---'
git diff --stat
git status --shortRepository: vyos/vyos-build Length of output: 26493 🌐 Web query:
💡 Result: In VyOS, the Citations:
🌐 Web query:
💡 Result: The term "hw-id" in the context of VyOS is not a command, but rather a configuration node used to associate a physical network interface (Ethernet or wireless) with its specific hardware MAC address [1][2][3]. By defining the hw-id under an interface configuration (e.g., set interfaces ethernet eth0 hw-id 'xx:xx:xx:xx:xx:xx'), you ensure that the system consistently assigns the name (e.g., eth0) to the physical network card with that specific MAC address, regardless of the boot order or the presence of other hardware [3][4]. This mechanism is crucial in VyOS for predictable network interface naming [4]. If an interface is renamed or replaced, updating or deleting the hw-id entry is a common administrative task to allow the system to re-identify and correctly assign the interface name [3][4]. There is no "install image hw-id" command; if you encountered such a phrase, it likely refers to setting the hw-id during the initial installation or configuration of a network interface within a VyOS system image [5][2]. Citations:
🌐 Web query:
💡 Result: In VyOS, the hw-id configuration node is used to associate a specific network interface (such as an ethernet or wireless interface) with a particular Media Access Control (MAC) address [1]. This configuration, found within the config.boot file, ensures that the system assigns the desired interface name (e.g., eth0) to the physical hardware that possesses the specified MAC address, regardless of the order in which the kernel detects the interfaces at boot time [2][3][4]. When you define an interface with an hw-id, the system uses this identifier to perform interface renaming reliably [4]. This prevents issues where interface names might swap on reboot if multiple network interfaces are present or if hardware is added or removed [4]. Example of the hw-id configuration in config.boot: interfaces { ethernet eth0 { hw-id "00:11:22:33:44:55" } } The system processes these entries during the boot sequence—specifically, mechanisms like vyos-net-name-resolve or similar helper scripts read this configuration to map the MAC address to the intended interface name [2][4]. If an interface is not explicitly configured with an hw-id, the system uses other methods for naming, which may be less predictable across different hardware configurations [4]. Citations:
🔍 Additional research query:
💡 Result: Findings
|
||
| c.sendline('exit') | ||
| c.expect(op_mode_prompt) | ||
|
|
||
| log.info('Rebooting to verify interface naming survives across reboot') | ||
| c.sendline('reboot now') | ||
| waitForLogin(c, log) | ||
| loginVM(c, log) | ||
|
|
||
| log.info('Collecting interface naming diagnostics') | ||
| c.sendline('show configuration commands | match "hw-id"') | ||
| c.expect(op_mode_prompt) | ||
| c.sendline('show interfaces ethernet') | ||
| c.expect(op_mode_prompt) | ||
| c.sendline('ip link show') | ||
| c.expect(op_mode_prompt) | ||
| c.sendline('show log | match "hw-id"') | ||
| c.expect(op_mode_prompt) | ||
| c.sendline('cat /run/vyos-net-name-resolve.json 2>/dev/null || true') | ||
| c.expect(op_mode_prompt) | ||
| c.sendline('show log kernel | match "eth"') | ||
| c.expect(op_mode_prompt) | ||
|
|
||
| verify_eth_mac_mapping(c, log) | ||
|
|
||
| elif args.raid: | ||
| # Verify RAID subsystem - by deleting a disk and re-create the array | ||
| # from scratch | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.