From: Sage Weil Date: Mon, 12 Sep 2011 04:35:21 +0000 (-0700) Subject: librbd: convert C tests to gtest X-Git-Tag: v0.35~33 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=e2ec946858b26788595b39e9da9dcc6ce9c78f73;p=ceph.git librbd: convert C tests to gtest Signed-off-by: Sage Weil --- diff --git a/src/Makefile.am b/src/Makefile.am index cf561ddc2c81..a89304964fd6 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -294,9 +294,6 @@ rbd_CXXFLAGS = ${AM_CXXFLAGS} rbd_LDADD = libglobal.la librbd.la librados.la -lpthread -lm -lkeyutils $(CRYPTO_LIBS) $(EXTRALIBS) bin_PROGRAMS += rbd -testlibrbd_SOURCES = testlibrbd.c -testlibrbd_LDADD = librbd.la librados.la -lpthread -lm \ - $(CRYPTO_LIBS) $(EXTRALIBS) testlibrbdpp_SOURCES = testlibrbdpp.cc testlibrbdpp_LDADD = librbd.la librados.la -lpthread -lm \ $(CRYPTO_LIBS) $(EXTRALIBS) @@ -579,6 +576,11 @@ unittest_librgw_CXXFLAGS = ${CRYPTO_CFLAGS} ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} check_PROGRAMS += unittest_librgw endif +test_librbd_SOURCES = test/test_librbd.cc +test_librbd_LDADD = librbd.la ${UNITTEST_STATIC_LDADD} +test_librbd_CXXFLAGS = ${AM_CXXFLAGS} ${UNITTEST_CXXFLAGS} +bin_DEBUGPROGRAMS += test_librbd + test_rados_api_io_SOURCES = test/rados-api/io.cc test/rados-api/test.cc test_rados_api_io_LDFLAGS = ${AM_LDFLAGS} test_rados_api_io_LDADD = librados.la ${UNITTEST_STATIC_LDADD} diff --git a/src/test/test_librbd.cc b/src/test/test_librbd.cc new file mode 100644 index 000000000000..43d78082bcac --- /dev/null +++ b/src/test/test_librbd.cc @@ -0,0 +1,484 @@ +// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2011 New Dream Network + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License version 2, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include "include/rados/librados.h" +#include "include/rbd/librbd.h" + +#include "gtest/gtest.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "rados-api/test.cc" + +TEST(LibRBD, CreateAndStat) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + rbd_image_info_t info; + rbd_image_t image; + int order = 0; + const char *name = "testimg"; + uint64_t size = 2 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, size, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL)); + ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info))); + printf("image has size %llu and order %d\n", (unsigned long long) info.size, info.order); + ASSERT_EQ(info.size, size); + ASSERT_EQ(info.order, order); + ASSERT_EQ(0, rbd_close(image)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + +TEST(LibRBD, ResizeAndStat) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + rbd_image_info_t info; + rbd_image_t image; + int order = 0; + const char *name = "testimg"; + uint64_t size = 2 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, size, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL)); + + ASSERT_EQ(0, rbd_resize(image, size * 4)); + ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info))); + ASSERT_EQ(info.size, size * 4); + + ASSERT_EQ(0, rbd_resize(image, size / 2)); + ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info))); + ASSERT_EQ(info.size, size / 2); + + ASSERT_EQ(0, rbd_close(image)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + + +int test_ls(rados_ioctx_t io_ctx, size_t num_expected, ...) +{ + int num_images, i, j; + char *expected, *names, *cur_name; + va_list ap; + size_t max_size = 1024; + + names = (char *) malloc(sizeof(char *) * 1024); + int len = rbd_list(io_ctx, names, &max_size); + + for (i = 0, num_images = 0, cur_name = names; cur_name < names + len; i++) { + printf("image: %s\n", cur_name); + cur_name += strlen(cur_name) + 1; + num_images++; + } + + va_start(ap, num_expected); + for (i = num_expected; i > 0; i--) { + expected = va_arg(ap, char *); + printf("expected = %s\n", expected); + int found = 0; + for (j = 0, cur_name = names; j < num_images; j++) { + if (cur_name[0] == '_') { + cur_name += strlen(cur_name) + 1; + continue; + } + if (strcmp(cur_name, expected) == 0) { + printf("found %s\n", cur_name); + cur_name[0] = '_'; + found = 1; + break; + } + } + assert(found); + } + va_end(ap); + + for (i = 0, cur_name = names; cur_name < names + len; i++) { + assert(cur_name[0] == '_'); + cur_name += strlen(cur_name) + 1; + } + free(names); + + return num_images; +} + +TEST(LibRBD, TestCreateLsDelete) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + int order = 0; + const char *name = "testimg"; + const char *name2 = "testimg2"; + uint64_t size = 2 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, size, &order)); + ASSERT_EQ(1, test_ls(ioctx, 1, name)); + ASSERT_EQ(0, rbd_create(ioctx, name2, size, &order)); + ASSERT_EQ(2, test_ls(ioctx, 2, name, name2)); + ASSERT_EQ(0, rbd_remove(ioctx, name)); + ASSERT_EQ(1, test_ls(ioctx, 1, name2)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + + +static int print_progress_percent(uint64_t offset, uint64_t src_size, + void *data) +{ + float percent = ((float)offset * 100) / src_size; + printf("%3.2f%% done\n", percent); + return 0; +} + +TEST(LibRBD, TestCopy) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + rbd_image_t image; + int order = 0; + const char *name = "testimg"; + const char *name2 = "testimg2"; + const char *name3 = "testimg3"; + + uint64_t size = 2 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, size, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL)); + ASSERT_EQ(1, test_ls(ioctx, 1, name)); + ASSERT_LT(0, rbd_copy(image, ioctx, name2)); + ASSERT_EQ(2, test_ls(ioctx, 2, name, name2)); + ASSERT_LT(0, rbd_copy_with_progress(image, ioctx, name3, print_progress_percent, NULL)); + ASSERT_EQ(3, test_ls(ioctx, 3, name, name2, name3)); + + ASSERT_EQ(0, rbd_close(image)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + +int test_ls_snaps(rbd_image_t image, int num_expected, ...) +{ + rbd_snap_info_t *snaps; + int num_snaps, i, j, expected_size, max_size = 10; + char *expected; + va_list ap; + snaps = (rbd_snap_info_t *) malloc(sizeof(rbd_snap_info_t *) * 10); + num_snaps = rbd_snap_list(image, snaps, &max_size); + printf("num snaps is: %d\nexpected: %d\n", num_snaps, num_expected); + + for (i = 0; i < num_snaps; i++) { + printf("snap: %s\n", snaps[i].name); + } + + va_start(ap, num_expected); + for (i = num_expected; i > 0; i--) { + expected = va_arg(ap, char *); + expected_size = va_arg(ap, int); + int found = 0; + for (j = 0; j < num_snaps; j++) { + if (snaps[j].name == NULL) + continue; + if (strcmp(snaps[j].name, expected) == 0) { + printf("found %s with size %llu\n", snaps[j].name, (unsigned long long) snaps[j].size); + assert((int)snaps[j].size == expected_size); + free((void *) snaps[j].name); + snaps[j].name = NULL; + found = 1; + break; + } + } + assert(found); + } + va_end(ap); + + for (i = 0; i < num_snaps; i++) { + assert(snaps[i].name == NULL); + } + free(snaps); + + return num_snaps; +} + +TEST(LibRBD, TestCreateLsDeleteSnap) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + rbd_image_t image; + int order = 0; + const char *name = "testimg"; + uint64_t size = 2 << 20; + uint64_t size2 = 4 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, size, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL)); + + ASSERT_EQ(0, rbd_snap_create(image, "snap1")); + ASSERT_EQ(1, test_ls_snaps(image, 1, "snap1", size)); + ASSERT_EQ(0, rbd_resize(image, size2)); + ASSERT_EQ(0, rbd_snap_create(image, "snap2")); + ASSERT_EQ(2, test_ls_snaps(image, 2, "snap1", size, "snap2", size2)); + ASSERT_EQ(0, rbd_snap_remove(image, "snap1")); + ASSERT_EQ(1, test_ls_snaps(image, 1, "snap2", size2)); + ASSERT_EQ(0, rbd_snap_remove(image, "snap2")); + ASSERT_EQ(0, test_ls_snaps(image, 0)); + + ASSERT_EQ(0, rbd_close(image)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + + +#define TEST_IO_SIZE 512 +#define TEST_IO_TO_SNAP_SIZE 80 + +void simple_write_cb(rbd_completion_t cb, void *arg) +{ + printf("write completion cb called!\n"); +} + +void simple_read_cb(rbd_completion_t cb, void *arg) +{ + printf("read completion cb called!\n"); +} + +void aio_write_test_data(rbd_image_t image, const char *test_data, uint64_t off, size_t len) +{ + rbd_completion_t comp; + rbd_aio_create_completion(NULL, (rbd_callback_t) simple_write_cb, &comp); + printf("created completion\n"); + rbd_aio_write(image, off, len, test_data, comp); + printf("started write\n"); + rbd_aio_wait_for_complete(comp); + int r = rbd_aio_get_return_value(comp); + printf("return value is: %d\n", r); + assert(r == 0); + printf("finished write\n"); + rbd_aio_release(comp); +} + +void write_test_data(rbd_image_t image, const char *test_data, uint64_t off, size_t len) +{ + ssize_t written; + written = rbd_write(image, off, len, test_data); + printf("wrote: %d\n", (int) written); + assert(written == (ssize_t)len); +} + +void aio_read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len) +{ + rbd_completion_t comp; + char *result = (char *)malloc(len + 1); + + assert(result); + rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp); + printf("created completion\n"); + rbd_aio_read(image, off, len, result, comp); + printf("started read\n"); + rbd_aio_wait_for_complete(comp); + int r = rbd_aio_get_return_value(comp); + printf("return value is: %d\n", r); + assert(r == (ssize_t)len); + rbd_aio_release(comp); + printf("read: %s\nexpected: %s\n", result, expected); + assert(memcmp(result, expected, len) == 0); + free(result); +} + +void read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len) +{ + ssize_t read; + char *result = (char *)malloc(len + 1); + + assert(result); + read = rbd_read(image, off, len, result); + printf("read: %d\n", (int) read); + assert(read == (ssize_t)len); + result[len] = '\0'; + printf("read: %s\nexpected: %s\n", result, expected); + assert(memcmp(result, expected, len) == 0); + free(result); +} + +TEST(LibRBD, TestIO) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + rbd_image_t image; + int order = 0; + const char *name = "testimg"; + uint64_t size = 2 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, size, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL)); + + char test_data[TEST_IO_SIZE + 1]; + int i; + + for (i = 0; i < TEST_IO_SIZE; ++i) { + test_data[i] = (char) (rand() % (126 - 33) + 33); + } + test_data[TEST_IO_SIZE] = '\0'; + + for (i = 0; i < 5; ++i) + write_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); + + for (i = 5; i < 10; ++i) + aio_write_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); + + for (i = 0; i < 5; ++i) + read_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); + + for (i = 5; i < 10; ++i) + aio_read_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); + + rbd_image_info_t info; + rbd_completion_t comp; + ASSERT_EQ(0, rbd_stat(image, &info, sizeof(info))); + ASSERT_EQ(-EINVAL, rbd_write(image, info.size, 1, test_data)); + ASSERT_EQ(-EINVAL, rbd_read(image, info.size, 1, test_data)); + rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp); + ASSERT_EQ(-EINVAL, rbd_aio_write(image, info.size, 1, test_data, comp)); + ASSERT_EQ(-EINVAL, rbd_aio_read(image, info.size, 1, test_data, comp)); + + ASSERT_EQ(0, rbd_close(image)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + +TEST(LibRBD, TestIOToSnapshot) +{ + rados_t cluster; + rados_ioctx_t ioctx; + std::string pool_name = get_temp_pool_name(); + ASSERT_EQ("", create_one_pool(pool_name, &cluster)); + rados_ioctx_create(cluster, pool_name.c_str(), &ioctx); + + rbd_image_t image; + int order = 0; + const char *name = "testimg"; + uint64_t isize = 2 << 20; + + ASSERT_EQ(0, rbd_create(ioctx, name, isize, &order)); + ASSERT_EQ(0, rbd_open(ioctx, name, &image, NULL)); + + int i, r; + rbd_image_t image_at_snap; + char orig_data[TEST_IO_TO_SNAP_SIZE + 1]; + char test_data[TEST_IO_TO_SNAP_SIZE + 1]; + + for (i = 0; i < TEST_IO_TO_SNAP_SIZE - 1; ++i) + test_data[i] = (char) (i + 48); + test_data[TEST_IO_TO_SNAP_SIZE] = '\0'; + orig_data[TEST_IO_TO_SNAP_SIZE] = '\0'; + + r = rbd_read(image, 0, TEST_IO_TO_SNAP_SIZE, orig_data); + ASSERT_EQ(r, TEST_IO_TO_SNAP_SIZE); + + ASSERT_EQ(0, test_ls_snaps(image, 0)); + ASSERT_EQ(0, rbd_snap_create(image, "orig")); + ASSERT_EQ(1, test_ls_snaps(image, 1, "orig", isize)); + read_test_data(image, orig_data, 0, TEST_IO_TO_SNAP_SIZE); + + printf("write test data!\n"); + write_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); + ASSERT_EQ(0, rbd_snap_create(image, "written")); + ASSERT_EQ(2, test_ls_snaps(image, 2, "orig", isize, "written", isize)); + + read_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); + + rbd_snap_set(image, "orig"); + read_test_data(image, orig_data, 0, TEST_IO_TO_SNAP_SIZE); + + rbd_snap_set(image, "written"); + read_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); + + rbd_snap_set(image, "orig"); + + r = rbd_write(image, 0, TEST_IO_TO_SNAP_SIZE, test_data); + printf("write to snapshot returned %d\n", r); + ASSERT_LT(r, 0); + printf("%s\n", strerror(-r)); + + read_test_data(image, orig_data, 0, TEST_IO_TO_SNAP_SIZE); + rbd_snap_set(image, "written"); + read_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); + + r = rbd_snap_rollback(image, "orig"); + printf("rbd_snap_rollback returned %d\n", r); + ASSERT_GE(r, 0); + + r = rbd_snap_set(image, NULL); + ASSERT_EQ(r, 0); + write_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); + + printf("opening testimg@orig\n"); + ASSERT_EQ(0, rbd_open(ioctx, name, &image_at_snap, "orig")); + read_test_data(image_at_snap, orig_data, 0, TEST_IO_TO_SNAP_SIZE); + r = rbd_write(image_at_snap, 0, TEST_IO_TO_SNAP_SIZE, test_data); + printf("write to snapshot returned %d\n", r); + ASSERT_LT(r, 0); + printf("%s\n", strerror(-r)); + ASSERT_EQ(0, rbd_close(image_at_snap)); + + ASSERT_EQ(2, test_ls_snaps(image, 2, "orig", isize, "written", isize)); + ASSERT_EQ(0, rbd_snap_remove(image, "written")); + ASSERT_EQ(1, test_ls_snaps(image, 1, "orig", isize)); + ASSERT_EQ(0, rbd_snap_remove(image, "orig")); + ASSERT_EQ(0, test_ls_snaps(image, 0)); + + ASSERT_EQ(0, rbd_close(image)); + + rados_ioctx_destroy(ioctx); + ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster)); +} + + diff --git a/src/testlibrbd.c b/src/testlibrbd.c deleted file mode 100644 index 5624ebb5d9f4..000000000000 --- a/src/testlibrbd.c +++ /dev/null @@ -1,421 +0,0 @@ -// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2011 New Dream Network - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License version 2, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#include "include/rados/librados.h" -#include "include/rbd/librbd.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define TEST_IMAGE "testimg" -#define TEST_IMAGE2 "testimg2" -#define TEST_POOL "librbdtest" -#define TEST_SNAP "testsnap" -#define TEST_IO_SIZE 512 -#define TEST_IO_TO_SNAP_SIZE 80 -#define MB_BYTES(mb) (mb << 20) - -void test_create_and_stat(rados_ioctx_t io_ctx, const char *name, size_t size) -{ - rbd_image_info_t info; - rbd_image_t image; - int order = 0; - assert(rbd_create(io_ctx, name, size, &order) == 0); - assert(rbd_open(io_ctx, name, &image, NULL) == 0); - assert(rbd_stat(image, &info, sizeof(info)) == 0); - printf("image has size %llu and order %d\n", (unsigned long long) info.size, info.order); - assert(info.size == size); - assert(info.order == order); - assert(rbd_close(image) == 0); -} - -void test_resize_and_stat(rbd_image_t image, size_t size) -{ - rbd_image_info_t info; - assert(rbd_resize(image, size) == 0); - assert(rbd_stat(image, &info, sizeof(info)) == 0); - printf("image has size %llu and order %d\n", (unsigned long long) info.size, info.order); - assert(info.size == size); -} - -void test_ls(rados_ioctx_t io_ctx, size_t num_expected, ...) -{ - int num_images, i, j; - char *expected, *names, *cur_name; - va_list ap; - size_t max_size = 1024; - names = (char *) malloc(sizeof(char *) * 1024); - num_images = rbd_list(io_ctx, names, &max_size); - printf("num images is: %d\nexpected: %d\n", num_images, (int)num_expected); - assert(num_images >= 0); - assert(num_images == (int)num_expected); - - for (i = 0, cur_name = names; i < num_images; i++) { - printf("image: %s\n", cur_name); - cur_name += strlen(cur_name) + 1; - } - - va_start(ap, num_expected); - for (i = num_expected; i > 0; i--) { - expected = va_arg(ap, char *); - printf("expected = %s\n", expected); - int found = 0; - for (j = 0, cur_name = names; j < num_images; j++) { - if (cur_name[0] == '_') { - cur_name += strlen(cur_name) + 1; - continue; - } - if (strcmp(cur_name, expected) == 0) { - printf("found %s\n", cur_name); - cur_name[0] = '_'; - found = 1; - break; - } - } - assert(found); - } - va_end(ap); - - for (i = 0, cur_name = names; i < num_images; i++) { - assert(cur_name[0] == '_'); - cur_name += strlen(cur_name) + 1; - } - free(names); -} - -void test_delete(rados_ioctx_t io_ctx, const char *name) -{ - assert(rbd_remove(io_ctx, name) == 0); -} - -void test_create_snap(rbd_image_t image, const char *name) -{ - assert(rbd_snap_create(image, name) == 0); -} - -void test_ls_snaps(rbd_image_t image, int num_expected, ...) -{ - rbd_snap_info_t *snaps; - int num_snaps, i, j, expected_size, max_size = 10; - char *expected; - va_list ap; - snaps = (rbd_snap_info_t *) malloc(sizeof(rbd_snap_info_t *) * 10); - num_snaps = rbd_snap_list(image, snaps, &max_size); - printf("num snaps is: %d\nexpected: %d\n", num_snaps, num_expected); - assert(num_snaps == num_expected); - - for (i = 0; i < num_snaps; i++) { - printf("snap: %s\n", snaps[i].name); - } - - va_start(ap, num_expected); - for (i = num_expected; i > 0; i--) { - expected = va_arg(ap, char *); - expected_size = va_arg(ap, int); - int found = 0; - for (j = 0; j < num_snaps; j++) { - if (snaps[j].name == NULL) - continue; - if (strcmp(snaps[j].name, expected) == 0) { - printf("found %s with size %llu\n", snaps[j].name, (unsigned long long) snaps[j].size); - assert((int)snaps[j].size == expected_size); - free((void *) snaps[j].name); - snaps[j].name = NULL; - found = 1; - break; - } - } - assert(found); - } - va_end(ap); - - for (i = 0; i < num_snaps; i++) { - assert(snaps[i].name == NULL); - } - free(snaps); -} - -void test_delete_snap(rbd_image_t image, const char *name) -{ - assert(rbd_snap_remove(image, name) == 0); -} - -void simple_write_cb(rbd_completion_t cb, void *arg) -{ - printf("write completion cb called!\n"); -} - -void simple_read_cb(rbd_completion_t cb, void *arg) -{ - printf("read completion cb called!\n"); -} - -void aio_write_test_data(rbd_image_t image, const char *test_data, uint64_t off, size_t len) -{ - rbd_completion_t comp; - rbd_aio_create_completion(NULL, (rbd_callback_t) simple_write_cb, &comp); - printf("created completion\n"); - rbd_aio_write(image, off, len, test_data, comp); - printf("started write\n"); - rbd_aio_wait_for_complete(comp); - int r = rbd_aio_get_return_value(comp); - printf("return value is: %d\n", r); - assert(r == 0); - printf("finished write\n"); - rbd_aio_release(comp); -} - -void write_test_data(rbd_image_t image, const char *test_data, uint64_t off, size_t len) -{ - ssize_t written; - written = rbd_write(image, off, len, test_data); - printf("wrote: %d\n", (int) written); - assert(written == (ssize_t)len); -} - -void aio_read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len) -{ - rbd_completion_t comp; - char *result = malloc(len + 1); - - assert(result); - rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp); - printf("created completion\n"); - rbd_aio_read(image, off, len, result, comp); - printf("started read\n"); - rbd_aio_wait_for_complete(comp); - int r = rbd_aio_get_return_value(comp); - printf("return value is: %d\n", r); - assert(r == (ssize_t)len); - rbd_aio_release(comp); - printf("read: %s\nexpected: %s\n", result, expected); - assert(memcmp(result, expected, len) == 0); - free(result); -} - -void read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len) -{ - ssize_t read; - char *result = malloc(len + 1); - - assert(result); - read = rbd_read(image, off, len, result); - printf("read: %d\n", (int) read); - assert(read == (ssize_t)len); - result[len] = '\0'; - printf("read: %s\nexpected: %s\n", result, expected); - assert(memcmp(result, expected, len) == 0); - free(result); -} - -void test_io(rados_ioctx_t io, rbd_image_t image) -{ - char test_data[TEST_IO_SIZE + 1]; - int i; - - for (i = 0; i < TEST_IO_SIZE; ++i) { - test_data[i] = (char) (rand() % (126 - 33) + 33); - } - test_data[TEST_IO_SIZE] = '\0'; - - for (i = 0; i < 5; ++i) - write_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); - - for (i = 5; i < 10; ++i) - aio_write_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); - - for (i = 0; i < 5; ++i) - read_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); - - for (i = 5; i < 10; ++i) - aio_read_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE); - - rbd_image_info_t info; - rbd_completion_t comp; - assert(rbd_stat(image, &info, sizeof(info)) == 0); - assert(rbd_write(image, info.size, 1, test_data) == -EINVAL); - assert(rbd_read(image, info.size, 1, test_data) == -EINVAL); - rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp); - assert(rbd_aio_write(image, info.size, 1, test_data, comp) == -EINVAL); - assert(rbd_aio_read(image, info.size, 1, test_data, comp) == -EINVAL); -} - -void test_io_to_snapshot(rados_ioctx_t io_ctx, rbd_image_t image, size_t isize) -{ - int i, r; - rbd_image_t image_at_snap; - char orig_data[TEST_IO_TO_SNAP_SIZE + 1]; - char test_data[TEST_IO_TO_SNAP_SIZE + 1]; - - for (i = 0; i < TEST_IO_TO_SNAP_SIZE - 1; ++i) - test_data[i] = (char) (i + 48); - test_data[TEST_IO_TO_SNAP_SIZE] = '\0'; - orig_data[TEST_IO_TO_SNAP_SIZE] = '\0'; - - r = rbd_read(image, 0, TEST_IO_TO_SNAP_SIZE, orig_data); - assert(r == TEST_IO_TO_SNAP_SIZE); - - test_ls_snaps(image, 0); - test_create_snap(image, "orig"); - test_ls_snaps(image, 1, "orig", isize); - read_test_data(image, orig_data, 0, TEST_IO_TO_SNAP_SIZE); - - printf("write test data!\n"); - write_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); - test_create_snap(image, "written"); - test_ls_snaps(image, 2, "orig", isize, "written", isize); - - read_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); - - rbd_snap_set(image, "orig"); - read_test_data(image, orig_data, 0, TEST_IO_TO_SNAP_SIZE); - - rbd_snap_set(image, "written"); - read_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); - - rbd_snap_set(image, "orig"); - - r = rbd_write(image, 0, TEST_IO_TO_SNAP_SIZE, test_data); - printf("write to snapshot returned %d\n", r); - assert(r < 0); - printf("%s\n", strerror(-r)); - - read_test_data(image, orig_data, 0, TEST_IO_TO_SNAP_SIZE); - rbd_snap_set(image, "written"); - read_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); - - r = rbd_snap_rollback(image, "orig"); - printf("rbd_snap_rollback returned %d\n", r); - assert(r >= 0); - - r = rbd_snap_set(image, NULL); - assert(r == 0); - write_test_data(image, test_data, 0, TEST_IO_TO_SNAP_SIZE); - - printf("opening testimg@orig\n"); - assert(rbd_open(io_ctx, TEST_IMAGE, &image_at_snap, "orig") >= 0); - read_test_data(image_at_snap, orig_data, 0, TEST_IO_TO_SNAP_SIZE); - r = rbd_write(image_at_snap, 0, TEST_IO_TO_SNAP_SIZE, test_data); - printf("write to snapshot returned %d\n", r); - assert(r < 0); - printf("%s\n", strerror(-r)); - assert(rbd_close(image_at_snap) == 0); - - test_ls_snaps(image, 2, "orig", isize, "written", isize); - test_delete_snap(image, "written"); - test_ls_snaps(image, 1, "orig", isize); - test_delete_snap(image, "orig"); - test_ls_snaps(image, 0); -} - -void test_rbd_copy(rados_ioctx_t io_ctx, rbd_image_t image) -{ - int ret; - ret = rbd_copy(image, io_ctx, TEST_IMAGE2); - if (ret < 0) { - fprintf(stderr, "rbd_copy returned %d!\n", ret); - abort(); - } -} - -static int print_progress_percent(uint64_t offset, uint64_t src_size, - void *data) -{ - float percent = ((float)offset * 100) / src_size; - printf("%3.2f%% done\n", percent); - return 0; -} - -void test_rbd_copy_with_progress(rados_ioctx_t io_ctx, rbd_image_t image) -{ - int ret; - ret = rbd_copy_with_progress(image, io_ctx, TEST_IMAGE2, - print_progress_percent, NULL); - if (ret < 0) { - fprintf(stderr, "rbd_copy_with_progress returned %d!\n", ret); - abort(); - } -} - -int main(int argc, const char **argv) -{ - rados_t cluster; - rados_ioctx_t io_ctx; - rbd_image_t image; - - srand(time(0)); - - assert(rados_create(&cluster, NULL) == 0); - assert(rados_conf_parse_argv(cluster, argc, argv) == 0); - assert(rados_conf_read_file(cluster, NULL) == 0); - assert(rados_connect(cluster) == 0); - - if (rados_pool_lookup(cluster, TEST_POOL) != -ENOENT) { - int r = rados_pool_delete(cluster, TEST_POOL); - printf("rados_pool_delete returned %d\n", r); - } - int r = rados_pool_create(cluster, TEST_POOL); - printf("rados_pool_create returned %d\n", r); - - assert(rados_ioctx_create(cluster, TEST_POOL, &io_ctx) == 0); - test_ls(io_ctx, 0); - - test_create_and_stat(io_ctx, TEST_IMAGE, MB_BYTES(1)); - assert(rbd_open(io_ctx, TEST_IMAGE, &image, NULL) == 0); - - test_ls(io_ctx, 1, TEST_IMAGE); - test_ls_snaps(image, 0); - - test_create_snap(image, TEST_SNAP); - test_ls_snaps(image, 1, TEST_SNAP, MB_BYTES(1)); - test_resize_and_stat(image, MB_BYTES(2)); - test_io(io_ctx, image); - - test_create_snap(image, TEST_SNAP "1"); - test_ls_snaps(image, 2, TEST_SNAP, MB_BYTES(1), TEST_SNAP "1", MB_BYTES(2)); - - test_delete_snap(image, TEST_SNAP); - test_ls_snaps(image, 1, TEST_SNAP "1", MB_BYTES(2)); - - test_delete_snap(image, TEST_SNAP "1"); - test_ls_snaps(image, 0); - - test_io_to_snapshot(io_ctx, image, MB_BYTES(2)); - assert(rbd_close(image) == 0); - - test_create_and_stat(io_ctx, TEST_IMAGE "1", MB_BYTES(2)); - test_ls(io_ctx, 2, TEST_IMAGE, TEST_IMAGE "1"); - - test_delete(io_ctx, TEST_IMAGE); - test_ls(io_ctx, 1, TEST_IMAGE "1"); - - test_delete(io_ctx, TEST_IMAGE "1"); - test_ls(io_ctx, 0); - - test_rbd_copy(io_ctx, image); - test_delete(io_ctx, TEST_IMAGE2); - test_rbd_copy_with_progress(io_ctx, image); - - rados_ioctx_destroy(io_ctx); - rados_shutdown(cluster); - - return 0; -}