get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/808734/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 808734,
    "url": "http://patchwork.ozlabs.org/api/patches/808734/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170901153758.8628-3-armbru@redhat.com/",
    "project": {
        "id": 14,
        "url": "http://patchwork.ozlabs.org/api/projects/14/?format=api",
        "name": "QEMU Development",
        "link_name": "qemu-devel",
        "list_id": "qemu-devel.nongnu.org",
        "list_email": "qemu-devel@nongnu.org",
        "web_url": "",
        "scm_url": "",
        "webscm_url": "",
        "list_archive_url": "",
        "list_archive_url_format": "",
        "commit_url_format": ""
    },
    "msgid": "<20170901153758.8628-3-armbru@redhat.com>",
    "list_archive_url": null,
    "date": "2017-09-01T15:37:13",
    "name": "[PULL,v2,02/47] tests/qmp-test: Add generic, basic test of query commands",
    "commit_ref": null,
    "pull_url": null,
    "state": "new",
    "archived": false,
    "hash": "e624e8832442d0d5bc24b30eb7efccc8b2eb1b04",
    "submitter": {
        "id": 2645,
        "url": "http://patchwork.ozlabs.org/api/people/2645/?format=api",
        "name": "Markus Armbruster",
        "email": "armbru@redhat.com"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/qemu-devel/patch/20170901153758.8628-3-armbru@redhat.com/mbox/",
    "series": [
        {
            "id": 1049,
            "url": "http://patchwork.ozlabs.org/api/series/1049/?format=api",
            "web_url": "http://patchwork.ozlabs.org/project/qemu-devel/list/?series=1049",
            "date": "2017-09-01T15:37:14",
            "name": "[PULL,v2,01/47] qapi: Fix error handling code on alternate conflict",
            "version": 2,
            "mbox": "http://patchwork.ozlabs.org/series/1049/mbox/"
        }
    ],
    "comments": "http://patchwork.ozlabs.org/api/patches/808734/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/808734/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>",
        "X-Original-To": "incoming@patchwork.ozlabs.org",
        "Delivered-To": "patchwork-incoming@bilbo.ozlabs.org",
        "Authentication-Results": [
            "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=nongnu.org\n\t(client-ip=2001:4830:134:3::11; helo=lists.gnu.org;\n\tenvelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n\treceiver=<UNKNOWN>)",
            "ext-mx06.extmail.prod.ext.phx2.redhat.com;\n\tdmarc=none (p=none dis=none) header.from=redhat.com",
            "ext-mx06.extmail.prod.ext.phx2.redhat.com;\n\tspf=fail smtp.mailfrom=armbru@redhat.com"
        ],
        "Received": [
            "from lists.gnu.org (lists.gnu.org [IPv6:2001:4830:134:3::11])\n\t(using TLSv1 with cipher AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xkNpl06Mdz9t2d\n\tfor <incoming@patchwork.ozlabs.org>;\n\tSat,  2 Sep 2017 01:44:47 +1000 (AEST)",
            "from localhost ([::1]:46504 helo=lists.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.71) (envelope-from\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>)\n\tid 1dno7h-0004xH-1t\n\tfor incoming@patchwork.ozlabs.org; Fri, 01 Sep 2017 11:44:45 -0400",
            "from eggs.gnu.org ([2001:4830:134:3::10]:51369)\n\tby lists.gnu.org with esmtp (Exim 4.71)\n\t(envelope-from <armbru@redhat.com>) id 1dno1F-0006XR-VZ\n\tfor qemu-devel@nongnu.org; Fri, 01 Sep 2017 11:38:11 -0400",
            "from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)\n\t(envelope-from <armbru@redhat.com>) id 1dno1B-0001bB-CX\n\tfor qemu-devel@nongnu.org; Fri, 01 Sep 2017 11:38:05 -0400",
            "from mx1.redhat.com ([209.132.183.28]:55790)\n\tby eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32)\n\t(Exim 4.71) (envelope-from <armbru@redhat.com>) id 1dno1B-0001aa-3l\n\tfor qemu-devel@nongnu.org; Fri, 01 Sep 2017 11:38:01 -0400",
            "from smtp.corp.redhat.com\n\t(int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15])\n\t(using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits))\n\t(No client certificate requested)\n\tby mx1.redhat.com (Postfix) with ESMTPS id 24F9C25C28\n\tfor <qemu-devel@nongnu.org>; Fri,  1 Sep 2017 15:38:00 +0000 (UTC)",
            "from blackfin.pond.sub.org (ovpn-116-75.ams2.redhat.com\n\t[10.36.116.75])\n\tby smtp.corp.redhat.com (Postfix) with ESMTPS id C0228A63DE\n\tfor <qemu-devel@nongnu.org>; Fri,  1 Sep 2017 15:37:59 +0000 (UTC)",
            "by blackfin.pond.sub.org (Postfix, from userid 1000)\n\tid 4870C1138664; Fri,  1 Sep 2017 17:37:58 +0200 (CEST)"
        ],
        "DMARC-Filter": "OpenDMARC Filter v1.3.2 mx1.redhat.com 24F9C25C28",
        "From": "Markus Armbruster <armbru@redhat.com>",
        "To": "qemu-devel@nongnu.org",
        "Date": "Fri,  1 Sep 2017 17:37:13 +0200",
        "Message-Id": "<20170901153758.8628-3-armbru@redhat.com>",
        "In-Reply-To": "<20170901153758.8628-1-armbru@redhat.com>",
        "References": "<20170901153758.8628-1-armbru@redhat.com>",
        "X-Scanned-By": "MIMEDefang 2.79 on 10.5.11.15",
        "X-Greylist": "Sender IP whitelisted, not delayed by milter-greylist-4.5.16\n\t(mx1.redhat.com [10.5.110.30]);\n\tFri, 01 Sep 2017 15:38:00 +0000 (UTC)",
        "X-detected-operating-system": "by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic]\n\t[fuzzy]",
        "X-Received-From": "209.132.183.28",
        "Subject": "[Qemu-devel] [PULL v2 02/47] tests/qmp-test: Add generic,\n\tbasic test of query commands",
        "X-BeenThere": "qemu-devel@nongnu.org",
        "X-Mailman-Version": "2.1.21",
        "Precedence": "list",
        "List-Id": "<qemu-devel.nongnu.org>",
        "List-Unsubscribe": "<https://lists.nongnu.org/mailman/options/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.nongnu.org/archive/html/qemu-devel/>",
        "List-Post": "<mailto:qemu-devel@nongnu.org>",
        "List-Help": "<mailto:qemu-devel-request@nongnu.org?subject=help>",
        "List-Subscribe": "<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n\t<mailto:qemu-devel-request@nongnu.org?subject=subscribe>",
        "Errors-To": "qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org",
        "Sender": "\"Qemu-devel\"\n\t<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>"
    },
    "content": "A command is a query if it has no side effect and yields a result.\nSuch commands are typically named query-FOO, but there are exceptions.\n\nThe basic idea is to find candidates with query-qmp-schema, filter out\nthe ones that aren't queries with an explicit blacklist, and test the\nremaining ones against a QEMU with no special arguments.\n\nThe current blacklist is just add-fd.\n\nThe test can't do queries with arguments, because it knows nothing\nabout the arguments.  No coverage for query-cpu-model-baseline,\nquery-cpu-model-comparison, query-cpu-model-expansion, query-rocker,\nquery-rocker-ports, query-rocker-of-dpa-flows, and\nquery-rocker-of-dpa-groups.\n\nMost tested commands are expected to succeed.  The test does not check\nthe return value then.\n\nquery-balloon and query-vm-generation-id are expected to fail because\nthey need a virtio-balloon / vmgenid device to succeed, and this test\nis too dumb to set one up.  Could be addressed later.\n\nquery-acpi-ospm-status and query-hotpluggable-cpus are expected to\nfail because they require features provided only by special machine\ntypes, and this test is too dumb to set that up.  Could also be\naddressed later.\n\nSeveral commands may either be functional or stubs that always fail,\ndepending on build configuration.  Ideally, the stubs shouldn't be in\nquery-qmp-schema, but that requires QAPI schema compile-time\nconfiguration, which we don't have, yet.  Until we do, we need to\nfigure out whether a command is a stub.  When we have a suitable\nCONFIG_FOO preprocessor symbol is available, use that.  Else,\nsimply blacklist the command for now.\n\nWe get basic test coverage for the following commands, except as\nnoted:\n\n    qom-list-types\n    query-acpi-ospm-status      (expected to fail)\n    query-balloon               (expected to fail)\n    query-block\n    query-block-jobs\n    query-blockstats\n    query-chardev\n    query-chardev-backends\n    query-command-line-options\n    query-commands\n    query-cpu-definitions       (blacklisted for now)\n    query-cpus\n    query-dump\n    query-dump-guest-memory-capability\n    query-events\n    query-fdsets\n    query-gic-capabilities      (blacklisted for now)\n    query-hotpluggable-cpus     (expected to fail)\n    query-iothreads\n    query-kvm\n    query-machines\n    query-memdev\n    query-memory-devices\n    query-mice\n    query-migrate\n    query-migrate-cache-size\n    query-migrate-capabilities\n    query-migrate-parameters\n    query-name\n    query-named-block-nodes\n    query-pci                   (blacklisted for now)\n    query-qmp-schema\n    query-rx-filter\n    query-spice\n    query-status\n    query-target\n    query-tpm\n    query-tpm-models\n    query-tpm-types\n    query-uuid\n    query-version\n    query-vm-generation-id      (expected to fail)\n    query-vnc\n    query-vnc-servers\n    query-xen-replication-status\n\nSigned-off-by: Markus Armbruster <armbru@redhat.com>\nMessage-Id: <1502461148-10154-1-git-send-email-armbru@redhat.com>\nReviewed-by: Eric Blake <eblake@redhat.com>\n[Commit message typo fixed]\n---\n tests/qmp-test.c | 182 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-\n 1 file changed, 181 insertions(+), 1 deletion(-)",
    "diff": "diff --git a/tests/qmp-test.c b/tests/qmp-test.c\nindex 5d0260b2be..e5fb17c201 100644\n--- a/tests/qmp-test.c\n+++ b/tests/qmp-test.c\n@@ -15,6 +15,7 @@\n #include \"qapi-visit.h\"\n #include \"qapi/error.h\"\n #include \"qapi/qobject-input-visitor.h\"\n+#include \"qapi/util.h\"\n #include \"qapi/visitor.h\"\n \n const char common_args[] = \"-nodefaults -machine none\";\n@@ -129,11 +130,190 @@ static void test_qmp_protocol(void)\n     qtest_end();\n }\n \n+static int query_error_class(const char *cmd)\n+{\n+    static struct {\n+        const char *cmd;\n+        int err_class;\n+    } fails[] = {\n+        /* Success depends on build configuration: */\n+#ifndef CONFIG_SPICE\n+        \"query-spice\", ERROR_CLASS_COMMAND_NOT_FOUND,\n+#endif\n+#ifndef CONFIG_VNC\n+        \"query-vnc\", ERROR_CLASS_GENERIC_ERROR },\n+        \"query-vnc-servers\", ERROR_CLASS_GENERIC_ERROR },\n+#endif\n+#ifndef CONFIG_REPLICATION\n+        \"query-xen-replication-spice\", ERROR_CLASS_COMMAND_NOT_FOUND,\n+#endif\n+        /* Likewise, and require special QEMU command-line arguments: */\n+        { \"query-acpi-ospm-status\", ERROR_CLASS_GENERIC_ERROR },\n+        { \"query-balloon\", ERROR_CLASS_DEVICE_NOT_ACTIVE },\n+        { \"query-hotpluggable-cpus\", ERROR_CLASS_GENERIC_ERROR },\n+        { \"query-vm-generation-id\", ERROR_CLASS_GENERIC_ERROR },\n+        { NULL, -1 }\n+    };\n+    int i;\n+\n+    for (i = 0; fails[i].cmd; i++) {\n+        if (!strcmp(cmd, fails[i].cmd)) {\n+            return fails[i].err_class;\n+        }\n+    }\n+    return -1;\n+}\n+\n+static void test_query(const void *data)\n+{\n+    const char *cmd = data;\n+    int expected_error_class = query_error_class(cmd);\n+    QDict *resp, *error;\n+    const char *error_class;\n+\n+    qtest_start(common_args);\n+\n+    resp = qmp(\"{ 'execute': %s }\", cmd);\n+    error = qdict_get_qdict(resp, \"error\");\n+    error_class = error ? qdict_get_str(error, \"class\") : NULL;\n+\n+    if (expected_error_class < 0) {\n+        g_assert(qdict_haskey(resp, \"return\"));\n+    } else {\n+        g_assert(error);\n+        g_assert_cmpint(qapi_enum_parse(QapiErrorClass_lookup, error_class,\n+                                        QAPI_ERROR_CLASS__MAX, -1,\n+                                        &error_abort),\n+                        ==, expected_error_class);\n+    }\n+    QDECREF(resp);\n+\n+    qtest_end();\n+}\n+\n+static bool query_is_blacklisted(const char *cmd)\n+{\n+    const char *blacklist[] = {\n+        /* Not actually queries: */\n+        \"add-fd\",\n+        /* Success depends on target arch: */\n+        \"query-cpu-definitions\",  /* arm, i386, ppc, s390x */\n+        \"query-gic-capabilities\", /* arm */\n+        /* Success depends on target-specific build configuration: */\n+        \"query-pci\",              /* CONFIG_PCI */\n+        NULL\n+    };\n+    int i;\n+\n+    for (i = 0; blacklist[i]; i++) {\n+        if (!strcmp(cmd, blacklist[i])) {\n+            return true;\n+        }\n+    }\n+    return false;\n+}\n+\n+typedef struct {\n+    SchemaInfoList *list;\n+    GHashTable *hash;\n+} QmpSchema;\n+\n+static void qmp_schema_init(QmpSchema *schema)\n+{\n+    QDict *resp;\n+    Visitor *qiv;\n+    SchemaInfoList *tail;\n+\n+    qtest_start(common_args);\n+    resp = qmp(\"{ 'execute': 'query-qmp-schema' }\");\n+\n+    qiv = qobject_input_visitor_new(qdict_get(resp, \"return\"));\n+    visit_type_SchemaInfoList(qiv, NULL, &schema->list, &error_abort);\n+    visit_free(qiv);\n+\n+    QDECREF(resp);\n+    qtest_end();\n+\n+    schema->hash = g_hash_table_new(g_str_hash, g_str_equal);\n+\n+    /* Build @schema: hash table mapping entity name to SchemaInfo */\n+    for (tail = schema->list; tail; tail = tail->next) {\n+        g_hash_table_insert(schema->hash, tail->value->name, tail->value);\n+    }\n+}\n+\n+static SchemaInfo *qmp_schema_lookup(QmpSchema *schema, const char *name)\n+{\n+    return g_hash_table_lookup(schema->hash, name);\n+}\n+\n+static void qmp_schema_cleanup(QmpSchema *schema)\n+{\n+    qapi_free_SchemaInfoList(schema->list);\n+    g_hash_table_destroy(schema->hash);\n+}\n+\n+static bool object_type_has_mandatory_members(SchemaInfo *type)\n+{\n+    SchemaInfoObjectMemberList *tail;\n+\n+    g_assert(type->meta_type == SCHEMA_META_TYPE_OBJECT);\n+\n+    for (tail = type->u.object.members; tail; tail = tail->next) {\n+        if (!tail->value->has_q_default) {\n+            return true;\n+        }\n+    }\n+\n+    return false;\n+}\n+\n+static void add_query_tests(QmpSchema *schema)\n+{\n+    SchemaInfoList *tail;\n+    SchemaInfo *si, *arg_type, *ret_type;\n+    const char *test_name;\n+\n+    /* Test the query-like commands */\n+    for (tail = schema->list; tail; tail = tail->next) {\n+        si = tail->value;\n+        if (si->meta_type != SCHEMA_META_TYPE_COMMAND) {\n+            continue;\n+        }\n+\n+        if (query_is_blacklisted(si->name)) {\n+            continue;\n+        }\n+\n+        arg_type = qmp_schema_lookup(schema, si->u.command.arg_type);\n+        if (object_type_has_mandatory_members(arg_type)) {\n+            continue;\n+        }\n+\n+        ret_type = qmp_schema_lookup(schema, si->u.command.ret_type);\n+        if (ret_type->meta_type == SCHEMA_META_TYPE_OBJECT\n+            && !ret_type->u.object.members) {\n+            continue;\n+        }\n+\n+        test_name = g_strdup_printf(\"qmp/%s\", si->name);\n+        qtest_add_data_func(test_name, si->name, test_query);\n+    }\n+}\n+\n int main(int argc, char *argv[])\n {\n+    QmpSchema schema;\n+    int ret;\n+\n     g_test_init(&argc, &argv, NULL);\n \n     qtest_add_func(\"qmp/protocol\", test_qmp_protocol);\n+    qmp_schema_init(&schema);\n+    add_query_tests(&schema);\n \n-    return g_test_run();\n+    ret = g_test_run();\n+\n+    qmp_schema_cleanup(&schema);\n+    return ret;\n }\n",
    "prefixes": [
        "PULL",
        "v2",
        "02/47"
    ]
}