From 9ef8112a24d13c9d054c26105b24a3e12e1cb430 Mon Sep 17 00:00:00 2001 From: Alberto Garcia Date: Fri, 29 Jul 2016 17:31:41 +0300 Subject: [PATCH] tests: Test blockjob IDs Since 7f0317cfc8da6 we have API to specify the ID of block jobs and we also guarantee that they are well-formed and unique. This patch adds tests to check some common scenarios. Signed-off-by: Alberto Garcia Signed-off-by: Kevin Wolf --- tests/Makefile.include | 2 + tests/test-blockjob.c | 147 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 149 insertions(+) create mode 100644 tests/test-blockjob.c diff --git a/tests/Makefile.include b/tests/Makefile.include index ebecfa445c..14be4915b9 100644 --- a/tests/Makefile.include +++ b/tests/Makefile.include @@ -52,6 +52,7 @@ gcov-files-test-thread-pool-y = thread-pool.c gcov-files-test-hbitmap-y = util/hbitmap.c check-unit-y += tests/test-hbitmap$(EXESUF) gcov-files-test-hbitmap-y = blockjob.c +check-unit-y += tests/test-blockjob$(EXESUF) check-unit-y += tests/test-blockjob-txn$(EXESUF) check-unit-y += tests/test-x86-cpuid$(EXESUF) # all code tested by test-x86-cpuid is inside topology.h @@ -449,6 +450,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(test-block-obj-y) tests/test-aio$(EXESUF): tests/test-aio.o $(test-block-obj-y) tests/test-rfifolock$(EXESUF): tests/test-rfifolock.o $(test-util-obj-y) tests/test-throttle$(EXESUF): tests/test-throttle.o $(test-block-obj-y) +tests/test-blockjob$(EXESUF): tests/test-blockjob.o $(test-block-obj-y) $(test-util-obj-y) tests/test-blockjob-txn$(EXESUF): tests/test-blockjob-txn.o $(test-block-obj-y) $(test-util-obj-y) tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(test-block-obj-y) tests/test-iov$(EXESUF): tests/test-iov.o $(test-util-obj-y) diff --git a/tests/test-blockjob.c b/tests/test-blockjob.c new file mode 100644 index 0000000000..5b0e934a0c --- /dev/null +++ b/tests/test-blockjob.c @@ -0,0 +1,147 @@ +/* + * Blockjob tests + * + * Copyright Igalia, S.L. 2016 + * + * Authors: + * Alberto Garcia + * + * This work is licensed under the terms of the GNU LGPL, version 2 or later. + * See the COPYING.LIB file in the top-level directory. + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/main-loop.h" +#include "block/blockjob.h" +#include "sysemu/block-backend.h" + +static const BlockJobDriver test_block_job_driver = { + .instance_size = sizeof(BlockJob), +}; + +static void block_job_cb(void *opaque, int ret) +{ +} + +static BlockJob *do_test_id(BlockBackend *blk, const char *id, + bool should_succeed) +{ + BlockJob *job; + Error *errp = NULL; + + job = block_job_create(id, &test_block_job_driver, blk_bs(blk), 0, + block_job_cb, NULL, &errp); + if (should_succeed) { + g_assert_null(errp); + g_assert_nonnull(job); + if (id) { + g_assert_cmpstr(job->id, ==, id); + } else { + g_assert_cmpstr(job->id, ==, blk_name(blk)); + } + } else { + g_assert_nonnull(errp); + g_assert_null(job); + error_free(errp); + } + + return job; +} + +/* This creates a BlockBackend (optionally with a name) with a + * BlockDriverState inserted. */ +static BlockBackend *create_blk(const char *name) +{ + BlockBackend *blk = blk_new(); + BlockDriverState *bs = bdrv_new(); + + blk_insert_bs(blk, bs); + bdrv_unref(bs); + + if (name) { + Error *errp = NULL; + monitor_add_blk(blk, name, &errp); + g_assert_null(errp); + } + + return blk; +} + +/* This destroys the backend */ +static void destroy_blk(BlockBackend *blk) +{ + if (blk_name(blk)[0] != '\0') { + monitor_remove_blk(blk); + } + + blk_remove_bs(blk); + blk_unref(blk); +} + +static void test_job_ids(void) +{ + BlockBackend *blk[3]; + BlockJob *job[3]; + + blk[0] = create_blk(NULL); + blk[1] = create_blk("drive1"); + blk[2] = create_blk("drive2"); + + /* No job ID provided and the block backend has no name */ + job[0] = do_test_id(blk[0], NULL, false); + + /* These are all invalid job IDs */ + job[0] = do_test_id(blk[0], "0id", false); + job[0] = do_test_id(blk[0], "", false); + job[0] = do_test_id(blk[0], " ", false); + job[0] = do_test_id(blk[0], "123", false); + job[0] = do_test_id(blk[0], "_id", false); + job[0] = do_test_id(blk[0], "-id", false); + job[0] = do_test_id(blk[0], ".id", false); + job[0] = do_test_id(blk[0], "#id", false); + + /* This one is valid */ + job[0] = do_test_id(blk[0], "id0", true); + + /* We cannot have two jobs in the same BDS */ + do_test_id(blk[0], "id1", false); + + /* Duplicate job IDs are not allowed */ + job[1] = do_test_id(blk[1], "id0", false); + + /* But once job[0] finishes we can reuse its ID */ + block_job_unref(job[0]); + job[1] = do_test_id(blk[1], "id0", true); + + /* No job ID specified, defaults to the backend name ('drive1') */ + block_job_unref(job[1]); + job[1] = do_test_id(blk[1], NULL, true); + + /* Duplicate job ID */ + job[2] = do_test_id(blk[2], "drive1", false); + + /* The ID of job[2] would default to 'drive2' but it is already in use */ + job[0] = do_test_id(blk[0], "drive2", true); + job[2] = do_test_id(blk[2], NULL, false); + + /* This one is valid */ + job[2] = do_test_id(blk[2], "id_2", true); + + block_job_unref(job[0]); + block_job_unref(job[1]); + block_job_unref(job[2]); + + destroy_blk(blk[0]); + destroy_blk(blk[1]); + destroy_blk(blk[2]); +} + +int main(int argc, char **argv) +{ + qemu_init_main_loop(&error_abort); + + g_test_init(&argc, &argv, NULL); + g_test_add_func("/blockjob/ids", test_job_ids); + return g_test_run(); +}