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