1 /* 2 * QTest 3 * 4 * Copyright IBM, Corp. 2012 5 * Copyright Red Hat, Inc. 2012 6 * Copyright SUSE LINUX Products GmbH 2013 7 * 8 * Authors: 9 * Anthony Liguori <aliguori@us.ibm.com> 10 * Paolo Bonzini <pbonzini@redhat.com> 11 * Andreas Färber <afaerber@suse.de> 12 * 13 * This work is licensed under the terms of the GNU GPL, version 2 or later. 14 * See the COPYING file in the top-level directory. 15 */ 16 17 #include "qemu/osdep.h" 18 19 #ifndef _WIN32 20 #include <sys/socket.h> 21 #include <sys/wait.h> 22 #include <sys/un.h> 23 #endif /* _WIN32 */ 24 #ifdef __linux__ 25 #include <sys/prctl.h> 26 #endif /* __linux__ */ 27 28 #include "libqtest.h" 29 #include "libqmp.h" 30 #include "qemu/ctype.h" 31 #include "qemu/cutils.h" 32 #include "qemu/sockets.h" 33 #include "qapi/qmp/qdict.h" 34 #include "qapi/qmp/qjson.h" 35 #include "qapi/qmp/qlist.h" 36 #include "qapi/qmp/qstring.h" 37 38 #define MAX_IRQ 256 39 40 #ifndef _WIN32 41 # define SOCKET_TIMEOUT 50 42 # define CMD_EXEC "exec " 43 # define DEV_STDERR "/dev/fd/2" 44 # define DEV_NULL "/dev/null" 45 #else 46 # define SOCKET_TIMEOUT 50000 47 # define CMD_EXEC "" 48 # define DEV_STDERR "2" 49 # define DEV_NULL "nul" 50 #endif 51 52 #define WAITPID_TIMEOUT 30 53 54 typedef void (*QTestSendFn)(QTestState *s, const char *buf); 55 typedef void (*ExternalSendFn)(void *s, const char *buf); 56 typedef GString* (*QTestRecvFn)(QTestState *); 57 58 typedef struct QTestClientTransportOps { 59 QTestSendFn send; /* for sending qtest commands */ 60 61 /* 62 * use external_send to send qtest command strings through functions which 63 * do not accept a QTestState as the first parameter. 64 */ 65 ExternalSendFn external_send; 66 67 QTestRecvFn recv_line; /* for receiving qtest command responses */ 68 } QTestTransportOps; 69 70 struct QTestState 71 { 72 int fd; 73 int qmp_fd; 74 pid_t qemu_pid; /* our child QEMU process */ 75 int wstatus; 76 #ifdef _WIN32 77 DWORD exit_code; 78 #endif 79 int expected_status; 80 bool big_endian; 81 bool irq_level[MAX_IRQ]; 82 GString *rx; 83 QTestTransportOps ops; 84 GList *pending_events; 85 }; 86 87 static GHookList abrt_hooks; 88 static void (*sighandler_old)(int); 89 90 static int qtest_query_target_endianness(QTestState *s); 91 92 static void qtest_client_socket_send(QTestState*, const char *buf); 93 static void socket_send(int fd, const char *buf, size_t size); 94 95 static GString *qtest_client_socket_recv_line(QTestState *); 96 97 static void qtest_client_set_tx_handler(QTestState *s, QTestSendFn send); 98 static void qtest_client_set_rx_handler(QTestState *s, QTestRecvFn recv); 99 100 static int init_socket(const char *socket_path) 101 { 102 int sock = qtest_socket_server(socket_path); 103 qemu_set_cloexec(sock); 104 return sock; 105 } 106 107 static int socket_accept(int sock) 108 { 109 struct sockaddr_un addr; 110 socklen_t addrlen; 111 int ret; 112 /* 113 * timeout unit of blocking receive calls is different among platfoms. 114 * It's in seconds on non-Windows platforms but milliseconds on Windows. 115 */ 116 #ifndef _WIN32 117 struct timeval timeout = { .tv_sec = SOCKET_TIMEOUT, 118 .tv_usec = 0 }; 119 #else 120 DWORD timeout = SOCKET_TIMEOUT; 121 #endif 122 123 if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, 124 (void *)&timeout, sizeof(timeout))) { 125 fprintf(stderr, "%s failed to set SO_RCVTIMEO: %s\n", 126 __func__, strerror(errno)); 127 closesocket(sock); 128 return -1; 129 } 130 131 do { 132 addrlen = sizeof(addr); 133 ret = accept(sock, (struct sockaddr *)&addr, &addrlen); 134 } while (ret == -1 && errno == EINTR); 135 if (ret == -1) { 136 fprintf(stderr, "%s failed: %s\n", __func__, strerror(errno)); 137 } 138 closesocket(sock); 139 140 return ret; 141 } 142 143 bool qtest_probe_child(QTestState *s) 144 { 145 pid_t pid = s->qemu_pid; 146 147 if (pid != -1) { 148 #ifndef _WIN32 149 pid = waitpid(pid, &s->wstatus, WNOHANG); 150 if (pid == 0) { 151 return true; 152 } 153 #else 154 GetExitCodeProcess((HANDLE)pid, &s->exit_code); 155 if (s->exit_code == STILL_ACTIVE) { 156 return true; 157 } 158 CloseHandle((HANDLE)pid); 159 #endif 160 s->qemu_pid = -1; 161 } 162 return false; 163 } 164 165 void qtest_set_expected_status(QTestState *s, int status) 166 { 167 s->expected_status = status; 168 } 169 170 static void qtest_check_status(QTestState *s) 171 { 172 /* 173 * Check whether qemu exited with expected exit status; anything else is 174 * fishy and should be logged with as much detail as possible. 175 */ 176 #ifndef _WIN32 177 int wstatus = s->wstatus; 178 if (WIFEXITED(wstatus) && WEXITSTATUS(wstatus) != s->expected_status) { 179 fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " 180 "process but encountered exit status %d (expected %d)\n", 181 __FILE__, __LINE__, WEXITSTATUS(wstatus), s->expected_status); 182 abort(); 183 } else if (WIFSIGNALED(wstatus)) { 184 int sig = WTERMSIG(wstatus); 185 const char *signame = strsignal(sig) ?: "unknown ???"; 186 const char *dump = WCOREDUMP(wstatus) ? " (core dumped)" : ""; 187 188 fprintf(stderr, "%s:%d: kill_qemu() detected QEMU death " 189 "from signal %d (%s)%s\n", 190 __FILE__, __LINE__, sig, signame, dump); 191 abort(); 192 } 193 #else 194 if (s->exit_code != s->expected_status) { 195 fprintf(stderr, "%s:%d: kill_qemu() tried to terminate QEMU " 196 "process but encountered exit status %ld (expected %d)\n", 197 __FILE__, __LINE__, s->exit_code, s->expected_status); 198 abort(); 199 } 200 #endif 201 } 202 203 void qtest_wait_qemu(QTestState *s) 204 { 205 #ifndef _WIN32 206 pid_t pid; 207 uint64_t end; 208 209 /* poll for a while until sending SIGKILL */ 210 end = g_get_monotonic_time() + WAITPID_TIMEOUT * G_TIME_SPAN_SECOND; 211 212 do { 213 pid = waitpid(s->qemu_pid, &s->wstatus, WNOHANG); 214 if (pid != 0) { 215 break; 216 } 217 g_usleep(100 * 1000); 218 } while (g_get_monotonic_time() < end); 219 220 if (pid == 0) { 221 kill(s->qemu_pid, SIGKILL); 222 pid = RETRY_ON_EINTR(waitpid(s->qemu_pid, &s->wstatus, 0)); 223 } 224 225 assert(pid == s->qemu_pid); 226 #else 227 DWORD ret; 228 229 ret = WaitForSingleObject((HANDLE)s->qemu_pid, INFINITE); 230 assert(ret == WAIT_OBJECT_0); 231 GetExitCodeProcess((HANDLE)s->qemu_pid, &s->exit_code); 232 CloseHandle((HANDLE)s->qemu_pid); 233 #endif 234 235 qtest_check_status(s); 236 } 237 238 void qtest_kill_qemu(QTestState *s) 239 { 240 /* Skip wait if qtest_probe_child() already reaped */ 241 if (s->qemu_pid != -1) { 242 #ifndef _WIN32 243 kill(s->qemu_pid, SIGTERM); 244 #else 245 TerminateProcess((HANDLE)s->qemu_pid, s->expected_status); 246 #endif 247 qtest_wait_qemu(s); 248 s->qemu_pid = -1; 249 return; 250 } 251 252 qtest_check_status(s); 253 } 254 255 static void kill_qemu_hook_func(void *s) 256 { 257 qtest_kill_qemu(s); 258 } 259 260 static void sigabrt_handler(int signo) 261 { 262 g_hook_list_invoke(&abrt_hooks, FALSE); 263 } 264 265 static void setup_sigabrt_handler(void) 266 { 267 sighandler_old = signal(SIGABRT, sigabrt_handler); 268 } 269 270 static void cleanup_sigabrt_handler(void) 271 { 272 signal(SIGABRT, sighandler_old); 273 } 274 275 static bool hook_list_is_empty(GHookList *hook_list) 276 { 277 GHook *hook = g_hook_first_valid(hook_list, TRUE); 278 279 if (!hook) { 280 return true; 281 } 282 283 g_hook_unref(hook_list, hook); 284 return false; 285 } 286 287 void qtest_add_abrt_handler(GHookFunc fn, const void *data) 288 { 289 GHook *hook; 290 291 if (!abrt_hooks.is_setup) { 292 g_hook_list_init(&abrt_hooks, sizeof(GHook)); 293 } 294 295 /* Only install SIGABRT handler once */ 296 if (hook_list_is_empty(&abrt_hooks)) { 297 setup_sigabrt_handler(); 298 } 299 300 hook = g_hook_alloc(&abrt_hooks); 301 hook->func = fn; 302 hook->data = (void *)data; 303 304 g_hook_prepend(&abrt_hooks, hook); 305 } 306 307 void qtest_remove_abrt_handler(void *data) 308 { 309 GHook *hook = g_hook_find_data(&abrt_hooks, TRUE, data); 310 g_hook_destroy_link(&abrt_hooks, hook); 311 312 /* Uninstall SIGABRT handler on last instance */ 313 if (hook_list_is_empty(&abrt_hooks)) { 314 cleanup_sigabrt_handler(); 315 } 316 } 317 318 static const char *qtest_qemu_binary(void) 319 { 320 const char *qemu_bin; 321 322 qemu_bin = getenv("QTEST_QEMU_BINARY"); 323 if (!qemu_bin) { 324 fprintf(stderr, "Environment variable QTEST_QEMU_BINARY required\n"); 325 exit(1); 326 } 327 328 return qemu_bin; 329 } 330 331 #ifdef _WIN32 332 static pid_t qtest_create_process(char *cmd) 333 { 334 STARTUPINFO si; 335 PROCESS_INFORMATION pi; 336 BOOL ret; 337 338 ZeroMemory(&si, sizeof(si)); 339 si.cb = sizeof(si); 340 ZeroMemory(&pi, sizeof(pi)); 341 342 ret = CreateProcess(NULL, /* module name */ 343 cmd, /* command line */ 344 NULL, /* process handle not inheritable */ 345 NULL, /* thread handle not inheritable */ 346 FALSE, /* set handle inheritance to FALSE */ 347 0, /* No creation flags */ 348 NULL, /* use parent's environment block */ 349 NULL, /* use parent's starting directory */ 350 &si, /* pointer to STARTUPINFO structure */ 351 &pi /* pointer to PROCESS_INFORMATION structure */ 352 ); 353 if (ret == 0) { 354 fprintf(stderr, "%s:%d: unable to create a new process (%s)\n", 355 __FILE__, __LINE__, strerror(GetLastError())); 356 abort(); 357 } 358 359 return (pid_t)pi.hProcess; 360 } 361 #endif /* _WIN32 */ 362 363 QTestState *qtest_init_without_qmp_handshake(const char *extra_args) 364 { 365 QTestState *s; 366 int sock, qmpsock, i; 367 gchar *socket_path; 368 gchar *qmp_socket_path; 369 gchar *command; 370 const char *qemu_binary = qtest_qemu_binary(); 371 const char *trace = g_getenv("QTEST_TRACE"); 372 g_autofree char *tracearg = trace ? 373 g_strdup_printf("-trace %s ", trace) : g_strdup(""); 374 375 s = g_new(QTestState, 1); 376 377 socket_path = g_strdup_printf("%s/qtest-%d.sock", 378 g_get_tmp_dir(), getpid()); 379 qmp_socket_path = g_strdup_printf("%s/qtest-%d.qmp", 380 g_get_tmp_dir(), getpid()); 381 382 /* It's possible that if an earlier test run crashed it might 383 * have left a stale unix socket lying around. Delete any 384 * stale old socket to avoid spurious test failures with 385 * tests/libqtest.c:70:init_socket: assertion failed (ret != -1): (-1 != -1) 386 */ 387 unlink(socket_path); 388 unlink(qmp_socket_path); 389 390 socket_init(); 391 sock = init_socket(socket_path); 392 qmpsock = init_socket(qmp_socket_path); 393 394 qtest_client_set_rx_handler(s, qtest_client_socket_recv_line); 395 qtest_client_set_tx_handler(s, qtest_client_socket_send); 396 397 qtest_add_abrt_handler(kill_qemu_hook_func, s); 398 399 command = g_strdup_printf(CMD_EXEC "%s %s" 400 "-qtest unix:%s " 401 "-qtest-log %s " 402 "-chardev socket,path=%s,id=char0 " 403 "-mon chardev=char0,mode=control " 404 "-display none " 405 "%s" 406 " -accel qtest", 407 qemu_binary, tracearg, socket_path, 408 getenv("QTEST_LOG") ? DEV_STDERR : DEV_NULL, 409 qmp_socket_path, 410 extra_args ?: ""); 411 412 g_test_message("starting QEMU: %s", command); 413 414 s->pending_events = NULL; 415 s->wstatus = 0; 416 s->expected_status = 0; 417 #ifndef _WIN32 418 s->qemu_pid = fork(); 419 if (s->qemu_pid == 0) { 420 #ifdef __linux__ 421 /* 422 * Although we register a ABRT handler to kill off QEMU 423 * when g_assert() triggers, we want an extra safety 424 * net. The QEMU process might be non-functional and 425 * thus not have responded to SIGTERM. The test script 426 * might also have crashed with SEGV, in which case the 427 * cleanup handlers won't ever run. 428 * 429 * This PR_SET_PDEATHSIG setup will ensure any remaining 430 * QEMU will get terminated with SIGKILL in these cases. 431 */ 432 prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0); 433 #endif /* __linux__ */ 434 if (!g_setenv("QEMU_AUDIO_DRV", "none", true)) { 435 exit(1); 436 } 437 execlp("/bin/sh", "sh", "-c", command, NULL); 438 exit(1); 439 } 440 #else 441 s->qemu_pid = qtest_create_process(command); 442 #endif /* _WIN32 */ 443 444 g_free(command); 445 s->fd = socket_accept(sock); 446 if (s->fd >= 0) { 447 s->qmp_fd = socket_accept(qmpsock); 448 } 449 unlink(socket_path); 450 unlink(qmp_socket_path); 451 g_free(socket_path); 452 g_free(qmp_socket_path); 453 454 g_assert(s->fd >= 0 && s->qmp_fd >= 0); 455 456 s->rx = g_string_new(""); 457 for (i = 0; i < MAX_IRQ; i++) { 458 s->irq_level[i] = false; 459 } 460 461 /* 462 * Stopping QEMU for debugging is not supported on Windows. 463 * 464 * Using DebugActiveProcess() API can suspend the QEMU process, 465 * but gdb cannot attach to the process. Using the undocumented 466 * NtSuspendProcess() can suspend the QEMU process and gdb can 467 * attach to the process, but gdb cannot resume it. 468 */ 469 #ifndef _WIN32 470 if (getenv("QTEST_STOP")) { 471 kill(s->qemu_pid, SIGSTOP); 472 } 473 #endif 474 475 /* ask endianness of the target */ 476 477 s->big_endian = qtest_query_target_endianness(s); 478 479 return s; 480 } 481 482 QTestState *qtest_init(const char *extra_args) 483 { 484 QTestState *s = qtest_init_without_qmp_handshake(extra_args); 485 QDict *greeting; 486 487 /* Read the QMP greeting and then do the handshake */ 488 greeting = qtest_qmp_receive(s); 489 qobject_unref(greeting); 490 qobject_unref(qtest_qmp(s, "{ 'execute': 'qmp_capabilities' }")); 491 492 return s; 493 } 494 495 QTestState *qtest_vinitf(const char *fmt, va_list ap) 496 { 497 char *args = g_strdup_vprintf(fmt, ap); 498 QTestState *s; 499 500 s = qtest_init(args); 501 g_free(args); 502 return s; 503 } 504 505 QTestState *qtest_initf(const char *fmt, ...) 506 { 507 va_list ap; 508 QTestState *s; 509 510 va_start(ap, fmt); 511 s = qtest_vinitf(fmt, ap); 512 va_end(ap); 513 return s; 514 } 515 516 QTestState *qtest_init_with_serial(const char *extra_args, int *sock_fd) 517 { 518 int sock_fd_init; 519 g_autofree char *sock_dir = NULL; 520 char *sock_path; 521 QTestState *qts; 522 523 sock_dir = g_dir_make_tmp("qtest-serial-XXXXXX", NULL); 524 g_assert_true(sock_dir != NULL); 525 sock_path = g_strdup_printf("%s/sock", sock_dir); 526 527 socket_init(); 528 sock_fd_init = init_socket(sock_path); 529 530 qts = qtest_initf("-chardev socket,id=s0,path=%s -serial chardev:s0 %s", 531 sock_path, extra_args); 532 533 *sock_fd = socket_accept(sock_fd_init); 534 535 unlink(sock_path); 536 g_free(sock_path); 537 rmdir(sock_dir); 538 539 g_assert_true(*sock_fd >= 0); 540 541 return qts; 542 } 543 544 void qtest_quit(QTestState *s) 545 { 546 qtest_remove_abrt_handler(s); 547 548 qtest_kill_qemu(s); 549 closesocket(s->fd); 550 closesocket(s->qmp_fd); 551 g_string_free(s->rx, true); 552 553 for (GList *it = s->pending_events; it != NULL; it = it->next) { 554 qobject_unref((QDict *)it->data); 555 } 556 557 g_list_free(s->pending_events); 558 559 g_free(s); 560 } 561 562 static void socket_send(int fd, const char *buf, size_t size) 563 { 564 ssize_t res = qemu_send_full(fd, buf, size); 565 566 assert(res == size); 567 } 568 569 static void qtest_client_socket_send(QTestState *s, const char *buf) 570 { 571 socket_send(s->fd, buf, strlen(buf)); 572 } 573 574 static void G_GNUC_PRINTF(2, 3) qtest_sendf(QTestState *s, const char *fmt, ...) 575 { 576 va_list ap; 577 578 va_start(ap, fmt); 579 gchar *str = g_strdup_vprintf(fmt, ap); 580 va_end(ap); 581 582 s->ops.send(s, str); 583 g_free(str); 584 } 585 586 static GString *qtest_client_socket_recv_line(QTestState *s) 587 { 588 GString *line; 589 size_t offset; 590 char *eol; 591 592 while ((eol = strchr(s->rx->str, '\n')) == NULL) { 593 ssize_t len; 594 char buffer[1024]; 595 596 len = recv(s->fd, buffer, sizeof(buffer), 0); 597 if (len == -1 && errno == EINTR) { 598 continue; 599 } 600 601 if (len == -1 || len == 0) { 602 fprintf(stderr, "Broken pipe\n"); 603 abort(); 604 } 605 606 g_string_append_len(s->rx, buffer, len); 607 } 608 609 offset = eol - s->rx->str; 610 line = g_string_new_len(s->rx->str, offset); 611 g_string_erase(s->rx, 0, offset + 1); 612 613 return line; 614 } 615 616 static gchar **qtest_rsp_args(QTestState *s, int expected_args) 617 { 618 GString *line; 619 gchar **words; 620 int i; 621 622 redo: 623 line = s->ops.recv_line(s); 624 words = g_strsplit(line->str, " ", 0); 625 g_string_free(line, TRUE); 626 627 if (strcmp(words[0], "IRQ") == 0) { 628 long irq; 629 int ret; 630 631 g_assert(words[1] != NULL); 632 g_assert(words[2] != NULL); 633 634 ret = qemu_strtol(words[2], NULL, 0, &irq); 635 g_assert(!ret); 636 g_assert_cmpint(irq, >=, 0); 637 g_assert_cmpint(irq, <, MAX_IRQ); 638 639 if (strcmp(words[1], "raise") == 0) { 640 s->irq_level[irq] = true; 641 } else { 642 s->irq_level[irq] = false; 643 } 644 645 g_strfreev(words); 646 goto redo; 647 } 648 649 g_assert(words[0] != NULL); 650 g_assert_cmpstr(words[0], ==, "OK"); 651 652 for (i = 0; i < expected_args; i++) { 653 g_assert(words[i] != NULL); 654 } 655 656 return words; 657 } 658 659 static void qtest_rsp(QTestState *s) 660 { 661 gchar **words = qtest_rsp_args(s, 0); 662 663 g_strfreev(words); 664 } 665 666 static int qtest_query_target_endianness(QTestState *s) 667 { 668 gchar **args; 669 int big_endian; 670 671 qtest_sendf(s, "endianness\n"); 672 args = qtest_rsp_args(s, 1); 673 g_assert(strcmp(args[1], "big") == 0 || strcmp(args[1], "little") == 0); 674 big_endian = strcmp(args[1], "big") == 0; 675 g_strfreev(args); 676 677 return big_endian; 678 } 679 680 QDict *qtest_qmp_receive(QTestState *s) 681 { 682 while (true) { 683 QDict *response = qtest_qmp_receive_dict(s); 684 685 if (!qdict_get_try_str(response, "event")) { 686 return response; 687 } 688 /* Stash the event for a later consumption */ 689 s->pending_events = g_list_append(s->pending_events, response); 690 } 691 } 692 693 QDict *qtest_qmp_receive_dict(QTestState *s) 694 { 695 return qmp_fd_receive(s->qmp_fd); 696 } 697 698 int qtest_socket_server(const char *socket_path) 699 { 700 struct sockaddr_un addr; 701 int sock; 702 int ret; 703 704 sock = socket(PF_UNIX, SOCK_STREAM, 0); 705 g_assert_cmpint(sock, !=, -1); 706 707 addr.sun_family = AF_UNIX; 708 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socket_path); 709 710 ret = RETRY_ON_EINTR(bind(sock, (struct sockaddr *)&addr, sizeof(addr))); 711 g_assert_cmpint(ret, !=, -1); 712 ret = listen(sock, 1); 713 g_assert_cmpint(ret, !=, -1); 714 715 return sock; 716 } 717 718 #ifndef _WIN32 719 void qtest_qmp_vsend_fds(QTestState *s, int *fds, size_t fds_num, 720 const char *fmt, va_list ap) 721 { 722 qmp_fd_vsend_fds(s->qmp_fd, fds, fds_num, fmt, ap); 723 } 724 #endif 725 726 void qtest_qmp_vsend(QTestState *s, const char *fmt, va_list ap) 727 { 728 qmp_fd_vsend(s->qmp_fd, fmt, ap); 729 } 730 731 #ifndef _WIN32 732 QDict *qtest_vqmp_fds(QTestState *s, int *fds, size_t fds_num, 733 const char *fmt, va_list ap) 734 { 735 qtest_qmp_vsend_fds(s, fds, fds_num, fmt, ap); 736 737 /* Receive reply */ 738 return qtest_qmp_receive(s); 739 } 740 #endif 741 742 QDict *qtest_vqmp(QTestState *s, const char *fmt, va_list ap) 743 { 744 qtest_qmp_vsend(s, fmt, ap); 745 746 /* Receive reply */ 747 return qtest_qmp_receive(s); 748 } 749 750 #ifndef _WIN32 751 QDict *qtest_qmp_fds(QTestState *s, int *fds, size_t fds_num, 752 const char *fmt, ...) 753 { 754 va_list ap; 755 QDict *response; 756 757 va_start(ap, fmt); 758 response = qtest_vqmp_fds(s, fds, fds_num, fmt, ap); 759 va_end(ap); 760 return response; 761 } 762 #endif 763 764 QDict *qtest_qmp(QTestState *s, const char *fmt, ...) 765 { 766 va_list ap; 767 QDict *response; 768 769 va_start(ap, fmt); 770 response = qtest_vqmp(s, fmt, ap); 771 va_end(ap); 772 return response; 773 } 774 775 void qtest_qmp_send(QTestState *s, const char *fmt, ...) 776 { 777 va_list ap; 778 779 va_start(ap, fmt); 780 qtest_qmp_vsend(s, fmt, ap); 781 va_end(ap); 782 } 783 784 void qtest_qmp_send_raw(QTestState *s, const char *fmt, ...) 785 { 786 va_list ap; 787 788 va_start(ap, fmt); 789 qmp_fd_vsend_raw(s->qmp_fd, fmt, ap); 790 va_end(ap); 791 } 792 793 QDict *qtest_qmp_event_ref(QTestState *s, const char *event) 794 { 795 while (s->pending_events) { 796 797 GList *first = s->pending_events; 798 QDict *response = (QDict *)first->data; 799 800 s->pending_events = g_list_delete_link(s->pending_events, first); 801 802 if (!strcmp(qdict_get_str(response, "event"), event)) { 803 return response; 804 } 805 qobject_unref(response); 806 } 807 return NULL; 808 } 809 810 QDict *qtest_qmp_eventwait_ref(QTestState *s, const char *event) 811 { 812 QDict *response = qtest_qmp_event_ref(s, event); 813 814 if (response) { 815 return response; 816 } 817 818 for (;;) { 819 response = qtest_qmp_receive_dict(s); 820 if ((qdict_haskey(response, "event")) && 821 (strcmp(qdict_get_str(response, "event"), event) == 0)) { 822 return response; 823 } 824 qobject_unref(response); 825 } 826 } 827 828 void qtest_qmp_eventwait(QTestState *s, const char *event) 829 { 830 QDict *response; 831 832 response = qtest_qmp_eventwait_ref(s, event); 833 qobject_unref(response); 834 } 835 836 char *qtest_vhmp(QTestState *s, const char *fmt, va_list ap) 837 { 838 char *cmd; 839 QDict *resp; 840 char *ret; 841 842 cmd = g_strdup_vprintf(fmt, ap); 843 resp = qtest_qmp(s, "{'execute': 'human-monitor-command'," 844 " 'arguments': {'command-line': %s}}", 845 cmd); 846 ret = g_strdup(qdict_get_try_str(resp, "return")); 847 g_assert(ret); 848 qobject_unref(resp); 849 g_free(cmd); 850 return ret; 851 } 852 853 char *qtest_hmp(QTestState *s, const char *fmt, ...) 854 { 855 va_list ap; 856 char *ret; 857 858 va_start(ap, fmt); 859 ret = qtest_vhmp(s, fmt, ap); 860 va_end(ap); 861 return ret; 862 } 863 864 const char *qtest_get_arch(void) 865 { 866 const char *qemu = qtest_qemu_binary(); 867 const char *end = strrchr(qemu, '-'); 868 869 if (!end) { 870 fprintf(stderr, "Can't determine architecture from binary name.\n"); 871 exit(1); 872 } 873 874 if (!strstr(qemu, "-system-")) { 875 fprintf(stderr, "QTEST_QEMU_BINARY must end with *-system-<arch> " 876 "where 'arch' is the target\narchitecture (x86_64, aarch64, " 877 "etc).\n"); 878 exit(1); 879 } 880 881 return end + 1; 882 } 883 884 bool qtest_has_accel(const char *accel_name) 885 { 886 if (g_str_equal(accel_name, "tcg")) { 887 #if defined(CONFIG_TCG) 888 return true; 889 #else 890 return false; 891 #endif 892 } else if (g_str_equal(accel_name, "kvm")) { 893 int i; 894 const char *arch = qtest_get_arch(); 895 const char *targets[] = { CONFIG_KVM_TARGETS }; 896 897 for (i = 0; i < ARRAY_SIZE(targets); i++) { 898 if (!strncmp(targets[i], arch, strlen(arch))) { 899 if (!access("/dev/kvm", R_OK | W_OK)) { 900 return true; 901 } 902 } 903 } 904 } else { 905 /* not implemented */ 906 g_assert_not_reached(); 907 } 908 return false; 909 } 910 911 bool qtest_get_irq(QTestState *s, int num) 912 { 913 /* dummy operation in order to make sure irq is up to date */ 914 qtest_inb(s, 0); 915 916 return s->irq_level[num]; 917 } 918 919 void qtest_module_load(QTestState *s, const char *prefix, const char *libname) 920 { 921 qtest_sendf(s, "module_load %s %s\n", prefix, libname); 922 qtest_rsp(s); 923 } 924 925 static int64_t qtest_clock_rsp(QTestState *s) 926 { 927 gchar **words; 928 int64_t clock; 929 words = qtest_rsp_args(s, 2); 930 clock = g_ascii_strtoll(words[1], NULL, 0); 931 g_strfreev(words); 932 return clock; 933 } 934 935 int64_t qtest_clock_step_next(QTestState *s) 936 { 937 qtest_sendf(s, "clock_step\n"); 938 return qtest_clock_rsp(s); 939 } 940 941 int64_t qtest_clock_step(QTestState *s, int64_t step) 942 { 943 qtest_sendf(s, "clock_step %"PRIi64"\n", step); 944 return qtest_clock_rsp(s); 945 } 946 947 int64_t qtest_clock_set(QTestState *s, int64_t val) 948 { 949 qtest_sendf(s, "clock_set %"PRIi64"\n", val); 950 return qtest_clock_rsp(s); 951 } 952 953 void qtest_irq_intercept_out(QTestState *s, const char *qom_path) 954 { 955 qtest_sendf(s, "irq_intercept_out %s\n", qom_path); 956 qtest_rsp(s); 957 } 958 959 void qtest_irq_intercept_in(QTestState *s, const char *qom_path) 960 { 961 qtest_sendf(s, "irq_intercept_in %s\n", qom_path); 962 qtest_rsp(s); 963 } 964 965 void qtest_set_irq_in(QTestState *s, const char *qom_path, const char *name, 966 int num, int level) 967 { 968 if (!name) { 969 name = "unnamed-gpio-in"; 970 } 971 qtest_sendf(s, "set_irq_in %s %s %d %d\n", qom_path, name, num, level); 972 qtest_rsp(s); 973 } 974 975 static void qtest_out(QTestState *s, const char *cmd, uint16_t addr, uint32_t value) 976 { 977 qtest_sendf(s, "%s 0x%x 0x%x\n", cmd, addr, value); 978 qtest_rsp(s); 979 } 980 981 void qtest_outb(QTestState *s, uint16_t addr, uint8_t value) 982 { 983 qtest_out(s, "outb", addr, value); 984 } 985 986 void qtest_outw(QTestState *s, uint16_t addr, uint16_t value) 987 { 988 qtest_out(s, "outw", addr, value); 989 } 990 991 void qtest_outl(QTestState *s, uint16_t addr, uint32_t value) 992 { 993 qtest_out(s, "outl", addr, value); 994 } 995 996 static uint32_t qtest_in(QTestState *s, const char *cmd, uint16_t addr) 997 { 998 gchar **args; 999 int ret; 1000 unsigned long value; 1001 1002 qtest_sendf(s, "%s 0x%x\n", cmd, addr); 1003 args = qtest_rsp_args(s, 2); 1004 ret = qemu_strtoul(args[1], NULL, 0, &value); 1005 g_assert(!ret && value <= UINT32_MAX); 1006 g_strfreev(args); 1007 1008 return value; 1009 } 1010 1011 uint8_t qtest_inb(QTestState *s, uint16_t addr) 1012 { 1013 return qtest_in(s, "inb", addr); 1014 } 1015 1016 uint16_t qtest_inw(QTestState *s, uint16_t addr) 1017 { 1018 return qtest_in(s, "inw", addr); 1019 } 1020 1021 uint32_t qtest_inl(QTestState *s, uint16_t addr) 1022 { 1023 return qtest_in(s, "inl", addr); 1024 } 1025 1026 static void qtest_write(QTestState *s, const char *cmd, uint64_t addr, 1027 uint64_t value) 1028 { 1029 qtest_sendf(s, "%s 0x%" PRIx64 " 0x%" PRIx64 "\n", cmd, addr, value); 1030 qtest_rsp(s); 1031 } 1032 1033 void qtest_writeb(QTestState *s, uint64_t addr, uint8_t value) 1034 { 1035 qtest_write(s, "writeb", addr, value); 1036 } 1037 1038 void qtest_writew(QTestState *s, uint64_t addr, uint16_t value) 1039 { 1040 qtest_write(s, "writew", addr, value); 1041 } 1042 1043 void qtest_writel(QTestState *s, uint64_t addr, uint32_t value) 1044 { 1045 qtest_write(s, "writel", addr, value); 1046 } 1047 1048 void qtest_writeq(QTestState *s, uint64_t addr, uint64_t value) 1049 { 1050 qtest_write(s, "writeq", addr, value); 1051 } 1052 1053 static uint64_t qtest_read(QTestState *s, const char *cmd, uint64_t addr) 1054 { 1055 gchar **args; 1056 int ret; 1057 uint64_t value; 1058 1059 qtest_sendf(s, "%s 0x%" PRIx64 "\n", cmd, addr); 1060 args = qtest_rsp_args(s, 2); 1061 ret = qemu_strtou64(args[1], NULL, 0, &value); 1062 g_assert(!ret); 1063 g_strfreev(args); 1064 1065 return value; 1066 } 1067 1068 uint8_t qtest_readb(QTestState *s, uint64_t addr) 1069 { 1070 return qtest_read(s, "readb", addr); 1071 } 1072 1073 uint16_t qtest_readw(QTestState *s, uint64_t addr) 1074 { 1075 return qtest_read(s, "readw", addr); 1076 } 1077 1078 uint32_t qtest_readl(QTestState *s, uint64_t addr) 1079 { 1080 return qtest_read(s, "readl", addr); 1081 } 1082 1083 uint64_t qtest_readq(QTestState *s, uint64_t addr) 1084 { 1085 return qtest_read(s, "readq", addr); 1086 } 1087 1088 static int hex2nib(char ch) 1089 { 1090 if (ch >= '0' && ch <= '9') { 1091 return ch - '0'; 1092 } else if (ch >= 'a' && ch <= 'f') { 1093 return 10 + (ch - 'a'); 1094 } else if (ch >= 'A' && ch <= 'F') { 1095 return 10 + (ch - 'a'); 1096 } else { 1097 return -1; 1098 } 1099 } 1100 1101 void qtest_memread(QTestState *s, uint64_t addr, void *data, size_t size) 1102 { 1103 uint8_t *ptr = data; 1104 gchar **args; 1105 size_t i; 1106 1107 if (!size) { 1108 return; 1109 } 1110 1111 qtest_sendf(s, "read 0x%" PRIx64 " 0x%zx\n", addr, size); 1112 args = qtest_rsp_args(s, 2); 1113 1114 for (i = 0; i < size; i++) { 1115 ptr[i] = hex2nib(args[1][2 + (i * 2)]) << 4; 1116 ptr[i] |= hex2nib(args[1][2 + (i * 2) + 1]); 1117 } 1118 1119 g_strfreev(args); 1120 } 1121 1122 uint64_t qtest_rtas_call(QTestState *s, const char *name, 1123 uint32_t nargs, uint64_t args, 1124 uint32_t nret, uint64_t ret) 1125 { 1126 qtest_sendf(s, "rtas %s %u 0x%"PRIx64" %u 0x%"PRIx64"\n", 1127 name, nargs, args, nret, ret); 1128 qtest_rsp(s); 1129 return 0; 1130 } 1131 1132 void qtest_add_func(const char *str, void (*fn)(void)) 1133 { 1134 gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); 1135 g_test_add_func(path, fn); 1136 g_free(path); 1137 } 1138 1139 void qtest_add_data_func_full(const char *str, void *data, 1140 void (*fn)(const void *), 1141 GDestroyNotify data_free_func) 1142 { 1143 gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); 1144 g_test_add_data_func_full(path, data, fn, data_free_func); 1145 g_free(path); 1146 } 1147 1148 void qtest_add_data_func(const char *str, const void *data, 1149 void (*fn)(const void *)) 1150 { 1151 gchar *path = g_strdup_printf("/%s/%s", qtest_get_arch(), str); 1152 g_test_add_data_func(path, data, fn); 1153 g_free(path); 1154 } 1155 1156 void qtest_bufwrite(QTestState *s, uint64_t addr, const void *data, size_t size) 1157 { 1158 gchar *bdata; 1159 1160 bdata = g_base64_encode(data, size); 1161 qtest_sendf(s, "b64write 0x%" PRIx64 " 0x%zx ", addr, size); 1162 s->ops.send(s, bdata); 1163 s->ops.send(s, "\n"); 1164 qtest_rsp(s); 1165 g_free(bdata); 1166 } 1167 1168 void qtest_bufread(QTestState *s, uint64_t addr, void *data, size_t size) 1169 { 1170 gchar **args; 1171 size_t len; 1172 1173 qtest_sendf(s, "b64read 0x%" PRIx64 " 0x%zx\n", addr, size); 1174 args = qtest_rsp_args(s, 2); 1175 1176 g_base64_decode_inplace(args[1], &len); 1177 if (size != len) { 1178 fprintf(stderr, "bufread: asked for %zu bytes but decoded %zu\n", 1179 size, len); 1180 len = MIN(len, size); 1181 } 1182 1183 memcpy(data, args[1], len); 1184 g_strfreev(args); 1185 } 1186 1187 void qtest_memwrite(QTestState *s, uint64_t addr, const void *data, size_t size) 1188 { 1189 const uint8_t *ptr = data; 1190 size_t i; 1191 char *enc; 1192 1193 if (!size) { 1194 return; 1195 } 1196 1197 enc = g_malloc(2 * size + 1); 1198 1199 for (i = 0; i < size; i++) { 1200 sprintf(&enc[i * 2], "%02x", ptr[i]); 1201 } 1202 1203 qtest_sendf(s, "write 0x%" PRIx64 " 0x%zx 0x%s\n", addr, size, enc); 1204 qtest_rsp(s); 1205 g_free(enc); 1206 } 1207 1208 void qtest_memset(QTestState *s, uint64_t addr, uint8_t pattern, size_t size) 1209 { 1210 qtest_sendf(s, "memset 0x%" PRIx64 " 0x%zx 0x%02x\n", addr, size, pattern); 1211 qtest_rsp(s); 1212 } 1213 1214 void qtest_qmp_assert_success(QTestState *qts, const char *fmt, ...) 1215 { 1216 va_list ap; 1217 QDict *response; 1218 1219 va_start(ap, fmt); 1220 response = qtest_vqmp(qts, fmt, ap); 1221 va_end(ap); 1222 1223 g_assert(response); 1224 if (!qdict_haskey(response, "return")) { 1225 GString *s = qobject_to_json_pretty(QOBJECT(response), true); 1226 g_test_message("%s", s->str); 1227 g_string_free(s, true); 1228 } 1229 g_assert(qdict_haskey(response, "return")); 1230 qobject_unref(response); 1231 } 1232 1233 bool qtest_big_endian(QTestState *s) 1234 { 1235 return s->big_endian; 1236 } 1237 1238 static bool qtest_check_machine_version(const char *mname, const char *basename, 1239 int major, int minor) 1240 { 1241 char *newname; 1242 bool is_equal; 1243 1244 newname = g_strdup_printf("%s-%i.%i", basename, major, minor); 1245 is_equal = g_str_equal(mname, newname); 1246 g_free(newname); 1247 1248 return is_equal; 1249 } 1250 1251 static bool qtest_is_old_versioned_machine(const char *mname) 1252 { 1253 const char *dash = strrchr(mname, '-'); 1254 const char *dot = strrchr(mname, '.'); 1255 const char *chr; 1256 char *bname; 1257 const int major = QEMU_VERSION_MAJOR; 1258 const int minor = QEMU_VERSION_MINOR; 1259 bool res = false; 1260 1261 if (dash && dot && dot > dash) { 1262 for (chr = dash + 1; *chr; chr++) { 1263 if (!qemu_isdigit(*chr) && *chr != '.') { 1264 return false; 1265 } 1266 } 1267 /* 1268 * Now check if it is one of the latest versions. Check major + 1 1269 * and minor + 1 versions as well, since they might already exist 1270 * in the development branch. 1271 */ 1272 bname = g_strdup(mname); 1273 bname[dash - mname] = 0; 1274 res = !qtest_check_machine_version(mname, bname, major + 1, 0) && 1275 !qtest_check_machine_version(mname, bname, major, minor + 1) && 1276 !qtest_check_machine_version(mname, bname, major, minor); 1277 g_free(bname); 1278 } 1279 1280 return res; 1281 } 1282 1283 struct MachInfo { 1284 char *name; 1285 char *alias; 1286 }; 1287 1288 /* 1289 * Returns an array with pointers to the available machine names. 1290 * The terminating entry has the name set to NULL. 1291 */ 1292 static struct MachInfo *qtest_get_machines(void) 1293 { 1294 static struct MachInfo *machines; 1295 QDict *response, *minfo; 1296 QList *list; 1297 const QListEntry *p; 1298 QObject *qobj; 1299 QString *qstr; 1300 QTestState *qts; 1301 int idx; 1302 1303 if (machines) { 1304 return machines; 1305 } 1306 1307 qts = qtest_init("-machine none"); 1308 response = qtest_qmp(qts, "{ 'execute': 'query-machines' }"); 1309 g_assert(response); 1310 list = qdict_get_qlist(response, "return"); 1311 g_assert(list); 1312 1313 machines = g_new(struct MachInfo, qlist_size(list) + 1); 1314 1315 for (p = qlist_first(list), idx = 0; p; p = qlist_next(p), idx++) { 1316 minfo = qobject_to(QDict, qlist_entry_obj(p)); 1317 g_assert(minfo); 1318 1319 qobj = qdict_get(minfo, "name"); 1320 g_assert(qobj); 1321 qstr = qobject_to(QString, qobj); 1322 g_assert(qstr); 1323 machines[idx].name = g_strdup(qstring_get_str(qstr)); 1324 1325 qobj = qdict_get(minfo, "alias"); 1326 if (qobj) { /* The alias is optional */ 1327 qstr = qobject_to(QString, qobj); 1328 g_assert(qstr); 1329 machines[idx].alias = g_strdup(qstring_get_str(qstr)); 1330 } else { 1331 machines[idx].alias = NULL; 1332 } 1333 } 1334 1335 qtest_quit(qts); 1336 qobject_unref(response); 1337 1338 memset(&machines[idx], 0, sizeof(struct MachInfo)); /* Terminating entry */ 1339 return machines; 1340 } 1341 1342 void qtest_cb_for_every_machine(void (*cb)(const char *machine), 1343 bool skip_old_versioned) 1344 { 1345 struct MachInfo *machines; 1346 int i; 1347 1348 machines = qtest_get_machines(); 1349 1350 for (i = 0; machines[i].name != NULL; i++) { 1351 /* Ignore machines that cannot be used for qtests */ 1352 if (!strncmp("xenfv", machines[i].name, 5) || 1353 g_str_equal("xenpv", machines[i].name)) { 1354 continue; 1355 } 1356 if (!skip_old_versioned || 1357 !qtest_is_old_versioned_machine(machines[i].name)) { 1358 cb(machines[i].name); 1359 } 1360 } 1361 } 1362 1363 bool qtest_has_machine(const char *machine) 1364 { 1365 struct MachInfo *machines; 1366 int i; 1367 1368 machines = qtest_get_machines(); 1369 1370 for (i = 0; machines[i].name != NULL; i++) { 1371 if (g_str_equal(machine, machines[i].name) || 1372 (machines[i].alias && g_str_equal(machine, machines[i].alias))) { 1373 return true; 1374 } 1375 } 1376 1377 return false; 1378 } 1379 1380 bool qtest_has_device(const char *device) 1381 { 1382 static QList *list; 1383 const QListEntry *p; 1384 QObject *qobj; 1385 QString *qstr; 1386 QDict *devinfo; 1387 int idx; 1388 1389 if (!list) { 1390 QDict *resp; 1391 QDict *args; 1392 QTestState *qts = qtest_init("-machine none"); 1393 1394 args = qdict_new(); 1395 qdict_put_bool(args, "abstract", false); 1396 qdict_put_str(args, "implements", "device"); 1397 1398 resp = qtest_qmp(qts, "{'execute': 'qom-list-types', 'arguments': %p }", 1399 args); 1400 g_assert(qdict_haskey(resp, "return")); 1401 list = qdict_get_qlist(resp, "return"); 1402 qobject_ref(list); 1403 qobject_unref(resp); 1404 1405 qtest_quit(qts); 1406 } 1407 1408 for (p = qlist_first(list), idx = 0; p; p = qlist_next(p), idx++) { 1409 devinfo = qobject_to(QDict, qlist_entry_obj(p)); 1410 g_assert(devinfo); 1411 1412 qobj = qdict_get(devinfo, "name"); 1413 g_assert(qobj); 1414 qstr = qobject_to(QString, qobj); 1415 g_assert(qstr); 1416 if (g_str_equal(qstring_get_str(qstr), device)) { 1417 return true; 1418 } 1419 } 1420 1421 return false; 1422 } 1423 1424 /* 1425 * Generic hot-plugging test via the device_add QMP commands. 1426 */ 1427 void qtest_qmp_device_add_qdict(QTestState *qts, const char *drv, 1428 const QDict *arguments) 1429 { 1430 QDict *resp; 1431 QDict *args = arguments ? qdict_clone_shallow(arguments) : qdict_new(); 1432 1433 g_assert(!qdict_haskey(args, "driver")); 1434 qdict_put_str(args, "driver", drv); 1435 resp = qtest_qmp(qts, "{'execute': 'device_add', 'arguments': %p}", args); 1436 g_assert(resp); 1437 g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events */ 1438 g_assert(!qdict_haskey(resp, "error")); 1439 qobject_unref(resp); 1440 } 1441 1442 void qtest_qmp_device_add(QTestState *qts, const char *driver, const char *id, 1443 const char *fmt, ...) 1444 { 1445 QDict *args; 1446 va_list ap; 1447 1448 va_start(ap, fmt); 1449 args = qdict_from_vjsonf_nofail(fmt, ap); 1450 va_end(ap); 1451 1452 g_assert(!qdict_haskey(args, "id")); 1453 qdict_put_str(args, "id", id); 1454 1455 qtest_qmp_device_add_qdict(qts, driver, args); 1456 qobject_unref(args); 1457 } 1458 1459 #ifndef _WIN32 1460 void qtest_qmp_add_client(QTestState *qts, const char *protocol, int fd) 1461 { 1462 QDict *resp; 1463 1464 resp = qtest_qmp_fds(qts, &fd, 1, "{'execute': 'getfd'," 1465 "'arguments': {'fdname': 'fdname'}}"); 1466 g_assert(resp); 1467 g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events */ 1468 g_assert(!qdict_haskey(resp, "error")); 1469 qobject_unref(resp); 1470 1471 resp = qtest_qmp( 1472 qts, "{'execute': 'add_client'," 1473 "'arguments': {'protocol': %s, 'fdname': 'fdname'}}", protocol); 1474 g_assert(resp); 1475 g_assert(!qdict_haskey(resp, "event")); /* We don't expect any events */ 1476 g_assert(!qdict_haskey(resp, "error")); 1477 qobject_unref(resp); 1478 } 1479 #endif 1480 1481 /* 1482 * Generic hot-unplugging test via the device_del QMP command. 1483 * Device deletion will get one response and one event. For example: 1484 * 1485 * {'execute': 'device_del','arguments': { 'id': 'scsi-hd'}} 1486 * 1487 * will get this one: 1488 * 1489 * {"timestamp": {"seconds": 1505289667, "microseconds": 569862}, 1490 * "event": "DEVICE_DELETED", "data": {"device": "scsi-hd", 1491 * "path": "/machine/peripheral/scsi-hd"}} 1492 * 1493 * and this one: 1494 * 1495 * {"return": {}} 1496 */ 1497 void qtest_qmp_device_del_send(QTestState *qts, const char *id) 1498 { 1499 QDict *rsp = qtest_qmp(qts, "{'execute': 'device_del', " 1500 "'arguments': {'id': %s}}", id); 1501 g_assert(rsp); 1502 g_assert(qdict_haskey(rsp, "return")); 1503 g_assert(!qdict_haskey(rsp, "error")); 1504 qobject_unref(rsp); 1505 } 1506 1507 void qtest_qmp_device_del(QTestState *qts, const char *id) 1508 { 1509 qtest_qmp_device_del_send(qts, id); 1510 qtest_qmp_eventwait(qts, "DEVICE_DELETED"); 1511 } 1512 1513 static void qtest_client_set_tx_handler(QTestState *s, 1514 QTestSendFn send) 1515 { 1516 s->ops.send = send; 1517 } 1518 static void qtest_client_set_rx_handler(QTestState *s, QTestRecvFn recv) 1519 { 1520 s->ops.recv_line = recv; 1521 } 1522 /* A type-safe wrapper for s->send() */ 1523 static void send_wrapper(QTestState *s, const char *buf) 1524 { 1525 s->ops.external_send(s, buf); 1526 } 1527 1528 static GString *qtest_client_inproc_recv_line(QTestState *s) 1529 { 1530 GString *line; 1531 size_t offset; 1532 char *eol; 1533 1534 eol = strchr(s->rx->str, '\n'); 1535 offset = eol - s->rx->str; 1536 line = g_string_new_len(s->rx->str, offset); 1537 g_string_erase(s->rx, 0, offset + 1); 1538 return line; 1539 } 1540 1541 QTestState *qtest_inproc_init(QTestState **s, bool log, const char* arch, 1542 void (*send)(void*, const char*)) 1543 { 1544 QTestState *qts; 1545 qts = g_new0(QTestState, 1); 1546 qts->pending_events = NULL; 1547 *s = qts; /* Expose qts early on, since the query endianness relies on it */ 1548 qts->wstatus = 0; 1549 for (int i = 0; i < MAX_IRQ; i++) { 1550 qts->irq_level[i] = false; 1551 } 1552 1553 qtest_client_set_rx_handler(qts, qtest_client_inproc_recv_line); 1554 1555 /* send() may not have a matching protoype, so use a type-safe wrapper */ 1556 qts->ops.external_send = send; 1557 qtest_client_set_tx_handler(qts, send_wrapper); 1558 1559 qts->big_endian = qtest_query_target_endianness(qts); 1560 1561 /* 1562 * Set a dummy path for QTEST_QEMU_BINARY. Doesn't need to exist, but this 1563 * way, qtest_get_arch works for inproc qtest. 1564 */ 1565 gchar *bin_path = g_strconcat("/qemu-system-", arch, NULL); 1566 g_setenv("QTEST_QEMU_BINARY", bin_path, 0); 1567 g_free(bin_path); 1568 1569 return qts; 1570 } 1571 1572 void qtest_client_inproc_recv(void *opaque, const char *str) 1573 { 1574 QTestState *qts = *(QTestState **)opaque; 1575 1576 if (!qts->rx) { 1577 qts->rx = g_string_new(NULL); 1578 } 1579 g_string_append(qts->rx, str); 1580 return; 1581 } 1582 1583 void qtest_qom_set_bool(QTestState *s, const char *path, const char *property, 1584 bool value) 1585 { 1586 QDict *r; 1587 1588 r = qtest_qmp(s, "{ 'execute': 'qom-set', 'arguments': " 1589 "{ 'path': %s, 'property': %s, 'value': %i } }", 1590 path, property, value); 1591 qobject_unref(r); 1592 } 1593 1594 bool qtest_qom_get_bool(QTestState *s, const char *path, const char *property) 1595 { 1596 QDict *r; 1597 bool b; 1598 1599 r = qtest_qmp(s, "{ 'execute': 'qom-get', 'arguments': " 1600 "{ 'path': %s, 'property': %s } }", path, property); 1601 b = qdict_get_bool(r, "return"); 1602 qobject_unref(r); 1603 1604 return b; 1605 } 1606