]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
rgw/dbstore: change default value of dbstore_db_dir to /var/lib/ceph/radosgw
author0xavi0 <xavi.garcia@suse.com>
Mon, 23 May 2022 12:01:25 +0000 (14:01 +0200)
committer0xavi0 <xavi.garcia@suse.com>
Tue, 31 May 2022 07:01:56 +0000 (09:01 +0200)
Changes a few NULL to nullptr.

Adds std::filesystem for path building so they're platform independant.

Fixes a bug for DBStoreManager's second constructor not creating the DB.

Adds unit tests to test DB path and prefix.

Fixes: https://tracker.ceph.com/issues/55731
Signed-off-by: 0xavi0 <xavi.garcia@suse.com>
qa/suites/rgw/dbstore/tasks/rgw_s3tests.yaml
src/common/options/rgw.yaml.in
src/rgw/store/dbstore/README.md
src/rgw/store/dbstore/dbstore_mgr.cc
src/rgw/store/dbstore/dbstore_mgr.h
src/rgw/store/dbstore/tests/CMakeLists.txt
src/rgw/store/dbstore/tests/dbstore_mgr_tests.cc [new file with mode: 0644]

index 2042f832b6adc69432b10e72b23107b35f832e48..4c8764e4bab4b8ca26f3cddab341bf2305ac0f0d 100644 (file)
@@ -4,8 +4,9 @@ tasks:
 - rgw: [client.0]
 - exec:
     client.0:
-      - sudo chmod 0777 /var/run/ceph
-      - sudo chmod 0777 /var/run/ceph/dbstore-default_ns.db
+      - sudo chmod 0777 /var/lib/ceph
+      - sudo chmod 0777 /var/lib/ceph/radosgw
+      - sudo chmod 0777 /var/lib/ceph/radosgw/dbstore-default_ns.db
 - s3tests:
     client.0:
       force-branch: ceph-master
index 65bc6b41f8907f7218349a745edd777c69d89ae2..b174c902980212988483c5cd3360bfc15eacee6b 100644 (file)
@@ -3460,7 +3460,7 @@ options:
   type: str
   level: advanced
   desc: path for the directory for storing the db backend store data
-  default: /var/run/ceph
+  default: /var/lib/ceph/radosgw
   services:
   - rgw
 - name: dbstore_db_name_prefix
index dedf8416accdf1e510fa9aa2f3468bbd9077d2f1..659bc205276a5c6ec89dc45b067d7da46e723d5c 100644 (file)
@@ -29,7 +29,7 @@ The above vstart command brings up RGW server on dbstore and creates few default
 `radosgw-admin` can be used to create and remove other users.
 
 
-By default, dbstore creates .db file *'/var/run/ceph/dbstore-default_ns.db'* to store the data. This can be configured using below options in ceph.conf
+By default, dbstore creates .db file *'/var/lib/ceph/radosgw/dbstore-default_ns.db'* to store the data. This can be configured using below options in ceph.conf
 
     [client]
         dbstore db dir = <path for the directory for storing the db backend store data>
@@ -39,12 +39,15 @@ By default, dbstore creates .db file *'/var/run/ceph/dbstore-default_ns.db'* to
 ## DBStore Unit Tests
 To execute DBStore unit test cases (using Gtest framework), from build directory
 
-    ninja src/rgw/store/dbstore/install
-    ./bin/dbstore-tests [logfile] [loglevel]
+    ninja unittest_dbstore_tests
+    ./bin/unittest_dbstore_tests [logfile] [loglevel]
     (default logfile: rgw_dbstore_tests.log, loglevel: 20)
+    ninja unittest_dbstore_mgr_tests
+    ./bin/unittest_dbstore_mgr_tests
 
 To execute Sample test file
 
+    ninja src/rgw/store/dbstore/install
     ./bin/dbstore-bin [logfile] [loglevel]
     (default logfile: rgw_dbstore_bin.log, loglevel: 20)
 
index 5725793b71ba4effa9b1de5815216ca6add4924a..e54039ccf448aa11e9564d5d204fe4b139d73c50 100644 (file)
@@ -4,6 +4,8 @@
 #include "dbstore_mgr.h"
 #include "common/dbstore_log.h"
 
