* 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:
Peter Maydell 2024-09-05 18:01:51 +01:00
commit eabebca69b
83 changed files with 2915 additions and 1841 deletions

View File

@ -59,6 +59,10 @@
- cd build - cd build
- find . -type f -exec touch {} + - find . -type f -exec touch {} +
# Avoid recompiling by hiding ninja with NINJA=":" # 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 - $MAKE NINJA=":" $MAKE_CHECK_ARGS
.native_test_job_template: .native_test_job_template:
@ -72,12 +76,13 @@
reports: reports:
junit: build/meson-logs/testlog.junit.xml junit: build/meson-logs/testlog.junit.xml
.avocado_test_job_template: .functional_test_job_template:
extends: .common_test_job_template extends: .common_test_job_template
cache: cache:
key: "${CI_JOB_NAME}-cache" key: "${CI_JOB_NAME}-cache"
paths: paths:
- ${CI_PROJECT_DIR}/avocado-cache - ${CI_PROJECT_DIR}/avocado-cache
- ${CI_PROJECT_DIR}/functional-cache
policy: pull-push policy: pull-push
artifacts: artifacts:
name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG" name: "$CI_JOB_NAME-$CI_COMMIT_REF_SLUG"
@ -86,6 +91,7 @@
paths: paths:
- build/tests/results/latest/results.xml - build/tests/results/latest/results.xml
- build/tests/results/latest/test-results - build/tests/results/latest/test-results
- build/tests/functional/*/*/*.log
reports: reports:
junit: build/tests/results/latest/results.xml junit: build/tests/results/latest/results.xml
before_script: before_script:
@ -96,11 +102,13 @@
- echo -e '[job.output.testlogs]\nstatuses = ["FAIL", "INTERRUPT"]' - echo -e '[job.output.testlogs]\nstatuses = ["FAIL", "INTERRUPT"]'
>> ~/.config/avocado/avocado.conf >> ~/.config/avocado/avocado.conf
- if [ -d ${CI_PROJECT_DIR}/avocado-cache ]; then - if [ -d ${CI_PROJECT_DIR}/avocado-cache ]; then
du -chs ${CI_PROJECT_DIR}/avocado-cache ; du -chs ${CI_PROJECT_DIR}/*-cache ;
fi fi
- export AVOCADO_ALLOW_UNTRUSTED_CODE=1 - 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: after_script:
- cd build - cd build
- du -chs ${CI_PROJECT_DIR}/avocado-cache - du -chs ${CI_PROJECT_DIR}/*-cache
variables: variables:
QEMU_JOB_AVOCADO: 1 QEMU_JOB_AVOCADO: 1

View File

@ -22,14 +22,14 @@ check-system-alpine:
IMAGE: alpine IMAGE: alpine
MAKE_CHECK_ARGS: check-unit check-qtest MAKE_CHECK_ARGS: check-unit check-qtest
avocado-system-alpine: functional-system-alpine:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-alpine - job: build-system-alpine
artifacts: true artifacts: true
variables: variables:
IMAGE: alpine IMAGE: alpine
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel AVOCADO_TAGS: arch:avr arch:loongarch64 arch:mips64 arch:mipsel
build-system-ubuntu: build-system-ubuntu:
@ -53,14 +53,14 @@ check-system-ubuntu:
IMAGE: ubuntu2204 IMAGE: ubuntu2204
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-system-ubuntu: functional-system-ubuntu:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-ubuntu - job: build-system-ubuntu
artifacts: true artifacts: true
variables: variables:
IMAGE: ubuntu2204 IMAGE: ubuntu2204
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
AVOCADO_TAGS: arch:alpha arch:microblazeel arch:mips64el AVOCADO_TAGS: arch:alpha arch:microblazeel arch:mips64el
build-system-debian: build-system-debian:
@ -85,14 +85,14 @@ check-system-debian:
IMAGE: debian IMAGE: debian
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-system-debian: functional-system-debian:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-debian - job: build-system-debian
artifacts: true artifacts: true
variables: variables:
IMAGE: debian 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 AVOCADO_TAGS: arch:arm arch:i386 arch:riscv64 arch:sh4 arch:sparc arch:xtensa
crash-test-debian: crash-test-debian:
@ -129,14 +129,14 @@ check-system-fedora:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-system-fedora: functional-system-fedora:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-fedora - job: build-system-fedora
artifacts: true artifacts: true
variables: variables:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k AVOCADO_TAGS: arch:microblaze arch:mips arch:xtensa arch:m68k
arch:riscv32 arch:ppc arch:sparc64 arch:riscv32 arch:ppc arch:sparc64
@ -243,14 +243,14 @@ check-system-centos:
IMAGE: centos9 IMAGE: centos9
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-system-centos: functional-system-centos:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-centos - job: build-system-centos
artifacts: true artifacts: true
variables: variables:
IMAGE: centos9 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 AVOCADO_TAGS: arch:ppc64 arch:or1k arch:s390x arch:x86_64 arch:rx
arch:sh4 arch:sh4
@ -274,14 +274,14 @@ check-system-opensuse:
IMAGE: opensuse-leap IMAGE: opensuse-leap
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-system-opensuse: functional-system-opensuse:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-opensuse - job: build-system-opensuse
artifacts: true artifacts: true
variables: variables:
IMAGE: opensuse-leap IMAGE: opensuse-leap
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
AVOCADO_TAGS: arch:s390x arch:x86_64 arch:aarch64 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 ppc64-softmmu rx-softmmu s390x-softmmu sh4-softmmu x86_64-softmmu
MAKE_CHECK_ARGS: check-build MAKE_CHECK_ARGS: check-build
avocado-system-flaky: functional-system-flaky:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-system-flaky - job: build-system-flaky
artifacts: true artifacts: true
allow_failure: true allow_failure: true
variables: variables:
IMAGE: debian IMAGE: debian
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
QEMU_JOB_OPTIONAL: 1 QEMU_JOB_OPTIONAL: 1
QEMU_TEST_FLAKY_TESTS: 1 QEMU_TEST_FLAKY_TESTS: 1
AVOCADO_TAGS: flaky AVOCADO_TAGS: flaky
@ -485,14 +485,14 @@ check-cfi-aarch64:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-cfi-aarch64: functional-cfi-aarch64:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-cfi-aarch64 - job: build-cfi-aarch64
artifacts: true artifacts: true
variables: variables:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
build-cfi-ppc64-s390x: build-cfi-ppc64-s390x:
extends: extends:
@ -523,14 +523,14 @@ check-cfi-ppc64-s390x:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-cfi-ppc64-s390x: functional-cfi-ppc64-s390x:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-cfi-ppc64-s390x - job: build-cfi-ppc64-s390x
artifacts: true artifacts: true
variables: variables:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
build-cfi-x86_64: build-cfi-x86_64:
extends: extends:
@ -557,14 +557,14 @@ check-cfi-x86_64:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check MAKE_CHECK_ARGS: check
avocado-cfi-x86_64: functional-cfi-x86_64:
extends: .avocado_test_job_template extends: .functional_test_job_template
needs: needs:
- job: build-cfi-x86_64 - job: build-cfi-x86_64
artifacts: true artifacts: true
variables: variables:
IMAGE: fedora IMAGE: fedora
MAKE_CHECK_ARGS: check-avocado MAKE_CHECK_ARGS: check-avocado check-functional
tsan-build: tsan-build:
extends: .native_build_job_template extends: .native_build_job_template

View File

@ -222,7 +222,7 @@ S: Maintained
F: docs/system/target-avr.rst F: docs/system/target-avr.rst
F: gdb-xml/avr-cpu.xml F: gdb-xml/avr-cpu.xml
F: target/avr/ F: target/avr/
F: tests/avocado/machine_avr6.py F: tests/functional/test_avr_mega2560.py
CRIS TCG CPUs CRIS TCG CPUs
M: Edgar E. Iglesias <edgar.iglesias@gmail.com> M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@ -266,7 +266,7 @@ M: Song Gao <gaosong@loongson.cn>
S: Maintained S: Maintained
F: target/loongarch/ F: target/loongarch/
F: tests/tcg/loongarch64/ F: tests/tcg/loongarch64/
F: tests/avocado/machine_loongarch.py F: tests/functional/test_loongarch64_virt.py
M68K TCG CPUs M68K TCG CPUs
M: Laurent Vivier <laurent@vivier.eu> M: Laurent Vivier <laurent@vivier.eu>
@ -318,6 +318,7 @@ F: configs/devices/ppc*
F: docs/system/ppc/embedded.rst F: docs/system/ppc/embedded.rst
F: docs/system/target-ppc.rst F: docs/system/target-ppc.rst
F: tests/tcg/ppc*/* F: tests/tcg/ppc*/*
F: tests/functional/test_ppc_74xx.py
RISC-V TCG CPUs RISC-V TCG CPUs
M: Palmer Dabbelt <palmer@dabbelt.com> M: Palmer Dabbelt <palmer@dabbelt.com>
@ -734,7 +735,7 @@ S: Odd Fixes
F: include/hw/arm/digic.h F: include/hw/arm/digic.h
F: hw/*/digic* F: hw/*/digic*
F: include/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 F: docs/system/arm/digic.rst
Goldfish RTC Goldfish RTC
@ -785,7 +786,7 @@ S: Maintained
F: hw/arm/integratorcp.c F: hw/arm/integratorcp.c
F: hw/misc/arm_integrator_debug.c F: hw/misc/arm_integrator_debug.c
F: include/hw/misc/arm_integrator_debug.h 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 F: docs/system/arm/integratorcp.rst
MCIMX6UL EVK / i.MX6ul MCIMX6UL EVK / i.MX6ul
@ -971,7 +972,7 @@ F: hw/misc/sbsa_ec.c
F: hw/watchdog/sbsa_gwdt.c F: hw/watchdog/sbsa_gwdt.c
F: include/hw/watchdog/sbsa_gwdt.h F: include/hw/watchdog/sbsa_gwdt.h
F: docs/system/arm/sbsa.rst 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 Sharp SL-5500 (Collie) PDA
M: Peter Maydell <peter.maydell@linaro.org> M: Peter Maydell <peter.maydell@linaro.org>
@ -1023,7 +1024,7 @@ S: Maintained
F: hw/arm/virt* F: hw/arm/virt*
F: include/hw/arm/virt.h F: include/hw/arm/virt.h
F: docs/system/arm/virt.rst F: docs/system/arm/virt.rst
F: tests/avocado/machine_aarch64_virt.py F: tests/functional/test_aarch64_virt.py
Xilinx Zynq Xilinx Zynq
M: Edgar E. Iglesias <edgar.iglesias@gmail.com> M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@ -1283,6 +1284,7 @@ S: Odd Fixes
F: hw/m68k/next-*.c F: hw/m68k/next-*.c
F: hw/display/next-fb.c F: hw/display/next-fb.c
F: include/hw/m68k/next-cube.h F: include/hw/m68k/next-cube.h
F: tests/functional/test_m68k_nextcube.py
q800 q800
M: Laurent Vivier <laurent@vivier.eu> M: Laurent Vivier <laurent@vivier.eu>
@ -1330,7 +1332,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
S: Maintained S: Maintained
F: hw/microblaze/petalogix_s3adsp1800_mmu.c F: hw/microblaze/petalogix_s3adsp1800_mmu.c
F: include/hw/char/xilinx_uartlite.h F: include/hw/char/xilinx_uartlite.h
F: tests/avocado/machine_microblaze.py F: tests/functional/test_microblaze*.py
petalogix_ml605 petalogix_ml605
M: Edgar E. Iglesias <edgar.iglesias@gmail.com> M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
@ -1383,7 +1385,7 @@ S: Odd Fixes
F: hw/mips/fuloong2e.c F: hw/mips/fuloong2e.c
F: hw/pci-host/bonito.c F: hw/pci-host/bonito.c
F: include/hw/pci-host/bonito.h 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 Loongson-3 virtual platforms
M: Huacai Chen <chenhuacai@kernel.org> 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_common.h
F: include/hw/intc/loongson_ipi.h F: include/hw/intc/loongson_ipi.h
F: include/hw/intc/loongson_liointc.h F: include/hw/intc/loongson_liointc.h
F: tests/avocado/machine_mips_loongson3v.py F: tests/functional/test_mips64el_loongson3v.py
Boston Boston
M: Paul Burton <paulburton@kernel.org> M: Paul Burton <paulburton@kernel.org>
@ -1424,14 +1426,14 @@ PowerPC Machines
L: qemu-ppc@nongnu.org L: qemu-ppc@nongnu.org
S: Orphan S: Orphan
F: hw/ppc/ppc405* F: hw/ppc/ppc405*
F: tests/avocado/ppc_405.py F: tests/functional/test_ppc_405.py
Bamboo Bamboo
L: qemu-ppc@nongnu.org L: qemu-ppc@nongnu.org
S: Orphan S: Orphan
F: hw/ppc/ppc440_bamboo.c F: hw/ppc/ppc440_bamboo.c
F: hw/pci-host/ppc4xx_pci.c F: hw/pci-host/ppc4xx_pci.c
F: tests/avocado/ppc_bamboo.py F: tests/functional/test_ppc_bamboo.py
e500 e500
L: qemu-ppc@nongnu.org L: qemu-ppc@nongnu.org
@ -1454,7 +1456,7 @@ L: qemu-ppc@nongnu.org
S: Orphan S: Orphan
F: hw/ppc/mpc8544ds.c F: hw/ppc/mpc8544ds.c
F: hw/ppc/mpc8544_guts.c F: hw/ppc/mpc8544_guts.c
F: tests/avocado/ppc_mpc8544ds.py F: tests/functional/test_ppc_mpc8544ds.py
New World (mac99) New World (mac99)
M: Mark Cave-Ayland <mark.cave-ayland@ilande.co.uk> 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: hw/rtc/m48t59-isa.c
F: include/hw/isa/pc87312.h F: include/hw/isa/pc87312.h
F: include/hw/rtc/m48t59.h F: include/hw/rtc/m48t59.h
F: tests/avocado/ppc_prep_40p.py F: tests/functional/test_ppc_40p.py
sPAPR (pseries) sPAPR (pseries)
M: Nicholas Piggin <npiggin@gmail.com> M: Nicholas Piggin <npiggin@gmail.com>
@ -1531,8 +1533,8 @@ F: tests/qtest/spapr*
F: tests/qtest/libqos/*spapr* F: tests/qtest/libqos/*spapr*
F: tests/qtest/rtas* F: tests/qtest/rtas*
F: tests/qtest/libqos/rtas* F: tests/qtest/libqos/rtas*
F: tests/avocado/ppc_pseries.py F: tests/functional/test_ppc64_pseries.py
F: tests/avocado/ppc_hv_tests.py F: tests/functional/test_ppc64_hv.py
PowerNV (Non-Virtualized) PowerNV (Non-Virtualized)
M: Cédric Le Goater <clg@kaod.org> M: Cédric Le Goater <clg@kaod.org>
@ -1549,6 +1551,7 @@ F: include/hw/ppc/pnv*
F: include/hw/pci-host/pnv* F: include/hw/pci-host/pnv*
F: pc-bios/skiboot.lid F: pc-bios/skiboot.lid
F: tests/qtest/pnv* F: tests/qtest/pnv*
F: tests/functional/test_ppc64_powernv.py
pca955x pca955x
M: Glenn Miles <milesg@linux.ibm.com> M: Glenn Miles <milesg@linux.ibm.com>
@ -1563,7 +1566,7 @@ M: Edgar E. Iglesias <edgar.iglesias@gmail.com>
L: qemu-ppc@nongnu.org L: qemu-ppc@nongnu.org
S: Odd Fixes S: Odd Fixes
F: hw/ppc/virtex_ml507.c F: hw/ppc/virtex_ml507.c
F: tests/avocado/ppc_virtex_ml507.py F: tests/functional/test_ppc_virtex_ml507.py
sam460ex sam460ex
M: BALATON Zoltan <balaton@eik.bme.hu> M: BALATON Zoltan <balaton@eik.bme.hu>
@ -1596,6 +1599,7 @@ S: Maintained
F: hw/ppc/amigaone.c F: hw/ppc/amigaone.c
F: hw/pci-host/articia.c F: hw/pci-host/articia.c
F: include/hw/pci-host/articia.h F: include/hw/pci-host/articia.h
F: tests/functional/test_ppc_amiga.py
Virtual Open Firmware (VOF) Virtual Open Firmware (VOF)
M: Alexey Kardashevskiy <aik@ozlabs.ru> M: Alexey Kardashevskiy <aik@ozlabs.ru>
@ -1662,7 +1666,7 @@ R: Yoshinori Sato <ysato@users.sourceforge.jp>
S: Orphan S: Orphan
F: docs/system/target-rx.rst F: docs/system/target-rx.rst
F: hw/rx/rx-gdbsim.c F: hw/rx/rx-gdbsim.c
F: tests/avocado/machine_rx_gdbsim.py F: tests/functional/test_rx_gdbsim.py
SH4 Machines SH4 Machines
------------ ------------
@ -1717,7 +1721,7 @@ F: include/hw/pci-host/sabre.h
F: hw/pci-bridge/simba.c F: hw/pci-bridge/simba.c
F: include/hw/pci-bridge/simba.h F: include/hw/pci-bridge/simba.h
F: pc-bios/openbios-sparc64 F: pc-bios/openbios-sparc64
F: tests/avocado/machine_sparc64_sun4u.py F: tests/functional/test_sparc64_sun4u.py
Sun4v Sun4v
M: Artyom Tarasenko <atar4qemu@gmail.com> M: Artyom Tarasenko <atar4qemu@gmail.com>
@ -1744,7 +1748,7 @@ S: Supported
F: hw/s390x/ F: hw/s390x/
F: include/hw/s390x/ F: include/hw/s390x/
F: configs/devices/s390x-softmmu/default.mak 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 T: git https://github.com/borntraeger/qemu.git s390-next
L: qemu-s390x@nongnu.org L: qemu-s390x@nongnu.org
@ -1807,7 +1811,7 @@ F: hw/s390x/cpu-topology.c
F: target/s390x/kvm/stsi-topology.c F: target/s390x/kvm/stsi-topology.c
F: docs/devel/s390-cpu-topology.rst F: docs/devel/s390-cpu-topology.rst
F: docs/system/s390x/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 X86 Machines
------------ ------------
@ -1835,6 +1839,9 @@ F: hw/isa/apm.c
F: include/hw/isa/apm.h F: include/hw/isa/apm.h
F: tests/unit/test-x86-topo.c F: tests/unit/test-x86-topo.c
F: tests/qtest/test-x86-cpuid-compat.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 PC Chipset
M: Michael S. Tsirkin <mst@redhat.com> 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/core/cpu.h
F: include/hw/cpu/cluster.h F: include/hw/cpu/cluster.h
F: include/sysemu/numa.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 F: tests/unit/test-smp-parse.c
T: git https://gitlab.com/ehabkost/qemu.git machine-next T: git https://gitlab.com/ehabkost/qemu.git machine-next
@ -2067,8 +2076,8 @@ ACPI/AVOCADO/BIOSBITS
M: Ani Sinha <anisinha@redhat.com> M: Ani Sinha <anisinha@redhat.com>
M: Michael S. Tsirkin <mst@redhat.com> M: Michael S. Tsirkin <mst@redhat.com>
S: Supported S: Supported
F: tests/avocado/acpi-bits/* F: tests/functional/acpi-bits/*
F: tests/avocado/acpi-bits.py F: tests/functional/test_acpi_bits.py
F: docs/devel/acpi-bits.rst F: docs/devel/acpi-bits.rst
ACPI/HEST/GHES ACPI/HEST/GHES
@ -2105,6 +2114,7 @@ S: Odd Fixes
F: hw/net/ F: hw/net/
F: include/hw/net/ F: include/hw/net/
F: tests/qtest/virtio-net-test.c F: tests/qtest/virtio-net-test.c
F: tests/functional/test_info_usernet.py
F: docs/virtio-net-failover.rst F: docs/virtio-net-failover.rst
T: git https://github.com/jasowang/qemu.git net T: git https://github.com/jasowang/qemu.git net
@ -2240,6 +2250,7 @@ F: net/vhost-user.c
F: include/hw/virtio/ F: include/hw/virtio/
F: docs/devel/virtio* F: docs/devel/virtio*
F: docs/devel/migration/virtio.rst F: docs/devel/migration/virtio.rst
F: tests/functional/test_virtio_version.py
virtio-balloon virtio-balloon
M: Michael S. Tsirkin <mst@redhat.com> M: Michael S. Tsirkin <mst@redhat.com>
@ -2490,7 +2501,7 @@ R: Sriram Yagnaraman <sriram.yagnaraman@ericsson.com>
S: Maintained S: Maintained
F: docs/system/devices/igb.rst F: docs/system/devices/igb.rst
F: hw/net/igb* 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/igb-test.c
F: tests/qtest/libqos/igb.c F: tests/qtest/libqos/igb.c
@ -2973,6 +2984,7 @@ S: Supported
F: include/qemu/option.h F: include/qemu/option.h
F: tests/unit/test-keyval.c F: tests/unit/test-keyval.c
F: tests/unit/test-qemu-opts.c F: tests/unit/test-qemu-opts.c
F: tests/functional/test_version.py
F: util/keyval.c F: util/keyval.c
F: util/qemu-option.c F: util/qemu-option.c
@ -4148,6 +4160,11 @@ F: .gitlab-ci.d/cirrus/freebsd*
F: tests/vm/freebsd F: tests/vm/freebsd
W: https://cirrus-ci.com/github/qemu/qemu 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 Windows Hosted Continuous Integration
M: Yonggang Luo <luoyonggang@gmail.com> M: Yonggang Luo <luoyonggang@gmail.com>
S: Maintained S: Maintained

View File

@ -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 Details about how QEMU's build system works. You will need to understand
into our testing infrastructure. You will need to understand some of some of the basics if you are adding new files and targets to the build.
the basics if you are adding new files and targets to the build.
.. toctree:: .. toctree::
:maxdepth: 3 :maxdepth: 3
@ -11,10 +10,5 @@ the basics if you are adding new files and targets to the build.
build-system build-system
kconfig kconfig
docs docs
testing
acpi-bits
qtest
ci
qapi-code-gen qapi-code-gen
fuzzing
control-flow-integrity control-flow-integrity

View File

@ -31,6 +31,7 @@ the :ref:`tcg_internals`.
index-process index-process
index-build index-build
testing/index
index-api index-api
index-internals index-internals
index-tcg index-tcg

View File

@ -1,6 +1,6 @@
============================================================================= ==================================
ACPI/SMBIOS avocado tests using biosbits ACPI/SMBIOS testing using biosbits
============================================================================= ==================================
************ ************
Introduction 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 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>`__. dependent submodules `here <https://gitlab.com/qemu-project/biosbits-bits>`__.
This fork contains numerous fixes, a newer acpica and changes specific to 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 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 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-/>`__. 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 Description of the test framework
********************************* *********************************
Under the directory ``tests/avocado/``, ``acpi-bits.py`` is a QEMU avocado Under the directory ``tests/functional/``, ``test_acpi_bits.py`` is a QEMU
test that drives all this. functional test that drives all this.
A brief description of the various test files follows. 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 │ ├── smbios.py2
│ ├── testacpi.py2 │ ├── testacpi.py2
│ └── testcpuid.py2 │ └── testcpuid.py2
├── acpi-bits.py ├── test_acpi_bits.py
* ``tests/avocado``: * ``tests/functional``:
``acpi-bits.py``: ``test_acpi_bits.py``:
This is the main python avocado test script that generates a 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 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 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 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. you to inspect and run the specific commands manually.
In order to run this test, please perform the following steps from the QEMU 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) $ export PYTHONPATH=../python:../tests/functional
$ ./pyvenv/bin/avocado run -t acpi tests/avocado $ 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. The above will run all acpi-bits functional tests (producing output in
In order to run the individual tests, perform the following: 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 * ``tests/functional/acpi-bits/bits-config``:
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``:
This location contains biosbits configuration files that determine how the This location contains biosbits configuration files that determine how the
software runs the tests. 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 or actions are performed by bits. The description of the config options are
provided in the file itself. 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 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 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. (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 (b) They are run from within the bios bits VM and is not subjected to QEMU
build/test python script maintenance and dependency resolutions. 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> Author: Ani Sinha <anisinha@redhat.com>

View 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``.

View 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

View 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

View File

@ -862,6 +862,18 @@ supported. To start the fuzzer, run
Alternatively, some command different from ``qemu-img info`` can be tested, by Alternatively, some command different from ``qemu-img info`` can be tested, by
changing the ``-c`` option. 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 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 higher level tests, and may interact with external resources and with
various guest operating systems. 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: You can run the avocado tests simply by executing:
.. code:: .. code::
make check-avocado make check-avocado
This involves the automatic installation, from PyPI, of all the See :ref:`checkavocado-ref` for more details.
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.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: .. _checktcg-ref:

Binary file not shown.

View File

@ -20,6 +20,7 @@
[meson] [meson]
# The install key should match the version in python/wheels/ # The install key should match the version in python/wheels/
meson = { accepted = ">=1.1.0", installed = "1.2.3", canary = "meson" } meson = { accepted = ">=1.1.0", installed = "1.2.3", canary = "meson" }
pycotap = { accepted = ">=1.1.0", installed = "1.3.1" }
[docs] [docs]
# Please keep the installed versions in sync with docs/requirements.txt # 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. # Note that qemu.git/python/ is always implicitly installed.
# Prefer an LTS version when updating the accepted versions of # Prefer an LTS version when updating the accepted versions of
# avocado-framework, for example right now the limit is 92.x. # 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" } pycdlib = { accepted = ">=1.11.0" }

View File

@ -3,28 +3,30 @@
.PHONY: check-help .PHONY: check-help
check-help: check-help:
@echo "Regression testing targets:" @echo "Regression testing targets:"
@echo " $(MAKE) check Run block, qapi-schema, unit, softfloat, qtest and decodetree tests" @echo " $(MAKE) check Run block, qapi-schema, unit, softfloat, qtest and decodetree tests"
@echo " $(MAKE) bench Run speed tests" @echo " $(MAKE) bench Run speed tests"
@echo @echo
@echo "Individual test suites:" @echo "Individual test suites:"
@echo " $(MAKE) check-qtest-TARGET Run qtest tests for given target" @echo " $(MAKE) check-qtest-TARGET Run qtest tests for given target"
@echo " $(MAKE) check-qtest Run qtest tests" @echo " $(MAKE) check-qtest Run qtest tests"
@echo " $(MAKE) check-unit Run qobject tests" @echo " $(MAKE) check-functional Run python-based functional tests"
@echo " $(MAKE) check-qapi-schema Run QAPI schema tests" @echo " $(MAKE) check-functional-TARGET Run functional tests for a given target"
@echo " $(MAKE) check-block Run block tests" @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),) ifneq ($(filter $(all-check-targets), check-softfloat),)
@echo " $(MAKE) check-tcg Run TCG tests" @echo " $(MAKE) check-tcg Run TCG tests"
@echo " $(MAKE) check-softfloat Run FPU emulation tests" @echo " $(MAKE) check-softfloat Run FPU emulation tests"
endif 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
@echo " $(MAKE) check-report.junit.xml Generates an aggregated XML test report" @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-venv Creates a Python venv for tests"
@echo " $(MAKE) check-clean Clean the tests and related data" @echo " $(MAKE) check-clean Clean the tests and related data"
@echo @echo
@echo "The following are useful for CI builds" @echo "The following are useful for CI builds"
@echo " $(MAKE) check-build Build most test binaries" @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) get-vm-images Downloads all images used by avocado tests, according to configured targets (~350 MB each, 1.5 GB max)"
@echo @echo
@echo @echo
@echo "The variable SPEED can be set to control the gtester speed setting." @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) \ --show=$(AVOCADO_SHOW) run --job-results-dir=$(TESTS_RESULTS_DIR) \
$(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \ $(if $(AVOCADO_TAGS),, --filter-by-tags-include-empty \
--filter-by-tags-include-empty-key) \ --filter-by-tags-include-empty-key) \
$(AVOCADO_CMDLINE_TAGS) \ $(AVOCADO_CMDLINE_TAGS) --max-parallel-tasks=1 \
$(if $(GITLAB_CI),,--failfast) $(AVOCADO_TESTS), \ $(if $(GITLAB_CI),,--failfast) $(AVOCADO_TESTS), \
"AVOCADO", "tests/avocado") "AVOCADO", "tests/avocado")
@ -152,6 +154,16 @@ check-acceptance-deprecated-warning:
check-acceptance: check-acceptance-deprecated-warning | check-avocado 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 # Consolidated targets
.PHONY: check check-clean get-vm-images .PHONY: check check-clean get-vm-images

View File

@ -384,23 +384,6 @@ class QemuSystemTest(QemuBaseTest):
super().tearDown() 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: class LinuxSSHMixIn:
"""Contains utility methods for interacting with a guest via SSH.""" """Contains utility methods for interacting with a guest via SSH."""

View File

@ -13,8 +13,8 @@ import shutil
from avocado.utils import cloudinit, datadrainer, process, vmimage from avocado.utils import cloudinit, datadrainer, process, vmimage
from . import LinuxSSHMixIn from avocado_qemu import LinuxSSHMixIn
from . import QemuSystemTest from avocado_qemu import QemuSystemTest
if os.path.islink(os.path.dirname(os.path.dirname(__file__))): if os.path.islink(os.path.dirname(os.path.dirname(__file__))):
# The link to the avocado tests dir in the source code directory # The link to the avocado tests dir in the source code directory

View File

@ -1304,26 +1304,6 @@ class BootLinuxConsole(LinuxKernelTest):
self.vm.launch() self.vm.launch()
self.wait_for_console_pattern('version UEFI Firmware v1.15') 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): def test_alpha_clipper(self):
""" """
:avocado: tags=arch:alpha :avocado: tags=arch:alpha

View File

@ -30,23 +30,22 @@ class BootXen(LinuxKernelTest):
timeout = 90 timeout = 90
XEN_COMMON_COMMAND_LINE = 'dom0_mem=128M loglvl=all guest_loglvl=all' 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 # Using my own built kernel - which works
kernel_url = ('https://fileserver.linaro.org/' kernel_url = ('https://fileserver.linaro.org/'
's/JSsewXGZ6mqxPr5/download?path=%2F&files=' 's/JSsewXGZ6mqxPr5/download?path=%2F&files='
'linux-5.9.9-arm64-ajb') 'linux-5.9.9-arm64-ajb')
kernel_sha1 = '4f92bc4b9f88d5ab792fa7a43a68555d344e1b83' kernel_sha1 = '4f92bc4b9f88d5ab792fa7a43a68555d344e1b83'
kernel_path = self.fetch_asset(kernel_url, self.kernel_path = self.fetch_asset(kernel_url,
asset_hash=kernel_sha1) asset_hash=kernel_sha1)
return kernel_path
def launch_xen(self, xen_path): def launch_xen(self, xen_path):
""" """
Launch Xen with a dom0 guest kernel Launch Xen with a dom0 guest kernel
""" """
self.log.info("launch with xen_path: %s", xen_path) self.log.info("launch with xen_path: %s", xen_path)
kernel_path = self.fetch_guest_kernel()
self.vm.set_console() self.vm.set_console()
@ -56,7 +55,7 @@ class BootXen(LinuxKernelTest):
'-append', self.XEN_COMMON_COMMAND_LINE, '-append', self.XEN_COMMON_COMMAND_LINE,
'-device', '-device',
'guest-loader,addr=0x47000000,kernel=%s,bootargs=console=hvc0' 'guest-loader,addr=0x47000000,kernel=%s,bootargs=console=hvc0'
% (kernel_path)) % (self.kernel_path))
self.vm.launch() self.vm.launch()

View File

@ -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
View File

View 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')

View File

@ -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:')

View File

@ -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')

View File

@ -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:')

View File

@ -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

View 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'])

View 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

View 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)

View 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')

View 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()

View 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

View 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()

View 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)

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a Linux kernel and checks the console # Functional test that boots a Linux kernel and checks the console
# #
# SPDX-FileCopyrightText: 2023-2024 Linaro Ltd. # SPDX-FileCopyrightText: 2023-2024 Linaro Ltd.
@ -8,26 +10,31 @@
import os import os
from avocado import skipUnless from qemu_test import QemuSystemTest, Asset
from avocado.utils import archive from qemu_test import wait_for_console_pattern
from qemu_test import interrupt_interactive_console_until_pattern
from avocado_qemu import QemuSystemTest from qemu_test.utils import lzma_uncompress
from avocado_qemu import wait_for_console_pattern from unittest import skipUnless
from avocado_qemu import interrupt_interactive_console_until_pattern
class Aarch64SbsarefMachine(QemuSystemTest): 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 As firmware runs at a higher privilege level than the hypervisor we
can only run these tests under TCG emulation. can only run these tests under TCG emulation.
""" """
timeout = 180 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): def fetch_firmware(self):
""" """
Flash volumes generated using: Flash volumes generated using:
@ -44,47 +51,31 @@ class Aarch64SbsarefMachine(QemuSystemTest):
""" """
# Secure BootRom (TF-A code) # Secure BootRom (TF-A code)
fs0_xz_url = ( fs0_xz_path = self.ASSET_FLASH0.fetch()
"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_path = os.path.join(self.workdir, "SBSA_FLASH0.fd") fs0_path = os.path.join(self.workdir, "SBSA_FLASH0.fd")
lzma_uncompress(fs0_xz_path, fs0_path)
# Non-secure rom (UEFI and EFI variables) # Non-secure rom (UEFI and EFI variables)
fs1_xz_url = ( fs1_xz_path = self.ASSET_FLASH1.fetch()
"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_path = os.path.join(self.workdir, "SBSA_FLASH1.fd") fs1_path = os.path.join(self.workdir, "SBSA_FLASH1.fd")
lzma_uncompress(fs1_xz_path, fs1_path)
for path in [fs0_path, fs1_path]: for path in [fs0_path, fs1_path]:
with open(path, "ab+") as fd: with open(path, "ab+") as fd:
fd.truncate(256 << 20) # Expand volumes to 256MiB fd.truncate(256 << 20) # Expand volumes to 256MiB
self.set_machine('sbsa-ref')
self.vm.set_console() self.vm.set_console()
self.vm.add_args( self.vm.add_args(
"-drive", "-drive", f"if=pflash,file={fs0_path},format=raw",
f"if=pflash,file={fs0_path},format=raw", "-drive", f"if=pflash,file={fs1_path},format=raw",
"-drive",
f"if=pflash,file={fs1_path},format=raw",
"-machine",
"sbsa-ref",
) )
def test_sbsaref_edk2_firmware(self): def test_sbsaref_edk2_firmware(self):
"""
:avocado: tags=cpu:cortex-a57
"""
self.fetch_firmware() self.fetch_firmware()
self.vm.add_args('-cpu', 'cortex-a57')
self.vm.launch() self.vm.launch()
# TF-A boot sequence: # TF-A boot sequence:
@ -110,87 +101,62 @@ class Aarch64SbsarefMachine(QemuSystemTest):
wait_for_console_pattern(self, "UEFI firmware (version 1.0") wait_for_console_pattern(self, "UEFI firmware (version 1.0")
interrupt_interactive_console_until_pattern(self, "QEMU SBSA-REF Machine") 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 # This tests the whole boot chain from EFI to Userspace
# We only boot a whole OS for the current top level CPU and GIC # We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots # Other test profiles should use more minimal boots
def boot_alpine_linux(self, cpu): def boot_alpine_linux(self, cpu):
self.fetch_firmware() self.fetch_firmware()
iso_url = ( iso_path = self.ASSET_ALPINE_ISO.fetch()
"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)
self.vm.set_console() self.vm.set_console()
self.vm.add_args( self.vm.add_args(
"-cpu", "-cpu", cpu,
cpu, "-drive", f"file={iso_path},media=cdrom,format=raw",
"-drive",
f"file={iso_path},format=raw",
) )
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, "Welcome to Alpine Linux 3.17") wait_for_console_pattern(self, "Welcome to Alpine Linux 3.17")
def test_sbsaref_alpine_linux_cortex_a57(self): def test_sbsaref_alpine_linux_cortex_a57(self):
"""
:avocado: tags=cpu:cortex-a57
:avocado: tags=os:linux
"""
self.boot_alpine_linux("cortex-a57") self.boot_alpine_linux("cortex-a57")
def test_sbsaref_alpine_linux_neoverse_n1(self): def test_sbsaref_alpine_linux_neoverse_n1(self):
"""
:avocado: tags=cpu:neoverse-n1
:avocado: tags=os:linux
"""
self.boot_alpine_linux("neoverse-n1") self.boot_alpine_linux("neoverse-n1")
def test_sbsaref_alpine_linux_max_pauth_off(self): def test_sbsaref_alpine_linux_max_pauth_off(self):
"""
:avocado: tags=cpu:max
:avocado: tags=os:linux
"""
self.boot_alpine_linux("max,pauth=off") self.boot_alpine_linux("max,pauth=off")
def test_sbsaref_alpine_linux_max_pauth_impdef(self): 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") 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): def test_sbsaref_alpine_linux_max(self):
"""
:avocado: tags=cpu:max
:avocado: tags=os:linux
"""
self.boot_alpine_linux("max") 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 # This tests the whole boot chain from EFI to Userspace
# We only boot a whole OS for the current top level CPU and GIC # We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots # Other test profiles should use more minimal boots
def boot_openbsd73(self, cpu): def boot_openbsd73(self, cpu):
self.fetch_firmware() self.fetch_firmware()
img_url = ( img_path = self.ASSET_OPENBSD_ISO.fetch()
"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)
self.vm.set_console() self.vm.set_console()
self.vm.add_args( self.vm.add_args(
"-cpu", "-cpu", cpu,
cpu, "-drive", f"file={img_path},format=raw,snapshot=on",
"-drive",
f"file={img_path},format=raw",
) )
self.vm.launch() self.vm.launch()
@ -199,38 +165,22 @@ class Aarch64SbsarefMachine(QemuSystemTest):
" 7.3 installation program.") " 7.3 installation program.")
def test_sbsaref_openbsd73_cortex_a57(self): def test_sbsaref_openbsd73_cortex_a57(self):
"""
:avocado: tags=cpu:cortex-a57
:avocado: tags=os:openbsd
"""
self.boot_openbsd73("cortex-a57") self.boot_openbsd73("cortex-a57")
def test_sbsaref_openbsd73_neoverse_n1(self): def test_sbsaref_openbsd73_neoverse_n1(self):
"""
:avocado: tags=cpu:neoverse-n1
:avocado: tags=os:openbsd
"""
self.boot_openbsd73("neoverse-n1") self.boot_openbsd73("neoverse-n1")
def test_sbsaref_openbsd73_max_pauth_off(self): def test_sbsaref_openbsd73_max_pauth_off(self):
"""
:avocado: tags=cpu:max
:avocado: tags=os:openbsd
"""
self.boot_openbsd73("max,pauth=off") 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): def test_sbsaref_openbsd73_max_pauth_impdef(self):
"""
:avocado: tags=cpu:max
:avocado: tags=os:openbsd
"""
self.boot_openbsd73("max,pauth-impdef=on") 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): def test_sbsaref_openbsd73_max(self):
"""
:avocado: tags=cpu:max
:avocado: tags=os:openbsd
"""
self.boot_openbsd73("max") self.boot_openbsd73("max")
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a various Linux systems and checks the # Functional test that boots a various Linux systems and checks the
# console output. # console output.
# #
@ -12,12 +14,11 @@ import time
import os import os
import logging import logging
from avocado_qemu import QemuSystemTest from qemu_test import BUILD_DIR
from avocado_qemu import wait_for_console_pattern from qemu_test import QemuSystemTest, Asset
from avocado_qemu import exec_command from qemu_test import exec_command, wait_for_console_pattern
from avocado_qemu import BUILD_DIR from qemu_test import get_qemu_img, run_cmd
from avocado.utils import process
from avocado.utils.path import find_command
class Aarch64VirtMachine(QemuSystemTest): class Aarch64VirtMachine(QemuSystemTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
@ -28,23 +29,18 @@ class Aarch64VirtMachine(QemuSystemTest):
failure_message='Kernel panic - not syncing', failure_message='Kernel panic - not syncing',
vm=vm) 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 # This tests the whole boot chain from EFI to Userspace
# We only boot a whole OS for the current top level CPU and GIC # We only boot a whole OS for the current top level CPU and GIC
# Other test profiles should use more minimal boots # Other test profiles should use more minimal boots
def test_alpine_virt_tcg_gic_max(self): def test_alpine_virt_tcg_gic_max(self):
""" iso_path = self.ASSET_ALPINE_ISO.fetch()
: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)
self.set_machine('virt')
self.vm.set_console() self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0') 'console=ttyAMA0')
@ -60,7 +56,7 @@ class Aarch64VirtMachine(QemuSystemTest):
self.vm.add_args("-smp", "2", "-m", "1024") self.vm.add_args("-smp", "2", "-m", "1024")
self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios', self.vm.add_args('-bios', os.path.join(BUILD_DIR, 'pc-bios',
'edk2-aarch64-code.fd')) '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('-device', 'virtio-rng-pci,rng=rng0')
self.vm.add_args('-object', 'rng-random,id=rng0,filename=/dev/urandom') 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') 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): def common_aarch64_virt(self, machine):
""" """
Common code to launch basic virt machine with kernel+initrd Common code to launch basic virt machine with kernel+initrd
@ -75,11 +76,9 @@ class Aarch64VirtMachine(QemuSystemTest):
""" """
logger = logging.getLogger('aarch64_virt') logger = logging.getLogger('aarch64_virt')
kernel_url = ('https://fileserver.linaro.org/s/' kernel_path = self.ASSET_KERNEL.fetch()
'z6B2ARM7DQT3HWN/download')
kernel_hash = 'ed11daab50c151dde0e1e9c9cb8b2d9bd3215347'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.set_machine('virt')
self.vm.set_console() self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
'console=ttyAMA0') 'console=ttyAMA0')
@ -98,14 +97,8 @@ class Aarch64VirtMachine(QemuSystemTest):
# Also add a scratch block device # Also add a scratch block device
logger.info('creating scratch qcow2 image') logger.info('creating scratch qcow2 image')
image_path = os.path.join(self.workdir, 'scratch.qcow2') image_path = os.path.join(self.workdir, 'scratch.qcow2')
qemu_img = os.path.join(BUILD_DIR, 'qemu-img') qemu_img = get_qemu_img(self)
if not os.path.exists(qemu_img): run_cmd([qemu_img, 'create', '-f', 'qcow2', image_path, '8M'])
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)
# Add the device # Add the device
self.vm.add_args('-blockdev', self.vm.add_args('-blockdev',
@ -128,19 +121,11 @@ class Aarch64VirtMachine(QemuSystemTest):
time.sleep(0.1) time.sleep(0.1)
def test_aarch64_virt_gicv3(self): 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") self.common_aarch64_virt("virt,gic_version=3")
def test_aarch64_virt_gicv2(self): 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") self.common_aarch64_virt("virt,gic-version=2")
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,5 +1,5 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# group: rw quick #
# Exercise QEMU generated ACPI/SMBIOS tables using biosbits, # Exercise QEMU generated ACPI/SMBIOS tables using biosbits,
# https://biosbits.org/ # https://biosbits.org/
# #
@ -24,7 +24,7 @@
# pylint: disable=consider-using-f-string # 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/. Biosbits is available originally at https://biosbits.org/.
This test uses a fork of the upstream bits and has numerous fixes This test uses a fork of the upstream bits and has numerous fixes
including an upgraded acpica. The fork is located here: including an upgraded acpica. The fork is located here:
@ -41,15 +41,16 @@ import tarfile
import tempfile import tempfile
import time import time
import zipfile import zipfile
from pathlib import Path
from typing import ( from typing import (
List, List,
Optional, Optional,
Sequence, Sequence,
) )
from qemu.machine import QEMUMachine from qemu.machine import QEMUMachine
from avocado import skipIf from unittest import skipIf
from avocado.utils import datadrainer as drainer from qemu_test import QemuBaseTest, Asset
from avocado_qemu import QemuBaseTest
deps = ["xorriso", "mformat"] # dependent tools needed in the test setup/box. deps = ["xorriso", "mformat"] # dependent tools needed in the test setup/box.
supported_platforms = ['x86_64'] # supported test platforms. 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 class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
""" """
ACPI and SMBIOS tests using biosbits. 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. # in slower systems the test can take as long as 3 minutes to complete.
timeout = BITS_TIMEOUT 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): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._vm = None self._vm = None
self._workDir = None self._workDir = None
self._baseDir = 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_addr = '0x403'
self._debugcon_log = 'debugcon-log.txt' self._debugcon_log = 'debugcon-log.txt'
logging.basicConfig(level=logging.INFO) self.logger = self.log
self.logger = logging.getLogger('acpi-bits')
def _print_log(self, log): def _print_log(self, log):
self.logger.info('\nlogs from biosbits follows:') 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_dir = os.path.join(self._baseDir, 'acpi-bits',
'bits-config') 'bits-config')
target_config_dir = os.path.join(self._workDir, target_config_dir = os.path.join(self._workDir,
'bits-%d' %self._bitsInternalVer, 'bits-%d' %self.BITS_INTERNAL_VER,
'boot') 'boot')
self.assertTrue(os.path.exists(bits_config_dir)) self.assertTrue(os.path.exists(bits_config_dir))
self.assertTrue(os.path.exists(target_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_test_dir = os.path.join(self._baseDir, 'acpi-bits',
'bits-tests') 'bits-tests')
target_test_dir = os.path.join(self._workDir, target_test_dir = os.path.join(self._workDir,
'bits-%d' %self._bitsInternalVer, 'bits-%d' %self.BITS_INTERNAL_VER,
'boot', 'python') 'boot', 'python')
self.assertTrue(os.path.exists(bits_test_dir)) self.assertTrue(os.path.exists(bits_test_dir))
@ -248,9 +247,9 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
test scripts test scripts
""" """
bits_dir = os.path.join(self._workDir, bits_dir = os.path.join(self._workDir,
'bits-%d' %self._bitsInternalVer) 'bits-%d' %self.BITS_INTERNAL_VER)
iso_file = os.path.join(self._workDir, 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, mkrescue_script = os.path.join(self._workDir,
'grub-inst-x86_64-efi', 'bin', 'grub-inst-x86_64-efi', 'bin',
'grub-mkrescue') 'grub-mkrescue')
@ -264,8 +263,12 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
try: try:
if os.getenv('V') or os.getenv('BITS_DEBUG'): if os.getenv('V') or os.getenv('BITS_DEBUG'):
subprocess.check_call([mkrescue_script, '-o', iso_file, proc = subprocess.run([mkrescue_script, '-o', iso_file,
bits_dir], stderr=subprocess.STDOUT) bits_dir],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
check=True)
self.logger.info("grub-mkrescue output %s" % proc.stdout)
else: else:
subprocess.check_call([mkrescue_script, '-o', subprocess.check_call([mkrescue_script, '-o',
iso_file, bits_dir], iso_file, bits_dir],
@ -282,8 +285,9 @@ class AcpiBitsTest(QemuBaseTest): #pylint: disable=too-many-instance-attributes
def setUp(self): # pylint: disable=arguments-differ def setUp(self): # pylint: disable=arguments-differ
super().setUp('qemu-system-') 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. # workdir could also be avocado's own workdir in self.workdir.
# At present, I prefer to maintain my own temporary working # 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) os.mkdir(prebuiltDir, mode=0o775)
bits_zip_file = os.path.join(prebuiltDir, 'bits-%d-%s.zip' bits_zip_file = os.path.join(prebuiltDir, 'bits-%d-%s.zip'
%(self._bitsInternalVer, %(self.BITS_INTERNAL_VER,
self._bitsCommitHash)) self.BITS_COMMIT_HASH))
grub_tar_file = os.path.join(prebuiltDir, grub_tar_file = os.path.join(prebuiltDir,
'bits-%d-%s-grub.tar.gz' 'bits-%d-%s-grub.tar.gz'
%(self._bitsInternalVer, %(self.BITS_INTERNAL_VER,
self._bitsCommitHash)) self.BITS_COMMIT_HASH))
bitsLocalArtLoc = self.fetch_asset(self._bitsArtURL, bitsLocalArtLoc = self.ASSET_BITS.fetch()
asset_hash=self._bitsArtSHA1Hash)
self.logger.info("downloaded bits artifacts to %s", bitsLocalArtLoc) self.logger.info("downloaded bits artifacts to %s", bitsLocalArtLoc)
# extract the bits artifact in the temp working directory # 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.""" """The main test case implementation."""
iso_file = os.path.join(self._workDir, 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)) 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.set_console()
self._vm.launch() 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 # biosbits has been configured to run all the specified test suites
# in batch mode and then automatically initiate a vm shutdown. # 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. # with the avocado test timeout.
self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT) self._vm.event_wait('SHUTDOWN', timeout=BITS_TIMEOUT)
self._vm.wait(timeout=None) self._vm.wait(timeout=None)
self.logger.debug("Checking console output ...")
self.parse_log() self.parse_log()
if __name__ == '__main__':
QemuBaseTest.main()

View 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()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots the canon-a1100 machine with firmware # Functional test that boots the canon-a1100 machine with firmware
# #
# Copyright (c) 2020 Red Hat, Inc. # Copyright (c) 2020 Red Hat, Inc.
@ -8,28 +10,30 @@
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
from avocado.utils import archive from qemu_test.utils import archive_extract
class CanonA1100Machine(QemuSystemTest): class CanonA1100Machine(QemuSystemTest):
"""Boots the barebox firmware and checks that the console is operational""" """Boots the barebox firmware and checks that the console is operational"""
timeout = 90 timeout = 90
ASSET_BIOS = Asset(('https://qemu-advcal.gitlab.io'
'/qac-best-of-multiarch/download/day18.tar.xz'),
'28e71874ce985be66b7fd1345ed88cb2523b982f899c8d2900d6353054a1be49')
def test_arm_canona1100(self): def test_arm_canona1100(self):
""" self.set_machine('canon-a1100')
:avocado: tags=arch:arm
:avocado: tags=machine:canon-a1100 file_path = self.ASSET_BIOS.fetch()
:avocado: tags=device:pflash_cfi02 archive_extract(file_path, dest_dir=self.workdir,
""" member="day18/barebox.canon-a1100.bin")
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.vm.set_console() self.vm.set_console()
self.vm.add_args('-bios', self.vm.add_args('-bios',
self.workdir + '/day18/barebox.canon-a1100.bin') self.workdir + '/day18/barebox.canon-a1100.bin')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, 'running /env/bin/init') wait_for_console_pattern(self, 'running /env/bin/init')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a Linux kernel and checks the console # Functional test that boots a Linux kernel and checks the console
# #
# Copyright (c) 2020 Red Hat, Inc. # Copyright (c) 2020 Red Hat, Inc.
@ -7,13 +9,15 @@
# #
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
#
# SPDX-License-Identifier: GPL-2.0-or-later
import os import os
import logging import logging
from avocado import skipUnless from qemu_test import QemuSystemTest, Asset
from avocado_qemu import QemuSystemTest from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern from unittest import skipUnless
NUMPY_AVAILABLE = True NUMPY_AVAILABLE = True
@ -33,50 +37,49 @@ class IntegratorMachine(QemuSystemTest):
timeout = 90 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): def boot_integratorcp(self):
kernel_url = ('https://github.com/zayac/qemu-arm/raw/master/' kernel_path = self.ASSET_KERNEL.fetch()
'arm-test/kernel/zImage.integrator') initrd_path = self.ASSET_INITRD.fetch()
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)
self.set_machine('integratorcp')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-kernel', kernel_path, self.vm.add_args('-kernel', kernel_path,
'-initrd', initrd_path, '-initrd', initrd_path,
'-append', 'printk.time=0 console=ttyAMA0') '-append', 'printk.time=0 console=ttyAMA0')
self.vm.launch() 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): def test_integratorcp_console(self):
""" """
Boots the Linux kernel and checks that the console is operational 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() self.boot_integratorcp()
wait_for_console_pattern(self, 'Log in as root') wait_for_console_pattern(self, 'Log in as root')
@skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed') @skipUnless(NUMPY_AVAILABLE, 'Python NumPy not installed')
@skipUnless(CV2_AVAILABLE, 'Python OpenCV 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): def test_framebuffer_tux_logo(self):
""" """
Boot Linux and verify the Tux logo is displayed on the framebuffer. 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") screendump_path = os.path.join(self.workdir, "screendump.pbm")
tuxlogo_url = ('https://github.com/torvalds/linux/raw/v2.6.12/' tuxlogo_path = self.ASSET_TUXLOGO.fetch()
'drivers/video/logo/logo_linux_vga16.ppm')
tuxlogo_hash = '3991c2ddbd1ddaecda7601f8aafbcf5b02dc86af'
tuxlogo_path = self.fetch_asset(tuxlogo_url, asset_hash=tuxlogo_hash)
self.boot_integratorcp() self.boot_integratorcp()
framebuffer_ready = 'Console: switching to colour frame buffer device' 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): for tux_count, pt in enumerate(zip(*loc[::-1]), start=1):
logger.debug('found Tux at position [x, y] = %s', pt) logger.debug('found Tux at position [x, y] = %s', pt)
self.assertGreaterEqual(tux_count, cpu_count) self.assertGreaterEqual(tux_count, cpu_count)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
# #
# QEMU AVR integration tests # QEMU AVR integration tests
# #
@ -19,26 +20,24 @@
import time import time
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
class AVR6Machine(QemuSystemTest): class AVR6Machine(QemuSystemTest):
timeout = 5 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): 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 https://github.com/seharris/qemu-avr-tests/raw/master/free-rtos/Demo/AVR_ATMega2560_GCC/demo.elf
constantly prints out 'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX' constantly prints out 'ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX'
""" """
rom_url = ('https://github.com/seharris/qemu-avr-tests' rom_path = self.ASSET_ROM.fetch()
'/raw/36c3e67b8755dcf/free-rtos/Demo'
'/AVR_ATMega2560_GCC/demo.elf')
rom_hash = '7eb521f511ca8f2622e0a3c5e8dd686efbb911d4'
rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
self.set_machine('arduino-mega-2560-v3')
self.vm.add_args('-bios', rom_path) self.vm.add_args('-bios', rom_path)
self.vm.add_args('-nographic') self.vm.add_args('-nographic')
self.vm.launch() self.vm.launch()
@ -48,3 +47,6 @@ class AVR6Machine(QemuSystemTest):
self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX', self.assertIn('ABCDEFGHIJKLMNOPQRSTUVWXABCDEFGHIJKLMNOPQRSTUVWX',
self.vm.get_log()) self.vm.get_log())
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Sanity check of query-cpu-* results # Sanity check of query-cpu-* results
# #
# Copyright (c) 2019 Red Hat, Inc. # Copyright (c) 2019 Red Hat, Inc.
@ -8,7 +10,7 @@
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest
class QueryCPUModelExpansion(QemuSystemTest): class QueryCPUModelExpansion(QemuSystemTest):
""" """
@ -16,10 +18,7 @@ class QueryCPUModelExpansion(QemuSystemTest):
""" """
def test(self): def test(self):
""" self.set_machine('none')
:avocado: tags=arch:x86_64
:avocado: tags=machine:none
"""
self.vm.add_args('-S') self.vm.add_args('-S')
self.vm.launch() self.vm.launch()
@ -33,3 +32,6 @@ class QueryCPUModelExpansion(QemuSystemTest):
e = self.vm.cmd('query-cpu-model-expansion', model=model, e = self.vm.cmd('query-cpu-model-expansion', model=model,
type='full') type='full')
self.assertEqual(e['model']['name'], c['name']) self.assertEqual(e['model']['name'], c['name'])
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Check for crash when using empty -cpu option # Check for crash when using empty -cpu option
# #
# Copyright (c) 2019 Red Hat, Inc. # Copyright (c) 2019 Red Hat, Inc.
@ -7,7 +9,7 @@
# #
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest
class EmptyCPUModel(QemuSystemTest): class EmptyCPUModel(QemuSystemTest):
def test(self): def test(self):
@ -17,3 +19,6 @@ class EmptyCPUModel(QemuSystemTest):
self.vm.wait() self.vm.wait()
self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1") self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be 1")
self.assertRegex(self.vm.get_log(), r'-cpu option cannot be empty') self.assertRegex(self.vm.get_log(), r'-cpu option cannot be empty')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test for the hmp command "info usernet" # Test for the hmp command "info usernet"
# #
# Copyright (c) 2021 Red Hat, Inc. # Copyright (c) 2021 Red Hat, Inc.
@ -8,18 +10,16 @@
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # 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 from qemu.utils import get_info_usernet_hostfwd_port
class InfoUsernet(QemuSystemTest): class InfoUsernet(QemuSystemTest):
"""
:avocado: tags=machine:none
"""
def test_hostfwd(self): def test_hostfwd(self):
self.require_netdev('user') 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.add_args('-netdev', 'user,id=vnet,hostfwd=:127.0.0.1:0-:22')
self.vm.launch() self.vm.launch()
res = self.vm.cmd('human-monitor-command', res = self.vm.cmd('human-monitor-command',
@ -31,3 +31,6 @@ class InfoUsernet(QemuSystemTest):
self.assertGreater(port, 0, self.assertGreater(port, 0,
('Found a redirected port that is not greater than' ('Found a redirected port that is not greater than'
' zero')) ' zero'))
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Linux initrd integration test. # Linux initrd integration test.
# #
# Copyright (c) 2018 Red Hat, Inc. # Copyright (c) 2018 Red Hat, Inc.
@ -12,20 +14,27 @@ import os
import logging import logging
import tempfile import tempfile
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado import skipUnless from unittest import skipUnless
class LinuxInitrd(QemuSystemTest): class LinuxInitrd(QemuSystemTest):
""" """
Checks QEMU evaluates correctly the initrd file passed as -initrd option. Checks QEMU evaluates correctly the initrd file passed as -initrd option.
:avocado: tags=arch:x86_64
:avocado: tags=machine:pc
""" """
timeout = 300 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): 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 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 Fedora-18 shipped with linux-3.6 which have not supported xloadflags
cannot support more than 2GiB initrd. cannot support more than 2GiB initrd.
""" """
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora/li' self.set_machine('pc')
'nux/releases/18/Fedora/x86_64/os/images/pxeboot/vmlinuz') kernel_path = self.ASSET_F18_KERNEL.fetch()
kernel_hash = '41464f68efe42b9991250bed86c7081d2ccdbb21'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
max_size = 2 * (1024 ** 3) - 1 max_size = 2 * (1024 ** 3) - 1
with tempfile.NamedTemporaryFile() as initrd: with tempfile.NamedTemporaryFile() as initrd:
@ -56,16 +63,11 @@ class LinuxInitrd(QemuSystemTest):
@skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab') @skipUnless(os.getenv('QEMU_TEST_FLAKY_TESTS'), 'Test is unstable on GitLab')
def test_with_2gib_file_should_work_with_linux_v4_16(self): 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 QEMU has supported up to 4 GiB initrd for recent kernel
Expect guest can reach 'Unpacking initramfs...' Expect guest can reach 'Unpacking initramfs...'
""" """
kernel_url = ('https://archives.fedoraproject.org/pub/archive/fedora' self.set_machine('pc')
'/linux/releases/28/Everything/x86_64/os/images/pxeboot/' kernel_path = self.ASSET_F28_KERNEL.fetch()
'vmlinuz')
kernel_hash = '238e083e114c48200f80d889f7e32eeb2793e02a'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
max_size = 2 * (1024 ** 3) + 1 max_size = 2 * (1024 ** 3) + 1
with tempfile.NamedTemporaryFile() as initrd: with tempfile.NamedTemporaryFile() as initrd:
@ -89,3 +91,6 @@ class LinuxInitrd(QemuSystemTest):
break break
if 'Kernel panic - not syncing' in msg: if 'Kernel panic - not syncing' in msg:
self.fail("Kernel panic reached") self.fail("Kernel panic reached")
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
# #
# LoongArch virt test. # LoongArch virt test.
@ -5,15 +7,28 @@
# Copyright (c) 2023 Loongson Technology Corporation Limited # Copyright (c) 2023 Loongson Technology Corporation Limited
# #
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import exec_command_and_wait_for_pattern from qemu_test import exec_command_and_wait_for_pattern
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
class LoongArchMachine(QemuSystemTest): class LoongArchMachine(QemuSystemTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
timeout = 120 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): def wait_for_console_pattern(self, success_message, vm=None):
wait_for_console_pattern(self, success_message, wait_for_console_pattern(self, success_message,
failure_message='Kernel panic - not syncing', failure_message='Kernel panic - not syncing',
@ -21,25 +36,11 @@ class LoongArchMachine(QemuSystemTest):
def test_loongarch64_devices(self): def test_loongarch64_devices(self):
""" self.set_machine('virt')
:avocado: tags=arch:loongarch64
:avocado: tags=machine:virt
"""
kernel_url = ('https://github.com/yangxiaojuan-loongson/qemu-binary/' kernel_path = self.ASSET_KERNEL.fetch()
'releases/download/2024-05-30/vmlinuz.efi') initrd_path = self.ASSET_INITRD.fetch()
kernel_hash = '951b485b16e3788b6db03a3e1793c067009e31a2' bios_path = self.ASSET_BIOS.fetch()
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)
self.vm.set_console() self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + 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') self.wait_for_console_pattern('Run /sbin/init as init process')
exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo', exec_command_and_wait_for_pattern(self, 'cat /proc/cpuinfo',
'processor : 3') 'processor : 3')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a VM and run OCR on the framebuffer # Functional test that boots a VM and run OCR on the framebuffer
# #
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> # Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
@ -8,10 +10,10 @@
import os import os
import time import time
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado import skipUnless from unittest import skipUnless
from tesseract_utils import tesseract_available, tesseract_ocr from qemu_test.tesseract import tesseract_available, tesseract_ocr
PIL_AVAILABLE = True PIL_AVAILABLE = True
try: try:
@ -21,19 +23,15 @@ except ImportError:
class NextCubeMachine(QemuSystemTest): class NextCubeMachine(QemuSystemTest):
"""
:avocado: tags=arch:m68k
:avocado: tags=machine:next-cube
:avocado: tags=device:framebuffer
"""
timeout = 15 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): def check_bootrom_framebuffer(self, screenshot_path):
rom_url = ('https://sourceforge.net/p/previous/code/1350/tree/' rom_path = self.ASSET_ROM.fetch()
'trunk/src/Rev_2.5_v66.BIN?format=raw')
rom_hash = 'b3534796abae238a0111299fc406a9349f7fee24'
rom_path = self.fetch_asset(rom_url, asset_hash=rom_hash)
self.vm.add_args('-bios', rom_path) self.vm.add_args('-bios', rom_path)
self.vm.launch() self.vm.launch()
@ -48,6 +46,7 @@ class NextCubeMachine(QemuSystemTest):
@skipUnless(PIL_AVAILABLE, 'Python PIL not installed') @skipUnless(PIL_AVAILABLE, 'Python PIL not installed')
def test_bootrom_framebuffer_size(self): def test_bootrom_framebuffer_size(self):
self.set_machine('next-cube')
screenshot_path = os.path.join(self.workdir, "dump.ppm") screenshot_path = os.path.join(self.workdir, "dump.ppm")
self.check_bootrom_framebuffer(screenshot_path) self.check_bootrom_framebuffer(screenshot_path)
@ -60,11 +59,15 @@ class NextCubeMachine(QemuSystemTest):
# that it is still alpha-level software. # that it is still alpha-level software.
@skipUnless(tesseract_available(4), 'tesseract OCR tool not available') @skipUnless(tesseract_available(4), 'tesseract OCR tool not available')
def test_bootrom_framebuffer_ocr_with_tesseract(self): def test_bootrom_framebuffer_ocr_with_tesseract(self):
self.set_machine('next-cube')
screenshot_path = os.path.join(self.workdir, "dump.ppm") screenshot_path = os.path.join(self.workdir, "dump.ppm")
self.check_bootrom_framebuffer(screenshot_path) self.check_bootrom_framebuffer(screenshot_path)
lines = tesseract_ocr(screenshot_path, tesseract_version=4) lines = tesseract_ocr(screenshot_path)
text = '\n'.join(lines) text = '\n'.join(lines)
self.assertIn('Testing the FPU', text) self.assertIn('Testing the FPU', text)
self.assertIn('System test failed. Error code', text) self.assertIn('System test failed. Error code', text)
self.assertIn('Boot command', text) self.assertIn('Boot command', text)
self.assertIn('Next>', text) self.assertIn('Next>', text)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Check for crash when using memory beyond the available guest processor # Check for crash when using memory beyond the available guest processor
# address space. # address space.
# #
@ -8,7 +10,7 @@
# #
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest
import time import time
class MemAddrCheck(QemuSystemTest): class MemAddrCheck(QemuSystemTest):
@ -22,9 +24,6 @@ class MemAddrCheck(QemuSystemTest):
# for all 32-bit cases, pci64_hole_size is 0. # for all 32-bit cases, pci64_hole_size is 0.
def test_phybits_low_pse36(self): 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 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 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 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): 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 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 access up to a maximum of 64GiB of memory. Rest is the same as the case
with pse36 above. with pse36 above.
@ -72,9 +68,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_ok_pentium_pse36(self): 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 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. 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): 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. 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 Setting maxmem to 59.5G and making sure that QEMU can start fine
with the same options as the case above. with the same options as the case above.
@ -111,9 +101,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_ok_pentium2(self): 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 Pentium2 has 36 bits of addressing, so its same as pentium
with pse36 ON. with pse36 ON.
""" """
@ -130,9 +117,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_low_nonpse36(self): 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 Pentium processor has 32 bits of addressing without pse36 or pae
so it can access physical address up to 4 GiB. Setting maxmem to 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" 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. # now lets test some 64-bit CPU cases.
def test_phybits_low_tcg_q35_70_amd(self): 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 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, 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 "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): 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 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 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 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): 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 Same as q35-7.0 AMD case except that here we check that QEMU can
successfully start when maxmem is < 988G. successfully start when maxmem is < 988G.
""" """
@ -224,9 +199,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_ok_tcg_q35_71_amd(self): 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 Same as q35-7.1 AMD case except that here we check that QEMU can
successfully start when maxmem is < 976G. successfully start when maxmem is < 976G.
""" """
@ -243,9 +215,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_ok_tcg_q35_71_intel(self): 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 Same parameters as test_phybits_low_tcg_q35_71_amd() but use
Intel cpu instead. QEMU should start fine in this case as Intel cpu instead. QEMU should start fine in this case as
"above_4G" memory starts at 4G. "above_4G" memory starts at 4G.
@ -264,9 +233,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_low_tcg_q35_71_amd_41bits(self): 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. 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 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 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): 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. AMD processor with 41 bits. Max cpu hw address = 2 TiB.
Same as above but by setting maxram between 976 GiB and 992 Gib, Same as above but by setting maxram between 976 GiB and 992 Gib,
QEMU should start fine. QEMU should start fine.
@ -312,9 +275,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_low_tcg_q35_intel_cxl(self): 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 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 of cxl window memory. 4G_mem end aligns at 4G. pci64_hole is 32 GiB and
starts after the cxl memory window. starts after the cxl memory window.
@ -335,9 +295,6 @@ class MemAddrCheck(QemuSystemTest):
def test_phybits_ok_tcg_q35_intel_cxl(self): 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, 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 the exact same parameters as above, QEMU should start fine even
with cxl enabled. with cxl enabled.
@ -352,3 +309,6 @@ class MemAddrCheck(QemuSystemTest):
time.sleep(self.DELAY_Q35_BOOT_SEQUENCE) time.sleep(self.DELAY_Q35_BOOT_SEQUENCE)
self.vm.shutdown() self.vm.shutdown()
self.assertNotRegex(self.vm.get_log(), r'phys-bits too low') self.assertNotRegex(self.vm.get_log(), r'phys-bits too low')
if __name__ == '__main__':
QemuSystemTest.main()

View 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()

View 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()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional tests for the Lemote Fuloong-2E machine. # Functional tests for the Lemote Fuloong-2E machine.
# #
# Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org> # Copyright (c) 2019 Philippe Mathieu-Daudé <f4bug@amsat.org>
@ -8,35 +10,36 @@
# SPDX-License-Identifier: GPL-2.0-or-later # SPDX-License-Identifier: GPL-2.0-or-later
import os import os
import subprocess
from avocado import skipUnless from qemu_test import QemuSystemTest
from avocado_qemu import QemuSystemTest from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern from unittest import skipUnless
class MipsFuloong2e(QemuSystemTest): class MipsFuloong2e(QemuSystemTest):
timeout = 60 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') @skipUnless(os.getenv('RESCUE_YL_PATH'), 'RESCUE_YL_PATH not available')
def test_linux_kernel_isa_serial(self): def test_linux_kernel_2_6_27_isa_serial(self):
"""
:avocado: tags=arch:mips64el
:avocado: tags=machine:fuloong2e
:avocado: tags=endian:little
:avocado: tags=device:bonito64
:avocado: tags=device:via686b
"""
# Recovery system for the Yeeloong laptop # Recovery system for the Yeeloong laptop
# (enough to test the fuloong2e southbridge, accessing its ISA bus) # (enough to test the fuloong2e southbridge, accessing its ISA bus)
# http://dev.lemote.com/files/resource/download/rescue/rescue-yl # http://dev.lemote.com/files/resource/download/rescue/rescue-yl
kernel_hash = 'ec4d1bd89a8439c41033ca63db60160cc6d6f09a' sha = 'ab588d3316777c62cc81baa20ac92e98b01955c244dff3794b711bc34e26e51d'
kernel_path = self.fetch_asset('file://' + os.getenv('RESCUE_YL_PATH'), kernel_path = os.getenv('RESCUE_YL_PATH')
asset_hash=kernel_hash) 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.set_console()
self.vm.add_args('-kernel', kernel_path) self.vm.add_args('-kernel', kernel_path)
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, 'Linux version 2.6.27.7lemote') wait_for_console_pattern(self, 'Linux version 2.6.27.7lemote')
cpu_revision = 'CPU revision is: 00006302 (ICT Loongson-2)' cpu_revision = 'CPU revision is: 00006302 (ICT Loongson-2)'
wait_for_console_pattern(self, cpu_revision) wait_for_console_pattern(self, cpu_revision)
if __name__ == '__main__':
QemuSystemTest.main()

View 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()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# ethtool tests for emulated network devices # ethtool tests for emulated network devices
# #
# This test leverages ethtool's --test sequence to validate network # This test leverages ethtool's --test sequence to validate network
@ -5,39 +7,33 @@
# #
# SPDX-License-Identifier: GPL-2.0-or-late # SPDX-License-Identifier: GPL-2.0-or-late
from avocado import skip from unittest import skip
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
class NetDevEthtool(QemuSystemTest): class NetDevEthtool(QemuSystemTest):
"""
:avocado: tags=arch:x86_64
:avocado: tags=machine:q35
"""
# Runs in about 17s under KVM, 19s under TCG, 25s under GCOV # Runs in about 17s under KVM, 19s under TCG, 25s under GCOV
timeout = 45 timeout = 45
# Fetch assets from the netdev-ethtool subdir of my shared test # Fetch assets from the netdev-ethtool subdir of my shared test
# images directory on fileserver.linaro.org. # images directory on fileserver.linaro.org.
def get_asset(self, name, sha1): ASSET_BASEURL = ('https://fileserver.linaro.org/s/kE4nCFLdQcoBF9t/'
base_url = ('https://fileserver.linaro.org/s/' 'download?path=%2Fnetdev-ethtool&files=')
'kE4nCFLdQcoBF9t/download?' ASSET_BZIMAGE = Asset(
'path=%2Fnetdev-ethtool&files=' ) ASSET_BASEURL + "bzImage",
url = base_url + name "ed62ee06ea620b1035747f3f66a5e9fc5d3096b29f75562ada888b04cd1c4baf")
# use explicit name rather than failing to neatly parse the ASSET_ROOTFS = Asset(
# URL into a unique one ASSET_BASEURL + "rootfs.squashfs",
return self.fetch_asset(name=name, locations=(url), asset_hash=sha1) "8f0207e3c4d40832ae73c1a927e42ca30ccb1e71f047acb6ddb161ba422934e6")
def common_test_code(self, netdev, extra_args=None): def common_test_code(self, netdev, extra_args=None):
self.set_machine('q35')
# This custom kernel has drivers for all the supported network # This custom kernel has drivers for all the supported network
# devices we can emulate in QEMU # devices we can emulate in QEMU
kernel = self.get_asset("bzImage", kernel = self.ASSET_BZIMAGE.fetch()
"33469d7802732d5815226166581442395cb289e2") rootfs = self.ASSET_ROOTFS.fetch()
rootfs = self.get_asset("rootfs.squashfs",
"9793cea7021414ae844bda51f558bd6565b50cdc")
append = 'printk.time=0 console=ttyS0 ' append = 'printk.time=0 console=ttyS0 '
append += 'root=/dev/sr0 rootfstype=squashfs ' append += 'root=/dev/sr0 rootfstype=squashfs '
@ -68,15 +64,9 @@ class NetDevEthtool(QemuSystemTest):
self.vm.kill() self.vm.kill()
def test_igb(self): def test_igb(self):
"""
:avocado: tags=device:igb
"""
self.common_test_code("igb") self.common_test_code("igb")
def test_igb_nomsi(self): def test_igb_nomsi(self):
"""
:avocado: tags=device:igb
"""
self.common_test_code("igb", "pci=nomsi") self.common_test_code("igb", "pci=nomsi")
# It seems the other popular cards we model in QEMU currently fail # It seems the other popular cards we model in QEMU currently fail
@ -88,14 +78,11 @@ class NetDevEthtool(QemuSystemTest):
@skip("Incomplete reg 0x00178 support") @skip("Incomplete reg 0x00178 support")
def test_e1000(self): def test_e1000(self):
"""
:avocado: tags=device:e1000
"""
self.common_test_code("e1000") self.common_test_code("e1000")
@skip("Incomplete reg 0x00178 support") @skip("Incomplete reg 0x00178 support")
def test_i82550(self): def test_i82550(self):
"""
:avocado: tags=device:i82550
"""
self.common_test_code("i82550") self.common_test_code("i82550")
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
# #
# Ensure CPU die-id can be omitted on -device # 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/>. # 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): class OmittedCPUProps(QemuSystemTest):
"""
:avocado: tags=arch:x86_64
:avocado: tags=cpu:qemu64
"""
def test_no_die_id(self): def test_no_die_id(self):
self.vm.add_args('-nodefaults', '-S') self.vm.add_args('-nodefaults', '-S')
self.vm.add_args('-smp', '1,sockets=2,cores=2,threads=2,maxcpus=8') 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.add_args('-device', 'qemu64-x86_64-cpu,socket-id=1,core-id=0,thread-id=0')
self.vm.launch() self.vm.launch()
self.assertEqual(len(self.vm.cmd('query-cpus-fast')), 2) self.assertEqual(len(self.vm.cmd('query-cpus-fast')), 2)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Tests that specifically try to exercise hypervisor features of the # Tests that specifically try to exercise hypervisor features of the
# target machines. powernv supports the Power hypervisor ISA, and # target machines. powernv supports the Power hypervisor ISA, and
# pseries supports the nested-HV hypervisor spec. # 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 # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado import skipIf, skipUnless from unittest import skipIf, skipUnless
from avocado.utils import archive from qemu_test import QemuSystemTest, Asset
from avocado_qemu import QemuSystemTest from qemu_test import wait_for_console_pattern, exec_command
from avocado_qemu import wait_for_console_pattern, exec_command
import os import os
import time import time
import subprocess import subprocess
@ -45,8 +46,7 @@ def missing_deps():
# QEMU already installed and use that. # QEMU already installed and use that.
# XXX: The order of these tests seems to matter, see git blame. # XXX: The order of these tests seems to matter, see git blame.
@skipIf(missing_deps(), 'dependencies (%s) not installed' % ','.join(deps)) @skipIf(missing_deps(), 'dependencies (%s) not installed' % ','.join(deps))
@skipUnless(os.getenv('AVOCADO_ALLOW_LARGE_STORAGE'), 'storage limited') @skipUnless(os.getenv('QEMU_TEST_ALLOW_LARGE_STORAGE'), 'storage limited')
@skipUnless(os.getenv('SPEED') == 'slow', 'runtime limited')
class HypervisorTest(QemuSystemTest): class HypervisorTest(QemuSystemTest):
timeout = 1000 timeout = 1000
@ -54,6 +54,11 @@ class HypervisorTest(QemuSystemTest):
panic_message = 'Kernel panic - not syncing' panic_message = 'Kernel panic - not syncing'
good_message = 'VFS: Cannot open root device' 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): def extract_from_iso(self, iso, path):
""" """
Extracts a file from an iso file into the test workdir Extracts a file from an iso file into the test workdir
@ -72,6 +77,7 @@ class HypervisorTest(QemuSystemTest):
subprocess.run(cmd.split(), subprocess.run(cmd.split(),
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
os.chmod(filename, 0o600)
os.chdir(cwd) os.chdir(cwd)
# Return complete path to extracted file. Because callers to # Return complete path to extracted file. Because callers to
@ -83,16 +89,9 @@ class HypervisorTest(QemuSystemTest):
def setUp(self): def setUp(self):
super().setUp() super().setUp()
iso_url = ('https://dl-cdn.alpinelinux.org/alpine/v3.18/releases/ppc64le/alpine-standard-3.18.4-ppc64le.iso') self.iso_path = self.ASSET_ISO.fetch()
self.vmlinuz = self.extract_from_iso(self.iso_path, '/boot/vmlinuz-lts')
# Alpine use sha256 so I recalculated this myself self.initramfs = self.extract_from_iso(self.iso_path, '/boot/initramfs-lts')
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')
def do_start_alpine(self): def do_start_alpine(self):
self.vm.set_console() self.vm.set_console()
@ -158,12 +157,8 @@ class HypervisorTest(QemuSystemTest):
wait_for_console_pattern(self, 'alpine:~#') wait_for_console_pattern(self, 'alpine:~#')
def test_hv_pseries(self): def test_hv_pseries(self):
"""
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('pseries')
self.vm.add_args("-accel", "tcg,thread=multi") self.vm.add_args("-accel", "tcg,thread=multi")
self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0') self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0')
self.vm.add_args("-machine", "x-vof=on,cap-nested-hv=on") self.vm.add_args("-machine", "x-vof=on,cap-nested-hv=on")
@ -173,12 +168,8 @@ class HypervisorTest(QemuSystemTest):
self.do_stop_alpine() self.do_stop_alpine()
def test_hv_pseries_kvm(self): def test_hv_pseries_kvm(self):
"""
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
:avocado: tags=accel:kvm
"""
self.require_accelerator("kvm") self.require_accelerator("kvm")
self.set_machine('pseries')
self.vm.add_args("-accel", "kvm") self.vm.add_args("-accel", "kvm")
self.vm.add_args('-device', 'nvme,serial=1234,drive=drive0') 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") 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() self.do_stop_alpine()
def test_hv_powernv(self): def test_hv_powernv(self):
"""
:avocado: tags=arch:ppc64
:avocado: tags=machine:powernv
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('powernv')
self.vm.add_args("-accel", "tcg,thread=multi") self.vm.add_args("-accel", "tcg,thread=multi")
self.vm.add_args('-device', 'nvme,bus=pcie.2,addr=0x0,serial=1234,drive=drive0', 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', '-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()
self.do_test_kvm(True) self.do_test_kvm(True)
self.do_stop_alpine() self.do_stop_alpine()
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test that Linux kernel boots on ppc powernv machines and check the console # Test that Linux kernel boots on ppc powernv machines and check the console
# #
# Copyright (c) 2018, 2020 Red Hat, Inc. # 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 # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado.utils import archive from qemu_test import QemuSystemTest, Asset
from avocado_qemu import QemuSystemTest from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern
class powernvMachine(QemuSystemTest): class powernvMachine(QemuSystemTest):
@ -16,13 +17,14 @@ class powernvMachine(QemuSystemTest):
panic_message = 'Kernel panic - not syncing' panic_message = 'Kernel panic - not syncing'
good_message = 'VFS: Cannot open root device' 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): def do_test_linux_boot(self, command_line = KERNEL_COMMON_COMMAND_LINE):
self.require_accelerator("tcg") self.require_accelerator("tcg")
kernel_url = ('https://archives.fedoraproject.org/pub/archive' kernel_path = self.ASSET_KERNEL.fetch()
'/fedora-secondary/releases/29/Everything/ppc64le/os'
'/ppc/ppc64/vmlinuz')
kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-kernel', kernel_path, self.vm.add_args('-kernel', kernel_path,
@ -30,23 +32,13 @@ class powernvMachine(QemuSystemTest):
self.vm.launch() self.vm.launch()
def test_linux_boot(self): def test_linux_boot(self):
""" self.set_machine('powernv')
:avocado: tags=arch:ppc64
:avocado: tags=machine:powernv
:avocado: tags=accel:tcg
"""
self.do_test_linux_boot() self.do_test_linux_boot()
console_pattern = 'VFS: Cannot open root device' console_pattern = 'VFS: Cannot open root device'
wait_for_console_pattern(self, console_pattern, self.panic_message) wait_for_console_pattern(self, console_pattern, self.panic_message)
def test_linux_smp_boot(self): def test_linux_smp_boot(self):
""" self.set_machine('powernv')
:avocado: tags=arch:ppc64
:avocado: tags=machine:powernv
:avocado: tags=accel:tcg
"""
self.vm.add_args('-smp', '4') self.vm.add_args('-smp', '4')
self.do_test_linux_boot() self.do_test_linux_boot()
console_pattern = 'smp: Brought up 1 node, 4 CPUs' 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) wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_linux_smp_hpt_boot(self): def test_linux_smp_hpt_boot(self):
""" self.set_machine('powernv')
:avocado: tags=arch:ppc64
:avocado: tags=machine:powernv
:avocado: tags=accel:tcg
"""
self.vm.add_args('-smp', '4') self.vm.add_args('-smp', '4')
self.do_test_linux_boot(self.KERNEL_COMMON_COMMAND_LINE + self.do_test_linux_boot(self.KERNEL_COMMON_COMMAND_LINE +
'disable_radix') 'disable_radix')
@ -70,12 +57,7 @@ class powernvMachine(QemuSystemTest):
wait_for_console_pattern(self, self.good_message, self.panic_message) wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_linux_smt_boot(self): def test_linux_smt_boot(self):
""" self.set_machine('powernv')
:avocado: tags=arch:ppc64
:avocado: tags=machine:powernv
:avocado: tags=accel:tcg
"""
self.vm.add_args('-smp', '4,threads=4') self.vm.add_args('-smp', '4,threads=4')
self.do_test_linux_boot() self.do_test_linux_boot()
console_pattern = 'CPU maps initialized for 4 threads per core' 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) wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_linux_big_boot(self): def test_linux_big_boot(self):
""" self.set_machine('powernv')
:avocado: tags=arch:ppc64
:avocado: tags=machine:powernv
:avocado: tags=accel:tcg
"""
self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2') self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2')
# powernv does not support NUMA # powernv does not support NUMA
@ -100,3 +77,6 @@ class powernvMachine(QemuSystemTest):
console_pattern = 'smp: Brought up 2 nodes, 16 CPUs' console_pattern = 'smp: Brought up 2 nodes, 16 CPUs'
wait_for_console_pattern(self, console_pattern, self.panic_message) wait_for_console_pattern(self, console_pattern, self.panic_message)
wait_for_console_pattern(self, self.good_message, self.panic_message) wait_for_console_pattern(self, self.good_message, self.panic_message)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test that Linux kernel boots on ppc machines and check the console # Test that Linux kernel boots on ppc machines and check the console
# #
# Copyright (c) 2018, 2020 Red Hat, Inc. # 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 # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado.utils import archive from qemu_test import QemuSystemTest, Asset
from avocado_qemu import QemuSystemTest from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern
class pseriesMachine(QemuSystemTest): class pseriesMachine(QemuSystemTest):
@ -16,12 +17,13 @@ class pseriesMachine(QemuSystemTest):
panic_message = 'Kernel panic - not syncing' panic_message = 'Kernel panic - not syncing'
good_message = 'VFS: Cannot open root device' 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): def do_test_ppc64_linux_boot(self, kernel_command_line = KERNEL_COMMON_COMMAND_LINE):
kernel_url = ('https://archives.fedoraproject.org/pub/archive' kernel_path = self.ASSET_KERNEL.fetch()
'/fedora-secondary/releases/29/Everything/ppc64le/os'
'/ppc/ppc64/vmlinuz')
kernel_hash = '3fe04abfc852b66653b8c3c897a59a689270bc77'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-kernel', kernel_path, self.vm.add_args('-kernel', kernel_path,
@ -29,32 +31,20 @@ class pseriesMachine(QemuSystemTest):
self.vm.launch() self.vm.launch()
def test_ppc64_vof_linux_boot(self): def test_ppc64_vof_linux_boot(self):
""" self.set_machine('pseries')
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
self.vm.add_args('-machine', 'x-vof=on') self.vm.add_args('-machine', 'x-vof=on')
self.do_test_ppc64_linux_boot() self.do_test_ppc64_linux_boot()
console_pattern = 'VFS: Cannot open root device' console_pattern = 'VFS: Cannot open root device'
wait_for_console_pattern(self, console_pattern, self.panic_message) wait_for_console_pattern(self, console_pattern, self.panic_message)
def test_ppc64_linux_boot(self): def test_ppc64_linux_boot(self):
""" self.set_machine('pseries')
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
self.do_test_ppc64_linux_boot() self.do_test_ppc64_linux_boot()
console_pattern = 'VFS: Cannot open root device' console_pattern = 'VFS: Cannot open root device'
wait_for_console_pattern(self, console_pattern, self.panic_message) wait_for_console_pattern(self, console_pattern, self.panic_message)
def test_ppc64_linux_smp_boot(self): def test_ppc64_linux_smp_boot(self):
""" self.set_machine('pseries')
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
self.vm.add_args('-smp', '4') self.vm.add_args('-smp', '4')
self.do_test_ppc64_linux_boot() self.do_test_ppc64_linux_boot()
console_pattern = 'smp: Brought up 1 node, 4 CPUs' 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) wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_ppc64_linux_hpt_smp_boot(self): def test_ppc64_linux_hpt_smp_boot(self):
""" self.set_machine('pseries')
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
self.vm.add_args('-smp', '4') self.vm.add_args('-smp', '4')
self.do_test_ppc64_linux_boot(self.KERNEL_COMMON_COMMAND_LINE + self.do_test_ppc64_linux_boot(self.KERNEL_COMMON_COMMAND_LINE +
'disable_radix') 'disable_radix')
@ -77,11 +63,6 @@ class pseriesMachine(QemuSystemTest):
wait_for_console_pattern(self, self.good_message, self.panic_message) wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_ppc64_linux_smt_boot(self): def test_ppc64_linux_smt_boot(self):
"""
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
self.vm.add_args('-smp', '4,threads=4') self.vm.add_args('-smp', '4,threads=4')
self.do_test_ppc64_linux_boot() self.do_test_ppc64_linux_boot()
console_pattern = 'CPU maps initialized for 4 threads per core' 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) wait_for_console_pattern(self, self.good_message, self.panic_message)
def test_ppc64_linux_big_boot(self): def test_ppc64_linux_big_boot(self):
""" self.set_machine('pseries')
:avocado: tags=arch:ppc64
:avocado: tags=machine:pseries
"""
self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2') self.vm.add_args('-smp', '16,threads=4,cores=2,sockets=2')
self.vm.add_args('-m', '512M', self.vm.add_args('-m', '512M',
'-object', 'memory-backend-ram,size=256M,id=m0', '-object', 'memory-backend-ram,size=256M,id=m0',
@ -108,3 +85,6 @@ class pseriesMachine(QemuSystemTest):
console_pattern = 'smp: Brought up 2 nodes, 16 CPUs' console_pattern = 'smp: Brought up 2 nodes, 16 CPUs'
wait_for_console_pattern(self, console_pattern, self.panic_message) wait_for_console_pattern(self, console_pattern, self.panic_message)
wait_for_console_pattern(self, self.good_message, self.panic_message) wait_for_console_pattern(self, self.good_message, self.panic_message)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test that the U-Boot firmware boots on ppc 405 machines and check the console # Test that the U-Boot firmware boots on ppc 405 machines and check the console
# #
# Copyright (c) 2021 Red Hat, Inc. # Copyright (c) 2021 Red Hat, Inc.
@ -5,20 +7,21 @@
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado.utils import archive from qemu_test import QemuSystemTest, Asset
from avocado_qemu import QemuSystemTest from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern from qemu_test import exec_command_and_wait_for_pattern
from avocado_qemu import exec_command_and_wait_for_pattern
class Ppc405Machine(QemuSystemTest): class Ppc405Machine(QemuSystemTest):
timeout = 90 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): def do_test_ppc405(self):
uboot_url = ('https://gitlab.com/huth/u-boot/-/raw/' file_path = self.ASSET_UBOOT.fetch()
'taihu-2021-10-09/u-boot-taihu.bin')
uboot_hash = ('3208940e908a5edc7c03eab072c60f0dcfadc2ab');
file_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash)
self.vm.set_console(console_index=1) self.vm.set_console(console_index=1)
self.vm.add_args('-bios', file_path) self.vm.add_args('-bios', file_path)
self.vm.launch() self.vm.launch()
@ -26,11 +29,9 @@ class Ppc405Machine(QemuSystemTest):
exec_command_and_wait_for_pattern(self, 'reset', 'AMCC PowerPC 405EP') exec_command_and_wait_for_pattern(self, 'reset', 'AMCC PowerPC 405EP')
def test_ppc_ref405ep(self): 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.require_accelerator("tcg")
self.set_machine('ref405ep')
self.do_test_ppc405() self.do_test_ppc405()
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a PReP/40p machine and checks its serial console. # Functional test that boots a PReP/40p machine and checks its serial console.
# #
# Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org> # Copyright (c) Philippe Mathieu-Daudé <f4bug@amsat.org>
@ -7,39 +9,40 @@
import os import os
from avocado import skipUnless from unittest import skipUnless
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
class IbmPrep40pMachine(QemuSystemTest): class IbmPrep40pMachine(QemuSystemTest):
timeout = 60 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 # 12H0455 PPS Firmware Licensed Materials
# Property of IBM (C) Copyright IBM Corp. 1994. # Property of IBM (C) Copyright IBM Corp. 1994.
# All rights reserved. # All rights reserved.
# U.S. Government Users Restricted Rights - Use, duplication or disclosure # U.S. Government Users Restricted Rights - Use, duplication or disclosure
# restricted by GSA ADP Schedule Contract with IBM Corp. # 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): def test_factory_firmware_and_netbsd(self):
""" self.set_machine('40p')
:avocado: tags=arch:ppc
:avocado: tags=machine:40p
:avocado: tags=os:netbsd
:avocado: tags=slowness:high
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
bios_url = ('http://ftpmirror.your.org/pub/misc/' bios_path = self.ASSET_BIOS.fetch()
'ftp.software.ibm.com/rs6000/firmware/' drive_path = self.ASSET_NETBSD40.fetch()
'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)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-bios', bios_path, self.vm.add_args('-bios', bios_path,
@ -50,11 +53,7 @@ class IbmPrep40pMachine(QemuSystemTest):
wait_for_console_pattern(self, 'Model: IBM PPS Model 6015') wait_for_console_pattern(self, 'Model: IBM PPS Model 6015')
def test_openbios_192m(self): def test_openbios_192m(self):
""" self.set_machine('40p')
:avocado: tags=arch:ppc
:avocado: tags=machine:40p
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-m', '192') # test fw_cfg 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') wait_for_console_pattern(self, '>> CPU type PowerPC,604')
def test_openbios_and_netbsd(self): def test_openbios_and_netbsd(self):
""" self.set_machine('40p')
:avocado: tags=arch:ppc
:avocado: tags=machine:40p
:avocado: tags=os:netbsd
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
drive_url = ('https://archive.netbsd.org/pub/NetBSD-archive/' drive_path = self.ASSET_NETBSD71.fetch()
'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')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cdrom', drive_path, self.vm.add_args('-cdrom', drive_path,
'-boot', 'd') '-boot', 'd')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, 'NetBSD/prep BOOT, Revision 1.9') wait_for_console_pattern(self, 'NetBSD/prep BOOT, Revision 1.9')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Smoke tests for 74xx cpus (aka G4). # Smoke tests for 74xx cpus (aka G4).
# #
# Copyright (c) 2021, IBM Corp. # Copyright (c) 2021, IBM Corp.
@ -5,132 +7,120 @@
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
class ppc74xxCpu(QemuSystemTest): class ppc74xxCpu(QemuSystemTest):
"""
:avocado: tags=arch:ppc
:avocado: tags=accel:tcg
"""
timeout = 5 timeout = 5
def test_ppc_7400(self): def test_ppc_7400(self):
"""
:avocado: tags=cpu:7400
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7400')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7410(self): def test_ppc_7410(self):
"""
:avocado: tags=cpu:7410
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7410')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,74xx') wait_for_console_pattern(self, '>> CPU type PowerPC,74xx')
def test_ppc_7441(self): def test_ppc_7441(self):
"""
:avocado: tags=cpu:7441
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7441')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7445(self): def test_ppc_7445(self):
"""
:avocado: tags=cpu:7445
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7445')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7447(self): def test_ppc_7447(self):
"""
:avocado: tags=cpu:7447
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7447')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7447a(self): def test_ppc_7447a(self):
"""
:avocado: tags=cpu:7447a
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7447a')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7448(self): def test_ppc_7448(self):
"""
:avocado: tags=cpu:7448
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7448')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,MPC86xx') wait_for_console_pattern(self, '>> CPU type PowerPC,MPC86xx')
def test_ppc_7450(self): def test_ppc_7450(self):
"""
:avocado: tags=cpu:7450
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7450')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7451(self): def test_ppc_7451(self):
"""
:avocado: tags=cpu:7451
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7451')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7455(self): def test_ppc_7455(self):
"""
:avocado: tags=cpu:7455
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7455')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7457(self): def test_ppc_7457(self):
"""
:avocado: tags=cpu:7457
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7457')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
def test_ppc_7457a(self): def test_ppc_7457a(self):
"""
:avocado: tags=cpu:7457a
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.set_machine('g3beige')
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-cpu', '7457a')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, '>> OpenBIOS') wait_for_console_pattern(self, '>> OpenBIOS')
wait_for_console_pattern(self, '>> CPU type PowerPC,G4') wait_for_console_pattern(self, '>> CPU type PowerPC,G4')
if __name__ == '__main__':
QemuSystemTest.main()

View 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()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test that Linux kernel boots on the ppc bamboo board and check the console # Test that Linux kernel boots on the ppc bamboo board and check the console
# #
# Copyright (c) 2021 Red Hat # Copyright (c) 2021 Red Hat
@ -5,30 +7,26 @@
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado.utils import archive from qemu_test.utils import archive_extract
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
from avocado_qemu import exec_command_and_wait_for_pattern from qemu_test import exec_command_and_wait_for_pattern
class BambooMachine(QemuSystemTest): class BambooMachine(QemuSystemTest):
timeout = 90 timeout = 90
ASSET_IMAGE = Asset(
('http://landley.net/aboriginal/downloads/binaries/'
'system-image-powerpc-440fp.tar.gz'),
'c12b58f841c775a0e6df4832a55afe6b74814d1565d08ddeafc1fb949a075c5e')
def test_ppc_bamboo(self): def test_ppc_bamboo(self):
""" self.set_machine('bamboo')
:avocado: tags=arch:ppc
:avocado: tags=machine:bamboo
:avocado: tags=cpu:440epb
:avocado: tags=device:rtl8139
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
self.require_netdev('user') self.require_netdev('user')
tar_url = ('http://landley.net/aboriginal/downloads/binaries/' file_path = self.ASSET_IMAGE.fetch()
'system-image-powerpc-440fp.tar.gz') archive_extract(file_path, self.workdir)
tar_hash = '53e5f16414b195b82d2c70272f81c2eedb39bad9'
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
archive.extract(file_path, self.workdir)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-kernel', self.workdir + self.vm.add_args('-kernel', self.workdir +
'/system-image-powerpc-440fp/linux', '/system-image-powerpc-440fp/linux',
@ -40,3 +38,6 @@ class BambooMachine(QemuSystemTest):
exec_command_and_wait_for_pattern(self, 'ping 10.0.2.2', exec_command_and_wait_for_pattern(self, 'ping 10.0.2.2',
'10.0.2.2 is alive!') '10.0.2.2 is alive!')
exec_command_and_wait_for_pattern(self, 'halt', 'System Halted') exec_command_and_wait_for_pattern(self, 'halt', 'System Halted')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test that Linux kernel boots on ppc machines and check the console # Test that Linux kernel boots on ppc machines and check the console
# #
# Copyright (c) 2018, 2020 Red Hat, Inc. # 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 # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado.utils import archive from qemu_test.utils import archive_extract
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
class Mpc8544dsMachine(QemuSystemTest): class Mpc8544dsMachine(QemuSystemTest):
@ -15,20 +17,21 @@ class Mpc8544dsMachine(QemuSystemTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
panic_message = 'Kernel panic - not syncing' 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): def test_ppc_mpc8544ds(self):
"""
:avocado: tags=arch:ppc
:avocado: tags=machine:mpc8544ds
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
tar_url = ('https://qemu-advcal.gitlab.io' self.set_machine('mpc8544ds')
'/qac-best-of-multiarch/download/day04.tar.xz') file_path = self.ASSET_IMAGE.fetch()
tar_hash = 'f46724d281a9f30fa892d458be7beb7d34dc25f9' archive_extract(file_path, self.workdir, member='creek/creek.bin')
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
archive.extract(file_path, self.workdir)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-kernel', self.workdir + '/creek/creek.bin') self.vm.add_args('-kernel', self.workdir + '/creek/creek.bin')
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, 'QEMU advent calendar 2020', wait_for_console_pattern(self, 'QEMU advent calendar 2020',
self.panic_message) self.panic_message)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Test that Linux kernel boots on ppc machines and check the console # Test that Linux kernel boots on ppc machines and check the console
# #
# Copyright (c) 2018, 2020 Red Hat, Inc. # 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 # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado.utils import archive from qemu_test.utils import archive_extract
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
class VirtexMl507Machine(QemuSystemTest): class VirtexMl507Machine(QemuSystemTest):
@ -15,18 +17,16 @@ class VirtexMl507Machine(QemuSystemTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
panic_message = 'Kernel panic - not syncing' 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): def test_ppc_virtex_ml507(self):
"""
:avocado: tags=arch:ppc
:avocado: tags=machine:virtex-ml507
:avocado: tags=accel:tcg
"""
self.require_accelerator("tcg") self.require_accelerator("tcg")
tar_url = ('https://qemu-advcal.gitlab.io' self.set_machine('virtex-ml507')
'/qac-best-of-multiarch/download/day08.tar.xz') file_path = self.ASSET_IMAGE.fetch()
tar_hash = '74c68f5af7a7b8f21c03097b298f3bb77ff52c1f' archive_extract(file_path, self.workdir)
file_path = self.fetch_asset(tar_url, asset_hash=tar_hash)
archive.extract(file_path, self.workdir)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-kernel', self.workdir + '/hippo/hippo.linux', self.vm.add_args('-kernel', self.workdir + '/hippo/hippo.linux',
'-dtb', self.workdir + '/hippo/virtex440-ml507.dtb', '-dtb', self.workdir + '/hippo/virtex440-ml507.dtb',
@ -34,3 +34,6 @@ class VirtexMl507Machine(QemuSystemTest):
self.vm.launch() self.vm.launch()
wait_for_console_pattern(self, 'QEMU advent calendar 2020', wait_for_console_pattern(self, 'QEMU advent calendar 2020',
self.panic_message) self.panic_message)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a Linux kernel and checks the console # Functional test that boots a Linux kernel and checks the console
# #
# Copyright (c) 2018 Red Hat, Inc. # Copyright (c) 2018 Red Hat, Inc.
@ -10,11 +12,11 @@
import os import os
from avocado import skipUnless from unittest import skipUnless
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import exec_command_and_wait_for_pattern from qemu_test import exec_command_and_wait_for_pattern
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
from avocado.utils import archive from qemu_test.utils import gzip_uncompress
class RxGdbSimMachine(QemuSystemTest): class RxGdbSimMachine(QemuSystemTest):
@ -22,19 +24,25 @@ class RxGdbSimMachine(QemuSystemTest):
timeout = 30 timeout = 30
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' 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): def test_uboot(self):
""" """
U-Boot and checks that the console is operational. 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') self.set_machine('gdbsim-r5f562n8')
uboot_hash = '9b78dbd43b40b2526848c0b1ce9de02c24f4dcdb'
uboot_path = self.fetch_asset(uboot_url, asset_hash=uboot_hash) uboot_path_gz = self.ASSET_UBOOT.fetch()
uboot_path = archive.uncompress(uboot_path, self.workdir) uboot_path = os.path.join(self.workdir, 'u-boot.bin')
gzip_uncompress(uboot_path_gz, uboot_path)
self.vm.set_console() self.vm.set_console()
self.vm.add_args('-bios', uboot_path, self.vm.add_args('-bios', uboot_path,
@ -50,18 +58,11 @@ class RxGdbSimMachine(QemuSystemTest):
def test_linux_sash(self): def test_linux_sash(self):
""" """
Boots a Linux kernel and checks that the console is operational. 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') self.set_machine('gdbsim-r5f562n7')
dtb_hash = '7b4e4e2c71905da44e86ce47adee2210b026ac18'
dtb_path = self.fetch_asset(dtb_url, asset_hash=dtb_hash) dtb_path = self.ASSET_DTB.fetch()
kernel_url = ('http://acc.dl.osdn.jp/users/23/23845/zImage') kernel_path = self.ASSET_KERNEL.fetch()
kernel_hash = '39a81067f8d72faad90866ddfefa19165d68fc99'
kernel_path = self.fetch_asset(kernel_url, asset_hash=kernel_hash)
self.vm.set_console() self.vm.set_console()
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE + 'earlycon' 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)', wait_for_console_pattern(self, 'Sash command shell (version 1.1.1)',
failure_message='Kernel panic - not syncing') failure_message='Kernel panic - not syncing')
exec_command_and_wait_for_pattern(self, 'printenv', 'TERM=linux') exec_command_and_wait_for_pattern(self, 'printenv', 'TERM=linux')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots an s390x Linux guest with ccw and PCI devices # Functional test that boots an s390x Linux guest with ccw and PCI devices
# attached and checks whether the devices are recognized by Linux # attached and checks whether the devices are recognized by Linux
# #
@ -12,17 +14,38 @@
import os import os
import tempfile import tempfile
from avocado import skipUnless from qemu_test import QemuSystemTest, Asset
from avocado_qemu import QemuSystemTest from qemu_test import exec_command_and_wait_for_pattern
from avocado_qemu import exec_command_and_wait_for_pattern from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern from qemu_test.utils import lzma_uncompress
from avocado.utils import archive
class S390CCWVirtioMachine(QemuSystemTest): class S390CCWVirtioMachine(QemuSystemTest):
KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 ' KERNEL_COMMON_COMMAND_LINE = 'printk.time=0 '
timeout = 120 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): def wait_for_console_pattern(self, success_message, vm=None):
wait_for_console_pattern(self, success_message, wait_for_console_pattern(self, success_message,
failure_message='Kernel panic - not syncing', failure_message='Kernel panic - not syncing',
@ -41,23 +64,10 @@ class S390CCWVirtioMachine(QemuSystemTest):
self.dmesg_clear_count += 1 self.dmesg_clear_count += 1
def test_s390x_devices(self): def test_s390x_devices(self):
self.set_machine('s390-ccw-virtio')
""" kernel_path = self.ASSET_BUSTER_KERNEL.fetch()
:avocado: tags=arch:s390x initrd_path = self.ASSET_BUSTER_INITRD.fetch()
: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)
self.vm.set_console() self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE +
@ -160,29 +170,13 @@ class S390CCWVirtioMachine(QemuSystemTest):
def test_s390x_fedora(self): def test_s390x_fedora(self):
self.set_machine('s390-ccw-virtio')
""" kernel_path = self.ASSET_F31_KERNEL.fetch()
: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_url = ('https://archives.fedoraproject.org/pub/archive' initrd_path_xz = self.ASSET_F31_INITRD.fetch()
'/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 = os.path.join(self.workdir, 'initrd-raw.img') 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() self.vm.set_console()
kernel_command_line = (self.KERNEL_COMMON_COMMAND_LINE + ' audit=0 ' 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-rng-ccw,devno=fe.1.9876',
'-device', 'virtio-gpu-ccw,devno=fe.2.5432') '-device', 'virtio-gpu-ccw,devno=fe.2.5432')
self.vm.launch() self.vm.launch()
self.wait_for_console_pattern('Kernel command line: %s'
% kernel_command_line)
self.wait_for_console_pattern('Entering emergency mode') self.wait_for_console_pattern('Entering emergency mode')
# Some tests to see whether the CLI options have been considered: # 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, exec_command_and_wait_for_pattern(self,
'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do' 'while ! (dmesg -c | grep Start.virtcrypto_remove) ; do'
' sleep 1 ; done', 'Start virtcrypto_remove.') ' sleep 1 ; done', 'Start virtcrypto_remove.')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Functional test that boots a Linux kernel and checks the console # Functional test that boots a Linux kernel and checks the console
# #
# Copyright IBM Corp. 2023 # Copyright IBM Corp. 2023
@ -9,16 +11,13 @@
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
import os import os
import shutil
import time import time
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import exec_command from qemu_test import exec_command
from avocado_qemu import exec_command_and_wait_for_pattern from qemu_test import exec_command_and_wait_for_pattern
from avocado_qemu import interrupt_interactive_console_until_pattern from qemu_test import wait_for_console_pattern
from avocado_qemu import wait_for_console_pattern from qemu_test.utils import lzma_uncompress
from avocado.utils import process
from avocado.utils import archive
class S390CPUTopology(QemuSystemTest): class S390CPUTopology(QemuSystemTest):
@ -47,6 +46,17 @@ class S390CPUTopology(QemuSystemTest):
'root=/dev/ram ' 'root=/dev/ram '
'selinux=0 ' 'selinux=0 '
'rdinit=/bin/sh') '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): def wait_until_booted(self):
wait_for_console_pattern(self, 'no job control', wait_for_console_pattern(self, 'no job control',
@ -78,21 +88,10 @@ class S390CPUTopology(QemuSystemTest):
We need a minimal root filesystem with a shell. We need a minimal root filesystem with a shell.
""" """
self.require_accelerator("kvm") self.require_accelerator("kvm")
kernel_url = ('https://archives.fedoraproject.org/pub/archive' kernel_path = self.ASSET_F35_KERNEL.fetch()
'/fedora-secondary/releases/35/Server/s390x/os' initrd_path_xz = self.ASSET_F35_INITRD.fetch()
'/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)
initrd_path = os.path.join(self.workdir, 'initrd-raw.img') 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() self.vm.set_console()
kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE kernel_command_line = self.KERNEL_COMMON_COMMAND_LINE
@ -115,10 +114,8 @@ class S390CPUTopology(QemuSystemTest):
def test_single(self): def test_single(self):
""" """
This test checks the simplest topology with a single CPU. 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.kernel_init()
self.vm.launch() self.vm.launch()
self.wait_until_booted() self.wait_until_booted()
@ -127,10 +124,8 @@ class S390CPUTopology(QemuSystemTest):
def test_default(self): def test_default(self):
""" """
This test checks the implicit topology. 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.kernel_init()
self.vm.add_args('-smp', self.vm.add_args('-smp',
'13,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') '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 This test checks the topology modification by moving a CPU
to another socket: CPU 0 is moved from socket 0 to socket 2. 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.kernel_init()
self.vm.add_args('-smp', self.vm.add_args('-smp',
'1,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') '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' This test verifies that a CPU defined with the '-device'
command line option finds its right place inside the topology. 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.kernel_init()
self.vm.add_args('-smp', self.vm.add_args('-smp',
'1,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') '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 This test verifies that QEMU modifies the entitlement change after
several guest polarization change requests. 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.kernel_init()
self.vm.launch() self.vm.launch()
self.wait_until_booted() self.wait_until_booted()
@ -267,10 +256,8 @@ class S390CPUTopology(QemuSystemTest):
""" """
This test verifies that QEMU modifies the entitlement This test verifies that QEMU modifies the entitlement
after a guest request and that the guest sees the change. 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.kernel_init()
self.vm.launch() self.vm.launch()
self.wait_until_booted() self.wait_until_booted()
@ -313,10 +300,8 @@ class S390CPUTopology(QemuSystemTest):
CPU is made dedicated. CPU is made dedicated.
QEMU retains the entitlement value when horizontal polarization is in effect. QEMU retains the entitlement value when horizontal polarization is in effect.
For the guest, the field shows the effective value of the entitlement. 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.kernel_init()
self.vm.launch() self.vm.launch()
self.wait_until_booted() self.wait_until_booted()
@ -345,10 +330,8 @@ class S390CPUTopology(QemuSystemTest):
This test verifies that QEMU does not accept to overload a socket. 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 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. 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.kernel_init()
self.vm.add_args('-smp', self.vm.add_args('-smp',
'3,drawers=2,books=2,sockets=3,cores=2,maxcpus=24') '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 This test verifies that QEMU refuses to lower the entitlement
of a dedicated CPU of a dedicated CPU
:avocado: tags=arch:s390x
:avocado: tags=machine:s390-ccw-virtio
""" """
self.set_machine('s390-ccw-virtio')
self.kernel_init() self.kernel_init()
self.vm.launch() self.vm.launch()
self.wait_until_booted() self.wait_until_booted()
@ -417,10 +398,8 @@ class S390CPUTopology(QemuSystemTest):
""" """
This test verifies that QEMU refuses to move a CPU to an This test verifies that QEMU refuses to move a CPU to an
nonexistent location nonexistent location
:avocado: tags=arch:s390x
:avocado: tags=machine:s390-ccw-virtio
""" """
self.set_machine('s390-ccw-virtio')
self.kernel_init() self.kernel_init()
self.vm.launch() self.vm.launch()
self.wait_until_booted() self.wait_until_booted()
@ -437,3 +416,6 @@ class S390CPUTopology(QemuSystemTest):
self.assertEqual(res['error']['class'], 'GenericError') self.assertEqual(res['error']['class'], 'GenericError')
self.check_topology(0, 0, 0, 0, 'medium', False) self.check_topology(0, 0, 0, 0, 'medium', False)
if __name__ == '__main__':
QemuSystemTest.main()

View 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()

View File

@ -1,3 +1,5 @@
#!/usr/bin/env python3
#
# Version check example test # Version check example test
# #
# Copyright (c) 2018 Red Hat, Inc. # Copyright (c) 2018 Red Hat, Inc.
@ -9,17 +11,18 @@
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest
class Version(QemuSystemTest): class Version(QemuSystemTest):
"""
:avocado: tags=quick
:avocado: tags=machine:none
"""
def test_qmp_human_info_version(self): def test_qmp_human_info_version(self):
self.set_machine('none')
self.vm.add_args('-nodefaults') self.vm.add_args('-nodefaults')
self.vm.launch() self.vm.launch()
res = self.vm.cmd('human-monitor-command', res = self.vm.cmd('human-monitor-command',
command_line='info version') command_line='info version')
self.assertRegex(res, r'^(\d+\.\d+\.\d)') self.assertRegex(res, r'^(\d+\.\d+\.\d)')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,14 +1,16 @@
#!/usr/bin/env python3
#
# virtio-gpu tests # virtio-gpu tests
# #
# This work is licensed under the terms of the GNU GPL, version 2 or # This work is licensed under the terms of the GNU GPL, version 2 or
# later. See the COPYING file in the top-level directory. # later. See the COPYING file in the top-level directory.
from avocado_qemu import BUILD_DIR from qemu_test import BUILD_DIR
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest, Asset
from avocado_qemu import wait_for_console_pattern from qemu_test import wait_for_console_pattern
from avocado_qemu import exec_command_and_wait_for_pattern from qemu_test import exec_command_and_wait_for_pattern
from avocado_qemu import is_readable_executable_file from qemu_test import is_readable_executable_file
from qemu.utils import kvm_available from qemu.utils import kvm_available
@ -28,25 +30,18 @@ def pick_default_vug_bin():
class VirtioGPUx86(QemuSystemTest): 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_COMMAND_LINE = "printk.time=0 console=ttyS0 rdinit=/bin/bash"
KERNEL_URL = ( ASSET_KERNEL = Asset(
"https://archives.fedoraproject.org/pub/archive/fedora" ("https://archives.fedoraproject.org/pub/archive/fedora"
"/linux/releases/33/Everything/x86_64/os/images" "/linux/releases/33/Everything/x86_64/os/images"
"/pxeboot/vmlinuz" "/pxeboot/vmlinuz"),
) '2dc5fb5cfe9ac278fa45640f3602d9b7a08cc189ed63fd9b162b07073e4df397')
KERNEL_HASH = '1433cfe3f2ffaa44de4ecfb57ec25dc2399cdecf' ASSET_INITRD = Asset(
INITRD_URL = ( ("https://archives.fedoraproject.org/pub/archive/fedora"
"https://archives.fedoraproject.org/pub/archive/fedora" "/linux/releases/33/Everything/x86_64/os/images"
"/linux/releases/33/Everything/x86_64/os/images" "/pxeboot/initrd.img"),
"/pxeboot/initrd.img" 'c49b97f893a5349e4883452178763e402bdc5caa8845b226a2d1329b5f356045')
)
INITRD_HASH = 'c828d68a027b53e5220536585efe03412332c2d9'
def wait_for_console_pattern(self, success_message, vm=None): def wait_for_console_pattern(self, success_message, vm=None):
wait_for_console_pattern( wait_for_console_pattern(
@ -57,16 +52,14 @@ class VirtioGPUx86(QemuSystemTest):
) )
def test_virtio_vga_virgl(self): def test_virtio_vga_virgl(self):
"""
:avocado: tags=device:virtio-vga-gl
"""
# FIXME: should check presence of virtio, virgl etc # FIXME: should check presence of virtio, virgl etc
self.require_accelerator('kvm') self.require_accelerator('kvm')
kernel_path = self.fetch_asset(self.KERNEL_URL, self.KERNEL_HASH) kernel_path = self.ASSET_KERNEL.fetch()
initrd_path = self.fetch_asset(self.INITRD_URL, self.INITRD_HASH) initrd_path = self.ASSET_INITRD.fetch()
self.vm.set_console() self.vm.set_console()
self.vm.add_args("-cpu", "host")
self.vm.add_args("-m", "2G") self.vm.add_args("-m", "2G")
self.vm.add_args("-machine", "pc,accel=kvm") self.vm.add_args("-machine", "pc,accel=kvm")
self.vm.add_args("-device", "virtio-vga-gl") self.vm.add_args("-device", "virtio-vga-gl")
@ -83,7 +76,7 @@ class VirtioGPUx86(QemuSystemTest):
self.vm.launch() self.vm.launch()
except: except:
# TODO: probably fails because we are missing the VirGL features # 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") self.wait_for_console_pattern("as init process")
exec_command_and_wait_for_pattern( exec_command_and_wait_for_pattern(
@ -92,18 +85,15 @@ class VirtioGPUx86(QemuSystemTest):
self.wait_for_console_pattern("features: +virgl +edid") self.wait_for_console_pattern("features: +virgl +edid")
def test_vhost_user_vga_virgl(self): def test_vhost_user_vga_virgl(self):
"""
:avocado: tags=device:vhost-user-vga
"""
# FIXME: should check presence of vhost-user-gpu, virgl, memfd etc # FIXME: should check presence of vhost-user-gpu, virgl, memfd etc
self.require_accelerator('kvm') self.require_accelerator('kvm')
vug = pick_default_vug_bin() vug = pick_default_vug_bin()
if not vug: 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) kernel_path = self.ASSET_KERNEL.fetch()
initrd_path = self.fetch_asset(self.INITRD_URL, self.INITRD_HASH) initrd_path = self.ASSET_INITRD.fetch()
# Create socketpair to connect proxy and remote processes # Create socketpair to connect proxy and remote processes
qemu_sock, vug_sock = socket.socketpair( qemu_sock, vug_sock = socket.socketpair(
@ -129,6 +119,7 @@ class VirtioGPUx86(QemuSystemTest):
) )
self.vm.set_console() self.vm.set_console()
self.vm.add_args("-cpu", "host")
self.vm.add_args("-m", "2G") self.vm.add_args("-m", "2G")
self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G") self.vm.add_args("-object", "memory-backend-memfd,id=mem,size=2G")
self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm") self.vm.add_args("-machine", "pc,memory-backend=mem,accel=kvm")
@ -147,7 +138,7 @@ class VirtioGPUx86(QemuSystemTest):
self.vm.launch() self.vm.launch()
except: except:
# TODO: probably fails because we are missing the VirGL features # 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") self.wait_for_console_pattern("as init process")
exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu", exec_command_and_wait_for_pattern(self, "/usr/sbin/modprobe virtio_gpu",
"features: +virgl +edid") "features: +virgl +edid")
@ -155,3 +146,6 @@ class VirtioGPUx86(QemuSystemTest):
qemu_sock.close() qemu_sock.close()
vugp.terminate() vugp.terminate()
vugp.wait() vugp.wait()
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
""" """
Check compatibility of virtio device types Check compatibility of virtio device types
""" """
@ -12,7 +13,7 @@ import sys
import os import os
from qemu.machine import QEMUMachine from qemu.machine import QEMUMachine
from avocado_qemu import QemuSystemTest from qemu_test import QemuSystemTest
# Virtio Device IDs: # Virtio Device IDs:
VIRTIO_NET = 1 VIRTIO_NET = 1
@ -60,8 +61,6 @@ class VirtioVersionCheck(QemuSystemTest):
Check if virtio-version-specific device types result in the Check if virtio-version-specific device types result in the
same device tree created by `disable-modern` and same device tree created by `disable-modern` and
`disable-legacy`. `disable-legacy`.
:avocado: tags=arch:x86_64
""" """
# just in case there are failures, show larger diff: # 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-mouse-pci', VIRTIO_INPUT)
self.check_modern_only('virtio-tablet-pci', VIRTIO_INPUT) self.check_modern_only('virtio-tablet-pci', VIRTIO_INPUT)
self.check_modern_only('virtio-keyboard-pci', VIRTIO_INPUT) self.check_modern_only('virtio-keyboard-pci', VIRTIO_INPUT)
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -1,3 +1,4 @@
#!/usr/bin/env python3
# #
# Basic validation of x86 versioned CPU models and CPU model aliases # 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/>. # License along with this library; if not, see <http://www.gnu.org/licenses/>.
# #
import avocado_qemu
import re 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 Validation of PC CPU model versions and CPU model aliases
:avocado: tags=arch:x86_64
""" """
def validate_aliases(self, cpus): def validate_aliases(self, cpus):
for c in cpus.values(): for c in cpus.values():
@ -76,9 +75,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
def test_4_0_alias_compatibility(self): def test_4_0_alias_compatibility(self):
""" """
Check if pc-*-4.0 unversioned CPU model won't be reported as aliases 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 # pc-*-4.0 won't expose non-versioned CPU models as aliases
# We do this to help management software to keep compatibility # We do this to help management software to keep compatibility
# with older QEMU versions that didn't have the versioned CPU model # 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): def test_4_1_alias(self):
""" """
Check if unversioned CPU model is an alias pointing to right version 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.add_args('-S')
self.vm.launch() self.vm.launch()
@ -217,9 +214,8 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
def test_none_alias(self): def test_none_alias(self):
""" """
Check if unversioned CPU model is an alias pointing to some version 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.add_args('-S')
self.vm.launch() self.vm.launch()
@ -243,21 +239,16 @@ class X86CPUModelAliases(avocado_qemu.QemuSystemTest):
self.validate_aliases(cpus) self.validate_aliases(cpus)
class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest): class CascadelakeArchCapabilities(QemuSystemTest):
""" """
Validation of Cascadelake arch-capabilities Validation of Cascadelake arch-capabilities
:avocado: tags=arch:x86_64
""" """
def get_cpu_prop(self, prop): def get_cpu_prop(self, prop):
cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path') cpu_path = self.vm.cmd('query-cpus-fast')[0].get('qom-path')
return self.vm.cmd('qom-get', path=cpu_path, property=prop) return self.vm.cmd('qom-get', path=cpu_path, property=prop)
def test_4_1(self): def test_4_1(self):
""" self.set_machine('pc-i440fx-4.1')
:avocado: tags=machine:pc-i440fx-4.1
:avocado: tags=cpu:Cascadelake-Server
"""
# machine-type only: # machine-type only:
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', 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') 'pc-i440fx-4.1 + Cascadelake-Server should not have arch-capabilities')
def test_4_0(self): def test_4_0(self):
""" self.set_machine('pc-i440fx-4.0')
:avocado: tags=machine:pc-i440fx-4.0
:avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', self.set_vm_arg('-cpu',
'Cascadelake-Server,x-force-features=on,check=off,' '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') 'pc-i440fx-4.0 + Cascadelake-Server should not have arch-capabilities')
def test_set_4_0(self): def test_set_4_0(self):
""" self.set_machine('pc-i440fx-4.0')
:avocado: tags=machine:pc-i440fx-4.0
:avocado: tags=cpu:Cascadelake-Server
"""
# command line must override machine-type if CPU model is not versioned: # command line must override machine-type if CPU model is not versioned:
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', 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') 'pc-i440fx-4.0 + Cascadelake-Server,+arch-capabilities should have arch-capabilities')
def test_unset_4_1(self): def test_unset_4_1(self):
""" self.set_machine('pc-i440fx-4.1')
:avocado: tags=machine:pc-i440fx-4.1
:avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', self.set_vm_arg('-cpu',
'Cascadelake-Server,x-force-features=on,check=off,' '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') 'pc-i440fx-4.1 + Cascadelake-Server,-arch-capabilities should not have arch-capabilities')
def test_v1_4_0(self): def test_v1_4_0(self):
""" self.set_machine('pc-i440fx-4.0')
:avocado: tags=machine:pc-i440fx-4.0
:avocado: tags=cpu:Cascadelake-Server
"""
# versioned CPU model overrides machine-type: # versioned CPU model overrides machine-type:
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', 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') 'pc-i440fx-4.0 + Cascadelake-Server-v1 should not have arch-capabilities')
def test_v2_4_0(self): def test_v2_4_0(self):
""" self.set_machine('pc-i440fx-4.0')
:avocado: tags=machine:pc-i440fx-4.0
:avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', self.set_vm_arg('-cpu',
'Cascadelake-Server-v2,x-force-features=on,check=off,' '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') 'pc-i440fx-4.0 + Cascadelake-Server-v2 should have arch-capabilities')
def test_v1_set_4_0(self): def test_v1_set_4_0(self):
""" self.set_machine('pc-i440fx-4.0')
:avocado: tags=machine:pc-i440fx-4.0
:avocado: tags=cpu:Cascadelake-Server
"""
# command line must override machine-type and versioned CPU model: # command line must override machine-type and versioned CPU model:
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', 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') 'pc-i440fx-4.0 + Cascadelake-Server-v1,+arch-capabilities should have arch-capabilities')
def test_v2_unset_4_1(self): def test_v2_unset_4_1(self):
""" self.set_machine('pc-i440fx-4.1')
:avocado: tags=machine:pc-i440fx-4.1
:avocado: tags=cpu:Cascadelake-Server
"""
self.vm.add_args('-S') self.vm.add_args('-S')
self.set_vm_arg('-cpu', self.set_vm_arg('-cpu',
'Cascadelake-Server-v2,x-force-features=on,check=off,' 'Cascadelake-Server-v2,x-force-features=on,check=off,'
@ -360,3 +330,6 @@ class CascadelakeArchCapabilities(avocado_qemu.QemuSystemTest):
self.vm.launch() self.vm.launch()
self.assertFalse(self.get_cpu_prop('arch-capabilities'), self.assertFalse(self.get_cpu_prop('arch-capabilities'),
'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities') 'pc-i440fx-4.1 + Cascadelake-Server-v2,-arch-capabilities should not have arch-capabilities')
if __name__ == '__main__':
QemuSystemTest.main()

View File

@ -85,3 +85,4 @@ subdir('unit')
subdir('qapi-schema') subdir('qapi-schema')
subdir('qtest') subdir('qtest')
subdir('migration') subdir('migration')
subdir('functional')