Skip to content

Commit 949f2bc

Browse files
committed
pci: add tests for PCIe root bus
Add an integration test that checks that `lspci` correctly locates the PCIe root complex if PCI is enabled for the microVM. Also, add a negative test that checks that PCIe root complex doesn't exist when PCI is not enabled. Also, extend coverage of, at least some of, the tests to ensure that they run with and without PCI configuration enabled. Do that by extending the `uvm_any*` fixtures to yield both variants. Signed-off-by: Babis Chalios <[email protected]>
1 parent b514cbb commit 949f2bc

File tree

5 files changed

+90
-13
lines changed

5 files changed

+90
-13
lines changed

tests/conftest.py

Lines changed: 54 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -526,23 +526,27 @@ def mem_size_mib():
526526
"""Return memory size. Use indirect parametrization to override."""
527527
return 256
528528

529+
@pytest.fixture(params=[True, False])
530+
def pci_enabled(request):
531+
yield request.param
532+
529533

530534
def uvm_booted(
531-
microvm_factory, guest_kernel, rootfs, cpu_template, vcpu_count=2, mem_size_mib=256
535+
microvm_factory, guest_kernel, rootfs, cpu_template, pci_enabled, vcpu_count=2, mem_size_mib=256
532536
):
533537
"""Return a booted uvm"""
534538
uvm = microvm_factory.build(guest_kernel, rootfs)
535-
uvm.spawn()
539+
uvm.spawn(pci=pci_enabled)
536540
uvm.basic_config(vcpu_count=vcpu_count, mem_size_mib=mem_size_mib)
537541
uvm.set_cpu_template(cpu_template)
538542
uvm.add_net_iface()
539543
uvm.start()
540544
return uvm
541545

542546

543-
def uvm_restored(microvm_factory, guest_kernel, rootfs, cpu_template, **kwargs):
547+
def uvm_restored(microvm_factory, guest_kernel, rootfs, cpu_template, pci_enabled, **kwargs):
544548
"""Return a restored uvm"""
545-
uvm = uvm_booted(microvm_factory, guest_kernel, rootfs, cpu_template, **kwargs)
549+
uvm = uvm_booted(microvm_factory, guest_kernel, rootfs, cpu_template, pci_enabled, **kwargs)
546550
snapshot = uvm.snapshot_full()
547551
uvm.kill()
548552
uvm2 = microvm_factory.build_from_snapshot(snapshot)
@@ -563,6 +567,7 @@ def uvm_any(
563567
guest_kernel,
564568
rootfs,
565569
cpu_template_any,
570+
pci_enabled,
566571
vcpu_count,
567572
mem_size_mib,
568573
):
@@ -572,21 +577,65 @@ def uvm_any(
572577
guest_kernel,
573578
rootfs,
574579
cpu_template_any,
580+
pci_enabled,
575581
vcpu_count=vcpu_count,
576582
mem_size_mib=mem_size_mib,
577583
)
578584

579585

580586
@pytest.fixture
581587
def uvm_any_booted(
582-
microvm_factory, guest_kernel, rootfs, cpu_template_any, vcpu_count, mem_size_mib
588+
microvm_factory, guest_kernel, rootfs, cpu_template_any, pci_enabled, vcpu_count, mem_size_mib
583589
):
584590
"""Return booted uvms"""
585591
return uvm_booted(
586592
microvm_factory,
587593
guest_kernel,
588594
rootfs,
589595
cpu_template_any,
596+
pci_enabled,
597+
vcpu_count=vcpu_count,
598+
mem_size_mib=mem_size_mib,
599+
)
600+
601+
602+
@pytest.fixture
603+
def uvm_any_with_pci(
604+
uvm_ctor,
605+
microvm_factory,
606+
guest_kernel_acpi,
607+
rootfs,
608+
cpu_template_any,
609+
vcpu_count,
610+
mem_size_mib,
611+
):
612+
return uvm_ctor(
613+
microvm_factory,
614+
guest_kernel_acpi,
615+
rootfs,
616+
cpu_template_any,
617+
True,
618+
vcpu_count=vcpu_count,
619+
mem_size_mib=mem_size_mib,
620+
)
621+
622+
623+
@pytest.fixture
624+
def uvm_any_without_pci(
625+
uvm_ctor,
626+
microvm_factory,
627+
guest_kernel_acpi,
628+
rootfs,
629+
cpu_template_any,
630+
vcpu_count,
631+
mem_size_mib,
632+
):
633+
return uvm_ctor(
634+
microvm_factory,
635+
guest_kernel_acpi,
636+
rootfs,
637+
cpu_template_any,
638+
False,
590639
vcpu_count=vcpu_count,
591640
mem_size_mib=mem_size_mib,
592641
)

