aboutsummaryrefslogtreecommitdiff
path: root/tests/functional
diff options
context:
space:
mode:
Diffstat (limited to 'tests/functional')
-rw-r--r--tests/functional/aarch64/meson.build49
-rwxr-xr-xtests/functional/aarch64/test_aspeed_ast2700.py (renamed from tests/functional/test_aarch64_aspeed.py)102
-rwxr-xr-xtests/functional/aarch64/test_aspeed_ast2700fc.py148
-rwxr-xr-xtests/functional/aarch64/test_device_passthrough.py143
-rwxr-xr-xtests/functional/aarch64/test_hotplug_pci.py72
-rwxr-xr-xtests/functional/aarch64/test_imx8mp_evk.py68
-rwxr-xr-xtests/functional/aarch64/test_kvm.py71
-rwxr-xr-xtests/functional/aarch64/test_migration.py26
-rwxr-xr-xtests/functional/aarch64/test_multiprocess.py31
-rwxr-xr-xtests/functional/aarch64/test_raspi3.py (renamed from tests/functional/test_aarch64_raspi3.py)0
-rwxr-xr-xtests/functional/aarch64/test_raspi4.py (renamed from tests/functional/test_aarch64_raspi4.py)0
-rwxr-xr-xtests/functional/aarch64/test_replay.py51
-rwxr-xr-xtests/functional/aarch64/test_reverse_debug.py36
-rwxr-xr-xtests/functional/aarch64/test_rme_sbsaref.py77
-rwxr-xr-xtests/functional/aarch64/test_rme_virt.py76
-rwxr-xr-xtests/functional/aarch64/test_sbsaref.py (renamed from tests/functional/test_aarch64_sbsaref.py)5
-rwxr-xr-xtests/functional/aarch64/test_sbsaref_alpine.py (renamed from tests/functional/test_aarch64_sbsaref_alpine.py)8
-rwxr-xr-xtests/functional/aarch64/test_sbsaref_freebsd.py (renamed from tests/functional/test_aarch64_sbsaref_freebsd.py)15
-rwxr-xr-xtests/functional/aarch64/test_smmu.py211
-rwxr-xr-xtests/functional/aarch64/test_tcg_plugins.py (renamed from tests/functional/test_aarch64_tcg_plugins.py)1
-rwxr-xr-xtests/functional/aarch64/test_tuxrun.py (renamed from tests/functional/test_aarch64_tuxrun.py)0
-rwxr-xr-xtests/functional/aarch64/test_virt.py (renamed from tests/functional/test_aarch64_virt.py)12
-rwxr-xr-xtests/functional/aarch64/test_virt_gpu.py (renamed from tests/functional/test_aarch64_virt_gpu.py)2
-rwxr-xr-xtests/functional/aarch64/test_xen.py (renamed from tests/functional/test_aarch64_xen.py)1
-rwxr-xr-xtests/functional/aarch64/test_xlnx_versal.py (renamed from tests/functional/test_aarch64_xlnx_versal.py)12
-rw-r--r--tests/functional/alpha/meson.build10
-rwxr-xr-xtests/functional/alpha/test_clipper.py (renamed from tests/functional/test_alpha_clipper.py)0
-rwxr-xr-xtests/functional/alpha/test_migration.py26
-rwxr-xr-xtests/functional/alpha/test_replay.py (renamed from tests/functional/test_alpha_replay.py)0
-rw-r--r--tests/functional/arm/meson.build64
-rwxr-xr-xtests/functional/arm/test_aspeed_ast1030.py (renamed from tests/functional/test_arm_aspeed_ast1030.py)33
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2500.py (renamed from tests/functional/test_arm_aspeed_ast2500.py)17
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2600_buildroot.py (renamed from tests/functional/test_arm_aspeed_ast2600.py)61
-rwxr-xr-xtests/functional/arm/test_aspeed_ast2600_sdk.py94
-rwxr-xr-x[-rw-r--r--]tests/functional/arm/test_aspeed_bletchley.py (renamed from tests/functional/test_arm_aspeed_bletchley.py)4
-rwxr-xr-xtests/functional/arm/test_aspeed_catalina.py25
-rwxr-xr-xtests/functional/arm/test_aspeed_gb200nvl_bmc.py26
-rwxr-xr-xtests/functional/arm/test_aspeed_palmetto.py (renamed from tests/functional/test_arm_aspeed_palmetto.py)4
-rwxr-xr-xtests/functional/arm/test_aspeed_rainier.py (renamed from tests/functional/test_arm_aspeed_rainier.py)0
-rwxr-xr-xtests/functional/arm/test_aspeed_romulus.py (renamed from tests/functional/test_arm_aspeed_romulus.py)4
-rwxr-xr-x[-rw-r--r--]tests/functional/arm/test_aspeed_witherspoon.py (renamed from tests/functional/test_arm_aspeed_witherspoon.py)4
-rwxr-xr-xtests/functional/arm/test_bflt.py (renamed from tests/functional/test_arm_bflt.py)0
-rwxr-xr-xtests/functional/arm/test_bpim2u.py (renamed from tests/functional/test_arm_bpim2u.py)2
-rwxr-xr-xtests/functional/arm/test_canona1100.py (renamed from tests/functional/test_arm_canona1100.py)0
-rwxr-xr-xtests/functional/arm/test_collie.py (renamed from tests/functional/test_arm_collie.py)0
-rwxr-xr-xtests/functional/arm/test_cubieboard.py (renamed from tests/functional/test_arm_cubieboard.py)4
-rwxr-xr-xtests/functional/arm/test_emcraft_sf2.py (renamed from tests/functional/test_arm_emcraft_sf2.py)0
-rwxr-xr-xtests/functional/arm/test_integratorcp.py (renamed from tests/functional/test_arm_integratorcp.py)9
-rwxr-xr-xtests/functional/arm/test_max78000fthr.py48
-rwxr-xr-xtests/functional/arm/test_microbit.py (renamed from tests/functional/test_arm_microbit.py)0
-rwxr-xr-xtests/functional/arm/test_migration.py26
-rwxr-xr-xtests/functional/arm/test_orangepi.py (renamed from tests/functional/test_arm_orangepi.py)2
-rwxr-xr-xtests/functional/arm/test_quanta_gsj.py (renamed from tests/functional/test_arm_quanta_gsj.py)2
-rwxr-xr-xtests/functional/arm/test_raspi2.py (renamed from tests/functional/test_arm_raspi2.py)0
-rwxr-xr-xtests/functional/arm/test_realview.py47
-rwxr-xr-xtests/functional/arm/test_replay.py (renamed from tests/functional/test_arm_replay.py)0
-rwxr-xr-xtests/functional/arm/test_smdkc210.py (renamed from tests/functional/test_arm_smdkc210.py)2
-rwxr-xr-xtests/functional/arm/test_stellaris.py48
-rwxr-xr-xtests/functional/arm/test_sx1.py (renamed from tests/functional/test_arm_sx1.py)0
-rwxr-xr-xtests/functional/arm/test_tuxrun.py (renamed from tests/functional/test_arm_tuxrun.py)0
-rwxr-xr-xtests/functional/arm/test_vexpress.py (renamed from tests/functional/test_arm_vexpress.py)0
-rwxr-xr-xtests/functional/arm/test_virt.py (renamed from tests/functional/test_arm_virt.py)0
-rw-r--r--tests/functional/aspeed.py19
-rw-r--r--tests/functional/avr/meson.build6
-rwxr-xr-xtests/functional/avr/test_mega2560.py (renamed from tests/functional/test_avr_mega2560.py)11
-rwxr-xr-xtests/functional/avr/test_uno.py32
-rw-r--r--tests/functional/generic/meson.build14
-rwxr-xr-xtests/functional/generic/test_empty_cpu_model.py (renamed from tests/functional/test_empty_cpu_model.py)0
-rwxr-xr-xtests/functional/generic/test_info_usernet.py (renamed from tests/functional/test_info_usernet.py)0
-rwxr-xr-xtests/functional/generic/test_version.py (renamed from tests/functional/test_version.py)0
-rwxr-xr-xtests/functional/generic/test_vmstate.py67
-rwxr-xr-xtests/functional/generic/test_vnc.py (renamed from tests/functional/test_vnc.py)10
-rw-r--r--tests/functional/hppa/meson.build9
-rwxr-xr-xtests/functional/hppa/test_cdboot.py38
-rwxr-xr-xtests/functional/hppa/test_seabios.py (renamed from tests/functional/test_hppa_seabios.py)2
-rw-r--r--tests/functional/i386/meson.build10
-rwxr-xr-xtests/functional/i386/test_migration.py26
-rwxr-xr-xtests/functional/i386/test_replay.py28
-rwxr-xr-xtests/functional/i386/test_tuxrun.py (renamed from tests/functional/test_i386_tuxrun.py)0
-rw-r--r--tests/functional/loongarch64/meson.build5
-rwxr-xr-xtests/functional/loongarch64/test_virt.py (renamed from tests/functional/test_loongarch64_virt.py)0
-rw-r--r--tests/functional/m68k/meson.build13
-rwxr-xr-xtests/functional/m68k/test_mcf5208evb.py (renamed from tests/functional/test_m68k_mcf5208evb.py)0
-rwxr-xr-xtests/functional/m68k/test_nextcube.py (renamed from tests/functional/test_m68k_nextcube.py)26
-rwxr-xr-xtests/functional/m68k/test_q800.py (renamed from tests/functional/test_m68k_q800.py)3
-rwxr-xr-xtests/functional/m68k/test_replay.py (renamed from tests/functional/test_m68k_replay.py)3
-rwxr-xr-xtests/functional/m68k/test_tuxrun.py (renamed from tests/functional/test_m68k_tuxrun.py)0
-rw-r--r--tests/functional/meson.build362
-rw-r--r--tests/functional/microblaze/meson.build6
-rwxr-xr-xtests/functional/microblaze/test_replay.py (renamed from tests/functional/test_microblaze_replay.py)0
-rwxr-xr-xtests/functional/microblaze/test_s3adsp1800.py (renamed from tests/functional/test_microblaze_s3adsp1800.py)18
-rw-r--r--tests/functional/microblazeel/meson.build5
-rwxr-xr-xtests/functional/microblazeel/test_s3adsp1800.py (renamed from tests/functional/test_microblazeel_s3adsp1800.py)8
-rw-r--r--[-rwxr-xr-x]tests/functional/migration.py (renamed from tests/functional/test_migration.py)38
-rw-r--r--tests/functional/mips/meson.build11
-rwxr-xr-xtests/functional/mips/test_malta.py196
-rwxr-xr-xtests/functional/mips/test_replay.py (renamed from tests/functional/test_mips_replay.py)2
-rwxr-xr-xtests/functional/mips/test_tuxrun.py (renamed from tests/functional/test_mips_tuxrun.py)0
-rw-r--r--tests/functional/mips64/meson.build10
-rwxr-xr-xtests/functional/mips64/test_malta.py35
-rwxr-xr-xtests/functional/mips64/test_tuxrun.py (renamed from tests/functional/test_mips64_tuxrun.py)0
-rw-r--r--tests/functional/mips64el/meson.build14
-rwxr-xr-xtests/functional/mips64el/test_fuloong2e.py (renamed from tests/functional/test_mips64el_fuloong2e.py)0
-rwxr-xr-xtests/functional/mips64el/test_loongson3v.py (renamed from tests/functional/test_mips64el_loongson3v.py)0
-rwxr-xr-xtests/functional/mips64el/test_malta.py (renamed from tests/functional/test_mips64el_malta.py)33
-rwxr-xr-xtests/functional/mips64el/test_replay.py (renamed from tests/functional/test_mips64el_replay.py)6
-rwxr-xr-xtests/functional/mips64el/test_tuxrun.py (renamed from tests/functional/test_mips64el_tuxrun.py)0
-rw-r--r--tests/functional/mipsel/meson.build12
-rwxr-xr-xtests/functional/mipsel/test_malta.py (renamed from tests/functional/test_mipsel_malta.py)22
-rwxr-xr-x[-rw-r--r--]tests/functional/mipsel/test_replay.py (renamed from tests/functional/test_mipsel_replay.py)2
-rwxr-xr-xtests/functional/mipsel/test_tuxrun.py (renamed from tests/functional/test_mipsel_tuxrun.py)0
-rw-r--r--[-rwxr-xr-x]tests/functional/multiprocess.py (renamed from tests/functional/test_multiprocess.py)41
-rw-r--r--tests/functional/or1k/meson.build6
-rwxr-xr-xtests/functional/or1k/test_replay.py (renamed from tests/functional/test_or1k_replay.py)0
-rwxr-xr-xtests/functional/or1k/test_sim.py (renamed from tests/functional/test_or1k_sim.py)0
-rw-r--r--tests/functional/ppc/meson.build23
-rwxr-xr-xtests/functional/ppc/test_40p.py (renamed from tests/functional/test_ppc_40p.py)0
-rwxr-xr-xtests/functional/ppc/test_74xx.py (renamed from tests/functional/test_ppc_74xx.py)0
-rwxr-xr-xtests/functional/ppc/test_amiga.py (renamed from tests/functional/test_ppc_amiga.py)0
-rwxr-xr-xtests/functional/ppc/test_bamboo.py48
-rwxr-xr-xtests/functional/ppc/test_mac.py (renamed from tests/functional/test_ppc_mac.py)0
-rwxr-xr-xtests/functional/ppc/test_migration.py26
-rwxr-xr-xtests/functional/ppc/test_mpc8544ds.py (renamed from tests/functional/test_ppc_mpc8544ds.py)0
-rw-r--r--tests/functional/ppc/test_ppe42.py79
-rwxr-xr-xtests/functional/ppc/test_replay.py (renamed from tests/functional/test_ppc_replay.py)0
-rwxr-xr-x[-rw-r--r--]tests/functional/ppc/test_sam460ex.py (renamed from tests/functional/test_ppc_sam460ex.py)0
-rwxr-xr-xtests/functional/ppc/test_tuxrun.py (renamed from tests/functional/test_ppc_tuxrun.py)0
-rwxr-xr-xtests/functional/ppc/test_virtex_ml507.py (renamed from tests/functional/test_ppc_virtex_ml507.py)0
-rw-r--r--tests/functional/ppc64/meson.build26
-rwxr-xr-xtests/functional/ppc64/test_e500.py (renamed from tests/functional/test_ppc64_e500.py)0
-rwxr-xr-xtests/functional/ppc64/test_hv.py (renamed from tests/functional/test_ppc64_hv.py)8
-rwxr-xr-xtests/functional/ppc64/test_mac99.py (renamed from tests/functional/test_ppc64_mac99.py)0
-rwxr-xr-xtests/functional/ppc64/test_migration.py26
-rwxr-xr-xtests/functional/ppc64/test_powernv.py (renamed from tests/functional/test_ppc64_powernv.py)34
-rwxr-xr-xtests/functional/ppc64/test_pseries.py (renamed from tests/functional/test_ppc64_pseries.py)1
-rwxr-xr-xtests/functional/ppc64/test_replay.py (renamed from tests/functional/test_ppc64_replay.py)0
-rwxr-xr-xtests/functional/ppc64/test_reverse_debug.py38
-rwxr-xr-xtests/functional/ppc64/test_tuxrun.py (renamed from tests/functional/test_ppc64_tuxrun.py)0
-rw-r--r--tests/functional/qemu_test/__init__.py4
-rw-r--r--tests/functional/qemu_test/asset.py25
-rw-r--r--tests/functional/qemu_test/cmd.py67
-rw-r--r--tests/functional/qemu_test/decorators.py51
-rw-r--r--tests/functional/qemu_test/gdb.py86
-rw-r--r--tests/functional/qemu_test/ports.py8
-rw-r--r--tests/functional/qemu_test/testcase.py29
-rw-r--r--tests/functional/qemu_test/tuxruntest.py11
-rw-r--r--tests/functional/qemu_test/uncompress.py2
-rw-r--r--tests/functional/replay_kernel.py16
-rw-r--r--tests/functional/reverse_debugging.py202
-rw-r--r--tests/functional/riscv32/meson.build10
-rwxr-xr-xtests/functional/riscv32/test_migration.py26
-rwxr-xr-xtests/functional/riscv32/test_opensbi.py10
-rwxr-xr-xtests/functional/riscv32/test_tuxrun.py (renamed from tests/functional/test_riscv32_tuxrun.py)0
-rw-r--r--tests/functional/riscv64/meson.build15
-rwxr-xr-xtests/functional/riscv64/test_migration.py26
-rwxr-xr-xtests/functional/riscv64/test_opensbi.py (renamed from tests/functional/test_riscv_opensbi.py)0
-rwxr-xr-xtests/functional/riscv64/test_sifive_u.py63
-rwxr-xr-xtests/functional/riscv64/test_tuxrun.py (renamed from tests/functional/test_riscv64_tuxrun.py)0
-rw-r--r--tests/functional/rx/meson.build5
-rwxr-xr-xtests/functional/rx/test_gdbsim.py (renamed from tests/functional/test_rx_gdbsim.py)0
-rw-r--r--tests/functional/s390x/meson.build17
-rwxr-xr-xtests/functional/s390x/test_ccw_virtio.py (renamed from tests/functional/test_s390x_ccw_virtio.py)0
-rwxr-xr-xtests/functional/s390x/test_pxelinux.py130
-rwxr-xr-xtests/functional/s390x/test_replay.py (renamed from tests/functional/test_s390x_replay.py)0
-rwxr-xr-xtests/functional/s390x/test_topology.py (renamed from tests/functional/test_s390x_topology.py)12
-rwxr-xr-xtests/functional/s390x/test_tuxrun.py (renamed from tests/functional/test_s390x_tuxrun.py)1
-rw-r--r--tests/functional/sh4/meson.build10
-rwxr-xr-xtests/functional/sh4/test_r2d.py (renamed from tests/functional/test_sh4_r2d.py)0
-rwxr-xr-xtests/functional/sh4/test_tuxrun.py (renamed from tests/functional/test_sh4_tuxrun.py)0
-rw-r--r--tests/functional/sh4eb/meson.build5
-rwxr-xr-xtests/functional/sh4eb/test_r2d.py (renamed from tests/functional/test_sh4eb_r2d.py)0
-rw-r--r--tests/functional/sparc/meson.build10
-rwxr-xr-xtests/functional/sparc/test_migration.py26
-rwxr-xr-xtests/functional/sparc/test_replay.py (renamed from tests/functional/test_sparc_replay.py)0
-rwxr-xr-xtests/functional/sparc/test_sun4m.py (renamed from tests/functional/test_sparc_sun4m.py)0
-rw-r--r--tests/functional/sparc64/meson.build10
-rwxr-xr-xtests/functional/sparc64/test_migration.py26
-rwxr-xr-xtests/functional/sparc64/test_sun4u.py (renamed from tests/functional/test_sparc64_sun4u.py)0
-rwxr-xr-xtests/functional/sparc64/test_tuxrun.py (renamed from tests/functional/test_sparc64_tuxrun.py)1
-rwxr-xr-xtests/functional/test_aarch64_replay.py30
-rwxr-xr-xtests/functional/test_aarch64_rme_sbsaref.py71
-rwxr-xr-xtests/functional/test_aarch64_rme_virt.py101
-rwxr-xr-xtests/functional/test_mips_malta.py94
-rwxr-xr-xtests/functional/test_ppc_bamboo.py44
-rwxr-xr-xtests/functional/test_x86_64_replay.py35
-rw-r--r--tests/functional/x86_64/meson.build39
-rwxr-xr-xtests/functional/x86_64/test_acpi_bits.py (renamed from tests/functional/test_acpi_bits.py)31
-rwxr-xr-xtests/functional/x86_64/test_bad_vmstate.py58
-rwxr-xr-xtests/functional/x86_64/test_cpu_model_versions.py (renamed from tests/functional/test_x86_cpu_model_versions.py)110
-rwxr-xr-xtests/functional/x86_64/test_cpu_queries.py (renamed from tests/functional/test_cpu_queries.py)0
-rwxr-xr-xtests/functional/x86_64/test_hotplug_blk.py (renamed from tests/functional/test_x86_64_hotplug_blk.py)0
-rwxr-xr-xtests/functional/x86_64/test_hotplug_cpu.py (renamed from tests/functional/test_x86_64_hotplug_cpu.py)0
-rwxr-xr-xtests/functional/x86_64/test_intel_iommu.py (renamed from tests/functional/test_intel_iommu.py)0
-rwxr-xr-xtests/functional/x86_64/test_kvm_xen.py (renamed from tests/functional/test_x86_64_kvm_xen.py)2
-rwxr-xr-xtests/functional/x86_64/test_linux_initrd.py (renamed from tests/functional/test_linux_initrd.py)0
-rwxr-xr-xtests/functional/x86_64/test_mem_addr_space.py (renamed from tests/functional/test_mem_addr_space.py)63
-rwxr-xr-xtests/functional/x86_64/test_memlock.py80
-rwxr-xr-xtests/functional/x86_64/test_migration.py26
-rwxr-xr-xtests/functional/x86_64/test_multiprocess.py31
-rwxr-xr-xtests/functional/x86_64/test_netdev_ethtool.py (renamed from tests/functional/test_netdev_ethtool.py)0
-rwxr-xr-xtests/functional/x86_64/test_pc_cpu_hotplug_props.py (renamed from tests/functional/test_pc_cpu_hotplug_props.py)1
-rwxr-xr-xtests/functional/x86_64/test_replay.py58
-rwxr-xr-xtests/functional/x86_64/test_reverse_debug.py31
-rwxr-xr-xtests/functional/x86_64/test_tuxrun.py (renamed from tests/functional/test_x86_64_tuxrun.py)0
-rwxr-xr-xtests/functional/x86_64/test_vfio_user_client.py201
-rwxr-xr-xtests/functional/x86_64/test_virtio_balloon.py (renamed from tests/functional/test_virtio_balloon.py)0
-rwxr-xr-xtests/functional/x86_64/test_virtio_gpu.py (renamed from tests/functional/test_virtio_gpu.py)2
-rwxr-xr-xtests/functional/x86_64/test_virtio_version.py (renamed from tests/functional/test_virtio_version.py)0
-rw-r--r--tests/functional/xtensa/meson.build6
-rwxr-xr-xtests/functional/xtensa/test_lx60.py (renamed from tests/functional/test_xtensa_lx60.py)0
-rwxr-xr-xtests/functional/xtensa/test_replay.py (renamed from tests/functional/test_xtensa_replay.py)0
211 files changed, 4097 insertions, 1158 deletions
diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch64/meson.build
new file mode 100644
index 0000000..5ad52f9
--- /dev/null
+++ b/tests/functional/aarch64/meson.build
@@ -0,0 +1,49 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_aarch64_timeouts = {
+ 'aspeed_ast2700' : 600,
+ 'aspeed_ast2700fc' : 600,
+ 'device_passthrough' : 720,
+ 'imx8mp_evk' : 240,
+ 'raspi4' : 480,
+ 'reverse_debug' : 180,
+ 'rme_virt' : 1200,
+ 'rme_sbsaref' : 1200,
+ 'sbsaref_alpine' : 1200,
+ 'sbsaref_freebsd' : 720,
+ 'smmu' : 720,
+ 'tuxrun' : 240,
+ 'virt' : 360,
+ 'virt_gpu' : 480,
+}
+
+tests_aarch64_system_quick = [
+ 'migration',
+ 'vmstate',
+]
+
+tests_aarch64_system_thorough = [
+ 'aspeed_ast2700',
+ 'aspeed_ast2700fc',
+ 'device_passthrough',
+ 'hotplug_pci',
+ 'imx8mp_evk',
+ 'kvm',
+ 'multiprocess',
+ 'raspi3',
+ 'raspi4',
+ 'replay',
+ 'reverse_debug',
+ 'rme_virt',
+ 'rme_sbsaref',
+ 'sbsaref',
+ 'sbsaref_alpine',
+ 'sbsaref_freebsd',
+ 'smmu',
+ 'tcg_plugins',
+ 'tuxrun',
+ 'virt',
+ 'virt_gpu',
+ 'xen',
+ 'xlnx_versal',
+]
diff --git a/tests/functional/test_aarch64_aspeed.py b/tests/functional/aarch64/test_aspeed_ast2700.py
index c25c966..0ced1a2 100755
--- a/tests/functional/test_aarch64_aspeed.py
+++ b/tests/functional/aarch64/test_aspeed_ast2700.py
@@ -18,22 +18,64 @@ class AST2x00MachineSDK(QemuSystemTest):
def do_test_aarch64_aspeed_sdk_start(self, image):
self.require_netdev('user')
self.vm.set_console()
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
'-net', 'nic', '-net', 'user', '-snapshot')
self.vm.launch()
+ def verify_vbootrom_firmware_flow(self):
+ wait_for_console_pattern(self, 'Found valid FIT image')
+ wait_for_console_pattern(self, '[uboot] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[fdt] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[tee] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, '[atf] loading')
+ wait_for_console_pattern(self, 'done')
+ wait_for_console_pattern(self, 'Jumping to BL31 (Trusted Firmware-A)')
+
+ def verify_openbmc_boot_start(self):
wait_for_console_pattern(self, 'U-Boot 2023.10')
wait_for_console_pattern(self, '## Loading kernel from FIT Image')
- wait_for_console_pattern(self, 'Starting kernel ...')
+ wait_for_console_pattern(self, 'Linux version ')
+
+ def verify_openbmc_boot_and_login(self, name):
+ self.verify_openbmc_boot_start()
- ASSET_SDK_V905_AST2700 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-a0-default-obmc.tar.gz',
- 'cfbbd1cce72f2a3b73b9080c41eecdadebb7077fba4f7806d72ac99f3e84b74a')
+ wait_for_console_pattern(self, f'{name} login:')
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
- ASSET_SDK_V905_AST2700A1 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.05/ast2700-default-obmc.tar.gz',
- 'c1f4496aec06743c812a6e9a1a18d032f34d62f3ddb6956e924fef62aa2046a5')
+ ASSET_SDK_V908_AST2700A1 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2700-default-obmc.tar.gz',
+ 'eac3dc409b7ea3cd4b03d4792d3cebd469792ad893cb51e1d15f0fc20bd1e2cd')
+
+ def do_ast2700_i2c_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+
+ def do_ast2700_pcie_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 0002:00:00.0',
+ '0002:00:00.0 PCI bridge: '
+ 'ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 0002:01:00.0',
+ '0002:01:00.0 Ethernet controller: '
+ 'Intel Corporation 82574L Gigabit Network Connection')
+ exec_command_and_wait_for_pattern(self,
+ 'ip addr show dev eth2',
+ 'inet 10.0.2.15/24')
def start_ast2700_test(self, name):
num_cpu = 4
@@ -73,38 +115,36 @@ class AST2x00MachineSDK(QemuSystemTest):
f'loader,addr=0x430000000,cpu-num={i}')
self.vm.add_args('-smp', str(num_cpu))
- self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
self.do_test_aarch64_aspeed_sdk_start(
self.scratch_file(name, 'image-bmc'))
- wait_for_console_pattern(self, f'{name} login:')
-
- exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
-
- exec_command_and_wait_for_pattern(self,
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
- 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d');
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000)
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
-
- def test_aarch64_ast2700_evb_sdk_v09_05(self):
- self.set_machine('ast2700-evb')
-
- self.archive_extract(self.ASSET_SDK_V905_AST2700)
- self.start_ast2700_test('ast2700-a0-default')
+ def start_ast2700_test_vbootrom(self, name):
+ self.vm.add_args('-bios', 'ast27x0_bootrom.bin')
+ self.do_test_aarch64_aspeed_sdk_start(
+ self.scratch_file(name, 'image-bmc'))
- def test_aarch64_ast2700a1_evb_sdk_v09_05(self):
+ def test_aarch64_ast2700a1_evb_sdk_v09_08(self):
self.set_machine('ast2700a1-evb')
+ self.require_netdev('user')
- self.archive_extract(self.ASSET_SDK_V905_AST2700A1)
+ self.archive_extract(self.ASSET_SDK_V908_AST2700A1)
+ self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.2')
+ self.vm.add_args('-netdev', 'user,id=net1')
self.start_ast2700_test('ast2700-default')
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
+ self.do_ast2700_pcie_test()
+
+ def test_aarch64_ast2700a1_evb_sdk_vbootrom_v09_08(self):
+ self.set_machine('ast2700a1-evb')
+ self.require_netdev('user')
+ self.archive_extract(self.ASSET_SDK_V908_AST2700A1)
+ self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.2')
+ self.vm.add_args('-netdev', 'user,id=net1')
+ self.start_ast2700_test_vbootrom('ast2700-default')
+ self.verify_vbootrom_firmware_flow()
+ self.verify_openbmc_boot_start()
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_aspeed_ast2700fc.py b/tests/functional/aarch64/test_aspeed_ast2700fc.py
new file mode 100755
index 0000000..28b6661
--- /dev/null
+++ b/tests/functional/aarch64/test_aspeed_ast2700fc.py
@@ -0,0 +1,148 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED SoCs with firmware
+#
+# Copyright (C) 2022 ASPEED Technology Inc
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class AST2x00MachineSDK(QemuSystemTest):
+
+ def do_test_aarch64_aspeed_sdk_start(self, image):
+ self.require_netdev('user')
+ self.vm.set_console()
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.1,address=0x4d,id=tmp-test')
+ self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.2')
+ self.vm.add_args('-netdev', 'user,id=net1')
+ self.vm.add_args('-drive', 'file=' + image + ',if=mtd,format=raw',
+ '-net', 'nic', '-net', 'user', '-snapshot')
+
+ self.vm.launch()
+
+ def verify_openbmc_boot_and_login(self, name):
+ wait_for_console_pattern(self, 'U-Boot 2023.10')
+ wait_for_console_pattern(self, '## Loading kernel from FIT Image')
+ wait_for_console_pattern(self, 'Starting kernel ...')
+
+ wait_for_console_pattern(self, f'{name} login:')
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc', f'root@{name}:~#')
+
+ ASSET_SDK_V906_AST2700 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.06/ast2700-default-obmc.tar.gz',
+ 'f1d53e0be8a404ecce3e105f72bc50fa4e090ad13160ffa91b10a6e0233a9dc6')
+
+ def do_ast2700_i2c_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-1/device/new_device ',
+ 'i2c i2c-1: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/bus/i2c/devices/1-004d/hwmon/hwmon*/temp1_input', '18000')
+
+ def do_ast2700_pcie_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 0002:00:00.0',
+ '0002:00:00.0 PCI bridge: '
+ 'ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 0002:01:00.0',
+ '0002:01:00.0 Ethernet controller: '
+ 'Intel Corporation 82574L Gigabit Network Connection')
+
+ def do_ast2700fc_ssp_test(self):
+ self.vm.shutdown()
+ self.vm.set_console(console_index=1)
+ self.vm.launch()
+
+ exec_command_and_wait_for_pattern(self, '\012', 'ssp:~$')
+ exec_command_and_wait_for_pattern(self, 'version',
+ 'Zephyr version 3.7.1')
+ exec_command_and_wait_for_pattern(self, 'md 72c02000 1',
+ '[72c02000] 06010103')
+
+ def do_ast2700fc_tsp_test(self):
+ self.vm.shutdown()
+ self.vm.set_console(console_index=2)
+ self.vm.launch()
+
+ exec_command_and_wait_for_pattern(self, '\012', 'tsp:~$')
+ exec_command_and_wait_for_pattern(self, 'version',
+ 'Zephyr version 3.7.1')
+ exec_command_and_wait_for_pattern(self, 'md 72c02000 1',
+ '[72c02000] 06010103')
+
+ def start_ast2700fc_test(self, name):
+ ca35_core = 4
+ uboot_size = os.path.getsize(self.scratch_file(name,
+ 'u-boot-nodtb.bin'))
+ uboot_dtb_load_addr = hex(0x400000000 + uboot_size)
+
+ load_images_list = [
+ {
+ 'addr': '0x400000000',
+ 'file': self.scratch_file(name,
+ 'u-boot-nodtb.bin')
+ },
+ {
+ 'addr': str(uboot_dtb_load_addr),
+ 'file': self.scratch_file(name, 'u-boot.dtb')
+ },
+ {
+ 'addr': '0x430000000',
+ 'file': self.scratch_file(name, 'bl31.bin')
+ },
+ {
+ 'addr': '0x430080000',
+ 'file': self.scratch_file(name, 'optee',
+ 'tee-raw.bin')
+ }
+ ]
+
+ for load_image in load_images_list:
+ addr = load_image['addr']
+ file = load_image['file']
+ self.vm.add_args('-device',
+ f'loader,force-raw=on,addr={addr},file={file}')
+
+ for i in range(ca35_core):
+ self.vm.add_args('-device',
+ f'loader,addr=0x430000000,cpu-num={i}')
+
+ load_elf_list = {
+ 'ssp': self.scratch_file(name, 'zephyr-aspeed-ssp.elf'),
+ 'tsp': self.scratch_file(name, 'zephyr-aspeed-tsp.elf')
+ }
+
+ for cpu_num, key in enumerate(load_elf_list, start=4):
+ file = load_elf_list[key]
+ self.vm.add_args('-device',
+ f'loader,file={file},cpu-num={cpu_num}')
+
+ self.do_test_aarch64_aspeed_sdk_start(
+ self.scratch_file(name, 'image-bmc'))
+
+ def test_aarch64_ast2700fc_sdk_v09_06(self):
+ self.set_machine('ast2700fc')
+
+ self.archive_extract(self.ASSET_SDK_V906_AST2700)
+ self.start_ast2700fc_test('ast2700-default')
+ self.verify_openbmc_boot_and_login('ast2700-default')
+ self.do_ast2700_i2c_test()
+ self.do_ast2700_pcie_test()
+ self.do_ast2700fc_ssp_test()
+ self.do_ast2700fc_tsp_test()
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_device_passthrough.py b/tests/functional/aarch64/test_device_passthrough.py
new file mode 100755
index 0000000..05a3f52
--- /dev/null
+++ b/tests/functional/aarch64/test_device_passthrough.py
@@ -0,0 +1,143 @@
+#!/usr/bin/env python3
+#
+# Boots a nested guest and compare content of a device (passthrough) to a
+# reference image. Both vfio group and iommufd passthrough methods are tested.
+#
+# Copyright (c) 2025 Linaro Ltd.
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from os.path import join
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import exec_command, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+from random import randbytes
+
+guest_script = '''
+#!/usr/bin/env bash
+
+set -euo pipefail
+set -x
+
+# find disks from nvme serial
+dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
+dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
+pci_vfio=$(basename $(readlink -f /sys/block/$dev_vfio/../../../))
+pci_iommufd=$(basename $(readlink -f /sys/block/$dev_iommufd/../../../))
+
+# bind disks to vfio
+for p in "$pci_vfio" "$pci_iommufd"; do
+ if [ "$(cat /sys/bus/pci/devices/$p/driver_override)" == vfio-pci ]; then
+ continue
+ fi
+ echo $p > /sys/bus/pci/drivers/nvme/unbind
+ echo vfio-pci > /sys/bus/pci/devices/$p/driver_override
+ echo $p > /sys/bus/pci/drivers/vfio-pci/bind
+done
+
+# boot nested guest and execute /host/nested_guest.sh
+# one disk is passed through vfio group, the other, through iommufd
+qemu-system-aarch64 \
+-M virt \
+-display none \
+-serial stdio \
+-cpu host \
+-enable-kvm \
+-m 1G \
+-kernel /host/Image.gz \
+-drive format=raw,file=/host/guest.ext4,if=virtio \
+-append "root=/dev/vda init=/init -- bash /host/nested_guest.sh" \
+-virtfs local,path=/host,mount_tag=host,security_model=mapped,readonly=off \
+-device vfio-pci,host=$pci_vfio \
+-object iommufd,id=iommufd0 \
+-device vfio-pci,host=$pci_iommufd,iommufd=iommufd0
+'''
+
+nested_guest_script = '''
+#!/usr/bin/env bash
+
+set -euo pipefail
+set -x
+
+image_vfio=/host/disk_vfio
+image_iommufd=/host/disk_iommufd
+
+dev_vfio=$(lsblk --nvme | grep vfio | cut -f 1 -d ' ')
+dev_iommufd=$(lsblk --nvme | grep iommufd | cut -f 1 -d ' ')
+
+# compare if devices are identical to original images
+diff $image_vfio /dev/$dev_vfio
+diff $image_iommufd /dev/$dev_iommufd
+
+echo device_passthrough_test_ok
+'''
+
+class Aarch64DevicePassthrough(QemuSystemTest):
+
+ # https://github.com/pbo-linaro/qemu-linux-stack/tree/device_passthrough
+ # $ ./build.sh && ./archive_artifacts.sh out.tar.xz
+ #
+ # Linux kernel is compiled with defconfig +
+ # IOMMUFD + VFIO_DEVICE_CDEV + ARM_SMMU_V3_IOMMUFD
+ # https://docs.kernel.org/driver-api/vfio.html#vfio-device-cde
+ ASSET_DEVICE_PASSTHROUGH_STACK = Asset(
+ ('https://github.com/pbo-linaro/qemu-linux-stack/'
+ 'releases/download/build/device_passthrough-a9612a2.tar.xz'),
+ 'f7d2f70912e7231986e6e293e1a2c4786dd02bec113a7acb6bfc619e96155455')
+
+ # This tests the device passthrough implementation, by booting a VM
+ # supporting it with two nvme disks attached, and launching a nested VM
+ # reading their content.
+ def test_aarch64_device_passthrough(self):
+ self.set_machine('virt')
+ self.require_accelerator('tcg')
+
+ self.vm.set_console()
+
+ stack_path_tar = self.ASSET_DEVICE_PASSTHROUGH_STACK.fetch()
+ self.archive_extract(stack_path_tar, format="tar")
+
+ stack = self.scratch_file('out')
+ kernel = join(stack, 'Image.gz')
+ rootfs_host = join(stack, 'host.ext4')
+ disk_vfio = join(stack, 'disk_vfio')
+ disk_iommufd = join(stack, 'disk_iommufd')
+ guest_cmd = join(stack, 'guest.sh')
+ nested_guest_cmd = join(stack, 'nested_guest.sh')
+ # we generate two random disks
+ with open(disk_vfio, "wb") as d: d.write(randbytes(512))
+ with open(disk_iommufd, "wb") as d: d.write(randbytes(1024))
+ with open(guest_cmd, 'w') as s: s.write(guest_script)
+ with open(nested_guest_cmd, 'w') as s: s.write(nested_guest_script)
+
+ self.vm.add_args('-cpu', 'max')
+ self.vm.add_args('-m', '2G')
+ self.vm.add_args('-M', 'virt,'
+ 'virtualization=on,'
+ 'gic-version=max,'
+ 'iommu=smmuv3')
+ self.vm.add_args('-kernel', kernel)
+ self.vm.add_args('-drive', f'format=raw,file={rootfs_host}')
+ self.vm.add_args('-drive',
+ f'file={disk_vfio},if=none,id=vfio,format=raw')
+ self.vm.add_args('-device', 'nvme,serial=vfio,drive=vfio')
+ self.vm.add_args('-drive',
+ f'file={disk_iommufd},if=none,id=iommufd,format=raw')
+ self.vm.add_args('-device', 'nvme,serial=iommufd,drive=iommufd')
+ self.vm.add_args('-virtfs',
+ f'local,path={stack}/,mount_tag=host,'
+ 'security_model=mapped,readonly=off')
+ # boot and execute guest script
+ # init will trigger a kernel panic if script fails
+ self.vm.add_args('-append',
+ 'root=/dev/vda init=/init -- bash /host/guest.sh')
+
+ self.vm.launch()
+ wait_for_console_pattern(self, 'device_passthrough_test_ok',
+ failure_message='Kernel panic')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_hotplug_pci.py b/tests/functional/aarch64/test_hotplug_pci.py
new file mode 100755
index 0000000..bf67720
--- /dev/null
+++ b/tests/functional/aarch64/test_hotplug_pci.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+#
+# The test hotplugs a PCI device and checks it on a Linux guest.
+#
+# Copyright (c) 2025 Linaro Ltd.
+#
+# Author:
+# Gustavo Romero <gustavo.romero@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import BUILD_DIR
+
+class HotplugPCI(LinuxKernelTest):
+
+ ASSET_KERNEL = Asset(
+ ('https://ftp.debian.org/debian/dists/trixie/main/installer-arm64/'
+ '20250803/images/netboot/debian-installer/arm64/linux'),
+ '93a6e4f9627d759375d28f863437a86a0659e125792a435f8e526dda006b7d5e')
+
+ ASSET_INITRD = Asset(
+ ('https://ftp.debian.org/debian/dists/trixie/main/installer-arm64/'
+ '20250803/images/netboot/debian-installer/arm64/initrd.gz'),
+ 'f6c78af7078ca67638ef3a50c926cd3c1485673243f8b37952e6bd854d6ba007')
+
+ def test_hotplug_pci(self):
+
+ self.set_machine('virt')
+
+ self.vm.add_args('-m', '512M',
+ '-cpu', 'cortex-a57',
+ '-append',
+ 'console=ttyAMA0,115200 init=/bin/sh',
+ '-device',
+ 'pcie-root-port,bus=pcie.0,chassis=1,slot=1,id=pcie.1',
+ '-bios',
+ self.build_file('pc-bios', 'edk2-aarch64-code.fd'))
+
+ # BusyBox prompt
+ prompt = "~ #"
+ self.launch_kernel(self.ASSET_KERNEL.fetch(),
+ self.ASSET_INITRD.fetch(),
+ wait_for=prompt)
+
+ # Check for initial state: 2 network adapters, lo and enp0s1.
+ exec_command_and_wait_for_pattern(self,
+ 'ls /sys/class/net | wc -l',
+ '2')
+
+ # Hotplug one network adapter to the root port, i.e. pcie.1 bus.
+ self.vm.cmd('device_add',
+ driver='virtio-net-pci',
+ bus='pcie.1',
+ addr=0,
+ id='na')
+ # Wait for the kernel to recognize the new device.
+ self.wait_for_console_pattern('virtio-pci')
+ self.wait_for_console_pattern('virtio_net')
+
+ # Check if there is a new network adapter.
+ exec_command_and_wait_for_pattern(self,
+ 'ls /sys/class/net | wc -l',
+ '3')
+
+ self.vm.cmd('device_del', id='na')
+ exec_command_and_wait_for_pattern(self,
+ 'ls /sys/class/net | wc -l',
+ '2')
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/aarch64/test_imx8mp_evk.py b/tests/functional/aarch64/test_imx8mp_evk.py
new file mode 100755
index 0000000..99ddcde
--- /dev/null
+++ b/tests/functional/aarch64/test_imx8mp_evk.py
@@ -0,0 +1,68 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+
+
+class Imx8mpEvkMachine(LinuxKernelTest):
+
+ ASSET_IMAGE = Asset(
+ ('https://cloud.debian.org/images/cloud/bookworm/20231210-1590/'
+ 'debian-12-generic-arm64-20231210-1590.tar.xz'),
+ '7ebf1577b32d5af6204df74b54ca2e4675de9b5a9fa14f3ff70b88eeb7b3b359')
+
+ KERNEL_OFFSET = 0x51000000
+ KERNEL_SIZE = 32622528
+ INITRD_OFFSET = 0x76000000
+ INITRD_SIZE = 30987766
+ DTB_OFFSET = 0x64F51000
+ DTB_SIZE = 45 * 1024
+
+ def extract(self, in_path, out_path, offset, size):
+ try:
+ with open(in_path, "rb") as source:
+ source.seek(offset)
+ data = source.read(size)
+ with open(out_path, "wb") as target:
+ target.write(data)
+ except (IOError, ValueError) as e:
+ self.log.error(f"Failed to extract {out_path}: {e}")
+ raise
+
+ def setUp(self):
+ super().setUp()
+
+ self.image_path = self.scratch_file("disk.raw")
+ self.kernel_path = self.scratch_file("linux")
+ self.initrd_path = self.scratch_file("initrd.zstd")
+ self.dtb_path = self.scratch_file("imx8mp-evk.dtb")
+
+ self.archive_extract(self.ASSET_IMAGE)
+ self.extract(self.image_path, self.kernel_path,
+ self.KERNEL_OFFSET, self.KERNEL_SIZE)
+ self.extract(self.image_path, self.initrd_path,
+ self.INITRD_OFFSET, self.INITRD_SIZE)
+ self.extract(self.image_path, self.dtb_path,
+ self.DTB_OFFSET, self.DTB_SIZE)
+
+ def test_aarch64_imx8mp_evk_usdhc(self):
+ self.require_accelerator("tcg")
+ self.set_machine('imx8mp-evk')
+ self.vm.set_console(console_index=1)
+ self.vm.add_args('-m', '2G',
+ '-smp', '4',
+ '-kernel', self.kernel_path,
+ '-initrd', self.initrd_path,
+ '-dtb', self.dtb_path,
+ '-append', 'root=/dev/mmcblk2p1',
+ '-drive', f'file={self.image_path},if=sd,bus=2,'
+ 'format=raw,id=mmcblk2,snapshot=on')
+
+ self.vm.launch()
+ self.wait_for_console_pattern('Welcome to ')
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/aarch64/test_kvm.py b/tests/functional/aarch64/test_kvm.py
new file mode 100755
index 0000000..9fb9286
--- /dev/null
+++ b/tests/functional/aarch64/test_kvm.py
@@ -0,0 +1,71 @@
+#!/usr/bin/env python3
+#
+# Functional test that runs subsets of kvm-unit-tests on Aarch64.
+# These can run on TCG and any accelerator supporting nested
+# virtualisation.
+#
+# Copyright (c) 2025 Linaro
+#
+# Author:
+# Alex Bennée <alex.bennee@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from qemu_test import exec_command_and_wait_for_pattern as ec_and_wait
+from qemu_test.linuxkernel import LinuxKernelTest
+
+
+class Aarch64VirtKVMTests(LinuxKernelTest):
+
+ ASSET_KVM_TEST_KERNEL = Asset(
+ 'https://fileserver.linaro.org/s/HmjaxXXYHYSqbes/'
+ 'download?path=%2F&files='
+ 'image-with-kvm-tool-and-unit-tests.gz',
+ '34de4aaea90db5da42729e7d28b77f392c37a2f4da859f889a5234aaf0970696')
+
+ # make it easier to detect successful return to shell
+ PS1 = 'RES=[$?] # '
+ OK_CMD = 'RES=[0] # '
+
+ # base of tests
+ KUT_BASE = "/usr/share/kvm-unit-tests/"
+
+ def _launch_guest(self, kvm_mode="nvhe"):
+
+ self.set_machine('virt')
+ kernel_path = self.ASSET_KVM_TEST_KERNEL.fetch()
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ f"console=ttyAMA0 kvm-arm.mode={kvm_mode}")
+
+ self.vm.add_args("-cpu", "cortex-a72")
+ self.vm.add_args("-machine", "virt,gic-version=3,virtualization=on",
+ '-kernel', kernel_path,
+ '-append', kernel_command_line)
+ self.vm.add_args("-smp", "2", "-m", "320")
+
+ self.vm.launch()
+
+ self.wait_for_console_pattern('buildroot login:')
+ ec_and_wait(self, 'root', '#')
+ ec_and_wait(self, f"export PS1='{self.PS1}'", self.OK_CMD)
+
+ # this is just a smoketest, we don't run all the tests in the image
+ def _smoketest_kvm(self):
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-setup", self.OK_CMD)
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-smp", self.OK_CMD)
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-kernel", self.OK_CMD)
+ ec_and_wait(self, f"{self.KUT_BASE}/selftest-vectors-user", self.OK_CMD)
+
+ def test_aarch64_nvhe_selftest(self):
+ self._launch_guest("nvhe")
+ self._smoketest_kvm()
+
+ def test_aarch64_vhe_selftest(self):
+ self._launch_guest("vhe")
+ self._smoketest_kvm()
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/aarch64/test_migration.py b/tests/functional/aarch64/test_migration.py
new file mode 100755
index 0000000..70267e7
--- /dev/null
+++ b/tests/functional/aarch64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# aarch64 migration test
+
+from migration import MigrationTest
+
+
+class Aarch64MigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('quanta-gsj')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('quanta-gsj')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('quanta-gsj')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/aarch64/test_multiprocess.py b/tests/functional/aarch64/test_multiprocess.py
new file mode 100755
index 0000000..1c6e45e
--- /dev/null
+++ b/tests/functional/aarch64/test_multiprocess.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Test for multiprocess qemu on aarch64
+
+from multiprocess import Multiprocess
+from qemu_test import Asset
+
+
+class Aarch64Multiprocess(Multiprocess):
+
+ ASSET_KERNEL_AARCH64 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+ '/releases/31/Everything/aarch64/os/images/pxeboot/vmlinuz'),
+ '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
+
+ ASSET_INITRD_AARCH64 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+ '/releases/31/Everything/aarch64/os/images/pxeboot/initrd.img'),
+ '9fd230cab10b1dafea41cf00150e6669d37051fad133bd618d2130284e16d526')
+
+ def test_multiprocess(self):
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'rdinit=/bin/bash console=ttyAMA0')
+ self.do_test(self.ASSET_KERNEL_AARCH64, self.ASSET_INITRD_AARCH64,
+ kernel_command_line, 'virt,gic-version=3')
+
+
+if __name__ == '__main__':
+ Multiprocess.main()
diff --git a/tests/functional/test_aarch64_raspi3.py b/tests/functional/aarch64/test_raspi3.py
index 74f6630..74f6630 100755
--- a/tests/functional/test_aarch64_raspi3.py
+++ b/tests/functional/aarch64/test_raspi3.py
diff --git a/tests/functional/test_aarch64_raspi4.py b/tests/functional/aarch64/test_raspi4.py
index 7a4302b..7a4302b 100755
--- a/tests/functional/test_aarch64_raspi4.py
+++ b/tests/functional/aarch64/test_raspi4.py
diff --git a/tests/functional/aarch64/test_replay.py b/tests/functional/aarch64/test_replay.py
new file mode 100755
index 0000000..db12e76
--- /dev/null
+++ b/tests/functional/aarch64/test_replay.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+#
+# Replay test that boots a Linux kernel on an aarch64 machine
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from subprocess import check_call, DEVNULL
+
+from qemu_test import Asset, skipIfOperatingSystem, get_qemu_img
+from replay_kernel import ReplayKernelBase
+
+
+class Aarch64Replay(ReplayKernelBase):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/Image',
+ 'b74743c5e89e1cea0f73368d24ae0ae85c5204ff84be3b5e9610417417d2f235')
+
+ ASSET_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/arm64/rootfs.ext4.zst',
+ 'a1acaaae2068df4648d04ff75f532aaa8c5edcd6b936122b6f0db4848a07b465')
+
+ def test_aarch64_virt(self):
+ self.require_netdev('user')
+ self.set_machine('virt')
+ self.cpu = 'cortex-a57'
+ kernel_path = self.ASSET_KERNEL.fetch()
+
+ raw_disk = self.uncompress(self.ASSET_ROOTFS)
+ disk = self.scratch_file('scratch.qcow2')
+ qemu_img = get_qemu_img(self)
+ check_call([qemu_img, 'create', '-f', 'qcow2', '-b', raw_disk,
+ '-F', 'raw', disk], stdout=DEVNULL, stderr=DEVNULL)
+
+ args = ('-drive', 'file=%s,snapshot=on,id=hd0,if=none' % disk,
+ '-drive', 'driver=blkreplay,id=hd0-rr,if=none,image=hd0',
+ '-device', 'virtio-blk-device,drive=hd0-rr',
+ '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', 'virtio-net,netdev=vnet',
+ '-object', 'filter-replay,id=replay,netdev=vnet')
+
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'console=ttyAMA0 root=/dev/vda')
+ console_pattern = 'Welcome to TuxTest'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern,
+ args=args)
+
+
+if __name__ == '__main__':
+ ReplayKernelBase.main()
diff --git a/tests/functional/aarch64/test_reverse_debug.py b/tests/functional/aarch64/test_reverse_debug.py
new file mode 100755
index 0000000..ec3348c
--- /dev/null
+++ b/tests/functional/aarch64/test_reverse_debug.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test for aarch64
+#
+# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import Asset, skipFlakyTest
+from reverse_debugging import ReverseDebugging
+
+
+class ReverseDebugging_AArch64(ReverseDebugging):
+
+ ASSET_KERNEL = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'),
+ '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7')
+
+ def test_aarch64_virt(self):
+ self.set_machine('virt')
+ self.cpu = 'cortex-a53'
+ kernel_path = self.ASSET_KERNEL.fetch()
+ self.reverse_debugging(gdb_arch='aarch64', args=('-kernel', kernel_path))
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff --git a/tests/functional/aarch64/test_rme_sbsaref.py b/tests/functional/aarch64/test_rme_sbsaref.py
new file mode 100755
index 0000000..6f92858
--- /dev/null
+++ b/tests/functional/aarch64/test_rme_sbsaref.py
@@ -0,0 +1,77 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Realms environment on sbsa-ref machine and a
+# nested guest VM using it.
+#
+# Copyright (c) 2024 Linaro Ltd.
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+from os.path import join
+import shutil
+
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class Aarch64RMESbsaRefMachine(QemuSystemTest):
+
+ # Stack is inspired from:
+ # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
+ # https://github.com/pbo-linaro/qemu-linux-stack/tree/rme_sbsa_release
+ # ./build.sh && ./archive_artifacts.sh out.tar.xz
+ ASSET_RME_STACK_SBSA = Asset(
+ ('https://github.com/pbo-linaro/qemu-linux-stack/'
+ 'releases/download/build/rme_sbsa_release-6a2dfc5.tar.xz'),
+ '5adba482aa069912292a8da746c6b21268224d9d81c97fe7c0bed690579ebdcb')
+
+ # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
+ # and launching a nested VM using it.
+ def test_aarch64_rme_sbsaref(self):
+ self.set_machine('sbsa-ref')
+ self.require_accelerator('tcg')
+ self.require_netdev('user')
+
+ self.vm.set_console()
+
+ stack_path_tar = self.ASSET_RME_STACK_SBSA.fetch()
+ self.archive_extract(stack_path_tar, format="tar")
+
+ rme_stack = self.scratch_file('.')
+ pflash0 = join(rme_stack, 'out', 'SBSA_FLASH0.fd')
+ pflash1 = join(rme_stack, 'out', 'SBSA_FLASH1.fd')
+ rootfs = join(rme_stack, 'out', 'host.ext4')
+
+ efi = join(rme_stack, 'out', 'EFI')
+ os.makedirs(efi, exist_ok=True)
+ shutil.copyfile(join(rme_stack, 'out', 'Image'), join(efi, 'Image'))
+ with open(join(efi, 'startup.nsh'), 'w') as startup:
+ startup.write('fs0:Image nokaslr root=/dev/vda rw init=/init --'
+ ' /host/out/lkvm run --realm'
+ ' -m 256m'
+ ' --restricted_mem'
+ ' --kernel /host/out/Image'
+ ' --disk /host/out/guest.ext4'
+ ' --params "root=/dev/vda rw init=/init"')
+
+ self.vm.add_args('-cpu', 'max,x-rme=on')
+ self.vm.add_args('-smp', '2')
+ self.vm.add_args('-m', '2G')
+ self.vm.add_args('-M', 'sbsa-ref')
+ self.vm.add_args('-drive', f'file={pflash0},format=raw,if=pflash')
+ self.vm.add_args('-drive', f'file={pflash1},format=raw,if=pflash')
+ self.vm.add_args('-drive', f'file=fat:rw:{efi},format=raw')
+ self.vm.add_args('-drive', f'format=raw,file={rootfs},if=virtio')
+ self.vm.add_args('-virtfs',
+ f'local,path={rme_stack}/,mount_tag=host,'
+ 'security_model=mapped,readonly=off')
+ self.vm.launch()
+ # Wait for host and guest VM boot to complete.
+ wait_for_console_pattern(self, 'root@guest',
+ failure_message='Kernel panic')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/aarch64/test_rme_virt.py b/tests/functional/aarch64/test_rme_virt.py
new file mode 100755
index 0000000..5e23773
--- /dev/null
+++ b/tests/functional/aarch64/test_rme_virt.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Realms environment on virt machine and a nested
+# guest VM using it.
+#
+# Copyright (c) 2024 Linaro Ltd.
+#
+# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from os.path import join
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import exec_command, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+class Aarch64RMEVirtMachine(QemuSystemTest):
+
+ # Stack is inspired from:
+ # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
+ # https://github.com/pbo-linaro/qemu-linux-stack/tree/rme_release
+ # ./build.sh && ./archive_artifacts.sh out.tar.xz
+ ASSET_RME_STACK_VIRT = Asset(
+ ('https://github.com/pbo-linaro/qemu-linux-stack/'
+ 'releases/download/build/rme_release-56bc99e.tar.xz'),
+ '0e3dc6b8a4b828dbae09c951a40dcb710eded084b32432b50c69cf4173ffa4be')
+
+ # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
+ # and launching a nested VM using it.
+ def test_aarch64_rme_virt(self):
+ self.set_machine('virt')
+ self.require_accelerator('tcg')
+ self.require_netdev('user')
+
+ self.vm.set_console()
+
+ stack_path_tar = self.ASSET_RME_STACK_VIRT.fetch()
+ self.archive_extract(stack_path_tar, format="tar")
+
+ rme_stack = self.scratch_file('.')
+ kernel = join(rme_stack, 'out', 'Image')
+ bios = join(rme_stack, 'out', 'flash.bin')
+ rootfs = join(rme_stack, 'out', 'host.ext4')
+
+ self.vm.add_args('-cpu', 'max,x-rme=on')
+ self.vm.add_args('-smp', '2')
+ self.vm.add_args('-m', '2G')
+ self.vm.add_args('-M', 'virt,acpi=off,'
+ 'virtualization=on,'
+ 'secure=on,'
+ 'gic-version=3')
+ self.vm.add_args('-bios', bios)
+ self.vm.add_args('-kernel', kernel)
+ self.vm.add_args('-drive', f'format=raw,file={rootfs},if=virtio')
+ self.vm.add_args('-virtfs',
+ f'local,path={rme_stack}/,mount_tag=host,'
+ 'security_model=mapped,readonly=off')
+ # We need to add nokaslr to avoid triggering this sporadic bug:
+ # https://gitlab.com/qemu-project/qemu/-/issues/2823
+ self.vm.add_args('-append',
+ 'nokaslr root=/dev/vda rw init=/init --'
+ ' /host/out/lkvm run --realm'
+ ' -m 256m'
+ ' --restricted_mem'
+ ' --kernel /host/out/Image'
+ ' --disk /host/out/guest.ext4'
+ ' --params "root=/dev/vda rw init=/init"')
+
+ self.vm.launch()
+ # Wait for host and guest VM boot to complete.
+ wait_for_console_pattern(self, 'root@guest',
+ failure_message='Kernel panic')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_sbsaref.py b/tests/functional/aarch64/test_sbsaref.py
index e6a55ae..d3402f5 100755
--- a/tests/functional/test_aarch64_sbsaref.py
+++ b/tests/functional/aarch64/test_sbsaref.py
@@ -40,8 +40,6 @@ def fetch_firmware(test):
with open(path, "ab+") as fd:
fd.truncate(256 << 20) # Expand volumes to 256MiB
- test.set_machine('sbsa-ref')
- test.vm.set_console()
test.vm.add_args(
"-drive", f"if=pflash,file={fs0_path},format=raw",
"-drive", f"if=pflash,file={fs1_path},format=raw",
@@ -68,8 +66,11 @@ class Aarch64SbsarefMachine(QemuSystemTest):
def test_sbsaref_edk2_firmware(self):
+ self.set_machine('sbsa-ref')
+
fetch_firmware(self)
+ self.vm.set_console()
self.vm.add_args('-cpu', 'cortex-a57')
self.vm.launch()
diff --git a/tests/functional/test_aarch64_sbsaref_alpine.py b/tests/functional/aarch64/test_sbsaref_alpine.py
index c660cc7..abb8f51 100755
--- a/tests/functional/test_aarch64_sbsaref_alpine.py
+++ b/tests/functional/aarch64/test_sbsaref_alpine.py
@@ -10,12 +10,9 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern
-from unittest import skipUnless
-from test_aarch64_sbsaref import fetch_firmware
+from test_sbsaref import fetch_firmware
class Aarch64SbsarefAlpine(QemuSystemTest):
@@ -29,8 +26,9 @@ class Aarch64SbsarefAlpine(QemuSystemTest):
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
def boot_alpine_linux(self, cpu=None):
- fetch_firmware(self)
+ self.set_machine('sbsa-ref')
+ fetch_firmware(self)
iso_path = self.ASSET_ALPINE_ISO.fetch()
self.vm.set_console()
diff --git a/tests/functional/test_aarch64_sbsaref_freebsd.py b/tests/functional/aarch64/test_sbsaref_freebsd.py
index bd6728d..3b942f7 100755
--- a/tests/functional/test_aarch64_sbsaref_freebsd.py
+++ b/tests/functional/aarch64/test_sbsaref_freebsd.py
@@ -10,27 +10,26 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import QemuSystemTest, Asset, skipSlowTest
from qemu_test import wait_for_console_pattern
-from test_aarch64_sbsaref import fetch_firmware
+from test_sbsaref import fetch_firmware
class Aarch64SbsarefFreeBSD(QemuSystemTest):
ASSET_FREEBSD_ISO = Asset(
- ('https://download.freebsd.org/releases/arm64/aarch64/ISO-IMAGES/'
- '14.1/FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso'),
- '44cdbae275ef1bb6dab1d5fbb59473d4f741e1c8ea8a80fd9e906b531d6ad461')
+ ('http://ftp-archive.freebsd.org/pub/FreeBSD-Archive/old-releases/arm64'
+ '/aarch64/ISO-IMAGES/14.1/FreeBSD-14.1-RELEASE-arm64-aarch64-bootonly.iso.xz'),
+ '7313a4495ffd71ab77b49b1e83f571521c32756e1d75bf48bd890e0ab0f75827')
# This tests the whole boot chain from EFI to Userspace
# We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots
def boot_freebsd14(self, cpu=None):
- fetch_firmware(self)
+ self.set_machine('sbsa-ref')
- img_path = self.ASSET_FREEBSD_ISO.fetch()
+ fetch_firmware(self)
+ img_path = self.uncompress(self.ASSET_FREEBSD_ISO)
self.vm.set_console()
self.vm.add_args(
diff --git a/tests/functional/aarch64/test_smmu.py b/tests/functional/aarch64/test_smmu.py
new file mode 100755
index 0000000..e0f4a92
--- /dev/null
+++ b/tests/functional/aarch64/test_smmu.py
@@ -0,0 +1,211 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# SMMUv3 Functional tests
+#
+# Copyright (c) 2021 Red Hat, Inc.
+#
+# Author:
+# Eric Auger <eric.auger@redhat.com>
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+import os
+import time
+
+from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import BUILD_DIR
+from qemu.utils import kvm_available, hvf_available
+
+
+class SMMU(LinuxKernelTest):
+
+ default_kernel_params = ('earlyprintk=pl011,0x9000000 no_timer_check '
+ 'printk.time=1 rd_NO_PLYMOUTH net.ifnames=0 '
+ 'console=ttyAMA0 rd.rescue')
+ IOMMU_ADDON = ',iommu_platform=on,disable-modern=off,disable-legacy=on'
+ kernel_path = None
+ initrd_path = None
+ kernel_params = None
+
+ GUEST_PORT = 8080
+
+ def set_up_boot(self, path):
+ self.vm.add_args('-device', 'virtio-blk-pci,bus=pcie.0,' +
+ 'drive=drv0,id=virtio-disk0,bootindex=1,'
+ 'werror=stop,rerror=stop' + self.IOMMU_ADDON)
+ self.vm.add_args('-drive',
+ f'file={path},if=none,cache=writethrough,id=drv0,snapshot=on')
+
+ self.vm.add_args('-netdev',
+ 'user,id=n1,hostfwd=tcp:127.0.0.1:0-:%d' %
+ self.GUEST_PORT)
+ self.vm.add_args('-device', 'virtio-net,netdev=n1' + self.IOMMU_ADDON)
+
+ def common_vm_setup(self, kernel, initrd, disk):
+ if hvf_available(self.qemu_bin):
+ accel = "hvf"
+ elif kvm_available(self.qemu_bin):
+ accel = "kvm"
+ else:
+ self.skipTest("Neither HVF nor KVM accelerator is available")
+ self.require_accelerator(accel)
+ self.require_netdev('user')
+ self.set_machine("virt")
+ self.vm.add_args('-m', '1G')
+ self.vm.add_args("-accel", accel)
+ self.vm.add_args("-cpu", "host")
+ self.vm.add_args("-machine", "iommu=smmuv3")
+ self.vm.add_args("-d", "guest_errors")
+ self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
+ 'edk2-aarch64-code.fd'))
+ self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
+ self.vm.add_args('-object',
+ 'rng-random,id=rng0,filename=/dev/urandom')
+
+ self.kernel_path = kernel.fetch()
+ self.initrd_path = initrd.fetch()
+ self.set_up_boot(disk.fetch())
+
+ def run_and_check(self, filename, hashsum):
+ self.vm.add_args('-initrd', self.initrd_path)
+ self.vm.add_args('-append', self.kernel_params)
+ self.launch_kernel(self.kernel_path, initrd=self.initrd_path,
+ wait_for='attach it to a bug report.')
+ prompt = '# '
+ # Fedora 33 requires 'return' to be pressed to enter the shell.
+ # There seems to be a small race between detecting the previous ':'
+ # and sending the newline, so we need to add a small delay here.
+ self.wait_for_console_pattern(':')
+ time.sleep(0.2)
+ exec_command_and_wait_for_pattern(self, '\n', prompt)
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cmdline',
+ self.kernel_params)
+
+ # Checking for SMMU enablement:
+ self.log.info("Checking whether SMMU has been enabled...")
+ exec_command_and_wait_for_pattern(self, 'dmesg | grep smmu',
+ 'arm-smmu-v3')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ 'find /sys/kernel/iommu_groups/ -type l',
+ 'devices/0000:00:')
+ self.wait_for_console_pattern(prompt)
+
+ # Copy a file (checked later), umount afterwards to drop disk cache:
+ self.log.info("Checking hard disk...")
+ exec_command_and_wait_for_pattern(self,
+ "while ! (dmesg -c | grep vda:) ; do sleep 1 ; done",
+ "vda2")
+ exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
+ 'mounted filesystem')
+ exec_command_and_wait_for_pattern(self, 'cp /bin/vi /sysroot/root/vi',
+ prompt)
+ exec_command_and_wait_for_pattern(self, 'umount /sysroot', prompt)
+ # Switch from initrd to the cloud image filesystem:
+ exec_command_and_wait_for_pattern(self, 'mount /dev/vda2 /sysroot',
+ prompt)
+ exec_command_and_wait_for_pattern(self,
+ ('for d in dev proc sys run ; do '
+ 'mount -o bind /$d /sysroot/$d ; done'), prompt)
+ exec_command_and_wait_for_pattern(self, 'chroot /sysroot', prompt)
+ # Check files on the hard disk:
+ exec_command_and_wait_for_pattern(self,
+ ('if diff -q /root/vi /usr/bin/vi ; then echo "file" "ok" ; '
+ 'else echo "files differ"; fi'), 'file ok')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self, f'sha256sum {filename}',
+ hashsum)
+
+ # Check virtio-net via HTTP:
+ exec_command_and_wait_for_pattern(self, 'dhclient eth0', prompt)
+ self.check_http_download(filename, hashsum, self.GUEST_PORT)
+
+
+ # 5.3 kernel without RIL #
+
+ ASSET_KERNEL_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/31/Server/aarch64/os/images/pxeboot/vmlinuz'),
+ '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
+
+ ASSET_INITRD_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/31/Server/aarch64/os/images/pxeboot/initrd.img'),
+ '9f3146b28bc531c689f3c5f114cb74e4bd7bd548e0ba19fa77921d8bd256755a')
+
+ ASSET_DISK_F31 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
+ '/31/Cloud/aarch64/images/Fedora-Cloud-Base-31-1.9.aarch64.qcow2'),
+ '1e18d9c0cf734940c4b5d5ec592facaed2af0ad0329383d5639c997fdf16fe49')
+
+ F31_FILENAME = '/boot/initramfs-5.3.7-301.fc31.aarch64.img'
+ F31_HSUM = '1a4beec6607d94df73d9dd1b4985c9c23dd0fdcf4e6ca1351d477f190df7bef9'
+
+ def test_smmu_noril(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = self.default_kernel_params
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+ def test_smmu_noril_passthrough(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+ def test_smmu_noril_nostrict(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F31, self.ASSET_INITRD_F31,
+ self.ASSET_DISK_F31)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check(self.F31_FILENAME, self.F31_HSUM)
+
+
+ # 5.8 kernel featuring range invalidation
+ # >= v5.7 kernel
+
+ ASSET_KERNEL_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/pxeboot/vmlinuz'),
+ 'd8b1e6f7241f339d8e7609c456cf0461ffa4583ed07e0b55c7d1d8a0c154aa89')
+
+ ASSET_INITRD_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
+ 'releases/33/Server/aarch64/os/images/pxeboot/initrd.img'),
+ '92513f55295c2c16a777f7b6c35ccd70a438e9e1e40b6ba39e0e60900615b3df')
+
+ ASSET_DISK_F33 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux/releases'
+ '/33/Cloud/aarch64/images/Fedora-Cloud-Base-33-1.2.aarch64.qcow2'),
+ 'e7f75cdfd523fe5ac2ca9eeece68edc1a81f386a17f969c1d1c7c87031008a6b')
+
+ F33_FILENAME = '/boot/initramfs-5.8.15-301.fc33.aarch64.img'
+ F33_HSUM = '079cfad0caa82e84c8ca1fb0897a4999dd769f262216099f518619e807a550d9'
+
+ def test_smmu_ril(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = self.default_kernel_params
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+ def test_smmu_ril_passthrough(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.passthrough=on')
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+ def test_smmu_ril_nostrict(self):
+ self.common_vm_setup(self.ASSET_KERNEL_F33, self.ASSET_INITRD_F33,
+ self.ASSET_DISK_F33)
+ self.kernel_params = (self.default_kernel_params +
+ ' iommu.strict=0')
+ self.run_and_check(self.F33_FILENAME, self.F33_HSUM)
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_aarch64_tcg_plugins.py b/tests/functional/aarch64/test_tcg_plugins.py
index 4ea71f5..cb7e929 100755
--- a/tests/functional/test_aarch64_tcg_plugins.py
+++ b/tests/functional/aarch64/test_tcg_plugins.py
@@ -13,7 +13,6 @@
import tempfile
import mmap
-import os
import re
from qemu.machine.machine import VMLaunchFailure
diff --git a/tests/functional/test_aarch64_tuxrun.py b/tests/functional/aarch64/test_tuxrun.py
index 75adc8a..75adc8a 100755
--- a/tests/functional/test_aarch64_tuxrun.py
+++ b/tests/functional/aarch64/test_tuxrun.py
diff --git a/tests/functional/test_aarch64_virt.py b/tests/functional/aarch64/test_virt.py
index 884aad7..63071f9 100755
--- a/tests/functional/test_aarch64_virt.py
+++ b/tests/functional/aarch64/test_virt.py
@@ -13,12 +13,8 @@
import logging
from subprocess import check_call, DEVNULL
-from qemu.machine.machine import VMLaunchFailure
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, exec_command_and_wait_for_pattern
-from qemu_test import wait_for_console_pattern
-from qemu_test import skipIfMissingCommands, get_qemu_img
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern, get_qemu_img
class Aarch64VirtMachine(QemuSystemTest):
@@ -76,8 +72,6 @@ class Aarch64VirtMachine(QemuSystemTest):
self.set_machine('virt')
self.require_accelerator("tcg")
- logger = logging.getLogger('aarch64_virt')
-
kernel_path = self.ASSET_KERNEL.fetch()
self.vm.set_console()
@@ -95,7 +89,7 @@ class Aarch64VirtMachine(QemuSystemTest):
'rng-random,id=rng0,filename=/dev/urandom')
# Also add a scratch block device
- logger.info('creating scratch qcow2 image')
+ self.log.info('creating scratch qcow2 image')
image_path = self.scratch_file('scratch.qcow2')
qemu_img = get_qemu_img(self)
check_call([qemu_img, 'create', '-f', 'qcow2', image_path, '8M'],
diff --git a/tests/functional/test_aarch64_virt_gpu.py b/tests/functional/aarch64/test_virt_gpu.py
index 3844727..4e50887 100755
--- a/tests/functional/test_aarch64_virt_gpu.py
+++ b/tests/functional/aarch64/test_virt_gpu.py
@@ -76,6 +76,8 @@ class Aarch64VirtGPUMachine(LinuxKernelTest):
self.skipTest("egl-headless support is not available")
elif "'type' does not accept value 'dbus'" in excp.output:
self.skipTest("dbus display support is not available")
+ elif "eglInitialize failed: EGL_NOT_INITIALIZED" in excp.output:
+ self.skipTest("EGL failed to initialize on this host")
else:
self.log.info("unhandled launch failure: %s", excp.output)
raise excp
diff --git a/tests/functional/test_aarch64_xen.py b/tests/functional/aarch64/test_xen.py
index 3399042..261d796 100755
--- a/tests/functional/test_aarch64_xen.py
+++ b/tests/functional/aarch64/test_xen.py
@@ -33,6 +33,7 @@ class BootXen(LinuxKernelTest):
"""
Launch Xen with a dom0 guest kernel
"""
+ self.require_accelerator("tcg") # virtualization=on
self.set_machine('virt')
self.cpu = "cortex-a57"
self.kernel_path = self.ASSET_KERNEL.fetch()
diff --git a/tests/functional/test_aarch64_xlnx_versal.py b/tests/functional/aarch64/test_xlnx_versal.py
index 4b9c49e..45aa6e1 100755
--- a/tests/functional/test_aarch64_xlnx_versal.py
+++ b/tests/functional/aarch64/test_xlnx_versal.py
@@ -6,7 +6,7 @@
from qemu_test import LinuxKernelTest, Asset
-class XlnxVersalVirtMachine(LinuxKernelTest):
+class AmdVersalVirtMachine(LinuxKernelTest):
ASSET_KERNEL = Asset(
('http://ports.ubuntu.com/ubuntu-ports/dists/bionic-updates/main/'
@@ -20,8 +20,8 @@ class XlnxVersalVirtMachine(LinuxKernelTest):
'/ubuntu-installer/arm64/initrd.gz'),
'e7a5e716b6f516d8be315c06e7331aaf16994fe4222e0e7cfb34bc015698929e')
- def test_aarch64_xlnx_versal_virt(self):
- self.set_machine('xlnx-versal-virt')
+ def common_aarch64_amd_versal_virt(self, machine):
+ self.set_machine(machine)
kernel_path = self.ASSET_KERNEL.fetch()
initrd_path = self.ASSET_INITRD.fetch()
@@ -33,5 +33,11 @@ class XlnxVersalVirtMachine(LinuxKernelTest):
self.vm.launch()
self.wait_for_console_pattern('Checked W+X mappings: passed')
+ def test_aarch64_amd_versal_virt(self):
+ self.common_aarch64_amd_versal_virt('amd-versal-virt')
+
+ def test_aarch64_amd_versal2_virt(self):
+ self.common_aarch64_amd_versal_virt('amd-versal2-virt')
+
if __name__ == '__main__':
LinuxKernelTest.main()
diff --git a/tests/functional/alpha/meson.build b/tests/functional/alpha/meson.build
new file mode 100644
index 0000000..26a5b3f
--- /dev/null
+++ b/tests/functional/alpha/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_alpha_system_quick = [
+ 'migration',
+]
+
+tests_alpha_system_thorough = [
+ 'clipper',
+ 'replay',
+]
diff --git a/tests/functional/test_alpha_clipper.py b/tests/functional/alpha/test_clipper.py
index c5d7181..c5d7181 100755
--- a/tests/functional/test_alpha_clipper.py
+++ b/tests/functional/alpha/test_clipper.py
diff --git a/tests/functional/alpha/test_migration.py b/tests/functional/alpha/test_migration.py
new file mode 100755
index 0000000..f11b523
--- /dev/null
+++ b/tests/functional/alpha/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Alpha migration test
+
+from migration import MigrationTest
+
+
+class AlphaMigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('clipper')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('clipper')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('clipper')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_alpha_replay.py b/tests/functional/alpha/test_replay.py
index 24a17ef..24a17ef 100755
--- a/tests/functional/test_alpha_replay.py
+++ b/tests/functional/alpha/test_replay.py
diff --git a/tests/functional/arm/meson.build b/tests/functional/arm/meson.build
new file mode 100644
index 0000000..d1ed076
--- /dev/null
+++ b/tests/functional/arm/meson.build
@@ -0,0 +1,64 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_arm_timeouts = {
+ 'aspeed_palmetto' : 120,
+ 'aspeed_romulus' : 120,
+ 'aspeed_witherspoon' : 120,
+ 'aspeed_ast2500' : 720,
+ 'aspeed_ast2600_buildroot' : 720,
+ 'aspeed_ast2600_sdk' : 1200,
+ 'aspeed_bletchley' : 480,
+ 'aspeed_catalina' : 480,
+ 'aspeed_gb200nvl_bmc' : 480,
+ 'aspeed_rainier' : 480,
+ 'bpim2u' : 500,
+ 'collie' : 180,
+ 'cubieboard' : 360,
+ 'orangepi' : 540,
+ 'quanta_gsj' : 240,
+ 'raspi2' : 120,
+ 'replay' : 240,
+ 'tuxrun' : 240,
+ 'sx1' : 360,
+}
+
+tests_arm_system_quick = [
+ 'migration',
+]
+
+tests_arm_system_thorough = [
+ 'aspeed_ast1030',
+ 'aspeed_palmetto',
+ 'aspeed_romulus',
+ 'aspeed_witherspoon',
+ 'aspeed_ast2500',
+ 'aspeed_ast2600_buildroot',
+ 'aspeed_ast2600_sdk',
+ 'aspeed_bletchley',
+ 'aspeed_catalina',
+ 'aspeed_gb200nvl_bmc',
+ 'aspeed_rainier',
+ 'bpim2u',
+ 'canona1100',
+ 'collie',
+ 'cubieboard',
+ 'emcraft_sf2',
+ 'integratorcp',
+ 'max78000fthr',
+ 'microbit',
+ 'orangepi',
+ 'quanta_gsj',
+ 'raspi2',
+ 'realview',
+ 'replay',
+ 'smdkc210',
+ 'stellaris',
+ 'sx1',
+ 'vexpress',
+ 'virt',
+ 'tuxrun',
+]
+
+tests_arm_linuxuser_thorough = [
+ 'bflt',
+]
diff --git a/tests/functional/test_arm_aspeed_ast1030.py b/tests/functional/arm/test_aspeed_ast1030.py
index d45d9f7..60e2b02 100755
--- a/tests/functional/test_arm_aspeed_ast1030.py
+++ b/tests/functional/arm/test_aspeed_ast1030.py
@@ -7,22 +7,23 @@
# SPDX-License-Identifier: GPL-2.0-or-later
from qemu_test import LinuxKernelTest, Asset
+from aspeed import AspeedTest
from qemu_test import exec_command_and_wait_for_pattern
-class AST1030Machine(LinuxKernelTest):
+class AST1030Machine(AspeedTest):
- ASSET_ZEPHYR_1_04 = Asset(
+ ASSET_ZEPHYR_3_03 = Asset(
('https://github.com/AspeedTech-BMC'
- '/zephyr/releases/download/v00.01.04/ast1030-evb-demo.zip'),
- '4ac6210adcbc61294927918707c6762483fd844dde5e07f3ba834ad1f91434d3')
+ '/zephyr/releases/download/v00.03.03/ast1030-evb-demo.zip'),
+ '27cd73cdee6374bceb4ee58b3ace87989fa3f0684f4e612510804b588b24d4e0')
- def test_ast1030_zephyros_1_04(self):
+ def test_arm_ast1030_zephyros_3_03(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo/zephyr.elf"
kernel_file = self.archive_extract(
- self.ASSET_ZEPHYR_1_04, member=kernel_name)
+ self.ASSET_ZEPHYR_3_03, member=kernel_name)
self.vm.set_console()
self.vm.add_args('-kernel', kernel_file, '-nographic')
@@ -36,7 +37,7 @@ class AST1030Machine(LinuxKernelTest):
'/zephyr/releases/download/v00.01.07/ast1030-evb-demo.zip'),
'ad52e27959746988afaed8429bf4e12ab988c05c4d07c9d90e13ec6f7be4574c')
- def test_ast1030_zephyros_1_07(self):
+ def test_arm_ast1030_zephyros_1_07(self):
self.set_machine('ast1030-evb')
kernel_name = "ast1030-evb-demo/zephyr.bin"
@@ -68,6 +69,22 @@ class AST1030Machine(LinuxKernelTest):
'kernel uptime',
]: exec_command_and_wait_for_pattern(self, shell_cmd, "uart:~$")
+ def test_arm_ast1030_otp_blockdev_device(self):
+ self.vm.set_machine("ast1030-evb")
+
+ kernel_name = "ast1030-evb-demo/zephyr.elf"
+ kernel_file = self.archive_extract(self.ASSET_ZEPHYR_3_03,
+ member=kernel_name)
+ otp_img = self.generate_otpmem_image()
+
+ self.vm.set_console()
+ self.vm.add_args(
+ "-kernel", kernel_file,
+ "-blockdev", f"driver=file,filename={otp_img},node-name=otp",
+ "-global", "aspeed-otp.drive=otp",
+ )
+ self.vm.launch()
+ self.wait_for_console_pattern("Booting Zephyr OS")
if __name__ == '__main__':
- LinuxKernelTest.main()
+ AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_ast2500.py b/tests/functional/arm/test_aspeed_ast2500.py
index 1ffba6c..5efd104 100755
--- a/tests/functional/test_arm_aspeed_ast2500.py
+++ b/tests/functional/arm/test_aspeed_ast2500.py
@@ -4,9 +4,8 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset
+from qemu_test import Asset, exec_command_and_wait_for_pattern
from aspeed import AspeedTest
-from qemu_test import exec_command_and_wait_for_pattern
class AST2500Machine(AspeedTest):
@@ -22,30 +21,30 @@ class AST2500Machine(AspeedTest):
image_path = self.ASSET_BR2_202411_AST2500_FLASH.fetch()
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
self.do_test_arm_aspeed_buildroot_start(image_path, '0x0',
'ast2500-evb login:')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V806_AST2500 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2500-default-obmc.tar.gz',
- 'e1755f3cadff69190438c688d52dd0f0d399b70a1e14b1d3d5540fc4851d38ca')
+ ASSET_SDK_V908_AST2500 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2500-default-obmc.tar.gz',
+ 'c0a2ba169efd19be5eb77c50ec2a6afd9d826e196a0be3432f969fc72d4b7c0e')
def test_arm_ast2500_evb_sdk(self):
self.set_machine('ast2500-evb')
- self.archive_extract(self.ASSET_SDK_V806_AST2500)
+ self.archive_extract(self.ASSET_SDK_V908_AST2500)
self.do_test_arm_aspeed_sdk_start(
self.scratch_file("ast2500-default", "image-bmc"))
diff --git a/tests/functional/test_arm_aspeed_ast2600.py b/tests/functional/arm/test_aspeed_ast2600_buildroot.py
index 6ae4ed6..51f2676 100755
--- a/tests/functional/test_arm_aspeed_ast2600.py
+++ b/tests/functional/arm/test_aspeed_ast2600_buildroot.py
@@ -27,38 +27,38 @@ class AST2600Machine(AspeedTest):
image_path = self.ASSET_BR2_202411_AST2600_FLASH.fetch()
self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test');
+ 'tmp105,bus=aspeed.i2c.bus.3,address=0x4d,id=tmp-test')
self.vm.add_args('-device',
- 'ds1338,bus=aspeed.i2c.bus.3,address=0x32');
+ 'ds1338,bus=aspeed.i2c.bus.3,address=0x32')
self.vm.add_args('-device',
- 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42');
+ 'i2c-echo,bus=aspeed.i2c.bus.3,address=0x42')
self.do_test_arm_aspeed_buildroot_start(image_path, '0xf00',
'ast2600-evb login:')
exec_command_and_wait_for_pattern(self,
'echo lm75 0x4d > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d');
+ 'i2c i2c-3: new_device: Instantiated device lm75 at 0x4d')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '0')
self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
+ property='temperature', value=18000)
exec_command_and_wait_for_pattern(self,
'cat /sys/class/hwmon/hwmon1/temp1_input', '18000')
exec_command_and_wait_for_pattern(self,
'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-3/device/new_device',
- 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32');
+ 'i2c i2c-3: new_device: Instantiated device ds1307 at 0x32')
year = time.strftime("%Y")
- exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year);
+ exec_command_and_wait_for_pattern(self, 'hwclock -f /dev/rtc1', year)
exec_command_and_wait_for_pattern(self,
'echo slave-24c02 0x1064 > /sys/bus/i2c/devices/i2c-3/new_device',
- 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64');
+ 'i2c i2c-3: new_device: Instantiated device slave-24c02 at 0x64')
exec_command_and_wait_for_pattern(self,
- 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#');
+ 'i2cset -y 3 0x42 0x64 0x00 0xaa i', '#')
exec_command_and_wait_for_pattern(self,
'hexdump /sys/bus/i2c/devices/3-1064/slave-eeprom',
- '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff');
+ '0000000 ffaa ffff ffff ffff ffff ffff ffff ffff')
self.do_test_arm_aspeed_buildroot_poweroff()
ASSET_BR2_202302_AST2600_TPM_FLASH = Asset(
@@ -90,50 +90,13 @@ class AST2600Machine(AspeedTest):
exec_command_and_wait_for_pattern(self,
'echo tpm_tis_i2c 0x2e > /sys/bus/i2c/devices/i2c-12/new_device',
- 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)');
+ 'tpm_tis_i2c 12-002e: 2.0 TPM (device-id 0x1, rev-id 1)')
exec_command_and_wait_for_pattern(self,
'cat /sys/class/tpm/tpm0/pcr-sha256/0',
- 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0');
+ 'B804724EA13F52A9072BA87FE8FDCC497DFC9DF9AA15B9088694639C431688E0')
self.do_test_arm_aspeed_buildroot_poweroff()
- ASSET_SDK_V806_AST2600_A2 = Asset(
- 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v08.06/ast2600-a2-obmc.tar.gz',
- '9083506135f622d5e7351fcf7d4e1c7125cee5ba16141220c0ba88931f3681a4')
-
- def test_arm_ast2600_evb_sdk(self):
- self.set_machine('ast2600-evb')
-
- self.archive_extract(self.ASSET_SDK_V806_AST2600_A2)
-
- self.vm.add_args('-device',
- 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test');
- self.vm.add_args('-device',
- 'ds1338,bus=aspeed.i2c.bus.5,address=0x32');
- self.do_test_arm_aspeed_sdk_start(
- self.scratch_file("ast2600-a2", "image-bmc"))
-
- self.wait_for_console_pattern('ast2600-a2 login:')
-
- exec_command_and_wait_for_pattern(self, 'root', 'Password:')
- exec_command_and_wait_for_pattern(self, '0penBmc', 'root@ast2600-a2:~#')
-
- exec_command_and_wait_for_pattern(self,
- 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',
- 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d');
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
- self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
- property='temperature', value=18000);
- exec_command_and_wait_for_pattern(self,
- 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')
-
- exec_command_and_wait_for_pattern(self,
- 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device',
- 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32');
- year = time.strftime("%Y")
- exec_command_and_wait_for_pattern(self,
- '/sbin/hwclock -f /dev/rtc1', year);
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/arm/test_aspeed_ast2600_sdk.py b/tests/functional/arm/test_aspeed_ast2600_sdk.py
new file mode 100755
index 0000000..e3d4ed0
--- /dev/null
+++ b/tests/functional/arm/test_aspeed_ast2600_sdk.py
@@ -0,0 +1,94 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+import time
+
+from qemu_test import Asset
+from aspeed import AspeedTest
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class AST2600Machine(AspeedTest):
+
+ ASSET_SDK_V908_AST2600 = Asset(
+ 'https://github.com/AspeedTech-BMC/openbmc/releases/download/v09.08/ast2600-default-obmc.tar.gz',
+ 'a0414f14ad696550efe083c2156dbeda855c08cc9ae7f40fe1b41bf292295f82')
+
+ def do_ast2600_pcie_test(self):
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 80:00.0',
+ '80:00.0 Host bridge: '
+ 'ASPEED Technology, Inc. Device 2600')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 80:08.0',
+ '80:08.0 PCI bridge: '
+ 'ASPEED Technology, Inc. AST1150 PCI-to-PCI Bridge')
+ exec_command_and_wait_for_pattern(self,
+ 'lspci -s 81:00.0',
+ '81:00.0 Ethernet controller: '
+ 'Intel Corporation 82574L Gigabit Network Connection')
+ exec_command_and_wait_for_pattern(self,
+ 'ip addr show dev eth4',
+ 'inet 10.0.2.15/24')
+
+ def test_arm_ast2600_evb_sdk(self):
+ self.set_machine('ast2600-evb')
+ self.require_netdev('user')
+
+ self.archive_extract(self.ASSET_SDK_V908_AST2600)
+
+ self.vm.add_args('-device',
+ 'tmp105,bus=aspeed.i2c.bus.5,address=0x4d,id=tmp-test')
+ self.vm.add_args('-device',
+ 'ds1338,bus=aspeed.i2c.bus.5,address=0x32')
+ self.vm.add_args('-device', 'e1000e,netdev=net1,bus=pcie.0')
+ self.vm.add_args('-netdev', 'user,id=net1')
+ self.do_test_arm_aspeed_sdk_start(
+ self.scratch_file("ast2600-default", "image-bmc"))
+
+ self.wait_for_console_pattern('ast2600-default login:')
+
+ exec_command_and_wait_for_pattern(self, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(self, '0penBmc',
+ 'root@ast2600-default:~#')
+
+ exec_command_and_wait_for_pattern(self,
+ 'echo lm75 0x4d > /sys/class/i2c-dev/i2c-5/device/new_device',
+ 'i2c i2c-5: new_device: Instantiated device lm75 at 0x4d')
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/class/hwmon/hwmon19/temp1_input', '0')
+ self.vm.cmd('qom-set', path='/machine/peripheral/tmp-test',
+ property='temperature', value=18000)
+ exec_command_and_wait_for_pattern(self,
+ 'cat /sys/class/hwmon/hwmon19/temp1_input', '18000')
+
+ exec_command_and_wait_for_pattern(self,
+ 'echo ds1307 0x32 > /sys/class/i2c-dev/i2c-5/device/new_device',
+ 'i2c i2c-5: new_device: Instantiated device ds1307 at 0x32')
+ year = time.strftime("%Y")
+ exec_command_and_wait_for_pattern(self,
+ '/sbin/hwclock -f /dev/rtc1', year)
+ self.do_ast2600_pcie_test()
+
+ def test_arm_ast2600_otp_blockdev_device(self):
+ self.vm.set_machine("ast2600-evb")
+
+ image_path = self.archive_extract(self.ASSET_SDK_V908_AST2600)
+ otp_img = self.generate_otpmem_image()
+
+ self.vm.set_console()
+ self.vm.add_args(
+ "-blockdev", f"driver=file,filename={otp_img},node-name=otp",
+ "-global", "aspeed-otp.drive=otp",
+ )
+ self.do_test_arm_aspeed_sdk_start(
+ self.scratch_file("ast2600-default", "image-bmc"))
+ self.wait_for_console_pattern("ast2600-default login:")
+
+
+if __name__ == '__main__':
+ AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_bletchley.py b/tests/functional/arm/test_aspeed_bletchley.py
index 0da856c..5a60b24 100644..100755
--- a/tests/functional/test_arm_aspeed_bletchley.py
+++ b/tests/functional/arm/test_aspeed_bletchley.py
@@ -12,14 +12,14 @@ class BletchleyMachine(AspeedTest):
ASSET_BLETCHLEY_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/bletchley-bmc/openbmc-20250128071329/obmc-phosphor-image-bletchley-20250128071329.static.mtd.xz',
- 'db21d04d47d7bb2a276f59d308614b4dfb70b9c7c81facbbca40a3977a2d8844');
+ 'db21d04d47d7bb2a276f59d308614b4dfb70b9c7c81facbbca40a3977a2d8844')
def test_arm_ast2600_bletchley_openbmc(self):
image_path = self.uncompress(self.ASSET_BLETCHLEY_FLASH)
self.do_test_arm_aspeed_openbmc('bletchley-bmc', image=image_path,
uboot='2019.04', cpu_id='0xf00',
- soc='AST2600 rev A3');
+ soc='AST2600 rev A3')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/arm/test_aspeed_catalina.py b/tests/functional/arm/test_aspeed_catalina.py
new file mode 100755
index 0000000..dc2f24e
--- /dev/null
+++ b/tests/functional/arm/test_aspeed_catalina.py
@@ -0,0 +1,25 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from aspeed import AspeedTest
+
+
+class CatalinaMachine(AspeedTest):
+
+ ASSET_CATALINA_FLASH = Asset(
+ 'https://github.com/legoater/qemu-aspeed-boot/raw/a866feb5ef81245b4827a214584bf6bcc72939f6/images/catalina-bmc/obmc-phosphor-image-catalina-20250619123021.static.mtd.xz',
+ '287402e1ba021991e06be1d098f509444a02a3d81a73a932f66528b159e864f9')
+
+ def test_arm_ast2600_catalina_openbmc(self):
+ image_path = self.uncompress(self.ASSET_CATALINA_FLASH)
+
+ self.do_test_arm_aspeed_openbmc('catalina-bmc', image=image_path,
+ uboot='2019.04', cpu_id='0xf00',
+ soc='AST2600 rev A3')
+
+if __name__ == '__main__':
+ AspeedTest.main()
diff --git a/tests/functional/arm/test_aspeed_gb200nvl_bmc.py b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py
new file mode 100755
index 0000000..8e8e3f0
--- /dev/null
+++ b/tests/functional/arm/test_aspeed_gb200nvl_bmc.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots the ASPEED machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from aspeed import AspeedTest
+
+
+class GB200Machine(AspeedTest):
+
+ ASSET_GB200_FLASH = Asset(
+ 'https://github.com/legoater/qemu-aspeed-boot/raw/refs/heads/master/images/gb200nvl-obmc/obmc-phosphor-image-gb200nvl-obmc-20250702182348.static.mtd.xz',
+ 'b84819317cb3dc762895ad507705978ef000bfc77c50c33a63bdd37921db0dbc')
+
+ def test_arm_aspeed_gb200_openbmc(self):
+ image_path = self.uncompress(self.ASSET_GB200_FLASH)
+
+ self.do_test_arm_aspeed_openbmc('gb200nvl-bmc', image=image_path,
+ uboot='2019.04', cpu_id='0xf00',
+ soc='AST2600 rev A3',
+ image_hostname='gb200nvl-obmc')
+
+if __name__ == '__main__':
+ AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_palmetto.py b/tests/functional/arm/test_aspeed_palmetto.py
index 35d832b..ff0b821 100755
--- a/tests/functional/test_arm_aspeed_palmetto.py
+++ b/tests/functional/arm/test_aspeed_palmetto.py
@@ -12,14 +12,14 @@ class PalmettoMachine(AspeedTest):
ASSET_PALMETTO_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/palmetto-bmc/openbmc-20250128071432/obmc-phosphor-image-palmetto-20250128071432.static.mtd',
- 'bce7c392eec75c707a91cfc8fad7ca9a69d7e4f10df936930d65c1cb9897ac81');
+ 'bce7c392eec75c707a91cfc8fad7ca9a69d7e4f10df936930d65c1cb9897ac81')
def test_arm_ast2400_palmetto_openbmc(self):
image_path = self.ASSET_PALMETTO_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('palmetto-bmc', image=image_path,
uboot='2019.04', cpu_id='0x0',
- soc='AST2400 rev A1');
+ soc='AST2400 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_rainier.py b/tests/functional/arm/test_aspeed_rainier.py
index 602d619..602d619 100755
--- a/tests/functional/test_arm_aspeed_rainier.py
+++ b/tests/functional/arm/test_aspeed_rainier.py
diff --git a/tests/functional/test_arm_aspeed_romulus.py b/tests/functional/arm/test_aspeed_romulus.py
index b97ed95..0447212 100755
--- a/tests/functional/test_arm_aspeed_romulus.py
+++ b/tests/functional/arm/test_aspeed_romulus.py
@@ -12,14 +12,14 @@ class RomulusMachine(AspeedTest):
ASSET_ROMULUS_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/romulus-bmc/openbmc-20250128071340/obmc-phosphor-image-romulus-20250128071340.static.mtd',
- '6d031376440c82ed9d087d25e9fa76aea75b42f80daa252ec402c0bc3cf6cf5b');
+ '6d031376440c82ed9d087d25e9fa76aea75b42f80daa252ec402c0bc3cf6cf5b')
def test_arm_ast2500_romulus_openbmc(self):
image_path = self.ASSET_ROMULUS_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('romulus-bmc', image=image_path,
uboot='2019.04', cpu_id='0x0',
- soc='AST2500 rev A1');
+ soc='AST2500 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_aspeed_witherspoon.py b/tests/functional/arm/test_aspeed_witherspoon.py
index ea1ce89..51a2d47 100644..100755
--- a/tests/functional/test_arm_aspeed_witherspoon.py
+++ b/tests/functional/arm/test_aspeed_witherspoon.py
@@ -12,14 +12,14 @@ class WitherspoonMachine(AspeedTest):
ASSET_WITHERSPOON_FLASH = Asset(
'https://github.com/legoater/qemu-aspeed-boot/raw/master/images/witherspoon-bmc/openbmc-20240618035022/obmc-phosphor-image-witherspoon-20240618035022.ubi.mtd',
- '937d9ed449ea6c6cbed983519088a42d0cafe276bcfe4fce07772ca6673f9213');
+ '937d9ed449ea6c6cbed983519088a42d0cafe276bcfe4fce07772ca6673f9213')
def test_arm_ast2500_witherspoon_openbmc(self):
image_path = self.ASSET_WITHERSPOON_FLASH.fetch()
self.do_test_arm_aspeed_openbmc('witherspoon-bmc', image=image_path,
uboot='2016.07', cpu_id='0x0',
- soc='AST2500 rev A1');
+ soc='AST2500 rev A1')
if __name__ == '__main__':
AspeedTest.main()
diff --git a/tests/functional/test_arm_bflt.py b/tests/functional/arm/test_bflt.py
index f273fc8..f273fc8 100755
--- a/tests/functional/test_arm_bflt.py
+++ b/tests/functional/arm/test_bflt.py
diff --git a/tests/functional/test_arm_bpim2u.py b/tests/functional/arm/test_bpim2u.py
index 8de6ccb..8bed64b 100755
--- a/tests/functional/test_arm_bpim2u.py
+++ b/tests/functional/arm/test_bpim2u.py
@@ -163,7 +163,7 @@ class BananaPiMachine(LinuxKernelTest):
self, 'Hit any key to stop autoboot:', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern(
'Please press Enter to activate this console.')
diff --git a/tests/functional/test_arm_canona1100.py b/tests/functional/arm/test_canona1100.py
index 21a1a59..21a1a59 100755
--- a/tests/functional/test_arm_canona1100.py
+++ b/tests/functional/arm/test_canona1100.py
diff --git a/tests/functional/test_arm_collie.py b/tests/functional/arm/test_collie.py
index fe1be3d..fe1be3d 100755
--- a/tests/functional/test_arm_collie.py
+++ b/tests/functional/arm/test_collie.py
diff --git a/tests/functional/test_arm_cubieboard.py b/tests/functional/arm/test_cubieboard.py
index b87a281..b536c2f 100755
--- a/tests/functional/test_arm_cubieboard.py
+++ b/tests/functional/arm/test_cubieboard.py
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern
from qemu_test import skipBigDataTest
@@ -128,7 +126,7 @@ class CubieboardMachine(LinuxKernelTest):
self, 'Hit any key to stop autoboot:', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern(
'Please press Enter to activate this console.')
diff --git a/tests/functional/test_arm_emcraft_sf2.py b/tests/functional/arm/test_emcraft_sf2.py
index f9f3f06..f9f3f06 100755
--- a/tests/functional/test_arm_emcraft_sf2.py
+++ b/tests/functional/arm/test_emcraft_sf2.py
diff --git a/tests/functional/test_arm_integratorcp.py b/tests/functional/arm/test_integratorcp.py
index a85b339..23ae919 100755
--- a/tests/functional/test_arm_integratorcp.py
+++ b/tests/functional/arm/test_integratorcp.py
@@ -73,9 +73,10 @@ class IntegratorMachine(QemuSystemTest):
framebuffer_ready = 'Console: switching to colour frame buffer device'
wait_for_console_pattern(self, framebuffer_ready)
self.vm.cmd('human-monitor-command', command_line='stop')
- self.vm.cmd('human-monitor-command',
- command_line='screendump %s' % screendump_path)
- logger = logging.getLogger('framebuffer')
+ res = self.vm.cmd('human-monitor-command',
+ command_line='screendump %s' % screendump_path)
+ if 'unknown command' in res:
+ self.skipTest('screendump not available')
cpu_count = 1
match_threshold = 0.92
@@ -86,7 +87,7 @@ class IntegratorMachine(QemuSystemTest):
loc = np.where(result >= match_threshold)
tux_count = 0
for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
- logger.debug('found Tux at position [x, y] = %s', pt)
+ self.log.debug('found Tux at position [x, y] = %s', pt)
self.assertGreaterEqual(tux_count, cpu_count)
if __name__ == '__main__':
diff --git a/tests/functional/arm/test_max78000fthr.py b/tests/functional/arm/test_max78000fthr.py
new file mode 100755
index 0000000..a82980b
--- /dev/null
+++ b/tests/functional/arm/test_max78000fthr.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Functional test that checks the max78000fthr machine.
+# Tests ICC, GCR, TRNG, AES, and UART
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+
+class Max78000Machine(QemuSystemTest):
+
+ ASSET_FW = Asset(
+ 'https://github.com/JacksonDonaldson/max78000Test/raw/main/build/max78000.bin',
+ '86940b4bf60931bc6a8aa5db4b9f7f3cf8f64dbbd7ac534647980e536cf3adf7')
+
+ def test_fthr(self):
+ self.set_machine('max78000fthr')
+ fw_path = self.ASSET_FW.fetch()
+ self.vm.set_console()
+ self.vm.add_args('-kernel', fw_path)
+ self.vm.add_args('-device', "loader,file=" + fw_path + ",addr=0x10000000")
+ self.vm.launch()
+
+ wait_for_console_pattern(self, 'started')
+
+ # i -> prints instruction cache values
+ exec_command_and_wait_for_pattern(self, 'i', 'CTRL: 00010001')
+
+ # r -> gcr resets the machine
+ exec_command_and_wait_for_pattern(self, 'r', 'started')
+
+ # z -> sets some memory, then has gcr zero it
+ exec_command_and_wait_for_pattern(self, 'z', 'initial value: 12345678')
+ wait_for_console_pattern(self, "after memz: 00000000")
+
+ # t -> runs trng
+ exec_command_and_wait_for_pattern(self, 't', 'random data:')
+
+ # a -> runs aes
+ exec_command_and_wait_for_pattern(self, 'a',
+ 'encrypted to : a47ca9dd e0df4c86 a070af6e 91710dec')
+ wait_for_console_pattern(self,
+ 'encrypted to : cab7a28e bf456751 9049fcea 8960494b')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_arm_microbit.py b/tests/functional/arm/test_microbit.py
index 68ea4e7..68ea4e7 100755
--- a/tests/functional/test_arm_microbit.py
+++ b/tests/functional/arm/test_microbit.py
diff --git a/tests/functional/arm/test_migration.py b/tests/functional/arm/test_migration.py
new file mode 100755
index 0000000..0aa89f4
--- /dev/null
+++ b/tests/functional/arm/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# arm migration test
+
+from migration import MigrationTest
+
+
+class ArmMigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('npcm750-evb')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('npcm750-evb')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('npcm750-evb')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_arm_orangepi.py b/tests/functional/arm/test_orangepi.py
index 1815f56..f9bfa8c 100755
--- a/tests/functional/test_arm_orangepi.py
+++ b/tests/functional/arm/test_orangepi.py
@@ -174,7 +174,7 @@ class OrangePiMachine(LinuxKernelTest):
exec_command_and_wait_for_pattern(self, ' ', '=>')
exec_command_and_wait_for_pattern(self, "setenv extraargs '" +
kernel_command_line + "'", '=>')
- exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...');
+ exec_command_and_wait_for_pattern(self, 'boot', 'Starting kernel ...')
self.wait_for_console_pattern('systemd[1]: Hostname set ' +
'to <orangepipc>')
diff --git a/tests/functional/test_arm_quanta_gsj.py b/tests/functional/arm/test_quanta_gsj.py
index da60aeb..cb0545f 100755
--- a/tests/functional/test_arm_quanta_gsj.py
+++ b/tests/functional/arm/test_quanta_gsj.py
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset, exec_command_and_wait_for_pattern
from qemu_test import interrupt_interactive_console_until_pattern, skipSlowTest
diff --git a/tests/functional/test_arm_raspi2.py b/tests/functional/arm/test_raspi2.py
index d3c7aaa..d3c7aaa 100755
--- a/tests/functional/test_arm_raspi2.py
+++ b/tests/functional/arm/test_raspi2.py
diff --git a/tests/functional/arm/test_realview.py b/tests/functional/arm/test_realview.py
new file mode 100755
index 0000000..82cc964
--- /dev/null
+++ b/tests/functional/arm/test_realview.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel on a realview arm machine
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, exec_command_and_wait_for_pattern
+from qemu_test import Asset
+
+
+class RealviewMachine(LinuxKernelTest):
+
+ ASSET_REALVIEW_MPCORE = Asset(
+ ('https://archive.openwrt.org/chaos_calmer/15.05.1/realview/generic/'
+ 'openwrt-15.05.1-realview-vmlinux-initramfs.elf'),
+ 'd3a01037f33e7512d46d50975588d5c3a0e0cbf25f37afab44775c2a2be523e6')
+
+ def test_realview_ep_mpcore(self):
+ self.require_netdev('user')
+ self.set_machine('realview-eb-mpcore')
+ kernel_path = self.ASSET_REALVIEW_MPCORE.fetch()
+ self.vm.set_console()
+ kernel_param = 'console=ttyAMA0 mem=128M quiet'
+ self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_param)
+ self.vm.launch()
+ self.wait_for_console_pattern('Please press Enter to activate')
+ prompt = ':/#'
+ exec_command_and_wait_for_pattern(self, '', prompt)
+ exec_command_and_wait_for_pattern(self, 'dmesg', kernel_param)
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ ('while ! dmesg | grep "br-lan: port 1(eth0) entered" ;'
+ ' do sleep 1 ; done'),
+ 'entered forwarding state')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self,
+ 'while ! ifconfig | grep "10.0.2.15" ; do sleep 1 ; done',
+ 'addr:10.0.2.15')
+ self.wait_for_console_pattern(prompt)
+ exec_command_and_wait_for_pattern(self, 'ping -c 1 10.0.2.2',
+ '1 packets received, 0% packet loss')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_arm_replay.py b/tests/functional/arm/test_replay.py
index e002e6a..e002e6a 100755
--- a/tests/functional/test_arm_replay.py
+++ b/tests/functional/arm/test_replay.py
diff --git a/tests/functional/test_arm_smdkc210.py b/tests/functional/arm/test_smdkc210.py
index 0fda45c..3154e7f 100755
--- a/tests/functional/test_arm_smdkc210.py
+++ b/tests/functional/arm/test_smdkc210.py
@@ -4,8 +4,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu_test import LinuxKernelTest, Asset
diff --git a/tests/functional/arm/test_stellaris.py b/tests/functional/arm/test_stellaris.py
new file mode 100755
index 0000000..cbd21cb
--- /dev/null
+++ b/tests/functional/arm/test_stellaris.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Functional test that checks the serial console of the stellaris machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+
+class StellarisMachine(QemuSystemTest):
+
+ ASSET_DAY22 = Asset(
+ 'https://www.qemu-advent-calendar.org/2023/download/day22.tar.gz',
+ 'ae3a63ef4b7a22c21bfc7fc0d85e402fe95e223308ed23ac854405016431ff51')
+
+ def test_lm3s6965evb(self):
+ self.set_machine('lm3s6965evb')
+ kernel_path = self.archive_extract(self.ASSET_DAY22,
+ member='day22/day22.bin')
+ self.vm.set_console()
+ self.vm.add_args('-kernel', kernel_path)
+ self.vm.launch()
+
+ wait_for_console_pattern(self, 'In a one horse open')
+
+ ASSET_NOTMAIN = Asset(
+ 'https://github.com/Ahelion/QemuArmM4FDemoSw/raw/master/build/notmain.bin',
+ '6ceda031aa081a420fca2fca9e137fa681d6e3820d820ad1917736cb265e611a')
+
+ def test_lm3s811evb(self):
+ self.set_machine('lm3s811evb')
+ kernel_path = self.ASSET_NOTMAIN.fetch()
+
+ self.vm.set_console()
+ self.vm.add_args('-cpu', 'cortex-m4')
+ self.vm.add_args('-kernel', kernel_path)
+ self.vm.launch()
+
+ # The test kernel emits an initial '!' and then waits for input.
+ # For each character that we send it responds with a certain
+ # other ASCII character.
+ wait_for_console_pattern(self, '!')
+ exec_command_and_wait_for_pattern(self, '789', 'cdf')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_arm_sx1.py b/tests/functional/arm/test_sx1.py
index 25800b3..25800b3 100755
--- a/tests/functional/test_arm_sx1.py
+++ b/tests/functional/arm/test_sx1.py
diff --git a/tests/functional/test_arm_tuxrun.py b/tests/functional/arm/test_tuxrun.py
index 4ac85f4..4ac85f4 100755
--- a/tests/functional/test_arm_tuxrun.py
+++ b/tests/functional/arm/test_tuxrun.py
diff --git a/tests/functional/test_arm_vexpress.py b/tests/functional/arm/test_vexpress.py
index 6b11552..6b11552 100755
--- a/tests/functional/test_arm_vexpress.py
+++ b/tests/functional/arm/test_vexpress.py
diff --git a/tests/functional/test_arm_virt.py b/tests/functional/arm/test_virt.py
index 7b65491..7b65491 100755
--- a/tests/functional/test_arm_virt.py
+++ b/tests/functional/arm/test_virt.py
diff --git a/tests/functional/aspeed.py b/tests/functional/aspeed.py
index 77dc893..47e84e0 100644
--- a/tests/functional/aspeed.py
+++ b/tests/functional/aspeed.py
@@ -8,8 +8,13 @@ from qemu_test import LinuxKernelTest
class AspeedTest(LinuxKernelTest):
def do_test_arm_aspeed_openbmc(self, machine, image, uboot='2019.04',
- cpu_id='0x0', soc='AST2500 rev A1'):
- hostname = machine.removesuffix('-bmc')
+ cpu_id='0x0', soc='AST2500 rev A1',
+ image_hostname=None):
+ # Allow for the image hostname to not end in "-bmc"
+ if image_hostname is not None:
+ hostname = image_hostname
+ else:
+ hostname = machine.removesuffix('-bmc')
self.set_machine(machine)
self.vm.set_console()
@@ -44,7 +49,7 @@ class AspeedTest(LinuxKernelTest):
def do_test_arm_aspeed_buildroot_poweroff(self):
exec_command_and_wait_for_pattern(self, 'poweroff',
- 'System halted');
+ 'System halted')
def do_test_arm_aspeed_sdk_start(self, image):
self.require_netdev('user')
@@ -56,3 +61,11 @@ class AspeedTest(LinuxKernelTest):
self.wait_for_console_pattern('U-Boot 2019.04')
self.wait_for_console_pattern('## Loading kernel from FIT Image')
self.wait_for_console_pattern('Starting kernel ...')
+
+ def generate_otpmem_image(self):
+ path = self.scratch_file("otpmem.img")
+ pattern = b'\x00\x00\x00\x00\xff\xff\xff\xff' * (16 * 1024 // 8)
+ with open(path, "wb") as f:
+ f.write(pattern)
+ return path
+
diff --git a/tests/functional/avr/meson.build b/tests/functional/avr/meson.build
new file mode 100644
index 0000000..7a2cb70
--- /dev/null
+++ b/tests/functional/avr/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_avr_system_thorough = [
+ 'mega2560',
+ 'uno',
+]
diff --git a/tests/functional/test_avr_mega2560.py b/tests/functional/avr/test_mega2560.py
index 8e47b42..6359b72 100755
--- a/tests/functional/test_avr_mega2560.py
+++ b/tests/functional/avr/test_mega2560.py
@@ -18,12 +18,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import time
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
-from qemu_test import QemuSystemTest, Asset
class AVR6Machine(QemuSystemTest):
- timeout = 5
ASSET_ROM = Asset(('https://github.com/seharris/qemu-avr-tests'
'/raw/36c3e67b8755dcf/free-rtos/Demo'
@@ -40,13 +38,12 @@ class AVR6Machine(QemuSystemTest):
self.set_machine('arduino-mega-2560-v3')
self.vm.add_args('-bios', rom_path)
self.vm.add_args('-nographic')
+ self.vm.set_console()
self.vm.launch()
- time.sleep(2)
- self.vm.shutdown()
+ wait_for_console_pattern(self,
+ 'XABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWXA')
- self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
- self.vm.get_log())
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/avr/test_uno.py b/tests/functional/avr/test_uno.py
new file mode 100755
index 0000000..adb3b73
--- /dev/null
+++ b/tests/functional/avr/test_uno.py
@@ -0,0 +1,32 @@
+#!/usr/bin/env python3
+#
+# QEMU AVR Arduino UNO functional test
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+
+
+class UnoMachine(QemuSystemTest):
+
+ ASSET_UNO = Asset(
+ ('https://github.com/RahulRNandan/LED_Blink_AVR/raw/'
+ 'c6d602cbb974a193/build/main.elf'),
+ '3009a4e2cf5c5b65142f538abdf66d4dc6bc6beab7e552fff9ae314583761b72')
+
+ def test_uno(self):
+ """
+ The binary constantly prints out 'LED Blink'
+ """
+ self.set_machine('arduino-uno')
+ rom_path = self.ASSET_UNO.fetch()
+
+ self.vm.add_args('-bios', rom_path)
+ self.vm.set_console()
+ self.vm.launch()
+
+ wait_for_console_pattern(self, 'LED Blink')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/generic/meson.build b/tests/functional/generic/meson.build
new file mode 100644
index 0000000..013cc96
--- /dev/null
+++ b/tests/functional/generic/meson.build
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_generic_system = [
+ 'empty_cpu_model',
+ 'info_usernet',
+ 'version',
+ 'vnc',
+]
+
+tests_generic_linuxuser = [
+]
+
+tests_generic_bsduser = [
+]
diff --git a/tests/functional/test_empty_cpu_model.py b/tests/functional/generic/test_empty_cpu_model.py
index 0081b06..0081b06 100755
--- a/tests/functional/test_empty_cpu_model.py
+++ b/tests/functional/generic/test_empty_cpu_model.py
diff --git a/tests/functional/test_info_usernet.py b/tests/functional/generic/test_info_usernet.py
index e8cbc37..e8cbc37 100755
--- a/tests/functional/test_info_usernet.py
+++ b/tests/functional/generic/test_info_usernet.py
diff --git a/tests/functional/test_version.py b/tests/functional/generic/test_version.py
index 3ab3b67..3ab3b67 100755
--- a/tests/functional/test_version.py
+++ b/tests/functional/generic/test_version.py
diff --git a/tests/functional/generic/test_vmstate.py b/tests/functional/generic/test_vmstate.py
new file mode 100755
index 0000000..387ff54
--- /dev/null
+++ b/tests/functional/generic/test_vmstate.py
@@ -0,0 +1,67 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+'''This test runs the vmstate-static-checker script with the current QEMU'''
+
+import subprocess
+
+from qemu_test import QemuSystemTest, skipFlakyTest
+
+
+@skipFlakyTest("vmstate-static-checker can produce false positives")
+class VmStateTest(QemuSystemTest):
+ '''
+ This test helps to check whether there are problems between old
+ reference data and the current QEMU
+ '''
+
+ def test_vmstate_7_2(self):
+ '''Check reference data from QEMU v7.2'''
+
+ target_machine = {
+ 'aarch64': 'virt-7.2',
+ 'm68k': 'virt-7.2',
+ 'ppc64': 'pseries-7.2',
+ 's390x': 's390-ccw-virtio-7.2',
+ 'x86_64': 'pc-q35-7.2',
+ }
+ self.set_machine(target_machine[self.arch])
+
+ # Run QEMU to get the current vmstate json file:
+ dst_json = self.scratch_file('dest.json')
+ self.log.info('Dumping vmstate from %s', self.qemu_bin)
+ cp = subprocess.run([self.qemu_bin, '-nodefaults',
+ '-M', target_machine[self.arch],
+ '-dump-vmstate', dst_json],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True, check=True)
+ if cp.stdout:
+ self.log.info('QEMU output: %s', cp.stdout)
+
+ # Check whether the old vmstate json file is still compatible:
+ src_json = self.data_file('..', 'data', 'vmstate-static-checker',
+ self.arch,
+ target_machine[self.arch] + '.json')
+ self.log.info('Comparing vmstate with %s', src_json)
+ checkerscript = self.data_file('..', '..', 'scripts',
+ 'vmstate-static-checker.py')
+ cp = subprocess.run([checkerscript, '-s', src_json, '-d', dst_json],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True, check=False)
+ if cp.returncode != 0:
+ self.fail('Running vmstate-static-checker failed:\n' + cp.stdout +
+ '\nThis either means that there is a migration bug '
+ 'that needs to be fixed, or\nvmstate-static-checker.py '
+ 'needs to be improved (e.g. extend the changed_names\n'
+ 'in case a field has been renamed), or drop the '
+ 'problematic field from\n' + src_json +
+ '\nin case the script cannot be fixed easily.')
+ if cp.stdout:
+ self.log.warning('vmstate-static-checker output: %s', cp.stdout)
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_vnc.py b/tests/functional/generic/test_vnc.py
index 8c9953b..f1dd159 100755
--- a/tests/functional/test_vnc.py
+++ b/tests/functional/generic/test_vnc.py
@@ -11,12 +11,12 @@
# later. See the COPYING file in the top-level directory.
import socket
-from typing import List
-from qemu.machine.machine import VMLaunchFailure
+from qemu.machine.machine import VMLaunchFailure
from qemu_test import QemuSystemTest
from qemu_test.ports import Ports
+
VNC_ADDR = '127.0.0.1'
def check_connect(port: int) -> bool:
@@ -31,6 +31,7 @@ def check_connect(port: int) -> bool:
class Vnc(QemuSystemTest):
def test_no_vnc_change_password(self):
+ self.set_machine('none')
self.vm.add_args('-nodefaults', '-S')
self.vm.launch()
@@ -55,11 +56,14 @@ class Vnc(QemuSystemTest):
except VMLaunchFailure as excp:
if "-vnc: invalid option" in excp.output:
self.skipTest("VNC support not available")
+ elif "Cipher backend does not support DES algorithm" in excp.output:
+ self.skipTest("No cryptographic backend available")
else:
self.log.info("unhandled launch failure: %s", excp.output)
raise excp
def test_change_password_requires_a_password(self):
+ self.set_machine('none')
self.vm.add_args('-nodefaults', '-S', '-vnc', ':1,to=999')
self.launch_guarded()
self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
@@ -72,6 +76,7 @@ class Vnc(QemuSystemTest):
'Could not set password')
def test_change_password(self):
+ self.set_machine('none')
self.vm.add_args('-nodefaults', '-S', '-vnc', ':1,to=999,password=on')
self.launch_guarded()
self.assertTrue(self.vm.qmp('query-vnc')['return']['enabled'])
@@ -101,6 +106,7 @@ class Vnc(QemuSystemTest):
self.assertTrue(check_connect(c))
def test_change_listen(self):
+ self.set_machine('none')
with Ports() as ports:
a, b, c = ports.find_free_ports(3)
self.do_test_change_listen(a, b, c)
diff --git a/tests/functional/hppa/meson.build b/tests/functional/hppa/meson.build
new file mode 100644
index 0000000..df2f7cc
--- /dev/null
+++ b/tests/functional/hppa/meson.build
@@ -0,0 +1,9 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_hppa_system_quick = [
+ 'seabios',
+]
+
+tests_hppa_system_thorough = [
+ 'cdboot',
+]
diff --git a/tests/functional/hppa/test_cdboot.py b/tests/functional/hppa/test_cdboot.py
new file mode 100755
index 0000000..84421e8
--- /dev/null
+++ b/tests/functional/hppa/test_cdboot.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# CD boot test for HPPA machines
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+
+class HppaCdBoot(QemuSystemTest):
+
+ ASSET_CD = Asset(
+ ('https://github.com/philmd/qemu-testing-blob/raw/ec1b741/'
+ 'hppa/hp9000/712/C7120023.frm'),
+ '32c612ad2074516986bdc27768903c561fa92af2ca48e5ac3f3359ade1c42f70')
+
+ def test_cdboot(self):
+ self.set_machine('B160L')
+ cdrom_path = self.ASSET_CD.fetch()
+
+ self.vm.set_console()
+ self.vm.add_args('-cdrom', cdrom_path,
+ '-boot', 'd',
+ '-no-reboot')
+ self.vm.launch()
+ wait_for_console_pattern(self, 'Unrecognized MODEL TYPE = 502')
+ wait_for_console_pattern(self, 'UPDATE PAUSED>')
+
+ exec_command_and_wait_for_pattern(self, 'exit\r', 'UPDATE>')
+ exec_command_and_wait_for_pattern(self, 'ls\r', 'IMAGE1B')
+ wait_for_console_pattern(self, 'UPDATE>')
+ exec_command_and_wait_for_pattern(self, 'exit\r',
+ 'THIS UTILITY WILL NOW RESET THE SYSTEM.....')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_hppa_seabios.py b/tests/functional/hppa/test_seabios.py
index a44d1a3..661b246 100755
--- a/tests/functional/test_hppa_seabios.py
+++ b/tests/functional/hppa/test_seabios.py
@@ -17,9 +17,9 @@ class HppaSeabios(QemuSystemTest):
def boot_seabios(self):
mach = self.machine
bits = self.MACH_BITS[mach]
+ self.vm.add_args('-no-shutdown')
self.vm.set_console()
self.vm.launch()
- self.machine
wait_for_console_pattern(self, f'SeaBIOS PA-RISC {bits}-bit Firmware')
wait_for_console_pattern(self, f'Emulated machine: HP {mach} ({bits}-bit')
diff --git a/tests/functional/i386/meson.build b/tests/functional/i386/meson.build
new file mode 100644
index 0000000..23d8c21
--- /dev/null
+++ b/tests/functional/i386/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_i386_system_quick = [
+ 'migration',
+]
+
+tests_i386_system_thorough = [
+ 'replay',
+ 'tuxrun',
+]
diff --git a/tests/functional/i386/test_migration.py b/tests/functional/i386/test_migration.py
new file mode 100755
index 0000000..a57f316
--- /dev/null
+++ b/tests/functional/i386/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# i386 migration test
+
+from migration import MigrationTest
+
+
+class I386MigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('isapc')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('isapc')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('isapc')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/i386/test_replay.py b/tests/functional/i386/test_replay.py
new file mode 100755
index 0000000..7c4c260
--- /dev/null
+++ b/tests/functional/i386/test_replay.py
@@ -0,0 +1,28 @@
+#!/usr/bin/env python3
+#
+# Replay test that boots a Linux kernel on a i386 machine
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import Asset
+from replay_kernel import ReplayKernelBase
+
+
+class I386Replay(ReplayKernelBase):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/20230331/i386/bzImage',
+ 'a3e5b32a354729e65910f5a1ffcda7c14a6c12a55e8213fb86e277f1b76ed956')
+
+ def test_pc(self):
+ self.set_machine('pc')
+ kernel_url = ()
+ kernel_path = self.ASSET_KERNEL.fetch()
+ kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+ console_pattern = 'VFS: Cannot open root device'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
+
+
+if __name__ == '__main__':
+ ReplayKernelBase.main()
diff --git a/tests/functional/test_i386_tuxrun.py b/tests/functional/i386/test_tuxrun.py
index f3ccf11..f3ccf11 100755
--- a/tests/functional/test_i386_tuxrun.py
+++ b/tests/functional/i386/test_tuxrun.py
diff --git a/tests/functional/loongarch64/meson.build b/tests/functional/loongarch64/meson.build
new file mode 100644
index 0000000..d168717
--- /dev/null
+++ b/tests/functional/loongarch64/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_loongarch64_system_thorough = [
+ 'virt',
+]
diff --git a/tests/functional/test_loongarch64_virt.py b/tests/functional/loongarch64/test_virt.py
index b7d9abf..b7d9abf 100755
--- a/tests/functional/test_loongarch64_virt.py
+++ b/tests/functional/loongarch64/test_virt.py
diff --git a/tests/functional/m68k/meson.build b/tests/functional/m68k/meson.build
new file mode 100644
index 0000000..679faaf
--- /dev/null
+++ b/tests/functional/m68k/meson.build
@@ -0,0 +1,13 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_m68k_system_quick = [
+ 'vmstate',
+]
+
+tests_m68k_system_thorough = [
+ 'mcf5208evb',
+ 'nextcube',
+ 'replay',
+ 'q800',
+ 'tuxrun',
+]
diff --git a/tests/functional/test_m68k_mcf5208evb.py b/tests/functional/m68k/test_mcf5208evb.py
index c7d1998..c7d1998 100755
--- a/tests/functional/test_m68k_mcf5208evb.py
+++ b/tests/functional/m68k/test_mcf5208evb.py
diff --git a/tests/functional/test_m68k_nextcube.py b/tests/functional/m68k/test_nextcube.py
index ff773a7..e5e1c69 100755
--- a/tests/functional/test_m68k_nextcube.py
+++ b/tests/functional/m68k/test_nextcube.py
@@ -29,11 +29,20 @@ class NextCubeMachine(QemuSystemTest):
self.vm.launch()
self.log.info('VM launched, waiting for display')
- # TODO: wait for the 'displaysurface_create 1120x832' trace-event.
- time.sleep(2)
+ # Wait for the FPU test to finish, then the display is available, too:
+ while True:
+ res = self.vm.cmd('human-monitor-command',
+ command_line='info registers')
+ if ("F0 = 400e 8400000000000000" in res and
+ "F1 = 400e 83ff000000000000" in res and
+ "F2 = 400e 83ff000000000000" in res):
+ break
+ time.sleep(0.1)
- self.vm.cmd('human-monitor-command',
- command_line='screendump %s' % screenshot_path)
+ res = self.vm.cmd('human-monitor-command',
+ command_line='screendump %s' % screenshot_path)
+ if 'unknown command' in res:
+ self.skipTest('screendump not available')
@skipIfMissingImports("PIL")
def test_bootrom_framebuffer_size(self):
@@ -42,7 +51,8 @@ class NextCubeMachine(QemuSystemTest):
self.check_bootrom_framebuffer(screenshot_path)
from PIL import Image
- width, height = Image.open(screenshot_path).size
+ with Image.open(screenshot_path) as image:
+ width, height = image.size
self.assertEqual(width, 1120)
self.assertEqual(height, 832)
@@ -53,10 +63,10 @@ class NextCubeMachine(QemuSystemTest):
self.check_bootrom_framebuffer(screenshot_path)
lines = tesseract_ocr(screenshot_path)
text = '\n'.join(lines)
+ self.assertIn('Backplane slot', text)
+ self.assertIn('Ethernet address', text)
self.assertIn('Testing the FPU', text)
- self.assertIn('System test failed. Error code', text)
- self.assertIn('Boot command', text)
- self.assertIn('Next>', text)
+
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/test_m68k_q800.py b/tests/functional/m68k/test_q800.py
index 400b7ae..b3e6553 100755
--- a/tests/functional/test_m68k_q800.py
+++ b/tests/functional/m68k/test_q800.py
@@ -25,7 +25,8 @@ class Q800MachineTest(LinuxKernelTest):
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 vga=off')
self.vm.add_args('-kernel', kernel_path,
- '-append', kernel_command_line)
+ '-append', kernel_command_line,
+ '-audio', 'none')
self.vm.launch()
console_pattern = 'Kernel command line: %s' % kernel_command_line
self.wait_for_console_pattern(console_pattern)
diff --git a/tests/functional/test_m68k_replay.py b/tests/functional/m68k/test_replay.py
index 18c1db5..213d6ae 100755
--- a/tests/functional/test_m68k_replay.py
+++ b/tests/functional/m68k/test_replay.py
@@ -24,7 +24,8 @@ class M68kReplay(ReplayKernelBase):
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyS0 vga=off')
console_pattern = 'No filesystem could mount root'
- self.run_rr(kernel_path, kernel_command_line, console_pattern)
+ self.run_rr(kernel_path, kernel_command_line, console_pattern,
+ args=('-audio', 'none'))
ASSET_MCF5208 = Asset(
'https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/day07.tar.xz',
diff --git a/tests/functional/test_m68k_tuxrun.py b/tests/functional/m68k/test_tuxrun.py
index 7eacba1..7eacba1 100755
--- a/tests/functional/test_m68k_tuxrun.py
+++ b/tests/functional/m68k/test_tuxrun.py
diff --git a/tests/functional/meson.build b/tests/functional/meson.build
index 0f8be30..725630d 100644
--- a/tests/functional/meson.build
+++ b/tests/functional/meson.build
@@ -9,315 +9,34 @@ if get_option('tcg_interpreter')
subdir_done()
endif
-# Timeouts for individual tests that can be slow e.g. with debugging enabled
-test_timeouts = {
- 'aarch64_aspeed' : 600,
- 'aarch64_raspi4' : 480,
- 'aarch64_rme_virt' : 1200,
- 'aarch64_rme_sbsaref' : 1200,
- 'aarch64_sbsaref_alpine' : 1200,
- 'aarch64_sbsaref_freebsd' : 720,
- 'aarch64_tuxrun' : 240,
- 'aarch64_virt' : 360,
- 'aarch64_virt_gpu' : 480,
- 'acpi_bits' : 420,
- 'arm_aspeed_palmetto' : 120,
- 'arm_aspeed_romulus' : 120,
- 'arm_aspeed_witherspoon' : 120,
- 'arm_aspeed_ast2500' : 720,
- 'arm_aspeed_ast2600' : 1200,
- 'arm_aspeed_bletchley' : 480,
- 'arm_aspeed_rainier' : 480,
- 'arm_bpim2u' : 500,
- 'arm_collie' : 180,
- 'arm_cubieboard' : 360,
- 'arm_orangepi' : 540,
- 'arm_quanta_gsj' : 240,
- 'arm_raspi2' : 120,
- 'arm_replay' : 240,
- 'arm_tuxrun' : 240,
- 'arm_sx1' : 360,
- 'intel_iommu': 300,
- 'mips_malta' : 120,
- 'mipsel_replay' : 480,
- 'mips64el_replay' : 180,
- 'netdev_ethtool' : 180,
- 'ppc_40p' : 240,
- 'ppc64_hv' : 1000,
- 'ppc64_powernv' : 480,
- 'ppc64_pseries' : 480,
- 'ppc64_replay' : 210,
- 'ppc64_tuxrun' : 420,
- 'ppc64_mac99' : 120,
- 'riscv64_tuxrun' : 120,
- 's390x_ccw_virtio' : 420,
- 'sh4_tuxrun' : 240,
- 'virtio_balloon': 120,
- 'x86_64_kvm_xen' : 180,
- 'x86_64_replay' : 480,
-}
-
-tests_generic_system = [
- 'empty_cpu_model',
- 'info_usernet',
- 'version',
-]
-
-tests_generic_linuxuser = [
-]
-
-tests_generic_bsduser = [
-]
-
-tests_aarch64_system_quick = [
- 'migration',
-]
-
-tests_aarch64_system_thorough = [
- 'aarch64_aspeed',
- 'aarch64_raspi3',
- 'aarch64_raspi4',
- 'aarch64_replay',
- 'aarch64_rme_virt',
- 'aarch64_rme_sbsaref',
- 'aarch64_sbsaref',
- 'aarch64_sbsaref_alpine',
- 'aarch64_sbsaref_freebsd',
- 'aarch64_tcg_plugins',
- 'aarch64_tuxrun',
- 'aarch64_virt',
- 'aarch64_virt_gpu',
- 'aarch64_xen',
- 'aarch64_xlnx_versal',
- 'multiprocess',
-]
-
-tests_alpha_system_quick = [
- 'migration',
-]
-
-tests_alpha_system_thorough = [
- 'alpha_clipper',
- 'alpha_replay',
-]
-
-tests_arm_system_quick = [
- 'migration',
-]
-
-tests_arm_system_thorough = [
- 'arm_aspeed_ast1030',
- 'arm_aspeed_palmetto',
- 'arm_aspeed_romulus',
- 'arm_aspeed_witherspoon',
- 'arm_aspeed_ast2500',
- 'arm_aspeed_ast2600',
- 'arm_aspeed_bletchley',
- 'arm_aspeed_rainier',
- 'arm_bpim2u',
- 'arm_canona1100',
- 'arm_collie',
- 'arm_cubieboard',
- 'arm_emcraft_sf2',
- 'arm_integratorcp',
- 'arm_microbit',
- 'arm_orangepi',
- 'arm_quanta_gsj',
- 'arm_raspi2',
- 'arm_replay',
- 'arm_smdkc210',
- 'arm_sx1',
- 'arm_vexpress',
- 'arm_virt',
- 'arm_tuxrun',
-]
-
-tests_arm_linuxuser_thorough = [
- 'arm_bflt',
-]
-
-tests_avr_system_thorough = [
- 'avr_mega2560',
-]
-
-tests_hppa_system_quick = [
- 'hppa_seabios',
-]
-
-tests_i386_system_quick = [
- 'migration',
-]
-
-tests_i386_system_thorough = [
- 'i386_tuxrun',
-]
-
-tests_loongarch64_system_thorough = [
- 'loongarch64_virt',
-]
-
-tests_m68k_system_thorough = [
- 'm68k_mcf5208evb',
- 'm68k_nextcube',
- 'm68k_replay',
- 'm68k_q800',
- 'm68k_tuxrun',
-]
-
-tests_microblaze_system_thorough = [
- 'microblaze_replay',
- 'microblaze_s3adsp1800'
-]
-
-tests_microblazeel_system_thorough = [
- 'microblazeel_s3adsp1800'
-]
-
-tests_mips_system_thorough = [
- 'mips_malta',
- 'mips_replay',
- 'mips_tuxrun',
-]
-
-tests_mipsel_system_thorough = [
- 'mipsel_malta',
- 'mipsel_replay',
- 'mipsel_tuxrun',
-]
-
-tests_mips64_system_thorough = [
- 'mips64_tuxrun',
-]
-
-tests_mips64el_system_thorough = [
- 'mips64el_fuloong2e',
- 'mips64el_loongson3v',
- 'mips64el_malta',
- 'mips64el_replay',
- 'mips64el_tuxrun',
-]
-
-tests_or1k_system_thorough = [
- 'or1k_replay',
- 'or1k_sim',
-]
-
-tests_ppc_system_quick = [
- 'migration',
- 'ppc_74xx',
-]
-
-tests_ppc_system_thorough = [
- 'ppc_40p',
- 'ppc_amiga',
- 'ppc_bamboo',
- 'ppc_mac',
- 'ppc_mpc8544ds',
- 'ppc_replay',
- 'ppc_sam460ex',
- 'ppc_tuxrun',
- 'ppc_virtex_ml507',
-]
-
-tests_ppc64_system_quick = [
- 'migration',
-]
-
-tests_ppc64_system_thorough = [
- 'ppc64_e500',
- 'ppc64_hv',
- 'ppc64_powernv',
- 'ppc64_pseries',
- 'ppc64_replay',
- 'ppc64_tuxrun',
- 'ppc64_mac99',
-]
-
-tests_riscv32_system_quick = [
- 'migration',
- 'riscv_opensbi',
-]
-
-tests_riscv32_system_thorough = [
- 'riscv32_tuxrun',
-]
-
-tests_riscv64_system_quick = [
- 'migration',
- 'riscv_opensbi',
-]
-
-tests_riscv64_system_thorough = [
- 'riscv64_tuxrun',
-]
-
-tests_rx_system_thorough = [
- 'rx_gdbsim',
-]
-
-tests_s390x_system_thorough = [
- 's390x_ccw_virtio',
- 's390x_replay',
- 's390x_topology',
- 's390x_tuxrun',
-]
-
-tests_sh4_system_thorough = [
- 'sh4_r2d',
- 'sh4_tuxrun',
-]
-
-tests_sh4eb_system_thorough = [
- 'sh4eb_r2d',
-]
-
-tests_sparc_system_quick = [
- 'migration',
-]
-
-tests_sparc_system_thorough = [
- 'sparc_replay',
- 'sparc_sun4m',
-]
-
-tests_sparc64_system_quick = [
- 'migration',
-]
-
-tests_sparc64_system_thorough = [
- 'sparc64_sun4u',
- 'sparc64_tuxrun',
-]
-
-tests_x86_64_system_quick = [
- 'cpu_queries',
- 'mem_addr_space',
- 'migration',
- 'pc_cpu_hotplug_props',
- 'virtio_version',
- 'x86_cpu_model_versions',
- 'vnc',
-]
-
-tests_x86_64_system_thorough = [
- 'acpi_bits',
- 'intel_iommu',
- 'linux_initrd',
- 'multiprocess',
- 'netdev_ethtool',
- 'virtio_balloon',
- 'virtio_gpu',
- 'x86_64_hotplug_blk',
- 'x86_64_hotplug_cpu',
- 'x86_64_kvm_xen',
- 'x86_64_replay',
- 'x86_64_tuxrun',
-]
-
-tests_xtensa_system_thorough = [
- 'xtensa_lx60',
- 'xtensa_replay',
-]
+subdir('aarch64')
+subdir('alpha')
+subdir('arm')
+subdir('avr')
+subdir('hppa')
+subdir('i386')
+subdir('loongarch64')
+subdir('m68k')
+subdir('microblaze')
+subdir('microblazeel')
+subdir('mips')
+subdir('mipsel')
+subdir('mips64')
+subdir('mips64el')
+subdir('or1k')
+subdir('ppc')
+subdir('ppc64')
+subdir('riscv32')
+subdir('riscv64')
+subdir('rx')
+subdir('s390x')
+subdir('sh4')
+subdir('sh4eb')
+subdir('sparc')
+subdir('sparc64')
+subdir('x86_64')
+subdir('xtensa')
+subdir('generic')
precache_all = []
foreach speed : ['quick', 'thorough']
@@ -347,7 +66,7 @@ foreach speed : ['quick', 'thorough']
target_tests = get_variable('tests_' + target_base + '_' + sysmode + '_' + speed, [])
endif
- test_deps = roms
+ test_deps = [roms, keymap_targets]
test_env = environment()
if have_tools
test_env.set('QEMU_TEST_QEMU_IMG', meson.global_build_root() / 'qemu-img')
@@ -358,9 +77,19 @@ foreach speed : ['quick', 'thorough']
test_env.set('PYTHONPATH', meson.project_source_root() / 'python:' +
meson.current_source_dir())
+ # Define the GDB environment variable if gdb is available.
+ gdb = get_option('gdb')
+ if gdb != ''
+ test_env.set('QEMU_TEST_GDB', gdb)
+ endif
+
foreach test : target_tests
testname = '@0@-@1@'.format(target_base, test)
- testfile = 'test_' + test + '.py'
+ if fs.exists('generic' / 'test_' + test + '.py')
+ testfile = 'generic' / 'test_' + test + '.py'
+ else
+ testfile = target_base / 'test_' + test + '.py'
+ endif
testpath = meson.current_source_dir() / testfile
teststamp = testname + '.tstamp'
test_precache_env = environment()
@@ -374,6 +103,11 @@ foreach speed : ['quick', 'thorough']
build_by_default: false,
env: test_precache_env)
precache_all += precache
+ if is_variable('test_' + target_base + '_timeouts')
+ time_out = get_variable('test_' + target_base + '_timeouts').get(test, 90)
+ else
+ time_out = 90
+ endif
# Ideally we would add 'precache' to 'depends' here, such that
# 'build_by_default: false' lets the pre-caching automatically
@@ -389,8 +123,8 @@ foreach speed : ['quick', 'thorough']
env: test_env,
args: [testpath],
protocol: 'tap',
- timeout: test_timeouts.get(test, 90),
- priority: test_timeouts.get(test, 90),
+ timeout: time_out,
+ priority: time_out,
suite: suites)
endforeach
endforeach
@@ -398,4 +132,4 @@ endforeach
run_target('precache-functional',
depends: precache_all,
- command: ['true'])
+ command: [python, '-c', ''])
diff --git a/tests/functional/microblaze/meson.build b/tests/functional/microblaze/meson.build
new file mode 100644
index 0000000..8069ca9
--- /dev/null
+++ b/tests/functional/microblaze/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_microblaze_system_thorough = [
+ 'replay',
+ 's3adsp1800'
+]
diff --git a/tests/functional/test_microblaze_replay.py b/tests/functional/microblaze/test_replay.py
index 7484c41..7484c41 100755
--- a/tests/functional/test_microblaze_replay.py
+++ b/tests/functional/microblaze/test_replay.py
diff --git a/tests/functional/test_microblaze_s3adsp1800.py b/tests/functional/microblaze/test_s3adsp1800.py
index c93fa14..f093b16 100755
--- a/tests/functional/test_microblaze_s3adsp1800.py
+++ b/tests/functional/microblaze/test_s3adsp1800.py
@@ -25,12 +25,14 @@ class MicroblazeMachine(QemuSystemTest):
('http://www.qemu-advent-calendar.org/2023/download/day13.tar.gz'),
'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22')
- def do_ballerina_be_test(self, machine):
- self.set_machine(machine)
+ def do_ballerina_be_test(self, force_endianness=False):
+ self.set_machine('petalogix-s3adsp1800')
self.archive_extract(self.ASSET_IMAGE_BE)
self.vm.set_console()
self.vm.add_args('-kernel',
self.scratch_file('day17', 'ballerina.bin'))
+ if force_endianness:
+ self.vm.add_args('-M', 'endianness=big')
self.vm.launch()
wait_for_console_pattern(self, 'This architecture does not have '
'kernel memory protection')
@@ -39,12 +41,14 @@ class MicroblazeMachine(QemuSystemTest):
# message, that's why we don't test for a later string here. This
# needs some investigation by a microblaze wizard one day...
- def do_xmaton_le_test(self, machine):
+ def do_xmaton_le_test(self, force_endianness=False):
self.require_netdev('user')
- self.set_machine(machine)
+ self.set_machine('petalogix-s3adsp1800')
self.archive_extract(self.ASSET_IMAGE_LE)
self.vm.set_console()
self.vm.add_args('-kernel', self.scratch_file('day13', 'xmaton.bin'))
+ if force_endianness:
+ self.vm.add_args('-M', 'endianness=little')
tftproot = self.scratch_file('day13')
self.vm.add_args('-nic', f'user,tftp={tftproot}')
self.vm.launch()
@@ -59,9 +63,13 @@ class MicroblazeMachine(QemuSystemTest):
class MicroblazeBigEndianMachine(MicroblazeMachine):
ASSET_IMAGE_BE = MicroblazeMachine.ASSET_IMAGE_BE
+ ASSET_IMAGE_LE = MicroblazeMachine.ASSET_IMAGE_LE
def test_microblaze_s3adsp1800_legacy_be(self):
- self.do_ballerina_be_test('petalogix-s3adsp1800')
+ self.do_ballerina_be_test()
+
+ def test_microblaze_s3adsp1800_legacy_le(self):
+ self.do_xmaton_le_test(force_endianness=True)
if __name__ == '__main__':
diff --git a/tests/functional/microblazeel/meson.build b/tests/functional/microblazeel/meson.build
new file mode 100644
index 0000000..27619dc
--- /dev/null
+++ b/tests/functional/microblazeel/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_microblazeel_system_thorough = [
+ 's3adsp1800'
+]
diff --git a/tests/functional/test_microblazeel_s3adsp1800.py b/tests/functional/microblazeel/test_s3adsp1800.py
index ab59941..75ce885 100755
--- a/tests/functional/test_microblazeel_s3adsp1800.py
+++ b/tests/functional/microblazeel/test_s3adsp1800.py
@@ -7,15 +7,19 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-from test_microblaze_s3adsp1800 import MicroblazeMachine
+from microblaze.test_s3adsp1800 import MicroblazeMachine
class MicroblazeLittleEndianMachine(MicroblazeMachine):
ASSET_IMAGE_LE = MicroblazeMachine.ASSET_IMAGE_LE
+ ASSET_IMAGE_BE = MicroblazeMachine.ASSET_IMAGE_BE
def test_microblaze_s3adsp1800_legacy_le(self):
- self.do_xmaton_le_test('petalogix-s3adsp1800')
+ self.do_xmaton_le_test()
+
+ def test_microblaze_s3adsp1800_legacy_be(self):
+ self.do_ballerina_be_test(force_endianness=True)
if __name__ == '__main__':
diff --git a/tests/functional/test_migration.py b/tests/functional/migration.py
index 181223a..0739554 100755..100644
--- a/tests/functional/test_migration.py
+++ b/tests/functional/migration.py
@@ -1,6 +1,6 @@
-#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
#
-# Migration test
+# Migration test base class
#
# Copyright (c) 2019 Red Hat, Inc.
#
@@ -11,14 +11,13 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
-
import tempfile
-import os
import time
-from qemu_test import QemuSystemTest, skipIfMissingCommands
+from qemu_test import QemuSystemTest, which
from qemu_test.ports import Ports
+
class MigrationTest(QemuSystemTest):
timeout = 10
@@ -42,24 +41,7 @@ class MigrationTest(QemuSystemTest):
self.assertEqual(dst_vm.cmd('query-status')['status'], 'running')
self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate')
- def select_machine(self):
- target_machine = {
- 'aarch64': 'quanta-gsj',
- 'alpha': 'clipper',
- 'arm': 'npcm750-evb',
- 'i386': 'isapc',
- 'ppc': 'sam460ex',
- 'ppc64': 'mac99',
- 'riscv32': 'spike',
- 'riscv64': 'virt',
- 'sparc': 'SS-4',
- 'sparc64': 'sun4u',
- 'x86_64': 'microvm',
- }
- self.set_machine(target_machine[self.arch])
-
def do_migrate(self, dest_uri, src_uri=None):
- self.select_machine()
dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu")
dest_vm.add_args('-nodefaults')
dest_vm.launch()
@@ -77,23 +59,21 @@ class MigrationTest(QemuSystemTest):
self.skipTest('Failed to find a free port')
return port
- def test_migration_with_tcp_localhost(self):
+ def migration_with_tcp_localhost(self):
with Ports() as ports:
dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports)
self.do_migrate(dest_uri)
- def test_migration_with_unix(self):
+ def migration_with_unix(self):
with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
dest_uri = 'unix:%s/qemu-test.sock' % socket_path
self.do_migrate(dest_uri)
- @skipIfMissingCommands('ncat')
- def test_migration_with_exec(self):
+ def migration_with_exec(self):
+ if not which('ncat'):
+ self.skipTest('ncat is not available')
with Ports() as ports:
free_port = self._get_free_port(ports)
dest_uri = 'exec:ncat -l localhost %u' % free_port
src_uri = 'exec:ncat localhost %u' % free_port
self.do_migrate(dest_uri, src_uri)
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/mips/meson.build b/tests/functional/mips/meson.build
new file mode 100644
index 0000000..49aaf53
--- /dev/null
+++ b/tests/functional/mips/meson.build
@@ -0,0 +1,11 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mips_timeouts = {
+ 'malta' : 480,
+}
+
+tests_mips_system_thorough = [
+ 'malta',
+ 'replay',
+ 'tuxrun',
+]
diff --git a/tests/functional/mips/test_malta.py b/tests/functional/mips/test_malta.py
new file mode 100755
index 0000000..30279f0
--- /dev/null
+++ b/tests/functional/mips/test_malta.py
@@ -0,0 +1,196 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the big-endian 32-bit MIPS Malta board
+#
+# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+from qemu_test import LinuxKernelTest, Asset, wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+def mips_run_common_commands(test, prompt='#'):
+ exec_command_and_wait_for_pattern(test,
+ 'uname -m',
+ 'mips')
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'timer')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'serial')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'ata_piix')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'grep XT-PIC /proc/interrupts',
+ 'rtc')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/devices',
+ 'input')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/devices',
+ 'fb')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/ioports',
+ ' : serial')
+ wait_for_console_pattern(test, prompt)
+ exec_command_and_wait_for_pattern(test,
+ 'cat /proc/ioports',
+ ' : ata_piix')
+ wait_for_console_pattern(test, prompt)
+
+def mips_check_wheezy(test, kernel_path, image_path, kernel_command_line,
+ dl_file, hsum, nic='pcnet', cpuinfo='MIPS 24Kc'):
+ test.require_netdev('user')
+ test.require_device(nic)
+ test.set_machine('malta')
+
+ port=8080
+ test.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line,
+ '-drive', 'file=%s,snapshot=on' % image_path,
+ '-netdev', 'user,id=n1' +
+ ',tftp=' + os.path.basename(kernel_path) +
+ ',hostfwd=tcp:127.0.0.1:0-:%d' % port,
+ '-device', f'{nic},netdev=n1',
+ '-no-reboot')
+ test.vm.set_console()
+ test.vm.launch()
+
+ wait_for_console_pattern(test, 'login: ', 'Oops')
+ exec_command_and_wait_for_pattern(test, 'root', 'Password:')
+ exec_command_and_wait_for_pattern(test, 'root', ':~# ')
+ mips_run_common_commands(test)
+
+ exec_command_and_wait_for_pattern(test, 'cd /', '# ')
+ test.check_http_download(dl_file, hsum, port,
+ pythoncmd='python -m SimpleHTTPServer')
+
+ exec_command_and_wait_for_pattern(test, 'cat /proc/cpuinfo', cpuinfo)
+ exec_command_and_wait_for_pattern(test, 'cat /proc/devices', 'usb')
+ exec_command_and_wait_for_pattern(test, 'cat /proc/ioports',
+ ' : piix4_smbus')
+ exec_command_and_wait_for_pattern(test, 'lspci -d 11ab:4620',
+ 'GT-64120')
+ exec_command_and_wait_for_pattern(test,
+ 'cat /sys/bus/i2c/devices/i2c-0/name',
+ 'SMBus PIIX4 adapter')
+ exec_command_and_wait_for_pattern(test, 'cat /proc/mtd', 'YAMON')
+ # Empty 'Board Config' (64KB)
+ exec_command_and_wait_for_pattern(test, 'md5sum /dev/mtd2ro',
+ '0dfbe8aa4c20b52e1b8bf3cb6cbdf193')
+
+
+class MaltaMachineConsole(LinuxKernelTest):
+
+ ASSET_KERNEL_2_63_2 = Asset(
+ ('http://snapshot.debian.org/archive/debian/'
+ '20130217T032700Z/pool/main/l/linux-2.6/'
+ 'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb'),
+ '16ca524148afb0626f483163e5edf352bc1ab0e4fc7b9f9d473252762f2c7a43')
+
+ def test_mips_malta(self):
+ kernel_path = self.archive_extract(
+ self.ASSET_KERNEL_2_63_2,
+ member='boot/vmlinux-2.6.32-5-4kc-malta')
+
+ self.set_machine('malta')
+ self.vm.set_console()
+ kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
+ self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line)
+ self.vm.launch()
+ console_pattern = 'Kernel command line: %s' % kernel_command_line
+ self.wait_for_console_pattern(console_pattern)
+
+ ASSET_KERNEL_4_5_0 = Asset(
+ ('http://snapshot.debian.org/archive/debian/'
+ '20160601T041800Z/pool/main/l/linux/'
+ 'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb'),
+ '526b17d5889840888b76fc2c36a0ebde182c9b1410a3a1e68203c3b160eb2027')
+
+ ASSET_INITRD = Asset(
+ ('https://github.com/groeck/linux-build-test/raw/'
+ '8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/'
+ 'mips/rootfs.cpio.gz'),
+ 'dcfe3a7fe3200da3a00d176b95caaa086495eb158f2bff64afc67d7e1eb2cddc')
+
+ def test_mips_malta_cpio(self):
+ self.require_netdev('user')
+ self.set_machine('malta')
+ self.require_device('pcnet')
+
+ kernel_path = self.archive_extract(
+ self.ASSET_KERNEL_4_5_0,
+ member='boot/vmlinux-4.5.0-2-4kc-malta')
+ initrd_path = self.uncompress(self.ASSET_INITRD)
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 console=tty '
+ + 'rdinit=/sbin/init noreboot')
+ self.vm.add_args('-kernel', kernel_path,
+ '-initrd', initrd_path,
+ '-append', kernel_command_line,
+ '-netdev', 'user,id=n1,tftp=' + self.scratch_file('boot'),
+ '-device', 'pcnet,netdev=n1',
+ '-no-reboot')
+ self.vm.launch()
+ self.wait_for_console_pattern('Boot successful.')
+
+ exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
+ 'BogoMIPS')
+ exec_command_and_wait_for_pattern(self, 'uname -a',
+ '4.5.0-2-4kc-malta #1 Debian')
+ mips_run_common_commands(self)
+
+ exec_command_and_wait_for_pattern(self, 'ip link set eth0 up',
+ 'eth0: link up')
+ exec_command_and_wait_for_pattern(self,
+ 'ip addr add 10.0.2.15 dev eth0',
+ '#')
+ exec_command_and_wait_for_pattern(self, 'route add default eth0', '#')
+ exec_command_and_wait_for_pattern(self,
+ 'tftp -g -r vmlinux-4.5.0-2-4kc-malta 10.0.2.2', '#')
+ exec_command_and_wait_for_pattern(self,
+ 'md5sum vmlinux-4.5.0-2-4kc-malta',
+ 'a98218a7efbdefb2dfdf9ecd08c98318')
+
+ exec_command_and_wait_for_pattern(self, 'reboot',
+ 'reboot: Restarting system')
+ # Wait for VM to shut down gracefully
+ self.vm.wait()
+
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'vmlinux-3.2.0-4-4kc-malta'),
+ '0377fcda31299213c10b8e5babe7260ef99188b3ae1aca6f56594abb71e7f67e')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2'),
+ 'de03599285b8382ad309309a6c4869f6c6c42a5cfc983342bab9ec0dfa7849a2')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, nic='e1000',
+ dl_file='/boot/initrd.img-3.2.0-4-4kc-malta',
+ hsum='ff0c0369143d9bbb9a6e6bc79322a2be535619df639e84103237f406e87493dc')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_mips_replay.py b/tests/functional/mips/test_replay.py
index eda031c..4327481 100755
--- a/tests/functional/test_mips_replay.py
+++ b/tests/functional/mips/test_replay.py
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, skipSlowTest, exec_command_and_wait_for_pattern
+from qemu_test import Asset, skipSlowTest
from replay_kernel import ReplayKernelBase
diff --git a/tests/functional/test_mips_tuxrun.py b/tests/functional/mips/test_tuxrun.py
index 6771dbd..6771dbd 100755
--- a/tests/functional/test_mips_tuxrun.py
+++ b/tests/functional/mips/test_tuxrun.py
diff --git a/tests/functional/mips64/meson.build b/tests/functional/mips64/meson.build
new file mode 100644
index 0000000..3ff2118
--- /dev/null
+++ b/tests/functional/mips64/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mips64_timeouts = {
+ 'malta' : 240,
+}
+
+tests_mips64_system_thorough = [
+ 'malta',
+ 'tuxrun',
+]
diff --git a/tests/functional/mips64/test_malta.py b/tests/functional/mips64/test_malta.py
new file mode 100755
index 0000000..a553d3c
--- /dev/null
+++ b/tests/functional/mips64/test_malta.py
@@ -0,0 +1,35 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the big-endian 64-bit MIPS Malta board
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import LinuxKernelTest, Asset
+from mips.test_malta import mips_check_wheezy
+
+
+class MaltaMachineConsole(LinuxKernelTest):
+
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'vmlinux-3.2.0-4-5kc-malta'),
+ '3e4ec154db080b3f1839f04dde83120654a33e5e1716863de576c47cb94f68f6')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mips/'
+ 'debian_wheezy_mips_standard.qcow2'),
+ 'de03599285b8382ad309309a6c4869f6c6c42a5cfc983342bab9ec0dfa7849a2')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, cpuinfo='MIPS 20Kc',
+ dl_file='/boot/initrd.img-3.2.0-4-5kc-malta',
+ hsum='d98b953bb4a41c0fc0fd8d19bbc691c08989ac52568c1d3054d92dfd890d3f06')
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_mips64_tuxrun.py b/tests/functional/mips64/test_tuxrun.py
index 0e4c659..0e4c659 100755
--- a/tests/functional/test_mips64_tuxrun.py
+++ b/tests/functional/mips64/test_tuxrun.py
diff --git a/tests/functional/mips64el/meson.build b/tests/functional/mips64el/meson.build
new file mode 100644
index 0000000..69ec501
--- /dev/null
+++ b/tests/functional/mips64el/meson.build
@@ -0,0 +1,14 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mips64el_timeouts = {
+ 'malta' : 420,
+ 'replay' : 180,
+}
+
+tests_mips64el_system_thorough = [
+ 'fuloong2e',
+ 'loongson3v',
+ 'malta',
+ 'replay',
+ 'tuxrun',
+]
diff --git a/tests/functional/test_mips64el_fuloong2e.py b/tests/functional/mips64el/test_fuloong2e.py
index 35e500b..35e500b 100755
--- a/tests/functional/test_mips64el_fuloong2e.py
+++ b/tests/functional/mips64el/test_fuloong2e.py
diff --git a/tests/functional/test_mips64el_loongson3v.py b/tests/functional/mips64el/test_loongson3v.py
index f85371e..f85371e 100755
--- a/tests/functional/test_mips64el_loongson3v.py
+++ b/tests/functional/mips64el/test_loongson3v.py
diff --git a/tests/functional/test_mips64el_malta.py b/tests/functional/mips64el/test_malta.py
index a8da15a..170147b 100755
--- a/tests/functional/test_mips64el_malta.py
+++ b/tests/functional/mips64el/test_malta.py
@@ -16,6 +16,8 @@ from qemu_test import LinuxKernelTest, Asset
from qemu_test import exec_command_and_wait_for_pattern
from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest
+from mips.test_malta import mips_check_wheezy
+
class MaltaMachineConsole(LinuxKernelTest):
@@ -90,6 +92,26 @@ class MaltaMachineConsole(LinuxKernelTest):
# Wait for VM to shut down gracefully
self.vm.wait()
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'vmlinux-3.2.0-4-5kc-malta'),
+ '5e8b725244c59745bb8b64f5d8f49f25fecfa549f3395fb6d19a3b9e5065b85b')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2'),
+ '454f09ae39f7e6461c84727b927100d2c7813841f2a0a5dce328114887ecf914')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line, cpuinfo='MIPS 20Kc',
+ dl_file='/boot/initrd.img-3.2.0-4-5kc-malta',
+ hsum='7579f8b56c1187c7c04d0dc3c0c56c7a6314c5ddd3a9bf8803ecc7cf8a3be9f8')
+
@skipIfMissingImports('numpy', 'cv2')
class MaltaMachineFramebuffer(LinuxKernelTest):
@@ -133,9 +155,10 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
framebuffer_ready = 'Console: switching to colour frame buffer device'
self.wait_for_console_pattern(framebuffer_ready)
self.vm.cmd('human-monitor-command', command_line='stop')
- self.vm.cmd('human-monitor-command',
- command_line='screendump %s' % screendump_path)
- logger = logging.getLogger('framebuffer')
+ res = self.vm.cmd('human-monitor-command',
+ command_line='screendump %s' % screendump_path)
+ if 'unknown command' in res:
+ self.skipTest('screendump not available')
match_threshold = 0.95
screendump_bgr = cv2.imread(screendump_path, cv2.IMREAD_COLOR)
@@ -147,7 +170,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
h, w = tuxlogo_bgr.shape[:2]
debug_png = os.getenv('QEMU_TEST_CV2_SCREENDUMP_PNG_PATH')
for tuxlogo_count, pt in enumerate(zip(*loc[::-1]), start=1):
- logger.debug('found Tux at position (x, y) = %s', pt)
+ self.log.debug('found Tux at position (x, y) = %s', pt)
cv2.rectangle(screendump_bgr, pt,
(pt[0] + w, pt[1] + h), (0, 0, 255), 2)
if debug_png:
@@ -167,7 +190,7 @@ class MaltaMachineFramebuffer(LinuxKernelTest):
self.do_test_i6400_framebuffer_logo(8)
-from test_mipsel_malta import MaltaMachineYAMON
+from mipsel.test_malta import MaltaMachineYAMON
if __name__ == '__main__':
LinuxKernelTest.main()
diff --git a/tests/functional/test_mips64el_replay.py b/tests/functional/mips64el/test_replay.py
index 4f63d7f..26a6ccf 100755
--- a/tests/functional/test_mips64el_replay.py
+++ b/tests/functional/mips64el/test_replay.py
@@ -4,11 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-import logging
-
-from qemu_test import Asset, exec_command_and_wait_for_pattern
-from qemu_test import skipIfMissingImports, skipFlakyTest, skipUntrustedTest
+from qemu_test import Asset, skipUntrustedTest
from replay_kernel import ReplayKernelBase
diff --git a/tests/functional/test_mips64el_tuxrun.py b/tests/functional/mips64el/test_tuxrun.py
index 0a24757..0a24757 100755
--- a/tests/functional/test_mips64el_tuxrun.py
+++ b/tests/functional/mips64el/test_tuxrun.py
diff --git a/tests/functional/mipsel/meson.build b/tests/functional/mipsel/meson.build
new file mode 100644
index 0000000..8bfdf06
--- /dev/null
+++ b/tests/functional/mipsel/meson.build
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_mipsel_timeouts = {
+ 'malta' : 420,
+ 'replay' : 480,
+}
+
+tests_mipsel_system_thorough = [
+ 'malta',
+ 'replay',
+ 'tuxrun',
+]
diff --git a/tests/functional/test_mipsel_malta.py b/tests/functional/mipsel/test_malta.py
index fe9c3a1..427e163 100755
--- a/tests/functional/test_mipsel_malta.py
+++ b/tests/functional/mipsel/test_malta.py
@@ -13,6 +13,8 @@ from qemu_test import QemuSystemTest, LinuxKernelTest, Asset
from qemu_test import interrupt_interactive_console_until_pattern
from qemu_test import wait_for_console_pattern
+from mips.test_malta import mips_check_wheezy
+
class MaltaMachineConsole(LinuxKernelTest):
@@ -57,6 +59,26 @@ class MaltaMachineConsole(LinuxKernelTest):
def test_mips_malta32el_nanomips_64k_dbg(self):
self.do_test_mips_malta32el_nanomips(self.ASSET_KERNEL_64K)
+ ASSET_WHEEZY_KERNEL = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'vmlinux-3.2.0-4-4kc-malta'),
+ 'dc8a3648305b0201ca7a5cd135fe2890067a65d93c38728022bb0e656ad2bf9a')
+
+ ASSET_WHEEZY_DISK = Asset(
+ ('https://people.debian.org/~aurel32/qemu/mipsel/'
+ 'debian_wheezy_mipsel_standard.qcow2'),
+ '454f09ae39f7e6461c84727b927100d2c7813841f2a0a5dce328114887ecf914')
+
+ def test_wheezy(self):
+ kernel_path = self.ASSET_WHEEZY_KERNEL.fetch()
+ image_path = self.ASSET_WHEEZY_DISK.fetch()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
+ + 'console=ttyS0 root=/dev/sda1')
+ mips_check_wheezy(self,
+ kernel_path, image_path, kernel_command_line,
+ dl_file='/boot/initrd.img-3.2.0-4-4kc-malta',
+ hsum='9fc9f250ed56a74e35e704ddfd5a1c5a5625adefc5c9da91f649288d3ca000f0')
+
class MaltaMachineYAMON(QemuSystemTest):
diff --git a/tests/functional/test_mipsel_replay.py b/tests/functional/mipsel/test_replay.py
index 0a330de..5f4796c 100644..100755
--- a/tests/functional/test_mipsel_replay.py
+++ b/tests/functional/mipsel/test_replay.py
@@ -4,7 +4,7 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-from qemu_test import Asset, wait_for_console_pattern, skipSlowTest
+from qemu_test import Asset, skipSlowTest
from replay_kernel import ReplayKernelBase
diff --git a/tests/functional/test_mipsel_tuxrun.py b/tests/functional/mipsel/test_tuxrun.py
index d4b39ba..d4b39ba 100755
--- a/tests/functional/test_mipsel_tuxrun.py
+++ b/tests/functional/mipsel/test_tuxrun.py
diff --git a/tests/functional/test_multiprocess.py b/tests/functional/multiprocess.py
index 751cf10..6a06c1e 100755..100644
--- a/tests/functional/test_multiprocess.py
+++ b/tests/functional/multiprocess.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0-or-later
#
# Test for multiprocess qemu
#
@@ -9,33 +9,13 @@
import os
import socket
-from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+from qemu_test import QemuSystemTest, wait_for_console_pattern
from qemu_test import exec_command, exec_command_and_wait_for_pattern
class Multiprocess(QemuSystemTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
- ASSET_KERNEL_X86 = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/31/Everything/x86_64/os/images/pxeboot/vmlinuz'),
- 'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129')
-
- ASSET_INITRD_X86 = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/31/Everything/x86_64/os/images/pxeboot/initrd.img'),
- '3b6cb5c91a14c42e2f61520f1689264d865e772a1f0069e660a800d31dd61fb9')
-
- ASSET_KERNEL_AARCH64 = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/31/Everything/aarch64/os/images/pxeboot/vmlinuz'),
- '3ae07fcafbfc8e4abeb693035a74fe10698faae15e9ccd48882a9167800c1527')
-
- ASSET_INITRD_AARCH64 = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/31/Everything/aarch64/os/images/pxeboot/initrd.img'),
- '9fd230cab10b1dafea41cf00150e6669d37051fad133bd618d2130284e16d526')
-
def do_test(self, kernel_asset, initrd_asset,
kernel_command_line, machine_type):
"""Main test method"""
@@ -83,18 +63,5 @@ class Multiprocess(QemuSystemTest):
'cat /sys/bus/pci/devices/*/uevent',
'PCI_ID=1000:0012')
- def test_multiprocess(self):
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE
- if self.arch == 'x86_64':
- kernel_command_line += 'console=ttyS0 rdinit=/bin/bash'
- self.do_test(self.ASSET_KERNEL_X86, self.ASSET_INITRD_X86,
- kernel_command_line, 'pc')
- elif self.arch == 'aarch64':
- kernel_command_line += 'rdinit=/bin/bash console=ttyAMA0'
- self.do_test(self.ASSET_KERNEL_AARCH64, self.ASSET_INITRD_AARCH64,
- kernel_command_line, 'virt,gic-version=3')
- else:
- assert False
-
-if __name__ == '__main__':
- QemuSystemTest.main()
+ proxy_sock.close()
+ remote_sock.close()
diff --git a/tests/functional/or1k/meson.build b/tests/functional/or1k/meson.build
new file mode 100644
index 0000000..e246e2a
--- /dev/null
+++ b/tests/functional/or1k/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_or1k_system_thorough = [
+ 'replay',
+ 'sim',
+]
diff --git a/tests/functional/test_or1k_replay.py b/tests/functional/or1k/test_replay.py
index 2b60a93..2b60a93 100755
--- a/tests/functional/test_or1k_replay.py
+++ b/tests/functional/or1k/test_replay.py
diff --git a/tests/functional/test_or1k_sim.py b/tests/functional/or1k/test_sim.py
index f9f0b69..f9f0b69 100755
--- a/tests/functional/test_or1k_sim.py
+++ b/tests/functional/or1k/test_sim.py
diff --git a/tests/functional/ppc/meson.build b/tests/functional/ppc/meson.build
new file mode 100644
index 0000000..ae061fe
--- /dev/null
+++ b/tests/functional/ppc/meson.build
@@ -0,0 +1,23 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_ppc_timeouts = {
+ '40p' : 240,
+}
+
+tests_ppc_system_quick = [
+ 'migration',
+ '74xx',
+]
+
+tests_ppc_system_thorough = [
+ '40p',
+ 'amiga',
+ 'bamboo',
+ 'mac',
+ 'mpc8544ds',
+ 'ppe42',
+ 'replay',
+ 'sam460ex',
+ 'tuxrun',
+ 'virtex_ml507',
+]
diff --git a/tests/functional/test_ppc_40p.py b/tests/functional/ppc/test_40p.py
index 614972a..614972a 100755
--- a/tests/functional/test_ppc_40p.py
+++ b/tests/functional/ppc/test_40p.py
diff --git a/tests/functional/test_ppc_74xx.py b/tests/functional/ppc/test_74xx.py
index 5386016..5386016 100755
--- a/tests/functional/test_ppc_74xx.py
+++ b/tests/functional/ppc/test_74xx.py
diff --git a/tests/functional/test_ppc_amiga.py b/tests/functional/ppc/test_amiga.py
index 8600e2e..8600e2e 100755
--- a/tests/functional/test_ppc_amiga.py
+++ b/tests/functional/ppc/test_amiga.py
diff --git a/tests/functional/ppc/test_bamboo.py b/tests/functional/ppc/test_bamboo.py
new file mode 100755
index 0000000..c634ae7
--- /dev/null
+++ b/tests/functional/ppc/test_bamboo.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+#
+# Test that Linux kernel boots on the ppc bamboo board and check the console
+#
+# Copyright (c) 2021 Red Hat
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import QemuSystemTest, Asset
+from qemu_test import wait_for_console_pattern
+from qemu_test import exec_command_and_wait_for_pattern
+
+
+class BambooMachine(QemuSystemTest):
+
+ timeout = 90
+
+ ASSET_KERNEL = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc_bamboo-2023.11-8-gdcd9f0f6eb-20240105/vmlinux'),
+ 'a2e12eb45b73491ac62fc0bbeb68dead0dc5c0f22cf83146558389209b420ad1')
+ ASSET_INITRD = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc_bamboo-2023.11-8-gdcd9f0f6eb-20240105/rootfs.cpio'),
+ 'd2a36bdb8763b389765dc8c29d4904cec2bd001c587f92e85ab9eb10d5ddda54')
+
+ def test_ppc_bamboo(self):
+ self.set_machine('bamboo')
+ self.require_accelerator("tcg")
+ self.require_netdev('user')
+
+ kernel = self.ASSET_KERNEL.fetch()
+ initrd = self.ASSET_INITRD.fetch()
+
+ self.vm.set_console()
+ self.vm.add_args('-kernel', kernel,
+ '-initrd', initrd,
+ '-nic', 'user,model=virtio-net-pci,restrict=on')
+ self.vm.launch()
+ wait_for_console_pattern(self, 'buildroot login:')
+ exec_command_and_wait_for_pattern(self, 'root', '#')
+ exec_command_and_wait_for_pattern(self, 'ping -c1 10.0.2.2',
+ '1 packets transmitted, 1 packets received, 0% packet loss')
+ exec_command_and_wait_for_pattern(self, 'halt', 'System Halted')
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_ppc_mac.py b/tests/functional/ppc/test_mac.py
index 9e4bc1a..9e4bc1a 100755
--- a/tests/functional/test_ppc_mac.py
+++ b/tests/functional/ppc/test_mac.py
diff --git a/tests/functional/ppc/test_migration.py b/tests/functional/ppc/test_migration.py
new file mode 100755
index 0000000..a869282
--- /dev/null
+++ b/tests/functional/ppc/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# ppc migration test
+
+from migration import MigrationTest
+
+
+class PpcMigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('sam460ex')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('sam460ex')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('sam460ex')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_ppc_mpc8544ds.py b/tests/functional/ppc/test_mpc8544ds.py
index 0715410..0715410 100755
--- a/tests/functional/test_ppc_mpc8544ds.py
+++ b/tests/functional/ppc/test_mpc8544ds.py
diff --git a/tests/functional/ppc/test_ppe42.py b/tests/functional/ppc/test_ppe42.py
new file mode 100644
index 0000000..26bbe11
--- /dev/null
+++ b/tests/functional/ppc/test_ppe42.py
@@ -0,0 +1,79 @@
+#!/usr/bin/env python3
+#
+# Functional tests for the IBM PPE42 processor
+#
+# Copyright (c) 2025, IBM Corporation
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from qemu_test import QemuSystemTest, Asset
+import asyncio
+
+class Ppe42Machine(QemuSystemTest):
+
+ timeout = 90
+ poll_period = 1.0
+
+ ASSET_PPE42_TEST_IMAGE = Asset(
+ ('https://github.com/milesg-github/ppe42-tests/raw/refs/heads/main/'
+ 'images/ppe42-test.out'),
+ '03c1ac0fb7f6c025102a02776a93b35101dae7c14b75e4eab36a337e39042ea8')
+
+ def _test_completed(self):
+ self.log.info("Checking for test completion...")
+ try:
+ output = self.vm.cmd('human-monitor-command',
+ command_line='info registers')
+ except Exception as err:
+ self.log.debug(f"'info registers' cmd failed due to {err=},"
+ " {type(err)=}")
+ raise
+
+ self.log.info(output)
+ if "NIP fff80200" in output:
+ self.log.info("<test completed>")
+ return True
+ else:
+ self.log.info("<test not completed>")
+ return False
+
+ def _wait_pass_fail(self, timeout):
+ while not self._test_completed():
+ if timeout >= self.poll_period:
+ timeout = timeout - self.poll_period
+ self.log.info(f"Waiting {self.poll_period} seconds for test"
+ " to complete...")
+ e = None
+ try:
+ e = self.vm.event_wait('STOP', self.poll_period)
+
+ except asyncio.TimeoutError:
+ self.log.info("Poll period ended.")
+ pass
+
+ except Exception as err:
+ self.log.debug(f"event_wait() failed due to {err=},"
+ " {type(err)=}")
+ raise
+
+ if e != None:
+ self.log.debug(f"Execution stopped: {e}")
+ self.log.debug("Exiting due to test failure")
+ self.fail("Failure detected!")
+ break
+ else:
+ self.fail("Timed out waiting for test completion.")
+
+ def test_ppe42_instructions(self):
+ self.set_machine('ppe42_machine')
+ self.require_accelerator("tcg")
+ image_path = self.ASSET_PPE42_TEST_IMAGE.fetch()
+ self.vm.add_args('-nographic')
+ self.vm.add_args('-device', f'loader,file={image_path}')
+ self.vm.add_args('-device', 'loader,addr=0xfff80040,cpu-num=0')
+ self.vm.add_args('-action', 'panic=pause')
+ self.vm.launch()
+ self._wait_pass_fail(self.timeout)
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_ppc_replay.py b/tests/functional/ppc/test_replay.py
index 8382070..8382070 100755
--- a/tests/functional/test_ppc_replay.py
+++ b/tests/functional/ppc/test_replay.py
diff --git a/tests/functional/test_ppc_sam460ex.py b/tests/functional/ppc/test_sam460ex.py
index 31cf9dd..31cf9dd 100644..100755
--- a/tests/functional/test_ppc_sam460ex.py
+++ b/tests/functional/ppc/test_sam460ex.py
diff --git a/tests/functional/test_ppc_tuxrun.py b/tests/functional/ppc/test_tuxrun.py
index 5458a7f..5458a7f 100755
--- a/tests/functional/test_ppc_tuxrun.py
+++ b/tests/functional/ppc/test_tuxrun.py
diff --git a/tests/functional/test_ppc_virtex_ml507.py b/tests/functional/ppc/test_virtex_ml507.py
index 8fe4354..8fe4354 100755
--- a/tests/functional/test_ppc_virtex_ml507.py
+++ b/tests/functional/ppc/test_virtex_ml507.py
diff --git a/tests/functional/ppc64/meson.build b/tests/functional/ppc64/meson.build
new file mode 100644
index 0000000..1fa0a70
--- /dev/null
+++ b/tests/functional/ppc64/meson.build
@@ -0,0 +1,26 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_ppc64_timeouts = {
+ 'hv' : 1000,
+ 'mac99' : 120,
+ 'powernv' : 480,
+ 'pseries' : 480,
+ 'replay' : 210,
+ 'tuxrun' : 420,
+}
+
+tests_ppc64_system_quick = [
+ 'migration',
+ 'vmstate',
+]
+
+tests_ppc64_system_thorough = [
+ 'e500',
+ 'hv',
+ 'mac99',
+ 'powernv',
+ 'pseries',
+ 'replay',
+ 'reverse_debug',
+ 'tuxrun',
+]
diff --git a/tests/functional/test_ppc64_e500.py b/tests/functional/ppc64/test_e500.py
index f5fcad9..f5fcad9 100755
--- a/tests/functional/test_ppc64_e500.py
+++ b/tests/functional/ppc64/test_e500.py
diff --git a/tests/functional/test_ppc64_hv.py b/tests/functional/ppc64/test_hv.py
index 1920e91..d87f440 100755
--- a/tests/functional/test_ppc64_hv.py
+++ b/tests/functional/ppc64/test_hv.py
@@ -9,14 +9,14 @@
# This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory.
+import os
+import subprocess
+
+from datetime import datetime
from qemu_test import QemuSystemTest, Asset
from qemu_test import wait_for_console_pattern, exec_command
from qemu_test import skipIfMissingCommands, skipBigDataTest
from qemu_test import exec_command_and_wait_for_pattern
-import os
-import time
-import subprocess
-from datetime import datetime
# Alpine is a light weight distro that supports QEMU. These tests boot
# that on the machine then run a QEMU guest inside it in KVM mode,
diff --git a/tests/functional/test_ppc64_mac99.py b/tests/functional/ppc64/test_mac99.py
index dfd9c01..dfd9c01 100755
--- a/tests/functional/test_ppc64_mac99.py
+++ b/tests/functional/ppc64/test_mac99.py
diff --git a/tests/functional/ppc64/test_migration.py b/tests/functional/ppc64/test_migration.py
new file mode 100755
index 0000000..5dfdaaf
--- /dev/null
+++ b/tests/functional/ppc64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# ppc migration test
+
+from migration import MigrationTest
+
+
+class PpcMigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('mac99')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('mac99')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('mac99')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_ppc64_powernv.py b/tests/functional/ppc64/test_powernv.py
index 685e217..9ada832 100755
--- a/tests/functional/test_ppc64_powernv.py
+++ b/tests/functional/ppc64/test_powernv.py
@@ -18,9 +18,14 @@ class powernvMachine(LinuxKernelTest):
good_message = 'VFS: Cannot open root device'
ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora-secondary/'
- 'releases/29/Everything/ppc64le/os/ppc/ppc64/vmlinuz'),
- '383c2f5c23bc0d9d32680c3924d3fd7ee25cc5ef97091ac1aa5e1d853422fc5f')
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc64le_powernv8-2025.02/vmlinux'),
+ '6fd29aff9ad4362511ea5d0acbb510667c7031928e97d64ec15bbc5daf4b8151')
+
+ ASSET_INITRD = Asset(
+ ('https://github.com/legoater/qemu-ppc-boot/raw/refs/heads/main/'
+ 'buildroot/qemu_ppc64le_powernv8-2025.02/rootfs.ext2'),
+ 'aee2192b692077c4bde31cb56ce474424b358f17cec323d5c94af3970c9aada2')
def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE):
self.require_accelerator("tcg")
@@ -78,27 +83,24 @@ class powernvMachine(LinuxKernelTest):
wait_for_console_pattern(self, console_pattern, self.panic_message)
wait_for_console_pattern(self, self.good_message, self.panic_message)
-
- ASSET_EPAPR_KERNEL = Asset(
- ('https://github.com/open-power/op-build/releases/download/v2.7/'
- 'zImage.epapr'),
- '0ab237df661727e5392cee97460e8674057a883c5f74381a128fa772588d45cd')
-
def do_test_ppc64_powernv(self, proc):
self.require_accelerator("tcg")
- kernel_path = self.ASSET_EPAPR_KERNEL.fetch()
+ kernel_path = self.ASSET_KERNEL.fetch()
+ initrd_path = self.ASSET_INITRD.fetch()
self.vm.set_console()
self.vm.add_args('-kernel', kernel_path,
- '-append', 'console=tty0 console=hvc0',
+ '-drive',
+ f'file={initrd_path},format=raw,if=none,id=drive0,readonly=on',
+ '-append', 'root=/dev/nvme0n1 console=tty0 console=hvc0',
'-device', 'pcie-pci-bridge,id=bridge1,bus=pcie.1,addr=0x0',
- '-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234',
+ '-device', 'nvme,drive=drive0,bus=pcie.2,addr=0x0,serial=1234',
'-device', 'e1000e,bus=bridge1,addr=0x3',
'-device', 'nec-usb-xhci,bus=bridge1,addr=0x2')
self.vm.launch()
self.wait_for_console_pattern("CPU: " + proc + " generation processor")
- self.wait_for_console_pattern("zImage starting: loaded")
- self.wait_for_console_pattern("Run /init as init process")
+ self.wait_for_console_pattern("INIT: Starting kernel at ")
+ self.wait_for_console_pattern("Run /sbin/init as init process")
# Device detection output driven by udev probing is sometimes cut off
# from console output, suspect S14silence-console init script.
@@ -114,5 +116,9 @@ class powernvMachine(LinuxKernelTest):
self.set_machine('powernv10')
self.do_test_ppc64_powernv('P10')
+ def test_powernv11(self):
+ self.set_machine('powernv11')
+ self.do_test_ppc64_powernv('Power11')
+
if __name__ == '__main__':
LinuxKernelTest.main()
diff --git a/tests/functional/test_ppc64_pseries.py b/tests/functional/ppc64/test_pseries.py
index fdc404e..6705793 100755
--- a/tests/functional/test_ppc64_pseries.py
+++ b/tests/functional/ppc64/test_pseries.py
@@ -63,6 +63,7 @@ class pseriesMachine(QemuSystemTest):
wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_ppc64_linux_smt_boot(self):
+ self.set_machine('pseries')
self.vm.add_args('-smp', '4,threads=4')
self.do_test_ppc64_linux_boot()
console_pattern = 'CPU maps initialized for 4 threads per core'
diff --git a/tests/functional/test_ppc64_replay.py b/tests/functional/ppc64/test_replay.py
index e8c9c4b..e8c9c4b 100755
--- a/tests/functional/test_ppc64_replay.py
+++ b/tests/functional/ppc64/test_replay.py
diff --git a/tests/functional/ppc64/test_reverse_debug.py b/tests/functional/ppc64/test_reverse_debug.py
new file mode 100755
index 0000000..69551fb
--- /dev/null
+++ b/tests/functional/ppc64/test_reverse_debug.py
@@ -0,0 +1,38 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test for ppc64
+#
+# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import skipFlakyTest
+from reverse_debugging import ReverseDebugging
+
+
+class ReverseDebugging_ppc64(ReverseDebugging):
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/1992")
+ def test_ppc64_pseries(self):
+ self.set_machine('pseries')
+ # SLOF branches back to its entry point, which causes this test
+ # to take the 'hit a breakpoint again' path. That's not a problem,
+ # just slightly different than the other machines.
+ self.reverse_debugging(gdb_arch='powerpc:common64')
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/1992")
+ def test_ppc64_powernv(self):
+ self.set_machine('powernv')
+ self.reverse_debugging(gdb_arch='powerpc:common64')
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff --git a/tests/functional/test_ppc64_tuxrun.py b/tests/functional/ppc64/test_tuxrun.py
index e8f79c6..e8f79c6 100755
--- a/tests/functional/test_ppc64_tuxrun.py
+++ b/tests/functional/ppc64/test_tuxrun.py
diff --git a/tests/functional/qemu_test/__init__.py b/tests/functional/qemu_test/__init__.py
index 45f7bef..3201935 100644
--- a/tests/functional/qemu_test/__init__.py
+++ b/tests/functional/qemu_test/__init__.py
@@ -15,6 +15,8 @@ from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest
from .linuxkernel import LinuxKernelTest
from .decorators import skipIfMissingCommands, skipIfNotMachine, \
skipFlakyTest, skipUntrustedTest, skipBigDataTest, skipSlowTest, \
- skipIfMissingImports
+ skipIfMissingImports, skipIfOperatingSystem, skipLockedMemoryTest, \
+ skipIfMissingEnv
from .archive import archive_extract
from .uncompress import uncompress
+from .gdb import GDB
diff --git a/tests/functional/qemu_test/asset.py b/tests/functional/qemu_test/asset.py
index 704b84d..f666125 100644
--- a/tests/functional/qemu_test/asset.py
+++ b/tests/functional/qemu_test/asset.py
@@ -15,7 +15,7 @@ import urllib.request
from time import sleep
from pathlib import Path
from shutil import copyfileobj
-from urllib.error import HTTPError
+from urllib.error import HTTPError, URLError
class AssetError(Exception):
def __init__(self, asset, msg, transient=False):
@@ -72,6 +72,10 @@ class Asset:
return self.hash == hl.hexdigest()
def valid(self):
+ if os.getenv("QEMU_TEST_REFRESH_CACHE", None) is not None:
+ self.log.info("Force refresh of asset %s", self.url)
+ return False
+
return self.cache_file.exists() and self._check(self.cache_file)
def fetchable(self):
@@ -167,9 +171,25 @@ class Asset:
raise AssetError(self, "Unable to download: "
"HTTP error %d" % e.code)
continue
+ except URLError as e:
+ # This is typically a network/service level error
+ # eg urlopen error [Errno 110] Connection timed out>
+ tmp_cache_file.unlink()
+ self.log.error("Unable to download %s: URL error %s",
+ self.url, e.reason)
+ raise AssetError(self, "Unable to download: URL error %s" %
+ e.reason, transient=True)
+ except ConnectionError as e:
+ # A socket connection failure, such as dropped conn
+ # or refused conn
+ tmp_cache_file.unlink()
+ self.log.error("Unable to download %s: Connection error %s",
+ self.url, e)
+ continue
except Exception as e:
tmp_cache_file.unlink()
- raise AssetError(self, "Unable to download: " % e)
+ raise AssetError(self, "Unable to download: %s" % e,
+ transient=True)
if not os.path.exists(tmp_cache_file):
raise AssetError(self, "Download retries exceeded", transient=True)
@@ -205,7 +225,6 @@ class Asset:
log.addHandler(handler)
for name, asset in vars(test.__class__).items():
if name.startswith("ASSET_") and type(asset) == Asset:
- log.info("Attempting to cache '%s'" % asset)
try:
asset.fetch()
except AssetError as e:
diff --git a/tests/functional/qemu_test/cmd.py b/tests/functional/qemu_test/cmd.py
index dc5f422..f544566 100644
--- a/tests/functional/qemu_test/cmd.py
+++ b/tests/functional/qemu_test/cmd.py
@@ -45,13 +45,16 @@ def is_readable_executable_file(path):
# If end of line is seen, with neither @success or @failure
# return False
#
+# In both cases, also return the contents of the line (in bytes)
+# up to that point.
+#
# If @failure is seen, then mark @test as failed
def _console_read_line_until_match(test, vm, success, failure):
msg = bytes([])
done = False
while True:
c = vm.console_socket.recv(1)
- if c is None:
+ if not c:
done = True
test.fail(
f"EOF in console, expected '{success}'")
@@ -76,10 +79,23 @@ def _console_read_line_until_match(test, vm, success, failure):
except:
console_logger.debug(msg)
- return done
+ return done, msg
def _console_interaction(test, success_message, failure_message,
send_string, keep_sending=False, vm=None):
+ """
+ Interact with the console until either message is seen.
+
+ :param success_message: if this message appears, finish interaction
+ :param failure_message: if this message appears, test fails
+ :param send_string: a string to send to the console before trying
+ to read a new line
+ :param keep_sending: keep sending the send string each time
+ :param vm: the VM to interact with
+
+ :return: The collected output (in bytes form).
+ """
+
assert not keep_sending or send_string
assert success_message or send_string
@@ -101,6 +117,8 @@ def _console_interaction(test, success_message, failure_message,
if failure_message is not None:
failure_message_b = failure_message.encode()
+ out = bytes([])
+
while True:
if send_string:
vm.console_socket.sendall(send_string.encode())
@@ -113,14 +131,21 @@ def _console_interaction(test, success_message, failure_message,
break
continue
- if _console_read_line_until_match(test, vm,
- success_message_b,
- failure_message_b):
+ done, line = _console_read_line_until_match(test, vm,
+ success_message_b,
+ failure_message_b)
+
+ out += line
+
+ if done:
break
+ return out
+
def interrupt_interactive_console_until_pattern(test, success_message,
failure_message=None,
- interrupt_string='\r'):
+ interrupt_string='\r',
+ vm=None):
"""
Keep sending a string to interrupt a console prompt, while logging the
console output. Typical use case is to break a boot loader prompt, such:
@@ -140,10 +165,13 @@ def interrupt_interactive_console_until_pattern(test, success_message,
:param failure_message: if this message appears, test fails
:param interrupt_string: a string to send to the console before trying
to read a new line
+ :param vm: VM to use
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message,
- interrupt_string, True)
+ return _console_interaction(test, success_message, failure_message,
+ interrupt_string, True, vm=vm)
def wait_for_console_pattern(test, success_message, failure_message=None,
vm=None):
@@ -155,11 +183,15 @@ def wait_for_console_pattern(test, success_message, failure_message=None,
:type test: :class:`qemu_test.QemuSystemTest`
:param success_message: if this message appears, test succeeds
:param failure_message: if this message appears, test fails
+ :param vm: VM to use
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message, None, vm=vm)
+ return _console_interaction(test, success_message, failure_message,
+ None, vm=vm)
-def exec_command(test, command):
+def exec_command(test, command, vm=None):
"""
Send a command to a console (appending CRLF characters), while logging
the content.
@@ -167,12 +199,16 @@ def exec_command(test, command):
:param test: a test containing a VM.
:type test: :class:`qemu_test.QemuSystemTest`
:param command: the command to send
+ :param vm: VM to use
:type command: str
+
+ :return: The collected output (in bytes form).
"""
- _console_interaction(test, None, None, command + '\r')
+ return _console_interaction(test, None, None, command + '\r', vm=vm)
def exec_command_and_wait_for_pattern(test, command,
- success_message, failure_message=None):
+ success_message, failure_message=None,
+ vm=None):
"""
Send a command to a console (appending CRLF characters), then wait
for success_message to appear on the console, while logging the.
@@ -184,9 +220,14 @@ def exec_command_and_wait_for_pattern(test, command,
:param command: the command to send
:param success_message: if this message appears, test succeeds
:param failure_message: if this message appears, test fails
+ :param vm: VM to use
+
+ :return: The collected output (in bytes form).
"""
assert success_message
- _console_interaction(test, success_message, failure_message, command + '\r')
+
+ return _console_interaction(test, success_message, failure_message,
+ command + '\r', vm=vm)
def get_qemu_img(test):
test.log.debug('Looking for and selecting a qemu-img binary')
diff --git a/tests/functional/qemu_test/decorators.py b/tests/functional/qemu_test/decorators.py
index 1651eb7..b239295 100644
--- a/tests/functional/qemu_test/decorators.py
+++ b/tests/functional/qemu_test/decorators.py
@@ -5,11 +5,30 @@
import importlib
import os
import platform
-from unittest import skipUnless
+import resource
+from unittest import skipIf, skipUnless
from .cmd import which
'''
+Decorator to skip execution of a test if the provided
+environment variables are not set.
+Example:
+
+ @skipIfMissingEnv("QEMU_ENV_VAR0", "QEMU_ENV_VAR1")
+'''
+def skipIfMissingEnv(*vars_):
+ missing_vars = []
+ for var in vars_:
+ if os.getenv(var) == None:
+ missing_vars.append(var)
+
+ has_vars = True if len(missing_vars) == 0 else False
+
+ return skipUnless(has_vars, f"Missing env var(s): {', '.join(missing_vars)}")
+
+'''
+
Decorator to skip execution of a test if the list
of command binaries is not available in $PATH.
Example:
@@ -28,6 +47,19 @@ def skipIfMissingCommands(*args):
'''
Decorator to skip execution of a test if the current
+host operating system does match one of the prohibited
+ones.
+Example
+
+ @skipIfOperatingSystem("Linux", "Darwin")
+'''
+def skipIfOperatingSystem(*args):
+ return skipIf(platform.system() in args,
+ 'running on an OS (%s) that is not able to run this test' %
+ ", ".join(args))
+
+'''
+Decorator to skip execution of a test if the current
host machine does not match one of the permitted
machines.
Example
@@ -118,3 +150,20 @@ def skipIfMissingImports(*args):
return skipUnless(has_imports, 'required import(s) "%s" not installed' %
", ".join(args))
+
+'''
+Decorator to skip execution of a test if the system's
+locked memory limit is below the required threshold.
+Takes required locked memory threshold in kB.
+Example:
+
+ @skipLockedMemoryTest(2_097_152)
+'''
+def skipLockedMemoryTest(locked_memory):
+ # get memlock hard limit in bytes
+ _, ulimit_memory = resource.getrlimit(resource.RLIMIT_MEMLOCK)
+
+ return skipUnless(
+ ulimit_memory == resource.RLIM_INFINITY or ulimit_memory >= locked_memory * 1024,
+ f'Test required {locked_memory} kB of available locked memory',
+ )
diff --git a/tests/functional/qemu_test/gdb.py b/tests/functional/qemu_test/gdb.py
new file mode 100644
index 0000000..558d476
--- /dev/null
+++ b/tests/functional/qemu_test/gdb.py
@@ -0,0 +1,86 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# A simple interface module built around pygdbmi for handling GDB commands.
+#
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Gustavo Romero <gustavo.romero@linaro.org>
+#
+
+import re
+
+
+class GDB:
+ """Provides methods to run and capture GDB command output."""
+
+
+ def __init__(self, gdb_path, echo=True, suffix='# ', prompt="$ "):
+ from pygdbmi.gdbcontroller import GdbController
+ from pygdbmi.constants import GdbTimeoutError
+ type(self).TimeoutError = GdbTimeoutError
+
+ gdb_cmd = [gdb_path, "-q", "--interpreter=mi2"]
+ self.gdbmi = GdbController(gdb_cmd)
+ self.echo = echo
+ self.suffix = suffix
+ self.prompt = prompt
+ self.response = None
+ self.cmd_output = None
+
+
+ def get_payload(self, response, kind):
+ output = []
+ for o in response:
+ # Unpack payloads of the same type.
+ _type, _, payload, *_ = o.values()
+ if _type == kind:
+ output += [payload]
+
+ # Some output lines do not end with \n but begin with it,
+ # so remove the leading \n and merge them with the next line
+ # that ends with \n.
+ lines = [line.lstrip('\n') for line in output]
+ lines = "".join(lines)
+ lines = lines.splitlines(keepends=True)
+
+ return lines
+
+
+ def cli(self, cmd, timeout=32.0):
+ self.response = self.gdbmi.write(cmd, timeout_sec=timeout)
+ self.cmd_output = self.get_payload(self.response, kind="console")
+ if self.echo:
+ print(self.suffix + self.prompt + cmd)
+
+ if len(self.cmd_output) > 0:
+ cmd_output = self.suffix.join(self.cmd_output)
+ print(self.suffix + cmd_output, end="")
+
+ return self
+
+
+ def get_addr(self):
+ address_pattern = r"0x[0-9A-Fa-f]+"
+ cmd_output = "".join(self.cmd_output) # Concat output lines.
+
+ match = re.search(address_pattern, cmd_output)
+
+ return int(match[0], 16) if match else None
+
+
+ def get_log(self):
+ r = self.get_payload(self.response, kind="log")
+ r = "".join(r)
+
+ return r
+
+
+ def get_console(self):
+ r = "".join(self.cmd_output)
+
+ return r
+
+
+ def exit(self):
+ self.gdbmi.exit()
diff --git a/tests/functional/qemu_test/ports.py b/tests/functional/qemu_test/ports.py
index cc39939..81174a6 100644
--- a/tests/functional/qemu_test/ports.py
+++ b/tests/functional/qemu_test/ports.py
@@ -10,12 +10,11 @@
import fcntl
import os
import socket
-import sys
-import tempfile
from .config import BUILD_DIR
from typing import List
+
class Ports():
PORTS_ADDR = '127.0.0.1'
@@ -24,8 +23,9 @@ class Ports():
PORTS_END = PORTS_START + PORTS_RANGE_SIZE
def __enter__(self):
- lock_file = os.path.join(BUILD_DIR, "tests", "functional", "port_lock")
- self.lock_fh = os.open(lock_file, os.O_CREAT)
+ lock_file = os.path.join(BUILD_DIR, "tests", "functional",
+ f".port_lock.{self.PORTS_START}")
+ self.lock_fh = os.open(lock_file, os.O_CREAT, mode=0o666)
fcntl.flock(self.lock_fh, fcntl.LOCK_EX)
return self
diff --git a/tests/functional/qemu_test/testcase.py b/tests/functional/qemu_test/testcase.py
index 50c401b..2c0abde 100644
--- a/tests/functional/qemu_test/testcase.py
+++ b/tests/functional/qemu_test/testcase.py
@@ -19,11 +19,12 @@ import shutil
from subprocess import run
import sys
import tempfile
+import warnings
import unittest
import uuid
from qemu.machine import QEMUMachine
-from qemu.utils import kvm_available, tcg_available
+from qemu.utils import hvf_available, kvm_available, tcg_available
from .archive import archive_extract
from .asset import Asset
@@ -204,6 +205,10 @@ class QemuBaseTest(unittest.TestCase):
self.outputdir = self.build_file('tests', 'functional',
self.arch, self.id())
self.workdir = os.path.join(self.outputdir, 'scratch')
+ if os.path.exists(self.workdir):
+ # Purge as safety net in case of unclean termination of
+ # previous test, or use of QEMU_TEST_KEEP_SCRATCH
+ shutil.rmtree(self.workdir)
os.makedirs(self.workdir, exist_ok=True)
self.log_filename = self.log_file('base.log')
@@ -232,8 +237,13 @@ class QemuBaseTest(unittest.TestCase):
self.socketdir = None
self.machinelog.removeHandler(self._log_fh)
self.log.removeHandler(self._log_fh)
+ self._log_fh.close()
+ @staticmethod
def main():
+ warnings.simplefilter("default")
+ os.environ["PYTHONWARNINGS"] = "default"
+
path = os.path.basename(sys.argv[0])[:-3]
cache = os.environ.get("QEMU_TEST_PRECACHE", None)
@@ -244,14 +254,15 @@ class QemuBaseTest(unittest.TestCase):
tr = pycotap.TAPTestRunner(message_log = pycotap.LogMode.LogToError,
test_output_log = pycotap.LogMode.LogToError)
res = unittest.main(module = None, testRunner = tr, exit = False,
- argv=["__dummy__", path])
+ argv=[sys.argv[0], path] + sys.argv[1:])
+ failed = {}
for (test, message) in res.result.errors + res.result.failures:
-
- if hasattr(test, "log_filename"):
+ if hasattr(test, "log_filename") and not test.id() in failed:
print('More information on ' + test.id() + ' could be found here:'
'\n %s' % test.log_filename, file=sys.stderr)
if hasattr(test, 'console_log_name'):
print(' %s' % test.console_log_name, file=sys.stderr)
+ failed[test.id()] = True
sys.exit(not res.result.wasSuccessful())
@@ -317,7 +328,9 @@ class QemuSystemTest(QemuBaseTest):
:type accelerator: str
"""
checker = {'tcg': tcg_available,
- 'kvm': kvm_available}.get(accelerator)
+ 'kvm': kvm_available,
+ 'hvf': hvf_available,
+ }.get(accelerator)
if checker is None:
self.skipTest("Don't know how to check for the presence "
"of accelerator %s" % accelerator)
@@ -395,6 +408,10 @@ class QemuSystemTest(QemuBaseTest):
def tearDown(self):
for vm in self._vms.values():
- vm.shutdown()
+ try:
+ vm.shutdown()
+ except Exception as ex:
+ self.log.error("Failed to teardown VM: %s" % ex)
logging.getLogger('console').removeHandler(self._console_log_fh)
+ self._console_log_fh.close()
super().tearDown()
diff --git a/tests/functional/qemu_test/tuxruntest.py b/tests/functional/qemu_test/tuxruntest.py
index ad74156..6c442ff 100644
--- a/tests/functional/qemu_test/tuxruntest.py
+++ b/tests/functional/qemu_test/tuxruntest.py
@@ -10,8 +10,6 @@
# SPDX-License-Identifier: GPL-2.0-or-later
import os
-import stat
-from subprocess import check_call, DEVNULL
from qemu_test import QemuSystemTest
from qemu_test import exec_command_and_wait_for_pattern
@@ -77,12 +75,12 @@ class TuxRunBaselineTest(QemuSystemTest):
blockdev = "driver=raw,file.driver=file," \
+ f"file.filename={disk},node-name=hd0"
- kcmd_line = self.KERNEL_COMMON_COMMAND_LINE
- kcmd_line += f" root=/dev/{self.root}"
- kcmd_line += f" console={self.console}"
+ self.kcmd_line = self.KERNEL_COMMON_COMMAND_LINE
+ self.kcmd_line += f" root=/dev/{self.root}"
+ self.kcmd_line += f" console={self.console}"
self.vm.add_args('-kernel', kernel,
- '-append', kcmd_line,
+ '-append', self.kcmd_line,
'-blockdev', blockdev)
# Sometimes we need extra devices attached
@@ -103,6 +101,7 @@ class TuxRunBaselineTest(QemuSystemTest):
wait to exit cleanly.
"""
ps1='root@tuxtest:~#'
+ self.wait_for_console_pattern(self.kcmd_line)
self.wait_for_console_pattern('tuxtest login:')
exec_command_and_wait_for_pattern(self, 'root', ps1)
exec_command_and_wait_for_pattern(self, 'cat /proc/interrupts', ps1)
diff --git a/tests/functional/qemu_test/uncompress.py b/tests/functional/qemu_test/uncompress.py
index ce79da1..b7ef8f7 100644
--- a/tests/functional/qemu_test/uncompress.py
+++ b/tests/functional/qemu_test/uncompress.py
@@ -13,7 +13,7 @@ import os
import stat
import shutil
from urllib.parse import urlparse
-from subprocess import run, CalledProcessError, DEVNULL
+from subprocess import run, CalledProcessError
from .asset import Asset
diff --git a/tests/functional/replay_kernel.py b/tests/functional/replay_kernel.py
index 80795eb..acb1d29 100644
--- a/tests/functional/replay_kernel.py
+++ b/tests/functional/replay_kernel.py
@@ -32,15 +32,14 @@ class ReplayKernelBase(LinuxKernelTest):
# icount requires TCG to be available
self.require_accelerator('tcg')
- logger = logging.getLogger('replay')
start_time = time.time()
vm = self.get_vm(name='recording' if record else 'replay')
vm.set_console()
if record:
- logger.info('recording the execution...')
+ self.log.info('recording the execution...')
mode = 'record'
else:
- logger.info('replaying the execution...')
+ self.log.info('replaying the execution...')
mode = 'replay'
vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s' %
(shift, mode, replay_path),
@@ -54,15 +53,15 @@ class ReplayKernelBase(LinuxKernelTest):
self.wait_for_console_pattern(console_pattern, vm)
if record:
vm.shutdown()
- logger.info('finished the recording with log size %s bytes'
+ self.log.info('finished the recording with log size %s bytes'
% os.path.getsize(replay_path))
self.run_replay_dump(replay_path)
- logger.info('successfully tested replay-dump.py')
+ self.log.info('successfully tested replay-dump.py')
else:
vm.wait()
- logger.info('successfully finished the replay')
+ self.log.info('successfully finished the replay')
elapsed = time.time() - start_time
- logger.info('elapsed time %.2f sec' % elapsed)
+ self.log.info('elapsed time %.2f sec' % elapsed)
return elapsed
def run_replay_dump(self, replay_path):
@@ -80,5 +79,4 @@ class ReplayKernelBase(LinuxKernelTest):
True, shift, args, replay_path)
t2 = self.run_vm(kernel_path, kernel_command_line, console_pattern,
False, shift, args, replay_path)
- logger = logging.getLogger('replay')
- logger.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
+ self.log.info('replay overhead {:.2%}'.format(t2 / t1 - 1))
diff --git a/tests/functional/reverse_debugging.py b/tests/functional/reverse_debugging.py
new file mode 100644
index 0000000..68cfcb3
--- /dev/null
+++ b/tests/functional/reverse_debugging.py
@@ -0,0 +1,202 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test
+#
+# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+import logging
+import os
+from subprocess import check_output
+
+from qemu_test import LinuxKernelTest, get_qemu_img, GDB, \
+ skipIfMissingEnv, skipIfMissingImports
+from qemu_test.ports import Ports
+
+
+class ReverseDebugging(LinuxKernelTest):
+ """
+ Test GDB reverse debugging commands: reverse step and reverse continue.
+ Recording saves the execution of some instructions and makes an initial
+ VM snapshot to allow reverse execution.
+ Replay saves the order of the first instructions and then checks that they
+ are executed backwards in the correct order.
+ After that the execution is replayed to the end, and reverse continue
+ command is checked by setting several breakpoints, and asserting
+ that the execution is stopped at the last of them.
+ """
+
+ STEPS = 10
+
+ def run_vm(self, record, shift, args, replay_path, image_path, port):
+ logger = logging.getLogger('replay')
+ vm = self.get_vm(name='record' if record else 'replay')
+ vm.set_console()
+ if record:
+ logger.info('recording the execution...')
+ mode = 'record'
+ else:
+ logger.info('replaying the execution...')
+ mode = 'replay'
+ vm.add_args('-gdb', 'tcp::%d' % port, '-S')
+ vm.add_args('-icount', 'shift=%s,rr=%s,rrfile=%s,rrsnapshot=init' %
+ (shift, mode, replay_path),
+ '-net', 'none')
+ vm.add_args('-drive', 'file=%s,if=none' % image_path)
+ if args:
+ vm.add_args(*args)
+ vm.launch()
+ return vm
+
+ @staticmethod
+ def get_pc(gdb: GDB):
+ return gdb.cli("print $pc").get_addr()
+
+ @staticmethod
+ def vm_get_icount(vm):
+ return vm.qmp('query-replay')['return']['icount']
+
+ @skipIfMissingImports("pygdbmi") # Required by GDB class
+ @skipIfMissingEnv("QEMU_TEST_GDB")
+ def reverse_debugging(self, gdb_arch, shift=7, args=None):
+ from qemu_test import GDB
+
+ logger = logging.getLogger('replay')
+
+ # create qcow2 for snapshots
+ logger.info('creating qcow2 image for VM snapshots')
+ image_path = os.path.join(self.workdir, 'disk.qcow2')
+ qemu_img = get_qemu_img(self)
+ if qemu_img is None:
+ self.skipTest('Could not find "qemu-img", which is required to '
+ 'create the temporary qcow2 image')
+ out = check_output([qemu_img, 'create', '-f', 'qcow2', image_path, '128M'],
+ encoding='utf8')
+ logger.info("qemu-img: %s" % out)
+
+ replay_path = os.path.join(self.workdir, 'replay.bin')
+
+ # record the log
+ vm = self.run_vm(True, shift, args, replay_path, image_path, -1)
+ while self.vm_get_icount(vm) <= self.STEPS:
+ pass
+ last_icount = self.vm_get_icount(vm)
+ vm.shutdown()
+
+ logger.info("recorded log with %s+ steps" % last_icount)
+
+ # replay and run debug commands
+ with Ports() as ports:
+ port = ports.find_free_port()
+ vm = self.run_vm(False, shift, args, replay_path, image_path, port)
+
+ try:
+ logger.info('Connecting to gdbstub...')
+ self.reverse_debugging_run(vm, port, gdb_arch, last_icount)
+ logger.info('Test passed.')
+ except GDB.TimeoutError:
+ # Convert a GDB timeout exception into a unittest failure exception.
+ raise self.failureException("Timeout while connecting to or "
+ "communicating with gdbstub...") from None
+ except Exception:
+ # Re-throw exceptions from unittest, like the ones caused by fail(),
+ # skipTest(), etc.
+ raise
+
+ def reverse_debugging_run(self, vm, port, gdb_arch, last_icount):
+ logger = logging.getLogger('replay')
+
+ gdb_cmd = os.getenv('QEMU_TEST_GDB')
+ gdb = GDB(gdb_cmd)
+
+ r = gdb.cli("set architecture").get_log()
+ if gdb_arch not in r:
+ self.skipTest(f"GDB does not support arch '{gdb_arch}'")
+
+ gdb.cli("set debug remote 1")
+
+ c = gdb.cli(f"target remote localhost:{port}").get_console()
+ if not f"Remote debugging using localhost:{port}" in c:
+ self.fail("Could not connect to gdbstub!")
+
+ # Remote debug messages are in 'log' payloads.
+ r = gdb.get_log()
+ if 'ReverseStep+' not in r:
+ self.fail('Reverse step is not supported by QEMU')
+ if 'ReverseContinue+' not in r:
+ self.fail('Reverse continue is not supported by QEMU')
+
+ gdb.cli("set debug remote 0")
+
+ logger.info('stepping forward')
+ steps = []
+ # record first instruction addresses
+ for _ in range(self.STEPS):
+ pc = self.get_pc(gdb)
+ logger.info('saving position %x' % pc)
+ steps.append(pc)
+ gdb.cli("stepi")
+
+ # visit the recorded instruction in reverse order
+ logger.info('stepping backward')
+ for addr in steps[::-1]:
+ logger.info('found position %x' % addr)
+ gdb.cli("reverse-stepi")
+ pc = self.get_pc(gdb)
+ if pc != addr:
+ logger.info('Invalid PC (read %x instead of %x)' % (pc, addr))
+ self.fail('Reverse stepping failed!')
+
+ # visit the recorded instruction in forward order
+ logger.info('stepping forward')
+ for addr in steps:
+ logger.info('found position %x' % addr)
+ pc = self.get_pc(gdb)
+ if pc != addr:
+ logger.info('Invalid PC (read %x instead of %x)' % (pc, addr))
+ self.fail('Forward stepping failed!')
+ gdb.cli("stepi")
+
+ # set breakpoints for the instructions just stepped over
+ logger.info('setting breakpoints')
+ for addr in steps:
+ gdb.cli(f"break *{hex(addr)}")
+
+ # this may hit a breakpoint if first instructions are executed
+ # again
+ logger.info('continuing execution')
+ vm.qmp('replay-break', icount=last_icount - 1)
+ # continue - will return after pausing
+ # This can stop at the end of the replay-break and gdb gets a SIGINT,
+ # or by re-executing one of the breakpoints and gdb stops at a
+ # breakpoint.
+ gdb.cli("continue")
+
+ if self.vm_get_icount(vm) == last_icount - 1:
+ logger.info('reached the end (icount %s)' % (last_icount - 1))
+ else:
+ logger.info('hit a breakpoint again at %x (icount %s)' %
+ (self.get_pc(gdb), self.vm_get_icount(vm)))
+
+ logger.info('running reverse continue to reach %x' % steps[-1])
+ # reverse continue - will return after stopping at the breakpoint
+ gdb.cli("reverse-continue")
+
+ # assume that none of the first instructions is executed again
+ # breaking the order of the breakpoints
+ pc = self.get_pc(gdb)
+ if pc != steps[-1]:
+ self.fail("'reverse-continue' did not hit the first PC in reverse order!")
+
+ logger.info('successfully reached %x' % steps[-1])
+
+ logger.info('exiting gdb and qemu')
+ gdb.exit()
+ vm.shutdown()
diff --git a/tests/functional/riscv32/meson.build b/tests/functional/riscv32/meson.build
new file mode 100644
index 0000000..f3ebbb8
--- /dev/null
+++ b/tests/functional/riscv32/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_riscv32_system_quick = [
+ 'migration',
+ 'opensbi',
+]
+
+tests_riscv32_system_thorough = [
+ 'tuxrun',
+]
diff --git a/tests/functional/riscv32/test_migration.py b/tests/functional/riscv32/test_migration.py
new file mode 100755
index 0000000..30acbbe
--- /dev/null
+++ b/tests/functional/riscv32/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# riscv32 migration test
+
+from migration import MigrationTest
+
+
+class Rv32MigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('spike')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('virt')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('spike')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/riscv32/test_opensbi.py b/tests/functional/riscv32/test_opensbi.py
new file mode 100755
index 0000000..d1ac706
--- /dev/null
+++ b/tests/functional/riscv32/test_opensbi.py
@@ -0,0 +1,10 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reuse the 64-bit OpenSBI test for RISC-V 32-bit machines
+
+from riscv64.test_opensbi import RiscvOpenSBI
+
+if __name__ == '__main__':
+ RiscvOpenSBI.main()
diff --git a/tests/functional/test_riscv32_tuxrun.py b/tests/functional/riscv32/test_tuxrun.py
index 3c57020..3c57020 100755
--- a/tests/functional/test_riscv32_tuxrun.py
+++ b/tests/functional/riscv32/test_tuxrun.py
diff --git a/tests/functional/riscv64/meson.build b/tests/functional/riscv64/meson.build
new file mode 100644
index 0000000..c1704d9
--- /dev/null
+++ b/tests/functional/riscv64/meson.build
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_riscv64_timeouts = {
+ 'tuxrun' : 120,
+}
+
+tests_riscv64_system_quick = [
+ 'migration',
+ 'opensbi',
+]
+
+tests_riscv64_system_thorough = [
+ 'sifive_u',
+ 'tuxrun',
+]
diff --git a/tests/functional/riscv64/test_migration.py b/tests/functional/riscv64/test_migration.py
new file mode 100755
index 0000000..2d613a2
--- /dev/null
+++ b/tests/functional/riscv64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# riscv64 migration test
+
+from migration import MigrationTest
+
+
+class Rv64MigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('virt')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('spike')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('virt')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_riscv_opensbi.py b/tests/functional/riscv64/test_opensbi.py
index d077e40..d077e40 100755
--- a/tests/functional/test_riscv_opensbi.py
+++ b/tests/functional/riscv64/test_opensbi.py
diff --git a/tests/functional/riscv64/test_sifive_u.py b/tests/functional/riscv64/test_sifive_u.py
new file mode 100755
index 0000000..358ff0d
--- /dev/null
+++ b/tests/functional/riscv64/test_sifive_u.py
@@ -0,0 +1,63 @@
+#!/usr/bin/env python3
+#
+# Functional test that boots a Linux kernel on a Sifive U machine
+# and checks the console
+#
+# Copyright (c) Linaro Ltd.
+#
+# Author:
+# Philippe Mathieu-Daudé
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import os
+
+from qemu_test import Asset, LinuxKernelTest
+from qemu_test import skipIfMissingCommands
+
+
+class SifiveU(LinuxKernelTest):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/riscv64/Image',
+ '2bd8132a3bf21570290042324fff48c987f42f2a00c08de979f43f0662ebadba')
+ ASSET_ROOTFS = Asset(
+ ('https://github.com/groeck/linux-build-test/raw/'
+ '9819da19e6eef291686fdd7b029ea00e764dc62f/rootfs/riscv64/'
+ 'rootfs.ext2.gz'),
+ 'b6ed95610310b7956f9bf20c4c9c0c05fea647900df441da9dfe767d24e8b28b')
+
+ def do_test_riscv64_sifive_u_mmc_spi(self, connect_card):
+ self.set_machine('sifive_u')
+ kernel_path = self.ASSET_KERNEL.fetch()
+ rootfs_path = self.uncompress(self.ASSET_ROOTFS)
+
+ self.vm.set_console()
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'earlycon=sbi console=ttySIF0 '
+ 'root=/dev/mmcblk0 ')
+ self.vm.add_args('-kernel', kernel_path,
+ '-append', kernel_command_line,
+ '-no-reboot')
+ if connect_card:
+ kernel_command_line += 'panic=-1 noreboot rootwait '
+ self.vm.add_args('-drive', f'file={rootfs_path},if=sd,format=raw')
+ pattern = 'Boot successful.'
+ else:
+ kernel_command_line += 'panic=0 noreboot '
+ pattern = 'Cannot open root device "mmcblk0" or unknown-block(0,0)'
+
+ self.vm.launch()
+ self.wait_for_console_pattern(pattern)
+
+ os.remove(rootfs_path)
+
+ def test_riscv64_sifive_u_nommc_spi(self):
+ self.do_test_riscv64_sifive_u_mmc_spi(False)
+
+ def test_riscv64_sifive_u_mmc_spi(self):
+ self.do_test_riscv64_sifive_u_mmc_spi(True)
+
+
+if __name__ == '__main__':
+ LinuxKernelTest.main()
diff --git a/tests/functional/test_riscv64_tuxrun.py b/tests/functional/riscv64/test_tuxrun.py
index 0d8de36..0d8de36 100755
--- a/tests/functional/test_riscv64_tuxrun.py
+++ b/tests/functional/riscv64/test_tuxrun.py
diff --git a/tests/functional/rx/meson.build b/tests/functional/rx/meson.build
new file mode 100644
index 0000000..6af83a9
--- /dev/null
+++ b/tests/functional/rx/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_rx_system_thorough = [
+ 'gdbsim',
+]
diff --git a/tests/functional/test_rx_gdbsim.py b/tests/functional/rx/test_gdbsim.py
index 4924579..4924579 100755
--- a/tests/functional/test_rx_gdbsim.py
+++ b/tests/functional/rx/test_gdbsim.py
diff --git a/tests/functional/s390x/meson.build b/tests/functional/s390x/meson.build
new file mode 100644
index 0000000..70cd36e
--- /dev/null
+++ b/tests/functional/s390x/meson.build
@@ -0,0 +1,17 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_s390x_timeouts = {
+ 'ccw_virtio' : 420,
+}
+
+tests_s390x_system_quick = [
+ 'vmstate',
+]
+
+tests_s390x_system_thorough = [
+ 'ccw_virtio',
+ 'pxelinux',
+ 'replay',
+ 'topology',
+ 'tuxrun',
+]
diff --git a/tests/functional/test_s390x_ccw_virtio.py b/tests/functional/s390x/test_ccw_virtio.py
index 453711a..453711a 100755
--- a/tests/functional/test_s390x_ccw_virtio.py
+++ b/tests/functional/s390x/test_ccw_virtio.py
diff --git a/tests/functional/s390x/test_pxelinux.py b/tests/functional/s390x/test_pxelinux.py
new file mode 100755
index 0000000..c00cce6
--- /dev/null
+++ b/tests/functional/s390x/test_pxelinux.py
@@ -0,0 +1,130 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+'''
+Functional test that checks the pxelinux.cfg network booting of a s390x VM
+(TFTP booting without config file is already tested by the pxe qtest, so
+we don't repeat that here).
+'''
+
+import os
+import shutil
+
+from qemu_test import QemuSystemTest, Asset, wait_for_console_pattern
+
+
+PXELINUX_CFG_CONTENTS='''# pxelinux.cfg style config file
+default Debian
+label Nonexisting
+kernel kernel.notavailable
+initrd initrd.notavailable
+label Debian
+kernel kernel.debian
+initrd initrd.debian
+append testoption=teststring
+label Fedora
+kernel kernel.fedora
+'''
+
+class S390PxeLinux(QemuSystemTest):
+ '''
+ Test various ways of booting via a pxelinux.cfg file, for details see:
+ https://wiki.syslinux.org/wiki/index.php?title=PXELINUX#Configuration
+ '''
+
+ ASSET_DEBIAN_KERNEL = Asset(
+ ('https://snapshot.debian.org/archive/debian/'
+ '20201126T092837Z/dists/buster/main/installer-s390x/'
+ '20190702+deb10u6/images/generic/kernel.debian'),
+ 'd411d17c39ae7ad38d27534376cbe88b68b403c325739364122c2e6f1537e818')
+
+ ASSET_DEBIAN_INITRD = Asset(
+ ('https://snapshot.debian.org/archive/debian/'
+ '20201126T092837Z/dists/buster/main/installer-s390x/'
+ '20190702+deb10u6/images/generic/initrd.debian'),
+ '836bbd0fe6a5ca81274c28c2b063ea315ce1868660866e9b60180c575fef9fd5')
+
+ ASSET_FEDORA_KERNEL = Asset(
+ ('https://archives.fedoraproject.org/pub/archive'
+ '/fedora-secondary/releases/31/Server/s390x/os'
+ '/images/kernel.img'),
+ '480859574f3f44caa6cd35c62d70e1ac0609134e22ce2a954bbed9b110c06e0b')
+
+ def pxelinux_launch(self, pl_name='default', extra_opts=None):
+ '''Create a pxelinux.cfg file in the right location and launch QEMU'''
+ self.require_netdev('user')
+ self.set_machine('s390-ccw-virtio')
+
+ debian_kernel = self.ASSET_DEBIAN_KERNEL.fetch()
+ debian_initrd = self.ASSET_DEBIAN_INITRD.fetch()
+ fedora_kernel = self.ASSET_FEDORA_KERNEL.fetch()
+
+ # Prepare a folder for the TFTP "server":
+ tftpdir = self.scratch_file('tftp')
+ shutil.rmtree(tftpdir, ignore_errors=True) # Remove stale stuff
+ os.mkdir(tftpdir)
+ shutil.copy(debian_kernel, os.path.join(tftpdir, 'kernel.debian'))
+ shutil.copy(debian_initrd, os.path.join(tftpdir, 'initrd.debian'))
+ shutil.copy(fedora_kernel, os.path.join(tftpdir, 'kernel.fedora'))
+
+ pxelinuxdir = self.scratch_file('tftp', 'pxelinux.cfg')
+ os.mkdir(pxelinuxdir)
+
+ cfg_fname = self.scratch_file('tftp', 'pxelinux.cfg', pl_name)
+ with open(cfg_fname, 'w', encoding='utf-8') as f:
+ f.write(PXELINUX_CFG_CONTENTS)
+
+ virtio_net_dev = 'virtio-net-ccw,netdev=n1,bootindex=1'
+ if extra_opts:
+ virtio_net_dev += ',' + extra_opts
+
+ self.vm.add_args('-m', '384',
+ '-netdev', f'user,id=n1,tftp={tftpdir}',
+ '-device', virtio_net_dev)
+ self.vm.set_console()
+ self.vm.launch()
+
+
+ def test_default(self):
+ '''Check whether the guest uses the "default" file name'''
+ self.pxelinux_launch()
+ # The kernel prints its arguments to the console, so we can use
+ # this to check whether the kernel parameters are correctly handled:
+ wait_for_console_pattern(self, 'testoption=teststring')
+ # Now also check that we've successfully loaded the initrd:
+ wait_for_console_pattern(self, 'Unpacking initramfs...')
+ wait_for_console_pattern(self, 'Run /init as init process')
+
+ def test_mac(self):
+ '''Check whether the guest uses file name based on its MAC address'''
+ self.pxelinux_launch(pl_name='01-02-ca-fe-ba-be-42',
+ extra_opts='mac=02:ca:fe:ba:be:42,loadparm=3')
+ wait_for_console_pattern(self, 'Linux version 5.3.7-301.fc31.s390x')
+
+ def test_uuid(self):
+ '''Check whether the guest uses file name based on its UUID'''
+ # Also add a non-bootable disk to check the fallback to network boot:
+ self.vm.add_args('-blockdev', 'null-co,size=65536,node-name=d1',
+ '-device', 'virtio-blk,drive=d1,bootindex=0,loadparm=1',
+ '-uuid', '550e8400-e29b-11d4-a716-446655441234')
+ self.pxelinux_launch(pl_name='550e8400-e29b-11d4-a716-446655441234')
+ wait_for_console_pattern(self, 'Debian 4.19.146-1 (2020-09-17)')
+
+ def test_ip(self):
+ '''Check whether the guest uses file name based on its IP address'''
+ self.vm.add_args('-M', 'loadparm=3')
+ self.pxelinux_launch(pl_name='0A00020F')
+ wait_for_console_pattern(self, 'Linux version 5.3.7-301.fc31.s390x')
+
+ def test_menu(self):
+ '''Check whether the boot menu works for pxelinux.cfg booting'''
+ self.vm.add_args('-boot', 'menu=on,splash-time=10')
+ self.pxelinux_launch(pl_name='0A00')
+ wait_for_console_pattern(self, '[1] Nonexisting')
+ wait_for_console_pattern(self, '[2] Debian')
+ wait_for_console_pattern(self, '[3] Fedora')
+ wait_for_console_pattern(self, 'Debian 4.19.146-1 (2020-09-17)')
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_s390x_replay.py b/tests/functional/s390x/test_replay.py
index 33b5843..33b5843 100755
--- a/tests/functional/test_s390x_replay.py
+++ b/tests/functional/s390x/test_replay.py
diff --git a/tests/functional/test_s390x_topology.py b/tests/functional/s390x/test_topology.py
index eefd972..1b5dc65 100755
--- a/tests/functional/test_s390x_topology.py
+++ b/tests/functional/s390x/test_topology.py
@@ -217,12 +217,12 @@ class S390CPUTopology(QemuSystemTest):
self.assertEqual(res['return']['polarization'], 'horizontal')
self.check_topology(0, 0, 0, 0, 'medium', False)
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
res = self.vm.qmp('query-s390x-cpu-polarization')
self.assertEqual(res['return']['polarization'], 'vertical')
self.check_topology(0, 0, 0, 0, 'medium', False)
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
res = self.vm.qmp('query-s390x-cpu-polarization')
self.assertEqual(res['return']['polarization'], 'horizontal')
self.check_topology(0, 0, 0, 0, 'medium', False)
@@ -283,7 +283,7 @@ class S390CPUTopology(QemuSystemTest):
self.check_polarization('vertical:high')
self.check_topology(0, 0, 0, 0, 'high', False)
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
self.check_polarization("horizontal")
self.check_topology(0, 0, 0, 0, 'high', False)
@@ -310,11 +310,11 @@ class S390CPUTopology(QemuSystemTest):
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("horizontal")
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("vertical:high")
- self.guest_set_dispatching('0');
+ self.guest_set_dispatching('0')
self.check_topology(0, 0, 0, 0, 'high', True)
self.check_polarization("horizontal")
@@ -360,7 +360,7 @@ class S390CPUTopology(QemuSystemTest):
self.check_topology(0, 0, 0, 0, 'high', True)
- self.guest_set_dispatching('1');
+ self.guest_set_dispatching('1')
self.check_topology(0, 0, 0, 0, 'high', True)
diff --git a/tests/functional/test_s390x_tuxrun.py b/tests/functional/s390x/test_tuxrun.py
index a7db4bf..8df3c68 100755
--- a/tests/functional/test_s390x_tuxrun.py
+++ b/tests/functional/s390x/test_tuxrun.py
@@ -24,6 +24,7 @@ class TuxRunS390xTest(TuxRunBaselineTest):
'bff7971fc2fef56372d98afe4557b82fd0a785a241e44c29b058e577ad1bbb44')
def test_s390(self):
+ self.set_machine('s390-ccw-virtio')
self.wait_for_shutdown=False
self.common_tuxrun(kernel_asset=self.ASSET_S390X_KERNEL,
rootfs_asset=self.ASSET_S390X_ROOTFS,
diff --git a/tests/functional/sh4/meson.build b/tests/functional/sh4/meson.build
new file mode 100644
index 0000000..56f824e
--- /dev/null
+++ b/tests/functional/sh4/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_sh4_timeouts = {
+ 'tuxrun' : 240,
+}
+
+tests_sh4_system_thorough = [
+ 'r2d',
+ 'tuxrun',
+]
diff --git a/tests/functional/test_sh4_r2d.py b/tests/functional/sh4/test_r2d.py
index 03a64837..03a64837 100755
--- a/tests/functional/test_sh4_r2d.py
+++ b/tests/functional/sh4/test_r2d.py
diff --git a/tests/functional/test_sh4_tuxrun.py b/tests/functional/sh4/test_tuxrun.py
index 1748f8c..1748f8c 100755
--- a/tests/functional/test_sh4_tuxrun.py
+++ b/tests/functional/sh4/test_tuxrun.py
diff --git a/tests/functional/sh4eb/meson.build b/tests/functional/sh4eb/meson.build
new file mode 100644
index 0000000..25e9a6e
--- /dev/null
+++ b/tests/functional/sh4eb/meson.build
@@ -0,0 +1,5 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_sh4eb_system_thorough = [
+ 'r2d',
+]
diff --git a/tests/functional/test_sh4eb_r2d.py b/tests/functional/sh4eb/test_r2d.py
index 473093b..473093b 100755
--- a/tests/functional/test_sh4eb_r2d.py
+++ b/tests/functional/sh4eb/test_r2d.py
diff --git a/tests/functional/sparc/meson.build b/tests/functional/sparc/meson.build
new file mode 100644
index 0000000..88732be
--- /dev/null
+++ b/tests/functional/sparc/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_sparc_system_quick = [
+ 'migration',
+]
+
+tests_sparc_system_thorough = [
+ 'replay',
+ 'sun4m',
+]
diff --git a/tests/functional/sparc/test_migration.py b/tests/functional/sparc/test_migration.py
new file mode 100755
index 0000000..dd6d578
--- /dev/null
+++ b/tests/functional/sparc/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Sparc migration test
+
+from migration import MigrationTest
+
+
+class SparcMigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('SS-4')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('SS-5')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('SS-4')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_sparc_replay.py b/tests/functional/sparc/test_replay.py
index 865d648..865d648 100755
--- a/tests/functional/test_sparc_replay.py
+++ b/tests/functional/sparc/test_replay.py
diff --git a/tests/functional/test_sparc_sun4m.py b/tests/functional/sparc/test_sun4m.py
index 7cd28eb..7cd28eb 100755
--- a/tests/functional/test_sparc_sun4m.py
+++ b/tests/functional/sparc/test_sun4m.py
diff --git a/tests/functional/sparc64/meson.build b/tests/functional/sparc64/meson.build
new file mode 100644
index 0000000..2e04e7d
--- /dev/null
+++ b/tests/functional/sparc64/meson.build
@@ -0,0 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_sparc64_system_quick = [
+ 'migration',
+]
+
+tests_sparc64_system_thorough = [
+ 'sun4u',
+ 'tuxrun',
+]
diff --git a/tests/functional/sparc64/test_migration.py b/tests/functional/sparc64/test_migration.py
new file mode 100755
index 0000000..a8a6c73
--- /dev/null
+++ b/tests/functional/sparc64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Sparc64 migration test
+
+from migration import MigrationTest
+
+
+class Sparc64MigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('sun4u')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('sun4u')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('sun4u')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/test_sparc64_sun4u.py b/tests/functional/sparc64/test_sun4u.py
index 27ac289..27ac289 100755
--- a/tests/functional/test_sparc64_sun4u.py
+++ b/tests/functional/sparc64/test_sun4u.py
diff --git a/tests/functional/test_sparc64_tuxrun.py b/tests/functional/sparc64/test_tuxrun.py
index 3be08d6..0d7b43d 100755
--- a/tests/functional/test_sparc64_tuxrun.py
+++ b/tests/functional/sparc64/test_tuxrun.py
@@ -24,6 +24,7 @@ class TuxRunSparc64Test(TuxRunBaselineTest):
'479c3dc104c82b68be55e2c0c5c38cd473d0b37ad4badccde4775bb88ce34611')
def test_sparc64(self):
+ self.set_machine('sun4u')
self.root='sda'
self.wait_for_shutdown=False
self.common_tuxrun(kernel_asset=self.ASSET_SPARC64_KERNEL,
diff --git a/tests/functional/test_aarch64_replay.py b/tests/functional/test_aarch64_replay.py
deleted file mode 100755
index 04cde43..0000000
--- a/tests/functional/test_aarch64_replay.py
+++ /dev/null
@@ -1,30 +0,0 @@
-#!/usr/bin/env python3
-#
-# Replay test that boots a Linux kernel on an aarch64 machine
-# and checks the console
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-from qemu_test import Asset
-from replay_kernel import ReplayKernelBase
-
-
-class Aarch64Replay(ReplayKernelBase):
-
- ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
- 'releases/29/Everything/aarch64/os/images/pxeboot/vmlinuz'),
- '7e1430b81c26bdd0da025eeb8fbd77b5dc961da4364af26e771bd39f379cbbf7')
-
- def test_aarch64_virt(self):
- self.set_machine('virt')
- self.cpu = 'cortex-a53'
- kernel_path = self.ASSET_KERNEL.fetch()
- kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
- 'console=ttyAMA0')
- console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern)
-
-
-if __name__ == '__main__':
- ReplayKernelBase.main()
diff --git a/tests/functional/test_aarch64_rme_sbsaref.py b/tests/functional/test_aarch64_rme_sbsaref.py
deleted file mode 100755
index 0f4f610..0000000
--- a/tests/functional/test_aarch64_rme_sbsaref.py
+++ /dev/null
@@ -1,71 +0,0 @@
-#!/usr/bin/env python3
-#
-# Functional test that boots a Realms environment on sbsa-ref machine and a
-# nested guest VM using it.
-#
-# Copyright (c) 2024 Linaro Ltd.
-#
-# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-import time
-import os
-import logging
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, wait_for_console_pattern
-from qemu_test import exec_command_and_wait_for_pattern
-from test_aarch64_rme_virt import test_realms_guest
-
-class Aarch64RMESbsaRefMachine(QemuSystemTest):
-
- # Stack is built with OP-TEE build environment from those instructions:
- # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
- # https://github.com/pbo-linaro/qemu-rme-stack
- ASSET_RME_STACK_SBSA = Asset(
- ('https://fileserver.linaro.org/s/KJyeBxL82mz2r7F/'
- 'download/rme-stack-op-tee-4.2.0-cca-v4-sbsa.tar.gz'),
- 'dd9ab28ec869bdf3b5376116cb3689103b43433fd5c4bca0f4a8d8b3c104999e')
-
- # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
- # and launching a nested VM using it.
- def test_aarch64_rme_sbsaref(self):
- self.set_machine('sbsa-ref')
- self.require_accelerator('tcg')
- self.require_netdev('user')
-
- self.vm.set_console()
-
- stack_path_tar_gz = self.ASSET_RME_STACK_SBSA.fetch()
- self.archive_extract(stack_path_tar_gz, format="tar")
-
- rme_stack = self.scratch_file('rme-stack-op-tee-4.2.0-cca-v4-sbsa')
- pflash0 = os.path.join(rme_stack, 'images', 'SBSA_FLASH0.fd')
- pflash1 = os.path.join(rme_stack, 'images', 'SBSA_FLASH1.fd')
- virtual = os.path.join(rme_stack, 'images', 'disks', 'virtual')
- drive = os.path.join(rme_stack, 'out-br', 'images', 'rootfs.ext4')
-
- self.vm.add_args('-cpu', 'max,x-rme=on,pauth-impdef=on')
- self.vm.add_args('-m', '2G')
- self.vm.add_args('-M', 'sbsa-ref')
- self.vm.add_args('-drive', f'file={pflash0},format=raw,if=pflash')
- self.vm.add_args('-drive', f'file={pflash1},format=raw,if=pflash')
- self.vm.add_args('-drive', f'file=fat:rw:{virtual},format=raw')
- self.vm.add_args('-drive', f'format=raw,if=none,file={drive},id=hd0')
- self.vm.add_args('-device', 'virtio-blk-pci,drive=hd0')
- self.vm.add_args('-device', 'virtio-9p-pci,fsdev=shr0,mount_tag=shr0')
- self.vm.add_args('-fsdev', f'local,security_model=none,path={rme_stack},id=shr0')
- self.vm.add_args('-device', 'virtio-net-pci,netdev=net0')
- self.vm.add_args('-netdev', 'user,id=net0')
-
- self.vm.launch()
- # Wait for host VM boot to complete.
- wait_for_console_pattern(self, 'Welcome to Buildroot',
- failure_message='Synchronous Exception at')
- exec_command_and_wait_for_pattern(self, 'root', '#')
-
- test_realms_guest(self)
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/test_aarch64_rme_virt.py b/tests/functional/test_aarch64_rme_virt.py
deleted file mode 100755
index f4ad4d3..0000000
--- a/tests/functional/test_aarch64_rme_virt.py
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python3
-#
-# Functional test that boots a Realms environment on virt machine and a nested
-# guest VM using it.
-#
-# Copyright (c) 2024 Linaro Ltd.
-#
-# Author: Pierrick Bouvier <pierrick.bouvier@linaro.org>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-import time
-import os
-import logging
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import exec_command, wait_for_console_pattern
-from qemu_test import exec_command_and_wait_for_pattern
-
-def test_realms_guest(test_rme_instance):
-
- # Boot the (nested) guest VM
- exec_command(test_rme_instance,
- 'qemu-system-aarch64 -M virt,gic-version=3 '
- '-cpu host -enable-kvm -m 512M '
- '-M confidential-guest-support=rme0 '
- '-object rme-guest,id=rme0 '
- '-device virtio-net-pci,netdev=net0,romfile= '
- '-netdev user,id=net0 '
- '-kernel /mnt/out/bin/Image '
- '-initrd /mnt/out-br/images/rootfs.cpio '
- '-serial stdio')
- # Detect Realm activation during (nested) guest boot.
- wait_for_console_pattern(test_rme_instance,
- 'SMC_RMI_REALM_ACTIVATE')
- # Wait for (nested) guest boot to complete.
- wait_for_console_pattern(test_rme_instance,
- 'Welcome to Buildroot')
- exec_command_and_wait_for_pattern(test_rme_instance, 'root', '#')
- # query (nested) guest cca report
- exec_command(test_rme_instance, 'cca-workload-attestation report')
- wait_for_console_pattern(test_rme_instance,
- '"cca-platform-hash-algo-id": "sha-256"')
- wait_for_console_pattern(test_rme_instance,
- '"cca-realm-hash-algo-id": "sha-512"')
- wait_for_console_pattern(test_rme_instance,
- '"cca-realm-public-key-hash-algo-id": "sha-256"')
-
-class Aarch64RMEVirtMachine(QemuSystemTest):
-
- # Stack is built with OP-TEE build environment from those instructions:
- # https://linaro.atlassian.net/wiki/spaces/QEMU/pages/29051027459/
- # https://github.com/pbo-linaro/qemu-rme-stack
- ASSET_RME_STACK_VIRT = Asset(
- ('https://fileserver.linaro.org/s/iaRsNDJp2CXHMSJ/'
- 'download/rme-stack-op-tee-4.2.0-cca-v4-qemu_v8.tar.gz'),
- '1851adc232b094384d8b879b9a2cfff07ef3d6205032b85e9b3a4a9ae6b0b7ad')
-
- # This tests the FEAT_RME cpu implementation, by booting a VM supporting it,
- # and launching a nested VM using it.
- def test_aarch64_rme_virt(self):
- self.set_machine('virt')
- self.require_accelerator('tcg')
- self.require_netdev('user')
-
- self.vm.set_console()
-
- stack_path_tar_gz = self.ASSET_RME_STACK_VIRT.fetch()
- self.archive_extract(stack_path_tar_gz, format="tar")
-
- rme_stack = self.scratch_file('rme-stack-op-tee-4.2.0-cca-v4-qemu_v8')
- kernel = os.path.join(rme_stack, 'out', 'bin', 'Image')
- bios = os.path.join(rme_stack, 'out', 'bin', 'flash.bin')
- drive = os.path.join(rme_stack, 'out-br', 'images', 'rootfs.ext4')
-
- self.vm.add_args('-cpu', 'max,x-rme=on,pauth-impdef=on')
- self.vm.add_args('-m', '2G')
- self.vm.add_args('-M', 'virt,acpi=off,'
- 'virtualization=on,'
- 'secure=on,'
- 'gic-version=3')
- self.vm.add_args('-bios', bios)
- self.vm.add_args('-kernel', kernel)
- self.vm.add_args('-drive', f'format=raw,if=none,file={drive},id=hd0')
- self.vm.add_args('-device', 'virtio-blk-pci,drive=hd0')
- self.vm.add_args('-device', 'virtio-9p-device,fsdev=shr0,mount_tag=shr0')
- self.vm.add_args('-fsdev', f'local,security_model=none,path={rme_stack},id=shr0')
- self.vm.add_args('-device', 'virtio-net-pci,netdev=net0')
- self.vm.add_args('-netdev', 'user,id=net0')
- self.vm.add_args('-append', 'root=/dev/vda')
-
- self.vm.launch()
- # Wait for host VM boot to complete.
- wait_for_console_pattern(self, 'Welcome to Buildroot',
- failure_message='Synchronous Exception at')
- exec_command_and_wait_for_pattern(self, 'root', '#')
-
- test_realms_guest(self)
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/test_mips_malta.py b/tests/functional/test_mips_malta.py
deleted file mode 100755
index 9697c7d..0000000
--- a/tests/functional/test_mips_malta.py
+++ /dev/null
@@ -1,94 +0,0 @@
-#!/usr/bin/env python3
-#
-# Functional tests for the big-endian 32-bit MIPS Malta board
-#
-# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-from qemu_test import LinuxKernelTest, Asset
-from qemu_test import exec_command_and_wait_for_pattern
-
-
-class MaltaMachineConsole(LinuxKernelTest):
-
- ASSET_KERNEL_2_63_2 = Asset(
- ('http://snapshot.debian.org/archive/debian/'
- '20130217T032700Z/pool/main/l/linux-2.6/'
- 'linux-image-2.6.32-5-4kc-malta_2.6.32-48_mips.deb'),
- '16ca524148afb0626f483163e5edf352bc1ab0e4fc7b9f9d473252762f2c7a43')
-
- def test_mips_malta(self):
- kernel_path = self.archive_extract(
- self.ASSET_KERNEL_2_63_2,
- member='boot/vmlinux-2.6.32-5-4kc-malta')
-
- self.set_machine('malta')
- self.vm.set_console()
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
- self.vm.add_args('-kernel', kernel_path,
- '-append', kernel_command_line)
- self.vm.launch()
- console_pattern = 'Kernel command line: %s' % kernel_command_line
- self.wait_for_console_pattern(console_pattern)
-
- ASSET_KERNEL_4_5_0 = Asset(
- ('http://snapshot.debian.org/archive/debian/'
- '20160601T041800Z/pool/main/l/linux/'
- 'linux-image-4.5.0-2-4kc-malta_4.5.5-1_mips.deb'),
- '526b17d5889840888b76fc2c36a0ebde182c9b1410a3a1e68203c3b160eb2027')
-
- ASSET_INITRD = Asset(
- ('https://github.com/groeck/linux-build-test/raw/'
- '8584a59ed9e5eb5ee7ca91f6d74bbb06619205b8/rootfs/'
- 'mips/rootfs.cpio.gz'),
- 'dcfe3a7fe3200da3a00d176b95caaa086495eb158f2bff64afc67d7e1eb2cddc')
-
- def test_mips_malta_cpio(self):
- self.require_netdev('user')
- self.set_machine('malta')
- self.require_device('pcnet')
-
- kernel_path = self.archive_extract(
- self.ASSET_KERNEL_4_5_0,
- member='boot/vmlinux-4.5.0-2-4kc-malta')
- initrd_path = self.uncompress(self.ASSET_INITRD)
-
- self.vm.set_console()
- kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE
- + 'console=ttyS0 console=tty '
- + 'rdinit=/sbin/init noreboot')
- self.vm.add_args('-kernel', kernel_path,
- '-initrd', initrd_path,
- '-append', kernel_command_line,
- '-netdev', 'user,id=n1,tftp=' + self.scratch_file('boot'),
- '-device', 'pcnet,netdev=n1',
- '-no-reboot')
- self.vm.launch()
- self.wait_for_console_pattern('Boot successful.')
-
- exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
- 'BogoMIPS')
- exec_command_and_wait_for_pattern(self, 'uname -a',
- 'Debian')
-
- exec_command_and_wait_for_pattern(self, 'ip link set eth0 up',
- 'eth0: link up')
- exec_command_and_wait_for_pattern(self,
- 'ip addr add 10.0.2.15 dev eth0',
- '#')
- exec_command_and_wait_for_pattern(self, 'route add default eth0', '#')
- exec_command_and_wait_for_pattern(self,
- 'tftp -g -r vmlinux-4.5.0-2-4kc-malta 10.0.2.2', '#')
- exec_command_and_wait_for_pattern(self,
- 'md5sum vmlinux-4.5.0-2-4kc-malta',
- 'a98218a7efbdefb2dfdf9ecd08c98318')
-
- exec_command_and_wait_for_pattern(self, 'reboot',
- 'reboot: Restarting system')
- # Wait for VM to shut down gracefully
- self.vm.wait()
-
-
-if __name__ == '__main__':
- LinuxKernelTest.main()
diff --git a/tests/functional/test_ppc_bamboo.py b/tests/functional/test_ppc_bamboo.py
deleted file mode 100755
index fddcc24..0000000
--- a/tests/functional/test_ppc_bamboo.py
+++ /dev/null
@@ -1,44 +0,0 @@
-#!/usr/bin/env python3
-#
-# Test that Linux kernel boots on the ppc bamboo board and check the console
-#
-# Copyright (c) 2021 Red Hat
-#
-# This work is licensed under the terms of the GNU GPL, version 2 or
-# later. See the COPYING file in the top-level directory.
-
-from qemu_test import QemuSystemTest, Asset
-from qemu_test import wait_for_console_pattern
-from qemu_test import exec_command_and_wait_for_pattern
-
-
-class BambooMachine(QemuSystemTest):
-
- timeout = 90
-
- ASSET_IMAGE = Asset(
- ('http://landley.net/aboriginal/downloads/binaries/'
- 'system-image-powerpc-440fp.tar.gz'),
- 'c12b58f841c775a0e6df4832a55afe6b74814d1565d08ddeafc1fb949a075c5e')
-
- def test_ppc_bamboo(self):
- self.set_machine('bamboo')
- self.require_accelerator("tcg")
- self.require_netdev('user')
- self.archive_extract(self.ASSET_IMAGE)
- self.vm.set_console()
- self.vm.add_args('-kernel',
- self.scratch_file('system-image-powerpc-440fp',
- 'linux'),
- '-initrd',
- self.scratch_file('system-image-powerpc-440fp',
- 'rootfs.cpio.gz'),
- '-nic', 'user,model=rtl8139,restrict=on')
- self.vm.launch()
- wait_for_console_pattern(self, 'Type exit when done')
- exec_command_and_wait_for_pattern(self, 'ping 10.0.2.2',
- '10.0.2.2 is alive!')
- exec_command_and_wait_for_pattern(self, 'halt', 'System Halted')
-
-if __name__ == '__main__':
- QemuSystemTest.main()
diff --git a/tests/functional/test_x86_64_replay.py b/tests/functional/test_x86_64_replay.py
deleted file mode 100755
index 180f23a..0000000
--- a/tests/functional/test_x86_64_replay.py
+++ /dev/null
@@ -1,35 +0,0 @@
-#!/usr/bin/env python3
-#
-# Replay test that boots a Linux kernel on x86_64 machines
-# and checks the console
-#
-# SPDX-License-Identifier: GPL-2.0-or-later
-
-from qemu_test import Asset, skipFlakyTest
-from replay_kernel import ReplayKernelBase
-
-
-class X86Replay(ReplayKernelBase):
-
- ASSET_KERNEL = Asset(
- ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
- '/releases/29/Everything/x86_64/os/images/pxeboot/vmlinuz'),
- '8f237d84712b1b411baf3af2aeaaee10b9aae8e345ec265b87ab3a39639eb143')
-
- def do_test_x86(self, machine):
- self.set_machine(machine)
- kernel_path = self.ASSET_KERNEL.fetch()
- kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=ttyS0'
- console_pattern = 'VFS: Cannot open root device'
- self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5)
-
- @skipFlakyTest('https://gitlab.com/qemu-project/qemu/-/issues/2094')
- def test_pc(self):
- self.do_test_x86('pc')
-
- def test_q35(self):
- self.do_test_x86('q35')
-
-
-if __name__ == '__main__':
- ReplayKernelBase.main()
diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/meson.build
new file mode 100644
index 0000000..f78eec5
--- /dev/null
+++ b/tests/functional/x86_64/meson.build
@@ -0,0 +1,39 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+test_x86_64_timeouts = {
+ 'acpi_bits' : 420,
+ 'intel_iommu': 300,
+ 'kvm_xen' : 180,
+ 'netdev_ethtool' : 180,
+ 'replay' : 480,
+ 'virtio_balloon': 120,
+}
+
+tests_x86_64_system_quick = [
+ 'bad_vmstate',
+ 'cpu_model_versions',
+ 'cpu_queries',
+ 'mem_addr_space',
+ 'memlock',
+ 'migration',
+ 'pc_cpu_hotplug_props',
+ 'virtio_version',
+ 'vmstate',
+]
+
+tests_x86_64_system_thorough = [
+ 'acpi_bits',
+ 'hotplug_blk',
+ 'hotplug_cpu',
+ 'intel_iommu',
+ 'kvm_xen',
+ 'linux_initrd',
+ 'multiprocess',
+ 'netdev_ethtool',
+ 'replay',
+ 'reverse_debug',
+ 'tuxrun',
+ 'vfio_user_client',
+ 'virtio_balloon',
+ 'virtio_gpu',
+]
diff --git a/tests/functional/test_acpi_bits.py b/tests/functional/x86_64/test_acpi_bits.py
index 8e0563a..9a28165 100755
--- a/tests/functional/test_acpi_bits.py
+++ b/tests/functional/x86_64/test_acpi_bits.py
@@ -121,10 +121,10 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self._debugcon_log = 'debugcon-log.txt'
def _print_log(self, log):
- self.logger.info('\nlogs from biosbits follows:')
- self.logger.info('==========================================\n')
- self.logger.info(log)
- self.logger.info('==========================================\n')
+ self.log.info('\nlogs from biosbits follows:')
+ self.log.info('==========================================\n')
+ self.log.info(log)
+ self.log.info('==========================================\n')
def copy_bits_config(self):
""" copies the bios bits config file into bits.
@@ -138,8 +138,8 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self.assertTrue(os.path.exists(bits_config_file))
self.assertTrue(os.path.exists(target_config_dir))
shutil.copy2(bits_config_file, target_config_dir)
- self.logger.info('copied config file %s to %s',
- bits_config_file, target_config_dir)
+ self.log.info('copied config file %s to %s',
+ bits_config_file, target_config_dir)
def copy_test_scripts(self):
"""copies the python test scripts into bits. """
@@ -163,8 +163,8 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
newfilename = os.path.splitext(filename)[0] + '.py'
shutil.copy2(os.path.join(bits_test_dir, filename),
os.path.join(target_test_dir, newfilename))
- self.logger.info('copied test file %s to %s',
- filename, target_test_dir)
+ self.log.info('copied test file %s to %s',
+ filename, target_test_dir)
# now remove the pyc test file if it exists, otherwise the
# changes in the python test script won't be executed.
@@ -172,9 +172,9 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
if os.access(os.path.join(target_test_dir, testfile_pyc),
os.F_OK):
os.remove(os.path.join(target_test_dir, testfile_pyc))
- self.logger.info('removed compiled file %s',
- os.path.join(target_test_dir,
- testfile_pyc))
+ self.log.info('removed compiled file %s',
+ os.path.join(target_test_dir,
+ testfile_pyc))
def fix_mkrescue(self, mkrescue):
""" grub-mkrescue is a bash script with two variables, 'prefix' and
@@ -216,7 +216,7 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self.fix_mkrescue(mkrescue_script)
- self.logger.info('using grub-mkrescue for generating biosbits iso ...')
+ self.log.info('using grub-mkrescue for generating biosbits iso ...')
try:
if os.getenv('V') or os.getenv('BITS_DEBUG'):
@@ -225,7 +225,7 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
check=True)
- self.logger.info("grub-mkrescue output %s" % proc.stdout)
+ self.log.info("grub-mkrescue output %s" % proc.stdout)
else:
subprocess.check_call([mkrescue_script, '-o',
iso_file, bits_dir],
@@ -238,11 +238,10 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
self.assertTrue(os.access(iso_file, os.R_OK))
- self.logger.info('iso file %s successfully generated.', iso_file)
+ self.log.info('iso file %s successfully generated.', iso_file)
def setUp(self): # pylint: disable=arguments-differ
super().setUp()
- self.logger = self.log
prebuiltDir = self.scratch_file('prebuilt')
if not os.path.isdir(prebuiltDir):
@@ -333,7 +332,7 @@ class AcpiBitsTest(QemuSystemTest): #pylint: disable=too-many-instance-attribute
# in batch mode and then automatically initiate a vm shutdown.
self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT)
self._vm.wait(timeout=None)
- self.logger.debug("Checking console output ...")
+ self.log.debug("Checking console output ...")
self.parse_log()
if __name__ == '__main__':
diff --git a/tests/functional/x86_64/test_bad_vmstate.py b/tests/functional/x86_64/test_bad_vmstate.py
new file mode 100755
index 0000000..40098a8
--- /dev/null
+++ b/tests/functional/x86_64/test_bad_vmstate.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+'''Test whether the vmstate-static-checker script detects problems correctly'''
+
+import subprocess
+
+from qemu_test import QemuBaseTest
+
+
+EXPECTED_OUTPUT='''Warning: checking incompatible machine types: "pc-i440fx-2.1", "pc-i440fx-2.2"
+Section "fw_cfg" does not exist in dest
+Section "fusbh200-ehci-usb" version error: 2 > 1
+Section "fusbh200-ehci-usb", Description "ehci-core": expected field "usbsts", got "usbsts_pending"; skipping rest
+Section "pci-serial-4x" Description "pci-serial-multi": Entry "Fields" missing
+Section "intel-hda-generic", Description "intel-hda", Field "pci": missing description
+Section "cfi.pflash01": Entry "Description" missing
+Section "megasas", Description "PCIDevice": expected field "irq_state", while dest has no further fields
+Section "PIIX3-xen" Description "PIIX3": minimum version error: 1 < 2
+Section "PIIX3-xen" Description "PIIX3": Entry "Subsections" missing
+Section "tpci200": Description "tpci200" missing, got "tpci2002" instead; skipping
+Section "sun-fdtwo" Description "fdc": version error: 2 > 1
+Section "sun-fdtwo", Description "fdrive": Subsection "fdrive/media_rate" not found
+Section "usb-kbd" Description "usb-kbd" Field "kbd.keycodes" size mismatch: 4 , 2
+'''
+
+class BadVmStateTest(QemuBaseTest):
+ '''Test class for testing vmstat-static-checker script with bad input'''
+
+ def test_checker(self):
+ """
+ Test whether the checker script correctly detects the changes
+ between dump1.json and dump2.json.
+ """
+ src_json = self.data_file('..', 'data', 'vmstate-static-checker',
+ 'dump1.json')
+ dst_json = self.data_file('..', 'data', 'vmstate-static-checker',
+ 'dump2.json')
+ checkerscript = self.data_file('..', '..', 'scripts',
+ 'vmstate-static-checker.py')
+
+ self.log.info('Comparing %s with %s', src_json, dst_json)
+ cp = subprocess.run([checkerscript, '-s', src_json, '-d', dst_json],
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ text=True, check=False)
+ if cp.returncode != 13:
+ self.fail('Unexpected return code of vmstate-static-checker: ' +
+ cp.returncode)
+ if cp.stdout != EXPECTED_OUTPUT:
+ self.log.info('vmstate-static-checker output:\n%s', cp.stdout)
+ self.log.info('expected output:\n%s', EXPECTED_OUTPUT)
+ self.fail('Unexpected vmstate-static-checker output!')
+
+
+if __name__ == '__main__':
+ QemuBaseTest.main()
diff --git a/tests/functional/test_x86_cpu_model_versions.py b/tests/functional/x86_64/test_cpu_model_versions.py
index bd18acd..36c968f 100755
--- a/tests/functional/test_x86_cpu_model_versions.py
+++ b/tests/functional/x86_64/test_cpu_model_versions.py
@@ -72,44 +72,11 @@ class X86CPUModelAliases(QemuSystemTest):
self.assertNotIn("EPYC-IBPB-v1", cpus,
"EPYC-IBPB shouldn't be versioned")
- def test_4_0_alias_compatibility(self):
- """
- Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
- """
- self.set_machine('pc-i440fx-4.0')
- # pc-*-4.0 won't expose non-versioned CPU models as aliases
- # We do this to help management software to keep compatibility
- # with older QEMU versions that didn't have the versioned CPU model
- self.vm.add_args('-S')
- self.vm.launch()
- cpus = dict((m['name'], m) for m in
- self.vm.cmd('query-cpu-definitions'))
-
- self.assertFalse(cpus['Cascadelake-Server']['static'],
- 'unversioned Cascadelake-Server CPU model must not be static')
- self.assertNotIn('alias-of', cpus['Cascadelake-Server'],
- 'Cascadelake-Server must not be an alias')
- self.assertNotIn('alias-of', cpus['Cascadelake-Server-v1'],
- 'Cascadelake-Server-v1 must not be an alias')
-
- self.assertFalse(cpus['qemu64']['static'],
- 'unversioned qemu64 CPU model must not be static')
- self.assertNotIn('alias-of', cpus['qemu64'],
- 'qemu64 must not be an alias')
- self.assertNotIn('alias-of', cpus['qemu64-v1'],
- 'qemu64-v1 must not be an alias')
-
- self.validate_variant_aliases(cpus)
-
- # On pc-*-4.0, no CPU model should be reported as an alias:
- for name,c in cpus.items():
- self.assertNotIn('alias-of', c, "%s shouldn't be an alias" % (name))
-
- def test_4_1_alias(self):
+ def test_unversioned_alias(self):
"""
Check if unversioned CPU model is an alias pointing to right version
"""
- self.set_machine('pc-i440fx-4.1')
+ self.set_machine('pc')
self.vm.add_args('-S')
self.vm.launch()
@@ -133,7 +100,7 @@ class X86CPUModelAliases(QemuSystemTest):
self.validate_variant_aliases(cpus)
- # On pc-*-4.1, -noTSX and -IBRS models should be aliases:
+ # On recent PC machines, -noTSX and -IBRS models should be aliases:
self.assertEqual(cpus["Haswell"].get('alias-of'),
"Haswell-v1",
"Haswell must be an alias")
@@ -247,8 +214,8 @@ class CascadelakeArchCapabilities(QemuSystemTest):
cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
return self.vm.cmd('qom-get', path=cpu_path, property=prop)
- def test_4_1(self):
- self.set_machine('pc-i440fx-4.1')
+ def test(self):
+ self.set_machine('pc')
# machine-type only:
self.vm.add_args('-S')
self.set_vm_arg('-cpu',
@@ -256,80 +223,27 @@ class CascadelakeArchCapabilities(QemuSystemTest):
'enforce=off')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
-
- def test_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server,x-force-features=on,check=off,'
- 'enforce=off')
- self.vm.launch()
- self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
-
- def test_set_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- # command line must override machine-type if CPU model is not versioned:
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server,x-force-features=on,check=off,'
- 'enforce=off,+arch-capabilities')
- self.vm.launch()
- self.assertTrue(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
+ 'pc + Cascadelake-Server should not have arch-capabilities')
- def test_unset_4_1(self):
- self.set_machine('pc-i440fx-4.1')
+ def test_unset(self):
+ self.set_machine('pc')
self.vm.add_args('-S')
self.set_vm_arg('-cpu',
'Cascadelake-Server,x-force-features=on,check=off,'
'enforce=off,-arch-capabilities')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
-
- def test_v1_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- # versioned CPU model overrides machine-type:
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server-v1,x-force-features=on,check=off,'
- 'enforce=off')
- self.vm.launch()
- self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
-
- def test_v2_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server-v2,x-force-features=on,check=off,'
- 'enforce=off')
- self.vm.launch()
- self.assertTrue(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
-
- def test_v1_set_4_0(self):
- self.set_machine('pc-i440fx-4.0')
- # command line must override machine-type and versioned CPU model:
- self.vm.add_args('-S')
- self.set_vm_arg('-cpu',
- 'Cascadelake-Server-v1,x-force-features=on,check=off,'
- 'enforce=off,+arch-capabilities')
- self.vm.launch()
- self.assertTrue(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
+ 'pc + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
- def test_v2_unset_4_1(self):
- self.set_machine('pc-i440fx-4.1')
+ def test_v2_unset(self):
+ self.set_machine('pc')
self.vm.add_args('-S')
self.set_vm_arg('-cpu',
'Cascadelake-Server-v2,x-force-features=on,check=off,'
'enforce=off,-arch-capabilities')
self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'),
- 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
+ 'pc + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
if __name__ == '__main__':
QemuSystemTest.main()
diff --git a/tests/functional/test_cpu_queries.py b/tests/functional/x86_64/test_cpu_queries.py
index b1122a0..b1122a0 100755
--- a/tests/functional/test_cpu_queries.py
+++ b/tests/functional/x86_64/test_cpu_queries.py
diff --git a/tests/functional/test_x86_64_hotplug_blk.py b/tests/functional/x86_64/test_hotplug_blk.py
index 7ddbfef..7ddbfef 100755
--- a/tests/functional/test_x86_64_hotplug_blk.py
+++ b/tests/functional/x86_64/test_hotplug_blk.py
diff --git a/tests/functional/test_x86_64_hotplug_cpu.py b/tests/functional/x86_64/test_hotplug_cpu.py
index 7b9200a..7b9200a 100755
--- a/tests/functional/test_x86_64_hotplug_cpu.py
+++ b/tests/functional/x86_64/test_hotplug_cpu.py
diff --git a/tests/functional/test_intel_iommu.py b/tests/functional/x86_64/test_intel_iommu.py
index 62268d6..62268d6 100755
--- a/tests/functional/test_intel_iommu.py
+++ b/tests/functional/x86_64/test_intel_iommu.py
diff --git a/tests/functional/test_x86_64_kvm_xen.py b/tests/functional/x86_64/test_kvm_xen.py
index c6abf6b..a5d4450 100755
--- a/tests/functional/test_x86_64_kvm_xen.py
+++ b/tests/functional/x86_64/test_kvm_xen.py
@@ -11,8 +11,6 @@
#
# SPDX-License-Identifier: GPL-2.0-or-later
-import os
-
from qemu.machine import machine
from qemu_test import QemuSystemTest, Asset, exec_command_and_wait_for_pattern
diff --git a/tests/functional/test_linux_initrd.py b/tests/functional/x86_64/test_linux_initrd.py
index 2207f83..2207f83 100755
--- a/tests/functional/test_linux_initrd.py
+++ b/tests/functional/x86_64/test_linux_initrd.py
diff --git a/tests/functional/test_mem_addr_space.py b/tests/functional/x86_64/test_mem_addr_space.py
index 2d9d31e..61b4a19 100755
--- a/tests/functional/test_mem_addr_space.py
+++ b/tests/functional/x86_64/test_mem_addr_space.py
@@ -58,8 +58,8 @@ class MemAddrCheck(QemuSystemTest):
should start fine.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.6G',
+ self.set_machine('q35')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=59.6G',
'-cpu', 'pentium,pse36=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -76,8 +76,8 @@ class MemAddrCheck(QemuSystemTest):
with pse36 above.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.6G',
+ self.set_machine('q35')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=59.6G',
'-cpu', 'pentium,pae=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -93,8 +93,8 @@ class MemAddrCheck(QemuSystemTest):
same options as the failing case above with pse36 cpu feature.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.5G',
+ self.set_machine('q35')
+ self.vm.add_args('-m', '512,slots=1,maxmem=59.5G',
'-cpu', 'pentium,pse36=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -111,8 +111,8 @@ class MemAddrCheck(QemuSystemTest):
with the same options as the case above.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.5G',
+ self.set_machine('q35')
+ self.vm.add_args('-m', '512,slots=1,maxmem=59.5G',
'-cpu', 'pentium,pae=on', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -128,8 +128,8 @@ class MemAddrCheck(QemuSystemTest):
with pse36 ON.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-machine', 'q35', '-m',
- '512,slots=1,maxmem=59.5G',
+ self.set_machine('q35')
+ self.vm.add_args('-m', '512,slots=1,maxmem=59.5G',
'-cpu', 'pentium2', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -148,8 +148,8 @@ class MemAddrCheck(QemuSystemTest):
above 4 GiB due to the PCI hole and simplicity.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'q35', '-m',
- '512,slots=1,maxmem=4G',
+ self.set_machine('q35')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=4G',
'-cpu', 'pentium', '-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -176,8 +176,8 @@ class MemAddrCheck(QemuSystemTest):
make QEMU fail with the error message.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.0', '-m',
- '512,slots=1,maxmem=988G',
+ self.set_machine('pc-q35-7.0')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=988G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -197,8 +197,8 @@ class MemAddrCheck(QemuSystemTest):
than 988 GiB).
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=976G',
+ self.set_machine('pc-q35-7.1')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=976G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -214,8 +214,8 @@ class MemAddrCheck(QemuSystemTest):
successfully start when maxmem is < 988G.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.0', '-m',
- '512,slots=1,maxmem=987.5G',
+ self.set_machine('pc-q35-7.0')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=987.5G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -231,8 +231,8 @@ class MemAddrCheck(QemuSystemTest):
successfully start when maxmem is < 976G.
"""
self.ensure_64bit_binary()
- self.vm.add_args('-S', '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=975.5G',
+ self.set_machine('pc-q35-7.1')
+ self.vm.add_args('-S', '-m', '512,slots=1,maxmem=975.5G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -249,9 +249,9 @@ class MemAddrCheck(QemuSystemTest):
"above_4G" memory starts at 4G.
"""
self.ensure_64bit_binary()
+ self.set_machine('pc-q35-7.1')
self.vm.add_args('-S', '-cpu', 'Skylake-Server',
- '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=976G',
+ '-m', '512,slots=1,maxmem=976G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -274,9 +274,9 @@ class MemAddrCheck(QemuSystemTest):
fail to start.
"""
self.ensure_64bit_binary()
+ self.set_machine('pc-q35-7.1')
self.vm.add_args('-S', '-cpu', 'EPYC-v4,phys-bits=41',
- '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=992G',
+ '-m', '512,slots=1,maxmem=992G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -293,9 +293,9 @@ class MemAddrCheck(QemuSystemTest):
QEMU should start fine.
"""
self.ensure_64bit_binary()
+ self.set_machine('pc-q35-7.1')
self.vm.add_args('-S', '-cpu', 'EPYC-v4,phys-bits=41',
- '-machine', 'pc-q35-7.1', '-m',
- '512,slots=1,maxmem=990G',
+ '-m', '512,slots=1,maxmem=990G',
'-display', 'none',
'-object', 'memory-backend-ram,id=mem1,size=1G',
'-device', 'pc-dimm,id=vm0,memdev=mem1')
@@ -314,12 +314,12 @@ class MemAddrCheck(QemuSystemTest):
alignment constraints with 40 bits (1 TiB) of processor physical bits.
"""
self.ensure_64bit_binary()
+ self.set_machine('q35')
self.vm.add_args('-S', '-cpu', 'Skylake-Server,phys-bits=40',
- '-machine', 'q35,cxl=on', '-m',
- '512,slots=1,maxmem=987G',
+ '-m', '512,slots=1,maxmem=987G',
'-display', 'none',
'-device', 'pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1',
- '-M', 'cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=1G')
+ '-M', 'cxl=on,cxl-fmw.0.targets.0=cxl.1,cxl-fmw.0.size=1G')
self.vm.set_qmp_monitor(enabled=False)
self.vm.launch()
self.vm.wait()
@@ -333,9 +333,10 @@ class MemAddrCheck(QemuSystemTest):
with cxl enabled.
"""
self.ensure_64bit_binary()
+ self.set_machine('q35')
self.vm.add_args('-S', '-cpu', 'Skylake-Server,phys-bits=40',
- '-machine', 'q35,cxl=on', '-m',
- '512,slots=1,maxmem=987G',
+ '-machine', 'cxl=on',
+ '-m', '512,slots=1,maxmem=987G',
'-display', 'none',
'-device', 'pxb-cxl,bus_nr=12,bus=pcie.0,id=cxl.1')
self.vm.set_qmp_monitor(enabled=False)
diff --git a/tests/functional/x86_64/test_memlock.py b/tests/functional/x86_64/test_memlock.py
new file mode 100755
index 0000000..81bce80
--- /dev/null
+++ b/tests/functional/x86_64/test_memlock.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python3
+#
+# Functional test that check overcommit memlock options
+#
+# Copyright (c) Yandex Technologies LLC, 2025
+#
+# Author:
+# Alexandr Moshkov <dtalexundeer@yandex-team.ru>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+import re
+
+from typing import Dict
+
+from qemu_test import QemuSystemTest
+from qemu_test import skipLockedMemoryTest
+
+
+STATUS_VALUE_PATTERN = re.compile(r'^(\w+):\s+(\d+) kB', re.MULTILINE)
+
+
+@skipLockedMemoryTest(2_097_152) # 2GB
+class MemlockTest(QemuSystemTest):
+ """
+ Runs a guest with memlock options.
+ Then verify, that this options is working correctly
+ by checking the status file of the QEMU process.
+ """
+
+ def common_vm_setup_with_memlock(self, memlock):
+ self.vm.add_args('-overcommit', f'mem-lock={memlock}')
+ self.vm.launch()
+
+ def test_memlock_off(self):
+ self.common_vm_setup_with_memlock('off')
+
+ status = self.get_process_status_values(self.vm.get_pid())
+
+ # libgcrypt may mlock a few pages
+ self.assertTrue(status['VmLck'] < 32)
+
+ def test_memlock_on(self):
+ self.common_vm_setup_with_memlock('on')
+
+ status = self.get_process_status_values(self.vm.get_pid())
+
+ # VmLck > 0 kB and almost all memory is resident
+ self.assertTrue(status['VmLck'] > 0)
+ self.assertTrue(status['VmRSS'] >= status['VmSize'] * 0.70)
+
+ def test_memlock_onfault(self):
+ self.common_vm_setup_with_memlock('on-fault')
+
+ status = self.get_process_status_values(self.vm.get_pid())
+
+ # VmLck > 0 kB and only few memory is resident
+ self.assertTrue(status['VmLck'] > 0)
+ self.assertTrue(status['VmRSS'] <= status['VmSize'] * 0.30)
+
+ def get_process_status_values(self, pid: int) -> Dict[str, int]:
+ result = {}
+ raw_status = self._get_raw_process_status(pid)
+
+ for line in raw_status.split('\n'):
+ if m := STATUS_VALUE_PATTERN.match(line):
+ result[m.group(1)] = int(m.group(2))
+
+ return result
+
+ def _get_raw_process_status(self, pid: int) -> str:
+ try:
+ with open(f'/proc/{pid}/status', 'r') as f:
+ return f.read()
+ except FileNotFoundError:
+ self.skipTest("Can't open status file of the process")
+
+
+if __name__ == '__main__':
+ MemlockTest.main()
diff --git a/tests/functional/x86_64/test_migration.py b/tests/functional/x86_64/test_migration.py
new file mode 100755
index 0000000..f3a517a
--- /dev/null
+++ b/tests/functional/x86_64/test_migration.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# x86_64 migration test
+
+from migration import MigrationTest
+
+
+class X8664MigrationTest(MigrationTest):
+
+ def test_migration_with_tcp_localhost(self):
+ self.set_machine('microvm')
+ self.migration_with_tcp_localhost()
+
+ def test_migration_with_unix(self):
+ self.set_machine('microvm')
+ self.migration_with_unix()
+
+ def test_migration_with_exec(self):
+ self.set_machine('microvm')
+ self.migration_with_exec()
+
+
+if __name__ == '__main__':
+ MigrationTest.main()
diff --git a/tests/functional/x86_64/test_multiprocess.py b/tests/functional/x86_64/test_multiprocess.py
new file mode 100755
index 0000000..756629d
--- /dev/null
+++ b/tests/functional/x86_64/test_multiprocess.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Test for multiprocess qemu on x86
+
+from multiprocess import Multiprocess
+from qemu_test import Asset
+
+
+class X86Multiprocess(Multiprocess):
+
+ ASSET_KERNEL_X86 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+ '/releases/31/Everything/x86_64/os/images/pxeboot/vmlinuz'),
+ 'd4738d03dbbe083ca610d0821d0a8f1488bebbdccef54ce33e3adb35fda00129')
+
+ ASSET_INITRD_X86 = Asset(
+ ('https://archives.fedoraproject.org/pub/archive/fedora/linux'
+ '/releases/31/Everything/x86_64/os/images/pxeboot/initrd.img'),
+ '3b6cb5c91a14c42e2f61520f1689264d865e772a1f0069e660a800d31dd61fb9')
+
+ def test_multiprocess(self):
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ 'console=ttyS0 rdinit=/bin/bash')
+ self.do_test(self.ASSET_KERNEL_X86, self.ASSET_INITRD_X86,
+ kernel_command_line, 'pc')
+
+
+if __name__ == '__main__':
+ Multiprocess.main()
diff --git a/tests/functional/test_netdev_ethtool.py b/tests/functional/x86_64/test_netdev_ethtool.py
index ee1a397..ee1a397 100755
--- a/tests/functional/test_netdev_ethtool.py
+++ b/tests/functional/x86_64/test_netdev_ethtool.py
diff --git a/tests/functional/test_pc_cpu_hotplug_props.py b/tests/functional/x86_64/test_pc_cpu_hotplug_props.py
index 9d5a37c..2bed8ad 100755
--- a/tests/functional/test_pc_cpu_hotplug_props.py
+++ b/tests/functional/x86_64/test_pc_cpu_hotplug_props.py
@@ -26,6 +26,7 @@ from qemu_test import QemuSystemTest
class OmittedCPUProps(QemuSystemTest):
def test_no_die_id(self):
+ self.set_machine('pc')
self.vm.add_args('-nodefaults', '-S')
self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8')
self.vm.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
diff --git a/tests/functional/x86_64/test_replay.py b/tests/functional/x86_64/test_replay.py
new file mode 100755
index 0000000..27287d4
--- /dev/null
+++ b/tests/functional/x86_64/test_replay.py
@@ -0,0 +1,58 @@
+#!/usr/bin/env python3
+#
+# Replay test that boots a Linux kernel on x86_64 machines
+# and checks the console
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+from subprocess import check_call, DEVNULL
+
+from qemu_test import Asset, skipFlakyTest, get_qemu_img
+from replay_kernel import ReplayKernelBase
+
+
+class X86Replay(ReplayKernelBase):
+
+ ASSET_KERNEL = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/x86_64/bzImage',
+ 'f57bfc6553bcd6e0a54aab86095bf642b33b5571d14e3af1731b18c87ed5aef8')
+
+ ASSET_ROOTFS = Asset(
+ 'https://storage.tuxboot.com/buildroot/20241119/x86_64/rootfs.ext4.zst',
+ '4b8b2a99117519c5290e1202cb36eb6c7aaba92b357b5160f5970cf5fb78a751')
+
+ def do_test_x86(self, machine, blkdevice, devroot):
+ self.require_netdev('user')
+ self.set_machine(machine)
+ self.cpu="Nehalem"
+ kernel_path = self.ASSET_KERNEL.fetch()
+
+ raw_disk = self.uncompress(self.ASSET_ROOTFS)
+ disk = self.scratch_file('scratch.qcow2')
+ qemu_img = get_qemu_img(self)
+ check_call([qemu_img, 'create', '-f', 'qcow2', '-b', raw_disk,
+ '-F', 'raw', disk], stdout=DEVNULL, stderr=DEVNULL)
+
+ args = ('-drive', 'file=%s,snapshot=on,id=hd0,if=none' % disk,
+ '-drive', 'driver=blkreplay,id=hd0-rr,if=none,image=hd0',
+ '-device', '%s,drive=hd0-rr' % blkdevice,
+ '-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22',
+ '-device', 'virtio-net,netdev=vnet',
+ '-object', 'filter-replay,id=replay,netdev=vnet')
+
+ kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
+ f"console=ttyS0 root=/dev/{devroot}")
+ console_pattern = 'Welcome to TuxTest'
+ self.run_rr(kernel_path, kernel_command_line, console_pattern, shift=5,
+ args=args)
+
+ @skipFlakyTest('https://gitlab.com/qemu-project/qemu/-/issues/2094')
+ def test_pc(self):
+ self.do_test_x86('pc', 'virtio-blk', 'vda')
+
+ def test_q35(self):
+ self.do_test_x86('q35', 'ide-hd', 'sda')
+
+
+if __name__ == '__main__':
+ ReplayKernelBase.main()
diff --git a/tests/functional/x86_64/test_reverse_debug.py b/tests/functional/x86_64/test_reverse_debug.py
new file mode 100755
index 0000000..2b31ae8
--- /dev/null
+++ b/tests/functional/x86_64/test_reverse_debug.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python3
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Reverse debugging test for x86_64
+#
+# Copyright (c) 2020 ISP RAS
+# Copyright (c) 2025 Linaro Limited
+#
+# Author:
+# Pavel Dovgalyuk <Pavel.Dovgalyuk@ispras.ru>
+# Gustavo Romero <gustavo.romero@linaro.org> (Run without Avocado)
+#
+# This work is licensed under the terms of the GNU GPL, version 2 or
+# later. See the COPYING file in the top-level directory.
+
+from qemu_test import skipFlakyTest
+from reverse_debugging import ReverseDebugging
+
+
+class ReverseDebugging_X86_64(ReverseDebugging):
+
+ @skipFlakyTest("https://gitlab.com/qemu-project/qemu/-/issues/2922")
+ def test_x86_64_pc(self):
+ self.set_machine('pc')
+ # start with BIOS only
+ self.reverse_debugging(gdb_arch='x86-64')
+
+
+if __name__ == '__main__':
+ ReverseDebugging.main()
diff --git a/tests/functional/test_x86_64_tuxrun.py b/tests/functional/x86_64/test_tuxrun.py
index fcbc62b..fcbc62b 100755
--- a/tests/functional/test_x86_64_tuxrun.py
+++ b/tests/functional/x86_64/test_tuxrun.py
diff --git a/tests/functional/x86_64/test_vfio_user_client.py b/tests/functional/x86_64/test_vfio_user_client.py
new file mode 100755
index 0000000..8bc16e5
--- /dev/null
+++ b/tests/functional/x86_64/test_vfio_user_client.py
@@ -0,0 +1,201 @@
+#!/usr/bin/env python3
+#
+# Copyright (c) 2025 Nutanix, Inc.
+#
+# Author:
+# Mark Cave-Ayland <mark.caveayland@nutanix.com>
+# John Levon <john.levon@nutanix.com>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+"""
+Check basic vfio-user-pci client functionality. The test starts two VMs:
+
+ - the server VM runs the libvfio-user "gpio" example server inside it,
+ piping vfio-user traffic between a local UNIX socket and a virtio-serial
+ port. On the host, the virtio-serial port is backed by a local socket.
+
+ - the client VM loads the gpio-pci-idio-16 kernel module, with the
+ vfio-user client connecting to the above local UNIX socket.
+
+This way, we don't depend on trying to run a vfio-user server on the host
+itself.
+
+Once both VMs are running, we run some basic configuration on the gpio device
+and verify that the server is logging the expected out. As this is consistent
+given the same VM images, we just do a simple direct comparison.
+"""
+
+import os
+
+from qemu_test import Asset
+from qemu_test import QemuSystemTest
+from qemu_test import exec_command_and_wait_for_pattern
+from qemu_test import wait_for_console_pattern
+
+# Exact output can vary, so we just sample for some expected lines.
+EXPECTED_SERVER_LINES = [
+ "gpio: adding DMA region [0, 0xc0000) offset=0 flags=0x3",
+ "gpio: devinfo flags 0x3, num_regions 9, num_irqs 5",
+ "gpio: region_info[0] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[1] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[2] offset 0 flags 0x3 size 256 argsz 32",
+ "gpio: region_info[3] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[4] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[5] offset 0 flags 0 size 0 argsz 32",
+ "gpio: region_info[7] offset 0 flags 0x3 size 256 argsz 32",
+ "gpio: region7: read 256 bytes at 0",
+ "gpio: region7: read 0 from (0x30:4)",
+ "gpio: cleared EROM",
+ "gpio: I/O space enabled",
+ "gpio: memory space enabled",
+ "gpio: SERR# enabled",
+ "gpio: region7: wrote 0x103 to (0x4:2)",
+ "gpio: I/O space enabled",
+ "gpio: memory space enabled",
+]
+
+class VfioUserClient(QemuSystemTest):
+ """vfio-user testing class."""
+
+ ASSET_REPO = 'https://github.com/mcayland-ntx/libvfio-user-test'
+
+ ASSET_KERNEL = Asset(
+ f'{ASSET_REPO}/raw/refs/heads/main/images/bzImage',
+ '40292fa6ce95d516e26bccf5974e138d0db65a6de0bc540cabae060fe9dea605'
+ )
+
+ ASSET_ROOTFS = Asset(
+ f'{ASSET_REPO}/raw/refs/heads/main/images/rootfs.ext2',
+ 'e1e3abae8aebb8e6e77f08b1c531caeacf46250c94c815655c6bbea59fc3d1c1'
+ )
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ self.kernel_path = None
+ self.rootfs_path = None
+
+ def configure_server_vm_args(self, server_vm, sock_path):
+ """
+ Configuration for the server VM. Set up virtio-serial device backed by
+ the given socket path.
+ """
+ server_vm.add_args('-kernel', self.kernel_path)
+ server_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
+ server_vm.add_args('-drive',
+ f"file={self.rootfs_path},if=ide,format=raw,id=drv0")
+ server_vm.add_args('-snapshot')
+ server_vm.add_args('-chardev',
+ f"socket,id=sock0,path={sock_path},telnet=off,server=on,wait=off")
+ server_vm.add_args('-device', 'virtio-serial')
+ server_vm.add_args('-device',
+ 'virtserialport,chardev=sock0,name=org.fedoraproject.port.0')
+
+ def configure_client_vm_args(self, client_vm, sock_path):
+ """
+ Configuration for the client VM. Point the vfio-user-pci device to the
+ socket path configured above.
+ """
+
+ client_vm.add_args('-kernel', self.kernel_path)
+ client_vm.add_args('-append', 'console=ttyS0 root=/dev/sda')
+ client_vm.add_args('-drive',
+ f'file={self.rootfs_path},if=ide,format=raw,id=drv0')
+ client_vm.add_args('-snapshot')
+ client_vm.add_args('-device',
+ '{"driver":"vfio-user-pci",' +
+ '"socket":{"path": "%s", "type": "unix"}}' % sock_path)
+
+ def setup_vfio_user_pci_server(self, server_vm):
+ """
+ Start the libvfio-user server within the server VM, and arrange
+ for data to shuttle between its socket and the virtio serial port.
+ """
+ wait_for_console_pattern(self, 'login:', None, server_vm)
+ exec_command_and_wait_for_pattern(self, 'root', '#', None, server_vm)
+
+ exec_command_and_wait_for_pattern(self,
+ 'gpio-pci-idio-16 -v /tmp/vfio-user.sock >/var/tmp/gpio.out 2>&1 &',
+ '#', None, server_vm)
+
+ # wait for libvfio-user socket to appear
+ while True:
+ out = exec_command_and_wait_for_pattern(self,
+ 'ls --color=no /tmp/vfio-user.sock', '#', None, server_vm)
+ ls_out = out.decode().splitlines()[1].strip()
+ if ls_out == "/tmp/vfio-user.sock":
+ break
+
+ exec_command_and_wait_for_pattern(self,
+ 'socat UNIX-CONNECT:/tmp/vfio-user.sock /dev/vport0p1,ignoreeof ' +
+ ' &', '#', None, server_vm)
+
+ def test_vfio_user_pci(self):
+ """Run basic sanity test."""
+
+ self.set_machine('pc')
+ self.require_device('virtio-serial')
+ self.require_device('vfio-user-pci')
+
+ self.kernel_path = self.ASSET_KERNEL.fetch()
+ self.rootfs_path = self.ASSET_ROOTFS.fetch()
+
+ sock_dir = self.socket_dir()
+ socket_path = os.path.join(sock_dir.name, 'vfio-user.sock')
+
+ server_vm = self.get_vm(name='server')
+ server_vm.set_console()
+ self.configure_server_vm_args(server_vm, socket_path)
+
+ server_vm.launch()
+
+ self.log.debug('starting libvfio-user server')
+
+ self.setup_vfio_user_pci_server(server_vm)
+
+ client_vm = self.get_vm(name="client")
+ client_vm.set_console()
+ self.configure_client_vm_args(client_vm, socket_path)
+
+ try:
+ client_vm.launch()
+ except:
+ self.log.error('client VM failed to start, dumping server logs')
+ exec_command_and_wait_for_pattern(self, 'cat /var/tmp/gpio.out',
+ '#', None, server_vm)
+ raise
+
+ self.log.debug('waiting for client VM boot')
+
+ wait_for_console_pattern(self, 'login:', None, client_vm)
+ exec_command_and_wait_for_pattern(self, 'root', '#', None, client_vm)
+
+ #
+ # Here, we'd like to actually interact with the gpio device a little
+ # more as described at:
+ #
+ # https://github.com/nutanix/libvfio-user/blob/master/docs/qemu.md
+ #
+ # Unfortunately, the buildroot Linux kernel has some undiagnosed issue
+ # so we don't get /sys/class/gpio. Nonetheless just the basic
+ # initialization and setup is enough for basic testing of vfio-user.
+ #
+
+ self.log.debug('collecting libvfio-user server output')
+
+ out = exec_command_and_wait_for_pattern(self,
+ 'cat /var/tmp/gpio.out',
+ 'gpio: region2: wrote 0 to (0x1:1)',
+ None, server_vm)
+
+ gpio_server_out = [s for s in out.decode().splitlines()
+ if s.startswith("gpio:")]
+
+ for line in EXPECTED_SERVER_LINES:
+ if line not in gpio_server_out:
+ self.log.error(f'Missing server debug line: {line}')
+ self.fail(False)
+
+
+if __name__ == '__main__':
+ QemuSystemTest.main()
diff --git a/tests/functional/test_virtio_balloon.py b/tests/functional/x86_64/test_virtio_balloon.py
index 5877b6c..5877b6c 100755
--- a/tests/functional/test_virtio_balloon.py
+++ b/tests/functional/x86_64/test_virtio_balloon.py
diff --git a/tests/functional/test_virtio_gpu.py b/tests/functional/x86_64/test_virtio_gpu.py
index 81c9156..be96de2 100755
--- a/tests/functional/test_virtio_gpu.py
+++ b/tests/functional/x86_64/test_virtio_gpu.py
@@ -108,6 +108,7 @@ class VirtioGPUx86(QemuSystemTest):
shell=False,
close_fds=False,
)
+ self._vug_log_file.close()
self.vm.set_console()
self.vm.add_args("-cpu", "host")
@@ -135,6 +136,7 @@ class VirtioGPUx86(QemuSystemTest):
"features: +virgl +edid")
self.vm.shutdown()
qemu_sock.close()
+ vug_sock.close()
vugp.terminate()
vugp.wait()
diff --git a/tests/functional/test_virtio_version.py b/tests/functional/x86_64/test_virtio_version.py
index a5ea732..a5ea732 100755
--- a/tests/functional/test_virtio_version.py
+++ b/tests/functional/x86_64/test_virtio_version.py
diff --git a/tests/functional/xtensa/meson.build b/tests/functional/xtensa/meson.build
new file mode 100644
index 0000000..d61d82a
--- /dev/null
+++ b/tests/functional/xtensa/meson.build
@@ -0,0 +1,6 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+tests_xtensa_system_thorough = [
+ 'lx60',
+ 'replay',
+]
diff --git a/tests/functional/test_xtensa_lx60.py b/tests/functional/xtensa/test_lx60.py
index 147c920..147c920 100755
--- a/tests/functional/test_xtensa_lx60.py
+++ b/tests/functional/xtensa/test_lx60.py
diff --git a/tests/functional/test_xtensa_replay.py b/tests/functional/xtensa/test_replay.py
index eb00a3b..eb00a3b 100755
--- a/tests/functional/test_xtensa_replay.py
+++ b/tests/functional/xtensa/test_replay.py