Commit fa198ad9 authored by Peter Xu's avatar Peter Xu Committed by Eric Blake
Browse files

tests: qmp-test: add test for new "x-oob"



Test the new OOB capability. It's mostly the reverted OOB test
(see commit 4fd78ad7), but differs in that:

- It uses the new qtest_init_without_qmp_handshake() parameter to
  create the monitor with "x-oob"
- Squashed the capability tests on greeting message
- Don't use qtest_global any more, instead use self-maintained
  QTestState, which is the trend

Signed-off-by: default avatarPeter Xu <peterx@redhat.com>
Message-Id: <20180326063901.27425-9-peterx@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
[eblake: rebase to qtest_init changes]
Reviewed-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Tested-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarEric Blake <eblake@redhat.com>
parent ddee57e0
Loading
Loading
Loading
Loading
+82 −0
Original line number Diff line number Diff line
@@ -135,6 +135,87 @@ static void test_qmp_protocol(void)
    qtest_quit(qts);
}

/* Tests for Out-Of-Band support. */
static void test_qmp_oob(void)
{
    QTestState *qts;
    QDict *resp, *q;
    int acks = 0;
    const QListEntry *entry;
    QList *capabilities;
    QString *qstr;
    const char *cmd_id;

    qts = qtest_init_without_qmp_handshake(true, common_args);

    /* Check the greeting message. */
    resp = qtest_qmp_receive(qts);
    q = qdict_get_qdict(resp, "QMP");
    g_assert(q);
    capabilities = qdict_get_qlist(q, "capabilities");
    g_assert(capabilities && !qlist_empty(capabilities));
    entry = qlist_first(capabilities);
    g_assert(entry);
    qstr = qobject_to(QString, entry->value);
    g_assert(qstr);
    g_assert_cmpstr(qstring_get_str(qstr), ==, "oob");
    QDECREF(resp);

    /* Try a fake capability, it should fail. */
    resp = qtest_qmp(qts,
                     "{ 'execute': 'qmp_capabilities', "
                     "  'arguments': { 'enable': [ 'cap-does-not-exist' ] } }");
    g_assert(qdict_haskey(resp, "error"));
    QDECREF(resp);

    /* Now, enable OOB in current QMP session, it should succeed. */
    resp = qtest_qmp(qts,
                     "{ 'execute': 'qmp_capabilities', "
                     "  'arguments': { 'enable': [ 'oob' ] } }");
    g_assert(qdict_haskey(resp, "return"));
    QDECREF(resp);

    /*
     * Try any command that does not support OOB but with OOB flag. We
     * should get failure.
     */
    resp = qtest_qmp(qts,
                     "{ 'execute': 'query-cpus',"
                     "  'control': { 'run-oob': true } }");
    g_assert(qdict_haskey(resp, "error"));
    QDECREF(resp);

    /*
     * First send the "x-oob-test" command with lock=true and
     * oob=false, it should hang the dispatcher and main thread;
     * later, we send another lock=false with oob=true to continue
     * that thread processing.  Finally we should receive replies from
     * both commands.
     */
    qtest_async_qmp(qts,
                    "{ 'execute': 'x-oob-test',"
                    "  'arguments': { 'lock': true }, "
                    "  'id': 'lock-cmd'}");
    qtest_async_qmp(qts,
                    "{ 'execute': 'x-oob-test', "
                    "  'arguments': { 'lock': false }, "
                    "  'control': { 'run-oob': true }, "
                    "  'id': 'unlock-cmd' }");

    /* Ignore all events.  Wait for 2 acks */
    while (acks < 2) {
        resp = qtest_qmp_receive(qts);
        cmd_id = qdict_get_str(resp, "id");
        if (!g_strcmp0(cmd_id, "lock-cmd") ||
            !g_strcmp0(cmd_id, "unlock-cmd")) {
            acks++;
        }
        QDECREF(resp);
    }

    qtest_quit(qts);
}

static int query_error_class(const char *cmd)
{
    static struct {
@@ -319,6 +400,7 @@ int main(int argc, char *argv[])
    g_test_init(&argc, &argv, NULL);

    qtest_add_func("qmp/protocol", test_qmp_protocol);
    qtest_add_func("qmp/oob", test_qmp_oob);
    qmp_schema_init(&schema);
    add_query_tests(&schema);