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"
15407bc4bfSDaniel P. Berrangé #include "qobject/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
test_baddest(void)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
test_analyze_script(void)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
test_ignore_shared(void)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,
101*115cec9dSPrasad Pandit .caps[MIGRATION_CAPABILITY_X_IGNORE_SHARED] = true,
102de8bc62cSFabiano Rosas };
103de8bc62cSFabiano Rosas
104de8bc62cSFabiano Rosas if (migrate_start(&from, &to, uri, &args)) {
105de8bc62cSFabiano Rosas return;
106de8bc62cSFabiano Rosas }
107de8bc62cSFabiano Rosas
108de8bc62cSFabiano Rosas migrate_ensure_non_converge(from);
109de8bc62cSFabiano Rosas migrate_prepare_for_dirty_mem(from);
110de8bc62cSFabiano Rosas
111de8bc62cSFabiano Rosas /* Wait for the first serial output from the source */
112de8bc62cSFabiano Rosas wait_for_serial("src_serial");
113de8bc62cSFabiano Rosas
114de8bc62cSFabiano Rosas migrate_qmp(from, to, uri, NULL, "{}");
115de8bc62cSFabiano Rosas
116de8bc62cSFabiano Rosas migrate_wait_for_dirty_mem(from, to);
117de8bc62cSFabiano Rosas
118de8bc62cSFabiano Rosas wait_for_stop(from, get_src());
119de8bc62cSFabiano Rosas
120de8bc62cSFabiano Rosas qtest_qmp_eventwait(to, "RESUME");
121de8bc62cSFabiano Rosas
122de8bc62cSFabiano Rosas wait_for_serial("dest_serial");
123de8bc62cSFabiano Rosas wait_for_migration_complete(from);
124de8bc62cSFabiano Rosas
125de8bc62cSFabiano Rosas /* Check whether shared RAM has been really skipped */
126de8bc62cSFabiano Rosas g_assert_cmpint(
127de8bc62cSFabiano Rosas read_ram_property_int(from, "transferred"), <, 4 * 1024 * 1024);
128de8bc62cSFabiano Rosas
129de8bc62cSFabiano Rosas migrate_end(from, to, true);
130de8bc62cSFabiano Rosas }
131de8bc62cSFabiano Rosas
do_test_validate_uuid(MigrateStart * args,bool should_fail)132de8bc62cSFabiano Rosas static void do_test_validate_uuid(MigrateStart *args, bool should_fail)
133de8bc62cSFabiano Rosas {
134de8bc62cSFabiano Rosas g_autofree char *uri = g_strdup_printf("unix:%s/migsocket", tmpfs);
135de8bc62cSFabiano Rosas QTestState *from, *to;
136de8bc62cSFabiano Rosas
137de8bc62cSFabiano Rosas if (migrate_start(&from, &to, uri, args)) {
138de8bc62cSFabiano Rosas return;
139de8bc62cSFabiano Rosas }
140de8bc62cSFabiano Rosas
141de8bc62cSFabiano Rosas /*
142de8bc62cSFabiano Rosas * UUID validation is at the begin of migration. So, the main process of
143de8bc62cSFabiano Rosas * migration is not interesting for us here. Thus, set huge downtime for
144de8bc62cSFabiano Rosas * very fast migration.
145de8bc62cSFabiano Rosas */
146de8bc62cSFabiano Rosas migrate_set_parameter_int(from, "downtime-limit", 1000000);
147de8bc62cSFabiano Rosas migrate_set_capability(from, "validate-uuid", true);
148de8bc62cSFabiano Rosas
149de8bc62cSFabiano Rosas /* Wait for the first serial output from the source */
150de8bc62cSFabiano Rosas wait_for_serial("src_serial");
151de8bc62cSFabiano Rosas
152de8bc62cSFabiano Rosas migrate_qmp(from, to, uri, NULL, "{}");
153de8bc62cSFabiano Rosas
154de8bc62cSFabiano Rosas if (should_fail) {
155de8bc62cSFabiano Rosas qtest_set_expected_status(to, EXIT_FAILURE);
156de8bc62cSFabiano Rosas wait_for_migration_fail(from, true);
157de8bc62cSFabiano Rosas } else {
158de8bc62cSFabiano Rosas wait_for_migration_complete(from);
159de8bc62cSFabiano Rosas }
160de8bc62cSFabiano Rosas
161de8bc62cSFabiano Rosas migrate_end(from, to, false);
162de8bc62cSFabiano Rosas }
163de8bc62cSFabiano Rosas
test_validate_uuid(void)164de8bc62cSFabiano Rosas static void test_validate_uuid(void)
165de8bc62cSFabiano Rosas {
166de8bc62cSFabiano Rosas MigrateStart args = {
167de8bc62cSFabiano Rosas .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
168de8bc62cSFabiano Rosas .opts_target = "-uuid 11111111-1111-1111-1111-111111111111",
169de8bc62cSFabiano Rosas };
170de8bc62cSFabiano Rosas
171de8bc62cSFabiano Rosas do_test_validate_uuid(&args, false);
172de8bc62cSFabiano Rosas }
173de8bc62cSFabiano Rosas
test_validate_uuid_error(void)174de8bc62cSFabiano Rosas static void test_validate_uuid_error(void)
175de8bc62cSFabiano Rosas {
176de8bc62cSFabiano Rosas MigrateStart args = {
177de8bc62cSFabiano Rosas .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
178de8bc62cSFabiano Rosas .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
179de8bc62cSFabiano Rosas .hide_stderr = true,
180de8bc62cSFabiano Rosas };
181de8bc62cSFabiano Rosas
182de8bc62cSFabiano Rosas do_test_validate_uuid(&args, true);
183de8bc62cSFabiano Rosas }
184de8bc62cSFabiano Rosas
test_validate_uuid_src_not_set(void)185de8bc62cSFabiano Rosas static void test_validate_uuid_src_not_set(void)
186de8bc62cSFabiano Rosas {
187de8bc62cSFabiano Rosas MigrateStart args = {
188de8bc62cSFabiano Rosas .opts_target = "-uuid 22222222-2222-2222-2222-222222222222",
189de8bc62cSFabiano Rosas .hide_stderr = true,
190de8bc62cSFabiano Rosas };
191de8bc62cSFabiano Rosas
192de8bc62cSFabiano Rosas do_test_validate_uuid(&args, false);
193de8bc62cSFabiano Rosas }
194de8bc62cSFabiano Rosas
test_validate_uuid_dst_not_set(void)195de8bc62cSFabiano Rosas static void test_validate_uuid_dst_not_set(void)
196de8bc62cSFabiano Rosas {
197de8bc62cSFabiano Rosas MigrateStart args = {
198de8bc62cSFabiano Rosas .opts_source = "-uuid 11111111-1111-1111-1111-111111111111",
199de8bc62cSFabiano Rosas .hide_stderr = true,
200de8bc62cSFabiano Rosas };
201de8bc62cSFabiano Rosas
202de8bc62cSFabiano Rosas do_test_validate_uuid(&args, false);
203de8bc62cSFabiano Rosas }
204de8bc62cSFabiano Rosas
do_test_validate_uri_channel(MigrateCommon * args)205de8bc62cSFabiano Rosas static void do_test_validate_uri_channel(MigrateCommon *args)
206de8bc62cSFabiano Rosas {
207de8bc62cSFabiano Rosas QTestState *from, *to;
20843ca9d18SSteve Sistare QObject *channels;
209de8bc62cSFabiano Rosas
210de8bc62cSFabiano Rosas if (migrate_start(&from, &to, args->listen_uri, &args->start)) {
211de8bc62cSFabiano Rosas return;
212de8bc62cSFabiano Rosas }
213de8bc62cSFabiano Rosas
214de8bc62cSFabiano Rosas /* Wait for the first serial output from the source */
215de8bc62cSFabiano Rosas wait_for_serial("src_serial");
216de8bc62cSFabiano Rosas
217de8bc62cSFabiano Rosas /*
218de8bc62cSFabiano Rosas * 'uri' and 'channels' validation is checked even before the migration
219de8bc62cSFabiano Rosas * starts.
220de8bc62cSFabiano Rosas */
22143ca9d18SSteve Sistare channels = args->connect_channels ?
22243ca9d18SSteve Sistare qobject_from_json(args->connect_channels, &error_abort) :
22343ca9d18SSteve Sistare NULL;
22443ca9d18SSteve Sistare migrate_qmp_fail(from, args->connect_uri, channels, "{}");
22543ca9d18SSteve Sistare
226de8bc62cSFabiano Rosas migrate_end(from, to, false);
227de8bc62cSFabiano Rosas }
228de8bc62cSFabiano Rosas
test_validate_uri_channels_both_set(void)229de8bc62cSFabiano Rosas static void test_validate_uri_channels_both_set(void)
230de8bc62cSFabiano Rosas {
231de8bc62cSFabiano Rosas MigrateCommon args = {
232de8bc62cSFabiano Rosas .start = {
233de8bc62cSFabiano Rosas .hide_stderr = true,
234de8bc62cSFabiano Rosas },
235de8bc62cSFabiano Rosas .listen_uri = "defer",
236de8bc62cSFabiano Rosas .connect_uri = "tcp:127.0.0.1:0",
237de8bc62cSFabiano Rosas .connect_channels = ("[ { ""'channel-type': 'main',"
238de8bc62cSFabiano Rosas " 'addr': { 'transport': 'socket',"
239de8bc62cSFabiano Rosas " 'type': 'inet',"
240de8bc62cSFabiano Rosas " 'host': '127.0.0.1',"
241de8bc62cSFabiano Rosas " 'port': '0' } } ]"),
242de8bc62cSFabiano Rosas };
243de8bc62cSFabiano Rosas
244de8bc62cSFabiano Rosas do_test_validate_uri_channel(&args);
245de8bc62cSFabiano Rosas }
246de8bc62cSFabiano Rosas
test_validate_uri_channels_none_set(void)247de8bc62cSFabiano Rosas static void test_validate_uri_channels_none_set(void)
248de8bc62cSFabiano Rosas {
249de8bc62cSFabiano Rosas MigrateCommon args = {
250de8bc62cSFabiano Rosas .start = {
251de8bc62cSFabiano Rosas .hide_stderr = true,
252de8bc62cSFabiano Rosas },
253de8bc62cSFabiano Rosas .listen_uri = "defer",
254de8bc62cSFabiano Rosas };
255de8bc62cSFabiano Rosas
256de8bc62cSFabiano Rosas do_test_validate_uri_channel(&args);
257de8bc62cSFabiano Rosas }
258de8bc62cSFabiano Rosas
migration_test_add_misc_smoke(MigrationTestEnv * env)25943ab3fb3SFabiano Rosas static void migration_test_add_misc_smoke(MigrationTestEnv *env)
26043ab3fb3SFabiano Rosas {
26143ab3fb3SFabiano Rosas #ifndef _WIN32
26243ab3fb3SFabiano Rosas migration_test_add("/migration/analyze-script", test_analyze_script);
26343ab3fb3SFabiano Rosas #endif
26443ab3fb3SFabiano Rosas }
26543ab3fb3SFabiano Rosas
migration_test_add_misc(MigrationTestEnv * env)266de8bc62cSFabiano Rosas void migration_test_add_misc(MigrationTestEnv *env)
267de8bc62cSFabiano Rosas {
268de8bc62cSFabiano Rosas tmpfs = env->tmpfs;
269de8bc62cSFabiano Rosas
27043ab3fb3SFabiano Rosas migration_test_add_misc_smoke(env);
27143ab3fb3SFabiano Rosas
272bc2a1f1aSFabiano Rosas if (!env->full_set) {
273bc2a1f1aSFabiano Rosas return;
274bc2a1f1aSFabiano Rosas }
275bc2a1f1aSFabiano Rosas
276de8bc62cSFabiano Rosas migration_test_add("/migration/bad_dest", test_baddest);
277de8bc62cSFabiano Rosas
278de8bc62cSFabiano Rosas /*
279de8bc62cSFabiano Rosas * Our CI system has problems with shared memory.
280de8bc62cSFabiano Rosas * Don't run this test until we find a workaround.
281de8bc62cSFabiano Rosas */
282de8bc62cSFabiano Rosas if (getenv("QEMU_TEST_FLAKY_TESTS")) {
283de8bc62cSFabiano Rosas migration_test_add("/migration/ignore-shared", test_ignore_shared);
284de8bc62cSFabiano Rosas }
285de8bc62cSFabiano Rosas
286de8bc62cSFabiano Rosas migration_test_add("/migration/validate_uuid", test_validate_uuid);
287de8bc62cSFabiano Rosas migration_test_add("/migration/validate_uuid_error",
288de8bc62cSFabiano Rosas test_validate_uuid_error);
289de8bc62cSFabiano Rosas migration_test_add("/migration/validate_uuid_src_not_set",
290de8bc62cSFabiano Rosas test_validate_uuid_src_not_set);
291de8bc62cSFabiano Rosas migration_test_add("/migration/validate_uuid_dst_not_set",
292de8bc62cSFabiano Rosas test_validate_uuid_dst_not_set);
293de8bc62cSFabiano Rosas migration_test_add("/migration/validate_uri/channels/both_set",
294de8bc62cSFabiano Rosas test_validate_uri_channels_both_set);
295de8bc62cSFabiano Rosas migration_test_add("/migration/validate_uri/channels/none_set",
296de8bc62cSFabiano Rosas test_validate_uri_channels_none_set);
297de8bc62cSFabiano Rosas }
298