tests/framework/microvm.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -597,6 +597,7 @@ def spawn(
597597
log_show_origin=False,
598598
metrics_path="fc.ndjson",
599599
emit_metrics: bool = False,
600+
pci: bool = False,
600601
):
601602
"""Start a microVM as a daemon or in a screen session."""
602603
# pylint: disable=subprocess-run-check
@@ -637,6 +638,9 @@ def spawn(
637638
# Checking the timings requires DEBUG level log messages
638639
self.time_api_requests = False
639640

641+
if pci:
642+
self.jailer.extra_args["enable-pci"] = None
643+
640644
cmd = [
641645
*self._pre_cmd,
642646
str(self.jailer_binary_path),

tests/integration_tests/functional/test_net.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ def test_multi_queue_unsupported(uvm_plain):
8989

9090

9191
@pytest.fixture
92-
def uvm_any(microvm_factory, uvm_ctor, guest_kernel, rootfs):
92+
def uvm_any(microvm_factory, uvm_ctor, guest_kernel, rootfs, pci_enabled):
9393
"""Return booted and restored uvm with no CPU templates"""
94-
return uvm_ctor(microvm_factory, guest_kernel, rootfs, None)
94+
return uvm_ctor(microvm_factory, guest_kernel, rootfs, None, pci_enabled)
9595

9696

9797
def test_tap_offload(uvm_any):
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
"""Tests for the PCI devices"""
4+
5+
def test_pci_root_present(uvm_any_with_pci):
6+
"""
7+
Test that a guest with PCI enabled has a PCI root device.
8+
"""
9+
10+
vm = uvm_any_with_pci
11+
devices = vm.ssh.run("lspci").stdout.strip().split('\n')
12+
print(devices)
13+
assert devices[0].startswith(
14+
"00:00.0 Host bridge: Intel Corporation Device"
15+
), "PCI root not found in guest"
16+
17+
def test_pci_disabled(uvm_any_without_pci):
18+
"""
19+
Test that a guest with PCI disabled does not have a PCI root device but still works.
20+
"""
21+
22+
vm = uvm_any_without_pci
23+
_, stdout, _ = vm.ssh.run("lspci")
24+
assert "00:00.0 Host bridge: Intel Corporation Device" not in stdout, "PCI root not found in guest"

tests/integration_tests/functional/test_rng.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@
88
from host_tools.network import SSHConnection
99

1010

11-
def uvm_with_rng_booted(microvm_factory, guest_kernel, rootfs, rate_limiter):
11+
def uvm_with_rng_booted(microvm_factory, guest_kernel, rootfs, rate_limiter, pci_enabled):
1212
"""Return a booted microvm with virtio-rng configured"""
1313
uvm = microvm_factory.build(guest_kernel, rootfs)
14-
uvm.spawn(log_level="INFO")
14+
uvm.spawn(log_level="INFO", pci=pci_enabled)
1515
uvm.basic_config(vcpu_count=2, mem_size_mib=256)
1616
uvm.add_net_iface()
1717
uvm.api.entropy.put(rate_limiter=rate_limiter)
@@ -21,9 +21,9 @@ def uvm_with_rng_booted(microvm_factory, guest_kernel, rootfs, rate_limiter):
2121
return uvm
2222

2323

24-
def uvm_with_rng_restored(microvm_factory, guest_kernel, rootfs, rate_limiter):
24+
def uvm_with_rng_restored(microvm_factory, guest_kernel, rootfs, rate_limiter, pci_enabled):
2525
"""Return a restored uvm with virtio-rng configured"""
26-
uvm = uvm_with_rng_booted(microvm_factory, guest_kernel, rootfs, rate_limiter)
26+
uvm = uvm_with_rng_booted(microvm_factory, guest_kernel, rootfs, rate_limiter, pci_enabled)
2727
snapshot = uvm.snapshot_full()
2828
uvm.kill()
2929
uvm2 = microvm_factory.build_from_snapshot(snapshot)
@@ -44,9 +44,9 @@ def rate_limiter(request):
4444

4545

4646
@pytest.fixture
47-
def uvm_any(microvm_factory, uvm_ctor, guest_kernel, rootfs, rate_limiter):
47+
def uvm_any(microvm_factory, uvm_ctor, guest_kernel, rootfs, rate_limiter, pci_enabled):
4848
"""Return booted and restored uvms"""
49-
return uvm_ctor(microvm_factory, guest_kernel, rootfs, rate_limiter)
49+
return uvm_ctor(microvm_factory, guest_kernel, rootfs, rate_limiter, pci_enabled)
5050

5151

5252
def list_rng_available(ssh_connection: SSHConnection) -> list[str]:

0 commit comments

Comments
 (0)