+#include <filesystem>
+
 using namespace std;
 
 /* Given a tenant, find and return the DBStore handle.
@@ -29,7 +31,7 @@ DB *DBStoreManager::getDB (string tenant, bool create)
 
 not_found:
   if (!create)
-    return NULL;
+    return nullptr;
 
   dbs = createDB(tenant);
 
@@ -41,16 +43,16 @@ DB *DBStoreManager::createDB(std::string tenant) {
   DB *dbs = nullptr;
   pair<map<string, DB*>::iterator,bool> ret;
   const auto& db_path = g_conf().get_val<std::string>("dbstore_db_dir");
-  const auto& db_name = g_conf().get_val<std::string>("dbstore_db_name_prefix");
+  const auto& db_name = g_conf().get_val<std::string>("dbstore_db_name_prefix") + "-" + tenant;
 
-  std::string db_full_path = db_path + "/" + db_name + "-" + tenant;
-   ldout(cct, 0) << "DB initialization full db_path("<<db_full_path<<")" << dendl;
+  auto db_full_path = std::filesystem::path(db_path) / db_name;
+  ldout(cct, 0) << "DB initialization full db_path("<<db_full_path<<")" << dendl;
 
   /* Create the handle */
 #ifdef SQLITE_ENABLED
-  dbs = new SQLiteDB(db_full_path, cct);
+  dbs = new SQLiteDB(db_full_path.string(), cct);
 #else
