From 9845740a162f2d9a4c852068155e94f1a3c487f9 Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 19 Aug 2025 13:23:38 +0200 Subject: tests/functional: Rework the migration test to have target-specific files We are going to move the tests for each target into separate subdirectories. The migration test does not fit quite into this scheme, since it works for multiple targets, but not all. Rework the test to have a common test class, and target specific files with a target specific class, so that this will fit better into the new scheme. Reviewed-by: Pierrick Bouvier Signed-off-by: Thomas Huth Message-ID: <20250819112403.432587-2-thuth@redhat.com> --- tests/functional/meson.build | 22 +++---- tests/functional/migration.py | 79 ++++++++++++++++++++++++ tests/functional/test_aarch64_migration.py | 26 ++++++++ tests/functional/test_alpha_migration.py | 26 ++++++++ tests/functional/test_arm_migration.py | 26 ++++++++ tests/functional/test_i386_migration.py | 26 ++++++++ tests/functional/test_migration.py | 98 ------------------------------ tests/functional/test_ppc64_migration.py | 26 ++++++++ tests/functional/test_ppc_migration.py | 26 ++++++++ tests/functional/test_riscv32_migration.py | 26 ++++++++ tests/functional/test_riscv64_migration.py | 26 ++++++++ tests/functional/test_sparc64_migration.py | 26 ++++++++ tests/functional/test_sparc_migration.py | 26 ++++++++ tests/functional/test_x86_64_migration.py | 26 ++++++++ 14 files changed, 376 insertions(+), 109 deletions(-) create mode 100644 tests/functional/migration.py create mode 100755 tests/functional/test_aarch64_migration.py create mode 100755 tests/functional/test_alpha_migration.py create mode 100755 tests/functional/test_arm_migration.py create mode 100755 tests/functional/test_i386_migration.py delete mode 100755 tests/functional/test_migration.py create mode 100755 tests/functional/test_ppc64_migration.py create mode 100755 tests/functional/test_ppc_migration.py create mode 100755 tests/functional/test_riscv32_migration.py create mode 100755 tests/functional/test_riscv64_migration.py create mode 100755 tests/functional/test_sparc64_migration.py create mode 100755 tests/functional/test_sparc_migration.py create mode 100755 tests/functional/test_x86_64_migration.py (limited to 'tests') diff --git a/tests/functional/meson.build b/tests/functional/meson.build index 311c6f1..c32436d 100644 --- a/tests/functional/meson.build +++ b/tests/functional/meson.build @@ -80,7 +80,7 @@ tests_generic_bsduser = [ ] tests_aarch64_system_quick = [ - 'migration', + 'aarch64_migration', ] tests_aarch64_system_thorough = [ @@ -110,7 +110,7 @@ tests_aarch64_system_thorough = [ ] tests_alpha_system_quick = [ - 'migration', + 'alpha_migration', ] tests_alpha_system_thorough = [ @@ -119,7 +119,7 @@ tests_alpha_system_thorough = [ ] tests_arm_system_quick = [ - 'migration', + 'arm_migration', ] tests_arm_system_thorough = [ @@ -168,7 +168,7 @@ tests_hppa_system_quick = [ ] tests_i386_system_quick = [ - 'migration', + 'i386_migration', ] tests_i386_system_thorough = [ @@ -228,7 +228,7 @@ tests_or1k_system_thorough = [ ] tests_ppc_system_quick = [ - 'migration', + 'ppc_migration', 'ppc_74xx', ] @@ -245,7 +245,7 @@ tests_ppc_system_thorough = [ ] tests_ppc64_system_quick = [ - 'migration', + 'ppc64_migration', ] tests_ppc64_system_thorough = [ @@ -260,7 +260,7 @@ tests_ppc64_system_thorough = [ ] tests_riscv32_system_quick = [ - 'migration', + 'riscv32_migration', 'riscv_opensbi', ] @@ -269,7 +269,7 @@ tests_riscv32_system_thorough = [ ] tests_riscv64_system_quick = [ - 'migration', + 'riscv64_migration', 'riscv_opensbi', ] @@ -300,7 +300,7 @@ tests_sh4eb_system_thorough = [ ] tests_sparc_system_quick = [ - 'migration', + 'sparc_migration', ] tests_sparc_system_thorough = [ @@ -309,7 +309,7 @@ tests_sparc_system_thorough = [ ] tests_sparc64_system_quick = [ - 'migration', + 'sparc64_migration', ] tests_sparc64_system_thorough = [ @@ -320,7 +320,7 @@ tests_sparc64_system_thorough = [ tests_x86_64_system_quick = [ 'cpu_queries', 'mem_addr_space', - 'migration', + 'x86_64_migration', 'pc_cpu_hotplug_props', 'virtio_version', 'x86_cpu_model_versions', diff --git a/tests/functional/migration.py b/tests/functional/migration.py new file mode 100644 index 0000000..0739554 --- /dev/null +++ b/tests/functional/migration.py @@ -0,0 +1,79 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Migration test base class +# +# Copyright (c) 2019 Red Hat, Inc. +# +# Authors: +# Cleber Rosa +# Caio Carrara +# +# This work is licensed under the terms of the GNU GPL, version 2 or +# later. See the COPYING file in the top-level directory. + +import tempfile +import time + +from qemu_test import QemuSystemTest, which +from qemu_test.ports import Ports + + +class MigrationTest(QemuSystemTest): + + timeout = 10 + + @staticmethod + def migration_finished(vm): + return vm.cmd('query-migrate')['status'] in ('completed', 'failed') + + def assert_migration(self, src_vm, dst_vm): + + end = time.monotonic() + self.timeout + while time.monotonic() < end and not self.migration_finished(src_vm): + time.sleep(0.1) + + end = time.monotonic() + self.timeout + while time.monotonic() < end and not self.migration_finished(dst_vm): + time.sleep(0.1) + + self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed') + self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed') + self.assertEqual(dst_vm.cmd('query-status')['status'], 'running') + self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate') + + def do_migrate(self, dest_uri, src_uri=None): + dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu") + dest_vm.add_args('-nodefaults') + dest_vm.launch() + if src_uri is None: + src_uri = dest_uri + source_vm = self.get_vm(name="source-qemu") + source_vm.add_args('-nodefaults') + source_vm.launch() + source_vm.qmp('migrate', uri=src_uri) + self.assert_migration(source_vm, dest_vm) + + def _get_free_port(self, ports): + port = ports.find_free_port() + if port is None: + self.skipTest('Failed to find a free port') + return port + + def migration_with_tcp_localhost(self): + with Ports() as ports: + dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports) + self.do_migrate(dest_uri) + + def migration_with_unix(self): + with tempfile.TemporaryDirectory(prefix='socket_') as socket_path: + dest_uri = 'unix:%s/qemu-test.sock' % socket_path + self.do_migrate(dest_uri) + + def migration_with_exec(self): + if not which('ncat'): + self.skipTest('ncat is not available') + with Ports() as ports: + free_port = self._get_free_port(ports) + dest_uri = 'exec:ncat -l localhost %u' % free_port + src_uri = 'exec:ncat localhost %u' % free_port + self.do_migrate(dest_uri, src_uri) diff --git a/tests/functional/test_aarch64_migration.py b/tests/functional/test_aarch64_migration.py new file mode 100755 index 0000000..70267e7 --- /dev/null +++ b/tests/functional/test_aarch64_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# aarch64 migration test + +from migration import MigrationTest + + +class Aarch64MigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('quanta-gsj') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('quanta-gsj') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('quanta-gsj') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_alpha_migration.py b/tests/functional/test_alpha_migration.py new file mode 100755 index 0000000..f11b523 --- /dev/null +++ b/tests/functional/test_alpha_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Alpha migration test + +from migration import MigrationTest + + +class AlphaMigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('clipper') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('clipper') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('clipper') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_arm_migration.py b/tests/functional/test_arm_migration.py new file mode 100755 index 0000000..0aa89f4 --- /dev/null +++ b/tests/functional/test_arm_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# arm migration test + +from migration import MigrationTest + + +class ArmMigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('npcm750-evb') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('npcm750-evb') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('npcm750-evb') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_i386_migration.py b/tests/functional/test_i386_migration.py new file mode 100755 index 0000000..a57f316 --- /dev/null +++ b/tests/functional/test_i386_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# i386 migration test + +from migration import MigrationTest + + +class I386MigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('isapc') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('isapc') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('isapc') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_migration.py b/tests/functional/test_migration.py deleted file mode 100755 index c4393c3..0000000 --- a/tests/functional/test_migration.py +++ /dev/null @@ -1,98 +0,0 @@ -#!/usr/bin/env python3 -# -# Migration test -# -# Copyright (c) 2019 Red Hat, Inc. -# -# Authors: -# Cleber Rosa -# Caio Carrara -# -# This work is licensed under the terms of the GNU GPL, version 2 or -# later. See the COPYING file in the top-level directory. - -import tempfile -import time - -from qemu_test import QemuSystemTest, skipIfMissingCommands -from qemu_test.ports import Ports - - -class MigrationTest(QemuSystemTest): - - timeout = 10 - - @staticmethod - def migration_finished(vm): - return vm.cmd('query-migrate')['status'] in ('completed', 'failed') - - def assert_migration(self, src_vm, dst_vm): - - end = time.monotonic() + self.timeout - while time.monotonic() < end and not self.migration_finished(src_vm): - time.sleep(0.1) - - end = time.monotonic() + self.timeout - while time.monotonic() < end and not self.migration_finished(dst_vm): - time.sleep(0.1) - - self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed') - self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed') - self.assertEqual(dst_vm.cmd('query-status')['status'], 'running') - self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate') - - def select_machine(self): - target_machine = { - 'aarch64': 'quanta-gsj', - 'alpha': 'clipper', - 'arm': 'npcm750-evb', - 'i386': 'isapc', - 'ppc': 'sam460ex', - 'ppc64': 'mac99', - 'riscv32': 'spike', - 'riscv64': 'virt', - 'sparc': 'SS-4', - 'sparc64': 'sun4u', - 'x86_64': 'microvm', - } - self.set_machine(target_machine[self.arch]) - - def do_migrate(self, dest_uri, src_uri=None): - self.select_machine() - dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu") - dest_vm.add_args('-nodefaults') - dest_vm.launch() - if src_uri is None: - src_uri = dest_uri - source_vm = self.get_vm(name="source-qemu") - source_vm.add_args('-nodefaults') - source_vm.launch() - source_vm.qmp('migrate', uri=src_uri) - self.assert_migration(source_vm, dest_vm) - - def _get_free_port(self, ports): - port = ports.find_free_port() - if port is None: - self.skipTest('Failed to find a free port') - return port - - def test_migration_with_tcp_localhost(self): - with Ports() as ports: - dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports) - self.do_migrate(dest_uri) - - def test_migration_with_unix(self): - with tempfile.TemporaryDirectory(prefix='socket_') as socket_path: - dest_uri = 'unix:%s/qemu-test.sock' % socket_path - self.do_migrate(dest_uri) - - @skipIfMissingCommands('ncat') - def test_migration_with_exec(self): - with Ports() as ports: - free_port = self._get_free_port(ports) - dest_uri = 'exec:ncat -l localhost %u' % free_port - src_uri = 'exec:ncat localhost %u' % free_port - self.do_migrate(dest_uri, src_uri) - -if __name__ == '__main__': - QemuSystemTest.main() diff --git a/tests/functional/test_ppc64_migration.py b/tests/functional/test_ppc64_migration.py new file mode 100755 index 0000000..5dfdaaf --- /dev/null +++ b/tests/functional/test_ppc64_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# ppc migration test + +from migration import MigrationTest + + +class PpcMigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('mac99') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('mac99') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('mac99') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_ppc_migration.py b/tests/functional/test_ppc_migration.py new file mode 100755 index 0000000..a869282 --- /dev/null +++ b/tests/functional/test_ppc_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# ppc migration test + +from migration import MigrationTest + + +class PpcMigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('sam460ex') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('sam460ex') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('sam460ex') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_riscv32_migration.py b/tests/functional/test_riscv32_migration.py new file mode 100755 index 0000000..30acbbe --- /dev/null +++ b/tests/functional/test_riscv32_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# riscv32 migration test + +from migration import MigrationTest + + +class Rv32MigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('spike') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('virt') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('spike') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_riscv64_migration.py b/tests/functional/test_riscv64_migration.py new file mode 100755 index 0000000..2d613a2 --- /dev/null +++ b/tests/functional/test_riscv64_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# riscv64 migration test + +from migration import MigrationTest + + +class Rv64MigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('virt') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('spike') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('virt') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_sparc64_migration.py b/tests/functional/test_sparc64_migration.py new file mode 100755 index 0000000..a8a6c73 --- /dev/null +++ b/tests/functional/test_sparc64_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Sparc64 migration test + +from migration import MigrationTest + + +class Sparc64MigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('sun4u') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('sun4u') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('sun4u') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_sparc_migration.py b/tests/functional/test_sparc_migration.py new file mode 100755 index 0000000..dd6d578 --- /dev/null +++ b/tests/functional/test_sparc_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# Sparc migration test + +from migration import MigrationTest + + +class SparcMigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('SS-4') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('SS-5') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('SS-4') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() diff --git a/tests/functional/test_x86_64_migration.py b/tests/functional/test_x86_64_migration.py new file mode 100755 index 0000000..f3a517a --- /dev/null +++ b/tests/functional/test_x86_64_migration.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# +# SPDX-License-Identifier: GPL-2.0-or-later +# +# x86_64 migration test + +from migration import MigrationTest + + +class X8664MigrationTest(MigrationTest): + + def test_migration_with_tcp_localhost(self): + self.set_machine('microvm') + self.migration_with_tcp_localhost() + + def test_migration_with_unix(self): + self.set_machine('microvm') + self.migration_with_unix() + + def test_migration_with_exec(self): + self.set_machine('microvm') + self.migration_with_exec() + + +if __name__ == '__main__': + MigrationTest.main() -- cgit v1.1