1092fd648SThomas Huth#!/usr/bin/env python3 2092fd648SThomas Huth# 3092fd648SThomas Huth# Migration test 4092fd648SThomas Huth# 5092fd648SThomas Huth# Copyright (c) 2019 Red Hat, Inc. 6092fd648SThomas Huth# 7092fd648SThomas Huth# Authors: 8092fd648SThomas Huth# Cleber Rosa <crosa@redhat.com> 9092fd648SThomas Huth# Caio Carrara <ccarrara@redhat.com> 10092fd648SThomas Huth# 11092fd648SThomas Huth# This work is licensed under the terms of the GNU GPL, version 2 or 12092fd648SThomas Huth# later. See the COPYING file in the top-level directory. 13092fd648SThomas Huth 14092fd648SThomas Huthimport tempfile 15092fd648SThomas Huthimport time 16092fd648SThomas Huth 17092fd648SThomas Huthfrom qemu_test import QemuSystemTest, skipIfMissingCommands 18092fd648SThomas Huthfrom qemu_test.ports import Ports 19092fd648SThomas Huth 20*99fb9256SThomas Huth 21092fd648SThomas Huthclass MigrationTest(QemuSystemTest): 22092fd648SThomas Huth 23092fd648SThomas Huth timeout = 10 24092fd648SThomas Huth 25092fd648SThomas Huth @staticmethod 26092fd648SThomas Huth def migration_finished(vm): 27092fd648SThomas Huth return vm.cmd('query-migrate')['status'] in ('completed', 'failed') 28092fd648SThomas Huth 29092fd648SThomas Huth def assert_migration(self, src_vm, dst_vm): 30092fd648SThomas Huth 31092fd648SThomas Huth end = time.monotonic() + self.timeout 32092fd648SThomas Huth while time.monotonic() < end and not self.migration_finished(src_vm): 33092fd648SThomas Huth time.sleep(0.1) 34092fd648SThomas Huth 35092fd648SThomas Huth end = time.monotonic() + self.timeout 36092fd648SThomas Huth while time.monotonic() < end and not self.migration_finished(dst_vm): 37092fd648SThomas Huth time.sleep(0.1) 38092fd648SThomas Huth 39092fd648SThomas Huth self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed') 40092fd648SThomas Huth self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed') 41092fd648SThomas Huth self.assertEqual(dst_vm.cmd('query-status')['status'], 'running') 42092fd648SThomas Huth self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate') 43092fd648SThomas Huth 44092fd648SThomas Huth def select_machine(self): 45092fd648SThomas Huth target_machine = { 46092fd648SThomas Huth 'aarch64': 'quanta-gsj', 47092fd648SThomas Huth 'alpha': 'clipper', 48092fd648SThomas Huth 'arm': 'npcm750-evb', 49092fd648SThomas Huth 'i386': 'isapc', 50092fd648SThomas Huth 'ppc': 'sam460ex', 51092fd648SThomas Huth 'ppc64': 'mac99', 52092fd648SThomas Huth 'riscv32': 'spike', 53092fd648SThomas Huth 'riscv64': 'virt', 54092fd648SThomas Huth 'sparc': 'SS-4', 55092fd648SThomas Huth 'sparc64': 'sun4u', 56092fd648SThomas Huth 'x86_64': 'microvm', 57092fd648SThomas Huth } 58092fd648SThomas Huth self.set_machine(target_machine[self.arch]) 59092fd648SThomas Huth 60092fd648SThomas Huth def do_migrate(self, dest_uri, src_uri=None): 61092fd648SThomas Huth self.select_machine() 62092fd648SThomas Huth dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu") 63092fd648SThomas Huth dest_vm.add_args('-nodefaults') 64092fd648SThomas Huth dest_vm.launch() 65092fd648SThomas Huth if src_uri is None: 66092fd648SThomas Huth src_uri = dest_uri 67092fd648SThomas Huth source_vm = self.get_vm(name="source-qemu") 68092fd648SThomas Huth source_vm.add_args('-nodefaults') 69092fd648SThomas Huth source_vm.launch() 70092fd648SThomas Huth source_vm.qmp('migrate', uri=src_uri) 71092fd648SThomas Huth self.assert_migration(source_vm, dest_vm) 72092fd648SThomas Huth 73092fd648SThomas Huth def _get_free_port(self, ports): 74092fd648SThomas Huth port = ports.find_free_port() 75092fd648SThomas Huth if port is None: 76092fd648SThomas Huth self.skipTest('Failed to find a free port') 77092fd648SThomas Huth return port 78092fd648SThomas Huth 79092fd648SThomas Huth def test_migration_with_tcp_localhost(self): 80092fd648SThomas Huth with Ports() as ports: 81092fd648SThomas Huth dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports) 82092fd648SThomas Huth self.do_migrate(dest_uri) 83092fd648SThomas Huth 84092fd648SThomas Huth def test_migration_with_unix(self): 85092fd648SThomas Huth with tempfile.TemporaryDirectory(prefix='socket_') as socket_path: 86092fd648SThomas Huth dest_uri = 'unix:%s/qemu-test.sock' % socket_path 87092fd648SThomas Huth self.do_migrate(dest_uri) 88092fd648SThomas Huth 89f700abbbSThomas Huth @skipIfMissingCommands('ncat') 90092fd648SThomas Huth def test_migration_with_exec(self): 91092fd648SThomas Huth with Ports() as ports: 92092fd648SThomas Huth free_port = self._get_free_port(ports) 93f700abbbSThomas Huth dest_uri = 'exec:ncat -l localhost %u' % free_port 94f700abbbSThomas Huth src_uri = 'exec:ncat localhost %u' % free_port 95092fd648SThomas Huth self.do_migrate(dest_uri, src_uri) 96092fd648SThomas Huth 97092fd648SThomas Huthif __name__ == '__main__': 98092fd648SThomas Huth QemuSystemTest.main() 99