* Bump Avocado to version 103
* Introduce new functional test framework for Python-based tests * Convert many Avocado tests to the new functional test framework -----BEGIN PGP SIGNATURE----- iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmbYOEsRHHRodXRoQHJl ZGhhdC5jb20ACgkQLtnXdP5wLbUDAA/+Kdlak/nCrK5gXDyDasfy86IxgMD0QlDR U0MOpQyfXbM2EJjwCUhmgo8pui8qV23dKzfCwbDmkjB7mJ+yKi2ZdiFEp6onq/ke aAdaaZwENtWcFglRD80TOSQX6oyeNmE/PuvJGG0BfwWXyyhaEa6kCdytEPORipQs lZ+ZndHgXtcM3roXtgI3kp2V1nY5LLCJ044UrasKRq2xWfD/Ken90uWP5/nMLV7f 7YLRUIb0sgV7IdjZiT1UkXJZRB7MatV7+OsojYbG8BPbQEvXqpryXMIeygHVR9a0 yxNDUpTZR6JoS1IaLKkHh1mTM+L1JpFltKadKkXa0zqJHHSur7Tp0xVO/GeqCek4 9N8K4zw2CoO/AKmN8JjW5i4GnMrFMdcvxxNwLdRoVgYt4YA731wnHrbosXZOXcuv H0z8Tm6ueKvfBtrQErdvqsGrP/8FUYRqZP4H6XaaC+wEis++7OmVR2nlQ/gAyr6/ mMJtmxqVHCIcEVjDu1jYltrW3BN2CcxN2M9gxyOScq2/Xmzqtaeb4iyjxeCUjIBW Pc4LXlSafIg3hPrdH3EKN275ev8cx/5jp8oEgXD5We25Mj3W930zde6/STXoX318 NVNlbrIQjGjQN7rN5oxTFxTlIN8ax2tuuzpQDFvS/4bLyMYXcZ4I5gUrM5tvWTGv +0UN45pJ7Nk= =l6Ki -----END PGP SIGNATURE----- Merge tag 'pull-request-2024-09-04' of https://gitlab.com/thuth/qemu into staging * Bump Avocado to version 103 * Introduce new functional test framework for Python-based tests * Convert many Avocado tests to the new functional test framework # -----BEGIN PGP SIGNATURE----- # # iQJFBAABCAAvFiEEJ7iIR+7gJQEY8+q5LtnXdP5wLbUFAmbYOEsRHHRodXRoQHJl # ZGhhdC5jb20ACgkQLtnXdP5wLbUDAA/+Kdlak/nCrK5gXDyDasfy86IxgMD0QlDR # U0MOpQyfXbM2EJjwCUhmgo8pui8qV23dKzfCwbDmkjB7mJ+yKi2ZdiFEp6onq/ke # aAdaaZwENtWcFglRD80TOSQX6oyeNmE/PuvJGG0BfwWXyyhaEa6kCdytEPORipQs # lZ+ZndHgXtcM3roXtgI3kp2V1nY5LLCJ044UrasKRq2xWfD/Ken90uWP5/nMLV7f # 7YLRUIb0sgV7IdjZiT1UkXJZRB7MatV7+OsojYbG8BPbQEvXqpryXMIeygHVR9a0 # yxNDUpTZR6JoS1IaLKkHh1mTM+L1JpFltKadKkXa0zqJHHSur7Tp0xVO/GeqCek4 # 9N8K4zw2CoO/AKmN8JjW5i4GnMrFMdcvxxNwLdRoVgYt4YA731wnHrbosXZOXcuv # H0z8Tm6ueKvfBtrQErdvqsGrP/8FUYRqZP4H6XaaC+wEis++7OmVR2nlQ/gAyr6/ # mMJtmxqVHCIcEVjDu1jYltrW3BN2CcxN2M9gxyOScq2/Xmzqtaeb4iyjxeCUjIBW # Pc4LXlSafIg3hPrdH3EKN275ev8cx/5jp8oEgXD5We25Mj3W930zde6/STXoX318 # NVNlbrIQjGjQN7rN5oxTFxTlIN8ax2tuuzpQDFvS/4bLyMYXcZ4I5gUrM5tvWTGv # +0UN45pJ7Nk= # =l6Ki # -----END PGP SIGNATURE----- # gpg: Signature made Wed 04 Sep 2024 11:36:59 BST # gpg: using RSA key 27B88847EEE0250118F3EAB92ED9D774FE702DB5 # gpg: issuer "thuth@redhat.com" # gpg: Good signature from "Thomas Huth <th.huth@gmx.de>" [full] # gpg: aka "Thomas Huth <thuth@redhat.com>" [full] # gpg: aka "Thomas Huth <huth@tuxfamily.org>" [full] # gpg: aka "Thomas Huth <th.huth@posteo.de>" [unknown] # Primary key fingerprint: 27B8 8847 EEE0 2501 18F3 EAB9 2ED9 D774 FE70 2DB5 * tag 'pull-request-2024-09-04' of https://gitlab.com/thuth/qemu: (42 commits) docs/devel/testing: Add documentation for functional tests docs/devel/testing: Rename avocado_qemu.Test class docs/devel/testing: Split the Avocado documentation into a separate file docs/devel: Split testing docs from the build docs and move to separate folder gitlab-ci: Add "check-functional" to the build tests tests/avocado: Remove unused QemuUserTest class tests/functional: Convert ARM bFLT linux-user avocado test tests/functional: Add QemuUserTest class tests/functional: Convert mips64el Fuloong2e avocado test (1/2) tests/functional: Convert Aarch64 Virt machine avocado tests tests/functional: Convert Aarch64 SBSA-Ref avocado tests tests/functional: Convert ARM Integrator/CP avocado tests tests/functional: Convert the linux_initrd avocado test into a standalone test tests/functional: Convert the rx_gdbsim avocado test into a standalone test tests/functional: Convert the acpi-bits test into a standalone test tests/functional: Convert the m68k nextcube test with tesseract tests/functional: Convert the ppc_hv avocado test into a standalone test tests/functional: Convert the ppc_amiga avocado test into a standalone test tests/functional: Convert most ppc avocado tests into standalone tests tests/functional: Convert the virtio_gpu avocado test into a standalone test ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
eabebca69b
@ -59,6 +59,10 @@
|
||||
- cd build
|
||||
- find . -type f -exec touch {} +
|
||||
# Avoid recompiling by hiding ninja with NINJA=":"
|
||||
# We also have to pre-cache the functional tests manually in this case
|
||||
- if [ "x${QEMU_TEST_CACHE_DIR}" != "x" ]; then
|
||||
$MAKE precache-functional ;
|
||||
fi
|
||||
- $MAKE NINJA=":" $MAKE_CHECK_ARGS
|
||||
|
||||
.native_test_job_template:
|
||||
@ -72,12 +76,13 @@
|
||||
reports:
|
||||
junit: build/meson-logs/testlog.junit.xml
|
||||
|
||||
.avocado_test_job_template:
|
||||
.functional_test_job_template:
|
||||
extends: .common_test_job_template
|
||||
cache:
|
||||
key: "${CI_JOB_NAME}-cache"
|
||||
paths:
|
||||
- ${CI_PROJECT_DIR}/avocado-cache
|
||||
- ${CI_PROJECT_DIR}/functional-cache
|
||||
policy: pull-push
|
||||
artifacts:
|
||||
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
|
||||
@ -86,6 +91,7 @@
|
||||
paths:
|
||||
- build/tests/results/latest/results.xml
|
||||
- build/tests/results/latest/test-results
|
||||
- build/tests/functional/*/*/*.log
|
||||
reports:
|
||||
junit: build/tests/results/latest/results.xml
|
||||
before_script:
|
||||
@ -96,11 +102,13 @@
|
||||
- echo -e '[job.output.testlogs]\nstatuses = ["FAIL", "INTERRUPT"]'
|
||||
>> ~/.config/avocado/avocado.conf
|
||||
- if [ -d ${CI_PROJECT_DIR}/avocado-cache ]; then
|
||||
du -chs ${CI_PROJECT_DIR}/avocado-cache ;
|
||||
du -chs ${CI_PROJECT_DIR}/*-cache ;
|
||||
fi
|
||||
- export AVOCADO_ALLOW_UNTRUSTED_CODE=1
|
||||
- export QEMU_TEST_ALLOW_UNTRUSTED_CODE=1
|
||||
- export QEMU_TEST_CACHE_DIR=${CI_PROJECT_DIR}/functional-cache
|
||||
after_script:
|
||||
- cd build
|
||||
- du -chs ${CI_PROJECT_DIR}/avocado-cache
|
||||
- du -chs ${CI_PROJECT_DIR}/*-cache
|
||||
variables:
|
||||
QEMU_JOB_AVOCADO: 1
|
||||
|
@ -22,14 +22,14 @@ check-system-alpine:
|
||||
IMAGE: alpine
|
||||
MAKE_CHECK_ARGS: check-unit check-qtest
|
||||
|
||||
avocado-system-alpine:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-alpine:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-alpine
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: alpine
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
|
||||
|
||||
build-system-ubuntu:
|
||||
@ -53,14 +53,14 @@ check-system-ubuntu:
|
||||
IMAGE: ubuntu2204
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-system-ubuntu:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-ubuntu:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-ubuntu
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: ubuntu2204
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
AVOCADO_TAGS: arch:alpha arch:microblazeel arch:mips64el
|
||||
|
||||
build-system-debian:
|
||||
@ -85,14 +85,14 @@ check-system-debian:
|
||||
IMAGE: debian
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-system-debian:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-debian:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-debian
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: debian
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
|
||||
|
||||
crash-test-debian:
|
||||
@ -129,14 +129,14 @@ check-system-fedora:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-system-fedora:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-fedora:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-fedora
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
|
||||
arch:riscv32 arch:ppc arch:sparc64
|
||||
|
||||
@ -243,14 +243,14 @@ check-system-centos:
|
||||
IMAGE: centos9
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-system-centos:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-centos:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-centos
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: centos9
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
AVOCADO_TAGS: arch:ppc64 arch:or1k arch:s390x arch:x86_64 arch:rx
|
||||
arch:sh4
|
||||
|
||||
@ -274,14 +274,14 @@ check-system-opensuse:
|
||||
IMAGE: opensuse-leap
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-system-opensuse:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-opensuse:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-opensuse
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: opensuse-leap
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64
|
||||
|
||||
#
|
||||
@ -302,15 +302,15 @@ build-system-flaky:
|
||||
ppc64-softmmu rx-softmmu s390x-softmmu sh4-softmmu x86_64-softmmu
|
||||
MAKE_CHECK_ARGS: check-build
|
||||
|
||||
avocado-system-flaky:
|
||||
extends: .avocado_test_job_template
|
||||
functional-system-flaky:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-system-flaky
|
||||
artifacts: true
|
||||
allow_failure: true
|
||||
variables:
|
||||
IMAGE: debian
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
QEMU_JOB_OPTIONAL: 1
|
||||
QEMU_TEST_FLAKY_TESTS: 1
|
||||
AVOCADO_TAGS: flaky
|
||||
@ -485,14 +485,14 @@ check-cfi-aarch64:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-cfi-aarch64:
|
||||
extends: .avocado_test_job_template
|
||||
functional-cfi-aarch64:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-cfi-aarch64
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
|
||||
build-cfi-ppc64-s390x:
|
||||
extends:
|
||||
@ -523,14 +523,14 @@ check-cfi-ppc64-s390x:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-cfi-ppc64-s390x:
|
||||
extends: .avocado_test_job_template
|
||||
functional-cfi-ppc64-s390x:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-cfi-ppc64-s390x
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
|
||||
build-cfi-x86_64:
|
||||
extends:
|
||||
@ -557,14 +557,14 @@ check-cfi-x86_64:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check
|
||||
|
||||
avocado-cfi-x86_64:
|
||||
extends: .avocado_test_job_template
|
||||
functional-cfi-x86_64:
|
||||
extends: .functional_test_job_template
|
||||
needs:
|
||||
- job: build-cfi-x86_64
|
||||
artifacts: true
|
||||
variables:
|
||||
IMAGE: fedora
|
||||
MAKE_CHECK_ARGS: check-avocado
|
||||
MAKE_CHECK_ARGS: check-avocado check-functional
|
||||
|
||||
tsan-build:
|
||||
extends: .native_build_job_template
|
||||
|
63
MAINTAINERS
63
MAINTAINERS
@ -222,7 +222,7 @@ S: Maintained
|
||||
F: docs/system/target-avr.rst
|
||||
F: gdb-xml/avr-cpu.xml
|
||||
F: target/avr/
|
||||
F: tests/avocado/machine_avr6.py
|
||||
F: tests/functional/test_avr_mega2560.py
|
||||
|
||||
CRIS TCG CPUs
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
@ -266,7 +266,7 @@ M: Song Gao <gaosong@loongson.cn>
|
||||
S: Maintained
|
||||
F: target/loongarch/
|
||||
F: tests/tcg/loongarch64/
|
||||
F: tests/avocado/machine_loongarch.py
|
||||
F: tests/functional/test_loongarch64_virt.py
|
||||
|
||||
M68K TCG CPUs
|
||||
M: Laurent Vivier <laurent@vivier.eu>
|
||||
@ -318,6 +318,7 @@ F: configs/devices/ppc*
|
||||
F: docs/system/ppc/embedded.rst
|
||||
F: docs/system/target-ppc.rst
|
||||
F: tests/tcg/ppc*/*
|
||||
F: tests/functional/test_ppc_74xx.py
|
||||
|
||||
RISC-V TCG CPUs
|
||||
M: Palmer Dabbelt <palmer@dabbelt.com>
|
||||
@ -734,7 +735,7 @@ S: Odd Fixes
|
||||
F: include/hw/arm/digic.h
|
||||
F: hw/*/digic*
|
||||
F: include/hw/*/digic*
|
||||
F: tests/avocado/machine_arm_canona1100.py
|
||||
F: tests/functional/test_arm_canona1100.py
|
||||
F: docs/system/arm/digic.rst
|
||||
|
||||
Goldfish RTC
|
||||
@ -785,7 +786,7 @@ S: Maintained
|
||||
F: hw/arm/integratorcp.c
|
||||
F: hw/misc/arm_integrator_debug.c
|
||||
F: include/hw/misc/arm_integrator_debug.h
|
||||
F: tests/avocado/machine_arm_integratorcp.py
|
||||
F: tests/functional/test_arm_integratorcp.py
|
||||
F: docs/system/arm/integratorcp.rst
|
||||
|
||||
MCIMX6UL EVK / i.MX6ul
|
||||
@ -971,7 +972,7 @@ F: hw/misc/sbsa_ec.c
|
||||
F: hw/watchdog/sbsa_gwdt.c
|
||||
F: include/hw/watchdog/sbsa_gwdt.h
|
||||
F: docs/system/arm/sbsa.rst
|
||||
F: tests/avocado/machine_aarch64_sbsaref.py
|
||||
F: tests/functional/test_aarch64_sbsaref.py
|
||||
|
||||
Sharp SL-5500 (Collie) PDA
|
||||
M: Peter Maydell <peter.maydell@linaro.org>
|
||||
@ -1023,7 +1024,7 @@ S: Maintained
|
||||
F: hw/arm/virt*
|
||||
F: include/hw/arm/virt.h
|
||||
F: docs/system/arm/virt.rst
|
||||
F: tests/avocado/machine_aarch64_virt.py
|
||||
F: tests/functional/test_aarch64_virt.py
|
||||
|
||||
Xilinx Zynq
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
@ -1283,6 +1284,7 @@ S: Odd Fixes
|
||||
F: hw/m68k/next-*.c
|
||||
F: hw/display/next-fb.c
|
||||
F: include/hw/m68k/next-cube.h
|
||||
F: tests/functional/test_m68k_nextcube.py
|
||||
|
||||
q800
|
||||
M: Laurent Vivier <laurent@vivier.eu>
|
||||
@ -1330,7 +1332,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
S: Maintained
|
||||
F: hw/microblaze/petalogix_s3adsp1800_mmu.c
|
||||
F: include/hw/char/xilinx_uartlite.h
|
||||
F: tests/avocado/machine_microblaze.py
|
||||
F: tests/functional/test_microblaze*.py
|
||||
|
||||
petalogix_ml605
|
||||
M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
@ -1383,7 +1385,7 @@ S: Odd Fixes
|
||||
F: hw/mips/fuloong2e.c
|
||||
F: hw/pci-host/bonito.c
|
||||
F: include/hw/pci-host/bonito.h
|
||||
F: tests/avocado/machine_mips_fuloong2e.py
|
||||
F: tests/functional/test_mips64el_fuloong2e.py
|
||||
|
||||
Loongson-3 virtual platforms
|
||||
M: Huacai Chen <chenhuacai@kernel.org>
|
||||
@ -1398,7 +1400,7 @@ F: hw/mips/loongson3_virt.c
|
||||
F: include/hw/intc/loongson_ipi_common.h
|
||||
F: include/hw/intc/loongson_ipi.h
|
||||
F: include/hw/intc/loongson_liointc.h
|
||||
F: tests/avocado/machine_mips_loongson3v.py
|
||||
F: tests/functional/test_mips64el_loongson3v.py
|
||||
|
||||
Boston
|
||||
M: Paul Burton <paulburton@kernel.org>
|
||||
@ -1424,14 +1426,14 @@ PowerPC Machines
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Orphan
|
||||
F: hw/ppc/ppc405*
|
||||
F: tests/avocado/ppc_405.py
|
||||
F: tests/functional/test_ppc_405.py
|
||||
|
||||
Bamboo
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Orphan
|
||||
F: hw/ppc/ppc440_bamboo.c
|
||||
F: hw/pci-host/ppc4xx_pci.c
|
||||
F: tests/avocado/ppc_bamboo.py
|
||||
F: tests/functional/test_ppc_bamboo.py
|
||||
|
||||
e500
|
||||
L: qemu-ppc@nongnu.org
|
||||
@ -1454,7 +1456,7 @@ L: qemu-ppc@nongnu.org
|
||||
S: Orphan
|
||||
F: hw/ppc/mpc8544ds.c
|
||||
F: hw/ppc/mpc8544_guts.c
|
||||
F: tests/avocado/ppc_mpc8544ds.py
|
||||
F: tests/functional/test_ppc_mpc8544ds.py
|
||||
|
||||
New World (mac99)
|
||||
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk>
|
||||
@ -1507,7 +1509,7 @@ F: hw/dma/i82374.c
|
||||
F: hw/rtc/m48t59-isa.c
|
||||
F: include/hw/isa/pc87312.h
|
||||
F: include/hw/rtc/m48t59.h
|
||||
F: tests/avocado/ppc_prep_40p.py
|
||||
F: tests/functional/test_ppc_40p.py
|
||||
|
||||
sPAPR (pseries)
|
||||
M: Nicholas Piggin <npiggin@gmail.com>
|
||||
@ -1531,8 +1533,8 @@ F: tests/qtest/spapr*
|
||||
F: tests/qtest/libqos/*spapr*
|
||||
F: tests/qtest/rtas*
|
||||
F: tests/qtest/libqos/rtas*
|
||||
F: tests/avocado/ppc_pseries.py
|
||||
F: tests/avocado/ppc_hv_tests.py
|
||||
F: tests/functional/test_ppc64_pseries.py
|
||||
F: tests/functional/test_ppc64_hv.py
|
||||
|
||||
PowerNV (Non-Virtualized)
|
||||
M: Cédric Le Goater <clg@kaod.org>
|
||||
@ -1549,6 +1551,7 @@ F: include/hw/ppc/pnv*
|
||||
F: include/hw/pci-host/pnv*
|
||||
F: pc-bios/skiboot.lid
|
||||
F: tests/qtest/pnv*
|
||||
F: tests/functional/test_ppc64_powernv.py
|
||||
|
||||
pca955x
|
||||
M: Glenn Miles <milesg@linux.ibm.com>
|
||||
@ -1563,7 +1566,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
|
||||
L: qemu-ppc@nongnu.org
|
||||
S: Odd Fixes
|
||||
F: hw/ppc/virtex_ml507.c
|
||||
F: tests/avocado/ppc_virtex_ml507.py
|
||||
F: tests/functional/test_ppc_virtex_ml507.py
|
||||
|
||||
sam460ex
|
||||
M: BALATON Zoltan <balaton@eik.bme.hu>
|
||||
@ -1596,6 +1599,7 @@ S: Maintained
|
||||
F: hw/ppc/amigaone.c
|
||||
F: hw/pci-host/articia.c
|
||||
F: include/hw/pci-host/articia.h
|
||||
F: tests/functional/test_ppc_amiga.py
|
||||
|
||||
Virtual Open Firmware (VOF)
|
||||
M: Alexey Kardashevskiy <aik@ozlabs.ru>
|
||||
@ -1662,7 +1666,7 @@ R: Yoshinori Sato <ysato@users.sourceforge.jp>
|
||||
S: Orphan
|
||||
F: docs/system/target-rx.rst
|
||||
F: hw/rx/rx-gdbsim.c
|
||||
F: tests/avocado/machine_rx_gdbsim.py
|
||||
F: tests/functional/test_rx_gdbsim.py
|
||||
|
||||
SH4 Machines
|
||||
------------
|
||||
@ -1717,7 +1721,7 @@ F: include/hw/pci-host/sabre.h
|
||||
F: hw/pci-bridge/simba.c
|
||||
F: include/hw/pci-bridge/simba.h
|
||||
F: pc-bios/openbios-sparc64
|
||||
F: tests/avocado/machine_sparc64_sun4u.py
|
||||
F: tests/functional/test_sparc64_sun4u.py
|
||||
|
||||
Sun4v
|
||||
M: Artyom Tarasenko <atar4qemu@gmail.com>
|
||||
@ -1744,7 +1748,7 @@ S: Supported
|
||||
F: hw/s390x/
|
||||
F: include/hw/s390x/
|
||||
F: configs/devices/s390x-softmmu/default.mak
|
||||
F: tests/avocado/machine_s390_ccw_virtio.py
|
||||
F: tests/functional/test_s390x_ccw_virtio.py
|
||||
T: git https://github.com/borntraeger/qemu.git s390-next
|
||||
L: qemu-s390x@nongnu.org
|
||||
|
||||
@ -1807,7 +1811,7 @@ F: hw/s390x/cpu-topology.c
|
||||
F: target/s390x/kvm/stsi-topology.c
|
||||
F: docs/devel/s390-cpu-topology.rst
|
||||
F: docs/system/s390x/cpu-topology.rst
|
||||
F: tests/avocado/s390_topology.py
|
||||
F: tests/functional/test_s390x_topology.py
|
||||
|
||||
X86 Machines
|
||||
------------
|
||||
@ -1835,6 +1839,9 @@ F: hw/isa/apm.c
|
||||
F: include/hw/isa/apm.h
|
||||
F: tests/unit/test-x86-topo.c
|
||||
F: tests/qtest/test-x86-cpuid-compat.c
|
||||
F: tests/functional/test_mem_addr_space.py
|
||||
F: tests/functional/test_pc_cpu_hotplug_props.py
|
||||
F: tests/functional/test_x86_cpu_model_versions.py
|
||||
|
||||
PC Chipset
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
@ -1901,6 +1908,8 @@ F: include/hw/boards.h
|
||||
F: include/hw/core/cpu.h
|
||||
F: include/hw/cpu/cluster.h
|
||||
F: include/sysemu/numa.h
|
||||
F: tests/functional/test_cpu_queries.py
|
||||
F: tests/functional/test_empty_cpu_model.py
|
||||
F: tests/unit/test-smp-parse.c
|
||||
T: git https://gitlab.com/ehabkost/qemu.git machine-next
|
||||
|
||||
@ -2067,8 +2076,8 @@ ACPI/AVOCADO/BIOSBITS
|
||||
M: Ani Sinha <anisinha@redhat.com>
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
S: Supported
|
||||
F: tests/avocado/acpi-bits/*
|
||||
F: tests/avocado/acpi-bits.py
|
||||
F: tests/functional/acpi-bits/*
|
||||
F: tests/functional/test_acpi_bits.py
|
||||
F: docs/devel/acpi-bits.rst
|
||||
|
||||
ACPI/HEST/GHES
|
||||
@ -2105,6 +2114,7 @@ S: Odd Fixes
|
||||
F: hw/net/
|
||||
F: include/hw/net/
|
||||
F: tests/qtest/virtio-net-test.c
|
||||
F: tests/functional/test_info_usernet.py
|
||||
F: docs/virtio-net-failover.rst
|
||||
T: git https://github.com/jasowang/qemu.git net
|
||||
|
||||
@ -2240,6 +2250,7 @@ F: net/vhost-user.c
|
||||
F: include/hw/virtio/
|
||||
F: docs/devel/virtio*
|
||||
F: docs/devel/migration/virtio.rst
|
||||
F: tests/functional/test_virtio_version.py
|
||||
|
||||
virtio-balloon
|
||||
M: Michael S. Tsirkin <mst@redhat.com>
|
||||
@ -2490,7 +2501,7 @@ R: Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>
|
||||
S: Maintained
|
||||
F: docs/system/devices/igb.rst
|
||||
F: hw/net/igb*
|
||||
F: tests/avocado/netdev-ethtool.py
|
||||
F: tests/functional/test_netdev_ethtool.py
|
||||
F: tests/qtest/igb-test.c
|
||||
F: tests/qtest/libqos/igb.c
|
||||
|
||||
@ -2973,6 +2984,7 @@ S: Supported
|
||||
F: include/qemu/option.h
|
||||
F: tests/unit/test-keyval.c
|
||||
F: tests/unit/test-qemu-opts.c
|
||||
F: tests/functional/test_version.py
|
||||
F: util/keyval.c
|
||||
F: util/qemu-option.c
|
||||
|
||||
@ -4148,6 +4160,11 @@ F: .gitlab-ci.d/cirrus/freebsd*
|
||||
F: tests/vm/freebsd
|
||||
W: https://cirrus-ci.com/github/qemu/qemu
|
||||
|
||||
Functional testing framework
|
||||
M: Thomas Huth <thuth@redhat.com>
|
||||
R: Philippe Mathieu-Daudé <philmd@linaro.org>
|
||||
F: tests/functional/qemu_test/
|
||||
|
||||
Windows Hosted Continuous Integration
|
||||
M: Yonggang Luo <luoyonggang@gmail.com>
|
||||
S: Maintained
|
||||
|
@ -1,9 +1,8 @@
|
||||
QEMU Build and Test System
|
||||
--------------------------
|
||||
QEMU Build System
|
||||
-----------------
|
||||
|
||||
Details about how QEMU's build system works and how it is integrated
|
||||
into our testing infrastructure. You will need to understand some of
|
||||
the basics if you are adding new files and targets to the build.
|
||||
Details about how QEMU's build system works. You will need to understand
|
||||
some of the basics if you are adding new files and targets to the build.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
@ -11,10 +10,5 @@ the basics if you are adding new files and targets to the build.
|
||||
build-system
|
||||
kconfig
|
||||
docs
|
||||
testing
|
||||
acpi-bits
|
||||
qtest
|
||||
ci
|
||||
qapi-code-gen
|
||||
fuzzing
|
||||
control-flow-integrity
|
||||
|
@ -31,6 +31,7 @@ the :ref:`tcg_internals`.
|
||||
|
||||
index-process
|
||||
index-build
|
||||
testing/index
|
||||
index-api
|
||||
index-internals
|
||||
index-tcg
|
||||
|
@ -1,6 +1,6 @@
|
||||
=============================================================================
|
||||
ACPI/SMBIOS avocado tests using biosbits
|
||||
=============================================================================
|
||||
==================================
|
||||
ACPI/SMBIOS testing using biosbits
|
||||
==================================
|
||||
************
|
||||
Introduction
|
||||
************
|
||||
@ -35,7 +35,7 @@ for developing biosbits and its real life uses can be found in [#a]_ and [#b]_.
|
||||
For QEMU, we maintain a fork of bios bits in gitlab along with all the
|
||||
dependent submodules `here <https://gitlab.com/qemu-project/biosbits-bits>`__.
|
||||
This fork contains numerous fixes, a newer acpica and changes specific to
|
||||
running this avocado QEMU tests using bits. The author of this document
|
||||
running these functional QEMU tests using bits. The author of this document
|
||||
is the sole maintainer of the QEMU fork of bios bits repository. For more
|
||||
information, please see author's `FOSDEM talk on this bios-bits based test
|
||||
framework <https://fosdem.org/2024/schedule/event/fosdem-2024-2262-exercising-qemu-generated-acpi-smbios-tables-using-biosbits-from-within-a-guest-vm-/>`__.
|
||||
@ -44,12 +44,12 @@ framework <https://fosdem.org/2024/schedule/event/fosdem-2024-2262-exercising-qe
|
||||
Description of the test framework
|
||||
*********************************
|
||||
|
||||
Under the directory ``tests/avocado/``, ``acpi-bits.py`` is a QEMU avocado
|
||||
test that drives all this.
|
||||
Under the directory ``tests/functional/``, ``test_acpi_bits.py`` is a QEMU
|
||||
functional test that drives all this.
|
||||
|
||||
A brief description of the various test files follows.
|
||||
|
||||
Under ``tests/avocado/`` as the root we have:
|
||||
Under ``tests/functional/`` as the root we have:
|
||||
|
||||
::
|
||||
|
||||
@ -60,12 +60,12 @@ Under ``tests/avocado/`` as the root we have:
|
||||
│ ├── smbios.py2
|
||||
│ ├── testacpi.py2
|
||||
│ └── testcpuid.py2
|
||||
├── acpi-bits.py
|
||||
├── test_acpi_bits.py
|
||||
|
||||
* ``tests/avocado``:
|
||||
* ``tests/functional``:
|
||||
|
||||
``acpi-bits.py``:
|
||||
This is the main python avocado test script that generates a
|
||||
``test_acpi_bits.py``:
|
||||
This is the main python functional test script that generates a
|
||||
biosbits iso. It then spawns a QEMU VM with it, collects the log and reports
|
||||
test failures. This is the script one would be interested in if they wanted
|
||||
to add or change some component of the log parsing, add a new command line
|
||||
@ -79,35 +79,22 @@ Under ``tests/avocado/`` as the root we have:
|
||||
you to inspect and run the specific commands manually.
|
||||
|
||||
In order to run this test, please perform the following steps from the QEMU
|
||||
build directory:
|
||||
build directory (assuming that the sources are in ".."):
|
||||
::
|
||||
|
||||
$ make check-venv (needed only the first time to create the venv)
|
||||
$ ./pyvenv/bin/avocado run -t acpi tests/avocado
|
||||
$ export PYTHONPATH=../python:../tests/functional
|
||||
$ export QEMU_TEST_QEMU_BINARY=$PWD/qemu-system-x86_64
|
||||
$ python3 ../tests/functional/test_acpi_bits.py
|
||||
|
||||
The above will run all acpi avocado tests including this one.
|
||||
In order to run the individual tests, perform the following:
|
||||
::
|
||||
The above will run all acpi-bits functional tests (producing output in
|
||||
tap format).
|
||||
|
||||
$ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py --tap -
|
||||
You can inspect the log files in tests/functional/x86_64/test_acpi_bits.*/
|
||||
for more information about the run or in order to diagnoze issues.
|
||||
If you pass V=1 in the environment, more diagnostic logs will be put into
|
||||
the test log.
|
||||
|
||||
The above will produce output in tap format. You can omit "--tap -" in the
|
||||
end and it will produce output like the following:
|
||||
::
|
||||
|
||||
$ ./pyvenv/bin/avocado run tests/avocado/acpi-bits.py
|
||||
Fetching asset from tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits
|
||||
JOB ID : eab225724da7b64c012c65705dc2fa14ab1defef
|
||||
JOB LOG : /home/anisinha/avocado/job-results/job-2022-10-10T17.58-eab2257/job.log
|
||||
(1/1) tests/avocado/acpi-bits.py:AcpiBitsTest.test_acpi_smbios_bits: PASS (33.09 s)
|
||||
RESULTS : PASS 1 | ERROR 0 | FAIL 0 | SKIP 0 | WARN 0 | INTERRUPT 0 | CANCEL 0
|
||||
JOB TIME : 39.22 s
|
||||
|
||||
You can inspect the log file for more information about the run or in order
|
||||
to diagnoze issues. If you pass V=1 in the environment, more diagnostic logs
|
||||
would be found in the test log.
|
||||
|
||||
* ``tests/avocado/acpi-bits/bits-config``:
|
||||
* ``tests/functional/acpi-bits/bits-config``:
|
||||
|
||||
This location contains biosbits configuration files that determine how the
|
||||
software runs the tests.
|
||||
@ -117,7 +104,7 @@ Under ``tests/avocado/`` as the root we have:
|
||||
or actions are performed by bits. The description of the config options are
|
||||
provided in the file itself.
|
||||
|
||||
* ``tests/avocado/acpi-bits/bits-tests``:
|
||||
* ``tests/functional/acpi-bits/bits-tests``:
|
||||
|
||||
This directory contains biosbits python based tests that are run from within
|
||||
the biosbits environment in the spawned VM. New additions of test cases can
|
||||
@ -155,7 +142,8 @@ Under ``tests/avocado/`` as the root we have:
|
||||
(a) They are python2.7 based scripts and not python 3 scripts.
|
||||
(b) They are run from within the bios bits VM and is not subjected to QEMU
|
||||
build/test python script maintenance and dependency resolutions.
|
||||
(c) They need not be loaded by avocado framework when running tests.
|
||||
(c) They need not be loaded by the test framework by accident when running
|
||||
tests.
|
||||
|
||||
|
||||
Author: Ani Sinha <anisinha@redhat.com>
|
581
docs/devel/testing/avocado.rst
Normal file
581
docs/devel/testing/avocado.rst
Normal file
@ -0,0 +1,581 @@
|
||||
.. _checkavocado-ref:
|
||||
|
||||
|
||||
Integration testing with Avocado
|
||||
================================
|
||||
|
||||
The ``tests/avocado`` directory hosts integration tests. They're usually
|
||||
higher level tests, and may interact with external resources and with
|
||||
various guest operating systems.
|
||||
|
||||
These tests are written using the Avocado Testing Framework (which must be
|
||||
installed separately) in conjunction with a the ``avocado_qemu.QemuSystemTest``
|
||||
class, implemented at ``tests/avocado/avocado_qemu``.
|
||||
|
||||
Tests based on ``avocado_qemu.QemuSystemTest`` can easily:
|
||||
|
||||
* Customize the command line arguments given to the convenience
|
||||
``self.vm`` attribute (a QEMUMachine instance)
|
||||
|
||||
* Interact with the QEMU monitor, send QMP commands and check
|
||||
their results
|
||||
|
||||
* Interact with the guest OS, using the convenience console device
|
||||
(which may be useful to assert the effectiveness and correctness of
|
||||
command line arguments or QMP commands)
|
||||
|
||||
* Interact with external data files that accompany the test itself
|
||||
(see ``self.get_data()``)
|
||||
|
||||
* Download (and cache) remote data files, such as firmware and kernel
|
||||
images
|
||||
|
||||
* Have access to a library of guest OS images (by means of the
|
||||
``avocado.utils.vmimage`` library)
|
||||
|
||||
* Make use of various other test related utilities available at the
|
||||
test class itself and at the utility library:
|
||||
|
||||
- http://avocado-framework.readthedocs.io/en/latest/api/test/avocado.html#avocado.Test
|
||||
- http://avocado-framework.readthedocs.io/en/latest/api/utils/avocado.utils.html
|
||||
|
||||
Running tests
|
||||
-------------
|
||||
|
||||
You can run the avocado tests simply by executing:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado
|
||||
|
||||
This involves the automatic installation, from PyPI, of all the
|
||||
necessary avocado-framework dependencies into the QEMU venv within the
|
||||
build tree (at ``./pyvenv``). Test results are also saved within the
|
||||
build tree (at ``tests/results``).
|
||||
|
||||
Note: the build environment must be using a Python 3 stack, and have
|
||||
the ``venv`` and ``pip`` packages installed. If necessary, make sure
|
||||
``configure`` is called with ``--python=`` and that those modules are
|
||||
available. On Debian and Ubuntu based systems, depending on the
|
||||
specific version, they may be on packages named ``python3-venv`` and
|
||||
``python3-pip``.
|
||||
|
||||
It is also possible to run tests based on tags using the
|
||||
``make check-avocado`` command and the ``AVOCADO_TAGS`` environment
|
||||
variable:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TAGS=quick
|
||||
|
||||
Note that tags separated with commas have an AND behavior, while tags
|
||||
separated by spaces have an OR behavior. For more information on Avocado
|
||||
tags, see:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/tags.html
|
||||
|
||||
To run a single test file, a couple of them, or a test within a file
|
||||
using the ``make check-avocado`` command, set the ``AVOCADO_TESTS``
|
||||
environment variable with the test files or test names. To run all
|
||||
tests from a single file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS=$FILEPATH
|
||||
|
||||
The same is valid to run tests from multiple test files:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS='$FILEPATH1 $FILEPATH2'
|
||||
|
||||
To run a single test within a file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS=$FILEPATH:$TESTCLASS.$TESTNAME
|
||||
|
||||
The same is valid to run single tests from multiple test files:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS='$FILEPATH1:$TESTCLASS1.$TESTNAME1 $FILEPATH2:$TESTCLASS2.$TESTNAME2'
|
||||
|
||||
The scripts installed inside the virtual environment may be used
|
||||
without an "activation". For instance, the Avocado test runner
|
||||
may be invoked by running:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
|
||||
|
||||
Note that if ``make check-avocado`` was not executed before, it is
|
||||
possible to create the Python virtual environment with the dependencies
|
||||
needed running:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-venv
|
||||
|
||||
It is also possible to run tests from a single file or a single test within
|
||||
a test file. To run tests from a single file within the build tree, use:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE
|
||||
|
||||
To run a single test within a test file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
|
||||
|
||||
Valid test names are visible in the output from any previous execution
|
||||
of Avocado or ``make check-avocado``, and can also be queried using:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado list tests/avocado
|
||||
|
||||
Manual Installation
|
||||
-------------------
|
||||
|
||||
To manually install Avocado and its dependencies, run:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install --user avocado-framework
|
||||
|
||||
Alternatively, follow the instructions on this link:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/installing.html
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The ``tests/avocado/avocado_qemu`` directory provides the
|
||||
``avocado_qemu`` Python module, containing the ``avocado_qemu.QemuSystemTest``
|
||||
class. Here's a simple usage example:
|
||||
|
||||
.. code::
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
|
||||
|
||||
class Version(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=quick
|
||||
"""
|
||||
def test_qmp_human_info_version(self):
|
||||
self.vm.launch()
|
||||
res = self.vm.cmd('human-monitor-command',
|
||||
command_line='info version')
|
||||
self.assertRegex(res, r'^(\d+\.\d+\.\d)')
|
||||
|
||||
To execute your test, run:
|
||||
|
||||
.. code::
|
||||
|
||||
avocado run version.py
|
||||
|
||||
Tests may be classified according to a convention by using docstring
|
||||
directives such as ``:avocado: tags=TAG1,TAG2``. To run all tests
|
||||
in the current directory, tagged as "quick", run:
|
||||
|
||||
.. code::
|
||||
|
||||
avocado run -t quick .
|
||||
|
||||
The ``avocado_qemu.QemuSystemTest`` base test class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``avocado_qemu.QemuSystemTest`` class has a number of characteristics
|
||||
that are worth being mentioned right away.
|
||||
|
||||
First of all, it attempts to give each test a ready to use QEMUMachine
|
||||
instance, available at ``self.vm``. Because many tests will tweak the
|
||||
QEMU command line, launching the QEMUMachine (by using ``self.vm.launch()``)
|
||||
is left to the test writer.
|
||||
|
||||
The base test class has also support for tests with more than one
|
||||
QEMUMachine. The way to get machines is through the ``self.get_vm()``
|
||||
method which will return a QEMUMachine instance. The ``self.get_vm()``
|
||||
method accepts arguments that will be passed to the QEMUMachine creation
|
||||
and also an optional ``name`` attribute so you can identify a specific
|
||||
machine and get it more than once through the tests methods. A simple
|
||||
and hypothetical example follows:
|
||||
|
||||
.. code::
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
|
||||
|
||||
class MultipleMachines(QemuSystemTest):
|
||||
def test_multiple_machines(self):
|
||||
first_machine = self.get_vm()
|
||||
second_machine = self.get_vm()
|
||||
self.get_vm(name='third_machine').launch()
|
||||
|
||||
first_machine.launch()
|
||||
second_machine.launch()
|
||||
|
||||
first_res = first_machine.cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
second_res = second_machine.cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
third_res = self.get_vm(name='third_machine').cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
self.assertEqual(first_res, second_res, third_res)
|
||||
|
||||
At test "tear down", ``avocado_qemu.QemuSystemTest`` handles all the
|
||||
QEMUMachines shutdown.
|
||||
|
||||
The ``avocado_qemu.LinuxTest`` base test class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``avocado_qemu.LinuxTest`` is further specialization of the
|
||||
``avocado_qemu.QemuSystemTest`` class, so it contains all the characteristics
|
||||
of the later plus some extra features.
|
||||
|
||||
First of all, this base class is intended for tests that need to
|
||||
interact with a fully booted and operational Linux guest. At this
|
||||
time, it uses a Fedora 31 guest image. The most basic example looks
|
||||
like this:
|
||||
|
||||
.. code::
|
||||
|
||||
from avocado_qemu import LinuxTest
|
||||
|
||||
|
||||
class SomeTest(LinuxTest):
|
||||
|
||||
def test(self):
|
||||
self.launch_and_wait()
|
||||
self.ssh_command('some_command_to_be_run_in_the_guest')
|
||||
|
||||
Please refer to tests that use ``avocado_qemu.LinuxTest`` under
|
||||
``tests/avocado`` for more examples.
|
||||
|
||||
QEMUMachine
|
||||
-----------
|
||||
|
||||
The QEMUMachine API is already widely used in the Python iotests,
|
||||
device-crash-test and other Python scripts. It's a wrapper around the
|
||||
execution of a QEMU binary, giving its users:
|
||||
|
||||
* the ability to set command line arguments to be given to the QEMU
|
||||
binary
|
||||
|
||||
* a ready to use QMP connection and interface, which can be used to
|
||||
send commands and inspect its results, as well as asynchronous
|
||||
events
|
||||
|
||||
* convenience methods to set commonly used command line arguments in
|
||||
a more succinct and intuitive way
|
||||
|
||||
QEMU binary selection
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The QEMU binary used for the ``self.vm`` QEMUMachine instance will
|
||||
primarily depend on the value of the ``qemu_bin`` parameter. If it's
|
||||
not explicitly set, its default value will be the result of a dynamic
|
||||
probe in the same source tree. A suitable binary will be one that
|
||||
targets the architecture matching host machine.
|
||||
|
||||
Based on this description, test writers will usually rely on one of
|
||||
the following approaches:
|
||||
|
||||
1) Set ``qemu_bin``, and use the given binary
|
||||
|
||||
2) Do not set ``qemu_bin``, and use a QEMU binary named like
|
||||
"qemu-system-${arch}", either in the current
|
||||
working directory, or in the current source tree.
|
||||
|
||||
The resulting ``qemu_bin`` value will be preserved in the
|
||||
``avocado_qemu.QemuSystemTest`` as an attribute with the same name.
|
||||
|
||||
Attribute reference
|
||||
-------------------
|
||||
|
||||
Test
|
||||
^^^^
|
||||
|
||||
Besides the attributes and methods that are part of the base
|
||||
``avocado.Test`` class, the following attributes are available on any
|
||||
``avocado_qemu.QemuSystemTest`` instance.
|
||||
|
||||
vm
|
||||
""
|
||||
|
||||
A QEMUMachine instance, initially configured according to the given
|
||||
``qemu_bin`` parameter.
|
||||
|
||||
arch
|
||||
""""
|
||||
|
||||
The architecture can be used on different levels of the stack, e.g. by
|
||||
the framework or by the test itself. At the framework level, it will
|
||||
currently influence the selection of a QEMU binary (when one is not
|
||||
explicitly given).
|
||||
|
||||
Tests are also free to use this attribute value, for their own needs.
|
||||
A test may, for instance, use the same value when selecting the
|
||||
architecture of a kernel or disk image to boot a VM with.
|
||||
|
||||
The ``arch`` attribute will be set to the test parameter of the same
|
||||
name. If one is not given explicitly, it will either be set to
|
||||
``None``, or, if the test is tagged with one (and only one)
|
||||
``:avocado: tags=arch:VALUE`` tag, it will be set to ``VALUE``.
|
||||
|
||||
cpu
|
||||
"""
|
||||
|
||||
The cpu model that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
The ``cpu`` attribute will be set to the test parameter of the same
|
||||
name. If one is not given explicitly, it will either be set to
|
||||
``None ``, or, if the test is tagged with one (and only one)
|
||||
``:avocado: tags=cpu:VALUE`` tag, it will be set to ``VALUE``.
|
||||
|
||||
machine
|
||||
"""""""
|
||||
|
||||
The machine type that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
The ``machine`` attribute will be set to the test parameter of the same
|
||||
name. If one is not given explicitly, it will either be set to
|
||||
``None``, or, if the test is tagged with one (and only one)
|
||||
``:avocado: tags=machine:VALUE`` tag, it will be set to ``VALUE``.
|
||||
|
||||
qemu_bin
|
||||
""""""""
|
||||
|
||||
The preserved value of the ``qemu_bin`` parameter or the result of the
|
||||
dynamic probe for a QEMU binary in the current working directory or
|
||||
source tree.
|
||||
|
||||
LinuxTest
|
||||
^^^^^^^^^
|
||||
|
||||
Besides the attributes present on the ``avocado_qemu.QemuSystemTest`` base
|
||||
class, the ``avocado_qemu.LinuxTest`` adds the following attributes:
|
||||
|
||||
distro
|
||||
""""""
|
||||
|
||||
The name of the Linux distribution used as the guest image for the
|
||||
test. The name should match the **Provider** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_version
|
||||
""""""""""""""
|
||||
|
||||
The version of the Linux distribution as the guest image for the
|
||||
test. The name should match the **Version** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_checksum
|
||||
"""""""""""""""
|
||||
|
||||
The sha256 hash of the guest image file used for the test.
|
||||
|
||||
If this value is not set in the code or by a test parameter (with the
|
||||
same name), no validation on the integrity of the image will be
|
||||
performed.
|
||||
|
||||
Parameter reference
|
||||
-------------------
|
||||
|
||||
To understand how Avocado parameters are accessed by tests, and how
|
||||
they can be passed to tests, please refer to::
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#accessing-test-parameters
|
||||
|
||||
Parameter values can be easily seen in the log files, and will look
|
||||
like the following:
|
||||
|
||||
.. code::
|
||||
|
||||
PARAMS (key=qemu_bin, path=*, default=./qemu-system-x86_64) => './qemu-system-x86_64
|
||||
|
||||
Test
|
||||
^^^^
|
||||
|
||||
arch
|
||||
""""
|
||||
|
||||
The architecture that will influence the selection of a QEMU binary
|
||||
(when one is not explicitly given).
|
||||
|
||||
Tests are also free to use this parameter value, for their own needs.
|
||||
A test may, for instance, use the same value when selecting the
|
||||
architecture of a kernel or disk image to boot a VM with.
|
||||
|
||||
This parameter has a direct relation with the ``arch`` attribute. If
|
||||
not given, it will default to None.
|
||||
|
||||
cpu
|
||||
"""
|
||||
|
||||
The cpu model that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
machine
|
||||
"""""""
|
||||
|
||||
The machine type that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
qemu_bin
|
||||
""""""""
|
||||
|
||||
The exact QEMU binary to be used on QEMUMachine.
|
||||
|
||||
LinuxTest
|
||||
^^^^^^^^^
|
||||
|
||||
Besides the parameters present on the ``avocado_qemu.QemuSystemTest`` base
|
||||
class, the ``avocado_qemu.LinuxTest`` adds the following parameters:
|
||||
|
||||
distro
|
||||
""""""
|
||||
|
||||
The name of the Linux distribution used as the guest image for the
|
||||
test. The name should match the **Provider** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_version
|
||||
""""""""""""""
|
||||
|
||||
The version of the Linux distribution as the guest image for the
|
||||
test. The name should match the **Version** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_checksum
|
||||
"""""""""""""""
|
||||
|
||||
The sha256 hash of the guest image file used for the test.
|
||||
|
||||
If this value is not set in the code or by this parameter no
|
||||
validation on the integrity of the image will be performed.
|
||||
|
||||
Skipping tests
|
||||
--------------
|
||||
|
||||
The Avocado framework provides Python decorators which allow for easily skip
|
||||
tests running under certain conditions. For example, on the lack of a binary
|
||||
on the test system or when the running environment is a CI system. For further
|
||||
information about those decorators, please refer to::
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#skipping-tests
|
||||
|
||||
While the conditions for skipping tests are often specifics of each one, there
|
||||
are recurring scenarios identified by the QEMU developers and the use of
|
||||
environment variables became a kind of standard way to enable/disable tests.
|
||||
|
||||
Here is a list of the most used variables:
|
||||
|
||||
AVOCADO_ALLOW_LARGE_STORAGE
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Tests which are going to fetch or produce assets considered *large* are not
|
||||
going to run unless that ``AVOCADO_ALLOW_LARGE_STORAGE=1`` is exported on
|
||||
the environment.
|
||||
|
||||
The definition of *large* is a bit arbitrary here, but it usually means an
|
||||
asset which occupies at least 1GB of size on disk when uncompressed.
|
||||
|
||||
SPEED
|
||||
^^^^^
|
||||
Tests which have a long runtime will not be run unless ``SPEED=slow`` is
|
||||
exported on the environment.
|
||||
|
||||
The definition of *long* is a bit arbitrary here, and it depends on the
|
||||
usefulness of the test too. A unique test is worth spending more time on,
|
||||
small variations on existing tests perhaps less so. As a rough guide,
|
||||
a test or set of similar tests which take more than 100 seconds to
|
||||
complete.
|
||||
|
||||
AVOCADO_ALLOW_UNTRUSTED_CODE
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
There are tests which will boot a kernel image or firmware that can be
|
||||
considered not safe to run on the developer's workstation, thus they are
|
||||
skipped by default. The definition of *not safe* is also arbitrary but
|
||||
usually it means a blob which either its source or build process aren't
|
||||
public available.
|
||||
|
||||
You should export ``AVOCADO_ALLOW_UNTRUSTED_CODE=1`` on the environment in
|
||||
order to allow tests which make use of those kind of assets.
|
||||
|
||||
AVOCADO_TIMEOUT_EXPECTED
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The Avocado framework has a timeout mechanism which interrupts tests to avoid the
|
||||
test suite of getting stuck. The timeout value can be set via test parameter or
|
||||
property defined in the test class, for further details::
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#setting-a-test-timeout
|
||||
|
||||
Even though the timeout can be set by the test developer, there are some tests
|
||||
that may not have a well-defined limit of time to finish under certain
|
||||
conditions. For example, tests that take longer to execute when QEMU is
|
||||
compiled with debug flags. Therefore, the ``AVOCADO_TIMEOUT_EXPECTED`` variable
|
||||
has been used to determine whether those tests should run or not.
|
||||
|
||||
QEMU_TEST_FLAKY_TESTS
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
Some tests are not working reliably and thus are disabled by default.
|
||||
This includes tests that don't run reliably on GitLab's CI which
|
||||
usually expose real issues that are rarely seen on developer machines
|
||||
due to the constraints of the CI environment. If you encounter a
|
||||
similar situation then raise a bug and then mark the test as shown on
|
||||
the code snippet below:
|
||||
|
||||
.. code::
|
||||
|
||||
# See https://gitlab.com/qemu-project/qemu/-/issues/nnnn
|
||||
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
|
||||
def test(self):
|
||||
do_something()
|
||||
|
||||
You can also add ``:avocado: tags=flaky`` to the test meta-data so
|
||||
only the flaky tests can be run as a group:
|
||||
|
||||
.. code::
|
||||
|
||||
env QEMU_TEST_FLAKY_TESTS=1 ./pyvenv/bin/avocado \
|
||||
run tests/avocado -filter-by-tags=flaky
|
||||
|
||||
Tests should not live in this state forever and should either be fixed
|
||||
or eventually removed.
|
||||
|
||||
|
||||
Uninstalling Avocado
|
||||
--------------------
|
||||
|
||||
If you've followed the manual installation instructions above, you can
|
||||
easily uninstall Avocado. Start by listing the packages you have
|
||||
installed::
|
||||
|
||||
pip list --user
|
||||
|
||||
And remove any package you want with::
|
||||
|
||||
pip uninstall <package_name>
|
||||
|
||||
If you've used ``make check-avocado``, the Python virtual environment where
|
||||
Avocado is installed will be cleaned up as part of ``make check-clean``.
|
338
docs/devel/testing/functional.rst
Normal file
338
docs/devel/testing/functional.rst
Normal file
@ -0,0 +1,338 @@
|
||||
.. _checkfunctional-ref:
|
||||
|
||||
Functional testing with Python
|
||||
==============================
|
||||
|
||||
The ``tests/functional`` directory hosts functional tests written in
|
||||
Python. They are usually higher level tests, and may interact with
|
||||
external resources and with various guest operating systems.
|
||||
The functional tests have initially evolved from the Avocado tests, so there
|
||||
is a lot of similarity to those tests here (see :ref:`checkavocado-ref` for
|
||||
details about the Avocado tests).
|
||||
|
||||
The tests should be written in the style of the Python `unittest`_ framework,
|
||||
using stdio for the TAP protocol. The folder ``tests/functional/qemu_test``
|
||||
provides classes (e.g. the ``QemuBaseTest``, ``QemuUserTest`` and the
|
||||
``QemuSystemTest`` classes) and utility functions that help to get your test
|
||||
into the right shape, e.g. by replacing the 'stdout' python object to redirect
|
||||
the normal output of your test to stderr instead.
|
||||
|
||||
Note that if you don't use one of the QemuBaseTest based classes for your
|
||||
test, or if you spawn subprocesses from your test, you have to make sure
|
||||
that there is no TAP-incompatible output written to stdio, e.g. either by
|
||||
prefixing every line with a "# " to mark the output as a TAP comment, or
|
||||
e.g. by capturing the stdout output of subprocesses (redirecting it to
|
||||
stderr is OK).
|
||||
|
||||
Tests based on ``qemu_test.QemuSystemTest`` can easily:
|
||||
|
||||
* Customize the command line arguments given to the convenience
|
||||
``self.vm`` attribute (a QEMUMachine instance)
|
||||
|
||||
* Interact with the QEMU monitor, send QMP commands and check
|
||||
their results
|
||||
|
||||
* Interact with the guest OS, using the convenience console device
|
||||
(which may be useful to assert the effectiveness and correctness of
|
||||
command line arguments or QMP commands)
|
||||
|
||||
* Download (and cache) remote data files, such as firmware and kernel
|
||||
images
|
||||
|
||||
Running tests
|
||||
-------------
|
||||
|
||||
You can run the functional tests simply by executing:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-functional
|
||||
|
||||
It is also possible to run tests for a certain target only, for example
|
||||
the following line will only run the tests for the x86_64 target:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-functional-x86_64
|
||||
|
||||
To run a single test file without the meson test runner, you can also
|
||||
execute the file directly by specifying two environment variables first,
|
||||
the PYTHONPATH that has to include the python folder and the tests/functional
|
||||
folder of the source tree, and QEMU_TEST_QEMU_BINARY that has to point
|
||||
to the QEMU binary that should be used for the test, for example::
|
||||
|
||||
$ export PYTHONPATH=../python:../tests/functional
|
||||
$ export QEMU_TEST_QEMU_BINARY=$PWD/qemu-system-x86_64
|
||||
$ python3 ../tests/functional/test_file.py
|
||||
|
||||
Overview
|
||||
--------
|
||||
|
||||
The ``tests/functional/qemu_test`` directory provides the ``qemu_test``
|
||||
Python module, containing the ``qemu_test.QemuSystemTest`` class.
|
||||
Here is a simple usage example:
|
||||
|
||||
.. code::
|
||||
|
||||
#!/usr/bin/env python3
|
||||
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
class Version(QemuSystemTest):
|
||||
|
||||
def test_qmp_human_info_version(self):
|
||||
self.vm.launch()
|
||||
res = self.vm.cmd('human-monitor-command',
|
||||
command_line='info version')
|
||||
self.assertRegex(res, r'^(\d+\.\d+\.\d)')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
||||
|
||||
By providing the "hash bang" line at the beginning of the script, marking
|
||||
the file as executable and by calling into QemuSystemTest.main(), the test
|
||||
can also be run stand-alone, without a test runner. OTOH when run via a test
|
||||
runner, the QemuSystemTest.main() function takes care of running the test
|
||||
functions in the right fassion (e.g. with TAP output that is required by the
|
||||
meson test runner).
|
||||
|
||||
The ``qemu_test.QemuSystemTest`` base test class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``qemu_test.QemuSystemTest`` class has a number of characteristics
|
||||
that are worth being mentioned.
|
||||
|
||||
First of all, it attempts to give each test a ready to use QEMUMachine
|
||||
instance, available at ``self.vm``. Because many tests will tweak the
|
||||
QEMU command line, launching the QEMUMachine (by using ``self.vm.launch()``)
|
||||
is left to the test writer.
|
||||
|
||||
The base test class has also support for tests with more than one
|
||||
QEMUMachine. The way to get machines is through the ``self.get_vm()``
|
||||
method which will return a QEMUMachine instance. The ``self.get_vm()``
|
||||
method accepts arguments that will be passed to the QEMUMachine creation
|
||||
and also an optional ``name`` attribute so you can identify a specific
|
||||
machine and get it more than once through the tests methods. A simple
|
||||
and hypothetical example follows:
|
||||
|
||||
.. code::
|
||||
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
class MultipleMachines(QemuSystemTest):
|
||||
def test_multiple_machines(self):
|
||||
first_machine = self.get_vm()
|
||||
second_machine = self.get_vm()
|
||||
self.get_vm(name='third_machine').launch()
|
||||
|
||||
first_machine.launch()
|
||||
second_machine.launch()
|
||||
|
||||
first_res = first_machine.cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
second_res = second_machine.cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
third_res = self.get_vm(name='third_machine').cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
self.assertEqual(first_res, second_res, third_res)
|
||||
|
||||
At test "tear down", ``qemu_test.QemuSystemTest`` handles all the QEMUMachines
|
||||
shutdown.
|
||||
|
||||
QEMUMachine
|
||||
-----------
|
||||
|
||||
The QEMUMachine API is already widely used in the Python iotests,
|
||||
device-crash-test and other Python scripts. It's a wrapper around the
|
||||
execution of a QEMU binary, giving its users:
|
||||
|
||||
* the ability to set command line arguments to be given to the QEMU
|
||||
binary
|
||||
|
||||
* a ready to use QMP connection and interface, which can be used to
|
||||
send commands and inspect its results, as well as asynchronous
|
||||
events
|
||||
|
||||
* convenience methods to set commonly used command line arguments in
|
||||
a more succinct and intuitive way
|
||||
|
||||
QEMU binary selection
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The QEMU binary used for the ``self.vm`` QEMUMachine instance will
|
||||
primarily depend on the value of the ``qemu_bin`` class attribute.
|
||||
If it is not explicitly set by the test code, its default value will
|
||||
be the result the QEMU_TEST_QEMU_BINARY environment variable.
|
||||
|
||||
Attribute reference
|
||||
-------------------
|
||||
|
||||
QemuBaseTest
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The following attributes are available on any ``qemu_test.QemuBaseTest``
|
||||
instance.
|
||||
|
||||
arch
|
||||
""""
|
||||
|
||||
The target architecture of the QEMU binary.
|
||||
|
||||
Tests are also free to use this attribute value, for their own needs.
|
||||
A test may, for instance, use this value when selecting the architecture
|
||||
of a kernel or disk image to boot a VM with.
|
||||
|
||||
qemu_bin
|
||||
""""""""
|
||||
|
||||
The preserved value of the ``QEMU_TEST_QEMU_BINARY`` environment
|
||||
variable.
|
||||
|
||||
QemuUserTest
|
||||
^^^^^^^^^^^^
|
||||
|
||||
The QemuUserTest class can be used for running an executable via the
|
||||
usermode emulation binaries.
|
||||
|
||||
QemuSystemTest
|
||||
^^^^^^^^^^^^^^
|
||||
|
||||
The QemuSystemTest class can be used for running tests via one of the
|
||||
qemu-system-* binaries.
|
||||
|
||||
vm
|
||||
""
|
||||
|
||||
A QEMUMachine instance, initially configured according to the given
|
||||
``qemu_bin`` parameter.
|
||||
|
||||
cpu
|
||||
"""
|
||||
|
||||
The cpu model that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
machine
|
||||
"""""""
|
||||
|
||||
The machine type that will be set to all QEMUMachine instances created
|
||||
by the test. By using the set_machine() function of the QemuSystemTest
|
||||
class to set this attribute, you can automatically check whether the
|
||||
machine is available to skip the test in case it is not built into the
|
||||
QEMU binary.
|
||||
|
||||
Asset handling
|
||||
--------------
|
||||
|
||||
Many functional tests download assets (e.g. Linux kernels, initrds,
|
||||
firmware images, etc.) from the internet to be able to run tests with
|
||||
them. This imposes additional challenges to the test framework.
|
||||
|
||||
First there is the the problem that some people might not have an
|
||||
unconstrained internet connection, so such tests should not be run by
|
||||
default when running ``make check``. To accomplish this situation,
|
||||
the tests that download files should only be added to the "thorough"
|
||||
speed mode in the meson.build file, while the "quick" speed mode is
|
||||
fine for functional tests that can be run without downloading files.
|
||||
``make check`` then only runs the quick functional tests along with
|
||||
the other quick tests from the other test suites. If you choose to
|
||||
run only run ``make check-functional``, the "thorough" tests will be
|
||||
executed, too. And to run all functional tests along with the others,
|
||||
you can use something like::
|
||||
|
||||
make -j$(nproc) check SPEED=thorough
|
||||
|
||||
The second problem with downloading files from the internet are time
|
||||
constraints. The time for downloading files should not be taken into
|
||||
account when the test is running and the timeout of the test is ticking
|
||||
(since downloading can be very slow, depending on the network bandwidth).
|
||||
This problem is solved by downloading the assets ahead of time, before
|
||||
the tests are run. This pre-caching is done with the qemu_test.Asset
|
||||
class. To use it in your test, declare an asset in your test class with
|
||||
its URL and SHA256 checksum like this::
|
||||
|
||||
ASSET_somename = (
|
||||
('https://www.qemu.org/assets/images/qemu_head_200.png'),
|
||||
'34b74cad46ea28a2966c1d04e102510daf1fd73e6582b6b74523940d5da029dd')
|
||||
|
||||
In your test function, you can then get the file name of the cached
|
||||
asset like this::
|
||||
|
||||
def test_function(self):
|
||||
file_path = self.ASSET_somename.fetch()
|
||||
|
||||
The pre-caching will be done automatically when running
|
||||
``make check-functional`` (but not when running e.g.
|
||||
``make check-functional-<target>``). In case you just want to download
|
||||
the assets without running the tests, you can do so by running::
|
||||
|
||||
make precache-functional
|
||||
|
||||
The cache is populated in the ``~/.cache/qemu/download`` directory by
|
||||
default, but the location can be changed by setting the
|
||||
``QEMU_TEST_CACHE_DIR`` environment variable.
|
||||
|
||||
Skipping tests
|
||||
--------------
|
||||
|
||||
Since the test framework is based on the common Python unittest framework,
|
||||
you can use the usual Python decorators which allow for easily skipping
|
||||
tests running under certain conditions, for example, on the lack of a binary
|
||||
on the test system or when the running environment is a CI system. For further
|
||||
information about those decorators, please refer to:
|
||||
|
||||
https://docs.python.org/3/library/unittest.html#skipping-tests-and-expected-failures
|
||||
|
||||
While the conditions for skipping tests are often specifics of each one, there
|
||||
are recurring scenarios identified by the QEMU developers and the use of
|
||||
environment variables became a kind of standard way to enable/disable tests.
|
||||
|
||||
Here is a list of the most used variables:
|
||||
|
||||
QEMU_TEST_ALLOW_LARGE_STORAGE
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Tests which are going to fetch or produce assets considered *large* are not
|
||||
going to run unless that ``QEMU_TEST_ALLOW_LARGE_STORAGE=1`` is exported on
|
||||
the environment.
|
||||
|
||||
The definition of *large* is a bit arbitrary here, but it usually means an
|
||||
asset which occupies at least 1GB of size on disk when uncompressed.
|
||||
|
||||
QEMU_TEST_ALLOW_UNTRUSTED_CODE
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
There are tests which will boot a kernel image or firmware that can be
|
||||
considered not safe to run on the developer's workstation, thus they are
|
||||
skipped by default. The definition of *not safe* is also arbitrary but
|
||||
usually it means a blob which either its source or build process aren't
|
||||
public available.
|
||||
|
||||
You should export ``QEMU_TEST_ALLOW_UNTRUSTED_CODE=1`` on the environment in
|
||||
order to allow tests which make use of those kind of assets.
|
||||
|
||||
QEMU_TEST_FLAKY_TESTS
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
Some tests are not working reliably and thus are disabled by default.
|
||||
This includes tests that don't run reliably on GitLab's CI which
|
||||
usually expose real issues that are rarely seen on developer machines
|
||||
due to the constraints of the CI environment. If you encounter a
|
||||
similar situation then raise a bug and then mark the test as shown on
|
||||
the code snippet below:
|
||||
|
||||
.. code::
|
||||
|
||||
# See https://gitlab.com/qemu-project/qemu/-/issues/nnnn
|
||||
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
|
||||
def test(self):
|
||||
do_something()
|
||||
|
||||
Tests should not live in this state forever and should either be fixed
|
||||
or eventually removed.
|
||||
|
||||
|
||||
.. _unittest: https://docs.python.org/3/library/unittest.html
|
16
docs/devel/testing/index.rst
Normal file
16
docs/devel/testing/index.rst
Normal file
@ -0,0 +1,16 @@
|
||||
Testing QEMU
|
||||
------------
|
||||
|
||||
Details about how to test QEMU and how it is integrated into our CI
|
||||
testing infrastructure.
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 3
|
||||
|
||||
main
|
||||
qtest
|
||||
functional
|
||||
avocado
|
||||
acpi-bits
|
||||
ci
|
||||
fuzzing
|
@ -862,6 +862,18 @@ supported. To start the fuzzer, run
|
||||
Alternatively, some command different from ``qemu-img info`` can be tested, by
|
||||
changing the ``-c`` option.
|
||||
|
||||
Functional tests using Python
|
||||
-----------------------------
|
||||
|
||||
The ``tests/functional`` directory hosts functional tests written in
|
||||
Python. You can run the functional tests simply by executing:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-functional
|
||||
|
||||
See :ref:`checkfunctional-ref` for more details.
|
||||
|
||||
Integration tests using the Avocado Framework
|
||||
---------------------------------------------
|
||||
|
||||
@ -869,577 +881,14 @@ The ``tests/avocado`` directory hosts integration tests. They're usually
|
||||
higher level tests, and may interact with external resources and with
|
||||
various guest operating systems.
|
||||
|
||||
These tests are written using the Avocado Testing Framework (which must
|
||||
be installed separately) in conjunction with a the ``avocado_qemu.Test``
|
||||
class, implemented at ``tests/avocado/avocado_qemu``.
|
||||
|
||||
Tests based on ``avocado_qemu.Test`` can easily:
|
||||
|
||||
* Customize the command line arguments given to the convenience
|
||||
``self.vm`` attribute (a QEMUMachine instance)
|
||||
|
||||
* Interact with the QEMU monitor, send QMP commands and check
|
||||
their results
|
||||
|
||||
* Interact with the guest OS, using the convenience console device
|
||||
(which may be useful to assert the effectiveness and correctness of
|
||||
command line arguments or QMP commands)
|
||||
|
||||
* Interact with external data files that accompany the test itself
|
||||
(see ``self.get_data()``)
|
||||
|
||||
* Download (and cache) remote data files, such as firmware and kernel
|
||||
images
|
||||
|
||||
* Have access to a library of guest OS images (by means of the
|
||||
``avocado.utils.vmimage`` library)
|
||||
|
||||
* Make use of various other test related utilities available at the
|
||||
test class itself and at the utility library:
|
||||
|
||||
- http://avocado-framework.readthedocs.io/en/latest/api/test/avocado.html#avocado.Test
|
||||
- http://avocado-framework.readthedocs.io/en/latest/api/utils/avocado.utils.html
|
||||
|
||||
Running tests
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
You can run the avocado tests simply by executing:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado
|
||||
|
||||
This involves the automatic installation, from PyPI, of all the
|
||||
necessary avocado-framework dependencies into the QEMU venv within the
|
||||
build tree (at ``./pyvenv``). Test results are also saved within the
|
||||
build tree (at ``tests/results``).
|
||||
See :ref:`checkavocado-ref` for more details.
|
||||
|
||||
Note: the build environment must be using a Python 3 stack, and have
|
||||
the ``venv`` and ``pip`` packages installed. If necessary, make sure
|
||||
``configure`` is called with ``--python=`` and that those modules are
|
||||
available. On Debian and Ubuntu based systems, depending on the
|
||||
specific version, they may be on packages named ``python3-venv`` and
|
||||
``python3-pip``.
|
||||
|
||||
It is also possible to run tests based on tags using the
|
||||
``make check-avocado`` command and the ``AVOCADO_TAGS`` environment
|
||||
variable:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TAGS=quick
|
||||
|
||||
Note that tags separated with commas have an AND behavior, while tags
|
||||
separated by spaces have an OR behavior. For more information on Avocado
|
||||
tags, see:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/tags.html
|
||||
|
||||
To run a single test file, a couple of them, or a test within a file
|
||||
using the ``make check-avocado`` command, set the ``AVOCADO_TESTS``
|
||||
environment variable with the test files or test names. To run all
|
||||
tests from a single file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS=$FILEPATH
|
||||
|
||||
The same is valid to run tests from multiple test files:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS='$FILEPATH1 $FILEPATH2'
|
||||
|
||||
To run a single test within a file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS=$FILEPATH:$TESTCLASS.$TESTNAME
|
||||
|
||||
The same is valid to run single tests from multiple test files:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-avocado AVOCADO_TESTS='$FILEPATH1:$TESTCLASS1.$TESTNAME1 $FILEPATH2:$TESTCLASS2.$TESTNAME2'
|
||||
|
||||
The scripts installed inside the virtual environment may be used
|
||||
without an "activation". For instance, the Avocado test runner
|
||||
may be invoked by running:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run $OPTION1 $OPTION2 tests/avocado/
|
||||
|
||||
Note that if ``make check-avocado`` was not executed before, it is
|
||||
possible to create the Python virtual environment with the dependencies
|
||||
needed running:
|
||||
|
||||
.. code::
|
||||
|
||||
make check-venv
|
||||
|
||||
It is also possible to run tests from a single file or a single test within
|
||||
a test file. To run tests from a single file within the build tree, use:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE
|
||||
|
||||
To run a single test within a test file, use:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado run tests/avocado/$TESTFILE:$TESTCLASS.$TESTNAME
|
||||
|
||||
Valid test names are visible in the output from any previous execution
|
||||
of Avocado or ``make check-avocado``, and can also be queried using:
|
||||
|
||||
.. code::
|
||||
|
||||
pyvenv/bin/avocado list tests/avocado
|
||||
|
||||
Manual Installation
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To manually install Avocado and its dependencies, run:
|
||||
|
||||
.. code::
|
||||
|
||||
pip install --user avocado-framework
|
||||
|
||||
Alternatively, follow the instructions on this link:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/user/chapters/installing.html
|
||||
|
||||
Overview
|
||||
~~~~~~~~
|
||||
|
||||
The ``tests/avocado/avocado_qemu`` directory provides the
|
||||
``avocado_qemu`` Python module, containing the ``avocado_qemu.Test``
|
||||
class. Here's a simple usage example:
|
||||
|
||||
.. code::
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
|
||||
|
||||
class Version(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=quick
|
||||
"""
|
||||
def test_qmp_human_info_version(self):
|
||||
self.vm.launch()
|
||||
res = self.vm.cmd('human-monitor-command',
|
||||
command_line='info version')
|
||||
self.assertRegex(res, r'^(\d+\.\d+\.\d)')
|
||||
|
||||
To execute your test, run:
|
||||
|
||||
.. code::
|
||||
|
||||
avocado run version.py
|
||||
|
||||
Tests may be classified according to a convention by using docstring
|
||||
directives such as ``:avocado: tags=TAG1,TAG2``. To run all tests
|
||||
in the current directory, tagged as "quick", run:
|
||||
|
||||
.. code::
|
||||
|
||||
avocado run -t quick .
|
||||
|
||||
The ``avocado_qemu.Test`` base test class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``avocado_qemu.Test`` class has a number of characteristics that
|
||||
are worth being mentioned right away.
|
||||
|
||||
First of all, it attempts to give each test a ready to use QEMUMachine
|
||||
instance, available at ``self.vm``. Because many tests will tweak the
|
||||
QEMU command line, launching the QEMUMachine (by using ``self.vm.launch()``)
|
||||
is left to the test writer.
|
||||
|
||||
The base test class has also support for tests with more than one
|
||||
QEMUMachine. The way to get machines is through the ``self.get_vm()``
|
||||
method which will return a QEMUMachine instance. The ``self.get_vm()``
|
||||
method accepts arguments that will be passed to the QEMUMachine creation
|
||||
and also an optional ``name`` attribute so you can identify a specific
|
||||
machine and get it more than once through the tests methods. A simple
|
||||
and hypothetical example follows:
|
||||
|
||||
.. code::
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
|
||||
|
||||
class MultipleMachines(QemuSystemTest):
|
||||
def test_multiple_machines(self):
|
||||
first_machine = self.get_vm()
|
||||
second_machine = self.get_vm()
|
||||
self.get_vm(name='third_machine').launch()
|
||||
|
||||
first_machine.launch()
|
||||
second_machine.launch()
|
||||
|
||||
first_res = first_machine.cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
second_res = second_machine.cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
third_res = self.get_vm(name='third_machine').cmd(
|
||||
'human-monitor-command',
|
||||
command_line='info version')
|
||||
|
||||
self.assertEqual(first_res, second_res, third_res)
|
||||
|
||||
At test "tear down", ``avocado_qemu.Test`` handles all the QEMUMachines
|
||||
shutdown.
|
||||
|
||||
The ``avocado_qemu.LinuxTest`` base test class
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The ``avocado_qemu.LinuxTest`` is further specialization of the
|
||||
``avocado_qemu.Test`` class, so it contains all the characteristics of
|
||||
the later plus some extra features.
|
||||
|
||||
First of all, this base class is intended for tests that need to
|
||||
interact with a fully booted and operational Linux guest. At this
|
||||
time, it uses a Fedora 31 guest image. The most basic example looks
|
||||
like this:
|
||||
|
||||
.. code::
|
||||
|
||||
from avocado_qemu import LinuxTest
|
||||
|
||||
|
||||
class SomeTest(LinuxTest):
|
||||
|
||||
def test(self):
|
||||
self.launch_and_wait()
|
||||
self.ssh_command('some_command_to_be_run_in_the_guest')
|
||||
|
||||
Please refer to tests that use ``avocado_qemu.LinuxTest`` under
|
||||
``tests/avocado`` for more examples.
|
||||
|
||||
QEMUMachine
|
||||
~~~~~~~~~~~
|
||||
|
||||
The QEMUMachine API is already widely used in the Python iotests,
|
||||
device-crash-test and other Python scripts. It's a wrapper around the
|
||||
execution of a QEMU binary, giving its users:
|
||||
|
||||
* the ability to set command line arguments to be given to the QEMU
|
||||
binary
|
||||
|
||||
* a ready to use QMP connection and interface, which can be used to
|
||||
send commands and inspect its results, as well as asynchronous
|
||||
events
|
||||
|
||||
* convenience methods to set commonly used command line arguments in
|
||||
a more succinct and intuitive way
|
||||
|
||||
QEMU binary selection
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The QEMU binary used for the ``self.vm`` QEMUMachine instance will
|
||||
primarily depend on the value of the ``qemu_bin`` parameter. If it's
|
||||
not explicitly set, its default value will be the result of a dynamic
|
||||
probe in the same source tree. A suitable binary will be one that
|
||||
targets the architecture matching host machine.
|
||||
|
||||
Based on this description, test writers will usually rely on one of
|
||||
the following approaches:
|
||||
|
||||
1) Set ``qemu_bin``, and use the given binary
|
||||
|
||||
2) Do not set ``qemu_bin``, and use a QEMU binary named like
|
||||
"qemu-system-${arch}", either in the current
|
||||
working directory, or in the current source tree.
|
||||
|
||||
The resulting ``qemu_bin`` value will be preserved in the
|
||||
``avocado_qemu.Test`` as an attribute with the same name.
|
||||
|
||||
Attribute reference
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Test
|
||||
^^^^
|
||||
|
||||
Besides the attributes and methods that are part of the base
|
||||
``avocado.Test`` class, the following attributes are available on any
|
||||
``avocado_qemu.Test`` instance.
|
||||
|
||||
vm
|
||||
''
|
||||
|
||||
A QEMUMachine instance, initially configured according to the given
|
||||
``qemu_bin`` parameter.
|
||||
|
||||
arch
|
||||
''''
|
||||
|
||||
The architecture can be used on different levels of the stack, e.g. by
|
||||
the framework or by the test itself. At the framework level, it will
|
||||
currently influence the selection of a QEMU binary (when one is not
|
||||
explicitly given).
|
||||
|
||||
Tests are also free to use this attribute value, for their own needs.
|
||||
A test may, for instance, use the same value when selecting the
|
||||
architecture of a kernel or disk image to boot a VM with.
|
||||
|
||||
The ``arch`` attribute will be set to the test parameter of the same
|
||||
name. If one is not given explicitly, it will either be set to
|
||||
``None``, or, if the test is tagged with one (and only one)
|
||||
``:avocado: tags=arch:VALUE`` tag, it will be set to ``VALUE``.
|
||||
|
||||
cpu
|
||||
'''
|
||||
|
||||
The cpu model that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
The ``cpu`` attribute will be set to the test parameter of the same
|
||||
name. If one is not given explicitly, it will either be set to
|
||||
``None ``, or, if the test is tagged with one (and only one)
|
||||
``:avocado: tags=cpu:VALUE`` tag, it will be set to ``VALUE``.
|
||||
|
||||
machine
|
||||
'''''''
|
||||
|
||||
The machine type that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
The ``machine`` attribute will be set to the test parameter of the same
|
||||
name. If one is not given explicitly, it will either be set to
|
||||
``None``, or, if the test is tagged with one (and only one)
|
||||
``:avocado: tags=machine:VALUE`` tag, it will be set to ``VALUE``.
|
||||
|
||||
qemu_bin
|
||||
''''''''
|
||||
|
||||
The preserved value of the ``qemu_bin`` parameter or the result of the
|
||||
dynamic probe for a QEMU binary in the current working directory or
|
||||
source tree.
|
||||
|
||||
LinuxTest
|
||||
^^^^^^^^^
|
||||
|
||||
Besides the attributes present on the ``avocado_qemu.Test`` base
|
||||
class, the ``avocado_qemu.LinuxTest`` adds the following attributes:
|
||||
|
||||
distro
|
||||
''''''
|
||||
|
||||
The name of the Linux distribution used as the guest image for the
|
||||
test. The name should match the **Provider** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_version
|
||||
''''''''''''''
|
||||
|
||||
The version of the Linux distribution as the guest image for the
|
||||
test. The name should match the **Version** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_checksum
|
||||
'''''''''''''''
|
||||
|
||||
The sha256 hash of the guest image file used for the test.
|
||||
|
||||
If this value is not set in the code or by a test parameter (with the
|
||||
same name), no validation on the integrity of the image will be
|
||||
performed.
|
||||
|
||||
Parameter reference
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
To understand how Avocado parameters are accessed by tests, and how
|
||||
they can be passed to tests, please refer to::
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#accessing-test-parameters
|
||||
|
||||
Parameter values can be easily seen in the log files, and will look
|
||||
like the following:
|
||||
|
||||
.. code::
|
||||
|
||||
PARAMS (key=qemu_bin, path=*, default=./qemu-system-x86_64) => './qemu-system-x86_64
|
||||
|
||||
Test
|
||||
^^^^
|
||||
|
||||
arch
|
||||
''''
|
||||
|
||||
The architecture that will influence the selection of a QEMU binary
|
||||
(when one is not explicitly given).
|
||||
|
||||
Tests are also free to use this parameter value, for their own needs.
|
||||
A test may, for instance, use the same value when selecting the
|
||||
architecture of a kernel or disk image to boot a VM with.
|
||||
|
||||
This parameter has a direct relation with the ``arch`` attribute. If
|
||||
not given, it will default to None.
|
||||
|
||||
cpu
|
||||
'''
|
||||
|
||||
The cpu model that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
machine
|
||||
'''''''
|
||||
|
||||
The machine type that will be set to all QEMUMachine instances created
|
||||
by the test.
|
||||
|
||||
qemu_bin
|
||||
''''''''
|
||||
|
||||
The exact QEMU binary to be used on QEMUMachine.
|
||||
|
||||
LinuxTest
|
||||
^^^^^^^^^
|
||||
|
||||
Besides the parameters present on the ``avocado_qemu.Test`` base
|
||||
class, the ``avocado_qemu.LinuxTest`` adds the following parameters:
|
||||
|
||||
distro
|
||||
''''''
|
||||
|
||||
The name of the Linux distribution used as the guest image for the
|
||||
test. The name should match the **Provider** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_version
|
||||
''''''''''''''
|
||||
|
||||
The version of the Linux distribution as the guest image for the
|
||||
test. The name should match the **Version** column on the list
|
||||
of images supported by the avocado.utils.vmimage library:
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/libs/vmimage.html#supported-images
|
||||
|
||||
distro_checksum
|
||||
'''''''''''''''
|
||||
|
||||
The sha256 hash of the guest image file used for the test.
|
||||
|
||||
If this value is not set in the code or by this parameter no
|
||||
validation on the integrity of the image will be performed.
|
||||
|
||||
Skipping tests
|
||||
~~~~~~~~~~~~~~
|
||||
|
||||
The Avocado framework provides Python decorators which allow for easily skip
|
||||
tests running under certain conditions. For example, on the lack of a binary
|
||||
on the test system or when the running environment is a CI system. For further
|
||||
information about those decorators, please refer to::
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#skipping-tests
|
||||
|
||||
While the conditions for skipping tests are often specifics of each one, there
|
||||
are recurring scenarios identified by the QEMU developers and the use of
|
||||
environment variables became a kind of standard way to enable/disable tests.
|
||||
|
||||
Here is a list of the most used variables:
|
||||
|
||||
AVOCADO_ALLOW_LARGE_STORAGE
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
Tests which are going to fetch or produce assets considered *large* are not
|
||||
going to run unless that ``AVOCADO_ALLOW_LARGE_STORAGE=1`` is exported on
|
||||
the environment.
|
||||
|
||||
The definition of *large* is a bit arbitrary here, but it usually means an
|
||||
asset which occupies at least 1GB of size on disk when uncompressed.
|
||||
|
||||
SPEED
|
||||
^^^^^
|
||||
Tests which have a long runtime will not be run unless ``SPEED=slow`` is
|
||||
exported on the environment.
|
||||
|
||||
The definition of *long* is a bit arbitrary here, and it depends on the
|
||||
usefulness of the test too. A unique test is worth spending more time on,
|
||||
small variations on existing tests perhaps less so. As a rough guide,
|
||||
a test or set of similar tests which take more than 100 seconds to
|
||||
complete.
|
||||
|
||||
AVOCADO_ALLOW_UNTRUSTED_CODE
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
There are tests which will boot a kernel image or firmware that can be
|
||||
considered not safe to run on the developer's workstation, thus they are
|
||||
skipped by default. The definition of *not safe* is also arbitrary but
|
||||
usually it means a blob which either its source or build process aren't
|
||||
public available.
|
||||
|
||||
You should export ``AVOCADO_ALLOW_UNTRUSTED_CODE=1`` on the environment in
|
||||
order to allow tests which make use of those kind of assets.
|
||||
|
||||
AVOCADO_TIMEOUT_EXPECTED
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The Avocado framework has a timeout mechanism which interrupts tests to avoid the
|
||||
test suite of getting stuck. The timeout value can be set via test parameter or
|
||||
property defined in the test class, for further details::
|
||||
|
||||
https://avocado-framework.readthedocs.io/en/latest/guides/writer/chapters/writing.html#setting-a-test-timeout
|
||||
|
||||
Even though the timeout can be set by the test developer, there are some tests
|
||||
that may not have a well-defined limit of time to finish under certain
|
||||
conditions. For example, tests that take longer to execute when QEMU is
|
||||
compiled with debug flags. Therefore, the ``AVOCADO_TIMEOUT_EXPECTED`` variable
|
||||
has been used to determine whether those tests should run or not.
|
||||
|
||||
QEMU_TEST_FLAKY_TESTS
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
Some tests are not working reliably and thus are disabled by default.
|
||||
This includes tests that don't run reliably on GitLab's CI which
|
||||
usually expose real issues that are rarely seen on developer machines
|
||||
due to the constraints of the CI environment. If you encounter a
|
||||
similar situation then raise a bug and then mark the test as shown on
|
||||
the code snippet below:
|
||||
|
||||
.. code::
|
||||
|
||||
# See https://gitlab.com/qemu-project/qemu/-/issues/nnnn
|
||||
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
|
||||
def test(self):
|
||||
do_something()
|
||||
|
||||
You can also add ``:avocado: tags=flaky`` to the test meta-data so
|
||||
only the flaky tests can be run as a group:
|
||||
|
||||
.. code::
|
||||
|
||||
env QEMU_TEST_FLAKY_TESTS=1 ./pyvenv/bin/avocado \
|
||||
run tests/avocado -filter-by-tags=flaky
|
||||
|
||||
Tests should not live in this state forever and should either be fixed
|
||||
or eventually removed.
|
||||
|
||||
|
||||
Uninstalling Avocado
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
If you've followed the manual installation instructions above, you can
|
||||
easily uninstall Avocado. Start by listing the packages you have
|
||||
installed::
|
||||
|
||||
pip list --user
|
||||
|
||||
And remove any package you want with::
|
||||
|
||||
pip uninstall <package_name>
|
||||
|
||||
If you've used ``make check-avocado``, the Python virtual environment where
|
||||
Avocado is installed will be cleaned up as part of ``make check-clean``.
|
||||
|
||||
.. _checktcg-ref:
|
||||
|
BIN
python/wheels/pycotap-1.3.1-py3-none-any.whl
Normal file
BIN
python/wheels/pycotap-1.3.1-py3-none-any.whl
Normal file
Binary file not shown.
@ -20,6 +20,7 @@
|
||||
[meson]
|
||||
# The install key should match the version in python/wheels/
|
||||
meson = { accepted = ">=1.1.0", installed = "1.2.3", canary = "meson" }
|
||||
pycotap = { accepted = ">=1.1.0", installed = "1.3.1" }
|
||||
|
||||
[docs]
|
||||
# Please keep the installed versions in sync with docs/requirements.txt
|
||||
@ -30,5 +31,5 @@ sphinx_rtd_theme = { accepted = ">=0.5", installed = "1.1.1" }
|
||||
# Note that qemu.git/python/ is always implicitly installed.
|
||||
# Prefer an LTS version when updating the accepted versions of
|
||||
# avocado-framework, for example right now the limit is 92.x.
|
||||
avocado-framework = { accepted = "(>=88.1, <93.0)", installed = "88.1", canary = "avocado" }
|
||||
avocado-framework = { accepted = "(>=103.0, <104.0)", installed = "103.0", canary = "avocado" }
|
||||
pycdlib = { accepted = ">=1.11.0" }
|
||||
|
@ -3,28 +3,30 @@
|
||||
.PHONY: check-help
|
||||
check-help:
|
||||
@echo "Regression testing targets:"
|
||||
@echo " $(MAKE) check Run block, qapi-schema, unit, softfloat, qtest and decodetree tests"
|
||||
@echo " $(MAKE) bench Run speed tests"
|
||||
@echo " $(MAKE) check Run block, qapi-schema, unit, softfloat, qtest and decodetree tests"
|
||||
@echo " $(MAKE) bench Run speed tests"
|
||||
@echo
|
||||
@echo "Individual test suites:"
|
||||
@echo " $(MAKE) check-qtest-TARGET Run qtest tests for given target"
|
||||
@echo " $(MAKE) check-qtest Run qtest tests"
|
||||
@echo " $(MAKE) check-unit Run qobject tests"
|
||||
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests"
|
||||
@echo " $(MAKE) check-block Run block tests"
|
||||
@echo " $(MAKE) check-qtest-TARGET Run qtest tests for given target"
|
||||
@echo " $(MAKE) check-qtest Run qtest tests"
|
||||
@echo " $(MAKE) check-functional Run python-based functional tests"
|
||||
@echo " $(MAKE) check-functional-TARGET Run functional tests for a given target"
|
||||
@echo " $(MAKE) check-unit Run qobject tests"
|
||||
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests"
|
||||
@echo " $(MAKE) check-block Run block tests"
|
||||
ifneq ($(filter $(all-check-targets), check-softfloat),)
|
||||
@echo " $(MAKE) check-tcg Run TCG tests"
|
||||
@echo " $(MAKE) check-softfloat Run FPU emulation tests"
|
||||
@echo " $(MAKE) check-tcg Run TCG tests"
|
||||
@echo " $(MAKE) check-softfloat Run FPU emulation tests"
|
||||
endif
|
||||
@echo " $(MAKE) check-avocado Run avocado (integration) tests for currently configured targets"
|
||||
@echo " $(MAKE) check-avocado Run avocado (integration) tests for currently configured targets"
|
||||
@echo
|
||||
@echo " $(MAKE) check-report.junit.xml Generates an aggregated XML test report"
|
||||
@echo " $(MAKE) check-venv Creates a Python venv for tests"
|
||||
@echo " $(MAKE) check-clean Clean the tests and related data"
|
||||
@echo " $(MAKE) check-report.junit.xml Generates an aggregated XML test report"
|
||||
@echo " $(MAKE) check-venv Creates a Python venv for tests"
|
||||
@echo " $(MAKE) check-clean Clean the tests and related data"
|
||||
@echo
|
||||
@echo "The following are useful for CI builds"
|
||||
@echo " $(MAKE) check-build Build most test binaries"
|
||||
@echo " $(MAKE) get-vm-images Downloads all images used by avocado tests, according to configured targets (~350 MB each, 1.5 GB max)"
|
||||
@echo " $(MAKE) check-build Build most test binaries"
|
||||
@echo " $(MAKE) get-vm-images Downloads all images used by avocado tests, according to configured targets (~350 MB each, 1.5 GB max)"
|
||||
@echo
|
||||
@echo
|
||||
@echo "The variable SPEED can be set to control the gtester speed setting."
|
||||
@ -141,7 +143,7 @@ check-avocado: check-venv $(TESTS_RESULTS_DIR) get-vm-images
|
||||
--show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
|
||||
$(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \
|
||||
--filter-by-tags-include-empty-key) \
|
||||
$(AVOCADO_CMDLINE_TAGS) \
|
||||
$(AVOCADO_CMDLINE_TAGS) --max-parallel-tasks=1 \
|
||||
$(if $(GITLAB_CI),,--failfast) $(AVOCADO_TESTS), \
|
||||
"AVOCADO", "tests/avocado")
|
||||
|
||||
@ -152,6 +154,16 @@ check-acceptance-deprecated-warning:
|
||||
|
||||
check-acceptance: check-acceptance-deprecated-warning | check-avocado
|
||||
|
||||
FUNCTIONAL_TARGETS=$(patsubst %-softmmu,check-functional-%, $(filter %-softmmu,$(TARGETS)))
|
||||
.PHONY: $(FUNCTIONAL_TARGETS)
|
||||
$(FUNCTIONAL_TARGETS):
|
||||
@$(MAKE) SPEED=thorough $(subst -functional,-func,$@)
|
||||
|
||||
.PHONY: check-functional
|
||||
check-functional:
|
||||
@$(NINJA) precache-functional
|
||||
@QEMU_TEST_NO_DOWNLOAD=1 $(MAKE) SPEED=thorough check-func check-func-quick
|
||||
|
||||
# Consolidated targets
|
||||
|
||||
.PHONY: check check-clean get-vm-images
|
||||
|
@ -384,23 +384,6 @@ class QemuSystemTest(QemuBaseTest):
|
||||
super().tearDown()
|
||||
|
||||
|
||||
class QemuUserTest(QemuBaseTest):
|
||||
"""Facilitates user-mode emulation tests."""
|
||||
|
||||
def setUp(self):
|
||||
self._ldpath = []
|
||||
super().setUp('qemu-')
|
||||
|
||||
def add_ldpath(self, ldpath):
|
||||
self._ldpath.append(os.path.abspath(ldpath))
|
||||
|
||||
def run(self, bin_path, args=[]):
|
||||
qemu_args = " ".join(["-L %s" % ldpath for ldpath in self._ldpath])
|
||||
bin_args = " ".join(args)
|
||||
return process.run("%s %s %s %s" % (self.qemu_bin, qemu_args,
|
||||
bin_path, bin_args))
|
||||
|
||||
|
||||
class LinuxSSHMixIn:
|
||||
"""Contains utility methods for interacting with a guest via SSH."""
|
||||
|
||||
|
@ -13,8 +13,8 @@ import shutil
|
||||
|
||||
from avocado.utils import cloudinit, datadrainer, process, vmimage
|
||||
|
||||
from . import LinuxSSHMixIn
|
||||
from . import QemuSystemTest
|
||||
from avocado_qemu import LinuxSSHMixIn
|
||||
from avocado_qemu import QemuSystemTest
|
||||
|
||||
if os.path.islink(os.path.dirname(os.path.dirname(__file__))):
|
||||
# The link to the avocado tests dir in the source code directory
|
||||
|
@ -1304,26 +1304,6 @@ class BootLinuxConsole(LinuxKernelTest):
|
||||
self.vm.launch()
|
||||
self.wait_for_console_pattern('version UEFI Firmware v1.15')
|
||||
|
||||
def test_s390x_s390_ccw_virtio(self):
|
||||
"""
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/29/Everything/s390x/os/images'
|
||||
'/kernel.img')
|
||||
kernel_hash = 'e8e8439103ef8053418ef062644ffd46a7919313'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
|
||||
self.vm.set_console()
|
||||
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'console=sclp0'
|
||||
self.vm.add_args('-nodefaults',
|
||||
'-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)
|
||||
|
||||
def test_alpha_clipper(self):
|
||||
"""
|
||||
:avocado: tags=arch:alpha
|
||||
|
@ -30,23 +30,22 @@ class BootXen(LinuxKernelTest):
|
||||
timeout = 90
|
||||
XEN_COMMON_COMMAND_LINE = 'dom0_mem=128M loglvl=all guest_loglvl=all'
|
||||
|
||||
def fetch_guest_kernel(self):
|
||||
def setUp(self):
|
||||
super(BootXen, self).setUp()
|
||||
|
||||
# Using my own built kernel - which works
|
||||
kernel_url = ('https://fileserver.linaro.org/'
|
||||
's/JSsewXGZ6mqxPr5/download?path=%2F&files='
|
||||
'linux-5.9.9-arm64-ajb')
|
||||
kernel_sha1 = '4f92bc4b9f88d5ab792fa7a43a68555d344e1b83'
|
||||
kernel_path = self.fetch_asset(kernel_url,
|
||||
asset_hash=kernel_sha1)
|
||||
|
||||
return kernel_path
|
||||
self.kernel_path = self.fetch_asset(kernel_url,
|
||||
asset_hash=kernel_sha1)
|
||||
|
||||
def launch_xen(self, xen_path):
|
||||
"""
|
||||
Launch Xen with a dom0 guest kernel
|
||||
"""
|
||||
self.log.info("launch with xen_path: %s", xen_path)
|
||||
kernel_path = self.fetch_guest_kernel()
|
||||
|
||||
self.vm.set_console()
|
||||
|
||||
@ -56,7 +55,7 @@ class BootXen(LinuxKernelTest):
|
||||
'-append', self.XEN_COMMON_COMMAND_LINE,
|
||||
'-device',
|
||||
'guest-loader,addr=0x47000000,kernel=%s,bootargs=console=hvc0'
|
||||
% (kernel_path))
|
||||
% (self.kernel_path))
|
||||
|
||||
self.vm.launch()
|
||||
|
||||
|
@ -1,54 +0,0 @@
|
||||
# Test the bFLT loader format
|
||||
#
|
||||
# Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import bz2
|
||||
import subprocess
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuUserTest
|
||||
from avocado_qemu import has_cmd
|
||||
|
||||
|
||||
class LoadBFLT(QemuUserTest):
|
||||
|
||||
def extract_cpio(self, cpio_path):
|
||||
"""
|
||||
Extracts a cpio archive into the test workdir
|
||||
|
||||
:param cpio_path: path to the cpio archive
|
||||
"""
|
||||
cwd = os.getcwd()
|
||||
os.chdir(self.workdir)
|
||||
with bz2.open(cpio_path, 'rb') as archive_cpio:
|
||||
subprocess.run(['cpio', '-i'], input=archive_cpio.read(),
|
||||
stderr=subprocess.DEVNULL)
|
||||
os.chdir(cwd)
|
||||
|
||||
@skipUnless(*has_cmd('cpio'))
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_stm32(self):
|
||||
"""
|
||||
:avocado: tags=arch:arm
|
||||
:avocado: tags=linux_user
|
||||
:avocado: tags=quick
|
||||
"""
|
||||
# See https://elinux.org/STM32#User_Space
|
||||
rootfs_url = ('https://elinux.org/images/5/51/'
|
||||
'Stm32_mini_rootfs.cpio.bz2')
|
||||
rootfs_hash = '9f065e6ba40cce7411ba757f924f30fcc57951e6'
|
||||
rootfs_path_bz2 = self.fetch_asset(rootfs_url, asset_hash=rootfs_hash)
|
||||
busybox_path = os.path.join(self.workdir, "/bin/busybox")
|
||||
|
||||
self.extract_cpio(rootfs_path_bz2)
|
||||
|
||||
res = self.run(busybox_path)
|
||||
ver = 'BusyBox v1.24.0.git (2015-02-03 22:17:13 CET) multi-call binary.'
|
||||
self.assertIn(ver, res.stdout_text)
|
||||
|
||||
res = self.run(busybox_path, ['uname', '-a'])
|
||||
unm = 'armv7l GNU/Linux'
|
||||
self.assertIn(unm, res.stdout_text)
|
0
tests/avocado/machine_arm_n8x0.py
Normal file → Executable file
0
tests/avocado/machine_arm_n8x0.py
Normal file → Executable file
@ -1,61 +0,0 @@
|
||||
# Functional test that boots a microblaze Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2018, 2021 Red Hat, Inc.
|
||||
#
|
||||
# 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 time
|
||||
from avocado_qemu import exec_command, exec_command_and_wait_for_pattern
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado.utils import archive
|
||||
|
||||
class MicroblazeMachine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
def test_microblaze_s3adsp1800(self):
|
||||
"""
|
||||
:avocado: tags=arch:microblaze
|
||||
:avocado: tags=machine:petalogix-s3adsp1800
|
||||
"""
|
||||
|
||||
tar_url = ('https://qemu-advcal.gitlab.io'
|
||||
'/qac-best-of-multiarch/download/day17.tar.xz')
|
||||
tar_hash = '08bf3e3bfb6b6c7ce1e54ab65d54e189f2caf13f'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/day17/ballerina.bin')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'This architecture does not have '
|
||||
'kernel memory protection')
|
||||
# Note:
|
||||
# The kernel sometimes gets stuck after the "This architecture ..."
|
||||
# message, that's why we don't test for a later string here. This
|
||||
# needs some investigation by a microblaze wizard one day...
|
||||
|
||||
def test_microblazeel_s3adsp1800(self):
|
||||
"""
|
||||
:avocado: tags=arch:microblazeel
|
||||
:avocado: tags=machine:petalogix-s3adsp1800
|
||||
"""
|
||||
|
||||
self.require_netdev('user')
|
||||
tar_url = ('http://www.qemu-advent-calendar.org/2023/download/'
|
||||
'day13.tar.gz')
|
||||
tar_hash = '6623d5fff5f84cfa8f34e286f32eff6a26546f44'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/day13/xmaton.bin')
|
||||
self.vm.add_args('-nic', 'user,tftp=' + self.workdir + '/day13/')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'QEMU Advent Calendar 2023')
|
||||
time.sleep(0.1)
|
||||
exec_command(self, 'root')
|
||||
time.sleep(0.1)
|
||||
exec_command_and_wait_for_pattern(self,
|
||||
'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png',
|
||||
'821cd3cab8efd16ad6ee5acc3642a8ea')
|
@ -1,39 +0,0 @@
|
||||
# Functional tests for the Generic Loongson-3 Platform.
|
||||
#
|
||||
# Copyright (c) 2021 Jiaxun Yang <jiaxun.yang@flygoat.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.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
|
||||
class MipsLoongson3v(QemuSystemTest):
|
||||
timeout = 60
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_pmon_serial_console(self):
|
||||
"""
|
||||
:avocado: tags=arch:mips64el
|
||||
:avocado: tags=endian:little
|
||||
:avocado: tags=machine:loongson3-virt
|
||||
:avocado: tags=cpu:Loongson-3A1000
|
||||
:avocado: tags=device:liointc
|
||||
:avocado: tags=device:goldfish_rtc
|
||||
"""
|
||||
|
||||
pmon_hash = '7c8b45dd81ccfc55ff28f5aa267a41c3'
|
||||
pmon_path = self.fetch_asset('https://github.com/loongson-community/pmon/'
|
||||
'releases/download/20210112/pmon-3avirt.bin',
|
||||
asset_hash=pmon_hash, algorithm='md5')
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', pmon_path)
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'CPU GODSON3 BogoMIPS:')
|
@ -1,36 +0,0 @@
|
||||
# Functional test that boots a Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
#
|
||||
# Author:
|
||||
# Thomas Huth <thuth@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
|
||||
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado.utils import archive
|
||||
from boot_linux_console import LinuxKernelTest
|
||||
|
||||
class Sun4uMachine(LinuxKernelTest):
|
||||
"""Boots the Linux kernel and checks that the console is operational"""
|
||||
|
||||
timeout = 90
|
||||
|
||||
def test_sparc64_sun4u(self):
|
||||
"""
|
||||
:avocado: tags=arch:sparc64
|
||||
:avocado: tags=machine:sun4u
|
||||
"""
|
||||
tar_url = ('https://qemu-advcal.gitlab.io'
|
||||
'/qac-best-of-multiarch/download/day23.tar.xz')
|
||||
tar_hash = '142db83cd974ffadc4f75c8a5cad5bcc5722c240'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/day23/vmlinux',
|
||||
'-append', self.KERNEL_COMMON_COMMAND_LINE)
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'Starting logging: OK')
|
@ -1,38 +0,0 @@
|
||||
# Test AmigaNG boards
|
||||
#
|
||||
# Copyright (c) 2023 BALATON Zoltan
|
||||
#
|
||||
# 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 avocado.utils import archive
|
||||
from avocado.utils import process
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
|
||||
class AmigaOneMachine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
def test_ppc_amigaone(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:amigaone
|
||||
:avocado: tags=device:articia
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
tar_name = 'A1Firmware_Floppy_05-Mar-2005.zip'
|
||||
tar_url = ('https://www.hyperion-entertainment.com/index.php/'
|
||||
'downloads?view=download&format=raw&file=25')
|
||||
tar_hash = 'c52e59bc73e31d8bcc3cc2106778f7ac84f6c755'
|
||||
zip_file = self.fetch_asset(tar_name, locations=tar_url,
|
||||
asset_hash=tar_hash)
|
||||
archive.extract(zip_file, self.workdir)
|
||||
cmd = f"tail -c 524288 {self.workdir}/floppy_edition/updater.image >{self.workdir}/u-boot-amigaone.bin"
|
||||
process.run(cmd, shell=True)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', self.workdir + '/u-boot-amigaone.bin')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'FLASH:')
|
@ -1,46 +0,0 @@
|
||||
# ...
|
||||
#
|
||||
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
#
|
||||
# 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 re
|
||||
import logging
|
||||
|
||||
from avocado.utils import process
|
||||
from avocado.utils.path import find_command, CmdNotFoundError
|
||||
|
||||
def tesseract_available(expected_version):
|
||||
try:
|
||||
find_command('tesseract')
|
||||
except CmdNotFoundError:
|
||||
return False
|
||||
res = process.run('tesseract --version')
|
||||
try:
|
||||
version = res.stdout_text.split()[1]
|
||||
except IndexError:
|
||||
version = res.stderr_text.split()[1]
|
||||
return int(version.split('.')[0]) >= expected_version
|
||||
|
||||
match = re.match(r'tesseract\s(\d)', res)
|
||||
if match is None:
|
||||
return False
|
||||
# now this is guaranteed to be a digit
|
||||
return int(match.groups()[0]) >= expected_version
|
||||
|
||||
|
||||
def tesseract_ocr(image_path, tesseract_args='', tesseract_version=3):
|
||||
console_logger = logging.getLogger('tesseract')
|
||||
console_logger.debug(image_path)
|
||||
if tesseract_version == 4:
|
||||
tesseract_args += ' --oem 1'
|
||||
proc = process.run("tesseract {} {} stdout".format(tesseract_args,
|
||||
image_path))
|
||||
lines = []
|
||||
for line in proc.stdout_text.split('\n'):
|
||||
sline = line.strip()
|
||||
if len(sline):
|
||||
console_logger.debug(sline)
|
||||
lines += [sline]
|
||||
return lines
|
205
tests/functional/meson.build
Normal file
205
tests/functional/meson.build
Normal file
@ -0,0 +1,205 @@
|
||||
# QEMU functional tests:
|
||||
# Tests that are put in the 'quick' category are run by default during
|
||||
# 'make check'. Everything that should not be run during 'make check'
|
||||
# (e.g. tests that fetch assets from the internet) should be put into
|
||||
# the 'thorough' category instead.
|
||||
|
||||
# Most tests run too slow with TCI enabled, so skip the functional tests there
|
||||
if get_option('tcg_interpreter')
|
||||
subdir_done()
|
||||
endif
|
||||
|
||||
# Timeouts for individual tests that can be slow e.g. with debugging enabled
|
||||
test_timeouts = {
|
||||
'aarch64_sbsaref' : 600,
|
||||
'aarch64_virt' : 360,
|
||||
'acpi_bits' : 240,
|
||||
'netdev_ethtool' : 180,
|
||||
'ppc_40p' : 240,
|
||||
'ppc64_hv' : 1000,
|
||||
'ppc64_powernv' : 120,
|
||||
'ppc64_pseries' : 120,
|
||||
's390x_ccw_virtio' : 180,
|
||||
}
|
||||
|
||||
tests_generic_system = [
|
||||
'empty_cpu_model',
|
||||
'info_usernet',
|
||||
'version',
|
||||
]
|
||||
|
||||
tests_generic_linuxuser = [
|
||||
]
|
||||
|
||||
tests_generic_bsduser = [
|
||||
]
|
||||
|
||||
tests_aarch64_system_thorough = [
|
||||
'aarch64_sbsaref',
|
||||
'aarch64_virt',
|
||||
]
|
||||
|
||||
tests_arm_system_thorough = [
|
||||
'arm_canona1100',
|
||||
'arm_integratorcp',
|
||||
]
|
||||
|
||||
tests_arm_linuxuser_thorough = [
|
||||
'arm_bflt',
|
||||
]
|
||||
|
||||
tests_avr_system_thorough = [
|
||||
'avr_mega2560',
|
||||
]
|
||||
|
||||
tests_loongarch64_system_thorough = [
|
||||
'loongarch64_virt',
|
||||
]
|
||||
|
||||
tests_m68k_system_thorough = [
|
||||
'm68k_nextcube'
|
||||
]
|
||||
|
||||
tests_microblaze_system_thorough = [
|
||||
'microblaze_s3adsp1800'
|
||||
]
|
||||
|
||||
tests_microblazeel_system_thorough = [
|
||||
'microblazeel_s3adsp1800'
|
||||
]
|
||||
|
||||
tests_mips64el_system_quick = [
|
||||
'mips64el_fuloong2e',
|
||||
]
|
||||
|
||||
tests_mips64el_system_thorough = [
|
||||
'mips64el_loongson3v',
|
||||
]
|
||||
|
||||
tests_ppc_system_quick = [
|
||||
'ppc_74xx',
|
||||
]
|
||||
|
||||
tests_ppc_system_thorough = [
|
||||
'ppc_405',
|
||||
'ppc_40p',
|
||||
'ppc_amiga',
|
||||
'ppc_bamboo',
|
||||
'ppc_mpc8544ds',
|
||||
'ppc_virtex_ml507',
|
||||
]
|
||||
|
||||
tests_ppc64_system_thorough = [
|
||||
'ppc64_hv',
|
||||
'ppc64_powernv',
|
||||
'ppc64_pseries',
|
||||
]
|
||||
|
||||
tests_rx_system_thorough = [
|
||||
'rx_gdbsim',
|
||||
]
|
||||
|
||||
tests_s390x_system_thorough = [
|
||||
's390x_ccw_virtio',
|
||||
's390x_topology',
|
||||
]
|
||||
|
||||
tests_sparc64_system_thorough = [
|
||||
'sparc64_sun4u',
|
||||
]
|
||||
|
||||
tests_x86_64_system_quick = [
|
||||
'cpu_queries',
|
||||
'mem_addr_space',
|
||||
'pc_cpu_hotplug_props',
|
||||
'virtio_version',
|
||||
'x86_cpu_model_versions',
|
||||
]
|
||||
|
||||
tests_x86_64_system_thorough = [
|
||||
'acpi_bits',
|
||||
'linux_initrd',
|
||||
'netdev_ethtool',
|
||||
'virtio_gpu',
|
||||
]
|
||||
|
||||
precache_all = []
|
||||
foreach speed : ['quick', 'thorough']
|
||||
foreach dir : target_dirs
|
||||
|
||||
target_base = dir.split('-')[0]
|
||||
|
||||
if dir.endswith('-softmmu')
|
||||
sysmode = 'system'
|
||||
test_emulator = emulators['qemu-system-' + target_base]
|
||||
elif dir.endswith('-linux-user')
|
||||
sysmode = 'linuxuser'
|
||||
test_emulator = emulators['qemu-' + target_base]
|
||||
elif dir.endswith('-bsd-user')
|
||||
sysmode = 'bsduser'
|
||||
test_emulator = emulators['qemu-' + target_base]
|
||||
else
|
||||
continue
|
||||
endif
|
||||
|
||||
if speed == 'quick'
|
||||
suites = ['func-quick', 'func-' + target_base]
|
||||
target_tests = get_variable('tests_' + target_base + '_' + sysmode + '_quick', []) \
|
||||
+ get_variable('tests_generic_' + sysmode)
|
||||
else
|
||||
suites = ['func-' + speed, 'func-' + target_base + '-' + speed, speed]
|
||||
target_tests = get_variable('tests_' + target_base + '_' + sysmode + '_' + speed, [])
|
||||
endif
|
||||
|
||||
test_deps = roms
|
||||
test_env = environment()
|
||||
if have_tools
|
||||
test_env.set('QEMU_TEST_QEMU_IMG', meson.global_build_root() / 'qemu-img')
|
||||
test_deps += [qemu_img]
|
||||
endif
|
||||
test_env.set('QEMU_TEST_QEMU_BINARY', test_emulator.full_path())
|
||||
test_env.set('QEMU_BUILD_ROOT', meson.project_build_root())
|
||||
test_env.set('PYTHONPATH', meson.project_source_root() / 'python:' +
|
||||
meson.current_source_dir())
|
||||
|
||||
foreach test : target_tests
|
||||
testname = '@0@-@1@'.format(target_base, test)
|
||||
testfile = 'test_' + test + '.py'
|
||||
testpath = meson.current_source_dir() / testfile
|
||||
teststamp = testname + '.tstamp'
|
||||
test_precache_env = environment()
|
||||
test_precache_env.set('QEMU_TEST_PRECACHE', meson.current_build_dir() / teststamp)
|
||||
test_precache_env.set('PYTHONPATH', meson.project_source_root() / 'python:' +
|
||||
meson.current_source_dir())
|
||||
precache = custom_target('func-precache-' + testname,
|
||||
output: teststamp,
|
||||
command: [python, testpath],
|
||||
depend_files: files(testpath),
|
||||
build_by_default: false,
|
||||
env: test_precache_env)
|
||||
precache_all += precache
|
||||
|
||||
# Ideally we would add 'precache' to 'depends' here, such that
|
||||
# 'build_by_default: false' lets the pre-caching automatically
|
||||
# run immediately before the test runs. In practice this is
|
||||
# broken in meson, with it running the pre-caching in the normal
|
||||
# compile phase https://github.com/mesonbuild/meson/issues/2518
|
||||
# If the above bug ever gets fixed, when QEMU changes the min
|
||||
# meson version, add the 'depends' and remove the custom
|
||||
# 'run_target' logic below & in Makefile.include
|
||||
test('func-' + testname,
|
||||
python,
|
||||
depends: [test_deps, test_emulator, emulator_modules],
|
||||
env: test_env,
|
||||
args: [testpath],
|
||||
protocol: 'tap',
|
||||
timeout: test_timeouts.get(test, 60),
|
||||
priority: test_timeouts.get(test, 60),
|
||||
suite: suites)
|
||||
endforeach
|
||||
endforeach
|
||||
endforeach
|
||||
|
||||
run_target('precache-functional',
|
||||
depends: precache_all,
|
||||
command: ['true'])
|
14
tests/functional/qemu_test/__init__.py
Normal file
14
tests/functional/qemu_test/__init__.py
Normal file
@ -0,0 +1,14 @@
|
||||
# Test class and utilities for functional tests
|
||||
#
|
||||
# Copyright 2024 Red Hat, Inc.
|
||||
#
|
||||
# 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 .asset import Asset
|
||||
from .config import BUILD_DIR
|
||||
from .cmd import has_cmd, has_cmds, run_cmd, is_readable_executable_file, \
|
||||
interrupt_interactive_console_until_pattern, wait_for_console_pattern, \
|
||||
exec_command, exec_command_and_wait_for_pattern, get_qemu_img
|
||||
from .testcase import QemuBaseTest, QemuUserTest, QemuSystemTest
|
171
tests/functional/qemu_test/asset.py
Normal file
171
tests/functional/qemu_test/asset.py
Normal file
@ -0,0 +1,171 @@
|
||||
# Test utilities for fetching & caching assets
|
||||
#
|
||||
# Copyright 2024 Red Hat, Inc.
|
||||
#
|
||||
# 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 hashlib
|
||||
import logging
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
import unittest
|
||||
import urllib.request
|
||||
from time import sleep
|
||||
from pathlib import Path
|
||||
from shutil import copyfileobj
|
||||
|
||||
|
||||
# Instances of this class must be declared as class level variables
|
||||
# starting with a name "ASSET_". This enables the pre-caching logic
|
||||
# to easily find all referenced assets and download them prior to
|
||||
# execution of the tests.
|
||||
class Asset:
|
||||
|
||||
def __init__(self, url, hashsum):
|
||||
self.url = url
|
||||
self.hash = hashsum
|
||||
cache_dir_env = os.getenv('QEMU_TEST_CACHE_DIR')
|
||||
if cache_dir_env:
|
||||
self.cache_dir = Path(cache_dir_env, "download")
|
||||
else:
|
||||
self.cache_dir = Path(Path("~").expanduser(),
|
||||
".cache", "qemu", "download")
|
||||
self.cache_file = Path(self.cache_dir, hashsum)
|
||||
self.log = logging.getLogger('qemu-test')
|
||||
|
||||
def __repr__(self):
|
||||
return "Asset: url=%s hash=%s cache=%s" % (
|
||||
self.url, self.hash, self.cache_file)
|
||||
|
||||
def _check(self, cache_file):
|
||||
if self.hash is None:
|
||||
return True
|
||||
if len(self.hash) == 64:
|
||||
sum_prog = 'sha256sum'
|
||||
elif len(self.hash) == 128:
|
||||
sum_prog = 'sha512sum'
|
||||
else:
|
||||
raise Exception("unknown hash type")
|
||||
|
||||
checksum = subprocess.check_output(
|
||||
[sum_prog, str(cache_file)]).split()[0]
|
||||
return self.hash == checksum.decode("utf-8")
|
||||
|
||||
def valid(self):
|
||||
return self.cache_file.exists() and self._check(self.cache_file)
|
||||
|
||||
def _wait_for_other_download(self, tmp_cache_file):
|
||||
# Another thread already seems to download the asset, so wait until
|
||||
# it is done, while also checking the size to see whether it is stuck
|
||||
try:
|
||||
current_size = tmp_cache_file.stat().st_size
|
||||
new_size = current_size
|
||||
except:
|
||||
if os.path.exists(self.cache_file):
|
||||
return True
|
||||
raise
|
||||
waittime = lastchange = 600
|
||||
while waittime > 0:
|
||||
sleep(1)
|
||||
waittime -= 1
|
||||
try:
|
||||
new_size = tmp_cache_file.stat().st_size
|
||||
except:
|
||||
if os.path.exists(self.cache_file):
|
||||
return True
|
||||
raise
|
||||
if new_size != current_size:
|
||||
lastchange = waittime
|
||||
current_size = new_size
|
||||
elif lastchange - waittime > 90:
|
||||
return False
|
||||
|
||||
self.log.debug("Time out while waiting for %s!", tmp_cache_file)
|
||||
raise
|
||||
|
||||
def fetch(self):
|
||||
if not self.cache_dir.exists():
|
||||
self.cache_dir.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
if self.valid():
|
||||
self.log.debug("Using cached asset %s for %s",
|
||||
self.cache_file, self.url)
|
||||
return str(self.cache_file)
|
||||
|
||||
if os.environ.get("QEMU_TEST_NO_DOWNLOAD", False):
|
||||
raise Exception("Asset cache is invalid and downloads disabled")
|
||||
|
||||
self.log.info("Downloading %s to %s...", self.url, self.cache_file)
|
||||
tmp_cache_file = self.cache_file.with_suffix(".download")
|
||||
|
||||
for retries in range(3):
|
||||
try:
|
||||
with tmp_cache_file.open("xb") as dst:
|
||||
with urllib.request.urlopen(self.url) as resp:
|
||||
copyfileobj(resp, dst)
|
||||
break
|
||||
except FileExistsError:
|
||||
self.log.debug("%s already exists, "
|
||||
"waiting for other thread to finish...",
|
||||
tmp_cache_file)
|
||||
if self._wait_for_other_download(tmp_cache_file):
|
||||
return str(self.cache_file)
|
||||
self.log.debug("%s seems to be stale, "
|
||||
"deleting and retrying download...",
|
||||
tmp_cache_file)
|
||||
tmp_cache_file.unlink()
|
||||
continue
|
||||
except Exception as e:
|
||||
self.log.error("Unable to download %s: %s", self.url, e)
|
||||
tmp_cache_file.unlink()
|
||||
raise
|
||||
|
||||
try:
|
||||
# Set these just for informational purposes
|
||||
os.setxattr(str(tmp_cache_file), "user.qemu-asset-url",
|
||||
self.url.encode('utf8'))
|
||||
os.setxattr(str(tmp_cache_file), "user.qemu-asset-hash",
|
||||
self.hash.encode('utf8'))
|
||||
except Exception as e:
|
||||
self.log.debug("Unable to set xattr on %s: %s", tmp_cache_file, e)
|
||||
pass
|
||||
|
||||
if not self._check(tmp_cache_file):
|
||||
tmp_cache_file.unlink()
|
||||
raise Exception("Hash of %s does not match %s" %
|
||||
(self.url, self.hash))
|
||||
tmp_cache_file.replace(self.cache_file)
|
||||
|
||||
self.log.info("Cached %s at %s" % (self.url, self.cache_file))
|
||||
return str(self.cache_file)
|
||||
|
||||
def precache_test(test):
|
||||
log = logging.getLogger('qemu-test')
|
||||
log.setLevel(logging.DEBUG)
|
||||
handler = logging.StreamHandler(sys.stdout)
|
||||
handler.setLevel(logging.DEBUG)
|
||||
formatter = logging.Formatter(
|
||||
'%(asctime)s - %(name)s - %(levelname)s - %(message)s')
|
||||
handler.setFormatter(formatter)
|
||||
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)
|
||||
asset.fetch()
|
||||
log.removeHandler(handler)
|
||||
|
||||
def precache_suite(suite):
|
||||
for test in suite:
|
||||
if isinstance(test, unittest.TestSuite):
|
||||
Asset.precache_suite(test)
|
||||
elif isinstance(test, unittest.TestCase):
|
||||
Asset.precache_test(test)
|
||||
|
||||
def precache_suites(path, cacheTstamp):
|
||||
loader = unittest.loader.defaultTestLoader
|
||||
tests = loader.loadTestsFromNames([path], None)
|
||||
|
||||
with open(cacheTstamp, "w") as fh:
|
||||
Asset.precache_suite(tests)
|
193
tests/functional/qemu_test/cmd.py
Normal file
193
tests/functional/qemu_test/cmd.py
Normal file
@ -0,0 +1,193 @@
|
||||
# Test class and utilities for functional tests
|
||||
#
|
||||
# Copyright 2018, 2024 Red Hat, Inc.
|
||||
#
|
||||
# Original Author (Avocado-based tests):
|
||||
# Cleber Rosa <crosa@redhat.com>
|
||||
#
|
||||
# Adaption for standalone version:
|
||||
# Thomas Huth <thuth@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 logging
|
||||
import os
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
from .config import BUILD_DIR
|
||||
|
||||
|
||||
def has_cmd(name, args=None):
|
||||
"""
|
||||
This function is for use in a @skipUnless decorator, e.g.:
|
||||
|
||||
@skipUnless(*has_cmd('sudo -n', ('sudo', '-n', 'true')))
|
||||
def test_something_that_needs_sudo(self):
|
||||
...
|
||||
"""
|
||||
|
||||
if args is None:
|
||||
args = ('which', name)
|
||||
|
||||
try:
|
||||
_, stderr, exitcode = run_cmd(args)
|
||||
except Exception as e:
|
||||
exitcode = -1
|
||||
stderr = str(e)
|
||||
|
||||
if exitcode != 0:
|
||||
cmd_line = ' '.join(args)
|
||||
err = f'{name} required, but "{cmd_line}" failed: {stderr.strip()}'
|
||||
return (False, err)
|
||||
else:
|
||||
return (True, '')
|
||||
|
||||
def has_cmds(*cmds):
|
||||
"""
|
||||
This function is for use in a @skipUnless decorator and
|
||||
allows checking for the availability of multiple commands, e.g.:
|
||||
|
||||
@skipUnless(*has_cmds(('cmd1', ('cmd1', '--some-parameter')),
|
||||
'cmd2', 'cmd3'))
|
||||
def test_something_that_needs_cmd1_and_cmd2(self):
|
||||
...
|
||||
"""
|
||||
|
||||
for cmd in cmds:
|
||||
if isinstance(cmd, str):
|
||||
cmd = (cmd,)
|
||||
|
||||
ok, errstr = has_cmd(*cmd)
|
||||
if not ok:
|
||||
return (False, errstr)
|
||||
|
||||
return (True, '')
|
||||
|
||||
def run_cmd(args):
|
||||
subp = subprocess.Popen(args,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
universal_newlines=True)
|
||||
stdout, stderr = subp.communicate()
|
||||
ret = subp.returncode
|
||||
|
||||
return (stdout, stderr, ret)
|
||||
|
||||
def is_readable_executable_file(path):
|
||||
return os.path.isfile(path) and os.access(path, os.R_OK | os.X_OK)
|
||||
|
||||
def _console_interaction(test, success_message, failure_message,
|
||||
send_string, keep_sending=False, vm=None):
|
||||
assert not keep_sending or send_string
|
||||
if vm is None:
|
||||
vm = test.vm
|
||||
console = vm.console_file
|
||||
console_logger = logging.getLogger('console')
|
||||
while True:
|
||||
if send_string:
|
||||
vm.console_socket.sendall(send_string.encode())
|
||||
if not keep_sending:
|
||||
send_string = None # send only once
|
||||
|
||||
# Only consume console output if waiting for something
|
||||
if success_message is None and failure_message is None:
|
||||
if send_string is None:
|
||||
break
|
||||
continue
|
||||
|
||||
try:
|
||||
msg = console.readline().decode().strip()
|
||||
except UnicodeDecodeError:
|
||||
msg = None
|
||||
if not msg:
|
||||
continue
|
||||
console_logger.debug(msg)
|
||||
if success_message is None or success_message in msg:
|
||||
break
|
||||
if failure_message and failure_message in msg:
|
||||
console.close()
|
||||
fail = 'Failure message found in console: "%s". Expected: "%s"' % \
|
||||
(failure_message, success_message)
|
||||
test.fail(fail)
|
||||
|
||||
def interrupt_interactive_console_until_pattern(test, success_message,
|
||||
failure_message=None,
|
||||
interrupt_string='\r'):
|
||||
"""
|
||||
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:
|
||||
|
||||
Press a key within 5 seconds to interrupt boot process.
|
||||
5
|
||||
4
|
||||
3
|
||||
2
|
||||
1
|
||||
Booting default image...
|
||||
|
||||
:param test: a test containing a VM that will have its console
|
||||
read and probed for a success or failure message
|
||||
: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 interrupt_string: a string to send to the console before trying
|
||||
to read a new line
|
||||
"""
|
||||
_console_interaction(test, success_message, failure_message,
|
||||
interrupt_string, True)
|
||||
|
||||
def wait_for_console_pattern(test, success_message, failure_message=None,
|
||||
vm=None):
|
||||
"""
|
||||
Waits for messages to appear on the console, while logging the content
|
||||
|
||||
:param test: a test containing a VM that will have its console
|
||||
read and probed for a success or failure message
|
||||
:type test: :class:`qemu_test.QemuSystemTest`
|
||||
:param success_message: if this message appears, test succeeds
|
||||
:param failure_message: if this message appears, test fails
|
||||
"""
|
||||
_console_interaction(test, success_message, failure_message, None, vm=vm)
|
||||
|
||||
def exec_command(test, command):
|
||||
"""
|
||||
Send a command to a console (appending CRLF characters), while logging
|
||||
the content.
|
||||
|
||||
:param test: a test containing a VM.
|
||||
:type test: :class:`qemu_test.QemuSystemTest`
|
||||
:param command: the command to send
|
||||
:type command: str
|
||||
"""
|
||||
_console_interaction(test, None, None, command + '\r')
|
||||
|
||||
def exec_command_and_wait_for_pattern(test, command,
|
||||
success_message, failure_message=None):
|
||||
"""
|
||||
Send a command to a console (appending CRLF characters), then wait
|
||||
for success_message to appear on the console, while logging the.
|
||||
content. Mark the test as failed if failure_message is found instead.
|
||||
|
||||
:param test: a test containing a VM that will have its console
|
||||
read and probed for a success or failure message
|
||||
:type test: :class:`qemu_test.QemuSystemTest`
|
||||
:param command: the command to send
|
||||
:param success_message: if this message appears, test succeeds
|
||||
:param failure_message: if this message appears, test fails
|
||||
"""
|
||||
_console_interaction(test, success_message, failure_message, command + '\r')
|
||||
|
||||
def get_qemu_img(test):
|
||||
test.log.debug('Looking for and selecting a qemu-img binary')
|
||||
|
||||
# If qemu-img has been built, use it, otherwise the system wide one
|
||||
# will be used.
|
||||
qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
|
||||
if os.path.exists(qemu_img):
|
||||
return qemu_img
|
||||
if has_cmd('qemu-img'):
|
||||
return 'qemu-img'
|
||||
test.skipTest('Could not find "qemu-img", which is required to '
|
||||
'create temporary images')
|
36
tests/functional/qemu_test/config.py
Normal file
36
tests/functional/qemu_test/config.py
Normal file
@ -0,0 +1,36 @@
|
||||
# Test class and utilities for functional tests
|
||||
#
|
||||
# Copyright 2018, 2024 Red Hat, Inc.
|
||||
#
|
||||
# Original Author (Avocado-based tests):
|
||||
# Cleber Rosa <crosa@redhat.com>
|
||||
#
|
||||
# Adaption for standalone version:
|
||||
# Thomas Huth <thuth@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
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def _source_dir():
|
||||
# Determine top-level directory of the QEMU sources
|
||||
return Path(__file__).parent.parent.parent.parent
|
||||
|
||||
def _build_dir():
|
||||
root = os.getenv('QEMU_BUILD_ROOT')
|
||||
if root is not None:
|
||||
return Path(root)
|
||||
# Makefile.mtest only exists in build dir, so if it is available, use CWD
|
||||
if os.path.exists('Makefile.mtest'):
|
||||
return Path(os.getcwd())
|
||||
|
||||
root = os.path.join(_source_dir(), 'build')
|
||||
if os.path.exists(root):
|
||||
return Path(root)
|
||||
|
||||
raise Exception("Cannot identify build dir, set QEMU_BUILD_ROOT")
|
||||
|
||||
BUILD_DIR = _build_dir()
|
35
tests/functional/qemu_test/tesseract.py
Normal file
35
tests/functional/qemu_test/tesseract.py
Normal file
@ -0,0 +1,35 @@
|
||||
# ...
|
||||
#
|
||||
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
#
|
||||
# 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 re
|
||||
import logging
|
||||
|
||||
from . import has_cmd, run_cmd
|
||||
|
||||
def tesseract_available(expected_version):
|
||||
if not has_cmd('tesseract'):
|
||||
return False
|
||||
(stdout, stderr, ret) = run_cmd([ 'tesseract', '--version'])
|
||||
if ret:
|
||||
return False
|
||||
version = stdout.split()[1]
|
||||
return int(version.split('.')[0]) >= expected_version
|
||||
|
||||
def tesseract_ocr(image_path, tesseract_args=''):
|
||||
console_logger = logging.getLogger('console')
|
||||
console_logger.debug(image_path)
|
||||
(stdout, stderr, ret) = run_cmd(['tesseract', image_path,
|
||||
'stdout'])
|
||||
if ret:
|
||||
return None
|
||||
lines = []
|
||||
for line in stdout.split('\n'):
|
||||
sline = line.strip()
|
||||
if len(sline):
|
||||
console_logger.debug(sline)
|
||||
lines += [sline]
|
||||
return lines
|
202
tests/functional/qemu_test/testcase.py
Normal file
202
tests/functional/qemu_test/testcase.py
Normal file
@ -0,0 +1,202 @@
|
||||
# Test class and utilities for functional tests
|
||||
#
|
||||
# Copyright 2018, 2024 Red Hat, Inc.
|
||||
#
|
||||
# Original Author (Avocado-based tests):
|
||||
# Cleber Rosa <crosa@redhat.com>
|
||||
#
|
||||
# Adaption for standalone version:
|
||||
# Thomas Huth <thuth@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 logging
|
||||
import os
|
||||
import subprocess
|
||||
import pycotap
|
||||
import sys
|
||||
import unittest
|
||||
import uuid
|
||||
|
||||
from qemu.machine import QEMUMachine
|
||||
from qemu.utils import kvm_available, tcg_available
|
||||
|
||||
from .asset import Asset
|
||||
from .cmd import run_cmd
|
||||
from .config import BUILD_DIR
|
||||
|
||||
|
||||
class QemuBaseTest(unittest.TestCase):
|
||||
|
||||
qemu_bin = os.getenv('QEMU_TEST_QEMU_BINARY')
|
||||
arch = None
|
||||
|
||||
workdir = None
|
||||
log = None
|
||||
logdir = None
|
||||
|
||||
def setUp(self, bin_prefix):
|
||||
self.assertIsNotNone(self.qemu_bin, 'QEMU_TEST_QEMU_BINARY must be set')
|
||||
self.arch = self.qemu_bin.split('-')[-1]
|
||||
|
||||
self.workdir = os.path.join(BUILD_DIR, 'tests/functional', self.arch,
|
||||
self.id())
|
||||
os.makedirs(self.workdir, exist_ok=True)
|
||||
|
||||
self.logdir = self.workdir
|
||||
self.log = logging.getLogger('qemu-test')
|
||||
self.log.setLevel(logging.DEBUG)
|
||||
self._log_fh = logging.FileHandler(os.path.join(self.logdir,
|
||||
'base.log'), mode='w')
|
||||
self._log_fh.setLevel(logging.DEBUG)
|
||||
fileFormatter = logging.Formatter(
|
||||
'%(asctime)s - %(levelname)s: %(message)s')
|
||||
self._log_fh.setFormatter(fileFormatter)
|
||||
self.log.addHandler(self._log_fh)
|
||||
|
||||
def tearDown(self):
|
||||
self.log.removeHandler(self._log_fh)
|
||||
|
||||
def main():
|
||||
path = os.path.basename(sys.argv[0])[:-3]
|
||||
|
||||
cache = os.environ.get("QEMU_TEST_PRECACHE", None)
|
||||
if cache is not None:
|
||||
Asset.precache_suites(path, cache)
|
||||
return
|
||||
|
||||
tr = pycotap.TAPTestRunner(message_log = pycotap.LogMode.LogToError,
|
||||
test_output_log = pycotap.LogMode.LogToError)
|
||||
unittest.main(module = None, testRunner = tr, argv=["__dummy__", path])
|
||||
|
||||
|
||||
class QemuUserTest(QemuBaseTest):
|
||||
|
||||
def setUp(self):
|
||||
super().setUp('qemu-')
|
||||
self._ldpath = []
|
||||
|
||||
def add_ldpath(self, ldpath):
|
||||
self._ldpath.append(os.path.abspath(ldpath))
|
||||
|
||||
def run_cmd(self, bin_path, args=[]):
|
||||
return subprocess.run([self.qemu_bin]
|
||||
+ ["-L %s" % ldpath for ldpath in self._ldpath]
|
||||
+ [bin_path]
|
||||
+ args,
|
||||
text=True, capture_output=True)
|
||||
|
||||
class QemuSystemTest(QemuBaseTest):
|
||||
"""Facilitates system emulation tests."""
|
||||
|
||||
cpu = None
|
||||
machine = None
|
||||
_machinehelp = None
|
||||
|
||||
def setUp(self):
|
||||
self._vms = {}
|
||||
|
||||
super().setUp('qemu-system-')
|
||||
|
||||
console_log = logging.getLogger('console')
|
||||
console_log.setLevel(logging.DEBUG)
|
||||
self._console_log_fh = logging.FileHandler(os.path.join(self.workdir,
|
||||
'console.log'), mode='w')
|
||||
self._console_log_fh.setLevel(logging.DEBUG)
|
||||
fileFormatter = logging.Formatter('%(asctime)s: %(message)s')
|
||||
self._console_log_fh.setFormatter(fileFormatter)
|
||||
console_log.addHandler(self._console_log_fh)
|
||||
|
||||
def set_machine(self, machinename):
|
||||
# TODO: We should use QMP to get the list of available machines
|
||||
if not self._machinehelp:
|
||||
self._machinehelp = run_cmd([self.qemu_bin, '-M', 'help'])[0];
|
||||
if self._machinehelp.find(machinename) < 0:
|
||||
self.skipTest('no support for machine ' + machinename)
|
||||
self.machine = machinename
|
||||
|
||||
def require_accelerator(self, accelerator):
|
||||
"""
|
||||
Requires an accelerator to be available for the test to continue
|
||||
|
||||
It takes into account the currently set qemu binary.
|
||||
|
||||
If the check fails, the test is canceled. If the check itself
|
||||
for the given accelerator is not available, the test is also
|
||||
canceled.
|
||||
|
||||
:param accelerator: name of the accelerator, such as "kvm" or "tcg"
|
||||
:type accelerator: str
|
||||
"""
|
||||
checker = {'tcg': tcg_available,
|
||||
'kvm': kvm_available}.get(accelerator)
|
||||
if checker is None:
|
||||
self.skipTest("Don't know how to check for the presence "
|
||||
"of accelerator %s" % accelerator)
|
||||
if not checker(qemu_bin=self.qemu_bin):
|
||||
self.skipTest("%s accelerator does not seem to be "
|
||||
"available" % accelerator)
|
||||
|
||||
def require_netdev(self, netdevname):
|
||||
netdevhelp = run_cmd([self.qemu_bin,
|
||||
'-M', 'none', '-netdev', 'help'])[0];
|
||||
if netdevhelp.find('\n' + netdevname + '\n') < 0:
|
||||
self.skipTest('no support for " + netdevname + " networking')
|
||||
|
||||
def require_device(self, devicename):
|
||||
devhelp = run_cmd([self.qemu_bin,
|
||||
'-M', 'none', '-device', 'help'])[0];
|
||||
if devhelp.find(devicename) < 0:
|
||||
self.skipTest('no support for device ' + devicename)
|
||||
|
||||
def _new_vm(self, name, *args):
|
||||
vm = QEMUMachine(self.qemu_bin, base_temp_dir=self.workdir)
|
||||
self.log.debug('QEMUMachine "%s" created', name)
|
||||
self.log.debug('QEMUMachine "%s" temp_dir: %s', name, vm.temp_dir)
|
||||
self.log.debug('QEMUMachine "%s" log_dir: %s', name, vm.log_dir)
|
||||
if args:
|
||||
vm.add_args(*args)
|
||||
return vm
|
||||
|
||||
@property
|
||||
def vm(self):
|
||||
return self.get_vm(name='default')
|
||||
|
||||
def get_vm(self, *args, name=None):
|
||||
if not name:
|
||||
name = str(uuid.uuid4())
|
||||
if self._vms.get(name) is None:
|
||||
self._vms[name] = self._new_vm(name, *args)
|
||||
if self.cpu is not None:
|
||||
self._vms[name].add_args('-cpu', self.cpu)
|
||||
if self.machine is not None:
|
||||
self._vms[name].set_machine(self.machine)
|
||||
return self._vms[name]
|
||||
|
||||
def set_vm_arg(self, arg, value):
|
||||
"""
|
||||
Set an argument to list of extra arguments to be given to the QEMU
|
||||
binary. If the argument already exists then its value is replaced.
|
||||
|
||||
:param arg: the QEMU argument, such as "-cpu" in "-cpu host"
|
||||
:type arg: str
|
||||
:param value: the argument value, such as "host" in "-cpu host"
|
||||
:type value: str
|
||||
"""
|
||||
if not arg or not value:
|
||||
return
|
||||
if arg not in self.vm.args:
|
||||
self.vm.args.extend([arg, value])
|
||||
else:
|
||||
idx = self.vm.args.index(arg) + 1
|
||||
if idx < len(self.vm.args):
|
||||
self.vm.args[idx] = value
|
||||
else:
|
||||
self.vm.args.append(value)
|
||||
|
||||
def tearDown(self):
|
||||
for vm in self._vms.values():
|
||||
vm.shutdown()
|
||||
logging.getLogger('console').removeHandler(self._console_log_fh)
|
||||
super().tearDown()
|
56
tests/functional/qemu_test/utils.py
Normal file
56
tests/functional/qemu_test/utils.py
Normal file
@ -0,0 +1,56 @@
|
||||
# Utilities for python-based QEMU tests
|
||||
#
|
||||
# Copyright 2024 Red Hat, Inc.
|
||||
#
|
||||
# Authors:
|
||||
# Thomas Huth <thuth@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 gzip
|
||||
import lzma
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
import tarfile
|
||||
|
||||
def archive_extract(archive, dest_dir, member=None):
|
||||
with tarfile.open(archive) as tf:
|
||||
if hasattr(tarfile, 'data_filter'):
|
||||
tf.extraction_filter = getattr(tarfile, 'data_filter',
|
||||
(lambda member, path: member))
|
||||
if member:
|
||||
tf.extract(member=member, path=dest_dir)
|
||||
else:
|
||||
tf.extractall(path=dest_dir)
|
||||
|
||||
def gzip_uncompress(gz_path, output_path):
|
||||
if os.path.exists(output_path):
|
||||
return
|
||||
with gzip.open(gz_path, 'rb') as gz_in:
|
||||
try:
|
||||
with open(output_path, 'wb') as raw_out:
|
||||
shutil.copyfileobj(gz_in, raw_out)
|
||||
except:
|
||||
os.remove(output_path)
|
||||
raise
|
||||
|
||||
def lzma_uncompress(xz_path, output_path):
|
||||
if os.path.exists(output_path):
|
||||
return
|
||||
with lzma.open(xz_path, 'rb') as lzma_in:
|
||||
try:
|
||||
with open(output_path, 'wb') as raw_out:
|
||||
shutil.copyfileobj(lzma_in, raw_out)
|
||||
except:
|
||||
os.remove(output_path)
|
||||
raise
|
||||
|
||||
def cpio_extract(cpio_handle, output_path):
|
||||
cwd = os.getcwd()
|
||||
os.chdir(output_path)
|
||||
subprocess.run(['cpio', '-i'],
|
||||
input=cpio_handle.read(),
|
||||
stderr=subprocess.DEVNULL)
|
||||
os.chdir(cwd)
|
148
tests/avocado/machine_aarch64_sbsaref.py → tests/functional/test_aarch64_sbsaref.py
Normal file → Executable file
148
tests/avocado/machine_aarch64_sbsaref.py → tests/functional/test_aarch64_sbsaref.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a Linux kernel and checks the console
|
||||
#
|
||||
# SPDX-FileCopyrightText: 2023-2024 Linaro Ltd.
|
||||
@ -8,26 +10,31 @@
|
||||
|
||||
import os
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado.utils import archive
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado_qemu import interrupt_interactive_console_until_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test import interrupt_interactive_console_until_pattern
|
||||
from qemu_test.utils import lzma_uncompress
|
||||
from unittest import skipUnless
|
||||
|
||||
|
||||
class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=arch:aarch64
|
||||
:avocado: tags=machine:sbsa-ref
|
||||
:avocado: tags=accel:tcg
|
||||
|
||||
As firmware runs at a higher privilege level than the hypervisor we
|
||||
can only run these tests under TCG emulation.
|
||||
"""
|
||||
|
||||
timeout = 180
|
||||
|
||||
ASSET_FLASH0 = Asset(
|
||||
('https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/'
|
||||
'20240619-148232/edk2/SBSA_FLASH0.fd.xz'),
|
||||
'0c954842a590988f526984de22e21ae0ab9cb351a0c99a8a58e928f0c7359cf7')
|
||||
|
||||
ASSET_FLASH1 = Asset(
|
||||
('https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/'
|
||||
'20240619-148232/edk2/SBSA_FLASH1.fd.xz'),
|
||||
'c6ec39374c4d79bb9e9cdeeb6db44732d90bb4a334cec92002b3f4b9cac4b5ee')
|
||||
|
||||
def fetch_firmware(self):
|
||||
"""
|
||||
Flash volumes generated using:
|
||||
@ -44,47 +51,31 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
"""
|
||||
|
||||
# Secure BootRom (TF-A code)
|
||||
fs0_xz_url = (
|
||||
"https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/"
|
||||
"20240619-148232/edk2/SBSA_FLASH0.fd.xz"
|
||||
)
|
||||
fs0_xz_hash = "0c954842a590988f526984de22e21ae0ab9cb351a0c99a8a58e928f0c7359cf7"
|
||||
tar_xz_path = self.fetch_asset(fs0_xz_url, asset_hash=fs0_xz_hash,
|
||||
algorithm='sha256')
|
||||
archive.extract(tar_xz_path, self.workdir)
|
||||
fs0_xz_path = self.ASSET_FLASH0.fetch()
|
||||
fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd")
|
||||
lzma_uncompress(fs0_xz_path, fs0_path)
|
||||
|
||||
# Non-secure rom (UEFI and EFI variables)
|
||||
fs1_xz_url = (
|
||||
"https://artifacts.codelinaro.org/artifactory/linaro-419-sbsa-ref/"
|
||||
"20240619-148232/edk2/SBSA_FLASH1.fd.xz"
|
||||
)
|
||||
fs1_xz_hash = "c6ec39374c4d79bb9e9cdeeb6db44732d90bb4a334cec92002b3f4b9cac4b5ee"
|
||||
tar_xz_path = self.fetch_asset(fs1_xz_url, asset_hash=fs1_xz_hash,
|
||||
algorithm='sha256')
|
||||
archive.extract(tar_xz_path, self.workdir)
|
||||
fs1_xz_path = self.ASSET_FLASH1.fetch()
|
||||
fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd")
|
||||
lzma_uncompress(fs1_xz_path, fs1_path)
|
||||
|
||||
for path in [fs0_path, fs1_path]:
|
||||
with open(path, "ab+") as fd:
|
||||
fd.truncate(256 << 20) # Expand volumes to 256MiB
|
||||
|
||||
self.set_machine('sbsa-ref')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args(
|
||||
"-drive",
|
||||
f"if=pflash,file={fs0_path},format=raw",
|
||||
"-drive",
|
||||
f"if=pflash,file={fs1_path},format=raw",
|
||||
"-machine",
|
||||
"sbsa-ref",
|
||||
"-drive", f"if=pflash,file={fs0_path},format=raw",
|
||||
"-drive", f"if=pflash,file={fs1_path},format=raw",
|
||||
)
|
||||
|
||||
def test_sbsaref_edk2_firmware(self):
|
||||
"""
|
||||
:avocado: tags=cpu:cortex-a57
|
||||
"""
|
||||
|
||||
self.fetch_firmware()
|
||||
|
||||
self.vm.add_args('-cpu', 'cortex-a57')
|
||||
self.vm.launch()
|
||||
|
||||
# TF-A boot sequence:
|
||||
@ -110,87 +101,62 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, "UEFI firmware (version 1.0")
|
||||
interrupt_interactive_console_until_pattern(self, "QEMU SBSA-REF Machine")
|
||||
|
||||
|
||||
ASSET_ALPINE_ISO = Asset(
|
||||
('https://dl-cdn.alpinelinux.org/'
|
||||
'alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso'),
|
||||
'5a36304ecf039292082d92b48152a9ec21009d3a62f459de623e19c4bd9dc027')
|
||||
|
||||
# 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_alpine_linux(self, cpu):
|
||||
self.fetch_firmware()
|
||||
|
||||
iso_url = (
|
||||
"https://dl-cdn.alpinelinux.org/"
|
||||
"alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso"
|
||||
)
|
||||
|
||||
iso_hash = "5a36304ecf039292082d92b48152a9ec21009d3a62f459de623e19c4bd9dc027"
|
||||
iso_path = self.fetch_asset(iso_url, algorithm="sha256", asset_hash=iso_hash)
|
||||
iso_path = self.ASSET_ALPINE_ISO.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args(
|
||||
"-cpu",
|
||||
cpu,
|
||||
"-drive",
|
||||
f"file={iso_path},format=raw",
|
||||
"-cpu", cpu,
|
||||
"-drive", f"file={iso_path},media=cdrom,format=raw",
|
||||
)
|
||||
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, "Welcome to Alpine Linux 3.17")
|
||||
|
||||
def test_sbsaref_alpine_linux_cortex_a57(self):
|
||||
"""
|
||||
:avocado: tags=cpu:cortex-a57
|
||||
:avocado: tags=os:linux
|
||||
"""
|
||||
self.boot_alpine_linux("cortex-a57")
|
||||
|
||||
def test_sbsaref_alpine_linux_neoverse_n1(self):
|
||||
"""
|
||||
:avocado: tags=cpu:neoverse-n1
|
||||
:avocado: tags=os:linux
|
||||
"""
|
||||
self.boot_alpine_linux("neoverse-n1")
|
||||
|
||||
def test_sbsaref_alpine_linux_max_pauth_off(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=os:linux
|
||||
"""
|
||||
self.boot_alpine_linux("max,pauth=off")
|
||||
|
||||
def test_sbsaref_alpine_linux_max_pauth_impdef(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=os:linux
|
||||
"""
|
||||
self.boot_alpine_linux("max,pauth-impdef=on")
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
|
||||
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
|
||||
def test_sbsaref_alpine_linux_max(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=os:linux
|
||||
"""
|
||||
self.boot_alpine_linux("max")
|
||||
|
||||
|
||||
ASSET_OPENBSD_ISO = Asset(
|
||||
('https://cdn.openbsd.org/pub/OpenBSD/7.3/arm64/miniroot73.img'),
|
||||
'7fc2c75401d6f01fbfa25f4953f72ad7d7c18650056d30755c44b9c129b707e5')
|
||||
|
||||
# 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_openbsd73(self, cpu):
|
||||
self.fetch_firmware()
|
||||
|
||||
img_url = (
|
||||
"https://cdn.openbsd.org/pub/OpenBSD/7.3/arm64/miniroot73.img"
|
||||
)
|
||||
|
||||
img_hash = "7fc2c75401d6f01fbfa25f4953f72ad7d7c18650056d30755c44b9c129b707e5"
|
||||
img_path = self.fetch_asset(img_url, algorithm="sha256", asset_hash=img_hash)
|
||||
img_path = self.ASSET_OPENBSD_ISO.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args(
|
||||
"-cpu",
|
||||
cpu,
|
||||
"-drive",
|
||||
f"file={img_path},format=raw",
|
||||
"-cpu", cpu,
|
||||
"-drive", f"file={img_path},format=raw,snapshot=on",
|
||||
)
|
||||
|
||||
self.vm.launch()
|
||||
@ -199,38 +165,22 @@ class Aarch64SbsarefMachine(QemuSystemTest):
|
||||
" 7.3 installation program.")
|
||||
|
||||
def test_sbsaref_openbsd73_cortex_a57(self):
|
||||
"""
|
||||
:avocado: tags=cpu:cortex-a57
|
||||
:avocado: tags=os:openbsd
|
||||
"""
|
||||
self.boot_openbsd73("cortex-a57")
|
||||
|
||||
def test_sbsaref_openbsd73_neoverse_n1(self):
|
||||
"""
|
||||
:avocado: tags=cpu:neoverse-n1
|
||||
:avocado: tags=os:openbsd
|
||||
"""
|
||||
self.boot_openbsd73("neoverse-n1")
|
||||
|
||||
def test_sbsaref_openbsd73_max_pauth_off(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=os:openbsd
|
||||
"""
|
||||
self.boot_openbsd73("max,pauth=off")
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
|
||||
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
|
||||
def test_sbsaref_openbsd73_max_pauth_impdef(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=os:openbsd
|
||||
"""
|
||||
self.boot_openbsd73("max,pauth-impdef=on")
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_TIMEOUT_EXPECTED'), 'Test might timeout')
|
||||
@skipUnless(os.getenv('QEMU_TEST_TIMEOUT_EXPECTED'), 'Test might timeout')
|
||||
def test_sbsaref_openbsd73_max(self):
|
||||
"""
|
||||
:avocado: tags=cpu:max
|
||||
:avocado: tags=os:openbsd
|
||||
"""
|
||||
self.boot_openbsd73("max")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
71
tests/avocado/machine_aarch64_virt.py → tests/functional/test_aarch64_virt.py
Normal file → Executable file
71
tests/avocado/machine_aarch64_virt.py → tests/functional/test_aarch64_virt.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a various Linux systems and checks the
|
||||
# console output.
|
||||
#
|
||||
@ -12,12 +14,11 @@ import time
|
||||
import os
|
||||
import logging
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado_qemu import exec_command
|
||||
from avocado_qemu import BUILD_DIR
|
||||
from avocado.utils import process
|
||||
from avocado.utils.path import find_command
|
||||
from qemu_test import BUILD_DIR
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import exec_command, wait_for_console_pattern
|
||||
from qemu_test import get_qemu_img, run_cmd
|
||||
|
||||
|
||||
class Aarch64VirtMachine(QemuSystemTest):
|
||||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
@ -28,23 +29,18 @@ class Aarch64VirtMachine(QemuSystemTest):
|
||||
failure_message='Kernel panic - not syncing',
|
||||
vm=vm)
|
||||
|
||||
ASSET_ALPINE_ISO = Asset(
|
||||
('https://dl-cdn.alpinelinux.org/'
|
||||
'alpine/v3.17/releases/aarch64/alpine-standard-3.17.2-aarch64.iso'),
|
||||
'5a36304ecf039292082d92b48152a9ec21009d3a62f459de623e19c4bd9dc027')
|
||||
|
||||
# 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 test_alpine_virt_tcg_gic_max(self):
|
||||
"""
|
||||
:avocado: tags=arch:aarch64
|
||||
:avocado: tags=machine:virt
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
iso_url = ('https://dl-cdn.alpinelinux.org/'
|
||||
'alpine/v3.17/releases/aarch64/'
|
||||
'alpine-standard-3.17.2-aarch64.iso')
|
||||
|
||||
# Alpine use sha256 so I recalculated this myself
|
||||
iso_sha1 = '76284fcd7b41fe899b0c2375ceb8470803eea839'
|
||||
iso_path = self.fetch_asset(iso_url, asset_hash=iso_sha1)
|
||||
iso_path = self.ASSET_ALPINE_ISO.fetch()
|
||||
|
||||
self.set_machine('virt')
|
||||
self.vm.set_console()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
'console=ttyAMA0')
|
||||
@ -60,7 +56,7 @@ class Aarch64VirtMachine(QemuSystemTest):
|
||||
self.vm.add_args("-smp", "2", "-m", "1024")
|
||||
self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
|
||||
'edk2-aarch64-code.fd'))
|
||||
self.vm.add_args("-drive", f"file={iso_path},format=raw")
|
||||
self.vm.add_args("-drive", f"file={iso_path},media=cdrom,format=raw")
|
||||
self.vm.add_args('-device', 'virtio-rng-pci,rng=rng0')
|
||||
self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom')
|
||||
|
||||
@ -68,6 +64,11 @@ class Aarch64VirtMachine(QemuSystemTest):
|
||||
self.wait_for_console_pattern('Welcome to Alpine Linux 3.17')
|
||||
|
||||
|
||||
ASSET_KERNEL = Asset(
|
||||
('https://fileserver.linaro.org/s/'
|
||||
'z6B2ARM7DQT3HWN/download'),
|
||||
'12a54d4805cda6ab647cb7c7bbdb16fafb3df400e0d6f16445c1a0436100ef8d')
|
||||
|
||||
def common_aarch64_virt(self, machine):
|
||||
"""
|
||||
Common code to launch basic virt machine with kernel+initrd
|
||||
@ -75,11 +76,9 @@ class Aarch64VirtMachine(QemuSystemTest):
|
||||
"""
|
||||
logger = logging.getLogger('aarch64_virt')
|
||||
|
||||
kernel_url = ('https://fileserver.linaro.org/s/'
|
||||
'z6B2ARM7DQT3HWN/download')
|
||||
kernel_hash = 'ed11daab50c151dde0e1e9c9cb8b2d9bd3215347'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
|
||||
self.set_machine('virt')
|
||||
self.vm.set_console()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
'console=ttyAMA0')
|
||||
@ -98,14 +97,8 @@ class Aarch64VirtMachine(QemuSystemTest):
|
||||
# Also add a scratch block device
|
||||
logger.info('creating scratch qcow2 image')
|
||||
image_path = os.path.join(self.workdir, 'scratch.qcow2')
|
||||
qemu_img = os.path.join(BUILD_DIR, 'qemu-img')
|
||||
if not os.path.exists(qemu_img):
|
||||
qemu_img = find_command('qemu-img', False)
|
||||
if qemu_img is False:
|
||||
self.cancel('Could not find "qemu-img", which is required to '
|
||||
'create the temporary qcow2 image')
|
||||
cmd = '%s create -f qcow2 %s 8M' % (qemu_img, image_path)
|
||||
process.run(cmd)
|
||||
qemu_img = get_qemu_img(self)
|
||||
run_cmd([qemu_img, 'create', '-f', 'qcow2', image_path, '8M'])
|
||||
|
||||
# Add the device
|
||||
self.vm.add_args('-blockdev',
|
||||
@ -128,19 +121,11 @@ class Aarch64VirtMachine(QemuSystemTest):
|
||||
time.sleep(0.1)
|
||||
|
||||
def test_aarch64_virt_gicv3(self):
|
||||
"""
|
||||
:avocado: tags=arch:aarch64
|
||||
:avocado: tags=machine:virt
|
||||
:avocado: tags=accel:tcg
|
||||
:avocado: tags=cpu:max
|
||||
"""
|
||||
self.common_aarch64_virt("virt,gic_version=3")
|
||||
|
||||
def test_aarch64_virt_gicv2(self):
|
||||
"""
|
||||
:avocado: tags=arch:aarch64
|
||||
:avocado: tags=machine:virt
|
||||
:avocado: tags=accel:tcg
|
||||
:avocado: tags=cpu:max
|
||||
"""
|
||||
self.common_aarch64_virt("virt,gic-version=2")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
83
tests/avocado/acpi-bits.py → tests/functional/test_acpi_bits.py
Normal file → Executable file
83
tests/avocado/acpi-bits.py → tests/functional/test_acpi_bits.py
Normal file → Executable file
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
# group: rw quick
|
||||
#
|
||||
# Exercise QEMU generated ACPI/SMBIOS tables using biosbits,
|
||||
# https://biosbits.org/
|
||||
#
|
||||
@ -24,7 +24,7 @@
|
||||
# pylint: disable=consider-using-f-string
|
||||
|
||||
"""
|
||||
This is QEMU ACPI/SMBIOS avocado tests using biosbits.
|
||||
This is QEMU ACPI/SMBIOS functional tests using biosbits.
|
||||
Biosbits is available originally at https://biosbits.org/.
|
||||
This test uses a fork of the upstream bits and has numerous fixes
|
||||
including an upgraded acpica. The fork is located here:
|
||||
@ -41,15 +41,16 @@ import tarfile
|
||||
import tempfile
|
||||
import time
|
||||
import zipfile
|
||||
|
||||
from pathlib import Path
|
||||
from typing import (
|
||||
List,
|
||||
Optional,
|
||||
Sequence,
|
||||
)
|
||||
from qemu.machine import QEMUMachine
|
||||
from avocado import skipIf
|
||||
from avocado.utils import datadrainer as drainer
|
||||
from avocado_qemu import QemuBaseTest
|
||||
from unittest import skipIf
|
||||
from qemu_test import QemuBaseTest, Asset
|
||||
|
||||
deps = ["xorriso", "mformat"] # dependent tools needed in the test setup/box.
|
||||
supported_platforms = ['x86_64'] # supported test platforms.
|
||||
@ -129,34 +130,32 @@ class QEMUBitsMachine(QEMUMachine): # pylint: disable=too-few-public-methods
|
||||
class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
"""
|
||||
ACPI and SMBIOS tests using biosbits.
|
||||
|
||||
:avocado: tags=arch:x86_64
|
||||
:avocado: tags=acpi
|
||||
|
||||
"""
|
||||
# in slower systems the test can take as long as 3 minutes to complete.
|
||||
timeout = BITS_TIMEOUT
|
||||
|
||||
# following are some standard configuration constants
|
||||
# gitlab CI does shallow clones of depth 20
|
||||
BITS_INTERNAL_VER = 2020
|
||||
# commit hash must match the artifact tag below
|
||||
BITS_COMMIT_HASH = 'c7920d2b'
|
||||
# this is the latest bits release as of today.
|
||||
BITS_TAG = "qemu-bits-10262023"
|
||||
|
||||
ASSET_BITS = Asset(("https://gitlab.com/qemu-project/"
|
||||
"biosbits-bits/-/jobs/artifacts/%s/"
|
||||
"download?job=qemu-bits-build" % BITS_TAG),
|
||||
'1b8dd612c6831a6b491716a77acc486666aaa867051cdc34f7ce169c2e25f487')
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self._vm = None
|
||||
self._workDir = None
|
||||
self._baseDir = None
|
||||
|
||||
# following are some standard configuration constants
|
||||
self._bitsInternalVer = 2020 # gitlab CI does shallow clones of depth 20
|
||||
self._bitsCommitHash = 'c7920d2b' # commit hash must match
|
||||
# the artifact tag below
|
||||
self._bitsTag = "qemu-bits-10262023" # this is the latest bits
|
||||
# release as of today.
|
||||
self._bitsArtSHA1Hash = 'b22cdfcfc7453875297d06d626f5474ee36a343f'
|
||||
self._bitsArtURL = ("https://gitlab.com/qemu-project/"
|
||||
"biosbits-bits/-/jobs/artifacts/%s/"
|
||||
"download?job=qemu-bits-build" %self._bitsTag)
|
||||
self._debugcon_addr = '0x403'
|
||||
self._debugcon_log = 'debugcon-log.txt'
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
self.logger = logging.getLogger('acpi-bits')
|
||||
self.logger = self.log
|
||||
|
||||
def _print_log(self, log):
|
||||
self.logger.info('\nlogs from biosbits follows:')
|
||||
@ -171,7 +170,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
bits_config_dir = os.path.join(self._baseDir, 'acpi-bits',
|
||||
'bits-config')
|
||||
target_config_dir = os.path.join(self._workDir,
|
||||
'bits-%d' %self._bitsInternalVer,
|
||||
'bits-%d' %self.BITS_INTERNAL_VER,
|
||||
'boot')
|
||||
self.assertTrue(os.path.exists(bits_config_dir))
|
||||
self.assertTrue(os.path.exists(target_config_dir))
|
||||
@ -188,7 +187,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
bits_test_dir = os.path.join(self._baseDir, 'acpi-bits',
|
||||
'bits-tests')
|
||||
target_test_dir = os.path.join(self._workDir,
|
||||
'bits-%d' %self._bitsInternalVer,
|
||||
'bits-%d' %self.BITS_INTERNAL_VER,
|
||||
'boot', 'python')
|
||||
|
||||
self.assertTrue(os.path.exists(bits_test_dir))
|
||||
@ -248,9 +247,9 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
test scripts
|
||||
"""
|
||||
bits_dir = os.path.join(self._workDir,
|
||||
'bits-%d' %self._bitsInternalVer)
|
||||
'bits-%d' %self.BITS_INTERNAL_VER)
|
||||
iso_file = os.path.join(self._workDir,
|
||||
'bits-%d.iso' %self._bitsInternalVer)
|
||||
'bits-%d.iso' %self.BITS_INTERNAL_VER)
|
||||
mkrescue_script = os.path.join(self._workDir,
|
||||
'grub-inst-x86_64-efi', 'bin',
|
||||
'grub-mkrescue')
|
||||
@ -264,8 +263,12 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
|
||||
try:
|
||||
if os.getenv('V') or os.getenv('BITS_DEBUG'):
|
||||
subprocess.check_call([mkrescue_script, '-o', iso_file,
|
||||
bits_dir], stderr=subprocess.STDOUT)
|
||||
proc = subprocess.run([mkrescue_script, '-o', iso_file,
|
||||
bits_dir],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.STDOUT,
|
||||
check=True)
|
||||
self.logger.info("grub-mkrescue output %s" % proc.stdout)
|
||||
else:
|
||||
subprocess.check_call([mkrescue_script, '-o',
|
||||
iso_file, bits_dir],
|
||||
@ -282,8 +285,9 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
|
||||
def setUp(self): # pylint: disable=arguments-differ
|
||||
super().setUp('qemu-system-')
|
||||
self.logger = self.log
|
||||
|
||||
self._baseDir = os.getenv('AVOCADO_TEST_BASEDIR')
|
||||
self._baseDir = Path(__file__).parent
|
||||
|
||||
# workdir could also be avocado's own workdir in self.workdir.
|
||||
# At present, I prefer to maintain my own temporary working
|
||||
@ -300,15 +304,14 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
os.mkdir(prebuiltDir, mode=0o775)
|
||||
|
||||
bits_zip_file = os.path.join(prebuiltDir, 'bits-%d-%s.zip'
|
||||
%(self._bitsInternalVer,
|
||||
self._bitsCommitHash))
|
||||
%(self.BITS_INTERNAL_VER,
|
||||
self.BITS_COMMIT_HASH))
|
||||
grub_tar_file = os.path.join(prebuiltDir,
|
||||
'bits-%d-%s-grub.tar.gz'
|
||||
%(self._bitsInternalVer,
|
||||
self._bitsCommitHash))
|
||||
%(self.BITS_INTERNAL_VER,
|
||||
self.BITS_COMMIT_HASH))
|
||||
|
||||
bitsLocalArtLoc = self.fetch_asset(self._bitsArtURL,
|
||||
asset_hash=self._bitsArtSHA1Hash)
|
||||
bitsLocalArtLoc = self.ASSET_BITS.fetch()
|
||||
self.logger.info("downloaded bits artifacts to %s", bitsLocalArtLoc)
|
||||
|
||||
# extract the bits artifact in the temp working directory
|
||||
@ -369,7 +372,7 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
"""The main test case implementation."""
|
||||
|
||||
iso_file = os.path.join(self._workDir,
|
||||
'bits-%d.iso' %self._bitsInternalVer)
|
||||
'bits-%d.iso' %self.BITS_INTERNAL_VER)
|
||||
|
||||
self.assertTrue(os.access(iso_file, os.R_OK))
|
||||
|
||||
@ -393,12 +396,6 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
self._vm.set_console()
|
||||
self._vm.launch()
|
||||
|
||||
self.logger.debug("Console output from bits VM follows ...")
|
||||
c_drainer = drainer.LineLogger(self._vm.console_socket.fileno(),
|
||||
logger=self.logger.getChild("console"),
|
||||
stop_check=(lambda :
|
||||
not self._vm.is_running()))
|
||||
c_drainer.start()
|
||||
|
||||
# biosbits has been configured to run all the specified test suites
|
||||
# in batch mode and then automatically initiate a vm shutdown.
|
||||
@ -406,4 +403,8 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
|
||||
# with the avocado test timeout.
|
||||
self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT)
|
||||
self._vm.wait(timeout=None)
|
||||
self.logger.debug("Checking console output ...")
|
||||
self.parse_log()
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuBaseTest.main()
|
44
tests/functional/test_arm_bflt.py
Executable file
44
tests/functional/test_arm_bflt.py
Executable file
@ -0,0 +1,44 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test the bFLT loader format
|
||||
#
|
||||
# Copyright (C) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import bz2
|
||||
|
||||
from qemu_test import QemuUserTest, Asset
|
||||
from qemu_test import has_cmd
|
||||
from qemu_test.utils import cpio_extract
|
||||
from unittest import skipUnless
|
||||
|
||||
|
||||
class LoadBFLT(QemuUserTest):
|
||||
|
||||
ASSET_ROOTFS = Asset(
|
||||
('https://elinux.org/images/5/51/Stm32_mini_rootfs.cpio.bz2'),
|
||||
'eefb788e4980c9e8d6c9d60ce7d15d4da6bf4fbc6a80f487673824600d5ba9cc')
|
||||
|
||||
@skipUnless(*has_cmd('cpio'))
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_stm32(self):
|
||||
# See https://elinux.org/STM32#User_Space
|
||||
rootfs_path_bz2 = self.ASSET_ROOTFS.fetch()
|
||||
busybox_path = os.path.join(self.workdir, "bin/busybox")
|
||||
|
||||
with bz2.open(rootfs_path_bz2, 'rb') as cpio_handle:
|
||||
cpio_extract(cpio_handle, self.workdir)
|
||||
|
||||
res = self.run_cmd(busybox_path)
|
||||
ver = 'BusyBox v1.24.0.git (2015-02-03 22:17:13 CET) multi-call binary.'
|
||||
self.assertIn(ver, res.stdout)
|
||||
|
||||
res = self.run_cmd(busybox_path, ['uname', '-a'])
|
||||
unm = 'armv7l GNU/Linux'
|
||||
self.assertIn(unm, res.stdout)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuUserTest.main()
|
30
tests/avocado/machine_arm_canona1100.py → tests/functional/test_arm_canona1100.py
Normal file → Executable file
30
tests/avocado/machine_arm_canona1100.py → tests/functional/test_arm_canona1100.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots the canon-a1100 machine with firmware
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
@ -8,28 +10,30 @@
|
||||
# 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 avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado.utils import archive
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
|
||||
class CanonA1100Machine(QemuSystemTest):
|
||||
"""Boots the barebox firmware and checks that the console is operational"""
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_BIOS = Asset(('https://qemu-advcal.gitlab.io'
|
||||
'/qac-best-of-multiarch/download/day18.tar.xz'),
|
||||
'28e71874ce985be66b7fd1345ed88cb2523b982f899c8d2900d6353054a1be49')
|
||||
|
||||
def test_arm_canona1100(self):
|
||||
"""
|
||||
:avocado: tags=arch:arm
|
||||
:avocado: tags=machine:canon-a1100
|
||||
:avocado: tags=device:pflash_cfi02
|
||||
"""
|
||||
tar_url = ('https://qemu-advcal.gitlab.io'
|
||||
'/qac-best-of-multiarch/download/day18.tar.xz')
|
||||
tar_hash = '068b5fc4242b29381acee94713509f8a876e9db6'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
self.set_machine('canon-a1100')
|
||||
|
||||
file_path = self.ASSET_BIOS.fetch()
|
||||
archive_extract(file_path, dest_dir=self.workdir,
|
||||
member="day18/barebox.canon-a1100.bin")
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios',
|
||||
self.workdir + '/day18/barebox.canon-a1100.bin')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'running /env/bin/init')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
56
tests/avocado/machine_arm_integratorcp.py → tests/functional/test_arm_integratorcp.py
Normal file → Executable file
56
tests/avocado/machine_arm_integratorcp.py → tests/functional/test_arm_integratorcp.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
@ -7,13 +9,15 @@
|
||||
#
|
||||
# This work is licensed under the terms of the GNU GPL, version 2 or
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import logging
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from unittest import skipUnless
|
||||
|
||||
|
||||
NUMPY_AVAILABLE = True
|
||||
@ -33,50 +37,49 @@ class IntegratorMachine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_KERNEL = Asset(
|
||||
('https://github.com/zayac/qemu-arm/raw/master/'
|
||||
'arm-test/kernel/zImage.integrator'),
|
||||
'26e7c7e8f943de785d95bd3c74d66451604a9b6a7a3d25dceb279e7548fd8e78')
|
||||
|
||||
ASSET_INITRD = Asset(
|
||||
('https://github.com/zayac/qemu-arm/raw/master/'
|
||||
'arm-test/kernel/arm_root.img'),
|
||||
'e187c27fb342ad148c7f33475fbed124933e0b3f4be8c74bc4f3426a4793373a')
|
||||
|
||||
ASSET_TUXLOGO = Asset(
|
||||
('https://github.com/torvalds/linux/raw/v2.6.12/'
|
||||
'drivers/video/logo/logo_linux_vga16.ppm'),
|
||||
'b762f0d91ec018887ad1b334543c2fdf9be9fdfc87672b409211efaa3ea0ef79')
|
||||
|
||||
def boot_integratorcp(self):
|
||||
kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/'
|
||||
'arm-test/kernel/zImage.integrator')
|
||||
kernel_hash = '0d7adba893c503267c946a3cbdc63b4b54f25468'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
|
||||
initrd_url = ('https://github.com/zayac/qemu-arm/raw/master/'
|
||||
'arm-test/kernel/arm_root.img')
|
||||
initrd_hash = 'b51e4154285bf784e017a37586428332d8c7bd8b'
|
||||
initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
initrd_path = self.ASSET_INITRD.fetch()
|
||||
|
||||
self.set_machine('integratorcp')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_path,
|
||||
'-initrd', initrd_path,
|
||||
'-append', 'printk.time=0 console=ttyAMA0')
|
||||
self.vm.launch()
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_integratorcp_console(self):
|
||||
"""
|
||||
Boots the Linux kernel and checks that the console is operational
|
||||
:avocado: tags=arch:arm
|
||||
:avocado: tags=machine:integratorcp
|
||||
:avocado: tags=device:pl011
|
||||
"""
|
||||
self.boot_integratorcp()
|
||||
wait_for_console_pattern(self, 'Log in as root')
|
||||
|
||||
@skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed')
|
||||
@skipUnless(CV2_AVAILABLE, 'Python OpenCV not installed')
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_framebuffer_tux_logo(self):
|
||||
"""
|
||||
Boot Linux and verify the Tux logo is displayed on the framebuffer.
|
||||
:avocado: tags=arch:arm
|
||||
:avocado: tags=machine:integratorcp
|
||||
:avocado: tags=device:pl110
|
||||
:avocado: tags=device:framebuffer
|
||||
"""
|
||||
screendump_path = os.path.join(self.workdir, "screendump.pbm")
|
||||
tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/'
|
||||
'drivers/video/logo/logo_linux_vga16.ppm')
|
||||
tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af'
|
||||
tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash)
|
||||
tuxlogo_path = self.ASSET_TUXLOGO.fetch()
|
||||
|
||||
self.boot_integratorcp()
|
||||
framebuffer_ready = 'Console: switching to colour frame buffer device'
|
||||
@ -97,3 +100,6 @@ class IntegratorMachine(QemuSystemTest):
|
||||
for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
|
||||
logger.debug('found Tux at position [x, y] = %s', pt)
|
||||
self.assertGreaterEqual(tux_count, cpu_count)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
22
tests/avocado/machine_avr6.py → tests/functional/test_avr_mega2560.py
Normal file → Executable file
22
tests/avocado/machine_avr6.py → tests/functional/test_avr_mega2560.py
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# QEMU AVR integration tests
|
||||
#
|
||||
@ -19,26 +20,24 @@
|
||||
|
||||
import time
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
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'
|
||||
'/AVR_ATMega2560_GCC/demo.elf'),
|
||||
'ee4833bd65fc69e84a79ed1c608affddbd499a60e63acf87d9113618401904e4')
|
||||
|
||||
def test_freertos(self):
|
||||
"""
|
||||
:avocado: tags=arch:avr
|
||||
:avocado: tags=machine:arduino-mega-2560-v3
|
||||
"""
|
||||
"""
|
||||
https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
|
||||
constantly prints out 'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX'
|
||||
"""
|
||||
rom_url = ('https://github.com/seharris/qemu-avr-tests'
|
||||
'/raw/36c3e67b8755dcf/free-rtos/Demo'
|
||||
'/AVR_ATMega2560_GCC/demo.elf')
|
||||
rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4'
|
||||
rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
|
||||
rom_path = self.ASSET_ROM.fetch()
|
||||
|
||||
self.set_machine('arduino-mega-2560-v3')
|
||||
self.vm.add_args('-bios', rom_path)
|
||||
self.vm.add_args('-nographic')
|
||||
self.vm.launch()
|
||||
@ -48,3 +47,6 @@ class AVR6Machine(QemuSystemTest):
|
||||
|
||||
self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
|
||||
self.vm.get_log())
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
12
tests/avocado/cpu_queries.py → tests/functional/test_cpu_queries.py
Normal file → Executable file
12
tests/avocado/cpu_queries.py → tests/functional/test_cpu_queries.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Sanity check of query-cpu-* results
|
||||
#
|
||||
# Copyright (c) 2019 Red Hat, Inc.
|
||||
@ -8,7 +10,7 @@
|
||||
# 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 avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
class QueryCPUModelExpansion(QemuSystemTest):
|
||||
"""
|
||||
@ -16,10 +18,7 @@ class QueryCPUModelExpansion(QemuSystemTest):
|
||||
"""
|
||||
|
||||
def test(self):
|
||||
"""
|
||||
:avocado: tags=arch:x86_64
|
||||
:avocado: tags=machine:none
|
||||
"""
|
||||
self.set_machine('none')
|
||||
self.vm.add_args('-S')
|
||||
self.vm.launch()
|
||||
|
||||
@ -33,3 +32,6 @@ class QueryCPUModelExpansion(QemuSystemTest):
|
||||
e = self.vm.cmd('query-cpu-model-expansion', model=model,
|
||||
type='full')
|
||||
self.assertEqual(e['model']['name'], c['name'])
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
7
tests/avocado/empty_cpu_model.py → tests/functional/test_empty_cpu_model.py
Normal file → Executable file
7
tests/avocado/empty_cpu_model.py → tests/functional/test_empty_cpu_model.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Check for crash when using empty -cpu option
|
||||
#
|
||||
# Copyright (c) 2019 Red Hat, Inc.
|
||||
@ -7,7 +9,7 @@
|
||||
#
|
||||
# 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 avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
class EmptyCPUModel(QemuSystemTest):
|
||||
def test(self):
|
||||
@ -17,3 +19,6 @@ class EmptyCPUModel(QemuSystemTest):
|
||||
self.vm.wait()
|
||||
self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1")
|
||||
self.assertRegex(self.vm.get_log(), r'-cpu option cannot be empty')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
11
tests/avocado/info_usernet.py → tests/functional/test_info_usernet.py
Normal file → Executable file
11
tests/avocado/info_usernet.py → tests/functional/test_info_usernet.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test for the hmp command "info usernet"
|
||||
#
|
||||
# Copyright (c) 2021 Red Hat, Inc.
|
||||
@ -8,18 +10,16 @@
|
||||
# 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 avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
from qemu.utils import get_info_usernet_hostfwd_port
|
||||
|
||||
|
||||
class InfoUsernet(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=machine:none
|
||||
"""
|
||||
|
||||
def test_hostfwd(self):
|
||||
self.require_netdev('user')
|
||||
self.set_machine('none')
|
||||
self.vm.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
|
||||
self.vm.launch()
|
||||
res = self.vm.cmd('human-monitor-command',
|
||||
@ -31,3 +31,6 @@ class InfoUsernet(QemuSystemTest):
|
||||
self.assertGreater(port, 0,
|
||||
('Found a redirected port that is not greater than'
|
||||
' zero'))
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
37
tests/avocado/linux_initrd.py → tests/functional/test_linux_initrd.py
Normal file → Executable file
37
tests/avocado/linux_initrd.py → tests/functional/test_linux_initrd.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Linux initrd integration test.
|
||||
#
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
@ -12,20 +14,27 @@ import os
|
||||
import logging
|
||||
import tempfile
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado import skipUnless
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from unittest import skipUnless
|
||||
|
||||
|
||||
class LinuxInitrd(QemuSystemTest):
|
||||
"""
|
||||
Checks QEMU evaluates correctly the initrd file passed as -initrd option.
|
||||
|
||||
:avocado: tags=arch:x86_64
|
||||
:avocado: tags=machine:pc
|
||||
"""
|
||||
|
||||
timeout = 300
|
||||
|
||||
ASSET_F18_KERNEL = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
|
||||
'releases/18/Fedora/x86_64/os/images/pxeboot/vmlinuz'),
|
||||
'1a27cb42559ce29237ac186699d063556ad69c8349d732bb1bd8d614e5a8cc2e')
|
||||
|
||||
ASSET_F28_KERNEL = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive/fedora/linux/'
|
||||
'releases/28/Everything/x86_64/os/images/pxeboot/vmlinuz'),
|
||||
'd05909c9d4a742a6fcc84dcc0361009e4611769619cc187a07107579a035f24e')
|
||||
|
||||
def test_with_2gib_file_should_exit_error_msg_with_linux_v3_6(self):
|
||||
"""
|
||||
Pretends to boot QEMU with an initrd file with size of 2GiB
|
||||
@ -33,10 +42,8 @@ class LinuxInitrd(QemuSystemTest):
|
||||
Fedora-18 shipped with linux-3.6 which have not supported xloadflags
|
||||
cannot support more than 2GiB initrd.
|
||||
"""
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora/li'
|
||||
'nux/releases/18/Fedora/x86_64/os/images/pxeboot/vmlinuz')
|
||||
kernel_hash = '41464f68efe42b9991250bed86c7081d2ccdbb21'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
self.set_machine('pc')
|
||||
kernel_path = self.ASSET_F18_KERNEL.fetch()
|
||||
max_size = 2 * (1024 ** 3) - 1
|
||||
|
||||
with tempfile.NamedTemporaryFile() as initrd:
|
||||
@ -56,16 +63,11 @@ class LinuxInitrd(QemuSystemTest):
|
||||
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
|
||||
def test_with_2gib_file_should_work_with_linux_v4_16(self):
|
||||
"""
|
||||
:avocado: tags=flaky
|
||||
|
||||
QEMU has supported up to 4 GiB initrd for recent kernel
|
||||
Expect guest can reach 'Unpacking initramfs...'
|
||||
"""
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora'
|
||||
'/linux/releases/28/Everything/x86_64/os/images/pxeboot/'
|
||||
'vmlinuz')
|
||||
kernel_hash = '238e083e114c48200f80d889f7e32eeb2793e02a'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
self.set_machine('pc')
|
||||
kernel_path = self.ASSET_F28_KERNEL.fetch()
|
||||
max_size = 2 * (1024 ** 3) + 1
|
||||
|
||||
with tempfile.NamedTemporaryFile() as initrd:
|
||||
@ -89,3 +91,6 @@ class LinuxInitrd(QemuSystemTest):
|
||||
break
|
||||
if 'Kernel panic - not syncing' in msg:
|
||||
self.fail("Kernel panic reached")
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
46
tests/avocado/machine_loongarch.py → tests/functional/test_loongarch64_virt.py
Normal file → Executable file
46
tests/avocado/machine_loongarch.py → tests/functional/test_loongarch64_virt.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
#
|
||||
# LoongArch virt test.
|
||||
@ -5,15 +7,28 @@
|
||||
# Copyright (c) 2023 Loongson Technology Corporation Limited
|
||||
#
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class LoongArchMachine(QemuSystemTest):
|
||||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
|
||||
timeout = 120
|
||||
|
||||
ASSET_KERNEL = Asset(
|
||||
('https://github.com/yangxiaojuan-loongson/qemu-binary/'
|
||||
'releases/download/2024-05-30/vmlinuz.efi'),
|
||||
'08b88a45f48a5fd92260bae895be4e5175be2397481a6f7821b9f39b2965b79e')
|
||||
ASSET_INITRD = Asset(
|
||||
('https://github.com/yangxiaojuan-loongson/qemu-binary/'
|
||||
'releases/download/2024-05-30/ramdisk'),
|
||||
'03d6fb6f8ee64ecac961120a0bdacf741f17b3bee2141f17fa01908c8baf176a')
|
||||
ASSET_BIOS = Asset(
|
||||
('https://github.com/yangxiaojuan-loongson/qemu-binary/'
|
||||
'releases/download/2024-05-30/QEMU_EFI.fd'),
|
||||
'937c1e7815e2340150c194a9f8f0474259038a3d7b8845ed62cc08163c46bea1')
|
||||
|
||||
def wait_for_console_pattern(self, success_message, vm=None):
|
||||
wait_for_console_pattern(self, success_message,
|
||||
failure_message='Kernel panic - not syncing',
|
||||
@ -21,25 +36,11 @@ class LoongArchMachine(QemuSystemTest):
|
||||
|
||||
def test_loongarch64_devices(self):
|
||||
|
||||
"""
|
||||
:avocado: tags=arch:loongarch64
|
||||
:avocado: tags=machine:virt
|
||||
"""
|
||||
self.set_machine('virt')
|
||||
|
||||
kernel_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/'
|
||||
'releases/download/2024-05-30/vmlinuz.efi')
|
||||
kernel_hash = '951b485b16e3788b6db03a3e1793c067009e31a2'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
|
||||
initrd_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/'
|
||||
'releases/download/2024-05-30/ramdisk')
|
||||
initrd_hash = 'c67658d9b2a447ce7db2f73ba3d373c9b2b90ab2'
|
||||
initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
|
||||
|
||||
bios_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/'
|
||||
'releases/download/2024-05-30/QEMU_EFI.fd')
|
||||
bios_hash = ('f4d0966b5117d4cd82327c050dd668741046be69')
|
||||
bios_path = self.fetch_asset(bios_url, asset_hash=bios_hash)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
initrd_path = self.ASSET_INITRD.fetch()
|
||||
bios_path = self.ASSET_BIOS.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
@ -56,3 +57,6 @@ class LoongArchMachine(QemuSystemTest):
|
||||
self.wait_for_console_pattern('Run /sbin/init as init process')
|
||||
exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
|
||||
'processor : 3')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
29
tests/avocado/machine_m68k_nextcube.py → tests/functional/test_m68k_nextcube.py
Normal file → Executable file
29
tests/avocado/machine_m68k_nextcube.py → tests/functional/test_m68k_nextcube.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a VM and run OCR on the framebuffer
|
||||
#
|
||||
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
@ -8,10 +10,10 @@
|
||||
import os
|
||||
import time
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado import skipUnless
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from unittest import skipUnless
|
||||
|
||||
from tesseract_utils import tesseract_available, tesseract_ocr
|
||||
from qemu_test.tesseract import tesseract_available, tesseract_ocr
|
||||
|
||||
PIL_AVAILABLE = True
|
||||
try:
|
||||
@ -21,19 +23,15 @@ except ImportError:
|
||||
|
||||
|
||||
class NextCubeMachine(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=arch:m68k
|
||||
:avocado: tags=machine:next-cube
|
||||
:avocado: tags=device:framebuffer
|
||||
"""
|
||||
|
||||
timeout = 15
|
||||
|
||||
ASSET_ROM = Asset(('https://sourceforge.net/p/previous/code/1350/tree/'
|
||||
'trunk/src/Rev_2.5_v66.BIN?format=raw'),
|
||||
'1b753890b67095b73e104c939ddf62eca9e7d0aedde5108e3893b0ed9d8000a4')
|
||||
|
||||
def check_bootrom_framebuffer(self, screenshot_path):
|
||||
rom_url = ('https://sourceforge.net/p/previous/code/1350/tree/'
|
||||
'trunk/src/Rev_2.5_v66.BIN?format=raw')
|
||||
rom_hash = 'b3534796abae238a0111299fc406a9349f7fee24'
|
||||
rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
|
||||
rom_path = self.ASSET_ROM.fetch()
|
||||
|
||||
self.vm.add_args('-bios', rom_path)
|
||||
self.vm.launch()
|
||||
@ -48,6 +46,7 @@ class NextCubeMachine(QemuSystemTest):
|
||||
|
||||
@skipUnless(PIL_AVAILABLE, 'Python PIL not installed')
|
||||
def test_bootrom_framebuffer_size(self):
|
||||
self.set_machine('next-cube')
|
||||
screenshot_path = os.path.join(self.workdir, "dump.ppm")
|
||||
self.check_bootrom_framebuffer(screenshot_path)
|
||||
|
||||
@ -60,11 +59,15 @@ class NextCubeMachine(QemuSystemTest):
|
||||
# that it is still alpha-level software.
|
||||
@skipUnless(tesseract_available(4), 'tesseract OCR tool not available')
|
||||
def test_bootrom_framebuffer_ocr_with_tesseract(self):
|
||||
self.set_machine('next-cube')
|
||||
screenshot_path = os.path.join(self.workdir, "dump.ppm")
|
||||
self.check_bootrom_framebuffer(screenshot_path)
|
||||
lines = tesseract_ocr(screenshot_path, tesseract_version=4)
|
||||
lines = tesseract_ocr(screenshot_path)
|
||||
text = '\n'.join(lines)
|
||||
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()
|
52
tests/avocado/mem-addr-space-check.py → tests/functional/test_mem_addr_space.py
Normal file → Executable file
52
tests/avocado/mem-addr-space-check.py → tests/functional/test_mem_addr_space.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Check for crash when using memory beyond the available guest processor
|
||||
# address space.
|
||||
#
|
||||
@ -8,7 +10,7 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
import time
|
||||
|
||||
class MemAddrCheck(QemuSystemTest):
|
||||
@ -22,9 +24,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
# for all 32-bit cases, pci64_hole_size is 0.
|
||||
def test_phybits_low_pse36(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
With pse36 feature ON, a processor has 36 bits of addressing. So it can
|
||||
access up to a maximum of 64GiB of memory. Memory hotplug region begins
|
||||
at 4 GiB boundary when "above_4g_mem_size" is 0 (this would be true when
|
||||
@ -52,9 +51,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_low_pae(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
With pae feature ON, a processor has 36 bits of addressing. So it can
|
||||
access up to a maximum of 64GiB of memory. Rest is the same as the case
|
||||
with pse36 above.
|
||||
@ -72,9 +68,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_pentium_pse36(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Setting maxmem to 59.5G and making sure that QEMU can start with the
|
||||
same options as the failing case above with pse36 cpu feature.
|
||||
"""
|
||||
@ -91,9 +84,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_pentium_pae(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Test is same as above but now with pae cpu feature turned on.
|
||||
Setting maxmem to 59.5G and making sure that QEMU can start fine
|
||||
with the same options as the case above.
|
||||
@ -111,9 +101,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_pentium2(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Pentium2 has 36 bits of addressing, so its same as pentium
|
||||
with pse36 ON.
|
||||
"""
|
||||
@ -130,9 +117,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_low_nonpse36(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Pentium processor has 32 bits of addressing without pse36 or pae
|
||||
so it can access physical address up to 4 GiB. Setting maxmem to
|
||||
4 GiB should make QEMU fail to start with "phys-bits too low"
|
||||
@ -153,9 +137,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
# now lets test some 64-bit CPU cases.
|
||||
def test_phybits_low_tcg_q35_70_amd(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
For q35 7.1 machines and above, there is a HT window that starts at
|
||||
1024 GiB and ends at 1 TiB - 1. If the max GPA falls in this range,
|
||||
"above_4G" memory is adjusted to start at 1 TiB boundary for AMD cpus
|
||||
@ -182,9 +163,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_low_tcg_q35_71_amd(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
AMD_HT_START is defined to be at 1012 GiB. So for q35 machines
|
||||
version > 7.0 and AMD cpus, instead of 1024 GiB limit for 40 bit
|
||||
processor address space, it has to be 1012 GiB , that is 12 GiB
|
||||
@ -205,9 +183,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_tcg_q35_70_amd(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Same as q35-7.0 AMD case except that here we check that QEMU can
|
||||
successfully start when maxmem is < 988G.
|
||||
"""
|
||||
@ -224,9 +199,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_tcg_q35_71_amd(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Same as q35-7.1 AMD case except that here we check that QEMU can
|
||||
successfully start when maxmem is < 976G.
|
||||
"""
|
||||
@ -243,9 +215,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_tcg_q35_71_intel(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Same parameters as test_phybits_low_tcg_q35_71_amd() but use
|
||||
Intel cpu instead. QEMU should start fine in this case as
|
||||
"above_4G" memory starts at 4G.
|
||||
@ -264,9 +233,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_low_tcg_q35_71_amd_41bits(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
AMD processor with 41 bits. Max cpu hw address = 2 TiB.
|
||||
By setting maxram above 1012 GiB - 32 GiB - 4 GiB = 976 GiB, we can
|
||||
force "above_4G" memory to start at 1 TiB for q35-7.1 machines
|
||||
@ -291,9 +257,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_tcg_q35_71_amd_41bits(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
AMD processor with 41 bits. Max cpu hw address = 2 TiB.
|
||||
Same as above but by setting maxram between 976 GiB and 992 Gib,
|
||||
QEMU should start fine.
|
||||
@ -312,9 +275,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_low_tcg_q35_intel_cxl(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
cxl memory window starts after memory device range. Here, we use 1 GiB
|
||||
of cxl window memory. 4G_mem end aligns at 4G. pci64_hole is 32 GiB and
|
||||
starts after the cxl memory window.
|
||||
@ -335,9 +295,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
|
||||
def test_phybits_ok_tcg_q35_intel_cxl(self):
|
||||
"""
|
||||
:avocado: tags=machine:q35
|
||||
:avocado: tags=arch:x86_64
|
||||
|
||||
Same as above but here we do not reserve any cxl memory window. Hence,
|
||||
with the exact same parameters as above, QEMU should start fine even
|
||||
with cxl enabled.
|
||||
@ -352,3 +309,6 @@ class MemAddrCheck(QemuSystemTest):
|
||||
time.sleep(self.DELAY_Q35_BOOT_SEQUENCE)
|
||||
self.vm.shutdown()
|
||||
self.assertNotRegex(self.vm.get_log(), r'phys-bits too low')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
40
tests/functional/test_microblaze_s3adsp1800.py
Executable file
40
tests/functional/test_microblaze_s3adsp1800.py
Executable file
@ -0,0 +1,40 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a microblaze Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2018, 2021 Red Hat, Inc.
|
||||
#
|
||||
# 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 time
|
||||
from qemu_test import exec_command, exec_command_and_wait_for_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
|
||||
class MicroblazeMachine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_IMAGE = Asset(
|
||||
('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/'
|
||||
'day17.tar.xz'),
|
||||
'3ba7439dfbea7af4876662c97f8e1f0cdad9231fc166e4861d17042489270057')
|
||||
|
||||
def test_microblaze_s3adsp1800(self):
|
||||
self.set_machine('petalogix-s3adsp1800')
|
||||
file_path = self.ASSET_IMAGE.fetch()
|
||||
archive_extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/day17/ballerina.bin')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'This architecture does not have '
|
||||
'kernel memory protection')
|
||||
# Note:
|
||||
# The kernel sometimes gets stuck after the "This architecture ..."
|
||||
# message, that's why we don't test for a later string here. This
|
||||
# needs some investigation by a microblaze wizard one day...
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
42
tests/functional/test_microblazeel_s3adsp1800.py
Executable file
42
tests/functional/test_microblazeel_s3adsp1800.py
Executable file
@ -0,0 +1,42 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a microblaze Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2018, 2021 Red Hat, Inc.
|
||||
#
|
||||
# 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 time
|
||||
from qemu_test import exec_command, exec_command_and_wait_for_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
|
||||
class MicroblazeelMachine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_IMAGE = Asset(
|
||||
('http://www.qemu-advent-calendar.org/2023/download/day13.tar.gz'),
|
||||
'b9b3d43c5dd79db88ada495cc6e0d1f591153fe41355e925d791fbf44de50c22')
|
||||
|
||||
def test_microblazeel_s3adsp1800(self):
|
||||
self.require_netdev('user')
|
||||
self.set_machine('petalogix-s3adsp1800')
|
||||
file_path = self.ASSET_IMAGE.fetch()
|
||||
archive_extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/day13/xmaton.bin')
|
||||
self.vm.add_args('-nic', 'user,tftp=' + self.workdir + '/day13/')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'QEMU Advent Calendar 2023')
|
||||
time.sleep(0.1)
|
||||
exec_command(self, 'root')
|
||||
time.sleep(0.1)
|
||||
exec_command_and_wait_for_pattern(self,
|
||||
'tftp -g -r xmaton.png 10.0.2.2 ; md5sum xmaton.png',
|
||||
'821cd3cab8efd16ad6ee5acc3642a8ea')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
33
tests/avocado/machine_mips_fuloong2e.py → tests/functional/test_mips64el_fuloong2e.py
Normal file → Executable file
33
tests/avocado/machine_mips_fuloong2e.py → tests/functional/test_mips64el_fuloong2e.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional tests for the Lemote Fuloong-2E machine.
|
||||
#
|
||||
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
@ -8,35 +10,36 @@
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test import QemuSystemTest
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from unittest import skipUnless
|
||||
|
||||
class MipsFuloong2e(QemuSystemTest):
|
||||
|
||||
timeout = 60
|
||||
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
@skipUnless(os.getenv('RESCUE_YL_PATH'), 'RESCUE_YL_PATH not available')
|
||||
def test_linux_kernel_isa_serial(self):
|
||||
"""
|
||||
:avocado: tags=arch:mips64el
|
||||
:avocado: tags=machine:fuloong2e
|
||||
:avocado: tags=endian:little
|
||||
:avocado: tags=device:bonito64
|
||||
:avocado: tags=device:via686b
|
||||
"""
|
||||
def test_linux_kernel_2_6_27_isa_serial(self):
|
||||
# Recovery system for the Yeeloong laptop
|
||||
# (enough to test the fuloong2e southbridge, accessing its ISA bus)
|
||||
# http://dev.lemote.com/files/resource/download/rescue/rescue-yl
|
||||
kernel_hash = 'ec4d1bd89a8439c41033ca63db60160cc6d6f09a'
|
||||
kernel_path = self.fetch_asset('file://' + os.getenv('RESCUE_YL_PATH'),
|
||||
asset_hash=kernel_hash)
|
||||
sha = 'ab588d3316777c62cc81baa20ac92e98b01955c244dff3794b711bc34e26e51d'
|
||||
kernel_path = os.getenv('RESCUE_YL_PATH')
|
||||
output = subprocess.check_output(['sha256sum', kernel_path])
|
||||
checksum = output.split()[0]
|
||||
assert checksum.decode("utf-8") == sha
|
||||
|
||||
self.set_machine('fuloong2e')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_path)
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'Linux version 2.6.27.7lemote')
|
||||
cpu_revision = 'CPU revision is: 00006302 (ICT Loongson-2)'
|
||||
wait_for_console_pattern(self, cpu_revision)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
39
tests/functional/test_mips64el_loongson3v.py
Executable file
39
tests/functional/test_mips64el_loongson3v.py
Executable file
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional tests for the Generic Loongson-3 Platform.
|
||||
#
|
||||
# Copyright (c) 2021 Jiaxun Yang <jiaxun.yang@flygoat.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.
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import os
|
||||
import time
|
||||
|
||||
from unittest import skipUnless
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class MipsLoongson3v(QemuSystemTest):
|
||||
timeout = 60
|
||||
|
||||
ASSET_PMON = Asset(
|
||||
('https://github.com/loongson-community/pmon/'
|
||||
'releases/download/20210112/pmon-3avirt.bin'),
|
||||
'fcdf6bb2cb7885a4a62f31fcb0d5e368bac7b6cea28f40c6dfa678af22fea20a')
|
||||
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_pmon_serial_console(self):
|
||||
self.set_machine('loongson3-virt')
|
||||
|
||||
pmon_path = self.ASSET_PMON.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', pmon_path)
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'CPU GODSON3 BogoMIPS:')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
51
tests/avocado/netdev-ethtool.py → tests/functional/test_netdev_ethtool.py
Normal file → Executable file
51
tests/avocado/netdev-ethtool.py → tests/functional/test_netdev_ethtool.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# ethtool tests for emulated network devices
|
||||
#
|
||||
# This test leverages ethtool's --test sequence to validate network
|
||||
@ -5,39 +7,33 @@
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-late
|
||||
|
||||
from avocado import skip
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from unittest import skip
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class NetDevEthtool(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=arch:x86_64
|
||||
:avocado: tags=machine:q35
|
||||
"""
|
||||
|
||||
# Runs in about 17s under KVM, 19s under TCG, 25s under GCOV
|
||||
timeout = 45
|
||||
|
||||
# Fetch assets from the netdev-ethtool subdir of my shared test
|
||||
# images directory on fileserver.linaro.org.
|
||||
def get_asset(self, name, sha1):
|
||||
base_url = ('https://fileserver.linaro.org/s/'
|
||||
'kE4nCFLdQcoBF9t/download?'
|
||||
'path=%2Fnetdev-ethtool&files=' )
|
||||
url = base_url + name
|
||||
# use explicit name rather than failing to neatly parse the
|
||||
# URL into a unique one
|
||||
return self.fetch_asset(name=name, locations=(url), asset_hash=sha1)
|
||||
ASSET_BASEURL = ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/'
|
||||
'download?path=%2Fnetdev-ethtool&files=')
|
||||
ASSET_BZIMAGE = Asset(
|
||||
ASSET_BASEURL + "bzImage",
|
||||
"ed62ee06ea620b1035747f3f66a5e9fc5d3096b29f75562ada888b04cd1c4baf")
|
||||
ASSET_ROOTFS = Asset(
|
||||
ASSET_BASEURL + "rootfs.squashfs",
|
||||
"8f0207e3c4d40832ae73c1a927e42ca30ccb1e71f047acb6ddb161ba422934e6")
|
||||
|
||||
def common_test_code(self, netdev, extra_args=None):
|
||||
self.set_machine('q35')
|
||||
|
||||
# This custom kernel has drivers for all the supported network
|
||||
# devices we can emulate in QEMU
|
||||
kernel = self.get_asset("bzImage",
|
||||
"33469d7802732d5815226166581442395cb289e2")
|
||||
|
||||
rootfs = self.get_asset("rootfs.squashfs",
|
||||
"9793cea7021414ae844bda51f558bd6565b50cdc")
|
||||
kernel = self.ASSET_BZIMAGE.fetch()
|
||||
rootfs = self.ASSET_ROOTFS.fetch()
|
||||
|
||||
append = 'printk.time=0 console=ttyS0 '
|
||||
append += 'root=/dev/sr0 rootfstype=squashfs '
|
||||
@ -68,15 +64,9 @@ class NetDevEthtool(QemuSystemTest):
|
||||
self.vm.kill()
|
||||
|
||||
def test_igb(self):
|
||||
"""
|
||||
:avocado: tags=device:igb
|
||||
"""
|
||||
self.common_test_code("igb")
|
||||
|
||||
def test_igb_nomsi(self):
|
||||
"""
|
||||
:avocado: tags=device:igb
|
||||
"""
|
||||
self.common_test_code("igb", "pci=nomsi")
|
||||
|
||||
# It seems the other popular cards we model in QEMU currently fail
|
||||
@ -88,14 +78,11 @@ class NetDevEthtool(QemuSystemTest):
|
||||
|
||||
@skip("Incomplete reg 0x00178 support")
|
||||
def test_e1000(self):
|
||||
"""
|
||||
:avocado: tags=device:e1000
|
||||
"""
|
||||
self.common_test_code("e1000")
|
||||
|
||||
@skip("Incomplete reg 0x00178 support")
|
||||
def test_i82550(self):
|
||||
"""
|
||||
:avocado: tags=device:i82550
|
||||
"""
|
||||
self.common_test_code("i82550")
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
11
tests/avocado/pc_cpu_hotplug_props.py → tests/functional/test_pc_cpu_hotplug_props.py
Normal file → Executable file
11
tests/avocado/pc_cpu_hotplug_props.py → tests/functional/test_pc_cpu_hotplug_props.py
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Ensure CPU die-id can be omitted on -device
|
||||
#
|
||||
@ -20,16 +21,16 @@
|
||||
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
class OmittedCPUProps(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=arch:x86_64
|
||||
:avocado: tags=cpu:qemu64
|
||||
"""
|
||||
|
||||
def test_no_die_id(self):
|
||||
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')
|
||||
self.vm.launch()
|
||||
self.assertEqual(len(self.vm.cmd('query-cpus-fast')), 2)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
52
tests/avocado/ppc_hv_tests.py → tests/functional/test_ppc64_hv.py
Normal file → Executable file
52
tests/avocado/ppc_hv_tests.py → tests/functional/test_ppc64_hv.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Tests that specifically try to exercise hypervisor features of the
|
||||
# target machines. powernv supports the Power hypervisor ISA, and
|
||||
# pseries supports the nested-HV hypervisor spec.
|
||||
@ -7,10 +9,9 @@
|
||||
# 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 avocado import skipIf, skipUnless
|
||||
from avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern, exec_command
|
||||
from unittest import skipIf, skipUnless
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern, exec_command
|
||||
import os
|
||||
import time
|
||||
import subprocess
|
||||
@ -45,8 +46,7 @@ def missing_deps():
|
||||
# QEMU already installed and use that.
|
||||
# XXX: The order of these tests seems to matter, see git blame.
|
||||
@skipIf(missing_deps(), 'dependencies (%s) not installed' % ','.join(deps))
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited')
|
||||
@skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited')
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), 'storage limited')
|
||||
class HypervisorTest(QemuSystemTest):
|
||||
|
||||
timeout = 1000
|
||||
@ -54,6 +54,11 @@ class HypervisorTest(QemuSystemTest):
|
||||
panic_message = 'Kernel panic - not syncing'
|
||||
good_message = 'VFS: Cannot open root device'
|
||||
|
||||
ASSET_ISO = Asset(
|
||||
('https://dl-cdn.alpinelinux.org/alpine/v3.18/'
|
||||
'releases/ppc64le/alpine-standard-3.18.4-ppc64le.iso'),
|
||||
'c26b8d3e17c2f3f0fed02b4b1296589c2390e6d5548610099af75300edd7b3ff')
|
||||
|
||||
def extract_from_iso(self, iso, path):
|
||||
"""
|
||||
Extracts a file from an iso file into the test workdir
|
||||
@ -72,6 +77,7 @@ class HypervisorTest(QemuSystemTest):
|
||||
subprocess.run(cmd.split(),
|
||||
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
|
||||
|
||||
os.chmod(filename, 0o600)
|
||||
os.chdir(cwd)
|
||||
|
||||
# Return complete path to extracted file. Because callers to
|
||||
@ -83,16 +89,9 @@ class HypervisorTest(QemuSystemTest):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
|
||||
iso_url = ('https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/ppc64le/alpine-standard-3.18.4-ppc64le.iso')
|
||||
|
||||
# Alpine use sha256 so I recalculated this myself
|
||||
iso_sha256 = 'c26b8d3e17c2f3f0fed02b4b1296589c2390e6d5548610099af75300edd7b3ff'
|
||||
iso_path = self.fetch_asset(iso_url, asset_hash=iso_sha256,
|
||||
algorithm = "sha256")
|
||||
|
||||
self.iso_path = iso_path
|
||||
self.vmlinuz = self.extract_from_iso(iso_path, '/boot/vmlinuz-lts')
|
||||
self.initramfs = self.extract_from_iso(iso_path, '/boot/initramfs-lts')
|
||||
self.iso_path = self.ASSET_ISO.fetch()
|
||||
self.vmlinuz = self.extract_from_iso(self.iso_path, '/boot/vmlinuz-lts')
|
||||
self.initramfs = self.extract_from_iso(self.iso_path, '/boot/initramfs-lts')
|
||||
|
||||
def do_start_alpine(self):
|
||||
self.vm.set_console()
|
||||
@ -158,12 +157,8 @@ class HypervisorTest(QemuSystemTest):
|
||||
wait_for_console_pattern(self, 'alpine:~#')
|
||||
|
||||
def test_hv_pseries(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('pseries')
|
||||
self.vm.add_args("-accel", "tcg,thread=multi")
|
||||
self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0')
|
||||
self.vm.add_args("-machine", "x-vof=on,cap-nested-hv=on")
|
||||
@ -173,12 +168,8 @@ class HypervisorTest(QemuSystemTest):
|
||||
self.do_stop_alpine()
|
||||
|
||||
def test_hv_pseries_kvm(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
:avocado: tags=accel:kvm
|
||||
"""
|
||||
self.require_accelerator("kvm")
|
||||
self.set_machine('pseries')
|
||||
self.vm.add_args("-accel", "kvm")
|
||||
self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0')
|
||||
self.vm.add_args("-machine", "x-vof=on,cap-nested-hv=on,cap-ccf-assist=off")
|
||||
@ -188,12 +179,8 @@ class HypervisorTest(QemuSystemTest):
|
||||
self.do_stop_alpine()
|
||||
|
||||
def test_hv_powernv(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:powernv
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('powernv')
|
||||
self.vm.add_args("-accel", "tcg,thread=multi")
|
||||
self.vm.add_args('-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234,drive=drive0',
|
||||
'-device', 'e1000e,netdev=net0,mac=C0:FF:EE:00:00:02,bus=pcie.0,addr=0x0',
|
||||
@ -203,3 +190,6 @@ class HypervisorTest(QemuSystemTest):
|
||||
self.do_test_kvm()
|
||||
self.do_test_kvm(True)
|
||||
self.do_stop_alpine()
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
56
tests/avocado/ppc_powernv.py → tests/functional/test_ppc64_powernv.py
Normal file → Executable file
56
tests/avocado/ppc_powernv.py → tests/functional/test_ppc64_powernv.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test that Linux kernel boots on ppc powernv machines and check the console
|
||||
#
|
||||
# Copyright (c) 2018, 2020 Red Hat, Inc.
|
||||
@ -5,9 +7,8 @@
|
||||
# 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 avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class powernvMachine(QemuSystemTest):
|
||||
|
||||
@ -16,13 +17,14 @@ class powernvMachine(QemuSystemTest):
|
||||
panic_message = 'Kernel panic - not syncing'
|
||||
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')
|
||||
|
||||
def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE):
|
||||
self.require_accelerator("tcg")
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/29/Everything/ppc64le/os'
|
||||
'/ppc/ppc64/vmlinuz')
|
||||
kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_path,
|
||||
@ -30,23 +32,13 @@ class powernvMachine(QemuSystemTest):
|
||||
self.vm.launch()
|
||||
|
||||
def test_linux_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:powernv
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
|
||||
self.set_machine('powernv')
|
||||
self.do_test_linux_boot()
|
||||
console_pattern = 'VFS: Cannot open root device'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
|
||||
def test_linux_smp_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:powernv
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
|
||||
self.set_machine('powernv')
|
||||
self.vm.add_args('-smp', '4')
|
||||
self.do_test_linux_boot()
|
||||
console_pattern = 'smp: Brought up 1 node, 4 CPUs'
|
||||
@ -54,12 +46,7 @@ class powernvMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_linux_smp_hpt_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:powernv
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
|
||||
self.set_machine('powernv')
|
||||
self.vm.add_args('-smp', '4')
|
||||
self.do_test_linux_boot(self.KERNEL_COMMON_COMMAND_LINE +
|
||||
'disable_radix')
|
||||
@ -70,12 +57,7 @@ class powernvMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_linux_smt_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:powernv
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
|
||||
self.set_machine('powernv')
|
||||
self.vm.add_args('-smp', '4,threads=4')
|
||||
self.do_test_linux_boot()
|
||||
console_pattern = 'CPU maps initialized for 4 threads per core'
|
||||
@ -85,12 +67,7 @@ class powernvMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_linux_big_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:powernv
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
|
||||
self.set_machine('powernv')
|
||||
self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2')
|
||||
|
||||
# powernv does not support NUMA
|
||||
@ -100,3 +77,6 @@ class powernvMachine(QemuSystemTest):
|
||||
console_pattern = 'smp: Brought up 2 nodes, 16 CPUs'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
56
tests/avocado/ppc_pseries.py → tests/functional/test_ppc64_pseries.py
Normal file → Executable file
56
tests/avocado/ppc_pseries.py → tests/functional/test_ppc64_pseries.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test that Linux kernel boots on ppc machines and check the console
|
||||
#
|
||||
# Copyright (c) 2018, 2020 Red Hat, Inc.
|
||||
@ -5,9 +7,8 @@
|
||||
# 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 avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class pseriesMachine(QemuSystemTest):
|
||||
|
||||
@ -16,12 +17,13 @@ class pseriesMachine(QemuSystemTest):
|
||||
panic_message = 'Kernel panic - not syncing'
|
||||
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')
|
||||
|
||||
def do_test_ppc64_linux_boot(self, kernel_command_line = KERNEL_COMMON_COMMAND_LINE):
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/29/Everything/ppc64le/os'
|
||||
'/ppc/ppc64/vmlinuz')
|
||||
kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', kernel_path,
|
||||
@ -29,32 +31,20 @@ class pseriesMachine(QemuSystemTest):
|
||||
self.vm.launch()
|
||||
|
||||
def test_ppc64_vof_linux_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
"""
|
||||
|
||||
self.set_machine('pseries')
|
||||
self.vm.add_args('-machine', 'x-vof=on')
|
||||
self.do_test_ppc64_linux_boot()
|
||||
console_pattern = 'VFS: Cannot open root device'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
|
||||
def test_ppc64_linux_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
"""
|
||||
|
||||
self.set_machine('pseries')
|
||||
self.do_test_ppc64_linux_boot()
|
||||
console_pattern = 'VFS: Cannot open root device'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
|
||||
def test_ppc64_linux_smp_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
"""
|
||||
|
||||
self.set_machine('pseries')
|
||||
self.vm.add_args('-smp', '4')
|
||||
self.do_test_ppc64_linux_boot()
|
||||
console_pattern = 'smp: Brought up 1 node, 4 CPUs'
|
||||
@ -62,11 +52,7 @@ class pseriesMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_ppc64_linux_hpt_smp_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
"""
|
||||
|
||||
self.set_machine('pseries')
|
||||
self.vm.add_args('-smp', '4')
|
||||
self.do_test_ppc64_linux_boot(self.KERNEL_COMMON_COMMAND_LINE +
|
||||
'disable_radix')
|
||||
@ -77,11 +63,6 @@ class pseriesMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_ppc64_linux_smt_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=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'
|
||||
@ -91,11 +72,7 @@ class pseriesMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
def test_ppc64_linux_big_boot(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc64
|
||||
:avocado: tags=machine:pseries
|
||||
"""
|
||||
|
||||
self.set_machine('pseries')
|
||||
self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2')
|
||||
self.vm.add_args('-m', '512M',
|
||||
'-object', 'memory-backend-ram,size=256M,id=m0',
|
||||
@ -108,3 +85,6 @@ class pseriesMachine(QemuSystemTest):
|
||||
console_pattern = 'smp: Brought up 2 nodes, 16 CPUs'
|
||||
wait_for_console_pattern(self, console_pattern, self.panic_message)
|
||||
wait_for_console_pattern(self, self.good_message, self.panic_message)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
29
tests/avocado/ppc_405.py → tests/functional/test_ppc_405.py
Normal file → Executable file
29
tests/avocado/ppc_405.py → tests/functional/test_ppc_405.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test that the U-Boot firmware boots on ppc 405 machines and check the console
|
||||
#
|
||||
# Copyright (c) 2021 Red Hat, Inc.
|
||||
@ -5,20 +7,21 @@
|
||||
# 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 avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
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 Ppc405Machine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_UBOOT = Asset(
|
||||
('https://gitlab.com/huth/u-boot/-/raw/taihu-2021-10-09/'
|
||||
'u-boot-taihu.bin'),
|
||||
'a076bb6cdeaafa406330e51e074b66d8878d9036d67d4caa0137be03ee4c112c')
|
||||
|
||||
def do_test_ppc405(self):
|
||||
uboot_url = ('https://gitlab.com/huth/u-boot/-/raw/'
|
||||
'taihu-2021-10-09/u-boot-taihu.bin')
|
||||
uboot_hash = ('3208940e908a5edc7c03eab072c60f0dcfadc2ab');
|
||||
file_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash)
|
||||
file_path = self.ASSET_UBOOT.fetch()
|
||||
self.vm.set_console(console_index=1)
|
||||
self.vm.add_args('-bios', file_path)
|
||||
self.vm.launch()
|
||||
@ -26,11 +29,9 @@ class Ppc405Machine(QemuSystemTest):
|
||||
exec_command_and_wait_for_pattern(self, 'reset', 'AMCC PowerPC 405EP')
|
||||
|
||||
def test_ppc_ref405ep(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:ref405ep
|
||||
:avocado: tags=cpu:405ep
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('ref405ep')
|
||||
self.do_test_ppc405()
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
65
tests/avocado/ppc_prep_40p.py → tests/functional/test_ppc_40p.py
Normal file → Executable file
65
tests/avocado/ppc_prep_40p.py → tests/functional/test_ppc_40p.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a PReP/40p machine and checks its serial console.
|
||||
#
|
||||
# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
|
||||
@ -7,39 +9,40 @@
|
||||
|
||||
import os
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from unittest import skipUnless
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
|
||||
class IbmPrep40pMachine(QemuSystemTest):
|
||||
|
||||
timeout = 60
|
||||
|
||||
ASSET_BIOS = Asset(
|
||||
('http://ftpmirror.your.org/pub/misc/'
|
||||
'ftp.software.ibm.com/rs6000/firmware/'
|
||||
'7020-40p/P12H0456.IMG'),
|
||||
'd957f79c73f760d1455d2286fcd901ed6d06167320eb73511b478a939be25b3f')
|
||||
ASSET_NETBSD40 = Asset(
|
||||
('https://archive.netbsd.org/pub/NetBSD-archive/'
|
||||
'NetBSD-4.0/prep/installation/floppy/generic_com0.fs'),
|
||||
'f86236e9d01b3f0dd0f5d3b8d5bbd40c68e78b4db560a108358f5ad58e636619')
|
||||
ASSET_NETBSD71 = Asset(
|
||||
('https://archive.netbsd.org/pub/NetBSD-archive/'
|
||||
'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso'),
|
||||
'cc7cb290b06aaa839362deb7bd9f417ac5015557db24088508330f76c3f825ec')
|
||||
|
||||
# 12H0455 PPS Firmware Licensed Materials
|
||||
# Property of IBM (C) Copyright IBM Corp. 1994.
|
||||
# All rights reserved.
|
||||
# U.S. Government Users Restricted Rights - Use, duplication or disclosure
|
||||
# restricted by GSA ADP Schedule Contract with IBM Corp.
|
||||
@skipUnless(os.getenv('AVOCADO_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
@skipUnless(os.getenv('QEMU_TEST_ALLOW_UNTRUSTED_CODE'), 'untrusted code')
|
||||
def test_factory_firmware_and_netbsd(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:40p
|
||||
:avocado: tags=os:netbsd
|
||||
:avocado: tags=slowness:high
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.set_machine('40p')
|
||||
self.require_accelerator("tcg")
|
||||
bios_url = ('http://ftpmirror.your.org/pub/misc/'
|
||||
'ftp.software.ibm.com/rs6000/firmware/'
|
||||
'7020-40p/P12H0456.IMG')
|
||||
bios_hash = '1775face4e6dc27f3a6ed955ef6eb331bf817f03'
|
||||
bios_path = self.fetch_asset(bios_url, asset_hash=bios_hash)
|
||||
drive_url = ('https://archive.netbsd.org/pub/NetBSD-archive/'
|
||||
'NetBSD-4.0/prep/installation/floppy/generic_com0.fs')
|
||||
drive_hash = 'dbcfc09912e71bd5f0d82c7c1ee43082fb596ceb'
|
||||
drive_path = self.fetch_asset(drive_url, asset_hash=drive_hash)
|
||||
bios_path = self.ASSET_BIOS.fetch()
|
||||
drive_path = self.ASSET_NETBSD40.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', bios_path,
|
||||
@ -50,11 +53,7 @@ class IbmPrep40pMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, 'Model: IBM PPS Model 6015')
|
||||
|
||||
def test_openbios_192m(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:40p
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.set_machine('40p')
|
||||
self.require_accelerator("tcg")
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-m', '192') # test fw_cfg
|
||||
@ -65,21 +64,15 @@ class IbmPrep40pMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,604')
|
||||
|
||||
def test_openbios_and_netbsd(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:40p
|
||||
:avocado: tags=os:netbsd
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.set_machine('40p')
|
||||
self.require_accelerator("tcg")
|
||||
drive_url = ('https://archive.netbsd.org/pub/NetBSD-archive/'
|
||||
'NetBSD-7.1.2/iso/NetBSD-7.1.2-prep.iso')
|
||||
drive_hash = 'ac6fa2707d888b36d6fa64de6e7fe48e'
|
||||
drive_path = self.fetch_asset(drive_url, asset_hash=drive_hash,
|
||||
algorithm='md5')
|
||||
drive_path = self.ASSET_NETBSD71.fetch()
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cdrom', drive_path,
|
||||
'-boot', 'd')
|
||||
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'NetBSD/prep BOOT, Revision 1.9')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
74
tests/avocado/ppc_74xx.py → tests/functional/test_ppc_74xx.py
Normal file → Executable file
74
tests/avocado/ppc_74xx.py → tests/functional/test_ppc_74xx.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Smoke tests for 74xx cpus (aka G4).
|
||||
#
|
||||
# Copyright (c) 2021, IBM Corp.
|
||||
@ -5,132 +7,120 @@
|
||||
# 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 avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test import QemuSystemTest
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class ppc74xxCpu(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
|
||||
timeout = 5
|
||||
|
||||
def test_ppc_7400(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7400
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7400')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7410(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7410
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7410')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,74xx')
|
||||
|
||||
def test_ppc_7441(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7441
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7441')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7445(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7445
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7445')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7447(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7447
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7447')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7447a(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7447a
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7447a')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7448(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7448
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7448')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,MPC86xx')
|
||||
|
||||
def test_ppc_7450(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7450
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7450')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7451(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7451
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7451')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7455(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7455
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7455')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7457(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7457
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7457')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
def test_ppc_7457a(self):
|
||||
"""
|
||||
:avocado: tags=cpu:7457a
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('g3beige')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-cpu', '7457a')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, '>> OpenBIOS')
|
||||
wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
43
tests/functional/test_ppc_amiga.py
Executable file
43
tests/functional/test_ppc_amiga.py
Executable file
@ -0,0 +1,43 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test AmigaNG boards
|
||||
#
|
||||
# Copyright (c) 2023 BALATON Zoltan
|
||||
#
|
||||
# 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 subprocess
|
||||
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern, run_cmd
|
||||
from zipfile import ZipFile
|
||||
|
||||
class AmigaOneMachine(QemuSystemTest):
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_IMAGE = Asset(
|
||||
('https://www.hyperion-entertainment.com/index.php/'
|
||||
'downloads?view=download&format=raw&file=25'),
|
||||
'8ff39330ba47d4f64de4ee8fd6809e9c010a9ef17fe51e95c3c1d53437cb481f')
|
||||
|
||||
def test_ppc_amigaone(self):
|
||||
self.require_accelerator("tcg")
|
||||
self.set_machine('amigaone')
|
||||
tar_name = 'A1Firmware_Floppy_05-Mar-2005.zip'
|
||||
zip_file = self.ASSET_IMAGE.fetch()
|
||||
with ZipFile(zip_file, 'r') as zf:
|
||||
zf.extractall(path=self.workdir)
|
||||
bios_fh = open(self.workdir + "/u-boot-amigaone.bin", "wb")
|
||||
subprocess.run(['tail', '-c', '524288',
|
||||
self.workdir + "/floppy_edition/updater.image"],
|
||||
stdout=bios_fh)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', self.workdir + '/u-boot-amigaone.bin')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'FLASH:')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
33
tests/avocado/ppc_bamboo.py → tests/functional/test_ppc_bamboo.py
Normal file → Executable file
33
tests/avocado/ppc_bamboo.py → tests/functional/test_ppc_bamboo.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test that Linux kernel boots on the ppc bamboo board and check the console
|
||||
#
|
||||
# Copyright (c) 2021 Red Hat
|
||||
@ -5,30 +7,26 @@
|
||||
# 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 avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
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):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:bamboo
|
||||
:avocado: tags=cpu:440epb
|
||||
:avocado: tags=device:rtl8139
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.set_machine('bamboo')
|
||||
self.require_accelerator("tcg")
|
||||
self.require_netdev('user')
|
||||
tar_url = ('http://landley.net/aboriginal/downloads/binaries/'
|
||||
'system-image-powerpc-440fp.tar.gz')
|
||||
tar_hash = '53e5f16414b195b82d2c70272f81c2eedb39bad9'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
file_path = self.ASSET_IMAGE.fetch()
|
||||
archive_extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir +
|
||||
'/system-image-powerpc-440fp/linux',
|
||||
@ -40,3 +38,6 @@ class BambooMachine(QemuSystemTest):
|
||||
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()
|
29
tests/avocado/ppc_mpc8544ds.py → tests/functional/test_ppc_mpc8544ds.py
Normal file → Executable file
29
tests/avocado/ppc_mpc8544ds.py → tests/functional/test_ppc_mpc8544ds.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test that Linux kernel boots on ppc machines and check the console
|
||||
#
|
||||
# Copyright (c) 2018, 2020 Red Hat, Inc.
|
||||
@ -5,9 +7,9 @@
|
||||
# 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 avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class Mpc8544dsMachine(QemuSystemTest):
|
||||
|
||||
@ -15,20 +17,21 @@ class Mpc8544dsMachine(QemuSystemTest):
|
||||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
panic_message = 'Kernel panic - not syncing'
|
||||
|
||||
ASSET_IMAGE = Asset(
|
||||
('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/'
|
||||
'day04.tar.xz'),
|
||||
'88bc83f3c9f3d633bcfc108a6342d677abca247066a2fb8d4636744a0d319f94')
|
||||
|
||||
def test_ppc_mpc8544ds(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:mpc8544ds
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
tar_url = ('https://qemu-advcal.gitlab.io'
|
||||
'/qac-best-of-multiarch/download/day04.tar.xz')
|
||||
tar_hash = 'f46724d281a9f30fa892d458be7beb7d34dc25f9'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
self.set_machine('mpc8544ds')
|
||||
file_path = self.ASSET_IMAGE.fetch()
|
||||
archive_extract(file_path, self.workdir, member='creek/creek.bin')
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/creek/creek.bin')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'QEMU advent calendar 2020',
|
||||
self.panic_message)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
29
tests/avocado/ppc_virtex_ml507.py → tests/functional/test_ppc_virtex_ml507.py
Normal file → Executable file
29
tests/avocado/ppc_virtex_ml507.py → tests/functional/test_ppc_virtex_ml507.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Test that Linux kernel boots on ppc machines and check the console
|
||||
#
|
||||
# Copyright (c) 2018, 2020 Red Hat, Inc.
|
||||
@ -5,9 +7,9 @@
|
||||
# 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 avocado.utils import archive
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
|
||||
class VirtexMl507Machine(QemuSystemTest):
|
||||
|
||||
@ -15,18 +17,16 @@ class VirtexMl507Machine(QemuSystemTest):
|
||||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
panic_message = 'Kernel panic - not syncing'
|
||||
|
||||
ASSET_IMAGE = Asset(
|
||||
('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/'
|
||||
'day08.tar.xz'),
|
||||
'cefe5b8aeb5e9d2d1d4fd22dcf48d917d68d5a765132bf2ddd6332dc393b824c')
|
||||
|
||||
def test_ppc_virtex_ml507(self):
|
||||
"""
|
||||
:avocado: tags=arch:ppc
|
||||
:avocado: tags=machine:virtex-ml507
|
||||
:avocado: tags=accel:tcg
|
||||
"""
|
||||
self.require_accelerator("tcg")
|
||||
tar_url = ('https://qemu-advcal.gitlab.io'
|
||||
'/qac-best-of-multiarch/download/day08.tar.xz')
|
||||
tar_hash = '74c68f5af7a7b8f21c03097b298f3bb77ff52c1f'
|
||||
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
|
||||
archive.extract(file_path, self.workdir)
|
||||
self.set_machine('virtex-ml507')
|
||||
file_path = self.ASSET_IMAGE.fetch()
|
||||
archive_extract(file_path, self.workdir)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', self.workdir + '/hippo/hippo.linux',
|
||||
'-dtb', self.workdir + '/hippo/virtex440-ml507.dtb',
|
||||
@ -34,3 +34,6 @@ class VirtexMl507Machine(QemuSystemTest):
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'QEMU advent calendar 2020',
|
||||
self.panic_message)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
54
tests/avocado/machine_rx_gdbsim.py → tests/functional/test_rx_gdbsim.py
Normal file → Executable file
54
tests/avocado/machine_rx_gdbsim.py → tests/functional/test_rx_gdbsim.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
@ -10,11 +12,11 @@
|
||||
|
||||
import os
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado.utils import archive
|
||||
from unittest import skipUnless
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import gzip_uncompress
|
||||
|
||||
|
||||
class RxGdbSimMachine(QemuSystemTest):
|
||||
@ -22,19 +24,25 @@ class RxGdbSimMachine(QemuSystemTest):
|
||||
timeout = 30
|
||||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
|
||||
ASSET_UBOOT = Asset(
|
||||
'https://acc.dl.osdn.jp/users/23/23888/u-boot.bin.gz',
|
||||
'7146567d669e91dbac166384b29aeba1715beb844c8551e904b86831bfd9d046')
|
||||
ASSET_DTB = Asset(
|
||||
'https://acc.dl.osdn.jp/users/23/23887/rx-virt.dtb',
|
||||
'aa278d9c1907a4501741d7ee57e7f65c02dd1b3e0323b33c6d4247f1b32cf29a')
|
||||
ASSET_KERNEL = Asset(
|
||||
'http://acc.dl.osdn.jp/users/23/23845/zImage',
|
||||
'baa43205e74a7220ed8482188c5e9ce497226712abb7f4e7e4f825ce19ff9656')
|
||||
|
||||
def test_uboot(self):
|
||||
"""
|
||||
U-Boot and checks that the console is operational.
|
||||
|
||||
:avocado: tags=arch:rx
|
||||
:avocado: tags=machine:gdbsim-r5f562n8
|
||||
:avocado: tags=endian:little
|
||||
:avocado: tags=flaky
|
||||
"""
|
||||
uboot_url = ('https://acc.dl.osdn.jp/users/23/23888/u-boot.bin.gz')
|
||||
uboot_hash = '9b78dbd43b40b2526848c0b1ce9de02c24f4dcdb'
|
||||
uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash)
|
||||
uboot_path = archive.uncompress(uboot_path, self.workdir)
|
||||
self.set_machine('gdbsim-r5f562n8')
|
||||
|
||||
uboot_path_gz = self.ASSET_UBOOT.fetch()
|
||||
uboot_path = os.path.join(self.workdir, 'u-boot.bin')
|
||||
gzip_uncompress(uboot_path_gz, uboot_path)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-bios', uboot_path,
|
||||
@ -50,18 +58,11 @@ class RxGdbSimMachine(QemuSystemTest):
|
||||
def test_linux_sash(self):
|
||||
"""
|
||||
Boots a Linux kernel and checks that the console is operational.
|
||||
|
||||
:avocado: tags=arch:rx
|
||||
:avocado: tags=machine:gdbsim-r5f562n7
|
||||
:avocado: tags=endian:little
|
||||
:avocado: tags=flaky
|
||||
"""
|
||||
dtb_url = ('https://acc.dl.osdn.jp/users/23/23887/rx-virt.dtb')
|
||||
dtb_hash = '7b4e4e2c71905da44e86ce47adee2210b026ac18'
|
||||
dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash)
|
||||
kernel_url = ('http://acc.dl.osdn.jp/users/23/23845/zImage')
|
||||
kernel_hash = '39a81067f8d72faad90866ddfefa19165d68fc99'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
self.set_machine('gdbsim-r5f562n7')
|
||||
|
||||
dtb_path = self.ASSET_DTB.fetch()
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'earlycon'
|
||||
@ -72,3 +73,6 @@ class RxGdbSimMachine(QemuSystemTest):
|
||||
wait_for_console_pattern(self, 'Sash command shell (version 1.1.1)',
|
||||
failure_message='Kernel panic - not syncing')
|
||||
exec_command_and_wait_for_pattern(self, 'printenv', 'TERM=linux')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
81
tests/avocado/machine_s390_ccw_virtio.py → tests/functional/test_s390x_ccw_virtio.py
Normal file → Executable file
81
tests/avocado/machine_s390_ccw_virtio.py → tests/functional/test_s390x_ccw_virtio.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots an s390x Linux guest with ccw and PCI devices
|
||||
# attached and checks whether the devices are recognized by Linux
|
||||
#
|
||||
@ -12,17 +14,38 @@
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from avocado import skipUnless
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado.utils import archive
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import lzma_uncompress
|
||||
|
||||
class S390CCWVirtioMachine(QemuSystemTest):
|
||||
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
|
||||
|
||||
timeout = 120
|
||||
|
||||
ASSET_BUSTER_KERNEL = Asset(
|
||||
('https://snapshot.debian.org/archive/debian/'
|
||||
'20201126T092837Z/dists/buster/main/installer-s390x/'
|
||||
'20190702+deb10u6/images/generic/kernel.debian'),
|
||||
'd411d17c39ae7ad38d27534376cbe88b68b403c325739364122c2e6f1537e818')
|
||||
ASSET_BUSTER_INITRD = Asset(
|
||||
('https://snapshot.debian.org/archive/debian/'
|
||||
'20201126T092837Z/dists/buster/main/installer-s390x/'
|
||||
'20190702+deb10u6/images/generic/initrd.debian'),
|
||||
'836bbd0fe6a5ca81274c28c2b063ea315ce1868660866e9b60180c575fef9fd5')
|
||||
|
||||
ASSET_F31_KERNEL = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/31/Server/s390x/os'
|
||||
'/images/kernel.img'),
|
||||
'480859574f3f44caa6cd35c62d70e1ac0609134e22ce2a954bbed9b110c06e0b')
|
||||
ASSET_F31_INITRD = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/31/Server/s390x/os'
|
||||
'/images/initrd.img'),
|
||||
'04c46095b2c49020b1c2327158898b7db747e4892ae319726192fb949716aa9c')
|
||||
|
||||
def wait_for_console_pattern(self, success_message, vm=None):
|
||||
wait_for_console_pattern(self, success_message,
|
||||
failure_message='Kernel panic - not syncing',
|
||||
@ -41,23 +64,10 @@ class S390CCWVirtioMachine(QemuSystemTest):
|
||||
self.dmesg_clear_count += 1
|
||||
|
||||
def test_s390x_devices(self):
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
|
||||
"""
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
|
||||
kernel_url = ('https://snapshot.debian.org/archive/debian/'
|
||||
'20201126T092837Z/dists/buster/main/installer-s390x/'
|
||||
'20190702+deb10u6/images/generic/kernel.debian')
|
||||
kernel_hash = '5821fbee57d6220a067a8b967d24595621aa1eb6'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
|
||||
initrd_url = ('https://snapshot.debian.org/archive/debian/'
|
||||
'20201126T092837Z/dists/buster/main/installer-s390x/'
|
||||
'20190702+deb10u6/images/generic/initrd.debian')
|
||||
initrd_hash = '81ba09c97bef46e8f4660ac25b4ac0a5be3a94d6'
|
||||
initrd_path = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
|
||||
kernel_path = self.ASSET_BUSTER_KERNEL.fetch()
|
||||
initrd_path = self.ASSET_BUSTER_INITRD.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
|
||||
@ -160,29 +170,13 @@ class S390CCWVirtioMachine(QemuSystemTest):
|
||||
|
||||
|
||||
def test_s390x_fedora(self):
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
|
||||
"""
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
:avocado: tags=device:virtio-gpu
|
||||
:avocado: tags=device:virtio-crypto
|
||||
:avocado: tags=device:virtio-net
|
||||
:avocado: tags=flaky
|
||||
"""
|
||||
kernel_path = self.ASSET_F31_KERNEL.fetch()
|
||||
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/31/Server/s390x/os'
|
||||
'/images/kernel.img')
|
||||
kernel_hash = 'b93d1efcafcf29c1673a4ce371a1f8b43941cfeb'
|
||||
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
|
||||
|
||||
initrd_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/31/Server/s390x/os'
|
||||
'/images/initrd.img')
|
||||
initrd_hash = '3de45d411df5624b8d8ef21cd0b44419ab59b12f'
|
||||
initrd_path_xz = self.fetch_asset(initrd_url, asset_hash=initrd_hash)
|
||||
initrd_path_xz = self.ASSET_F31_INITRD.fetch()
|
||||
initrd_path = os.path.join(self.workdir, 'initrd-raw.img')
|
||||
archive.lzma_uncompress(initrd_path_xz, initrd_path)
|
||||
lzma_uncompress(initrd_path_xz, initrd_path)
|
||||
|
||||
self.vm.set_console()
|
||||
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + ' audit=0 '
|
||||
@ -200,6 +194,8 @@ class S390CCWVirtioMachine(QemuSystemTest):
|
||||
'-device', 'virtio-rng-ccw,devno=fe.1.9876',
|
||||
'-device', 'virtio-gpu-ccw,devno=fe.2.5432')
|
||||
self.vm.launch()
|
||||
self.wait_for_console_pattern('Kernel command line: %s'
|
||||
% kernel_command_line)
|
||||
self.wait_for_console_pattern('Entering emergency mode')
|
||||
|
||||
# Some tests to see whether the CLI options have been considered:
|
||||
@ -275,3 +271,6 @@ class S390CCWVirtioMachine(QemuSystemTest):
|
||||
exec_command_and_wait_for_pattern(self,
|
||||
'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do'
|
||||
' sleep 1 ; done', 'Start virtcrypto_remove.')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
86
tests/avocado/s390_topology.py → tests/functional/test_s390x_topology.py
Normal file → Executable file
86
tests/avocado/s390_topology.py → tests/functional/test_s390x_topology.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a Linux kernel and checks the console
|
||||
#
|
||||
# Copyright IBM Corp. 2023
|
||||
@ -9,16 +11,13 @@
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
|
||||
import os
|
||||
import shutil
|
||||
import time
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import exec_command
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from avocado_qemu import interrupt_interactive_console_until_pattern
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado.utils import process
|
||||
from avocado.utils import archive
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import exec_command
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import lzma_uncompress
|
||||
|
||||
|
||||
class S390CPUTopology(QemuSystemTest):
|
||||
@ -47,6 +46,17 @@ class S390CPUTopology(QemuSystemTest):
|
||||
'root=/dev/ram '
|
||||
'selinux=0 '
|
||||
'rdinit=/bin/sh')
|
||||
ASSET_F35_KERNEL = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/35/Server/s390x/os'
|
||||
'/images/kernel.img'),
|
||||
'1f2dddfd11bb1393dd2eb2e784036fbf6fc11057a6d7d27f9eb12d3edc67ef73')
|
||||
|
||||
ASSET_F35_INITRD = Asset(
|
||||
('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/35/Server/s390x/os'
|
||||
'/images/initrd.img'),
|
||||
'1100145fbca00240c8c372ae4b89b48c99844bc189b3dfbc3f481dc60055ca46')
|
||||
|
||||
def wait_until_booted(self):
|
||||
wait_for_console_pattern(self, 'no job control',
|
||||
@ -78,21 +88,10 @@ class S390CPUTopology(QemuSystemTest):
|
||||
We need a minimal root filesystem with a shell.
|
||||
"""
|
||||
self.require_accelerator("kvm")
|
||||
kernel_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/35/Server/s390x/os'
|
||||
'/images/kernel.img')
|
||||
kernel_hash = '0d1aaaf303f07cf0160c8c48e56fe638'
|
||||
kernel_path = self.fetch_asset(kernel_url, algorithm='md5',
|
||||
asset_hash=kernel_hash)
|
||||
|
||||
initrd_url = ('https://archives.fedoraproject.org/pub/archive'
|
||||
'/fedora-secondary/releases/35/Server/s390x/os'
|
||||
'/images/initrd.img')
|
||||
initrd_hash = 'a122057d95725ac030e2ec51df46e172'
|
||||
initrd_path_xz = self.fetch_asset(initrd_url, algorithm='md5',
|
||||
asset_hash=initrd_hash)
|
||||
kernel_path = self.ASSET_F35_KERNEL.fetch()
|
||||
initrd_path_xz = self.ASSET_F35_INITRD.fetch()
|
||||
initrd_path = os.path.join(self.workdir, 'initrd-raw.img')
|
||||
archive.lzma_uncompress(initrd_path_xz, initrd_path)
|
||||
lzma_uncompress(initrd_path_xz, initrd_path)
|
||||
|
||||
self.vm.set_console()
|
||||
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE
|
||||
@ -115,10 +114,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
def test_single(self):
|
||||
"""
|
||||
This test checks the simplest topology with a single CPU.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.launch()
|
||||
self.wait_until_booted()
|
||||
@ -127,10 +124,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
def test_default(self):
|
||||
"""
|
||||
This test checks the implicit topology.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.add_args('-smp',
|
||||
'13,drawers=2,books=2,sockets=3,cores=2,maxcpus=24')
|
||||
@ -154,10 +149,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
"""
|
||||
This test checks the topology modification by moving a CPU
|
||||
to another socket: CPU 0 is moved from socket 0 to socket 2.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.add_args('-smp',
|
||||
'1,drawers=2,books=2,sockets=3,cores=2,maxcpus=24')
|
||||
@ -174,10 +167,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
"""
|
||||
This test verifies that a CPU defined with the '-device'
|
||||
command line option finds its right place inside the topology.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.add_args('-smp',
|
||||
'1,drawers=2,books=2,sockets=3,cores=2,maxcpus=24')
|
||||
@ -221,10 +212,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
"""
|
||||
This test verifies that QEMU modifies the entitlement change after
|
||||
several guest polarization change requests.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.launch()
|
||||
self.wait_until_booted()
|
||||
@ -267,10 +256,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
"""
|
||||
This test verifies that QEMU modifies the entitlement
|
||||
after a guest request and that the guest sees the change.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.launch()
|
||||
self.wait_until_booted()
|
||||
@ -313,10 +300,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
CPU is made dedicated.
|
||||
QEMU retains the entitlement value when horizontal polarization is in effect.
|
||||
For the guest, the field shows the effective value of the entitlement.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.launch()
|
||||
self.wait_until_booted()
|
||||
@ -345,10 +330,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
This test verifies that QEMU does not accept to overload a socket.
|
||||
The socket-id 0 on book-id 0 already contains CPUs 0 and 1 and can
|
||||
not accept any new CPU while socket-id 0 on book-id 1 is free.
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.add_args('-smp',
|
||||
'3,drawers=2,books=2,sockets=3,cores=2,maxcpus=24')
|
||||
@ -369,10 +352,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
"""
|
||||
This test verifies that QEMU refuses to lower the entitlement
|
||||
of a dedicated CPU
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.launch()
|
||||
self.wait_until_booted()
|
||||
@ -417,10 +398,8 @@ class S390CPUTopology(QemuSystemTest):
|
||||
"""
|
||||
This test verifies that QEMU refuses to move a CPU to an
|
||||
nonexistent location
|
||||
|
||||
:avocado: tags=arch:s390x
|
||||
:avocado: tags=machine:s390-ccw-virtio
|
||||
"""
|
||||
self.set_machine('s390-ccw-virtio')
|
||||
self.kernel_init()
|
||||
self.vm.launch()
|
||||
self.wait_until_booted()
|
||||
@ -437,3 +416,6 @@ class S390CPUTopology(QemuSystemTest):
|
||||
self.assertEqual(res['error']['class'], 'GenericError')
|
||||
|
||||
self.check_topology(0, 0, 0, 0, 'medium', False)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
41
tests/functional/test_sparc64_sun4u.py
Executable file
41
tests/functional/test_sparc64_sun4u.py
Executable file
@ -0,0 +1,41 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Functional test that boots a Linux kernel and checks the console
|
||||
#
|
||||
# Copyright (c) 2020 Red Hat, Inc.
|
||||
#
|
||||
# Author:
|
||||
# Thomas Huth <thuth@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
|
||||
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test.utils import archive_extract
|
||||
|
||||
class Sun4uMachine(QemuSystemTest):
|
||||
"""Boots the Linux kernel and checks that the console is operational"""
|
||||
|
||||
timeout = 90
|
||||
|
||||
ASSET_IMAGE = Asset(
|
||||
('https://qemu-advcal.gitlab.io/qac-best-of-multiarch/download/'
|
||||
'day23.tar.xz'),
|
||||
'a3ed92450704af244178351afd0e769776e7decb298e95a63abfd9a6e3f6c854')
|
||||
|
||||
def test_sparc64_sun4u(self):
|
||||
self.set_machine('sun4u')
|
||||
file_path = self.ASSET_IMAGE.fetch()
|
||||
kernel_name = 'day23/vmlinux'
|
||||
archive_extract(file_path, self.workdir, kernel_name)
|
||||
self.vm.set_console()
|
||||
self.vm.add_args('-kernel', os.path.join(self.workdir, kernel_name),
|
||||
'-append', 'printk.time=0')
|
||||
self.vm.launch()
|
||||
wait_for_console_pattern(self, 'Starting logging: OK')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
13
tests/avocado/version.py → tests/functional/test_version.py
Normal file → Executable file
13
tests/avocado/version.py → tests/functional/test_version.py
Normal file → Executable file
@ -1,3 +1,5 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Version check example test
|
||||
#
|
||||
# Copyright (c) 2018 Red Hat, Inc.
|
||||
@ -9,17 +11,18 @@
|
||||
# later. See the COPYING file in the top-level directory.
|
||||
|
||||
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
|
||||
class Version(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=quick
|
||||
:avocado: tags=machine:none
|
||||
"""
|
||||
|
||||
def test_qmp_human_info_version(self):
|
||||
self.set_machine('none')
|
||||
self.vm.add_args('-nodefaults')
|
||||
self.vm.launch()
|
||||
res = self.vm.cmd('human-monitor-command',
|
||||
command_line='info version')
|
||||
self.assertRegex(res, r'^(\d+\.\d+\.\d)')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
64
tests/avocado/virtio-gpu.py → tests/functional/test_virtio_gpu.py
Normal file → Executable file
64
tests/avocado/virtio-gpu.py → tests/functional/test_virtio_gpu.py
Normal file → Executable file
@ -1,14 +1,16 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# virtio-gpu tests
|
||||
#
|
||||
# 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 avocado_qemu import BUILD_DIR
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from avocado_qemu import wait_for_console_pattern
|
||||
from avocado_qemu import exec_command_and_wait_for_pattern
|
||||
from avocado_qemu import is_readable_executable_file
|
||||
from qemu_test import BUILD_DIR
|
||||
from qemu_test import QemuSystemTest, Asset
|
||||
from qemu_test import wait_for_console_pattern
|
||||
from qemu_test import exec_command_and_wait_for_pattern
|
||||
from qemu_test import is_readable_executable_file
|
||||
|
||||
from qemu.utils import kvm_available
|
||||
|
||||
@ -28,25 +30,18 @@ def pick_default_vug_bin():
|
||||
|
||||
|
||||
class VirtioGPUx86(QemuSystemTest):
|
||||
"""
|
||||
:avocado: tags=virtio-gpu
|
||||
:avocado: tags=arch:x86_64
|
||||
:avocado: tags=cpu:host
|
||||
"""
|
||||
|
||||
KERNEL_COMMAND_LINE = "printk.time=0 console=ttyS0 rdinit=/bin/bash"
|
||||
KERNEL_URL = (
|
||||
"https://archives.fedoraproject.org/pub/archive/fedora"
|
||||
"/linux/releases/33/Everything/x86_64/os/images"
|
||||
"/pxeboot/vmlinuz"
|
||||
)
|
||||
KERNEL_HASH = '1433cfe3f2ffaa44de4ecfb57ec25dc2399cdecf'
|
||||
INITRD_URL = (
|
||||
"https://archives.fedoraproject.org/pub/archive/fedora"
|
||||
"/linux/releases/33/Everything/x86_64/os/images"
|
||||
"/pxeboot/initrd.img"
|
||||
)
|
||||
INITRD_HASH = 'c828d68a027b53e5220536585efe03412332c2d9'
|
||||
ASSET_KERNEL = Asset(
|
||||
("https://archives.fedoraproject.org/pub/archive/fedora"
|
||||
"/linux/releases/33/Everything/x86_64/os/images"
|
||||
"/pxeboot/vmlinuz"),
|
||||
'2dc5fb5cfe9ac278fa45640f3602d9b7a08cc189ed63fd9b162b07073e4df397')
|
||||
ASSET_INITRD = Asset(
|
||||
("https://archives.fedoraproject.org/pub/archive/fedora"
|
||||
"/linux/releases/33/Everything/x86_64/os/images"
|
||||
"/pxeboot/initrd.img"),
|
||||
'c49b97f893a5349e4883452178763e402bdc5caa8845b226a2d1329b5f356045')
|
||||
|
||||
def wait_for_console_pattern(self, success_message, vm=None):
|
||||
wait_for_console_pattern(
|
||||
@ -57,16 +52,14 @@ class VirtioGPUx86(QemuSystemTest):
|
||||
)
|
||||
|
||||
def test_virtio_vga_virgl(self):
|
||||
"""
|
||||
:avocado: tags=device:virtio-vga-gl
|
||||
"""
|
||||
# FIXME: should check presence of virtio, virgl etc
|
||||
self.require_accelerator('kvm')
|
||||
|
||||
kernel_path = self.fetch_asset(self.KERNEL_URL, self.KERNEL_HASH)
|
||||
initrd_path = self.fetch_asset(self.INITRD_URL, self.INITRD_HASH)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
initrd_path = self.ASSET_INITRD.fetch()
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args("-cpu", "host")
|
||||
self.vm.add_args("-m", "2G")
|
||||
self.vm.add_args("-machine", "pc,accel=kvm")
|
||||
self.vm.add_args("-device", "virtio-vga-gl")
|
||||
@ -83,7 +76,7 @@ class VirtioGPUx86(QemuSystemTest):
|
||||
self.vm.launch()
|
||||
except:
|
||||
# TODO: probably fails because we are missing the VirGL features
|
||||
self.cancel("VirGL not enabled?")
|
||||
self.skipTest("VirGL not enabled?")
|
||||
|
||||
self.wait_for_console_pattern("as init process")
|
||||
exec_command_and_wait_for_pattern(
|
||||
@ -92,18 +85,15 @@ class VirtioGPUx86(QemuSystemTest):
|
||||
self.wait_for_console_pattern("features: +virgl +edid")
|
||||
|
||||
def test_vhost_user_vga_virgl(self):
|
||||
"""
|
||||
:avocado: tags=device:vhost-user-vga
|
||||
"""
|
||||
# FIXME: should check presence of vhost-user-gpu, virgl, memfd etc
|
||||
self.require_accelerator('kvm')
|
||||
|
||||
vug = pick_default_vug_bin()
|
||||
if not vug:
|
||||
self.cancel("Could not find vhost-user-gpu")
|
||||
self.skipTest("Could not find vhost-user-gpu")
|
||||
|
||||
kernel_path = self.fetch_asset(self.KERNEL_URL, self.KERNEL_HASH)
|
||||
initrd_path = self.fetch_asset(self.INITRD_URL, self.INITRD_HASH)
|
||||
kernel_path = self.ASSET_KERNEL.fetch()
|
||||
initrd_path = self.ASSET_INITRD.fetch()
|
||||
|
||||
# Create socketpair to connect proxy and remote processes
|
||||
qemu_sock, vug_sock = socket.socketpair(
|
||||
@ -129,6 +119,7 @@ class VirtioGPUx86(QemuSystemTest):
|
||||
)
|
||||
|
||||
self.vm.set_console()
|
||||
self.vm.add_args("-cpu", "host")
|
||||
self.vm.add_args("-m", "2G")
|
||||
self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
|
||||
self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
|
||||
@ -147,7 +138,7 @@ class VirtioGPUx86(QemuSystemTest):
|
||||
self.vm.launch()
|
||||
except:
|
||||
# TODO: probably fails because we are missing the VirGL features
|
||||
self.cancel("VirGL not enabled?")
|
||||
self.skipTest("VirGL not enabled?")
|
||||
self.wait_for_console_pattern("as init process")
|
||||
exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu",
|
||||
"features: +virgl +edid")
|
||||
@ -155,3 +146,6 @@ class VirtioGPUx86(QemuSystemTest):
|
||||
qemu_sock.close()
|
||||
vugp.terminate()
|
||||
vugp.wait()
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
8
tests/avocado/virtio_version.py → tests/functional/test_virtio_version.py
Normal file → Executable file
8
tests/avocado/virtio_version.py → tests/functional/test_virtio_version.py
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Check compatibility of virtio device types
|
||||
"""
|
||||
@ -12,7 +13,7 @@ import sys
|
||||
import os
|
||||
|
||||
from qemu.machine import QEMUMachine
|
||||
from avocado_qemu import QemuSystemTest
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
# Virtio Device IDs:
|
||||
VIRTIO_NET = 1
|
||||
@ -60,8 +61,6 @@ class VirtioVersionCheck(QemuSystemTest):
|
||||
Check if virtio-version-specific device types result in the
|
||||
same device tree created by `disable-modern` and
|
||||
`disable-legacy`.
|
||||
|
||||
:avocado: tags=arch:x86_64
|
||||
"""
|
||||
|
||||
# just in case there are failures, show larger diff:
|
||||
@ -173,3 +172,6 @@ class VirtioVersionCheck(QemuSystemTest):
|
||||
self.check_modern_only('virtio-mouse-pci', VIRTIO_INPUT)
|
||||
self.check_modern_only('virtio-tablet-pci', VIRTIO_INPUT)
|
||||
self.check_modern_only('virtio-keyboard-pci', VIRTIO_INPUT)
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
65
tests/avocado/x86_cpu_model_versions.py → tests/functional/test_x86_cpu_model_versions.py
Normal file → Executable file
65
tests/avocado/x86_cpu_model_versions.py → tests/functional/test_x86_cpu_model_versions.py
Normal file → Executable file
@ -1,3 +1,4 @@
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Basic validation of x86 versioned CPU models and CPU model aliases
|
||||
#
|
||||
@ -20,15 +21,13 @@
|
||||
# License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
|
||||
import avocado_qemu
|
||||
import re
|
||||
|
||||
class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
|
||||
from qemu_test import QemuSystemTest
|
||||
|
||||
class X86CPUModelAliases(QemuSystemTest):
|
||||
"""
|
||||
Validation of PC CPU model versions and CPU model aliases
|
||||
|
||||
:avocado: tags=arch:x86_64
|
||||
"""
|
||||
def validate_aliases(self, cpus):
|
||||
for c in cpus.values():
|
||||
@ -76,9 +75,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
|
||||
def test_4_0_alias_compatibility(self):
|
||||
"""
|
||||
Check if pc-*-4.0 unversioned CPU model won't be reported as aliases
|
||||
|
||||
:avocado: tags=machine:pc-i440fx-4.0
|
||||
"""
|
||||
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
|
||||
@ -110,9 +108,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
|
||||
def test_4_1_alias(self):
|
||||
"""
|
||||
Check if unversioned CPU model is an alias pointing to right version
|
||||
|
||||
:avocado: tags=machine:pc-i440fx-4.1
|
||||
"""
|
||||
self.set_machine('pc-i440fx-4.1')
|
||||
self.vm.add_args('-S')
|
||||
self.vm.launch()
|
||||
|
||||
@ -217,9 +214,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
|
||||
def test_none_alias(self):
|
||||
"""
|
||||
Check if unversioned CPU model is an alias pointing to some version
|
||||
|
||||
:avocado: tags=machine:none
|
||||
"""
|
||||
self.set_machine('none')
|
||||
self.vm.add_args('-S')
|
||||
self.vm.launch()
|
||||
|
||||
@ -243,21 +239,16 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
|
||||
self.validate_aliases(cpus)
|
||||
|
||||
|
||||
class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
class CascadelakeArchCapabilities(QemuSystemTest):
|
||||
"""
|
||||
Validation of Cascadelake arch-capabilities
|
||||
|
||||
:avocado: tags=arch:x86_64
|
||||
"""
|
||||
def get_cpu_prop(self, prop):
|
||||
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):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.1
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
self.set_machine('pc-i440fx-4.1')
|
||||
# machine-type only:
|
||||
self.vm.add_args('-S')
|
||||
self.set_vm_arg('-cpu',
|
||||
@ -268,10 +259,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
|
||||
|
||||
def test_4_0(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.0
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
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,'
|
||||
@ -281,10 +269,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
|
||||
|
||||
def test_set_4_0(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.0
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
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',
|
||||
@ -295,10 +280,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
|
||||
|
||||
def test_unset_4_1(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.1
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
self.set_machine('pc-i440fx-4.1')
|
||||
self.vm.add_args('-S')
|
||||
self.set_vm_arg('-cpu',
|
||||
'Cascadelake-Server,x-force-features=on,check=off,'
|
||||
@ -308,10 +290,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
|
||||
|
||||
def test_v1_4_0(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.0
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
self.set_machine('pc-i440fx-4.0')
|
||||
# versioned CPU model overrides machine-type:
|
||||
self.vm.add_args('-S')
|
||||
self.set_vm_arg('-cpu',
|
||||
@ -322,10 +301,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
|
||||
|
||||
def test_v2_4_0(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.0
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
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,'
|
||||
@ -335,10 +311,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
|
||||
|
||||
def test_v1_set_4_0(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.0
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
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',
|
||||
@ -349,10 +322,7 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
|
||||
|
||||
def test_v2_unset_4_1(self):
|
||||
"""
|
||||
:avocado: tags=machine:pc-i440fx-4.1
|
||||
:avocado: tags=cpu:Cascadelake-Server
|
||||
"""
|
||||
self.set_machine('pc-i440fx-4.1')
|
||||
self.vm.add_args('-S')
|
||||
self.set_vm_arg('-cpu',
|
||||
'Cascadelake-Server-v2,x-force-features=on,check=off,'
|
||||
@ -360,3 +330,6 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
|
||||
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')
|
||||
|
||||
if __name__ == '__main__':
|
||||
QemuSystemTest.main()
|
@ -85,3 +85,4 @@ subdir('unit')
|
||||
subdir('qapi-schema')
|
||||
subdir('qtest')
|
||||
subdir('migration')
|
||||
subdir('functional')
|
||||
|
Loading…
Reference in New Issue
Block a user