]>
Commit | Line | Data |
---|---|---|
1 | From 5888766e8fa9a63452d2360287cdfca18ce8f65c Mon Sep 17 00:00:00 2001 | |
2 | From: Dietmar Maurer <dietmar@proxmox.com> | |
3 | Date: Wed, 14 Nov 2012 09:57:04 +0100 | |
4 | Subject: [PATCH v3 5/6] add regression tests for backup | |
5 | ||
6 | Simple regression tests using vma-reader and vma-writer. | |
7 | ||
8 | Signed-off-by: Dietmar Maurer <dietmar@proxmox.com> | |
9 | --- | |
10 | tests/Makefile | 11 +- | |
11 | tests/backup-test.c | 511 +++++++++++++++++++++++++++++++++++++++++++++++++++ | |
12 | 2 files changed, 520 insertions(+), 2 deletions(-) | |
13 | create mode 100644 tests/backup-test.c | |
14 | ||
15 | diff --git a/tests/Makefile b/tests/Makefile | |
16 | index b60f0fb..cffbd22 100644 | |
17 | --- a/tests/Makefile | |
18 | +++ b/tests/Makefile | |
19 | @@ -20,6 +20,8 @@ check-unit-y += tests/test-thread-pool$(EXESUF) | |
20 | ||
21 | check-block-$(CONFIG_POSIX) += tests/qemu-iotests-quick.sh | |
22 | ||
23 | +check-backup-y = tests/backup-test$(EXESUF) | |
24 | + | |
25 | # All QTests for now are POSIX-only, but the dependencies are | |
26 | # really in libqtest, not in the testcases themselves. | |
27 | check-qtest-i386-y = tests/fdc-test$(EXESUF) | |
28 | @@ -54,6 +56,7 @@ tests/test-coroutine$(EXESUF): tests/test-coroutine.o $(coroutine-obj-y) $(tools | |
29 | tests/test-aio$(EXESUF): tests/test-aio.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a | |
30 | tests/test-thread-pool$(EXESUF): tests/test-thread-pool.o $(coroutine-obj-y) $(tools-obj-y) $(block-obj-y) libqemustub.a | |
31 | tests/test-iov$(EXESUF): tests/test-iov.o iov.o | |
32 | +tests/backup-test$(EXESUF): tests/backup-test.o vma-reader.o $(tools-obj-y) $(block-obj-y) libqemustub.a | |
33 | ||
34 | tests/test-qapi-types.c tests/test-qapi-types.h :\ | |
35 | $(SRC_PATH)/qapi-schema-test.json $(SRC_PATH)/scripts/qapi-types.py | |
36 | @@ -146,10 +149,14 @@ check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) | |
37 | ||
38 | # Consolidated targets | |
39 | ||
40 | -.PHONY: check-qtest check-unit check | |
41 | +.PHONY: check-backup check-qtest check-unit check | |
42 | check-qtest: $(patsubst %,check-qtest-%, $(QTEST_TARGETS)) | |
43 | check-unit: $(patsubst %,check-%, $(check-unit-y)) | |
44 | check-block: $(patsubst %,check-%, $(check-block-y)) | |
45 | -check: check-unit check-qtest | |
46 | + | |
47 | +check-backup: tests/backup-test$(EXESUF) | |
48 | + $< | |
49 | + | |
50 | +check: check-unit check-qtest check-backup | |
51 | ||
52 | -include $(wildcard tests/*.d) | |
53 | diff --git a/tests/backup-test.c b/tests/backup-test.c | |
54 | new file mode 100644 | |
55 | index 0000000..b14e9a0 | |
56 | --- /dev/null | |
57 | +++ b/tests/backup-test.c | |
58 | @@ -0,0 +1,511 @@ | |
59 | +/* | |
60 | + * QEMU backup test suit | |
61 | + * | |
62 | + * Copyright (C) Proxmox Server Solutions | |
63 | + * | |
64 | + * Authors: | |
65 | + * Dietmar Maurer (dietmar@proxmox.com) | |
66 | + * | |
67 | + * This work is licensed under the terms of the GNU GPL, version 2. See | |
68 | + * the COPYING file in the top-level directory. | |
69 | + * | |
70 | + * Fixme: running 'backup-test -l' trigger a bug in g_slice_alloc() | |
71 | + * Note: 'G_SLICE=always-malloc ./tests/backup-test -l' works | |
72 | + * | |
73 | + */ | |
74 | + | |
75 | +#include <sys/time.h> | |
76 | +#include <sys/types.h> | |
77 | +#include <stdarg.h> | |
78 | +#include <stdio.h> | |
79 | +#include <getopt.h> | |
80 | +#include <libgen.h> | |
81 | + | |
82 | +#include "qemu-common.h" | |
83 | +#include "main-loop.h" | |
84 | +#include "block_int.h" | |
85 | + | |
86 | +#include "vma.h" | |
87 | + | |
88 | +static int opt_debug; | |
89 | +static int opt_loop; | |
90 | + | |
91 | +#define DPRINTF(fmt, ...) \ | |
92 | + do { if (opt_debug) { printf(fmt, ## __VA_ARGS__); } } while (0) | |
93 | + | |
94 | +#define CLUSTER(x) (x*BACKUP_CLUSTER_SIZE) | |
95 | + | |
96 | +#define RUN_TEST(testfunc, speed) \ | |
97 | + backup_test(#testfunc " speed " #speed, speed, testfunc); | |
98 | + | |
99 | + | |
100 | +static unsigned char buf_sec_pattern_cd[BDRV_SECTOR_SIZE]; | |
101 | +static unsigned char buf_sec_pattern_32[BDRV_SECTOR_SIZE]; | |
102 | + | |
103 | +#define TEST_IMG_SIZE (6*1024*1024+BDRV_SECTOR_SIZE) | |
104 | +#define TEST_IMG_NAME "backuptest.raw" | |
105 | +#define TEST_IMG_RESTORE_NAME "backuptest.raw.restore" | |
106 | +#define TEST_VMA_NAME "backuptest.vma" | |
107 | + | |
108 | +typedef struct BackupCB { | |
109 | + VmaWriter *vmaw; | |
110 | + uint8_t dev_id; | |
111 | +} BackupCB; | |
112 | + | |
113 | +static int backup_dump_cb(void *opaque, BlockDriverState *bs, | |
114 | + int64_t cluster_num, unsigned char *buf) | |
115 | +{ | |
116 | + BackupCB *bcb = opaque; | |
117 | + | |
118 | + DPRINTF("backup_dump_cb C%zd %d\n", cluster_num, bcb->dev_id); | |
119 | + | |
120 | + size_t zb = 0; | |
121 | + if (vma_writer_write(bcb->vmaw, bcb->dev_id, cluster_num, buf, &zb) < 0) { | |
122 | + printf("backup_dump_cb vma_writer_write failed\n"); | |
123 | + return -1; | |
124 | + } | |
125 | + | |
126 | + return 0; | |
127 | +} | |
128 | + | |
129 | +static void backup_complete_cb(void *opaque, int ret) | |
130 | +{ | |
131 | + BackupCB *bcb = opaque; | |
132 | + | |
133 | + DPRINTF("backup_complete_cb %d %d\n", bcb->dev_id, ret); | |
134 | + | |
135 | + if (ret < 0) { | |
136 | + vma_writer_set_error(bcb->vmaw, "backup_complete_cb %d", ret); | |
137 | + } | |
138 | + | |
139 | + if (vma_writer_close_stream(bcb->vmaw, bcb->dev_id) <= 0) { | |
140 | + Error *err = NULL; | |
141 | + if (vma_writer_close(bcb->vmaw, &err) != 0) { | |
142 | + g_error("vma_writer_close failed %s", error_get_pretty(err)); | |
143 | + } | |
144 | + } | |
145 | + DPRINTF("backup_complete_cb finish\n"); | |
146 | +} | |
147 | + | |
148 | +static void write_sec_pattern_cd(BlockDriverState *bs, int64_t offset) | |
149 | +{ | |
150 | + int ret; | |
151 | + | |
152 | + DPRINTF("write_sec_pattern_cd %zd\n", offset); | |
153 | + | |
154 | + if (offset & 0x1ff) { | |
155 | + g_error("write_sec_pattern_cd offset %zd is not sector aligned\n", | |
156 | + offset); | |
157 | + } | |
158 | + | |
159 | + ret = bdrv_write(bs, offset >> 9, buf_sec_pattern_cd, 1); | |
160 | + if (ret < 0) { | |
161 | + g_error("write_sec_pattern_cd %zd failed", offset); | |
162 | + } | |
163 | + | |
164 | +} | |
165 | + | |
166 | +static void read_sec(BlockDriverState *bs, int64_t offset, unsigned char *buf) | |
167 | +{ | |
168 | + DPRINTF("read_sec C%zd start %zd\n", offset>>VMA_CLUSTER_BITS, offset); | |
169 | + | |
170 | + if (offset & 0x1ff) { | |
171 | + g_error("read_sec offset %zd is not sector aligned\n", offset); | |
172 | + } | |
173 | + | |
174 | + if (bdrv_read(bs, offset >> 9, buf, 1) < 0) { | |
175 | + g_error("bdrv_read failed"); | |
176 | + } | |
177 | +} | |
178 | + | |
179 | +static bool request_term; | |
180 | + | |
181 | +typedef struct TestCB { | |
182 | + Coroutine *co; | |
183 | + BlockDriverState *bs; | |
184 | + bool finished; | |
185 | +} TestCB; | |
186 | + | |
187 | +static TestCB *enter_test_co(BlockDriverState *bs, CoroutineEntry *entry) | |
188 | +{ | |
189 | + TestCB *cb = g_new0(TestCB, 1); | |
190 | + cb->bs = bs; | |
191 | + cb->co = qemu_coroutine_create(entry); | |
192 | + qemu_coroutine_enter(cb->co, cb); | |
193 | + return cb; | |
194 | +} | |
195 | + | |
196 | +static void test_co_sleep(double sec) | |
197 | +{ | |
198 | + co_sleep_ns(rt_clock, (int64_t)(sec*1000000000)); | |
199 | +}; | |
200 | + | |
201 | +static void test_co_yield(void) | |
202 | +{ | |
203 | + co_sleep_ns(rt_clock, (int64_t)(1000)); | |
204 | +}; | |
205 | + | |
206 | +static void coroutine_fn run_co_test1(void *opaque) | |
207 | +{ | |
208 | + assert(opaque); | |
209 | + TestCB *cb = (TestCB *)opaque; | |
210 | + | |
211 | + test_co_sleep(0.2); | |
212 | + write_sec_pattern_cd(cb->bs, 5*BACKUP_CLUSTER_SIZE); | |
213 | + test_co_sleep(0.2); | |
214 | + write_sec_pattern_cd(cb->bs, 10*BACKUP_CLUSTER_SIZE); | |
215 | + test_co_sleep(0.2); | |
216 | + write_sec_pattern_cd(cb->bs, 10*BACKUP_CLUSTER_SIZE); | |
217 | + | |
218 | + cb->finished = true; | |
219 | +} | |
220 | + | |
221 | +static void coroutine_fn run_co_test2(void *opaque) | |
222 | +{ | |
223 | + assert(opaque); | |
224 | + TestCB *cb = (TestCB *)opaque; | |
225 | + unsigned char buf[512]; | |
226 | + | |
227 | + test_co_sleep(0.2); | |
228 | + read_sec(cb->bs, 5*BACKUP_CLUSTER_SIZE, buf); | |
229 | + write_sec_pattern_cd(cb->bs, 6*BACKUP_CLUSTER_SIZE); | |
230 | + | |
231 | + cb->finished = true; | |
232 | +} | |
233 | + | |
234 | +static void coroutine_fn run_co_random_read(void *opaque) | |
235 | +{ | |
236 | + assert(opaque); | |
237 | + TestCB *cb = (TestCB *)opaque; | |
238 | + int64_t sectors = bdrv_getlength(cb->bs)/BDRV_SECTOR_SIZE - 1; | |
239 | + unsigned char buf[512]; | |
240 | + | |
241 | + while (1) { | |
242 | + test_co_yield(); | |
243 | + if (request_term) { | |
244 | + DPRINTF("finish run_co_random_read\n"); | |
245 | + break; | |
246 | + } | |
247 | + int64_t s = (rand()*sectors)/RAND_MAX; | |
248 | + read_sec(cb->bs, s*BDRV_SECTOR_SIZE, buf); | |
249 | + } | |
250 | + | |
251 | + cb->finished = true; | |
252 | +} | |
253 | + | |
254 | +static void coroutine_fn run_co_random_write(void *opaque) | |
255 | +{ | |
256 | + assert(opaque); | |
257 | + TestCB *cb = (TestCB *)opaque; | |
258 | + int64_t sectors = bdrv_getlength(cb->bs)/BDRV_SECTOR_SIZE; | |
259 | + | |
260 | + while (1) { | |
261 | + test_co_yield(); | |
262 | + if (request_term) { | |
263 | + DPRINTF("finish run_co_random_write\n"); | |
264 | + break; | |
265 | + } | |
266 | + int64_t s = (rand()*sectors)/RAND_MAX; | |
267 | + write_sec_pattern_cd(cb->bs, s*BDRV_SECTOR_SIZE); | |
268 | + } | |
269 | + | |
270 | + cb->finished = true; | |
271 | +} | |
272 | + | |
273 | +static void fill_test_sector(void *buf, size_t sector_num) | |
274 | +{ | |
275 | + int64_t *i64buf = (int64_t *)buf; | |
276 | + int i; | |
277 | + | |
278 | + int data = sector_num; | |
279 | + if (sector_num >= 8 && sector_num < 8*(2*16+2)) { | |
280 | + data = 0; /* add zero region for testing */ | |
281 | + } | |
282 | + | |
283 | + for (i = 0; i < (512/sizeof(int64_t)); i++) { | |
284 | + i64buf[i] = data; | |
285 | + } | |
286 | +} | |
287 | + | |
288 | +static void verify_archive(const char *archive, size_t size) | |
289 | +{ | |
290 | + Error *errp = NULL; | |
291 | + | |
292 | + VmaReader *vmar = vma_reader_create(archive, &errp); | |
293 | + | |
294 | + if (!vmar) { | |
295 | + g_error("%s", error_get_pretty(errp)); | |
296 | + } | |
297 | + | |
298 | + VmaDeviceInfo *di = vma_reader_get_device_info(vmar, 1); | |
299 | + if (!di || strcmp((char *)di->devname, "hda") || di->size != size) { | |
300 | + g_error("got wrong device info"); | |
301 | + } | |
302 | + | |
303 | + unlink(TEST_IMG_RESTORE_NAME); | |
304 | + | |
305 | + int flags = BDRV_O_NATIVE_AIO|BDRV_O_RDWR|BDRV_O_CACHE_WB; | |
306 | + | |
307 | + if (bdrv_img_create(TEST_IMG_RESTORE_NAME, "raw", NULL, NULL, NULL, | |
308 | + size, flags)) { | |
309 | + g_error("can't create file %s", TEST_IMG_RESTORE_NAME); | |
310 | + } | |
311 | + | |
312 | + BlockDriverState *bs = NULL; | |
313 | + if (bdrv_file_open(&bs, TEST_IMG_RESTORE_NAME, flags)) { | |
314 | + g_error("can't open file %s", TEST_IMG_RESTORE_NAME); | |
315 | + } | |
316 | + if (vma_reader_register_bs(vmar, 1, bs, false, &errp) < 0) { | |
317 | + g_error("%s", error_get_pretty(errp)); | |
318 | + } | |
319 | + | |
320 | + if (vma_reader_restore(vmar, -1, false, &errp) < 0) { | |
321 | + g_error("restore failed - %s", error_get_pretty(errp)); | |
322 | + } | |
323 | + | |
324 | + size_t i; | |
325 | + size_t sectors = size/BDRV_SECTOR_SIZE; | |
326 | + int64_t buf[512/sizeof(int64_t)]; | |
327 | + int64_t buf2[512/sizeof(int64_t)]; | |
328 | + | |
329 | + for (i = 0; i < sectors; i++) { | |
330 | + if (bdrv_read(bs, i, (uint8_t *)buf, 1) != 0) { | |
331 | + g_error("bdrv_read failed"); | |
332 | + } | |
333 | + fill_test_sector(buf2, i); | |
334 | + if (bcmp(buf, buf2, sizeof(buf))) { | |
335 | + g_error("data is different at sector %zd", i); | |
336 | + } | |
337 | + } | |
338 | + | |
339 | + vma_reader_destroy(vmar); | |
340 | + | |
341 | + unlink(TEST_IMG_RESTORE_NAME); | |
342 | +} | |
343 | + | |
344 | +static void prepare_vm_image(const char *filename, size_t sectors) | |
345 | +{ | |
346 | + int fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, 0644); | |
347 | + if (fd < 0) { | |
348 | + g_error("can't open file %s\n", filename); | |
349 | + } | |
350 | + | |
351 | + size_t i; | |
352 | + int64_t buf[512/sizeof(int64_t)]; | |
353 | + | |
354 | + for (i = 0; i < sectors; i++) { | |
355 | + fill_test_sector(buf, i); | |
356 | + | |
357 | + int res = 0; | |
358 | + while (1) { | |
359 | + res = write(fd, buf, sizeof(buf)); | |
360 | + if (!(res < 0 && errno == EINTR)) { | |
361 | + break; | |
362 | + } | |
363 | + } | |
364 | + if (res != sizeof(buf)) { | |
365 | + g_error("can't initialize file %s - %s %d\n", | |
366 | + filename, strerror(errno), res); | |
367 | + } | |
368 | + } | |
369 | + | |
370 | + if (close(fd) != 0) { | |
371 | + g_error("close failed"); | |
372 | + } | |
373 | +} | |
374 | + | |
375 | +static GList *simple_test(BlockDriverState *bs) | |
376 | +{ | |
377 | + GList *cb_list = NULL; | |
378 | + | |
379 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_test1)); | |
380 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_test2)); | |
381 | + | |
382 | + return cb_list; | |
383 | +} | |
384 | + | |
385 | +static GList *random_read_write_test(BlockDriverState *bs) | |
386 | +{ | |
387 | + GList *cb_list = NULL; | |
388 | + | |
389 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_read)); | |
390 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_read)); | |
391 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_write)); | |
392 | + cb_list = g_list_append(cb_list, enter_test_co(bs, run_co_random_write)); | |
393 | + | |
394 | + return cb_list; | |
395 | +} | |
396 | + | |
397 | +static void backup_test(const char *testname, int64_t speed, | |
398 | + GList *(*start_test_cb)(BlockDriverState *bs)) | |
399 | +{ | |
400 | + BlockDriverState *bs = bdrv_new("hda"); | |
401 | + | |
402 | + static int test_counter; | |
403 | + | |
404 | + test_counter++; | |
405 | + | |
406 | + printf("starting test #%d '%s'\n", test_counter, testname); | |
407 | + | |
408 | + const char *filename = TEST_IMG_NAME; | |
409 | + | |
410 | + prepare_vm_image(TEST_IMG_NAME, TEST_IMG_SIZE/BDRV_SECTOR_SIZE); | |
411 | + | |
412 | + int flags = BDRV_O_NATIVE_AIO|BDRV_O_RDWR|BDRV_O_CACHE_WB; | |
413 | + | |
414 | + if (bdrv_open(bs, filename, flags, NULL) < 0) { | |
415 | + g_error("can't open device %s\n", filename); | |
416 | + } | |
417 | + | |
418 | + Error *err = NULL; | |
419 | + uuid_t uuid; | |
420 | + uuid_generate(uuid); | |
421 | + | |
422 | + unlink(TEST_VMA_NAME); | |
423 | + | |
424 | + VmaWriter *vmaw = vma_writer_create(TEST_VMA_NAME, uuid, speed, &err); | |
425 | + if (!vmaw) { | |
426 | + g_error("%s", error_get_pretty(err)); | |
427 | + } | |
428 | + | |
429 | + BackupCB bcb; | |
430 | + bcb.vmaw = vmaw; | |
431 | + bcb.dev_id = vma_writer_register_stream(vmaw, bdrv_get_device_name(bs), | |
432 | + bdrv_getlength(bs)); | |
433 | + if (backup_job_start(bs, backup_dump_cb, backup_complete_cb, &bcb) < 0) { | |
434 | + g_error("backup_job_start failed"); | |
435 | + } | |
436 | + | |
437 | + request_term = false; | |
438 | + | |
439 | + GList *cb_list = start_test_cb(bs); | |
440 | + | |
441 | + while (1) { | |
442 | + main_loop_wait(false); | |
443 | + | |
444 | + VmaStatus vmastat; | |
445 | + vma_writer_get_status(vmaw, &vmastat); | |
446 | + if (vmastat.closed) { | |
447 | + break; | |
448 | + } | |
449 | + } | |
450 | + | |
451 | + request_term = true; | |
452 | + | |
453 | + while (1) { | |
454 | + GList *l = cb_list; | |
455 | + bool active = 0; | |
456 | + while (l && l->data) { | |
457 | + TestCB *cb = (TestCB *)l->data; | |
458 | + l = g_list_next(l); | |
459 | + if (!cb->finished) { | |
460 | + active = true; | |
461 | + break; | |
462 | + } | |
463 | + } | |
464 | + if (!active) { | |
465 | + DPRINTF("All test coroutines finished\n"); | |
466 | + break; | |
467 | + } | |
468 | + main_loop_wait(false); | |
469 | + } | |
470 | + | |
471 | + /* Make sure all outstanding requests complete */ | |
472 | + bdrv_drain_all(); | |
473 | + | |
474 | + VmaStatus vmastat; | |
475 | + vma_writer_get_status(vmaw, &vmastat); | |
476 | + DPRINTF("statistic %zd %zd\n", vmastat.stream_info[1].size, | |
477 | + vmastat.stream_info[1].transferred); | |
478 | + assert(vmastat.stream_info[1].size == vmastat.stream_info[1].transferred); | |
479 | + | |
480 | + vma_writer_destroy(vmaw); | |
481 | + | |
482 | + bdrv_delete(bs); | |
483 | + | |
484 | + /* start verification */ | |
485 | + verify_archive(TEST_VMA_NAME, TEST_IMG_SIZE); | |
486 | + | |
487 | + bdrv_close_all(); | |
488 | + | |
489 | + unlink(TEST_IMG_NAME); | |
490 | + unlink(TEST_VMA_NAME); | |
491 | + | |
492 | + printf("finish test #%d '%s' OK\n", test_counter, testname); | |
493 | +} | |
494 | + | |
495 | +static void help(void) | |
496 | +{ | |
497 | + const char *help_msg = | |
498 | + "usage: backup-test [options]\n" | |
499 | + "\n" | |
500 | + "backup-test run default regression test (fast)\n" | |
501 | + "backup-test -l run long running test loop (endless)\n" | |
502 | + "\n" | |
503 | + "use option -d to turn on verbose debug output\n" | |
504 | + ; | |
505 | + | |
506 | + printf("%s", help_msg); | |
507 | + exit(1); | |
508 | +} | |
509 | + | |
510 | +int main(int argc, char **argv) | |
511 | +{ | |
512 | + int c; | |
513 | + | |
514 | + for (;;) { | |
515 | + c = getopt(argc, argv, "hdl"); | |
516 | + if (c == -1) { | |
517 | + break; | |
518 | + } | |
519 | + switch (c) { | |
520 | + case '?': | |
521 | + case 'h': | |
522 | + help(); | |
523 | + break; | |
524 | + case 'd': | |
525 | + opt_debug = 1; | |
526 | + break; | |
527 | + case 'l': | |
528 | + opt_loop = 1; | |
529 | + break; | |
530 | + default: | |
531 | + g_assert_not_reached(); | |
532 | + } | |
533 | + } | |
534 | + | |
535 | + memset(buf_sec_pattern_cd, 0xcd, sizeof(buf_sec_pattern_cd)); | |
536 | + memset(buf_sec_pattern_32, 0x32, sizeof(buf_sec_pattern_32)); | |
537 | + | |
538 | + srand(1234); | |
539 | + | |
540 | + /* ignore SIGPIPE */ | |
541 | + struct sigaction act; | |
542 | + sigfillset(&act.sa_mask); | |
543 | + act.sa_flags = 0; | |
544 | + act.sa_handler = SIG_IGN; | |
545 | + sigaction(SIGPIPE, &act, NULL); | |
546 | + | |
547 | + qemu_init_main_loop(); | |
548 | + | |
549 | + bdrv_init(); | |
550 | + | |
551 | + if (opt_loop) { /* endless test loop */ | |
552 | + while (1) { | |
553 | + RUN_TEST(random_read_write_test, 0); | |
554 | + } | |
555 | + return 0; | |
556 | + } | |
557 | + | |
558 | + if (opt_debug) { /* run simple test (rate limited) */ | |
559 | + RUN_TEST(simple_test, 1024*1024); | |
560 | + return 0; | |
561 | + } | |
562 | + | |
563 | + /* run default regression tests at full speed */ | |
564 | + | |
565 | + RUN_TEST(simple_test, 0); | |
566 | + RUN_TEST(random_read_write_test, 0); | |
567 | + | |
568 | + return 0; | |
569 | +} | |
570 | -- | |
571 | 1.7.2.5 | |
572 |