-From 6b0aa521526e0cc35539ee327b3e6c976da6e361 Mon Sep 17 00:00:00 2001
+From 348a009b2c63ac4d9b6dad7fe2169272c46221f2 Mon Sep 17 00:00:00 2001
From: Dietmar Maurer <dietmar@proxmox.com>
Date: Wed, 14 Nov 2012 09:57:04 +0100
-Subject: [PATCH v3 5/6] add regression tests for backup
+Subject: [PATCH v5 5/6] add regression tests for backup
Simple regression tests using vma-reader and vma-writer.
-Note: the call to g_thread_init() solves problems with g_slice_alloc() - without that call we get arbitrary crashes.
-
Signed-off-by: Dietmar Maurer <dietmar@proxmox.com>
---
tests/Makefile | 11 +-
- tests/backup-test.c | 517 +++++++++++++++++++++++++++++++++++++++++++++++++++
- 2 files changed, 526 insertions(+), 2 deletions(-)
+ tests/backup-test.c | 529 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 538 insertions(+), 2 deletions(-)
create mode 100644 tests/backup-test.c
diff --git a/tests/Makefile b/tests/Makefile
-index a2d62b8..c3d8b4a 100644
+index 567e36e..136be84 100644
--- a/tests/Makefile
+++ b/tests/Makefile
-@@ -57,6 +57,8 @@ gcov-files-test-cutils-y += util/cutils.c
+@@ -59,6 +59,8 @@ gcov-files-test-mul64-y = util/host-utils.c
check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh
# All QTests for now are POSIX-only, but the dependencies are
# really in libqtest, not in the testcases themselves.
check-qtest-i386-y = tests/fdc-test$(EXESUF)
-@@ -100,6 +102,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil
+@@ -102,6 +104,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(block-obj-y) libqemuutil
tests/test-aio$(EXESUF): tests/test-aio.o $(block-obj-y) libqemuutil.a libqemustub.a
tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(block-obj-y) libqemuutil.a libqemustub.a
tests/test-iov$(EXESUF): tests/test-iov.o libqemuutil.a
tests/test-hbitmap$(EXESUF): tests/test-hbitmap.o libqemuutil.a libqemustub.a
tests/test-x86-cpuid$(EXESUF): tests/test-x86-cpuid.o
tests/test-xbzrle$(EXESUF): tests/test-xbzrle.o xbzrle.o page_cache.o libqemuutil.a
-@@ -209,10 +212,14 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
+@@ -213,10 +216,14 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF)
# Consolidated targets
-include $(wildcard tests/*.d)
diff --git a/tests/backup-test.c b/tests/backup-test.c
new file mode 100644
-index 0000000..5ee3b90
+index 0000000..47a9664
--- /dev/null
+++ b/tests/backup-test.c
-@@ -0,0 +1,517 @@
+@@ -0,0 +1,529 @@
+/*
+ * QEMU backup test suit
+ *
-+ * Copyright (C) Proxmox Server Solutions
++ * Copyright (C) 2013 Proxmox Server Solutions
+ *
+ * Authors:
+ * Dietmar Maurer (dietmar@proxmox.com)
+ * This work is licensed under the terms of the GNU GPL, version 2. See
+ * the COPYING file in the top-level directory.
+ *
-+ * Fixme: running 'backup-test -l' trigger a bug in g_slice_alloc()
-+ * Note: 'G_SLICE=always-malloc ./tests/backup-test -l' works
-+ *
+ */
+
+#include <sys/time.h>
+{
+ BackupCB *bcb = opaque;
+
-+ DPRINTF("backup_dump_cb C%zd %d\n", cluster_num, bcb->dev_id);
++ DPRINTF("backup_dump_cb C%" PRId64 " %d\n", cluster_num, bcb->dev_id);
+
+ size_t zb = 0;
+ if (vma_writer_write(bcb->vmaw, bcb->dev_id, cluster_num, buf, &zb) < 0) {
+{
+ int ret;
+
-+ DPRINTF("write_sec_pattern_cd %zd\n", offset);
++ DPRINTF("write_sec_pattern_cd %" PRId64 "\n", offset);
+
+ if (offset & 0x1ff) {
-+ g_error("write_sec_pattern_cd offset %zd is not sector aligned\n",
-+ offset);
++ g_error("write_sec_pattern_cd offset %" PRId64
++ " is not sector aligned\n", offset);
+ }
+
+ ret = bdrv_write(bs, offset >> 9, buf_sec_pattern_cd, 1);
+ if (ret < 0) {
-+ g_error("write_sec_pattern_cd %zd failed", offset);
++ g_error("write_sec_pattern_cd %" PRId64 " failed", offset);
+ }
+
+}
+
+static void read_sec(BlockDriverState *bs, int64_t offset, unsigned char *buf)
+{
-+ DPRINTF("read_sec C%zd start %zd\n", offset>>VMA_CLUSTER_BITS, offset);
++ DPRINTF("read_sec C%" PRId64 " start %" PRId64 "\n",
++ offset>>VMA_CLUSTER_BITS, offset);
+
+ if (offset & 0x1ff) {
-+ g_error("read_sec offset %zd is not sector aligned\n", offset);
++ g_error("read_sec offset %" PRId64 " is not sector aligned\n", offset);
+ }
+
+ if (bdrv_read(bs, offset >> 9, buf, 1) < 0) {
+ data = 0; /* add zero region for testing */
+ }
+
++
++ if (sector_num >= 20*BACKUP_BLOCKS_PER_CLUSTER &&
++ sector_num <= 23*BACKUP_BLOCKS_PER_CLUSTER) {
++ data = 0; /* another zero region for testing unallocated regions */
++ }
++
+ for (i = 0; i < (512/sizeof(int64_t)); i++) {
+ i64buf[i] = data;
+ }
+ int flags = BDRV_O_NATIVE_AIO|BDRV_O_RDWR|BDRV_O_CACHE_WB;
+
+ bdrv_img_create(TEST_IMG_RESTORE_NAME, "raw", NULL, NULL, NULL,
-+ size, flags, &errp);
++ size, flags, &errp);
+ if (error_is_set(&errp)) {
+ g_error("can't create file %s: %s", TEST_IMG_RESTORE_NAME,
+ error_get_pretty(errp));
+ }
+ fill_test_sector(buf2, i);
+ if (bcmp(buf, buf2, sizeof(buf))) {
-+ g_error("data is different at sector %zd", i);
++ g_error("data is different at sector %" PRId64, i);
+ }
+ }
+
+ int64_t buf[512/sizeof(int64_t)];
+
+ for (i = 0; i < sectors; i++) {
++ if (i >= 20*BACKUP_BLOCKS_PER_CLUSTER &&
++ i <= 23*BACKUP_BLOCKS_PER_CLUSTER) {
++ continue; /* create a hole */
++ }
++
+ fill_test_sector(buf, i);
+
-+ int res = 0;
++ int res = 0;
+ while (1) {
-+ res = write(fd, buf, sizeof(buf));
++ res = pwrite(fd, buf, sizeof(buf), i*512);
+ if (!(res < 0 && errno == EINTR)) {
+ break;
+ }
+ }
+ if (res != sizeof(buf)) {
+ g_error("can't initialize file %s - %s %d\n",
-+ filename, strerror(errno), res);
++ filename, g_strerror(errno), res);
+ }
+ }
+
+ bcb.vmaw = vmaw;
+ bcb.dev_id = vma_writer_register_stream(vmaw, bdrv_get_device_name(bs),
+ bdrv_getlength(bs));
-+ if (backup_job_create(bs, backup_dump_cb, backup_complete_cb, &bcb,
-+ speed) < 0) {
++ if (backup_job_create(bs, backup_dump_cb, backup_complete_cb, &bcb,
++ speed) < 0) {
+ g_error("backup_job_create failed");
+ } else {
-+ backup_job_start(bs, false);
++ backup_job_start(bs, false);
+ }
+
+ request_term = false;
+
+ VmaStatus vmastat;
+ vma_writer_get_status(vmaw, &vmastat);
-+ DPRINTF("statistic %zd %zd\n", vmastat.stream_info[1].size,
++ DPRINTF("statistic %" PRId64 " %" PRId64 "\n", vmastat.stream_info[1].size,
+ vmastat.stream_info[1].transferred);
+ assert(vmastat.stream_info[1].size == vmastat.stream_info[1].transferred);
+
+{
+ int c;
+
++ /* Note: GLib needs to be running in multithreaded mode in order
++ * for the GSlice allocator to be thread-safe
++ */
+ g_thread_init(NULL);
+
+ for (;;) {