xref: /openbmc/qemu/tests/avocado/migration.py (revision dd84028f)
1# Migration test
2#
3# Copyright (c) 2019 Red Hat, Inc.
4#
5# Authors:
6#  Cleber Rosa <crosa@redhat.com>
7#  Caio Carrara <ccarrara@redhat.com>
8#
9# This work is licensed under the terms of the GNU GPL, version 2 or
10# later.  See the COPYING file in the top-level directory.
11
12
13import tempfile
14import os
15
16from avocado_qemu import QemuSystemTest
17from avocado import skipUnless
18
19from avocado.utils.network import ports
20from avocado.utils import wait
21from avocado.utils.path import find_command
22
23
24class MigrationTest(QemuSystemTest):
25    """
26    :avocado: tags=migration
27    """
28
29    timeout = 10
30
31    @staticmethod
32    def migration_finished(vm):
33        return vm.command('query-migrate')['status'] in ('completed', 'failed')
34
35    def assert_migration(self, src_vm, dst_vm):
36        wait.wait_for(self.migration_finished,
37                      timeout=self.timeout,
38                      step=0.1,
39                      args=(src_vm,))
40        wait.wait_for(self.migration_finished,
41                      timeout=self.timeout,
42                      step=0.1,
43                      args=(dst_vm,))
44        self.assertEqual(src_vm.command('query-migrate')['status'], 'completed')
45        self.assertEqual(dst_vm.command('query-migrate')['status'], 'completed')
46        self.assertEqual(dst_vm.command('query-status')['status'], 'running')
47        self.assertEqual(src_vm.command('query-status')['status'],'postmigrate')
48
49    def do_migrate(self, dest_uri, src_uri=None):
50        dest_vm = self.get_vm('-incoming', dest_uri)
51        dest_vm.add_args('-nodefaults')
52        dest_vm.launch()
53        if src_uri is None:
54            src_uri = dest_uri
55        source_vm = self.get_vm()
56        source_vm.add_args('-nodefaults')
57        source_vm.launch()
58        source_vm.qmp('migrate', uri=src_uri)
59        self.assert_migration(source_vm, dest_vm)
60
61    def _get_free_port(self):
62        port = ports.find_free_port()
63        if port is None:
64            self.cancel('Failed to find a free port')
65        return port
66
67    def migration_with_tcp_localhost(self):
68        dest_uri = 'tcp:localhost:%u' % self._get_free_port()
69        self.do_migrate(dest_uri)
70
71    def migration_with_unix(self):
72        with tempfile.TemporaryDirectory(prefix='socket_') as socket_path:
73            dest_uri = 'unix:%s/qemu-test.sock' % socket_path
74            self.do_migrate(dest_uri)
75
76    @skipUnless(find_command('nc', default=False), "'nc' command not found")
77    def migration_with_exec(self):
78        """The test works for both netcat-traditional and netcat-openbsd packages."""
79        free_port = self._get_free_port()
80        dest_uri = 'exec:nc -l localhost %u' % free_port
81        src_uri = 'exec:nc localhost %u' % free_port
82        self.do_migrate(dest_uri, src_uri)
83
84
85@skipUnless('aarch64' in os.uname()[4], "host != target")
86class Aarch64(MigrationTest):
87    """
88    :avocado: tags=arch:aarch64
89    :avocado: tags=machine:virt
90    :avocado: tags=cpu:max
91    """
92
93    def test_migration_with_tcp_localhost(self):
94        self.migration_with_tcp_localhost()
95
96    def test_migration_with_unix(self):
97        self.migration_with_unix()
98
99    def test_migration_with_exec(self):
100        self.migration_with_exec()
101
102
103@skipUnless('x86_64' in os.uname()[4], "host != target")
104class X86_64(MigrationTest):
105    """
106    :avocado: tags=arch:x86_64
107    :avocado: tags=machine:pc
108    :avocado: tags=cpu:qemu64
109    """
110
111    def test_migration_with_tcp_localhost(self):
112        self.migration_with_tcp_localhost()
113
114    def test_migration_with_unix(self):
115        self.migration_with_unix()
116
117    def test_migration_with_exec(self):
118        self.migration_with_exec()
119
120
121@skipUnless('ppc64le' in os.uname()[4], "host != target")
122class PPC64(MigrationTest):
123    """
124    :avocado: tags=arch:ppc64
125    :avocado: tags=machine:pseries
126    :avocado: tags=cpu:power9_v2.0
127    """
128
129    def test_migration_with_tcp_localhost(self):
130        self.migration_with_tcp_localhost()
131
132    def test_migration_with_unix(self):
133        self.migration_with_unix()
134
135    def test_migration_with_exec(self):
136        self.migration_with_exec()
137
138
139@skipUnless('s390x' in os.uname()[4], "host != target")
140class S390X(MigrationTest):
141    """
142    :avocado: tags=arch:s390x
143    :avocado: tags=machine:s390-ccw-virtio
144    :avocado: tags=cpu:qemu
145    """
146
147    def test_migration_with_tcp_localhost(self):
148        self.migration_with_tcp_localhost()
149
150    def test_migration_with_unix(self):
151        self.migration_with_unix()
152
153    def test_migration_with_exec(self):
154        self.migration_with_exec()
155