xref: /qemu/tests/qtest/migration/misc-tests.c (revision 43ab3fb375ebb55c5b2ee7b88945f1466e7e2d5f)
1de8bc62cSFabiano Rosas /*
2de8bc62cSFabiano Rosas  * QTest testcases for migration
3de8bc62cSFabiano Rosas  *
4de8bc62cSFabiano Rosas  * Copyright (c) 2016-2018 Red Hat, Inc. and/or its affiliates
5de8bc62cSFabiano Rosas  *   based on the vhost-user-test.c that is:
6de8bc62cSFabiano Rosas  *      Copyright (c) 2014 Virtual Open Systems Sarl.
7de8bc62cSFabiano Rosas  *
8de8bc62cSFabiano Rosas  * This work is licensed under the terms of the GNU GPL, version 2 or later.
9de8bc62cSFabiano Rosas  * See the COPYING file in the top-level directory.
10de8bc62cSFabiano Rosas  *
11de8bc62cSFabiano Rosas  */
12de8bc62cSFabiano Rosas 
13de8bc62cSFabiano Rosas #include "qemu/osdep.h"
1443ca9d18SSteve Sistare #include "qapi/error.h"
1543ca9d18SSteve Sistare #include "qapi/qmp/qjson.h"
16de8bc62cSFabiano Rosas #include "libqtest.h"
17de8bc62cSFabiano Rosas #include "migration/framework.h"
18de8bc62cSFabiano Rosas #include "migration/migration-qmp.h"
19de8bc62cSFabiano Rosas #include "migration/migration-util.h"
20de8bc62cSFabiano Rosas 
21de8bc62cSFabiano Rosas #define ANALYZE_SCRIPT "scripts/analyze-migration.py"
22de8bc62cSFabiano Rosas 
23de8bc62cSFabiano Rosas static char *tmpfs;
24de8bc62cSFabiano Rosas 
25de8bc62cSFabiano Rosas static void test_baddest(void)
26de8bc62cSFabiano Rosas {
27de8bc62cSFabiano Rosas     MigrateStart args = {
28de8bc62cSFabiano Rosas         .hide_stderr = true
29de8bc62cSFabiano Rosas     };
30de8bc62cSFabiano Rosas     QTestState *from, *to;
31de8bc62cSFabiano Rosas 
32de8bc62cSFabiano Rosas     if (migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
33de8bc62cSFabiano Rosas         return;
34de8bc62cSFabiano Rosas     }
35de8bc62cSFabiano Rosas     migrate_qmp(from, to, "tcp:127.0.0.1:0", NULL, "{}");
36de8bc62cSFabiano Rosas     wait_for_migration_fail(from, false);
37de8bc62cSFabiano Rosas     migrate_end(from, to, false);
38de8bc62cSFabiano Rosas }
39de8bc62cSFabiano Rosas 
40de8bc62cSFabiano Rosas #ifndef _WIN32
41de8bc62cSFabiano Rosas static void test_analyze_script(void)
42de8bc62cSFabiano Rosas {
43de8bc62cSFabiano Rosas     MigrateStart args = {
44de8bc62cSFabiano Rosas         .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
45de8bc62cSFabiano Rosas     };
46de8bc62cSFabiano Rosas     QTestState *from, *to;
47de8bc62cSFabiano Rosas     g_autofree char *uri = NULL;
48de8bc62cSFabiano Rosas     g_autofree char *file = NULL;
49de8bc62cSFabiano Rosas     int pid, wstatus;
50de8bc62cSFabiano Rosas     const char *python = g_getenv("PYTHON");
51de8bc62cSFabiano Rosas 
52de8bc62cSFabiano Rosas     if (!python) {
53de8bc62cSFabiano Rosas         g_test_skip("PYTHON variable not set");
54de8bc62cSFabiano Rosas         return;
55de8bc62cSFabiano Rosas     }
56de8bc62cSFabiano Rosas 
57de8bc62cSFabiano Rosas     /* dummy url */
58de8bc62cSFabiano Rosas     if (migrate_start(&from, &to, "tcp:127.0.0.1:0", &args)) {
59de8bc62cSFabiano Rosas         return;
60de8bc62cSFabiano Rosas     }
61de8bc62cSFabiano Rosas 
62de8bc62cSFabiano Rosas     /*
63de8bc62cSFabiano Rosas      * Setting these two capabilities causes the "configuration"
64de8bc62cSFabiano Rosas      * vmstate to include subsections for them. The script needs to
65de8bc62cSFabiano Rosas      * parse those subsections properly.
66de8bc62cSFabiano Rosas      */
67de8bc62cSFabiano Rosas     migrate_set_capability(from, "validate-uuid", true);
68de8bc62cSFabiano Rosas     migrate_set_capability(from, "x-ignore-shared", true);
69de8bc62cSFabiano Rosas 
70de8bc62cSFabiano Rosas     file = g_strdup_printf("%s/migfile", tmpfs);
71de8bc62cSFabiano Rosas     uri = g_strdup_printf("exec:cat > %s", file);
72de8bc62cSFabiano Rosas 
73de8bc62cSFabiano Rosas     migrate_ensure_converge(from);
74de8bc62cSFabiano Rosas     migrate_qmp(from, to, uri, NULL, "{}");
75de8bc62cSFabiano Rosas     wait_for_migration_complete(from);
76de8bc62cSFabiano Rosas 
77de8bc62cSFabiano Rosas     pid = fork();
78de8bc62cSFabiano Rosas     if (!pid) {
79de8bc62cSFabiano Rosas         close(1);
80de8bc62cSFabiano Rosas         open("/dev/null", O_WRONLY);
81de8bc62cSFabiano Rosas         execl(python, python, ANALYZE_SCRIPT, "-f", file, NULL);
82de8bc62cSFabiano Rosas         g_assert_not_reached();
83de8bc62cSFabiano Rosas     }
84de8bc62cSFabiano Rosas 
85de8bc62cSFabiano Rosas     g_assert(waitpid(pid, &wstatus, 0) == pid);
86de8bc62cSFabiano Rosas     if (!WIFEXITED(wstatus) || WEXITSTATUS(wstatus) != 0) {
87de8bc62cSFabiano Rosas         g_test_message("Failed to analyze the migration stream");
88de8bc62cSFabiano Rosas         g_test_fail();
89de8bc62cSFabiano Rosas     }
90de8bc62cSFabiano Rosas     migrate_end(from, to, false);
91de8bc62cSFabiano Rosas     unlink(file);
92de8bc62cSFabiano Rosas }
93de8bc62cSFabiano Rosas #endif
94de8bc62cSFabiano Rosas 
95de8bc62cSFabiano Rosas static void test_ignore_shared(void)
96de8bc62cSFabiano Rosas {
97de8bc62cSFabiano Rosas     g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
98de8bc62cSFabiano Rosas     QTestState *from, *to;
99de8bc62cSFabiano Rosas     MigrateStart args = {
100de8bc62cSFabiano Rosas         .use_shmem = true,
101de8bc62cSFabiano Rosas     };
102de8bc62cSFabiano Rosas 
103de8bc62cSFabiano Rosas     if (migrate_start(&from, &to, uri, &args)) {
104de8bc62cSFabiano Rosas         return;
105de8bc62cSFabiano Rosas     }
106de8bc62cSFabiano Rosas 
107de8bc62cSFabiano Rosas     migrate_ensure_non_converge(from);
108de8bc62cSFabiano Rosas     migrate_prepare_for_dirty_mem(from);
109de8bc62cSFabiano Rosas 
110de8bc62cSFabiano Rosas     migrate_set_capability(from, "x-ignore-shared", true);
111de8bc62cSFabiano Rosas     migrate_set_capability(to, "x-ignore-shared", true);
112de8bc62cSFabiano Rosas 
113de8bc62cSFabiano Rosas     /* Wait for the first serial output from the source */
114de8bc62cSFabiano Rosas     wait_for_serial("src_serial");
115de8bc62cSFabiano Rosas 
116de8bc62cSFabiano Rosas     migrate_qmp(from, to, uri, NULL, "{}");
117de8bc62cSFabiano Rosas 
118de8bc62cSFabiano Rosas     migrate_wait_for_dirty_mem(from, to);
119de8bc62cSFabiano Rosas 
120de8bc62cSFabiano Rosas     wait_for_stop(from, get_src());
121de8bc62cSFabiano Rosas 
122de8bc62cSFabiano Rosas     qtest_qmp_eventwait(to, "RESUME");
123de8bc62cSFabiano Rosas 
124de8bc62cSFabiano Rosas     wait_for_serial("dest_serial");
125de8bc62cSFabiano Rosas     wait_for_migration_complete(from);
126de8bc62cSFabiano Rosas 
127de8bc62cSFabiano Rosas     /* Check whether shared RAM has been really skipped */
128de8bc62cSFabiano Rosas     g_assert_cmpint(
129de8bc62cSFabiano Rosas         read_ram_property_int(from, "transferred"), <, 4 * 1024 * 1024);
130de8bc62cSFabiano Rosas 
131de8bc62cSFabiano Rosas     migrate_end(from, to, true);
132de8bc62cSFabiano Rosas }
133de8bc62cSFabiano Rosas 
134de8bc62cSFabiano Rosas static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
135de8bc62cSFabiano Rosas {
136de8bc62cSFabiano Rosas     g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
137de8bc62cSFabiano Rosas     QTestState *from, *to;
138de8bc62cSFabiano Rosas 
139de8bc62cSFabiano Rosas     if (migrate_start(&from, &to, uri, args)) {
140de8bc62cSFabiano Rosas         return;
141de8bc62cSFabiano Rosas     }
142de8bc62cSFabiano Rosas 
143de8bc62cSFabiano Rosas     /*
144de8bc62cSFabiano Rosas      * UUID validation is at the begin of migration. So, the main process of
145de8bc62cSFabiano Rosas      * migration is not interesting for us here. Thus, set huge downtime for
146de8bc62cSFabiano Rosas      * very fast migration.
147de8bc62cSFabiano Rosas      */
148de8bc62cSFabiano Rosas     migrate_set_parameter_int(from, "downtime-limit", 1000000);
149de8bc62cSFabiano Rosas     migrate_set_capability(from, "validate-uuid", true);
150de8bc62cSFabiano Rosas 
151de8bc62cSFabiano Rosas     /* Wait for the first serial output from the source */
152de8bc62cSFabiano Rosas     wait_for_serial("src_serial");
153de8bc62cSFabiano Rosas 
154de8bc62cSFabiano Rosas     migrate_qmp(from, to, uri, NULL, "{}");
155de8bc62cSFabiano Rosas 
156de8bc62cSFabiano Rosas     if (should_fail) {
157de8bc62cSFabiano Rosas         qtest_set_expected_status(to, EXIT_FAILURE);
158de8bc62cSFabiano Rosas         wait_for_migration_fail(from, true);
159de8bc62cSFabiano Rosas     } else {
160de8bc62cSFabiano Rosas         wait_for_migration_complete(from);
161de8bc62cSFabiano Rosas     }
162de8bc62cSFabiano Rosas 
163de8bc62cSFabiano Rosas     migrate_end(from, to, false);
164de8bc62cSFabiano Rosas }
165de8bc62cSFabiano Rosas 
166de8bc62cSFabiano Rosas static void test_validate_uuid(void)
167de8bc62cSFabiano Rosas {
168de8bc62cSFabiano Rosas     MigrateStart args = {
169de8bc62cSFabiano Rosas         .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
170de8bc62cSFabiano Rosas         .opts_target = "-uuid 11111111-1111-1111-1111-111111111111",
171de8bc62cSFabiano Rosas     };
172de8bc62cSFabiano Rosas 
173de8bc62cSFabiano Rosas     do_test_validate_uuid(&args, false);
174de8bc62cSFabiano Rosas }
175de8bc62cSFabiano Rosas 
176de8bc62cSFabiano Rosas static void test_validate_uuid_error(void)
177de8bc62cSFabiano Rosas {
178de8bc62cSFabiano Rosas     MigrateStart args = {
179de8bc62cSFabiano Rosas         .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
180de8bc62cSFabiano Rosas         .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
181de8bc62cSFabiano Rosas         .hide_stderr = true,
182de8bc62cSFabiano Rosas     };
183de8bc62cSFabiano Rosas 
184de8bc62cSFabiano Rosas     do_test_validate_uuid(&args, true);
185de8bc62cSFabiano Rosas }
186de8bc62cSFabiano Rosas 
187de8bc62cSFabiano Rosas static void test_validate_uuid_src_not_set(void)
188de8bc62cSFabiano Rosas {
189de8bc62cSFabiano Rosas     MigrateStart args = {
190de8bc62cSFabiano Rosas         .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
191de8bc62cSFabiano Rosas         .hide_stderr = true,
192de8bc62cSFabiano Rosas     };
193de8bc62cSFabiano Rosas 
194de8bc62cSFabiano Rosas     do_test_validate_uuid(&args, false);
195de8bc62cSFabiano Rosas }
196de8bc62cSFabiano Rosas 
197de8bc62cSFabiano Rosas static void test_validate_uuid_dst_not_set(void)
198de8bc62cSFabiano Rosas {
199de8bc62cSFabiano Rosas     MigrateStart args = {
200de8bc62cSFabiano Rosas         .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
201de8bc62cSFabiano Rosas         .hide_stderr = true,
202de8bc62cSFabiano Rosas     };
203de8bc62cSFabiano Rosas 
204de8bc62cSFabiano Rosas     do_test_validate_uuid(&args, false);
205de8bc62cSFabiano Rosas }
206de8bc62cSFabiano Rosas 
207de8bc62cSFabiano Rosas static void do_test_validate_uri_channel(MigrateCommon *args)
208de8bc62cSFabiano Rosas {
209de8bc62cSFabiano Rosas     QTestState *from, *to;
21043ca9d18SSteve Sistare     QObject *channels;
211de8bc62cSFabiano Rosas 
212de8bc62cSFabiano Rosas     if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
213de8bc62cSFabiano Rosas         return;
214de8bc62cSFabiano Rosas     }
215de8bc62cSFabiano Rosas 
216de8bc62cSFabiano Rosas     /* Wait for the first serial output from the source */
217de8bc62cSFabiano Rosas     wait_for_serial("src_serial");
218de8bc62cSFabiano Rosas 
219de8bc62cSFabiano Rosas     /*
220de8bc62cSFabiano Rosas      * 'uri' and 'channels' validation is checked even before the migration
221de8bc62cSFabiano Rosas      * starts.
222de8bc62cSFabiano Rosas      */
22343ca9d18SSteve Sistare     channels = args->connect_channels ?
22443ca9d18SSteve Sistare                qobject_from_json(args->connect_channels, &error_abort) :
22543ca9d18SSteve Sistare                NULL;
22643ca9d18SSteve Sistare     migrate_qmp_fail(from, args->connect_uri, channels, "{}");
22743ca9d18SSteve Sistare 
228de8bc62cSFabiano Rosas     migrate_end(from, to, false);
229de8bc62cSFabiano Rosas }
230de8bc62cSFabiano Rosas 
231de8bc62cSFabiano Rosas static void test_validate_uri_channels_both_set(void)
232de8bc62cSFabiano Rosas {
233de8bc62cSFabiano Rosas     MigrateCommon args = {
234de8bc62cSFabiano Rosas         .start = {
235de8bc62cSFabiano Rosas             .hide_stderr = true,
236de8bc62cSFabiano Rosas         },
237de8bc62cSFabiano Rosas         .listen_uri = "defer",
238de8bc62cSFabiano Rosas         .connect_uri = "tcp:127.0.0.1:0",
239de8bc62cSFabiano Rosas         .connect_channels = ("[ { ""'channel-type': 'main',"
240de8bc62cSFabiano Rosas                              "    'addr': { 'transport': 'socket',"
241de8bc62cSFabiano Rosas                              "              'type': 'inet',"
242de8bc62cSFabiano Rosas                              "              'host': '127.0.0.1',"
243de8bc62cSFabiano Rosas                              "              'port': '0' } } ]"),
244de8bc62cSFabiano Rosas     };
245de8bc62cSFabiano Rosas 
246de8bc62cSFabiano Rosas     do_test_validate_uri_channel(&args);
247de8bc62cSFabiano Rosas }
248de8bc62cSFabiano Rosas 
249de8bc62cSFabiano Rosas static void test_validate_uri_channels_none_set(void)
250de8bc62cSFabiano Rosas {
251de8bc62cSFabiano Rosas     MigrateCommon args = {
252de8bc62cSFabiano Rosas         .start = {
253de8bc62cSFabiano Rosas             .hide_stderr = true,
254de8bc62cSFabiano Rosas         },
255de8bc62cSFabiano Rosas         .listen_uri = "defer",
256de8bc62cSFabiano Rosas     };
257de8bc62cSFabiano Rosas 
258de8bc62cSFabiano Rosas     do_test_validate_uri_channel(&args);
259de8bc62cSFabiano Rosas }
260de8bc62cSFabiano Rosas 
261*43ab3fb3SFabiano Rosas static void migration_test_add_misc_smoke(MigrationTestEnv *env)
262*43ab3fb3SFabiano Rosas {
263*43ab3fb3SFabiano Rosas #ifndef _WIN32
264*43ab3fb3SFabiano Rosas     migration_test_add("/migration/analyze-script", test_analyze_script);
265*43ab3fb3SFabiano Rosas #endif
266*43ab3fb3SFabiano Rosas }
267*43ab3fb3SFabiano Rosas 
268de8bc62cSFabiano Rosas void migration_test_add_misc(MigrationTestEnv *env)
269de8bc62cSFabiano Rosas {
270de8bc62cSFabiano Rosas     tmpfs = env->tmpfs;
271de8bc62cSFabiano Rosas 
272*43ab3fb3SFabiano Rosas     migration_test_add_misc_smoke(env);
273*43ab3fb3SFabiano Rosas 
274bc2a1f1aSFabiano Rosas     if (!env->full_set) {
275bc2a1f1aSFabiano Rosas         return;
276bc2a1f1aSFabiano Rosas     }
277bc2a1f1aSFabiano Rosas 
278de8bc62cSFabiano Rosas     migration_test_add("/migration/bad_dest", test_baddest);
279de8bc62cSFabiano Rosas 
280de8bc62cSFabiano Rosas     /*
281de8bc62cSFabiano Rosas      * Our CI system has problems with shared memory.
282de8bc62cSFabiano Rosas      * Don't run this test until we find a workaround.
283de8bc62cSFabiano Rosas      */
284de8bc62cSFabiano Rosas     if (getenv("QEMU_TEST_FLAKY_TESTS")) {
285de8bc62cSFabiano Rosas         migration_test_add("/migration/ignore-shared", test_ignore_shared);
286de8bc62cSFabiano Rosas     }
287de8bc62cSFabiano Rosas 
288de8bc62cSFabiano Rosas     migration_test_add("/migration/validate_uuid", test_validate_uuid);
289de8bc62cSFabiano Rosas     migration_test_add("/migration/validate_uuid_error",
290de8bc62cSFabiano Rosas                        test_validate_uuid_error);
291de8bc62cSFabiano Rosas     migration_test_add("/migration/validate_uuid_src_not_set",
292de8bc62cSFabiano Rosas                        test_validate_uuid_src_not_set);
293de8bc62cSFabiano Rosas     migration_test_add("/migration/validate_uuid_dst_not_set",
294de8bc62cSFabiano Rosas                        test_validate_uuid_dst_not_set);
295de8bc62cSFabiano Rosas     migration_test_add("/migration/validate_uri/channels/both_set",
296de8bc62cSFabiano Rosas                        test_validate_uri_channels_both_set);
297de8bc62cSFabiano Rosas     migration_test_add("/migration/validate_uri/channels/none_set",
298de8bc62cSFabiano Rosas                        test_validate_uri_channels_none_set);
299de8bc62cSFabiano Rosas }
300