From cccdd43b38f027b9546917d0ee09e5242f0afd84 Mon Sep 17 00:00:00 2001 From: Colin Patrick McCabe Date: Wed, 6 Jul 2011 16:20:36 -0700 Subject: [PATCH] Add rados_open_pools_parallel test Also add rados_open_pools_parallel to .gitignore Signed-off-by: Colin McCabe --- src/.gitignore | 1 + src/Makefile.am | 11 +- src/test/system/rados_list_parallel.cc | 67 +--------- src/test/system/rados_open_pools_parallel.cc | 129 +++++++++++++++++++ src/test/system/st_rados_create_pool.cc | 94 ++++++++++++++ src/test/system/st_rados_create_pool.h | 42 ++++++ src/test/system/systest_runnable.h | 2 +- 7 files changed, 281 insertions(+), 65 deletions(-) create mode 100644 src/test/system/rados_open_pools_parallel.cc create mode 100644 src/test/system/st_rados_create_pool.cc create mode 100644 src/test/system/st_rados_create_pool.h diff --git a/src/.gitignore b/src/.gitignore index 60c39972c607c..17779dd7cee1c 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -89,3 +89,4 @@ ceph.conf .ceph_keyring massif.out.* rados_list_parallel +rados_open_pools_parallel diff --git a/src/Makefile.am b/src/Makefile.am index 4b836749b77b5..9c61de6a25008 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -383,10 +383,18 @@ libsystest_la_SOURCES = \ libsystest_la_LIBADD = libglobal.la noinst_LTLIBRARIES += libsystest.la -rados_list_parallel_SOURCES = test/system/rados_list_parallel.cc +rados_list_parallel_SOURCES = \ + test/system/rados_list_parallel.cc \ + test/system/st_rados_create_pool.cc rados_list_parallel_LDADD = libsystest.la librados.la bin_DEBUGPROGRAMS += rados_list_parallel +rados_open_pools_parallel_SOURCES = \ + test/system/rados_open_pools_parallel.cc \ + test/system/st_rados_create_pool.cc +rados_open_pools_parallel_LDADD = libsystest.la librados.la +bin_DEBUGPROGRAMS += rados_open_pools_parallel + ## unit tests # target to build but not run the unit tests @@ -1164,6 +1172,7 @@ noinst_HEADERS = \ global/pidfile.h\ common/sync_filesystem.h \ test/system/cross_process_sem.h \ + test/system/st_rados_create_pool.h \ test/system/systest_runnable.h \ test/system/systest_settings.h diff --git a/src/test/system/rados_list_parallel.cc b/src/test/system/rados_list_parallel.cc index 2823e8b0ee91c..9d3d22c85448b 100644 --- a/src/test/system/rados_list_parallel.cc +++ b/src/test/system/rados_list_parallel.cc @@ -12,9 +12,10 @@ * */ +#include "cross_process_sem.h" #include "include/rados/librados.h" +#include "st_rados_create_pool.h" #include "systest_runnable.h" -#include "cross_process_sem.h" #include #include @@ -31,71 +32,11 @@ using std::ostringstream; using std::string; using std::vector; -static const int RLP_NUM_OBJECTS = 50; //16384; -static const int RLP_OBJECT_SZ_MAX = 256; - -static std::string get_random_buf(void) -{ - ostringstream oss; - int size = rand() % RLP_OBJECT_SZ_MAX; // yep, it's not very random - for (int i = 0; i < size; ++i) { - oss << "."; - } - return oss.str(); -} +static const int RLP_NUM_OBJECTS = 50; static CrossProcessSem *pool_setup_sem = NULL; static CrossProcessSem *modify_sem = NULL; -class RadosCreateBigPoolR : public SysTestRunnable -{ -public: - RadosCreateBigPoolR(int argc, const char **argv) - : SysTestRunnable(argc, argv) - { - } - - ~RadosCreateBigPoolR() - { - } - - int run() - { - rados_t cl; - RETURN_IF_NONZERO(rados_create(&cl, NULL)); - rados_conf_parse_argv(cl, m_argc, m_argv); - RETURN_IF_NONZERO(rados_conf_read_file(cl, NULL)); - RETURN_IF_NONZERO(rados_connect(cl)); - int ret = rados_pool_delete(cl, "foo"); - if (!((ret == 0) || (ret == -ENOENT))) { - printf("%s: rados_pool_delete error %d\n", get_id_str(), ret); - return ret; - } - RETURN_IF_NONZERO(rados_pool_create(cl, "foo")); - rados_ioctx_t io_ctx; - RETURN_IF_NONZERO(rados_ioctx_create(cl, "foo", &io_ctx)); - - for (int i = 0; i < RLP_NUM_OBJECTS; ++i) { - char oid[128]; - snprintf(oid, sizeof(oid), "%d.obj", i); - std::string buf(get_random_buf()); - ret = rados_write(io_ctx, oid, buf.c_str(), buf.size(), 0); - if (ret < static_cast(buf.size())) { - printf("%s: rados_write error %d\n", get_id_str(), ret); - return ret; - } - if (((i % 25) == 0) || (i == RLP_NUM_OBJECTS - 1)) { - printf("%s: created object %d...\n", get_id_str(), i); - } - } - printf("%s: finishing.\n", get_id_str()); - pool_setup_sem->post(); - pool_setup_sem->post(); - rados_ioctx_destroy(cl); - return 0; - } -}; - /* Rados doesn't have read-after-write consistency for pool creation events. * What this means is that even after the first process has created the pool, * we may have to wait a while before we're able to see it. We will be able to @@ -239,7 +180,7 @@ int main(int argc, const char **argv) RETURN_IF_NONZERO(CrossProcessSem::create(0, &pool_setup_sem)); RETURN_IF_NONZERO(CrossProcessSem::create(1, &modify_sem)); - RadosCreateBigPoolR r1(argc, argv); + StRadosCreatePool r1(argc, argv, pool_setup_sem, NULL, RLP_NUM_OBJECTS); RadosListObjectsR r2(argc, argv); RadosModifyPoolR r3(argc, argv); vector < SysTestRunnable* > vec; diff --git a/src/test/system/rados_open_pools_parallel.cc b/src/test/system/rados_open_pools_parallel.cc new file mode 100644 index 0000000000000..b8eb53f662e8f --- /dev/null +++ b/src/test/system/rados_open_pools_parallel.cc @@ -0,0 +1,129 @@ + +// -*- 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 Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +* +*/ + +#include "cross_process_sem.h" +#include "include/rados/librados.h" +#include "st_rados_create_pool.h" +#include "systest_runnable.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using std::ostringstream; +using std::string; +using std::vector; + +/* + * rados_open_pools_parallel + * + * This tests creating a pool in one Runnable, and then opening an io context + * based on that pool in another. + * + * EXPECT: * can't create the same pool twice + * * one Runnable can use the pool after the other one creates it + * + * DO NOT EXPECT * hangs, crashes + */ +class StRadosOpenPool : public SysTestRunnable +{ +public: + StRadosOpenPool(int argc, const char **argv, + CrossProcessSem *pool_setup_sem, CrossProcessSem *open_pool_sem) + : SysTestRunnable(argc, argv), + m_pool_setup_sem(pool_setup_sem), m_open_pool_sem(open_pool_sem) + { + } + + ~StRadosOpenPool() + { + } + + int run() + { + rados_t cl; + RETURN_IF_NONZERO(rados_create(&cl, NULL)); + rados_conf_parse_argv(cl, m_argc, m_argv); + RETURN_IF_NONZERO(rados_conf_read_file(cl, NULL)); + RETURN_IF_NONZERO(rados_connect(cl)); + if (m_pool_setup_sem) + m_pool_setup_sem->wait(); + + printf("%s: rados_pool_create.\n", get_id_str()); + RETURN_IF_NOT_VAL(-EEXIST, rados_pool_create(cl, "foo")); + rados_ioctx_t io_ctx; + printf("%s: rados_ioctx_create.\n", get_id_str()); + RETURN_IF_NOT_VAL(0, rados_ioctx_create(cl, "foo", &io_ctx)); + if (m_open_pool_sem) + m_open_pool_sem->post(); + rados_ioctx_destroy(io_ctx); + rados_shutdown(cl); + return 0; + } + +private: + CrossProcessSem *m_pool_setup_sem; + CrossProcessSem *m_open_pool_sem; +}; + +const char *get_id_str() +{ + return "main"; +} + +int main(int argc, const char **argv) +{ + // first test: create a pool, shut down the client, access that + // pool in a different process. + CrossProcessSem *pool_setup_sem = NULL; + RETURN_IF_NONZERO(CrossProcessSem::create(0, &pool_setup_sem)); + StRadosCreatePool r1(argc, argv, pool_setup_sem, NULL, 50); + StRadosOpenPool r2(argc, argv, pool_setup_sem, NULL); + vector < SysTestRunnable* > vec; + vec.push_back(&r1); + vec.push_back(&r2); + std::string error = SysTestRunnable::run_until_finished(vec); + if (!error.empty()) { + printf("test1: got error: %s\n", error.c_str()); + return EXIT_FAILURE; + } + + // second test: create a pool, access that + // pool in a different process, THEN shut down the first client. + CrossProcessSem *pool_setup_sem2 = NULL; + RETURN_IF_NONZERO(CrossProcessSem::create(0, &pool_setup_sem2)); + CrossProcessSem *open_pool_sem2 = NULL; + RETURN_IF_NONZERO(CrossProcessSem::create(0, &open_pool_sem2)); + StRadosCreatePool r3(argc, argv, pool_setup_sem2, open_pool_sem2, 50); + StRadosOpenPool r4(argc, argv, pool_setup_sem2, open_pool_sem2); + vector < SysTestRunnable* > vec2; + vec2.push_back(&r3); + vec2.push_back(&r4); + error = SysTestRunnable::run_until_finished(vec2); + if (!error.empty()) { + printf("test2: got error: %s\n", error.c_str()); + return EXIT_FAILURE; + } + + printf("******* SUCCESS **********\n"); + return EXIT_SUCCESS; +} diff --git a/src/test/system/st_rados_create_pool.cc b/src/test/system/st_rados_create_pool.cc new file mode 100644 index 0000000000000..29be91eeb568d --- /dev/null +++ b/src/test/system/st_rados_create_pool.cc @@ -0,0 +1,94 @@ +// -*- 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 Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +* +*/ + +#include "cross_process_sem.h" +#include "include/rados/librados.h" +#include "st_rados_create_pool.h" +#include "systest_runnable.h" + +#include +#include +#include +#include +#include +#include + +using std::ostringstream; + +static const int RLP_OBJECT_SZ_MAX = 256; + +static std::string get_random_buf(void) +{ + ostringstream oss; + int size = rand() % RLP_OBJECT_SZ_MAX; // yep, it's not very random + for (int i = 0; i < size; ++i) { + oss << "."; + } + return oss.str(); +} + +StRadosCreatePool:: +StRadosCreatePool(int argc, const char **argv, + CrossProcessSem *pool_setup_sem, CrossProcessSem *close_create_pool, + int num_objects) + : SysTestRunnable(argc, argv), + m_pool_setup_sem(pool_setup_sem), m_close_create_pool(close_create_pool), + m_num_objects(num_objects) +{ +} + +StRadosCreatePool:: +~StRadosCreatePool() +{ +} + +int StRadosCreatePool:: +run() +{ + rados_t cl; + RETURN_IF_NONZERO(rados_create(&cl, NULL)); + rados_conf_parse_argv(cl, m_argc, m_argv); + RETURN_IF_NONZERO(rados_conf_read_file(cl, NULL)); + RETURN_IF_NONZERO(rados_connect(cl)); + int ret = rados_pool_delete(cl, "foo"); + if (!((ret == 0) || (ret == -ENOENT))) { + printf("%s: rados_pool_delete error %d\n", get_id_str(), ret); + return ret; + } + RETURN_IF_NONZERO(rados_pool_create(cl, "foo")); + rados_ioctx_t io_ctx; + RETURN_IF_NONZERO(rados_ioctx_create(cl, "foo", &io_ctx)); + + for (int i = 0; i < m_num_objects; ++i) { + char oid[128]; + snprintf(oid, sizeof(oid), "%d.obj", i); + std::string buf(get_random_buf()); + ret = rados_write(io_ctx, oid, buf.c_str(), buf.size(), 0); + if (ret < static_cast(buf.size())) { + printf("%s: rados_write error %d\n", get_id_str(), ret); + return ret; + } + if (((i % 25) == 0) || (i == m_num_objects - 1)) { + printf("%s: created object %d...\n", get_id_str(), i); + } + } + printf("%s: finishing.\n", get_id_str()); + if (m_pool_setup_sem) + m_pool_setup_sem->post(); + if (m_close_create_pool) + m_close_create_pool->wait(); + rados_ioctx_destroy(io_ctx); + rados_shutdown(cl); + return 0; +} diff --git a/src/test/system/st_rados_create_pool.h b/src/test/system/st_rados_create_pool.h new file mode 100644 index 0000000000000..55f06e037d89e --- /dev/null +++ b/src/test/system/st_rados_create_pool.h @@ -0,0 +1,42 @@ +// -*- 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 Lesser General Public +* License version 2.1, as published by the Free Software +* Foundation. See file COPYING. +* +*/ + +#ifndef TEST_SYSTEM_ST_RADOS_CREATE_POOL_H +#define TEST_SYSTEM_ST_RADOS_CREATE_POOL_H + +#include "systest_runnable.h" + +class CrossProcessSem; + +/* + * st_rados_create_pool + * + * Creates a pool and populates it with some objects. + * Then, calls pool_setup_sem->post() + */ +class StRadosCreatePool : public SysTestRunnable +{ +public: + StRadosCreatePool(int argc, const char **argv, + CrossProcessSem *pool_setup_sem, CrossProcessSem *close_create_pool_sem, + int num_objects); + ~StRadosCreatePool(); + virtual int run(); +private: + CrossProcessSem *m_pool_setup_sem; + CrossProcessSem *m_close_create_pool; + int m_num_objects; +}; + +#endif diff --git a/src/test/system/systest_runnable.h b/src/test/system/systest_runnable.h index 53dc8cef4d900..8962152c1205b 100644 --- a/src/test/system/systest_runnable.h +++ b/src/test/system/systest_runnable.h @@ -24,7 +24,7 @@ do {\ int _rinv_ret = expr;\ if (_rinv_ret != expected) {\ - printf("%s: file %s, line %d: expected %d, got %d",\ + printf("%s: file %s, line %d: expected %d, got %d\n",\ get_id_str(), __FILE__, __LINE__, expected, _rinv_ret);\ return _rinv_ret;\ }\ -- 2.39.5