]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
librados: create new ceph_test_rados_api_tier target
authorSage Weil <sage@inktank.com>
Sun, 6 Oct 2013 18:39:04 +0000 (11:39 -0700)
committerSage Weil <sage@inktank.com>
Fri, 6 Dec 2013 22:37:27 +0000 (14:37 -0800)
Move the dirty/undirty test to it, and add one for HitSets.

Signed-off-by: Sage Weil <sage@inktank.com>
Signed-off-by: Greg Farnum <greg@inktank.com>
ceph.spec.in
debian/ceph-test.install
qa/workunits/rados/test.sh
src/test/Makefile.am
src/test/librados/misc.cc
src/test/librados/tier.cc [new file with mode: 0644]

index 1c65957b42d20a17df3d842847b4a1e9040e823f..d98807605dfd9ecb447900f1dc9d2a5b5e83e19f 100644 (file)
@@ -647,6 +647,7 @@ fi
 %{_bindir}/ceph_test_rados_api_list
 %{_bindir}/ceph_test_rados_api_lock
 %{_bindir}/ceph_test_rados_api_misc
+%{_bindir}/ceph_test_rados_api_tier
 %{_bindir}/ceph_test_rados_api_pool
 %{_bindir}/ceph_test_rados_api_snapshots
 %{_bindir}/ceph_test_rados_api_stat
index 237a05850be987738808945862c3ddbe3b4918ce..876e750b6c6d6666bdc930e7f8c74ce2be418300 100644 (file)
@@ -56,6 +56,7 @@ usr/bin/ceph_test_rados_api_io
 usr/bin/ceph_test_rados_api_list
 usr/bin/ceph_test_rados_api_lock
 usr/bin/ceph_test_rados_api_misc
+usr/bin/ceph_test_rados_api_tier
 usr/bin/ceph_test_rados_api_pool
 usr/bin/ceph_test_rados_api_snapshots
 usr/bin/ceph_test_rados_api_stat
index d7b4e10a4efda6cc380a41f2e6956d8a79f530eb..a2066f4f40c28ae55a2e0b46ef53856967289fc7 100755 (executable)
@@ -5,6 +5,7 @@ ceph_test_rados_api_io
 ceph_test_rados_api_list
 ceph_test_rados_api_lock
 ceph_test_rados_api_misc
+ceph_test_rados_api_tier
 ceph_test_rados_api_pool
 ceph_test_rados_api_snapshots
 ceph_test_rados_api_stat
index 572d5d57dc441cac59d6beaeb60b1eaa8d5401ad..359ba852bc271227f6c5da18626006fa43beb4fe 100644 (file)
@@ -767,6 +767,14 @@ ceph_test_rados_api_misc_LDADD = $(LIBRADOS) $(UNITTEST_LDADD) $(CEPH_GLOBAL)
 ceph_test_rados_api_misc_CXXFLAGS = $(UNITTEST_CXXFLAGS)
 bin_DEBUGPROGRAMS += ceph_test_rados_api_misc
 
+ceph_test_rados_api_tier_SOURCES = \
+       test/librados/tier.cc \
+       test/librados/test.cc \
+       osd/HitSet.cc
+ceph_test_rados_api_tier_LDADD = $(LIBRADOS) $(UNITTEST_LDADD) $(CEPH_GLOBAL)
+ceph_test_rados_api_tier_CXXFLAGS = $(UNITTEST_CXXFLAGS)
+bin_DEBUGPROGRAMS += ceph_test_rados_api_tier
+
 ceph_test_rados_api_lock_SOURCES = \
        test/librados/lock.cc \
        test/librados/test.cc
index ec77cb009dc9306660fc6036d01c7b1b62f7af55..e2b78f24b404ab64716ae50cd9e5e9ed4f356d29 100644 (file)
@@ -1,3 +1,5 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
 #include "gtest/gtest.h"
 
 #include "mds/mdstypes.h"
@@ -657,60 +659,6 @@ TEST(LibRadosMisc, CopyPP) {
   ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
 }
 
