test/librados: create general test case classes

Using a test case allows us to remove a boatload of boilerplate code
in all the tests, and focus them more on what they're actually
testing.

Create one for C tests, and one for C++ tests, with the same
functionality:

- create a pool when the test case starts
- between individual tests, create an ioctx and set its namespace uniquely
- delete objects from the default namespace during individual test teardown
- delete the pool only when the whole test case is finished

In gtest, a test case is the whole set of tests declared as part of
the same class using TEST_F(). Many tests create and delete individual
pools, but this is unnecessary for independent operation in most
cases, since we can use namespaces for that now. Since pool creation
and deletion dominates test run time, using these test cases makes
running many of the tests much faster.

Signed-off-by: Josh Durgin <josh.durgin@inktank.com>
This commit is contained in:
Josh Durgin 2014-02-03 09:01:20 -08:00
parent 6273ba4a9f
commit 9630f2f02d
3 changed files with 152 additions and 1 deletions

View File

@ -610,7 +610,8 @@ bin_DEBUGPROGRAMS += ceph_test_cls_rgw_opstate
endif # WITH_RADOSGW
libradostest_la_SOURCES = \
test/librados/test.cc
test/librados/test.cc \
test/librados/TestCase.cc
noinst_LTLIBRARIES += libradostest.la
libradostest_la_CXXFLAGS = $(UNITTEST_CXXFLAGS)
RADOS_TEST_LDADD = libradostest.la
@ -866,6 +867,7 @@ noinst_HEADERS += \
test/objectstore/workload_generator.h \
test/kv_store_bench.h \
test/librados/test.h \
test/librados/TestCase.h \
test/ObjectMap/KeyValueDBMemory.h \
test/omap_bench.h \
test/osdc/FakeWriteback.h \

View File

@ -0,0 +1,93 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#include <errno.h>
#include "test/librados/test.h"
#include "test/librados/TestCase.h"
using namespace librados;
std::string RadosTest::pool_name;
rados_t RadosTest::s_cluster = NULL;
void RadosTest::SetUpTestCase()
{
pool_name = get_temp_pool_name();
ASSERT_EQ("", create_one_pool(pool_name, &s_cluster));
}
void RadosTest::TearDownTestCase()
{
ASSERT_EQ(0, destroy_one_pool(pool_name, &s_cluster));
}
void RadosTest::SetUp()
{
cluster = RadosTest::s_cluster;
ASSERT_EQ(0, rados_ioctx_create(cluster, pool_name.c_str(), &ioctx));
std::string nspace = get_temp_pool_name();
rados_ioctx_set_namespace(ioctx, nspace.c_str());
}
void RadosTest::TearDown()
{
cleanup_default_namespace(ioctx);
rados_ioctx_destroy(ioctx);
}
void RadosTest::cleanup_default_namespace(rados_ioctx_t ioctx)
{
// remove all objects from the default namespace to avoid polluting
// other tests
rados_ioctx_set_namespace(ioctx, "");
rados_list_ctx_t list_ctx;
ASSERT_EQ(0, rados_objects_list_open(ioctx, &list_ctx));
int r;
const char *entry = NULL;
const char *key = NULL;
while ((r = rados_objects_list_next(list_ctx, &entry, &key)) != -ENOENT) {
ASSERT_EQ(0, r);
rados_ioctx_locator_set_key(ioctx, key);
ASSERT_EQ(0, rados_remove(ioctx, entry));
}
rados_objects_list_close(list_ctx);
}
std::string RadosTestPP::pool_name;
Rados RadosTestPP::s_cluster;
void RadosTestPP::SetUpTestCase()
{
pool_name = get_temp_pool_name();
ASSERT_EQ("", create_one_pool_pp(pool_name, s_cluster));
}
void RadosTestPP::TearDownTestCase()
{
ASSERT_EQ(0, destroy_one_pool_pp(pool_name, s_cluster));
}
void RadosTestPP::SetUp()
{
ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
ns = get_temp_pool_name();
ioctx.set_namespace(ns);
}
void RadosTestPP::TearDown()
{
cleanup_default_namespace(ioctx);
ioctx.close();
}
void RadosTestPP::cleanup_default_namespace(librados::IoCtx ioctx)
{
// remove all objects from the default namespace to avoid polluting
// other tests
ioctx.set_namespace("");
for (ObjectIterator it = ioctx.objects_begin();
it != ioctx.objects_end(); ++it) {
ioctx.locator_set_key(it->second);
ASSERT_EQ(0, ioctx.remove(it->first));
}
}

View File

@ -0,0 +1,56 @@
// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
// vim: ts=8 sw=2 smarttab
#ifndef CEPH_TEST_RADOS_TESTCASE_H
#define CEPH_TEST_RADOS_TESTCASE_H
#include "include/rados/librados.h"
#include "include/rados/librados.hpp"
#include "gtest/gtest.h"
#include <string>
/**
* These test cases create a temporary pool that lives as long as the
* test case. Each test within a test case gets a new ioctx set to a
* unique namespace within the pool.
*
* Since pool creation and deletion is slow, this allows many tests to
* run faster.
*/
class RadosTest : public ::testing::Test {
public:
RadosTest() {}
virtual ~RadosTest() {}
protected:
static void SetUpTestCase();
static void TearDownTestCase();
static void cleanup_default_namespace(rados_ioctx_t ioctx);
static rados_t s_cluster;
static std::string pool_name;
virtual void SetUp();
virtual void TearDown();
rados_t cluster;
rados_ioctx_t ioctx;
};
class RadosTestPP : public ::testing::Test {
public:
RadosTestPP() : cluster(s_cluster) {}
virtual ~RadosTestPP() {}
protected:
static void SetUpTestCase();
static void TearDownTestCase();
static void cleanup_default_namespace(librados::IoCtx ioctx);
static librados::Rados s_cluster;
static std::string pool_name;
virtual void SetUp();
virtual void TearDown();
librados::Rados &cluster;
librados::IoCtx ioctx;
std::string ns;
};
#endif