#define TEST_IMAGE "testimg"
#define TEST_POOL "librbdtest"
#define TEST_SNAP "testsnap"
-#define TEST_IO_SIZE 513
+#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)
void test_resize_and_stat(rbd_image_t image, size_t size)
{
rbd_image_info_t info;
+ int r;
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);
printf("read completion cb called!\n");
}
-void aio_write_test_data(rbd_image_t image, const char *test_data, off_t off)
+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, strlen(test_data), test_data, comp);
+ 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);
rbd_aio_release(comp);
}
-void write_test_data(rbd_image_t image, const char *test_data, off_t off)
+void write_test_data(rbd_image_t image, const char *test_data, uint64_t off, size_t len)
{
- int written;
- size_t len = strlen(test_data);
- while (len > 0) {
- written = rbd_write(image, off, len, test_data);
- assert(written >= 0);
- len -= written;
- off += written;
- printf("wrote: %u\n", (unsigned int) written);
- }
+ ssize_t written;
+ written = rbd_write(image, off, len, test_data);
+ printf("wrote: %d\n", written);
+ assert(written == len);
}
-void aio_read_test_data(rbd_image_t image, const char *expected, off_t off)
+void aio_read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len)
{
rbd_completion_t comp;
- char result[TEST_IO_SIZE];
+ char *result;
+ assert((result = malloc(sizeof(result) * (len + 1))) != 0);
+
rbd_aio_create_completion(NULL, (rbd_callback_t) simple_read_cb, &comp);
printf("created completion\n");
- rbd_aio_read(image, off, strlen(expected), result, comp);
+ 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 == TEST_IO_SIZE - 1);
- assert(strncmp(expected, result, TEST_IO_SIZE) == 0);
- printf("finished read\n");
+ assert(r == 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, off_t off)
+void read_test_data(rbd_image_t image, const char *expected, uint64_t off, size_t len)
{
- int read, total_read = 0;
- size_t expected_len = strlen(expected);
- size_t len = expected_len;
- char result[TEST_IO_SIZE];
- char *buf = result;
- while (len > 0) {
- read = rbd_read(image, off + total_read, len, buf);
- assert(read >= 0);
- total_read += read;
- buf += read;
- len -= read;
- printf("read: %u\n", (unsigned int) read);
- }
+ ssize_t read;
+ char *result;
+ assert((result = malloc(sizeof(result) * (len + 1))) != 0);
+
+ read = rbd_read(image, off, len, result);
+ printf("read: %d\n", read);
+ assert(read == len);
+ result[len] = '\0';
printf("read: %s\nexpected: %s\n", result, expected);
- assert(memcmp(result, expected, expected_len) == 0);
+ 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];
+ char test_data[TEST_IO_SIZE + 1];
int i;
- srand(time(0));
- for (i = 0; i < TEST_IO_SIZE - 1; ++i) {
+ for (i = 0; i < TEST_IO_SIZE; ++i) {
test_data[i] = (char) (rand() % (126 - 33) + 33);
}
- test_data[TEST_IO_SIZE - 1] = '\0';
+ test_data[TEST_IO_SIZE] = '\0';
for (i = 0; i < 5; ++i)
- write_test_data(image, test_data, strlen(test_data) * 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, strlen(test_data) * 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, strlen(test_data) * 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, strlen(test_data) * i);
+ aio_read_test_data(image, test_data, TEST_IO_SIZE * i, TEST_IO_SIZE);
+}
+
+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';
+
+ 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);
}
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_read_file(cluster, NULL) == 0);
rados_reopen_log(cluster);
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);
- struct rados_pool_stat_t stats;
- rados_ioctx_pool_stat(io_ctx, &stats);
- test_ls(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);
+
rados_ioctx_destroy(io_ctx);
rados_shutdown(cluster);
+
return 0;
}