-  dbs = new DB(db_full_path, cct);
+  dbs = new DB(db_full_path.string(), cct);
 #endif
 
   /* API is DB::Initialize(string logfile, int loglevel);
@@ -62,7 +64,7 @@ DB *DBStoreManager::createDB(std::string tenant) {
     ldout(cct, 0) << "DB initialization failed for tenant("<<tenant<<")" << dendl;
 
     delete dbs;
-    return NULL;
+    return nullptr;
   }
 
   /* XXX: Do we need lock to protect this map?
index 68bb412e746a141c83fe60001184cf6e07792980..77fc3aaf731fb8b6a85116a33b7328d4622d8abe 100644 (file)
@@ -24,7 +24,7 @@ const static std::string default_tenant = "default_ns";
 class DBStoreManager {
 private:
   std::map<std::string, DB*> DBStoreHandles;
-  DB *default_db = NULL;
+  DB *default_db = nullptr;
   CephContext *cct;
 
 public:
@@ -38,6 +38,7 @@ public:
     cct->_log->set_log_file(logfile);
     cct->_log->reopen_log_file();
     cct->_conf->subsys.set_log_level(ceph_subsys_rgw, loglevel);
+    default_db = createDB(default_tenant);
   };
   ~DBStoreManager() { destroyAllHandles(); };
 
index 5ae2fba67b791abd53bdc1a881157348edbd7f68..4e60dcf5ee2b4c00e541ba5570ebb40ee42a4c9c 100644 (file)
@@ -11,3 +11,7 @@ include_directories(${CMAKE_INCLUDE_DIR})
 add_executable(unittest_dbstore_tests ${dbstore_tests_srcs})
 target_link_libraries(unittest_dbstore_tests ${CMAKE_LINK_LIBRARIES})
 add_ceph_unittest(unittest_dbstore_tests)
+
+add_executable(unittest_dbstore_mgr_tests dbstore_mgr_tests.cc)
+target_link_libraries(unittest_dbstore_mgr_tests dbstore gtest_main)
+add_ceph_unittest(unittest_dbstore_mgr_tests)
diff --git a/src/rgw/store/dbstore/tests/dbstore_mgr_tests.cc b/src/rgw/store/dbstore/tests/dbstore_mgr_tests.cc
new file mode 100644 (file)
index 0000000..4f58f47
--- /dev/null
@@ -0,0 +1,157 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "common/ceph_context.h"
+#include "rgw/store/dbstore/dbstore_mgr.h"
+
+#include <filesystem>
+#include <gtest/gtest.h>
+#include <memory>
+
+using namespace rgw;
+namespace fs = std::filesystem;
+const static std::string TEST_DIR = "rgw_dbstore_tests";
+
+bool endsWith(const std::string &mainStr, const std::string &toMatch)
+{
+    if(mainStr.size() >= toMatch.size() &&
+            mainStr.compare(mainStr.size() - toMatch.size(), toMatch.size(), toMatch) == 0)
+            return true;
+        else
+            return false;
+}
+
+class TestDBStoreManager : public ::testing::Test {
+protected:
+  void SetUp() override {
+    ctx_ = std::make_shared<CephContext>(CEPH_ENTITY_TYPE_CLIENT);
+    g_ceph_context = ctx_.get();
+    fs::current_path(fs::temp_directory_path());
+    fs::create_directory(TEST_DIR);
+  }
+
+  void TearDown() override {
+    fs::current_path(fs::temp_directory_path());
+    fs::remove_all(TEST_DIR);
+  }
+
+  std::string getTestDir() const {
+    auto test_dir = fs::temp_directory_path() / TEST_DIR;
+    return test_dir.string();
+  }
+
+  fs::path getDBFullPath(const std::string & base_dir,
+                         const std::string & tenant) const {
+    auto db_path = ctx_->_conf.get_val<std::string>("dbstore_db_dir");
+    const auto& db_name = ctx_->_conf.get_val<std::string>("dbstore_db_name_prefix") + "-" + tenant + ".db";
+
+    auto db_full_path = std::filesystem::path(db_path) / db_name;
+    auto db_full_path_test = fs::path(base_dir) / db_full_path;
+    return db_full_path_test;
+  }
+
+  std::string getDBTenant(const std::string & base_dir,
+                          const std::string & tenant) const {
+    auto db_name = ctx_->_conf.get_val<std::string>("dbstore_db_name_prefix");
+    db_name += "-" + tenant;
+    auto db_full_path = fs::path(base_dir) /  db_name;
+    return db_full_path.string();
+  }
+
+  std::string getDBTenant(const std::string & tenant = default_tenant) const {
+    return getDBTenant(getTestDir(), tenant);
+  }
+
+  fs::path getDBFullPath(const std::string & tenant) const {
+    return getDBFullPath(getTestDir(), tenant);
+  }
+
+  fs::path getLogFilePath(const std::string & log_file) {
+    return fs::temp_directory_path() / log_file;
+  }
+
+  std::shared_ptr<CephContext> getContext() const {
+    return ctx_;
+  }
+
+ private:
+    std::shared_ptr<CephContext> ctx_;
+};
+
+TEST_F(TestDBStoreManager, BasicInstantiateUsingDBDir) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  EXPECT_FALSE(fs::exists(getDBFullPath(default_tenant)));
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+  EXPECT_TRUE(fs::exists(getDBFullPath(default_tenant)));
+}
+
+TEST_F(TestDBStoreManager, DBNamePrefix) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+  std::string prefix = "testprefix";
+  getContext()->_conf.set_val("dbstore_db_name_prefix", prefix);
+
+  EXPECT_FALSE(fs::exists(getDBFullPath(default_tenant)));
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+  EXPECT_TRUE(fs::exists(getDBFullPath(default_tenant)));
+
+  // check that the database name contains the given prefix
+  std::string expected_db_name = prefix + "-" + default_tenant + ".db";
+  EXPECT_TRUE(endsWith(getDBFullPath(default_tenant), expected_db_name));
+}
+
+TEST_F(TestDBStoreManager, BasicInstantiateSecondConstructor) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  EXPECT_FALSE(fs::exists(getDBFullPath(default_tenant)));
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get(), getLogFilePath("test.log").string(), 10);
+  EXPECT_TRUE(fs::exists(getDBFullPath(default_tenant)));
+}
+
+TEST_F(TestDBStoreManager, TestDBName) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+  auto db = dbstore_mgr->getDB(default_tenant, false);
+  ASSERT_NE(nullptr, db);
+  EXPECT_EQ(getDBTenant(), db->getDBname());
+}
+
+
+TEST_F(TestDBStoreManager, TestDBNameDefaultDB) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+  // passing an empty tenant should return the default_db
+  auto db = dbstore_mgr->getDB("", false);
+  ASSERT_NE(nullptr, db);
+  EXPECT_EQ(getDBTenant(), db->getDBname());
+}
+
+TEST_F(TestDBStoreManager, TestDBBadTenant) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+  auto db = dbstore_mgr->getDB("does-not-exist", false);
+  ASSERT_EQ(nullptr, db);
+}
+
+TEST_F(TestDBStoreManager, TestGetNewDB) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+
+  auto new_tenant_path = "new_tenant";
+  auto db = dbstore_mgr->getDB(new_tenant_path, true);
+  ASSERT_NE(nullptr, db);
+  EXPECT_EQ(getDBTenant(new_tenant_path), db->getDBname());
+}
+
+TEST_F(TestDBStoreManager, TestDelete) {
+  getContext()->_conf.set_val("dbstore_db_dir", getTestDir());
+
+  auto dbstore_mgr = std::make_shared<DBStoreManager>(getContext().get());
+  dbstore_mgr->deleteDB(default_tenant);
+  auto db = dbstore_mgr->getDB(default_tenant, false);
+  ASSERT_EQ(nullptr, db);
+}