From nobody Fri Nov 7 08:01:22 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail(p=none dis=none) header.from=redhat.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1547576495821184.21018006725797; Tue, 15 Jan 2019 10:21:35 -0800 (PST) Received: from localhost ([127.0.0.1]:41158 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjTLC-0006Yy-8b for importer@patchew.org; Tue, 15 Jan 2019 13:21:34 -0500 Received: from eggs.gnu.org ([209.51.188.92]:53137) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1gjTIx-0005E5-4H for qemu-devel@nongnu.org; Tue, 15 Jan 2019 13:19:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1gjTIv-0005BY-C0 for qemu-devel@nongnu.org; Tue, 15 Jan 2019 13:19:15 -0500 Received: from mail-wm1-x335.google.com ([2a00:1450:4864:20::335]:35139) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1gjTIv-0005AF-0g for qemu-devel@nongnu.org; Tue, 15 Jan 2019 13:19:13 -0500 Received: by mail-wm1-x335.google.com with SMTP id t200so4295218wmt.0 for ; Tue, 15 Jan 2019 10:19:12 -0800 (PST) Received: from 640k.lan ([93.56.166.5]) by smtp.gmail.com with ESMTPSA id 127sm52446227wmm.45.2019.01.15.10.19.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 15 Jan 2019 10:19:10 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id; bh=2h1Sj2sidwORLcpWrqVcJL+4/YOspJq/NnGS+VYaylU=; b=o4vJXOfeaYkmAmsIba1D4WlzgF0Bf8jPfkEH7zSOIaeBzWO4NxmP3vjFhb1E/WvsoE R+mPXvRe3OKQdTWALJ8goBV4Db5qtzOd4WGbwoCBNLA5MSzGrPuo6bp0lsFOTIzBgOS0 b1gPnJPnFxcdgBZJF63CXCPEWIm/FnA5upwfr2VuYfWslR7xRxlYcGzr+LPLnGrqRqL6 m+lX5LdHYUP78NNhqp6GGJhHKf8+4/YGWB6oR4DKQXCsUEcz6S85uggj9anhZxyP0/n3 TO12omjSOZ/VKcMCqwp5MaNcz/+uZO4NOo50UlnoFprwQU8y/LcDh08aq0uYkaIyA0vx DOcQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id; bh=2h1Sj2sidwORLcpWrqVcJL+4/YOspJq/NnGS+VYaylU=; b=grIERTmdrVJf2J3HHb8gUCVEnX0XZe1IU1WQeUzt/EMqzVuLNHJURzyifefpjZQR85 25KAbMRZAwAK4Zg1j6KFJvYbc/ZaKDAvz+NzxLtAuHzfP0ad+xaPfNlkADkPAFvj6+XW 0YAk5eoiP9XMuLE7ZwriLBj8rojviWNpUiz1VPfJ4qxmUo0FvOb4zeNUZeymoiw5/CzG WZRXo93x5QXAqhLZ+Sqr6u2/eyRDZLjf0dEOBoD8g5YQ6Xj1iUKF0P5WeIRFYUlkR7o4 qsUkqkwyRt8a85BQvdhT/1A6CLyLUiA5LiJPzEE9++3dveB1wknyyebYbH1SEEFUykkb smMA== X-Gm-Message-State: AJcUukeDAZxjoZqA4oOnxk97KDS19lW49PCwnoksHy6rm6DyKPGHkgP2 yYvZATX9garfitRZoHuETNclr0q3 X-Google-Smtp-Source: ALg8bN54O/w6DCjXHY/C+UqRPNFfNRtf0oPKYd27fG0aeMuu+UlT4jKoM9xI5OKwbcIvNSsLq1htUQ== X-Received: by 2002:a1c:b687:: with SMTP id g129mr4328925wmf.59.1547576351170; Tue, 15 Jan 2019 10:19:11 -0800 (PST) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Tue, 15 Jan 2019 19:19:04 +0100 Message-Id: <1547576349-13337-1-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.8.3.1 X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 2a00:1450:4864:20::335 Subject: [Qemu-devel] [PATCH 0/5] qtest driver framework (core only) X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: lvivier@redhat.com, thuth@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" As promised, this is the implementation of the core qtest driver framework API. The diff of patch 5 from the previous post is at the end of the cover letter. Emanuele Giuseppe Esposito (3): tests/libqos: introduce virtio_start_device tests/libqos: rename qpci_init_pc and qpci_init_spapr functions tests: qgraph API for the qtest driver framework Paolo Bonzini (2): tests: remove rule for nonexisting qdev-monitor-test tests/libqos: embed allocators instead of malloc-ing them separately configure | 2 +- include/qemu/module.h | 2 + tests/Makefile.include | 14 +- tests/ahci-test.c | 6 +- tests/e1000e-test.c | 22 +- tests/i440fx-test.c | 2 +- tests/ide-test.c | 19 +- tests/libqos/ahci.c | 2 +- tests/libqos/libqos-pc.c | 5 +- tests/libqos/libqos-spapr.c | 5 +- tests/libqos/libqos.c | 13 +- tests/libqos/libqos.h | 13 +- tests/libqos/malloc-generic.c | 21 +- tests/libqos/malloc-generic.h | 7 +- tests/libqos/malloc-pc.c | 18 +- tests/libqos/malloc-pc.h | 4 +- tests/libqos/malloc-spapr.c | 19 +- tests/libqos/malloc-spapr.h | 4 +- tests/libqos/malloc.c | 41 +-- tests/libqos/malloc.h | 21 +- tests/libqos/pci-pc.c | 2 +- tests/libqos/pci-pc.h | 9 +- tests/libqos/pci-spapr.c | 2 +- tests/libqos/pci-spapr.h | 2 +- tests/libqos/qgraph.c | 756 +++++++++++++++++++++++++++++++++++++= ++++ tests/libqos/qgraph.h | 575 +++++++++++++++++++++++++++++++ tests/libqos/qgraph_internal.h | 257 ++++++++++++++ tests/libqos/virtio.c | 7 + tests/libqos/virtio.h | 1 + tests/libqtest.h | 3 + tests/q35-test.c | 4 +- tests/qos-test.c | 449 ++++++++++++++++++++++++ tests/rtas-test.c | 2 +- tests/rtl8139-test.c | 2 +- tests/sdhci-test.c | 2 +- tests/tco-test.c | 2 +- tests/test-qgraph.c | 434 +++++++++++++++++++++++ tests/usb-hcd-ehci-test.c | 2 +- tests/vhost-user-test.c | 16 +- tests/virtio-9p-test.c | 16 +- tests/virtio-blk-test.c | 79 +++-- tests/virtio-net-test.c | 14 +- tests/virtio-scsi-test.c | 18 +- 43 files changed, 2650 insertions(+), 244 deletions(-) create mode 100644 tests/libqos/qgraph.c create mode 100644 tests/libqos/qgraph.h create mode 100644 tests/libqos/qgraph_internal.h create mode 100644 tests/qos-test.c create mode 100644 tests/test-qgraph.c --=20 1.8.3.1 diff --git a/tests/libqos/qgraph.c b/tests/libqos/qgraph.c index 6a750aa..cc42641 100644 --- a/tests/libqos/qgraph.c +++ b/tests/libqos/qgraph.c @@ -247,7 +247,7 @@ static void create_interface(const char *node) if (!interface) { create_node(node, QNODE_INTERFACE); } else if (interface->type !=3D QNODE_INTERFACE) { - printf("Error: Node %s is not an interface\n", node); + fprintf(stderr, "Error: Node %s is not an interface\n", node); abort(); } } @@ -265,8 +265,7 @@ static void create_interface(const char *node) */ static void build_machine_cmd_line(QOSGraphNode *node, const char *args) { - char *arch, *machine; - qos_separate_arch_machine(node->name, &arch, &machine); + char *machine =3D qos_get_machine_type(node->name); if (args) { node->command_line =3D g_strconcat("-M ", machine, ",", args, NULL= ); } else { @@ -343,7 +342,7 @@ static void qos_push(QOSGraphNode *el, QOSStackElement = *parent, /* qos_tos(): returns the top of stack, without popping */ static QOSStackElement *qos_tos(void) { - return &qos_node_stack[(qos_node_tos - 1)]; + return &qos_node_stack[qos_node_tos - 1]; } =20 /* qos_pop(): pops an element from the tos, setting it unvisited*/ @@ -419,7 +418,7 @@ static void qos_traverse_graph(QOSGraphNode *root, QOST= estCallback callback) dest_node =3D search_node(e->dest); =20 if (!dest_node) { - printf("node %s in %s -> %s does not exist\n", + fprintf(stderr, "node %s in %s -> %s does not exist\n", e->dest, v->name, e->dest); abort(); } @@ -733,25 +732,24 @@ void qos_object_start_hw(QOSGraphObject *obj) } } =20 -void qos_separate_arch_machine(char *name, char **arch, char **machine) +char *qos_get_machine_type(char *name) { - *arch =3D name; while (*name !=3D '\0' && *name !=3D '/') { name++; } =20 - if (*name =3D=3D '/' && (*name + 1) !=3D '\0') { - *machine =3D name + 1; - } else { - printf("Machine name has to be of the form /\n"); + if (!*name || !name[1]) { + fprintf(stderr, "Machine name has to be of the form /\n"); abort(); } + + return name + 1; } =20 -void qos_delete_abstract_cmd_line(const char *name, bool abstract) +void qos_delete_cmd_line(const char *name) { QOSGraphNode *node =3D search_node(name); - if (node && abstract) { + if (node) { g_free(node->command_line); node->command_line =3D NULL; } diff --git a/tests/libqos/qgraph.h b/tests/libqos/qgraph.h index 8d68314..ccc30ee 100644 --- a/tests/libqos/qgraph.h +++ b/tests/libqos/qgraph.h @@ -243,7 +243,7 @@ typedef void *(*QOSBeforeTest) (GString *cmd_line, void= *arg); * There are three types of command line arguments: * - in node : created from the node name. For example, machines will * have "-M " to its command line, while devices - * "- device ". It is automatically done by the + * "-device ". It is automatically done by the * framework. * - after node : added as additional argument to the node name. * This argument is added optionally when creating edges, @@ -466,7 +466,7 @@ void qos_node_create_driver(const char *name, QOSCreate= DriverFunc function); * It also has the possibility to add optional NULL-terminated * @opts parameters (see %QOSGraphEdgeOptions) * - * This function can be useful whrn there are multiple devices + * This function can be useful when there are multiple devices * with the same node name contained in a machine/other node * * For example, if "arm/raspi2" contains 2 "generic-sdhci" diff --git a/tests/libqos/qgraph_internal.h b/tests/libqos/qgraph_internal.h index 3728a25..2ef748b 100644 --- a/tests/libqos/qgraph_internal.h +++ b/tests/libqos/qgraph_internal.h @@ -227,32 +227,26 @@ void qos_print_graph(void); void qos_graph_foreach_test_path(QOSTestCallback fn); =20 /** - * qos_separate_arch_machine(): separate arch from machine. + * qos_get_machine_type(): return QEMU machine type for a machine node. * This function requires every machine @name to be in the form * /, like "arm/raspi2" or "x86_64/pc". * - * The function will split then the string in two parts, - * assigning @arch to point to /, and - * @machine to . + * The function will validate the format and return a pointer to + * @machine to . For example, when passed "x86_64/pc" + * it will return "pc". * - * For example, "x86_64/pc" will be split in this way: - * *arch =3D "x86_64/pc" - * *machine =3D "pc" - * - * Note that this function *does not* allocate any new string, - * but just sets the pointer *arch and *machine to the respective - * part of the string. + * Note that this function *does not* allocate any new string. */ -void qos_separate_arch_machine(char *name, char **arch, char **machine); +char *qos_get_machine_type(char *name); =20 /** - * qos_delete_abstract_cmd_line(): if @abstract is #TRUE, delete the + * qos_delete_cmd_line(): delete the * command line present in node mapped with key @name. * * This function is called when the QMP query returns a node with - * { "abstract" : } attribute. + * { "abstract" : true } attribute. */ -void qos_delete_abstract_cmd_line(const char *name, bool abstract); +void qos_delete_cmd_line(const char *name); =20 /** * qos_graph_node_set_availability(): sets the node identified diff --git a/tests/qos-test.c b/tests/qos-test.c index d85ed71..386c399 100644 --- a/tests/qos-test.c +++ b/tests/qos-test.c @@ -29,30 +29,19 @@ =20 static char *old_path; =20 -/** - * create_machine_name(): appends the architecture to @name if - * @is_machine is valid. - */ -static void create_machine_name(const char **name, bool is_machine) +static void apply_to_node(const char *name, bool is_machine, bool is_abstr= act) { - const char *arch; - if (!is_machine) { - return; + char *machine_name =3D NULL; + if (is_machine) { + const char *arch =3D qtest_get_arch(); + machine_name =3D g_strconcat(arch, "/", name, NULL); + name =3D machine_name; } - arch =3D qtest_get_arch(); - *name =3D g_strconcat(arch, "/", *name, NULL); -} - -/** - * destroy_machine_name(): frees the given @name if - * @is_machine is valid. - */ -static void destroy_machine_name(const char *name, bool is_machine) -{ - if (!is_machine) { - return; + qos_graph_node_set_availability(name, TRUE); + if (is_abstract) { + qos_delete_cmd_line(name); } - g_free((char *)name); + g_free(machine_name); } =20 /** @@ -71,7 +60,7 @@ static void apply_to_qlist(QList *list, bool is_machine) QDict *minfo; QObject *qobj; QString *qstr; - QBool *qbol; + QBool *qbool; =20 for (p =3D qlist_first(list); p; p =3D qlist_next(p)) { minfo =3D qobject_to(QDict, qlist_entry_obj(p)); @@ -79,28 +68,21 @@ static void apply_to_qlist(QList *list, bool is_machine) qstr =3D qobject_to(QString, qobj); name =3D qstring_get_str(qstr); =20 - create_machine_name(&name, is_machine); - qos_graph_node_set_availability(name, TRUE); + qobj =3D qdict_get(minfo, "abstract"); + if (qobj) { + qbool =3D qobject_to(QBool, qobj); + abstract =3D qbool_get_bool(qbool); + } else { + abstract =3D false; + } =20 + apply_to_node(name, is_machine, abstract); qobj =3D qdict_get(minfo, "alias"); if (qobj) { qstr =3D qobject_to(QString, qobj); - - destroy_machine_name(name, is_machine); name =3D qstring_get_str(qstr); - - create_machine_name(&name, is_machine); - qos_graph_node_set_availability(name, TRUE); - } - - qobj =3D qdict_get(minfo, "abstract"); - if (qobj) { - qbol =3D qobject_to(QBool, qobj); - abstract =3D qbool_get_bool(qbol); - qos_delete_abstract_cmd_line(name, abstract); + apply_to_node(name, is_machine, abstract); } - - destroy_machine_name(name, is_machine); } } =20 @@ -363,7 +345,6 @@ static void walk_path(QOSGraphNode *orig_path, int len) char **path_vec =3D g_new0(char *, (QOS_PATH_MAX_ELEMENT_SIZE * 2)); int path_vec_size =3D 0; =20 - char *machine =3D NULL, *arch =3D NULL; char *after_cmd =3D NULL, *before_cmd =3D NULL, *after_device =3D NULL; char *node_name =3D orig_path->name, *path_str; =20 @@ -373,9 +354,8 @@ static void walk_path(QOSGraphNode *orig_path, int len) path =3D qos_graph_get_node(node_name); /* root */ node_name =3D qos_graph_edge_get_dest(path->path_edge); /* machine nam= e */ =20 - qos_separate_arch_machine(node_name, &arch, &machine); - path_vec[path_vec_size++] =3D arch; - path_vec[path_vec_size++] =3D machine; + path_vec[path_vec_size++] =3D node_name; + path_vec[path_vec_size++] =3D qos_get_machine_type(node_name); =20 for (;;) { path =3D qos_graph_get_node(node_name); @@ -417,19 +397,19 @@ static void walk_path(QOSGraphNode *orig_path, int le= n) g_string_free(cmd_line2, TRUE); =20 /* here position 0 has /, position 1 has . - * The path must not have the + * The path must not have the , qtest_add_data_func adds it. */ path_str =3D g_strjoinv("/", path_vec + 1); =20 /* put arch/machine in position 1 so run_one_test can do its work * and add the command line at position 0. */ + path_vec[1] =3D path_vec[0]; path_vec[0] =3D g_string_free(cmd_line, FALSE); - path_vec[1] =3D arch; =20 if (path->u.test.subprocess) { gchar *subprocess_path =3D g_strdup_printf("/%s/%s/subprocess", - qtest_get_arch(), path_st= r); + qtest_get_arch(), path_str); qtest_add_data_func(path_str, subprocess_path, subprocess_run_one_= test); g_test_add_data_func(subprocess_path, path_vec, run_one_test); } else {