-TEST(LibRadosMisc, Dirty) {
-  Rados cluster;
-  std::string pool_name = get_temp_pool_name();
-  ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
-  IoCtx ioctx;
-  ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
-
-  {
-    ObjectWriteOperation op;
-    op.create(true);
-    ASSERT_EQ(0, ioctx.operate("foo", &op));
-  }
-  {
-    bool dirty = false;
-    int r = -1;
-    ObjectReadOperation op;
-    op.is_dirty(&dirty, &r);
-    ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
-    ASSERT_TRUE(dirty);
-    ASSERT_EQ(0, r);
-  }
-  {
-    ObjectWriteOperation op;
-    op.undirty();
-    ASSERT_EQ(0, ioctx.operate("foo", &op));
-  }
-  {
-    bool dirty = false;
-    int r = -1;
-    ObjectReadOperation op;
-    op.is_dirty(&dirty, &r);
-    ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
-    ASSERT_FALSE(dirty);
-    ASSERT_EQ(0, r);
-  }
-  {
-    ObjectWriteOperation op;
-    op.truncate(0);  // still a write even tho it is a no-op
-    ASSERT_EQ(0, ioctx.operate("foo", &op));
-  }
-  {
-    bool dirty = false;
-    int r = -1;
-    ObjectReadOperation op;
-    op.is_dirty(&dirty, &r);
-    ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
-    ASSERT_TRUE(dirty);
-    ASSERT_EQ(0, r);
-  }
-
-  ioctx.close();
-  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
-}
-
 int main(int argc, char **argv)
 {
   ::testing::InitGoogleTest(&argc, argv);
diff --git a/src/test/librados/tier.cc b/src/test/librados/tier.cc
new file mode 100644 (file)
index 0000000..06abe2e
--- /dev/null
@@ -0,0 +1,216 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+#include "gtest/gtest.h"
+
+#include "mds/mdstypes.h"
+#include "include/buffer.h"
+#include "include/rbd_types.h"
+#include "include/rados/librados.h"
+#include "include/rados/librados.hpp"
+#include "include/stringify.h"
+#include "include/types.h"
+#include "global/global_context.h"
+#include "global/global_init.h"
+#include "common/ceph_argparse.h"
+#include "common/common_init.h"
+#include "test/librados/test.h"
+
+#include "osd/HitSet.h"
+
+#include <errno.h>
+#include <map>
+#include <sstream>
+#include <string>
+
+using namespace librados;
+using ceph::buffer;
+using std::map;
+using std::ostringstream;
+using std::string;
+
+TEST(LibRadosMisc, Dirty) {
+  Rados cluster;
+  std::string pool_name = get_temp_pool_name();
+  ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
+  IoCtx ioctx;
+  ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
+
+  {
+    ObjectWriteOperation op;
+    op.create(true);
+    ASSERT_EQ(0, ioctx.operate("foo", &op));
+  }
+  {
+    bool dirty = false;
+    int r = -1;
+    ObjectReadOperation op;
+    op.is_dirty(&dirty, &r);
+    ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
+    ASSERT_TRUE(dirty);
+    ASSERT_EQ(0, r);
+  }
+  {
+    ObjectWriteOperation op;
+    op.undirty();
+    ASSERT_EQ(0, ioctx.operate("foo", &op));
+  }
+  {
+    bool dirty = false;
+    int r = -1;
+    ObjectReadOperation op;
+    op.is_dirty(&dirty, &r);
+    ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
+    ASSERT_FALSE(dirty);
+    ASSERT_EQ(0, r);
+  }
+  {
+    ObjectWriteOperation op;
+    op.truncate(0);  // still a write even tho it is a no-op
+    ASSERT_EQ(0, ioctx.operate("foo", &op));
+  }
+  {
+    bool dirty = false;
+    int r = -1;
+    ObjectReadOperation op;
+    op.is_dirty(&dirty, &r);
+    ASSERT_EQ(0, ioctx.operate("foo", &op, NULL));
+    ASSERT_TRUE(dirty);
+    ASSERT_EQ(0, r);
+  }
+
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+}
+
+TEST(LibRadosMisc, HitSetNone) {
+  Rados cluster;
+  std::string pool_name = get_temp_pool_name();
+  ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
+  IoCtx ioctx;
+  ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
+
+  {
+    list< pair<time_t,time_t> > ls;
+    AioCompletion *c = librados::Rados::aio_create_completion();
+    ASSERT_EQ(0, ioctx.hit_set_list(123, c, &ls));
+    c->wait_for_complete();
+    ASSERT_EQ(0, c->get_return_value());
+    ASSERT_TRUE(ls.empty());
+    c->release();
+  }
+  {
+    bufferlist bl;
+    AioCompletion *c = librados::Rados::aio_create_completion();
+    ASSERT_EQ(0, ioctx.hit_set_get(123, c, 12345, &bl));
+    c->wait_for_complete();
+    ASSERT_EQ(-ENOENT, c->get_return_value());
+    c->release();
+  }
+
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+}
+
+string set_pool_str(string pool, string var, string val)
+{
+  return string("{\"prefix\": \"osd pool set\",\"pool\":\"") + pool
+    + string("\",\"var\": \"") + var + string("\",\"val\": \"")
+    + val + string("\"}");
+}
+
+string set_pool_str(string pool, string var, int val)
+{
+  return string("{\"prefix\": \"osd pool set\",\"pool\":\"") + pool
+    + string("\",\"var\": \"") + var + string("\",\"val\": ")
+    + stringify(val) + string("}");
+}
+
+TEST(LibRadosMisc, HitSetRead) {
+  Rados cluster;
+  std::string pool_name = get_temp_pool_name();
+  ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
+  IoCtx ioctx;
+  ASSERT_EQ(0, cluster.ioctx_create(pool_name.c_str(), ioctx));
+
+  // FIXME: detect num pgs
+  int num_pg = 8;
+
+  // enable hitset tracking for this pool
+  bufferlist inbl;
+  ASSERT_EQ(0, cluster.mon_command(set_pool_str(pool_name, "hit_set_count", 8),
+                                               inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(set_pool_str(pool_name, "hit_set_period", 60),
+                                               inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(set_pool_str(pool_name, "hit_set_type", "bloom"),
+                                  inbl, NULL, NULL));
+  ASSERT_EQ(0, cluster.mon_command(set_pool_str(pool_name, "hit_set_fpp", ".01"),
+                                  inbl, NULL, NULL));
+
+  // wait for maps to settle
+  cluster.wait_for_latest_osdmap();
+
+  // do a bunch of reads
+  for (int i=0; i<1000; ++i) {
+    bufferlist bl;
+    ASSERT_EQ(-ENOENT, ioctx.read(stringify(i), bl, 1, 0));
+  }
+
+  // get HitSets
+  std::map<int,HitSet> hitsets;
+  for (int i=0; i<num_pg; ++i) {
+    list< pair<time_t,time_t> > ls;
+    AioCompletion *c = librados::Rados::aio_create_completion();
+    ASSERT_EQ(0, ioctx.hit_set_list(i, c, &ls));
+    c->wait_for_complete();
+    c->release();
+    std::cout << "pg " << i << " ls " << ls << std::endl;
+    ASSERT_FALSE(ls.empty());
+
+    // get the latest
+    c = librados::Rados::aio_create_completion();
+    bufferlist bl;
+    ASSERT_EQ(0, ioctx.hit_set_get(i, c, ls.back().first, &bl));
+    c->wait_for_complete();
+    c->release();
+
+    //std::cout << "bl len is " << bl.length() << "\n";
+    //bl.hexdump(std::cout);
+    //std::cout << std::endl;
+
+    bufferlist::iterator p = bl.begin();
+    ::decode(hitsets[i], p);
+  }
+
+  for (int i=0; i<1000; ++i) {
+    string n = stringify(i);
+    uint32_t hash = ioctx.get_object_hash_position(n);
+    hobject_t oid(sobject_t(n, CEPH_NOSNAP), "", hash, -1, "");
+    int pg = ioctx.get_object_pg_hash_position(n);
+    std::cout << "checking for " << oid << ", should be in pg " << pg << std::endl;
+    bool found = false;
+    for (int p=0; p<num_pg; ++p) {
+      if (hitsets[p].contains(oid)) {
+       found = true;
+       break;
+      }
+    }
+    ASSERT_TRUE(found);
+  }
+
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
+}
+
+
+int main(int argc, char **argv)
+{
+  ::testing::InitGoogleTest(&argc, argv);
+
+  vector<const char*> args;
+  argv_to_vec(argc, (const char **)argv, args);
+
+  global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, CODE_ENVIRONMENT_UTILITY, 0);
+  common_init_finish(g_ceph_context);
+
+  return RUN_ALL_TESTS();
+}