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 Huth 15092fd648SThomas Huthimport tempfile 16092fd648SThomas Huthimport os 17092fd648SThomas Huthimport time 18092fd648SThomas Huth 19092fd648SThomas Huthfrom qemu_test import QemuSystemTest, skipIfMissingCommands 20092fd648SThomas Huthfrom qemu_test.ports import Ports 21092fd648SThomas Huth 22092fd648SThomas Huthclass MigrationTest(QemuSystemTest): 23092fd648SThomas Huth 24092fd648SThomas Huth timeout = 10 25092fd648SThomas Huth 26092fd648SThomas Huth @staticmethod 27092fd648SThomas Huth def migration_finished(vm): 28092fd648SThomas Huth return vm.cmd('query-migrate')['status'] in ('completed', 'failed') 29092fd648SThomas Huth 30092fd648SThomas Huth def assert_migration(self, src_vm, dst_vm): 31092fd648SThomas Huth 32092fd648SThomas Huth end = time.monotonic() + self.timeout 33092fd648SThomas Huth while time.monotonic() < end and not self.migration_finished(src_vm): 34092fd648SThomas Huth time.sleep(0.1) 35092fd648SThomas Huth 36092fd648SThomas Huth end = time.monotonic() + self.timeout 37092fd648SThomas Huth while time.monotonic() < end and not self.migration_finished(dst_vm): 38092fd648SThomas Huth time.sleep(0.1) 39092fd648SThomas Huth 40092fd648SThomas Huth self.assertEqual(src_vm.cmd('query-migrate')['status'], 'completed') 41092fd648SThomas Huth self.assertEqual(dst_vm.cmd('query-migrate')['status'], 'completed') 42092fd648SThomas Huth self.assertEqual(dst_vm.cmd('query-status')['status'], 'running') 43092fd648SThomas Huth self.assertEqual(src_vm.cmd('query-status')['status'],'postmigrate') 44092fd648SThomas Huth 45092fd648SThomas Huth def select_machine(self): 46092fd648SThomas Huth target_machine = { 47092fd648SThomas Huth 'aarch64': 'quanta-gsj', 48092fd648SThomas Huth 'alpha': 'clipper', 49092fd648SThomas Huth 'arm': 'npcm750-evb', 50092fd648SThomas Huth 'i386': 'isapc', 51092fd648SThomas Huth 'ppc': 'sam460ex', 52092fd648SThomas Huth 'ppc64': 'mac99', 53092fd648SThomas Huth 'riscv32': 'spike', 54092fd648SThomas Huth 'riscv64': 'virt', 55092fd648SThomas Huth 'sparc': 'SS-4', 56092fd648SThomas Huth 'sparc64': 'sun4u', 57092fd648SThomas Huth 'x86_64': 'microvm', 58092fd648SThomas Huth } 59092fd648SThomas Huth self.set_machine(target_machine[self.arch]) 60092fd648SThomas Huth 61092fd648SThomas Huth def do_migrate(self, dest_uri, src_uri=None): 62092fd648SThomas Huth self.select_machine() 63092fd648SThomas Huth dest_vm = self.get_vm('-incoming', dest_uri, name="dest-qemu") 64092fd648SThomas Huth dest_vm.add_args('-nodefaults') 65092fd648SThomas Huth dest_vm.launch() 66092fd648SThomas Huth if src_uri is None: 67092fd648SThomas Huth src_uri = dest_uri 68092fd648SThomas Huth source_vm = self.get_vm(name="source-qemu") 69092fd648SThomas Huth source_vm.add_args('-nodefaults') 70092fd648SThomas Huth source_vm.launch() 71092fd648SThomas Huth source_vm.qmp('migrate', uri=src_uri) 72092fd648SThomas Huth self.assert_migration(source_vm, dest_vm) 73092fd648SThomas Huth 74092fd648SThomas Huth def _get_free_port(self, ports): 75092fd648SThomas Huth port = ports.find_free_port() 76092fd648SThomas Huth if port is None: 77092fd648SThomas Huth self.skipTest('Failed to find a free port') 78092fd648SThomas Huth return port 79092fd648SThomas Huth 80092fd648SThomas Huth def test_migration_with_tcp_localhost(self): 81092fd648SThomas Huth with Ports() as ports: 82092fd648SThomas Huth dest_uri = 'tcp:localhost:%u' % self._get_free_port(ports) 83092fd648SThomas Huth self.do_migrate(dest_uri) 84092fd648SThomas Huth 85092fd648SThomas Huth def test_migration_with_unix(self): 86092fd648SThomas Huth with tempfile.TemporaryDirectory(prefix='socket_') as socket_path: 87092fd648SThomas Huth dest_uri = 'unix:%s/qemu-test.sock' % socket_path 88092fd648SThomas Huth self.do_migrate(dest_uri) 89092fd648SThomas Huth 90*f700abbbSThomas Huth @skipIfMissingCommands('ncat') 91092fd648SThomas Huth def test_migration_with_exec(self): 92092fd648SThomas Huth with Ports() as ports: 93092fd648SThomas Huth free_port = self._get_free_port(ports) 94*f700abbbSThomas Huth dest_uri = 'exec:ncat -l localhost %u' % free_port 95*f700abbbSThomas Huth src_uri = 'exec:ncat localhost %u' % free_port 96092fd648SThomas Huth self.do_migrate(dest_uri, src_uri) 97092fd648SThomas Huth 98092fd648SThomas Huthif __name__ == '__main__': 99092fd648SThomas Huth QemuSystemTest.main() 100