2 * Copyright (C) 2013, 2014 Red Hat, Inc.
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library. If not, see
16 * <http://www.gnu.org/licenses/>.
22 #include "testutils.h"
23 #include "testutilsqemu.h"
24 #include "qemumonitortestutils.h"
25 #include "qemu/qemu_conf.h"
26 #include "qemu/qemu_agent.h"
27 #include "virthread.h"
29 #include "virstring.h"
32 #define VIR_FROM_THIS VIR_FROM_NONE
35 testQemuAgentFSFreeze(const void *data)
37 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
38 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
39 const char *mountpoints[] = {"/fs1", "/fs2", "/fs3", "/fs4", "/fs5"};
45 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
48 if (qemuMonitorTestAddItem(test, "guest-fsfreeze-freeze",
49 "{ \"return\" : 5 }") < 0)
52 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
55 if (qemuMonitorTestAddItem(test, "guest-fsfreeze-freeze",
56 "{ \"return\" : 7 }") < 0)
59 if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test),
64 virReportError(VIR_ERR_INTERNAL_ERROR,
65 "expected 5 frozen filesystems, got %d", ret);
69 if ((ret = qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0)) < 0)
73 virReportError(VIR_ERR_INTERNAL_ERROR,
74 "expected 7 frozen filesystems, got %d", ret);
81 qemuMonitorTestFree(test);
87 testQemuAgentFSThaw(const void *data)
89 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
90 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
96 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
99 if (qemuMonitorTestAddItem(test, "guest-fsfreeze-thaw",
100 "{ \"return\" : 5 }") < 0)
103 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
106 if (qemuMonitorTestAddItem(test, "guest-fsfreeze-thaw",
107 "{ \"return\" : 7 }") < 0)
110 if ((ret = qemuAgentFSThaw(qemuMonitorTestGetAgent(test))) < 0)
114 virReportError(VIR_ERR_INTERNAL_ERROR,
115 "expected 5 thawed filesystems, got %d", ret);
119 if ((ret = qemuAgentFSThaw(qemuMonitorTestGetAgent(test))) < 0)
123 virReportError(VIR_ERR_INTERNAL_ERROR,
124 "expected 7 thawed filesystems, got %d", ret);
131 qemuMonitorTestFree(test);
137 testQemuAgentFSTrim(const void *data)
139 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
140 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
146 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
149 if (qemuMonitorTestAddItemParams(test, "guest-fstrim",
150 "{ \"return\" : {} }",
155 if (qemuAgentFSTrim(qemuMonitorTestGetAgent(test), 1337) < 0)
161 qemuMonitorTestFree(test);
167 testQemuAgentSuspend(const void *data)
169 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
170 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
177 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
180 if (qemuMonitorTestAddItem(test, "guest-suspend-ram",
181 "{ \"return\" : {} }") < 0)
184 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
187 if (qemuMonitorTestAddItem(test, "guest-suspend-disk",
188 "{ \"return\" : {} }") < 0)
191 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
194 if (qemuMonitorTestAddItem(test, "guest-suspend-hybrid",
195 "{ \"return\" : {} }") < 0)
198 /* try the commands - fail if ordering changes */
199 for (i = 0; i < VIR_NODE_SUSPEND_TARGET_LAST; i++) {
200 if (qemuAgentSuspend(qemuMonitorTestGetAgent(test), i) < 0)
207 qemuMonitorTestFree(test);
212 struct qemuAgentShutdownTestData {
214 qemuAgentEvent event;
219 qemuAgentShutdownTestMonitorHandler(qemuMonitorTestPtr test,
220 qemuMonitorTestItemPtr item,
223 struct qemuAgentShutdownTestData *data;
224 virJSONValuePtr val = NULL;
225 virJSONValuePtr args;
230 data = qemuMonitorTestItemGetPrivateData(item);
232 if (!(val = virJSONValueFromString(cmdstr)))
235 if (!(cmdname = virJSONValueObjectGetString(val, "execute"))) {
236 ret = qemuMonitorReportError(test, "Missing command name in %s", cmdstr);
240 if (STRNEQ(cmdname, "guest-shutdown")) {
241 ret = qemuMonitorTestAddUnexpectedErrorResponse(test);
245 if (!(args = virJSONValueObjectGet(val, "arguments"))) {
246 ret = qemuMonitorReportError(test,
247 "Missing arguments section");
251 if (!(mode = virJSONValueObjectGetString(args, "mode"))) {
252 ret = qemuMonitorReportError(test, "Missing shutdown mode");
256 if (STRNEQ(mode, data->mode)) {
257 ret = qemuMonitorReportError(test,
258 "expected shutdown mode '%s' got '%s'",
263 /* now don't reply but return a qemu agent event */
264 qemuAgentNotifyEvent(qemuMonitorTestGetAgent(test),
270 virJSONValueFree(val);
277 testQemuAgentShutdown(const void *data)
279 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
280 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
281 struct qemuAgentShutdownTestData priv;
287 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
290 priv.event = QEMU_AGENT_EVENT_SHUTDOWN;
293 if (qemuMonitorTestAddHandler(test, qemuAgentShutdownTestMonitorHandler,
297 if (qemuAgentShutdown(qemuMonitorTestGetAgent(test),
298 QEMU_AGENT_SHUTDOWN_HALT) < 0)
301 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
304 priv.event = QEMU_AGENT_EVENT_SHUTDOWN;
305 priv.mode = "powerdown";
307 if (qemuMonitorTestAddHandler(test, qemuAgentShutdownTestMonitorHandler,
311 if (qemuAgentShutdown(qemuMonitorTestGetAgent(test),
312 QEMU_AGENT_SHUTDOWN_POWERDOWN) < 0)
315 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
318 priv.event = QEMU_AGENT_EVENT_RESET;
319 priv.mode = "reboot";
321 if (qemuMonitorTestAddHandler(test, qemuAgentShutdownTestMonitorHandler,
325 if (qemuAgentShutdown(qemuMonitorTestGetAgent(test),
326 QEMU_AGENT_SHUTDOWN_REBOOT) < 0)
329 /* check negative response, so that we can verify that the agent breaks
332 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
335 if (qemuMonitorTestAddItem(test, "guest-shutdown",
337 " {\"class\":\"CommandDisabled\","
338 " \"desc\":\"The command guest-shutdown has "
339 "been disabled for this instance\","
340 " \"data\":{\"name\":\"guest-shutdown\"}"
345 if (qemuAgentShutdown(qemuMonitorTestGetAgent(test),
346 QEMU_AGENT_SHUTDOWN_REBOOT) != -1) {
347 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
348 "agent shutdown command should have failed");
355 qemuMonitorTestFree(test);
360 static const char testQemuAgentCPUResponse[] =
363 " {\"online\": true,"
364 " \"can-offline\": false,"
367 " {\"online\": true,"
368 " \"can-offline\": true,"
371 " {\"online\": true,"
372 " \"can-offline\": true,"
375 " {\"online\": false,"
376 " \"can-offline\": true,"
382 static const char testQemuAgentCPUArguments1[] =
383 "[{\"logical-id\":0,\"online\":true},"
384 "{\"logical-id\":1,\"online\":false},"
385 "{\"logical-id\":2,\"online\":true},"
386 "{\"logical-id\":3,\"online\":false}]";
388 static const char testQemuAgentCPUArguments2[] =
389 "[{\"logical-id\":0,\"online\":true},"
390 "{\"logical-id\":1,\"online\":true},"
391 "{\"logical-id\":2,\"online\":true},"
392 "{\"logical-id\":3,\"online\":true}]";
395 testQemuAgentCPU(const void *data)
397 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
398 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
399 qemuAgentCPUInfoPtr cpuinfo = NULL;
406 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
409 if (qemuMonitorTestAddItem(test, "guest-get-vcpus",
410 testQemuAgentCPUResponse) < 0)
414 if ((nvcpus = qemuAgentGetVCPUs(qemuMonitorTestGetAgent(test),
419 virReportError(VIR_ERR_INTERNAL_ERROR,
420 "Expected '4' cpus, got '%d'", nvcpus);
424 /* try to unplug one */
425 if (qemuAgentUpdateCPUInfo(2, cpuinfo, nvcpus) < 0)
428 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
431 if (qemuMonitorTestAddItemParams(test, "guest-set-vcpus",
432 "{ \"return\" : 4 }",
433 "vcpus", testQemuAgentCPUArguments1,
437 if ((nvcpus = qemuAgentSetVCPUs(qemuMonitorTestGetAgent(test),
438 cpuinfo, nvcpus)) < 0)
442 virReportError(VIR_ERR_INTERNAL_ERROR,
443 "Expected '4' cpus updated , got '%d'", nvcpus);
447 /* try to hotplug two */
448 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
451 if (qemuMonitorTestAddItemParams(test, "guest-set-vcpus",
452 "{ \"return\" : 4 }",
453 "vcpus", testQemuAgentCPUArguments2,
457 if (qemuAgentUpdateCPUInfo(4, cpuinfo, nvcpus) < 0)
460 if ((nvcpus = qemuAgentSetVCPUs(qemuMonitorTestGetAgent(test),
461 cpuinfo, nvcpus)) < 0)
465 virReportError(VIR_ERR_INTERNAL_ERROR,
466 "Expected '4' cpus updated , got '%d'", nvcpus);
474 qemuMonitorTestFree(test);
479 static const char testQemuAgentArbitraryCommandResponse[] =
480 "{\"return\":\"bla\"}";
483 testQemuAgentArbitraryCommand(const void *data)
485 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
486 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
493 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
496 if (qemuMonitorTestAddItem(test, "ble",
497 testQemuAgentArbitraryCommandResponse) < 0)
500 if (qemuAgentArbitraryCommand(qemuMonitorTestGetAgent(test),
501 "{\"execute\":\"ble\"}",
503 VIR_DOMAIN_QEMU_AGENT_COMMAND_BLOCK) < 0)
506 if (STRNEQ(reply, testQemuAgentArbitraryCommandResponse)) {
507 virReportError(VIR_ERR_INTERNAL_ERROR,
508 "invalid processing of guest agent reply: "
509 "got '%s' expected '%s'",
510 reply, testQemuAgentArbitraryCommandResponse);
518 qemuMonitorTestFree(test);
524 qemuAgentTimeoutTestMonitorHandler(qemuMonitorTestPtr test ATTRIBUTE_UNUSED,
525 qemuMonitorTestItemPtr item ATTRIBUTE_UNUSED,
526 const char *cmdstr ATTRIBUTE_UNUSED)
533 testQemuAgentTimeout(const void *data)
535 virDomainXMLOptionPtr xmlopt = (virDomainXMLOptionPtr)data;
536 qemuMonitorTestPtr test = qemuMonitorTestNewAgent(xmlopt);
543 if (virTestGetExpensive() == 0) {
548 if (qemuMonitorTestAddHandler(test, qemuAgentTimeoutTestMonitorHandler,
552 if (qemuAgentFSFreeze(qemuMonitorTestGetAgent(test), NULL, 0) != -1) {
553 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
554 "agent command should have failed");
559 if (qemuMonitorTestAddAgentSyncResponse(test) < 0)
562 if (qemuMonitorTestAddHandler(test, qemuAgentTimeoutTestMonitorHandler,
566 if (qemuAgentArbitraryCommand(qemuMonitorTestGetAgent(test),
567 "{\"execute\":\"ble\"}",
570 virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
571 "agent command didn't time out");
579 qemuMonitorTestFree(test);
588 virDomainXMLOptionPtr xmlopt;
591 fputs("libvirt not compiled with yajl, skipping this test\n", stderr);
595 if (virThreadInitialize() < 0 ||
596 !(xmlopt = virQEMUDriverCreateXMLConf(NULL)))
599 virEventRegisterDefaultImpl();
601 #define DO_TEST(name) \
602 if (virtTestRun(# name, testQemuAgent ## name, xmlopt) < 0) \
611 DO_TEST(ArbitraryCommand);
613 DO_TEST(Timeout); /* Timeout should always be called last */
615 virObjectUnref(xmlopt);
617 return (ret == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
620 VIRT_TEST_MAIN(mymain)