Commit 4eaab85c authored by Marc-André Lureau's avatar Marc-André Lureau Committed by Michael Roth
Browse files

tests: add file-write-read test

This test exhibits a POSIX behaviour regarding switching between write
and read. It's undefined result if the application doesn't ensure a
flush between the two operations (with glibc, the flush can be implicit
when the buffer size is relatively small). The previous commit fixes
this test.

Related to:
https://bugzilla.redhat.com/show_bug.cgi?id=1210246



Signed-off-by: default avatarMarc-André Lureau <marcandre.lureau@redhat.com>
Reviewed-by: default avatarEric Blake <eblake@redhat.com>
Signed-off-by: default avatarMichael Roth <mdroth@linux.vnet.ibm.com>
parent 895b00f6
Loading
Loading
Loading
Loading
+93 −2
Original line number Diff line number Diff line
@@ -352,10 +352,10 @@ static void test_qga_network_get_interfaces(gconstpointer fix)
static void test_qga_file_ops(gconstpointer fix)
{
    const TestFixture *fixture = fix;
    const guchar helloworld[] = "Hello World!\n";
    const unsigned char helloworld[] = "Hello World!\n";
    const char *b64;
    gchar *cmd, *path, *enc;
    guchar *dec;
    unsigned char *dec;
    QDict *ret, *val;
    int64_t id, eof;
    gsize count;
@@ -496,6 +496,96 @@ static void test_qga_file_ops(gconstpointer fix)
    g_free(cmd);
}

static void test_qga_file_write_read(gconstpointer fix)
{
    const TestFixture *fixture = fix;
    const unsigned char helloworld[] = "Hello World!\n";
    const char *b64;
    gchar *cmd, *enc;
    QDict *ret, *val;
    int64_t id, eof;
    gsize count;

    /* open */
    ret = qmp_fd(fixture->fd, "{'execute': 'guest-file-open',"
                 " 'arguments': { 'path': 'foo', 'mode': 'w+' } }");
    g_assert_nonnull(ret);
    qmp_assert_no_error(ret);
    id = qdict_get_int(ret, "return");
    QDECREF(ret);

    enc = g_base64_encode(helloworld, sizeof(helloworld));
    /* write */
    cmd = g_strdup_printf("{'execute': 'guest-file-write',"
                          " 'arguments': { 'handle': %" PRId64 ","
                          " 'buf-b64': '%s' } }", id, enc);
    ret = qmp_fd(fixture->fd, cmd);
    g_assert_nonnull(ret);
    qmp_assert_no_error(ret);

    val = qdict_get_qdict(ret, "return");
    count = qdict_get_int(val, "count");
    eof = qdict_get_bool(val, "eof");
    g_assert_cmpint(count, ==, sizeof(helloworld));
    g_assert_cmpint(eof, ==, 0);
    QDECREF(ret);
    g_free(cmd);

    /* read (check implicit flush) */
    cmd = g_strdup_printf("{'execute': 'guest-file-read',"
                          " 'arguments': { 'handle': %" PRId64 "} }",
                          id);
    ret = qmp_fd(fixture->fd, cmd);
    val = qdict_get_qdict(ret, "return");
    count = qdict_get_int(val, "count");
    eof = qdict_get_bool(val, "eof");
    b64 = qdict_get_str(val, "buf-b64");
    g_assert_cmpint(count, ==, 0);
    g_assert(eof);
    g_assert_cmpstr(b64, ==, "");
    QDECREF(ret);
    g_free(cmd);

    /* seek to 0 */
    cmd = g_strdup_printf("{'execute': 'guest-file-seek',"
                          " 'arguments': { 'handle': %" PRId64 ", "
                          " 'offset': %d, 'whence': %d } }",
                          id, 0, SEEK_SET);
    ret = qmp_fd(fixture->fd, cmd);
    qmp_assert_no_error(ret);
    val = qdict_get_qdict(ret, "return");
    count = qdict_get_int(val, "position");
    eof = qdict_get_bool(val, "eof");
    g_assert_cmpint(count, ==, 0);
    g_assert(!eof);
    QDECREF(ret);
    g_free(cmd);

    /* read */
    cmd = g_strdup_printf("{'execute': 'guest-file-read',"
                          " 'arguments': { 'handle': %" PRId64 "} }",
                          id);
    ret = qmp_fd(fixture->fd, cmd);
    val = qdict_get_qdict(ret, "return");
    count = qdict_get_int(val, "count");
    eof = qdict_get_bool(val, "eof");
    b64 = qdict_get_str(val, "buf-b64");
    g_assert_cmpint(count, ==, sizeof(helloworld));
    g_assert(eof);
    g_assert_cmpstr(b64, ==, enc);
    QDECREF(ret);
    g_free(cmd);
    g_free(enc);

    /* close */
    cmd = g_strdup_printf("{'execute': 'guest-file-close',"
                          " 'arguments': {'handle': %" PRId64 "} }",
                          id);
    ret = qmp_fd(fixture->fd, cmd);
    QDECREF(ret);
    g_free(cmd);
}

static void test_qga_get_time(gconstpointer fix)
{
    const TestFixture *fixture = fix;
@@ -762,6 +852,7 @@ int main(int argc, char **argv)
    g_test_add_data_func("/qga/get-memory-blocks", &fix,
                         test_qga_get_memory_blocks);
    g_test_add_data_func("/qga/file-ops", &fix, test_qga_file_ops);
    g_test_add_data_func("/qga/file-write-read", &fix, test_qga_file_write_read);
    g_test_add_data_func("/qga/get-time", &fix, test_qga_get_time);
    g_test_add_data_func("/qga/invalid-cmd", &fix, test_qga_invalid_cmd);
    g_test_add_data_func("/qga/fsfreeze-status", &fix,