-#include "../rgw/driver/d4n/d4n_directory.h" // Fix -Sam
-#include "rgw_process_env.h"
-#include <cpp_redis/cpp_redis>
-#include <iostream>
-#include <string>
-#include "gtest/gtest.h"
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/detached.hpp>
+#include <boost/redis/connection.hpp>
-using namespace std;
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "rgw_auth_registry.h"
+#include "driver/d4n/d4n_directory.h"
+
+namespace net = boost::asio;
+using boost::redis::config;
+using boost::redis::connection;
+using boost::redis::request;
+using boost::redis::response;
+
+class Environment* env;
+
+class Environment : public ::testing::Environment {
+ public:
+ Environment() {}
+
+ virtual ~Environment() {}
+
+ void SetUp() override {
+ std::vector<const char*> args;
+ std::string conf_file_list;
+ std::string cluster = "";
+ CephInitParameters iparams = ceph_argparse_early_args(
+ args, CEPH_ENTITY_TYPE_CLIENT,
+ &cluster, &conf_file_list);
+
+ cct = common_preinit(iparams, CODE_ENVIRONMENT_UTILITY, {});
+ dpp = new DoutPrefix(cct->get(), dout_subsys, "D4N Object Directory Test: ");
+
+ redisHost = cct->_conf->rgw_d4n_host + ":" + std::to_string(cct->_conf->rgw_d4n_port);
+ }
+
+ void TearDown() override {
+ delete dpp;
+ }
-string portStr;
-string hostStr;
-string redisHost = "";
-string oid = "testName";
-string bucketName = "testBucket";
-int blockSize = 123;
+ std::string redisHost;
+ CephContext* cct;
+ DoutPrefixProvider* dpp;
+};
-class DirectoryFixture: public ::testing::Test {
+class ObjectDirectoryFixture: public ::testing::Test {
protected:
virtual void SetUp() {
- blockDir = new rgw::d4n::BlockDirectory(hostStr, stoi(portStr));
- cacheBlock = new rgw::d4n::CacheBlock();
+ dir = new rgw::d4n::ObjectDirectory{io};
+ obj = new rgw::d4n::CacheObj{
+ .objName = "testName",
+ .bucketName = "testBucket",
+ .creationTime = 0,
+ .dirty = false,
+ .hostsList = { env->redisHost }
+ };
+
+ conn = new connection{boost::asio::make_strand(io)};
- cacheBlock->hostsList.push_back(redisHost);
- cacheBlock->size = blockSize;
- cacheBlock->cacheObj.bucketName = bucketName;
- cacheBlock->cacheObj.objName = oid;
+ ASSERT_NE(obj, nullptr);
+ ASSERT_NE(dir, nullptr);
+ ASSERT_NE(conn, nullptr);
+
+ dir->init(env->cct, env->dpp);
+
+ /* Run fixture's connection */
+ config cfg;
+ cfg.addr.host = env->cct->_conf->rgw_d4n_host;
+ cfg.addr.port = std::to_string(env->cct->_conf->rgw_d4n_port);
+
+ conn->async_run(cfg, {}, net::detached);
}
virtual void TearDown() {
- delete blockDir;
- blockDir = nullptr;
+ delete conn;
+ delete obj;
+ delete dir;
+ }
+
+ rgw::d4n::CacheObj* obj;
+ rgw::d4n::ObjectDirectory* dir;
+
+ net::io_context io;
+ connection* conn;
- delete cacheBlock;
- cacheBlock = nullptr;
+ std::vector<std::string> vals{"testName", "testBucket", "0", "0", env->redisHost};
+ std::vector<std::string> fields{"objName", "bucketName", "creationTime", "dirty", "objHosts"};
+};
+
+class BlockDirectoryFixture: public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ dir = new rgw::d4n::BlockDirectory{io};
+ block = new rgw::d4n::CacheBlock{
+ .cacheObj = {
+ .objName = "testName",
+ .bucketName = "testBucket",
+ .creationTime = 0,
+ .dirty = false,
+ .hostsList = { env->redisHost }
+ },
+ .blockID = 0,
+ .version = "",
+ .size = 0,
+ .hostsList = { env->redisHost }
+ };
+
+ conn = new connection{boost::asio::make_strand(io)};
+
+ ASSERT_NE(block, nullptr);
+ ASSERT_NE(dir, nullptr);
+ ASSERT_NE(conn, nullptr);
+
+ dir->init(env->cct, env->dpp);
+
+ /* Run fixture's connection */
+ config cfg;
+ cfg.addr.host = env->cct->_conf->rgw_d4n_host;
+ cfg.addr.port = std::to_string(env->cct->_conf->rgw_d4n_port);
+
+ conn->async_run(cfg, {}, net::detached);
+ }
+
+ virtual void TearDown() {
+ delete conn;
+ delete block;
+ delete dir;
}
- rgw::d4n::BlockDirectory* blockDir;
- rgw::d4n::CacheBlock* cacheBlock;
+ rgw::d4n::CacheBlock* block;
+ rgw::d4n::BlockDirectory* dir;
+
+ net::io_context io;
+ connection* conn;
+
+ std::vector<std::string> vals{"0", "", "0", "0", env->redisHost,
+ "testName", "testBucket", "0", "0", env->redisHost};
+ std::vector<std::string> fields{"blockID", "version", "size", "globalWeight", "blockHosts",
+ "objName", "bucketName", "creationTime", "dirty", "objHosts"};
};
-/* Successful initialization */
-TEST_F(DirectoryFixture, DirectoryInit) {
- ASSERT_NE(blockDir, nullptr);
- ASSERT_NE(cacheBlock, nullptr);
- ASSERT_NE(redisHost.length(), (long unsigned int)0);
+TEST_F(ObjectDirectoryFixture, SetYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(obj, optional_yield{io, yield}));
+ dir->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push_range("HMGET", "testBucket_testName", fields);
+ req.push("FLUSHALL");
+
+ response< std::vector<std::string>,
+ boost::redis::ignore_t > resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), vals);
+ conn->cancel();
+ });
+
+ io.run();
}
-/* Successful set_value Call and Redis Check */
-TEST_F(DirectoryFixture, SetValueTest) {
- cpp_redis::client client;
- int key_exist = -1;
- string key;
- string hosts;
- string size;
- string bucketName;
- string objName;
- std::vector<std::string> fields;
- int setReturn = blockDir->set_value(cacheBlock);
-
- ASSERT_EQ(setReturn, 0);
-
- fields.push_back("key");
- fields.push_back("hosts");
- fields.push_back("size");
- fields.push_back("bucketName");
- fields.push_back("objName");
-
- client.connect(hostStr, stoi(portStr), nullptr, 0, 5, 1000);
- ASSERT_EQ((bool)client.is_connected(), (bool)1);
-
- client.hmget("rgw-object:" + oid + ":block-directory", fields, [&key, &hosts, &size, &bucketName, &objName, &key_exist](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- key_exist = 0;
- key = arr[0].as_string();
- hosts = arr[1].as_string();
- size = arr[2].as_string();
- bucketName = arr[3].as_string();
- objName = arr[4].as_string();
+TEST_F(ObjectDirectoryFixture, GetYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(obj, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HSET", "testBucket_testName", "objName", "newoid");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
}
+
+ ASSERT_EQ(0, dir->get(obj, optional_yield{io, yield}));
+ EXPECT_EQ(obj->objName, "newoid");
+ dir->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("FLUSHALL");
+ response<boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+ }
+
+ conn->cancel();
});
- client.sync_commit();
+ io.run();
+}
+
+TEST_F(ObjectDirectoryFixture, CopyYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(obj, optional_yield{io, yield}));
+ ASSERT_EQ(0, dir->copy(obj, "copyTestName", "copyBucketName", optional_yield{io, yield}));
+ dir->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "copyBucketName_copyTestName");
+ req.push_range("HMGET", "copyBucketName_copyTestName", fields);
+ req.push("FLUSHALL");
+
+ response<int, std::vector<std::string>,
+ boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
+
+ auto copyVals = vals;
+ copyVals[0] = "copyTestName";
+ copyVals[1] = "copyBucketName";
+ EXPECT_EQ(std::get<1>(resp).value(), copyVals);
- EXPECT_EQ(key_exist, 0);
- EXPECT_EQ(key, "rgw-object:" + oid + ":block-directory");
- EXPECT_EQ(hosts, redisHost);
- EXPECT_EQ(size, to_string(blockSize));
- EXPECT_EQ(bucketName, bucketName);
- EXPECT_EQ(objName, oid);
+ conn->cancel();
+ });
- client.flushall();
+ io.run();
}
-/* Successful get_value Calls and Redis Check */
-TEST_F(DirectoryFixture, GetValueTest) {
- cpp_redis::client client;
- int key_exist = -1;
- string key;
- string hosts;
- string size;
- string bucketName;
- string objName;
- std::vector<std::string> fields;
- int setReturn = blockDir->set_value(cacheBlock);
-
- ASSERT_EQ(setReturn, 0);
-
- fields.push_back("key");
- fields.push_back("hosts");
- fields.push_back("size");
- fields.push_back("bucketName");
- fields.push_back("objName");
-
- client.connect(hostStr, stoi(portStr), nullptr, 0, 5, 1000);
- ASSERT_EQ((bool)client.is_connected(), (bool)1);
-
- client.hmget("rgw-object:" + oid + ":block-directory", fields, [&key, &hosts, &size, &bucketName, &objName, &key_exist](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- key_exist = 0;
- key = arr[0].as_string();
- hosts = arr[1].as_string();
- size = arr[2].as_string();
- bucketName = arr[3].as_string();
- objName = arr[4].as_string();
+TEST_F(ObjectDirectoryFixture, DelYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(obj, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "testBucket_testName");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
}
+
+ ASSERT_EQ(0, dir->del(obj, optional_yield{io, yield}));
+ dir->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "testBucket_testName");
+ req.push("FLUSHALL");
+ response<int, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(BlockDirectoryFixture, SetYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(block, optional_yield{io, yield}));
+ dir->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push_range("HMGET", "testBucket_testName_0", fields);
+ req.push("FLUSHALL");
+
+ response< std::vector<std::string>,
+ boost::redis::ignore_t > resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), vals);
+ conn->cancel();
});
- client.sync_commit();
+ io.run();
+}
+
+TEST_F(BlockDirectoryFixture, GetYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(block, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HSET", "testBucket_testName_0", "objName", "newoid");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
- EXPECT_EQ(key_exist, 0);
- EXPECT_EQ(key, "rgw-object:" + oid + ":block-directory");
- EXPECT_EQ(hosts, redisHost);
- EXPECT_EQ(size, to_string(blockSize));
- EXPECT_EQ(bucketName, bucketName);
- EXPECT_EQ(objName, oid);
+ ASSERT_EQ(0, dir->get(block, optional_yield{io, yield}));
+ EXPECT_EQ(block->cacheObj.objName, "newoid");
+ dir->shutdown();
- /* Check if object name in directory instance matches redis update */
- client.hset("rgw-object:" + oid + ":block-directory", "objName", "newoid", [](cpp_redis::reply& reply) {
- if (!reply.is_null()) {
- ASSERT_EQ(reply.as_integer(), 0);
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("FLUSHALL");
+ response<boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
}
+
+ conn->cancel();
});
- client.sync_commit();
+ io.run();
+}
+
+TEST_F(BlockDirectoryFixture, CopyYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(block, optional_yield{io, yield}));
+ ASSERT_EQ(0, dir->copy(block, "copyTestName", "copyBucketName", optional_yield{io, yield}));
+ dir->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "copyBucketName_copyTestName_0");
+ req.push_range("HMGET", "copyBucketName_copyTestName_0", fields);
+ req.push("FLUSHALL");
+
+ response<int, std::vector<std::string>,
+ boost::redis::ignore_t> resp;
- int getReturn = blockDir->get_value(cacheBlock);
+ conn->async_exec(req, resp, yield[ec]);
- ASSERT_EQ(getReturn, 0);
- EXPECT_EQ(cacheBlock->cacheObj.objName, "newoid");
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
- client.flushall();
+ auto copyVals = vals;
+ copyVals[5] = "copyTestName";
+ copyVals[6] = "copyBucketName";
+ EXPECT_EQ(std::get<1>(resp).value(), copyVals);
+
+ conn->cancel();
+ });
+
+ io.run();
}
-/* Successful del_value Call and Redis Check */
-TEST_F(DirectoryFixture, DelValueTest) {
- cpp_redis::client client;
- vector<string> keys;
- int setReturn = blockDir->set_value(cacheBlock);
+TEST_F(BlockDirectoryFixture, DelYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(block, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "testBucket_testName_0");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
+ }
+
+ ASSERT_EQ(0, dir->del(block, optional_yield{io, yield}));
+ dir->shutdown();
- ASSERT_EQ(setReturn, 0);
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "testBucket_testName_0");
+ req.push("FLUSHALL");
+ response<int, boost::redis::ignore_t> resp;
- /* Ensure entry exists in directory before deletion */
- keys.push_back("rgw-object:" + oid + ":block-directory");
+ conn->async_exec(req, resp, yield[ec]);
- client.exists(keys, [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- ASSERT_EQ(reply.as_integer(), 1);
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
}
+
+ conn->cancel();
});
- int delReturn = blockDir->del_value(cacheBlock);
+ io.run();
+}
+
+TEST_F(BlockDirectoryFixture, UpdateFieldYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, dir->set(block, optional_yield{io, yield}));
+ ASSERT_EQ(0, dir->update_field(block, "objName", "newTestName", optional_yield{io, yield}));
+ ASSERT_EQ(0, dir->update_field(block, "blockHosts", "127.0.0.1:5000", optional_yield{io, yield}));
+ dir->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("HMGET", "testBucket_testName_0", "objName", "blockHosts");
+ req.push("FLUSHALL");
+ response< std::vector<std::string>,
+ boost::redis::ignore_t> resp;
- ASSERT_EQ(delReturn, 0);
+ conn->async_exec(req, resp, yield[ec]);
- client.exists(keys, [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- ASSERT_EQ(reply.as_integer(), 0); /* Zero keys exist */
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value()[0], "newTestName");
+ EXPECT_EQ(std::get<0>(resp).value()[1], "127.0.0.1:6379_127.0.0.1:5000");
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(BlockDirectoryFixture, RemoveHostYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ block->hostsList.push_back("127.0.0.1:6000");
+ ASSERT_EQ(0, dir->set(block, optional_yield{io, yield}));
+ ASSERT_EQ(0, dir->remove_host(block, "127.0.0.1:6379", optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HEXISTS", "testBucket_testName_0", "blockHosts");
+ req.push("HGET", "testBucket_testName_0", "blockHosts");
+ response<int, std::string> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
+ EXPECT_EQ(std::get<1>(resp).value(), "127.0.0.1:6000");
}
+
+ ASSERT_EQ(0, dir->remove_host(block, "127.0.0.1:6000", optional_yield{io, yield}));
+ dir->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "testBucket_testName_0");
+ req.push("FLUSHALL");
+ response<int, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ conn->cancel();
});
- client.flushall();
+ io.run();
}
int main(int argc, char *argv[]) {
::testing::InitGoogleTest(&argc, argv);
- /* Other ports can be passed to the program */
- if (argc == 1) {
- portStr = "6379";
- hostStr = "127.0.0.1";
- } else if (argc == 3) {
- hostStr = argv[1];
- portStr = argv[2];
- } else {
- cout << "Incorrect number of arguments." << std::endl;
- return -1;
- }
-
- redisHost = hostStr + ":" + portStr;
+ env = new Environment();
+ ::testing::AddGlobalTestEnvironment(env);
return RUN_ALL_TESTS();
}
+++ /dev/null
-#include "gtest/gtest.h"
-#include "common/ceph_context.h"
-#include <iostream>
-#include <string>
-#include "rgw_process_env.h"
-#include <cpp_redis/cpp_redis>
-#include "driver/dbstore/common/dbstore.h"
-#include "rgw_sal_store.h"
-#include "../../rgw/driver/d4n/rgw_sal_d4n.h" // fix -Sam
-
-#include "rgw_sal.h"
-#include "rgw_auth.h"
-#include "rgw_auth_registry.h"
-#include "driver/rados/rgw_zone.h"
-#include "rgw_sal_config.h"
-
-#include <boost/asio/io_context.hpp>
-
-#define dout_subsys ceph_subsys_rgw
-
-#define METADATA_LENGTH 22
-
-using namespace std;
-
-string portStr;
-string hostStr;
-string redisHost = "";
-
-vector<const char*> args;
-class Environment* env;
-const DoutPrefixProvider* dpp;
-const req_context rctx{dpp, null_yield, nullptr};
-
-class StoreObject : public rgw::sal::StoreObject {
- friend class D4NFilterFixture;
- FRIEND_TEST(D4NFilterFixture, StoreGetMetadata);
-};
-
-class Environment : public ::testing::Environment {
- boost::asio::io_context ioc;
- public:
- Environment() {}
-
- virtual ~Environment() {}
-
- void SetUp() override {
- /* Ensure redis instance is running */
- try {
- env_client.connect(hostStr, stoi(portStr), nullptr, 0, 5, 1000);
- } catch (std::exception &e) {
- std::cerr << "[ ] ERROR: Redis instance not running." << std::endl;
- }
-
- ASSERT_EQ((bool)env_client.is_connected(), (bool)1);
-
- /* Proceed with environment setup */
- cct = global_init(nullptr, args, CEPH_ENTITY_TYPE_CLIENT,
- CODE_ENVIRONMENT_UTILITY,
- CINIT_FLAG_NO_MON_CONFIG);
-
- dpp = new DoutPrefix(cct->get(), dout_subsys, "d4n test: ");
- DriverManager::Config cfg;
-
- cfg.store_name = "dbstore";
- cfg.filter_name = "d4n";
- auto config_store_type = g_conf().get_val<std::string>("rgw_config_store");
- std::unique_ptr<rgw::sal::ConfigStore> cfgstore
- = DriverManager::create_config_store(dpp, config_store_type);
- ASSERT_TRUE(cfgstore);
- rgw::SiteConfig site;
- auto r = site.load(dpp, null_yield, cfgstore.get());
- ASSERT_GT(r, 0);
-
- driver = DriverManager::get_storage(dpp, dpp->get_cct(),
- cfg,
- ioc,
- site,
- false,
- false,
- false,
- false,
- false,
- false, null_yield,
- false);
-
- ASSERT_NE(driver, nullptr);
- }
-
- void TearDown() override {
- if (env_client.is_connected()) {
- delete driver;
- delete dpp;
-
- env_client.disconnect();
- }
- }
-
- boost::intrusive_ptr<CephContext> cct;
- rgw::sal::Driver* driver;
- cpp_redis::client env_client;
-};
-
-class D4NFilterFixture : public ::testing::Test {
- protected:
- rgw::sal::Driver* driver;
- unique_ptr<rgw::sal::User> testUser = nullptr;
- unique_ptr<rgw::sal::Bucket> testBucket = nullptr;
- unique_ptr<rgw::sal::Writer> testWriter = nullptr;
-
- public:
- D4NFilterFixture() {}
-
- void SetUp() {
- driver = env->driver;
- }
-
- void TearDown() {}
-
- int createUser() {
- rgw_user u("test_tenant", "test_user", "ns");
-
- testUser = driver->get_user(u);
- testUser->get_info().user_id = u;
-
- int ret = testUser->store_user(dpp, null_yield, false);
-
- return ret;
- }
-
- int createBucket() {
- RGWBucketInfo info;
- info.bucket.name = "test_bucket";
-
- testBucket = driver->get_bucket(info);
-
- rgw::sal::Bucket::CreateParams params;
- params.zonegroup_id = "test_id";
- params.placement_rule.storage_class = "test_sc";
- params.swift_ver_location = "test_location";
-
- return testBucket->create(dpp, params, null_yield);
- }
-
- int putObject(string name) {
- string object_name = "test_object_" + name;
- unique_ptr<rgw::sal::Object> obj = testBucket->get_object(rgw_obj_key(object_name));
- rgw_user owner;
- rgw_placement_rule ptail_placement_rule;
- uint64_t olh_epoch = 123;
- string unique_tag;
-
- obj->get_obj_attrs(null_yield, dpp);
-
- testWriter = driver->get_atomic_writer(dpp,
- null_yield,
- obj.get(),
- owner,
- &ptail_placement_rule,
- olh_epoch,
- unique_tag);
-
- size_t accounted_size = 4;
- string etag("test_etag");
- ceph::real_time mtime;
- ceph::real_time set_mtime;
-
- buffer::list bl;
- string tmp = "test_attrs_value_" + name;
- bl.append("test_attrs_value_" + name);
- map<string, bufferlist> attrs{{"test_attrs_key_" + name, bl}};
-
- ceph::real_time delete_at;
- char if_match;
- char if_nomatch;
- string user_data;
- rgw_zone_set zones_trace;
- bool canceled;
-
- int ret = testWriter->prepare(null_yield);
-
- if (!ret) {
- ret = testWriter->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- rctx, rgw::sal::FLAG_LOG_OP);
-
- return ret;
- }
-
- void clientSetUp(cpp_redis::client* client) {
- client->connect(hostStr, stoi(portStr), nullptr, 0, 5, 1000);
- ASSERT_EQ((bool)client->is_connected(), (bool)1);
-
- client->flushdb([](cpp_redis::reply& reply) {});
- client->sync_commit();
- }
-
- void clientReset(cpp_redis::client* client) {
- client->flushdb([](cpp_redis::reply& reply) {});
- client->sync_commit();
- }
-};
-
-/* General operation-related tests */
-TEST_F(D4NFilterFixture, CreateUser) {
- EXPECT_EQ(createUser(), 0);
- EXPECT_NE(testUser, nullptr);
-}
-
-TEST_F(D4NFilterFixture, CreateBucket) {
- ASSERT_EQ(createUser(), 0);
- ASSERT_NE(testUser, nullptr);
-
- EXPECT_EQ(createBucket(), 0);
- EXPECT_NE(testBucket, nullptr);
-}
-
-TEST_F(D4NFilterFixture, PutObject) {
- cpp_redis::client client;
- vector<string> fields;
- fields.push_back("test_attrs_key_PutObject");
- clientSetUp(&client);
-
- ASSERT_EQ(createUser(), 0);
- ASSERT_NE(testUser, nullptr);
-
- ASSERT_EQ(createBucket(), 0);
- ASSERT_NE(testBucket, nullptr);
-
- EXPECT_EQ(putObject("PutObject"), 0);
- EXPECT_NE(testWriter, nullptr);
-
- client.hgetall("rgw-object:test_object_PutObject:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_PutObject:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_PutObject");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, GetObject) {
- cpp_redis::client client;
- vector<string> fields;
- fields.push_back("test_attrs_key_GetObject");
- clientSetUp(&client);
-
- ASSERT_EQ(createUser(), 0);
- ASSERT_NE(testUser, nullptr);
-
- ASSERT_EQ(createBucket(), 0);
- ASSERT_NE(testBucket, nullptr);
-
- ASSERT_EQ(putObject("GetObject"), 0);
- ASSERT_NE(testWriter, nullptr);
-
- unique_ptr<rgw::sal::Object> testObject_GetObject = testBucket->get_object(rgw_obj_key("test_object_GetObject"));
-
- EXPECT_NE(testObject_GetObject, nullptr);
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_GetObject.get())->get_next();
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- unique_ptr<rgw::sal::Object::ReadOp> testROp = testObject_GetObject->get_read_op();
-
- EXPECT_NE(testROp, nullptr);
- EXPECT_EQ(testROp->prepare(null_yield, dpp), 0);
-
- client.hgetall("rgw-object:test_object_GetObject:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_GetObject:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_GetObject");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, CopyObjectNone) {
- cpp_redis::client client;
- vector<string> fields;
- fields.push_back("test_attrs_key_CopyObjectNone");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("CopyObjectNone");
- unique_ptr<rgw::sal::Object> testObject_CopyObjectNone = testBucket->get_object(rgw_obj_key("test_object_CopyObjectNone"));
-
- ASSERT_NE(testObject_CopyObjectNone, nullptr);
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_CopyObjectNone.get())->get_next();
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Update object */
- RGWEnv rgw_env;
- req_info info(get_pointer(env->cct), &rgw_env);
- rgw_zone_id source_zone;
- rgw_placement_rule dest_placement;
- ceph::real_time src_mtime;
- ceph::real_time mtime;
- ceph::real_time mod_ptr;
- ceph::real_time unmod_ptr;
- char if_match;
- char if_nomatch;
- rgw::sal::AttrsMod attrs_mod = rgw::sal::ATTRSMOD_NONE;
- rgw::sal::Attrs attrs;
- RGWObjCategory category = RGWObjCategory::Main;
- uint64_t olh_epoch = 0;
- ceph::real_time delete_at;
- string tag;
- string etag;
-
- EXPECT_EQ(testObject_CopyObjectNone->copy_object(testUser.get(),
- &info, source_zone, testObject_CopyObjectNone.get(),
- testBucket.get(), testBucket.get(),
- dest_placement, &src_mtime, &mtime,
- &mod_ptr, &unmod_ptr, false,
- &if_match, &if_nomatch, attrs_mod,
- false, attrs, category, olh_epoch,
- delete_at, NULL, &tag, &etag,
- NULL, NULL, dpp, null_yield), 0);
-
- client.hgetall("rgw-object:test_object_CopyObjectNone:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_CopyObjectNone:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_CopyObjectNone");
- }
- });
-
- client.sync_commit();
-}
-
-TEST_F(D4NFilterFixture, CopyObjectReplace) {
- cpp_redis::client client;
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("CopyObjectReplace");
- unique_ptr<rgw::sal::Object> testObject_CopyObjectReplace = testBucket->get_object(rgw_obj_key("test_object_CopyObjectReplace"));
-
- ASSERT_NE(testObject_CopyObjectReplace, nullptr);
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_CopyObjectReplace.get())->get_next();
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Copy to new object */
- unique_ptr<rgw::sal::Writer> testWriterCopy = nullptr;
- unique_ptr<rgw::sal::Object> obj = testBucket->get_object(rgw_obj_key("test_object_copy"));
- rgw_user owner;
- rgw_placement_rule ptail_placement_rule;
- uint64_t olh_epoch_copy = 123;
- string unique_tag;
-
- obj->get_obj_attrs(null_yield, dpp);
-
- testWriterCopy = driver->get_atomic_writer(dpp,
- null_yield,
- obj.get(),
- owner,
- &ptail_placement_rule,
- olh_epoch_copy,
- unique_tag);
-
- RGWEnv rgw_env;
- size_t accounted_size = 0;
- req_info info(get_pointer(env->cct), &rgw_env);
- rgw_zone_id source_zone;
- rgw_placement_rule dest_placement;
- ceph::real_time src_mtime;
- ceph::real_time mtime;
- ceph::real_time set_mtime;
- ceph::real_time mod_ptr;
- ceph::real_time unmod_ptr;
- rgw::sal::AttrsMod attrs_mod = rgw::sal::ATTRSMOD_REPLACE;
- char if_match;
- char if_nomatch;
- RGWObjCategory category = RGWObjCategory::Main;
- uint64_t olh_epoch = 0;
- ceph::real_time delete_at;
- string tag;
- string etag("test_etag_copy");
-
- /* Attribute to replace */
- buffer::list bl;
- bl.append("test_attrs_copy_value");
- rgw::sal::Attrs attrs{{"test_attrs_key_CopyObjectReplace", bl}};
-
- string user_data;
- rgw_zone_set zones_trace;
- bool canceled;
-
- ASSERT_EQ(testWriterCopy->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- rctx, rgw::sal::FLAG_LOG_OP), 0);
-
- unique_ptr<rgw::sal::Object> testObject_copy = testBucket->get_object(rgw_obj_key("test_object_copy"));
-
- EXPECT_EQ(testObject_CopyObjectReplace->copy_object(testUser.get(),
- &info, source_zone, testObject_copy.get(),
- testBucket.get(), testBucket.get(),
- dest_placement, &src_mtime, &mtime,
- &mod_ptr, &unmod_ptr, false,
- &if_match, &if_nomatch, attrs_mod,
- false, attrs, category, olh_epoch,
- delete_at, NULL, &tag, &etag,
- NULL, NULL, dpp, null_yield), 0);
-
- /* Ensure the original object is still in the cache */
- vector<string> keys;
- keys.push_back("rgw-object:test_object_CopyObjectReplace:cache");
-
- client.exists(keys, [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 1);
- }
- });
-
- client.sync_commit();
-
- /* Retrieve original object's redis data for later comparison */
- std::vector< std::pair<std::string, std::string> > data;
-
- client.hgetall("rgw-object:test_object_CopyObjectReplace:cache", [&data](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- for (int i = 0; i < (int)arr.size() - 1; i += 2) {
- data.push_back({arr[i].as_string(), arr[i + 1].as_string()});
- }
- }
- });
-
- client.sync_commit();
-
- /* Check copy */
- client.hgetall("rgw-object:test_object_copy:cache", [&data](cpp_redis::reply& reply) {
- bool unexpected = false;
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 4 + METADATA_LENGTH); /* With etag */
-
- for (int i = 0; i < (int)arr.size() - 1; i += 2) {
- auto it = std::find_if(data.begin(), data.end(),
- [&](const auto& pair) { return pair.first == arr[i].as_string(); });
-
- if (it != data.end()) {
- if (arr[i].as_string() == "test_attrs_key_CopyObjectReplace")
- EXPECT_EQ(arr[i + 1].as_string(), "test_attrs_copy_value");
- else if (arr[i].as_string() != "mtime") { /* mtime will be different */
- int index = std::distance(data.begin(), it);
- EXPECT_EQ(arr[i + 1].as_string(), data[index].second);
- }
- } else if (arr[i].as_string() == "etag") {
- EXPECT_EQ(arr[i + 1].as_string(), "test_etag_copy");
- } else
- unexpected = true; /* Unexpected field */
- }
-
- EXPECT_EQ(unexpected, false);
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, CopyObjectMerge) {
- cpp_redis::client client;
- vector<string> fields;
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("CopyObjectMerge");
- unique_ptr<rgw::sal::Object> testObject_CopyObjectMerge = testBucket->get_object(rgw_obj_key("test_object_CopyObjectMerge"));
-
- ASSERT_NE(testObject_CopyObjectMerge, nullptr);
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_CopyObjectMerge.get())->get_next();
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Copy to new object */
- unique_ptr<rgw::sal::Writer> testWriterCopy = nullptr;
- string object_name = "test_object_copy";
- unique_ptr<rgw::sal::Object> obj = testBucket->get_object(rgw_obj_key(object_name));
- rgw_user owner;
- rgw_placement_rule ptail_placement_rule;
- uint64_t olh_epoch_copy = 123;
- string unique_tag;
-
- obj->get_obj_attrs(null_yield, dpp);
-
- testWriterCopy = driver->get_atomic_writer(dpp,
- null_yield,
- obj.get(),
- owner,
- &ptail_placement_rule,
- olh_epoch_copy,
- unique_tag);
-
- RGWEnv rgw_env;
- size_t accounted_size = 4;
- req_info info(get_pointer(env->cct), &rgw_env);
- rgw_zone_id source_zone;
- rgw_placement_rule dest_placement;
- ceph::real_time src_mtime;
- ceph::real_time mtime;
- ceph::real_time set_mtime;
- ceph::real_time mod_ptr;
- ceph::real_time unmod_ptr;
- rgw::sal::AttrsMod attrs_mod = rgw::sal::ATTRSMOD_MERGE;
- char if_match;
- char if_nomatch;
- RGWObjCategory category = RGWObjCategory::Main;
- uint64_t olh_epoch = 0;
- ceph::real_time delete_at;
- string tag;
- string etag("test_etag_copy");
-
- buffer::list bl;
- bl.append("bad_value");
- rgw::sal::Attrs attrs{{"test_attrs_key_CopyObjectMerge", bl}}; /* Existing attr */
- bl.clear();
- bl.append("test_attrs_copy_extra_value");
- attrs.insert({"test_attrs_copy_extra_key", bl}); /* New attr */
-
- string user_data;
- rgw_zone_set zones_trace;
- bool canceled;
-
- ASSERT_EQ(testWriterCopy->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- rctx, rgw::sal::FLAG_LOG_OP), 0);
-
- unique_ptr<rgw::sal::Object> testObject_copy = testBucket->get_object(rgw_obj_key("test_object_copy"));
-
- EXPECT_EQ(testObject_CopyObjectMerge->copy_object(testUser.get(),
- &info, source_zone, testObject_copy.get(),
- testBucket.get(), testBucket.get(),
- dest_placement, &src_mtime, &mtime,
- &mod_ptr, &unmod_ptr, false,
- &if_match, &if_nomatch, attrs_mod,
- false, attrs, category, olh_epoch,
- delete_at, NULL, &tag, &etag,
- NULL, NULL, dpp, null_yield), 0);
-
- /* Ensure the original object is still in the cache */
- vector<string> keys;
- keys.push_back("rgw-object:test_object_CopyObjectMerge:cache");
-
- client.exists(keys, [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 1);
- }
- });
-
- client.sync_commit();
-
- /* Retrieve original object's redis data for later comparison */
- std::vector< std::pair<std::string, std::string> > data;
-
- client.hgetall("rgw-object:test_object_CopyObjectMerge:cache", [&data](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- for (int i = 0; i < (int)arr.size() - 1; i += 2) {
- data.push_back({arr[i].as_string(), arr[i + 1].as_string()});
- }
- }
- });
-
- client.sync_commit();
-
- /* Check copy */
- client.hgetall("rgw-object:test_object_copy:cache", [&data](cpp_redis::reply& reply) {
- bool unexpected = false;
- bool merge = false;
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 6 + METADATA_LENGTH); /* With etag */
-
- for (int i = 0; i < (int)arr.size() - 1; i += 2) {
- auto it = std::find_if(data.begin(), data.end(),
- [&](const auto& pair) { return pair.first == arr[i].as_string(); });
-
- if (it != data.end()) {
- if (arr[i].as_string() == "test_attrs_key_CopyObjectMerge")
- EXPECT_EQ(arr[i + 1].as_string(), "test_attrs_value_CopyObjectMerge");
- else if (arr[i].as_string() != "mtime") { /* mtime will be different */
- int index = std::distance(data.begin(), it);
- EXPECT_EQ(arr[i + 1].as_string(), data[index].second);
- }
- } else if (arr[i].as_string() == "etag") {
- EXPECT_EQ(arr[i + 1].as_string(), "test_etag_copy");
- } else if (arr[i].as_string() == "test_attrs_copy_extra_key") {
- merge = true;
- EXPECT_EQ(arr[i + 1].as_string(), "test_attrs_copy_extra_value");
- } else
- unexpected = true; /* Unexpected field */
- }
-
- EXPECT_EQ(unexpected, false);
- EXPECT_EQ(merge, true);
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, DelObject) {
- cpp_redis::client client;
- vector<string> keys;
- keys.push_back("rgw-object:test_object_DelObject:cache");
- clientSetUp(&client);
-
- ASSERT_EQ(createUser(), 0);
- ASSERT_NE(testUser, nullptr);
-
- ASSERT_EQ(createBucket(), 0);
- ASSERT_NE(testBucket, nullptr);
-
- ASSERT_EQ(putObject("DelObject"), 0);
- ASSERT_NE(testWriter, nullptr);
-
- /* Check the object exists before delete op */
- client.exists(keys, [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 1);
- }
- });
-
- client.sync_commit();
-
- unique_ptr<rgw::sal::Object> testObject_DelObject = testBucket->get_object(rgw_obj_key("test_object_DelObject"));
-
- EXPECT_NE(testObject_DelObject, nullptr);
-
- unique_ptr<rgw::sal::Object::DeleteOp> testDOp = testObject_DelObject->get_delete_op();
-
- EXPECT_NE(testDOp, nullptr);
- EXPECT_EQ(testDOp->delete_obj(dpp, null_yield, true), 0);
-
- /* Check the object does not exist after delete op */
- client.exists(keys, [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 0); /* Zero keys exist */
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, CachePolicy) {
- cpp_redis::client client;
- clientSetUp(&client);
-
- createUser();
- createBucket();
-
- /* Create multipart object */
- string object_name = "test_object_CachePolicy";
- unique_ptr<rgw::sal::Object> obj = testBucket->get_object(rgw_obj_key(object_name));
- rgw_user owner;
- rgw_placement_rule ptail_placement_rule;
- uint64_t olh_epoch = 123;
- string unique_tag;
-
- obj->get_obj_attrs(null_yield, dpp);
-
- testWriter = driver->get_atomic_writer(dpp,
- null_yield,
- obj.get(),
- owner,
- &ptail_placement_rule,
- olh_epoch,
- unique_tag);
-
- size_t accounted_size = 15; /* Uploaded as multipart */
- string etag("test_etag");
- ceph::real_time mtime;
- ceph::real_time set_mtime;
-
- buffer::list bl;
- string tmp = "test_attrs_value_CachePolicy";
- bl.append("test_attrs_value_CachePolicy");
- map<string, bufferlist> attrs{{"test_attrs_key_CachePolicy", bl}};
-
- ceph::real_time delete_at;
- char if_match;
- char if_nomatch;
- string user_data;
- rgw_zone_set zones_trace;
- bool canceled;
-
- ASSERT_EQ(testWriter->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- null_yield), 0);
-
-
- unique_ptr<rgw::sal::Object> testObject_CachePolicy = testBucket->get_object(rgw_obj_key("test_object_CachePolicy"));
-
- ASSERT_NE(testObject_CachePolicy, nullptr);
-
- /* Copy to new multipart object */
- unique_ptr<rgw::sal::Writer> testWriterCopy = nullptr;
- unique_ptr<rgw::sal::Object> obj_copy = testBucket->get_object(rgw_obj_key("test_object_copy"));
- uint64_t olh_epoch_copy = 123;
-
- obj_copy->get_obj_attrs(null_yield, dpp);
-
- testWriterCopy = driver->get_atomic_writer(dpp,
- null_yield,
- obj_copy.get(),
- owner,
- &ptail_placement_rule,
- olh_epoch_copy,
- unique_tag);
-
- RGWEnv rgw_env;
- req_info info(get_pointer(env->cct), &rgw_env);
- rgw_zone_id source_zone;
- rgw_placement_rule dest_placement;
- ceph::real_time src_mtime;
- ceph::real_time mod_ptr;
- ceph::real_time unmod_ptr;
- rgw::sal::AttrsMod attrs_mod = rgw::sal::ATTRSMOD_REPLACE;
- RGWObjCategory category = RGWObjCategory::Main;
- string tag;
-
- ASSERT_EQ(testWriterCopy->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- null_yield), 0);
-
- unique_ptr<rgw::sal::Object> testObject_copy = testBucket->get_object(rgw_obj_key("test_object_copy"));
-
- EXPECT_EQ(testObject_CachePolicy->copy_object(testUser.get(),
- &info, source_zone, testObject_copy.get(),
- testBucket.get(), testBucket.get(),
- dest_placement, &src_mtime, &mtime,
- &mod_ptr, &unmod_ptr, false,
- &if_match, &if_nomatch, attrs_mod,
- false, attrs, category, olh_epoch,
- delete_at, NULL, &tag, &etag,
- NULL, NULL, dpp, null_yield), 0);
-
- /* Ensure data field doesn't exist for original object */
- client.hexists("rgw-object:test_object_CachePolicy:cache", "data", [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 0);
- }
- });
-
- client.sync_commit();
-
- /* Ensure data field doesn't exist for copy */
- client.hexists("rgw-object:test_object_CachePolicy:cache", "data", [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 0);
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-/* Attribute-related tests */
-TEST_F(D4NFilterFixture, SetObjectAttrs) {
- cpp_redis::client client;
- vector<string> fields;
- fields.push_back("test_attrs_key_SetObjectAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("SetObjectAttrs");
- unique_ptr<rgw::sal::Object> testObject_SetObjectAttrs = testBucket->get_object(rgw_obj_key("test_object_SetObjectAttrs"));
-
- ASSERT_NE(testObject_SetObjectAttrs, nullptr);
-
- buffer::list bl;
- bl.append("test_attrs_value_extra");
- map<string, bufferlist> test_attrs{{"test_attrs_key_extra", bl}};
- fields.push_back("test_attrs_key_extra");
-
- EXPECT_EQ(testObject_SetObjectAttrs->set_obj_attrs(dpp, &test_attrs, NULL, null_yield), 0);
-
- client.hgetall("rgw-object:test_object_SetObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 4 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_SetObjectAttrs:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_SetObjectAttrs");
- EXPECT_EQ(arr[1].as_string(), "test_attrs_value_extra");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, GetObjectAttrs) {
- cpp_redis::client client;
- vector<string> fields;
- fields.push_back("test_attrs_key_GetObjectAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("GetObjectAttrs");
- unique_ptr<rgw::sal::Object> testObject_GetObjectAttrs = testBucket->get_object(rgw_obj_key("test_object_GetObjectAttrs"));
-
- ASSERT_NE(testObject_GetObjectAttrs, nullptr);
-
- buffer::list bl;
- bl.append("test_attrs_value_extra");
- map<string, bufferlist> test_attrs{{"test_attrs_key_extra", bl}};
- fields.push_back("test_attrs_key_extra");
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_GetObjectAttrs.get())->get_next();
-
- ASSERT_EQ(testObject_GetObjectAttrs->set_obj_attrs(dpp, &test_attrs, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- EXPECT_EQ(testObject_GetObjectAttrs->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- client.hgetall("rgw-object:test_object_GetObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 4 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_GetObjectAttrs:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_GetObjectAttrs");
- EXPECT_EQ(arr[1].as_string(), "test_attrs_value_extra");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, DelObjectAttrs) {
- cpp_redis::client client;
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("DelObjectAttrs");
- unique_ptr<rgw::sal::Object> testObject_DelObjectAttrs = testBucket->get_object(rgw_obj_key("test_object_DelObjectAttrs"));
-
- ASSERT_NE(testObject_DelObjectAttrs, nullptr);
-
- buffer::list bl;
- bl.append("test_attrs_value_extra");
- map<string, bufferlist> test_attrs{{"test_attrs_key_extra", bl}};
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_DelObjectAttrs.get())->get_next();
-
- ASSERT_EQ(testObject_DelObjectAttrs->set_obj_attrs(dpp, &test_attrs, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Check that the attributes exist before deletion */
- client.hgetall("rgw-object:test_object_DelObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 4 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- EXPECT_EQ(testObject_DelObjectAttrs->set_obj_attrs(dpp, NULL, &test_attrs, null_yield), 0);
-
- /* Check that the attribute does not exist after deletion */
- client.hgetall("rgw-object:test_object_DelObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hexists("rgw-object:test_object_DelObjectAttrs:cache", "test_attrs_key_extra", [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 0);
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, SetLongObjectAttrs) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_long;
- vector<string> fields;
- fields.push_back("test_attrs_key_SetLongObjectAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("SetLongObjectAttrs");
- unique_ptr<rgw::sal::Object> testObject_SetLongObjectAttrs = testBucket->get_object(rgw_obj_key("test_object_SetLongObjectAttrs"));
-
- ASSERT_NE(testObject_SetLongObjectAttrs, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_long.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- EXPECT_EQ(testObject_SetLongObjectAttrs->set_obj_attrs(dpp, &test_attrs_long, NULL, null_yield), 0);
-
- client.hgetall("rgw-object:test_object_SetLongObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_SetLongObjectAttrs:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_SetLongObjectAttrs");
-
- for (int i = 1; i < 11; ++i) {
- EXPECT_EQ(arr[i].as_string(), "test_attrs_value_extra_" + to_string(i - 1));
- }
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, GetLongObjectAttrs) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_long;
- vector<string> fields;
- fields.push_back("test_attrs_key_GetLongObjectAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("GetLongObjectAttrs");
- unique_ptr<rgw::sal::Object> testObject_GetLongObjectAttrs = testBucket->get_object(rgw_obj_key("test_object_GetLongObjectAttrs"));
-
- ASSERT_NE(testObject_GetLongObjectAttrs, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_long.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_GetLongObjectAttrs.get())->get_next();
-
- ASSERT_EQ(testObject_GetLongObjectAttrs->set_obj_attrs(dpp, &test_attrs_long, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- EXPECT_EQ(testObject_GetLongObjectAttrs->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- client.hgetall("rgw-object:test_object_GetLongObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_GetLongObjectAttrs:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_GetLongObjectAttrs");
-
- for (int i = 1; i < 11; ++i) {
- EXPECT_EQ(arr[i].as_string(), "test_attrs_value_extra_" + to_string(i - 1));
- }
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, ModifyObjectAttr) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_long;
- vector<string> fields;
- fields.push_back("test_attrs_key_ModifyObjectAttr");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("ModifyObjectAttr");
- unique_ptr<rgw::sal::Object> testObject_ModifyObjectAttr = testBucket->get_object(rgw_obj_key("test_object_ModifyObjectAttr"));
-
- ASSERT_NE(testObject_ModifyObjectAttr, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_long.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_ModifyObjectAttr.get())->get_next();
-
- ASSERT_EQ(testObject_ModifyObjectAttr->set_obj_attrs(dpp, &test_attrs_long, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- buffer::list bl_tmp;
- string tmp_value = "new_test_attrs_value_extra_5";
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- EXPECT_EQ(testObject_ModifyObjectAttr->modify_obj_attrs("test_attrs_key_extra_5", bl_tmp, null_yield, dpp), 0);
-
- client.hgetall("rgw-object:test_object_ModifyObjectAttr:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_ModifyObjectAttr:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_ModifyObjectAttr");
-
- for (int i = 1; i < 11; ++i) {
- if (i == 6) {
- EXPECT_EQ(arr[i].as_string(), "new_test_attrs_value_extra_" + to_string(i - 1));
- } else {
- EXPECT_EQ(arr[i].as_string(), "test_attrs_value_extra_" + to_string(i - 1));
- }
- }
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, DelLongObjectAttrs) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_long;
- vector<string> fields;
- fields.push_back("test_attrs_key_DelLongObjectAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("DelLongObjectAttrs");
- unique_ptr<rgw::sal::Object> testObject_DelLongObjectAttrs = testBucket->get_object(rgw_obj_key("test_object_DelLongObjectAttrs"));
-
- ASSERT_NE(testObject_DelLongObjectAttrs, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_long.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_DelLongObjectAttrs.get())->get_next();
-
- ASSERT_EQ(testObject_DelLongObjectAttrs->set_obj_attrs(dpp, &test_attrs_long, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Check that the attributes exist before deletion */
- client.hgetall("rgw-object:test_object_DelLongObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- EXPECT_EQ(testObject_DelLongObjectAttrs->set_obj_attrs(dpp, NULL, &test_attrs_long, null_yield), 0);
-
- /* Check that the attributes do not exist after deletion */
- client.hgetall("rgw-object:test_object_DelLongObjectAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
-
- for (int i = 0; i < (int)arr.size(); ++i) {
- EXPECT_EQ((int)arr[i].as_string().find("extra"), -1);
- }
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, DelObjectAttr) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_long;
- vector<string> fields;
- fields.push_back("test_attrs_key_DelObjectAttr");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("DelObjectAttr");
- unique_ptr<rgw::sal::Object> testObject_DelObjectAttr = testBucket->get_object(rgw_obj_key("test_object_DelObjectAttr"));
-
- ASSERT_NE(testObject_DelObjectAttr, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_long.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_DelObjectAttr.get())->get_next();
-
- ASSERT_EQ(testObject_DelObjectAttr->set_obj_attrs(dpp, &test_attrs_long, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Check that the attribute exists before deletion */
- client.hgetall("rgw-object:test_object_DelObjectAttr:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- EXPECT_EQ(testObject_DelObjectAttr->delete_obj_attrs(dpp, "test_attrs_key_extra_5", null_yield), 0);
-
- /* Check that the attribute does not exist after deletion */
- client.hgetall("rgw-object:test_object_DelObjectAttr:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 20 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hexists("rgw-object:test_object_DelObjectAttr:cache", "test_attrs_key_extra_5", [](cpp_redis::reply& reply) {
- if (reply.is_integer()) {
- EXPECT_EQ(reply.as_integer(), 0);
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-/* Edge cases */
-TEST_F(D4NFilterFixture, PrepareCopyObject) {
- cpp_redis::client client;
- vector<string> fields;
- fields.push_back("test_attrs_key_PrepareCopyObject");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("PrepareCopyObject");
- unique_ptr<rgw::sal::Object> testObject_PrepareCopyObject = testBucket->get_object(rgw_obj_key("test_object_PrepareCopyObject"));
-
- ASSERT_NE(testObject_PrepareCopyObject, nullptr);
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_PrepareCopyObject.get())->get_next();
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- unique_ptr<rgw::sal::Object::ReadOp> testROp = testObject_PrepareCopyObject->get_read_op();
-
- ASSERT_NE(testROp, nullptr);
- ASSERT_EQ(testROp->prepare(null_yield, dpp), 0);
-
- /* Update object */
- RGWEnv rgw_env;
- req_info info(get_pointer(env->cct), &rgw_env);
- rgw_zone_id source_zone;
- rgw_placement_rule dest_placement;
- ceph::real_time src_mtime;
- ceph::real_time mtime;
- ceph::real_time mod_ptr;
- ceph::real_time unmod_ptr;
- char if_match;
- char if_nomatch;
- rgw::sal::AttrsMod attrs_mod = rgw::sal::ATTRSMOD_NONE;
- rgw::sal::Attrs attrs;
- RGWObjCategory category = RGWObjCategory::Main;
- uint64_t olh_epoch = 0;
- ceph::real_time delete_at;
- string tag;
- string etag;
-
- EXPECT_EQ(testObject_PrepareCopyObject->copy_object(testUser.get(),
- &info, source_zone, testObject_PrepareCopyObject.get(),
- testBucket.get(), testBucket.get(),
- dest_placement, &src_mtime, &mtime,
- &mod_ptr, &unmod_ptr, false,
- &if_match, &if_nomatch, attrs_mod,
- false, attrs, category, olh_epoch,
- delete_at, NULL, &tag, &etag,
- NULL, NULL, dpp, null_yield), 0);
-
- client.hgetall("rgw-object:test_object_PrepareCopyObject:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_PrepareCopyObject:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_PrepareCopyObject");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, SetDelAttrs) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_base;
- vector<string> fields;
- fields.push_back("test_attrs_key_SetDelAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("SetDelAttrs");
- unique_ptr<rgw::sal::Object> testObject_SetDelAttrs = testBucket->get_object(rgw_obj_key("test_object_SetDelAttrs"));
-
- ASSERT_NE(testObject_SetDelAttrs, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_SetDelAttrs.get())->get_next();
-
- ASSERT_EQ(testObject_SetDelAttrs->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Attempt to set and delete attrs with the same API call */
- buffer::list bl;
- bl.append("test_attrs_value_extra");
- map<string, bufferlist> test_attrs_new{{"test_attrs_key_extra", bl}};
- fields.push_back("test_attrs_key_extra");
-
- EXPECT_EQ(testObject_SetDelAttrs->set_obj_attrs(dpp, &test_attrs_new, &test_attrs_base, null_yield), 0);
-
- client.hgetall("rgw-object:test_object_SetDelAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 4 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_SetDelAttrs:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_SetDelAttrs");
- EXPECT_EQ(arr[1].as_string(), "test_attrs_value_extra");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, ModifyNonexistentAttr) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_base;
- vector<string> fields;
- fields.push_back("test_attrs_key_ModifyNonexistentAttr");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("ModifyNonexistentAttr");
- unique_ptr<rgw::sal::Object> testObject_ModifyNonexistentAttr = testBucket->get_object(rgw_obj_key("test_object_ModifyNonexistentAttr"));
-
- ASSERT_NE(testObject_ModifyNonexistentAttr, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_ModifyNonexistentAttr.get())->get_next();
-
- ASSERT_EQ(testObject_ModifyNonexistentAttr->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- buffer::list bl_tmp;
- bl_tmp.append("new_test_attrs_value_extra_ModifyNonexistentAttr");
-
- EXPECT_EQ(testObject_ModifyNonexistentAttr->modify_obj_attrs("test_attrs_key_extra_ModifyNonexistentAttr", bl_tmp, null_yield, dpp), 0);
-
- fields.push_back("test_attrs_key_extra_ModifyNonexistentAttr");
-
- client.hgetall("rgw-object:test_object_ModifyNonexistentAttr:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 24 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_ModifyNonexistentAttr:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_ModifyNonexistentAttr");
-
- for (int i = 1; i < 11; ++i) {
- EXPECT_EQ(arr[i].as_string(), "test_attrs_value_extra_" + to_string(i - 1));
- }
-
- /* New attribute will be created and stored since it was not found in the existing attributes */
- EXPECT_EQ(arr[11].as_string(), "new_test_attrs_value_extra_ModifyNonexistentAttr");
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, ModifyGetAttrs) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_base;
- vector<string> fields;
- fields.push_back("test_attrs_key_ModifyGetAttrs");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("ModifyGetAttrs");
- unique_ptr<rgw::sal::Object> testObject_ModifyGetAttrs = testBucket->get_object(rgw_obj_key("test_object_ModifyGetAttrs"));
-
- ASSERT_NE(testObject_ModifyGetAttrs, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_ModifyGetAttrs.get())->get_next();
-
- ASSERT_EQ(testObject_ModifyGetAttrs->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Attempt to get immediately after a modification */
- buffer::list bl_tmp;
- bl_tmp.append("new_test_attrs_value_extra_5");
-
- ASSERT_EQ(testObject_ModifyGetAttrs->modify_obj_attrs("test_attrs_key_extra_5", bl_tmp, null_yield, dpp), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- EXPECT_EQ(testObject_ModifyGetAttrs->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- client.hgetall("rgw-object:test_object_ModifyGetAttrs:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_ModifyGetAttrs:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_ModifyGetAttrs");
-
- for (int i = 1; i < 11; ++i) {
- if (i == 6) {
- EXPECT_EQ(arr[i].as_string(), "new_test_attrs_value_extra_5");
- } else {
- EXPECT_EQ(arr[i].as_string(), "test_attrs_value_extra_" + to_string(i - 1));
- }
- }
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, DelNonexistentAttr) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_base;
- vector<string> fields;
- fields.push_back("test_attrs_key_DelNonexistentAttr");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("DelNonexistentAttr");
- unique_ptr<rgw::sal::Object> testObject_DelNonexistentAttr = testBucket->get_object(rgw_obj_key("test_object_DelNonexistentAttr"));
-
- ASSERT_NE(testObject_DelNonexistentAttr, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- fields.push_back(tmp_key);
- }
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_DelNonexistentAttr.get())->get_next();
-
- ASSERT_EQ(testObject_DelNonexistentAttr->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield), 0);
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Attempt to delete an attribute that does not exist */
- ASSERT_EQ(testObject_DelNonexistentAttr->delete_obj_attrs(dpp, "test_attrs_key_extra_12", null_yield), 0);
-
- client.hgetall("rgw-object:test_object_DelNonexistentAttr:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 22 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- client.hmget("rgw-object:test_object_DelNonexistentAttr:cache", fields, [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ(arr[0].as_string(), "test_attrs_value_DelNonexistentAttr");
-
- for (int i = 1; i < 11; ++i) {
- EXPECT_EQ(arr[i].as_string(), "test_attrs_value_extra_" + to_string(i - 1));
- }
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, DelSetWithNonexisentAttr) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_base;
- vector<string> fields;
- fields.push_back("test_attrs_key_DelSetWithNonexistentAttr");
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("DelSetWithNonexistentAttr");
- unique_ptr<rgw::sal::Object> testObject_DelSetWithNonexistentAttr = testBucket->get_object(rgw_obj_key("test_object_DelSetWithNonexistentAttr"));
-
- ASSERT_NE(testObject_DelSetWithNonexistentAttr, nullptr);
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- }
-
- ASSERT_EQ(testObject_DelSetWithNonexistentAttr->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield), 0);
-
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_DelSetWithNonexistentAttr.get())->get_next();
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- EXPECT_EQ(testObject_DelSetWithNonexistentAttr->delete_obj_attrs(dpp, "test_attrs_key_extra_5", null_yield), 0);
-
- /* Attempt to delete a set of attrs, including one that does not exist */
- EXPECT_EQ(testObject_DelSetWithNonexistentAttr->set_obj_attrs(dpp, NULL, &test_attrs_base, null_yield), 0);
-
- client.hgetall("rgw-object:test_object_DelSetWithNonexistentAttr:cache", [](cpp_redis::reply& reply) {
- auto arr = reply.as_array();
-
- if (!arr[0].is_null()) {
- EXPECT_EQ((int)arr.size(), 2 + METADATA_LENGTH);
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-/* Underlying store attribute check */
-TEST_F(D4NFilterFixture, StoreSetAttr) {
- createUser();
- createBucket();
- putObject("StoreSetAttr");
- unique_ptr<rgw::sal::Object> testObject_StoreSetAttr = testBucket->get_object(rgw_obj_key("test_object_StoreSetAttr"));
-
- /* Get the underlying store */
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreSetAttr.get())->get_next();
-
- EXPECT_NE(nextObject, nullptr);
-
- /* Set one attribute */
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
- ASSERT_NE(nextObject->get_attrs().empty(), true);
-
- /* Check the attribute */
- rgw::sal::Attrs driverAttrs = nextObject->get_attrs();
- pair<string, string> value(driverAttrs.begin()->first, driverAttrs.begin()->second.to_str());
-
- EXPECT_EQ(value, make_pair(string("test_attrs_key_StoreSetAttr"), string("test_attrs_value_StoreSetAttr")));
-}
-
-TEST_F(D4NFilterFixture, StoreSetAttrs) {
- createUser();
- createBucket();
- putObject("StoreSetAttrs");
- unique_ptr<rgw::sal::Object> testObject_StoreSetAttrs = testBucket->get_object(rgw_obj_key("test_object_StoreSetAttrs"));
-
- /* Get the underlying store */
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreSetAttrs.get())->get_next();
-
- EXPECT_NE(nextObject, nullptr);
-
- /* Delete base attribute for easier comparison */
- testObject_StoreSetAttrs->delete_obj_attrs(dpp, "test_attrs_key_StoreSetAttrs", null_yield);
-
- /* Set more attributes */
- map<string, bufferlist> test_attrs_base;
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- }
-
- testObject_StoreSetAttrs->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Check the attributes */
- rgw::sal::Attrs driverAttrs = nextObject->get_attrs();
- rgw::sal::Attrs::iterator attrs;
- vector< pair<string, string> > values;
-
- for (attrs = driverAttrs.begin(); attrs != driverAttrs.end(); ++attrs) {
- values.push_back(make_pair(attrs->first, attrs->second.to_str()));
- }
-
- int i = 0;
-
- for (const auto& pair : values) {
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
-
- EXPECT_EQ(pair, make_pair(tmp_key, tmp_value));
- ++i;
- }
-}
-
-TEST_F(D4NFilterFixture, StoreGetAttrs) {
- cpp_redis::client client;
- map<string, bufferlist> test_attrs_base;
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("StoreGetAttrs");
- unique_ptr<rgw::sal::Object> testObject_StoreGetAttrs = testBucket->get_object(rgw_obj_key("test_object_StoreGetAttrs"));
-
- /* Get the underlying store */
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreGetAttrs.get())->get_next();
-
- EXPECT_NE(nextObject, nullptr);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Delete base attribute for easier comparison */
- testObject_StoreGetAttrs->delete_obj_attrs(dpp, "test_attrs_key_StoreGetAttrs", null_yield);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Set more attributes */
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- }
-
- testObject_StoreGetAttrs->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield);
- nextObject->get_obj_attrs(null_yield, dpp, NULL);
-
- /* Change an attribute through redis */
- vector< pair<string, string> > value;
- value.push_back(make_pair("test_attrs_key_extra_5", "new_test_attrs_value_extra_5"));
-
- client.hmset("rgw-object:test_object_StoreGetAttrs:cache", value, [&](cpp_redis::reply& reply) {
- if (!reply.is_null()) {
- EXPECT_EQ(reply.as_string(), "OK");
- }
- });
-
- client.sync_commit();
-
- /* Artificially adding the data field so getObject will succeed
- for the purposes of this test */
- value.clear();
- value.push_back(make_pair("data", ""));
-
- client.hmset("rgw-object:test_object_StoreGetAttrs:cache", value, [&](cpp_redis::reply& reply) {
- if (!reply.is_null()) {
- ASSERT_EQ(reply.as_string(), "OK");
- }
- });
-
- client.sync_commit();
-
- ASSERT_EQ(testObject_StoreGetAttrs->get_obj_attrs(null_yield, dpp, NULL), 0); /* Cache attributes */
-
- /* Check the attributes on the store layer */
- rgw::sal::Attrs driverAttrs = nextObject->get_attrs();
- rgw::sal::Attrs::iterator driverattrs;
- vector< pair<string, string> > driverValues;
-
- for (driverattrs = driverAttrs.begin(); driverattrs != driverAttrs.end(); ++driverattrs) {
- driverValues.push_back(make_pair(driverattrs->first, driverattrs->second.to_str()));
- }
-
- EXPECT_EQ((int)driverValues.size(), 10);
-
- int i = 0;
-
- for (const auto& pair : driverValues) {
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
-
- if (i == 5) {
- tmp_value = "new_" + tmp_value;
- }
-
- EXPECT_EQ(pair, make_pair(tmp_key, tmp_value));
- ++i;
- }
-
- /* Restore and check original attributes */
- nextObject->get_obj_attrs(null_yield, dpp, NULL);
- driverAttrs = nextObject->get_attrs();
- driverValues.clear();
-
- for (driverattrs = driverAttrs.begin(); driverattrs != driverAttrs.end(); ++driverattrs) {
- driverValues.push_back(make_pair(driverattrs->first, driverattrs->second.to_str()));
- }
-
- EXPECT_EQ((int)driverValues.size(), 10);
-
- i = 0;
-
- for (const auto& pair : driverValues) {
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
-
- EXPECT_EQ(pair, make_pair(tmp_key, tmp_value));
- ++i;
- }
-
- clientReset(&client);
-}
-
-TEST_F(D4NFilterFixture, StoreGetMetadata) {
- cpp_redis::client client;
- clientSetUp(&client);
-
- createUser();
- createBucket();
- putObject("StoreGetMetadata");
- unique_ptr<rgw::sal::Object> testObject_StoreGetMetadata = testBucket->get_object(rgw_obj_key("test_object_StoreGetMetadata"));
-
- /* Get the underlying store */
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreGetMetadata.get())->get_next();
-
- EXPECT_NE(nextObject, nullptr);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Change metadata values through redis */
- vector< pair<string, string> > value;
- value.push_back(make_pair("mtime", "2021-11-08T21:13:38.334696731Z"));
- value.push_back(make_pair("object_size", "100"));
- value.push_back(make_pair("accounted_size", "200"));
- value.push_back(make_pair("epoch", "3")); /* version_id is not tested because the object does not have an instance */
- value.push_back(make_pair("source_zone_short_id", "300"));
- value.push_back(make_pair("bucket_count", "10"));
- value.push_back(make_pair("bucket_size", "20"));
-
- client.hmset("rgw-object:test_object_StoreGetMetadata:cache", value, [](cpp_redis::reply& reply) {
- if (!reply.is_null()) {
- EXPECT_EQ(reply.as_string(), "OK");
- }
- });
-
- client.sync_commit();
-
- /* Artificially adding the data field so getObject will succeed
- for the purposes of this test */
- value.clear();
- value.push_back(make_pair("data", ""));
-
- client.hmset("rgw-object:test_object_StoreGetMetadata:cache", value, [](cpp_redis::reply& reply) {
- if (!reply.is_null()) {
- ASSERT_EQ(reply.as_string(), "OK");
- }
- });
-
- client.sync_commit();
-
- unique_ptr<rgw::sal::Object::ReadOp> testROp = testObject_StoreGetMetadata->get_read_op();
-
- ASSERT_NE(testROp, nullptr);
- ASSERT_EQ(testROp->prepare(null_yield, dpp), 0);
-
- /* Check updated metadata values */
- static StoreObject* storeObject = static_cast<StoreObject*>(dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreGetMetadata.get())->get_next());
-
- EXPECT_EQ(to_iso_8601(storeObject->state.mtime), "2021-11-08T21:13:38.334696731Z");
- EXPECT_EQ(testObject_StoreGetMetadata->get_obj_size(), (uint64_t)100);
- EXPECT_EQ(storeObject->state.accounted_size, (uint64_t)200);
- EXPECT_EQ(storeObject->state.epoch, (uint64_t)3);
- EXPECT_EQ(storeObject->state.zone_short_id, (uint32_t)300);
-}
-
-TEST_F(D4NFilterFixture, StoreModifyAttr) {
- createUser();
- createBucket();
- putObject("StoreModifyAttr");
- unique_ptr<rgw::sal::Object> testObject_StoreModifyAttr = testBucket->get_object(rgw_obj_key("test_object_StoreModifyAttr"));
-
- /* Get the underlying store */
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreModifyAttr.get())->get_next();
-
- ASSERT_NE(nextObject, nullptr);
-
- /* Modify existing attribute */
- buffer::list bl_tmp;
- string tmp_value = "new_test_attrs_value_StoreModifyAttr";
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- testObject_StoreModifyAttr->modify_obj_attrs("test_attrs_key_StoreModifyAttr", bl_tmp, null_yield, dpp);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Check the attribute */
- rgw::sal::Attrs driverAttrs = nextObject->get_attrs();
- pair<string, string> value(driverAttrs.begin()->first, driverAttrs.begin()->second.to_str());
-
- EXPECT_EQ(value, make_pair(string("test_attrs_key_StoreModifyAttr"), string("new_test_attrs_value_StoreModifyAttr")));
-}
-
-TEST_F(D4NFilterFixture, StoreDelAttrs) {
- createUser();
- createBucket();
- putObject("StoreDelAttrs");
- unique_ptr<rgw::sal::Object> testObject_StoreDelAttrs = testBucket->get_object(rgw_obj_key("test_object_StoreDelAttrs"));
-
- /* Get the underlying store */
- static rgw::sal::Object* nextObject = dynamic_cast<rgw::sal::FilterObject*>(testObject_StoreDelAttrs.get())->get_next();
-
- ASSERT_NE(nextObject, nullptr);
-
- /* Set more attributes */
- map<string, bufferlist> test_attrs_base;
-
- for (int i = 0; i < 10; ++i) {
- buffer::list bl_tmp;
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
- bl_tmp.append(tmp_value.data(), strlen(tmp_value.data()));
-
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- test_attrs_base.insert({tmp_key, bl_tmp});
- }
-
- testObject_StoreDelAttrs->set_obj_attrs(dpp, &test_attrs_base, NULL, null_yield);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Check that the attributes exist before deletion */
- rgw::sal::Attrs driverAttrs = nextObject->get_attrs();
-
- EXPECT_EQ(driverAttrs.size(), (long unsigned int)11);
-
- rgw::sal::Attrs::iterator driverattrs;
- vector< pair<string, string> > driverValues;
-
- for (driverattrs = ++driverAttrs.begin(); driverattrs != driverAttrs.end(); ++driverattrs) {
- driverValues.push_back(make_pair(driverattrs->first, driverattrs->second.to_str()));
- }
-
- int i = 0;
-
- for (const auto& pair : driverValues) {
- string tmp_key = "test_attrs_key_extra_" + to_string(i);
- string tmp_value = "test_attrs_value_extra_" + to_string(i);
-
- EXPECT_EQ(pair, make_pair(tmp_key, tmp_value));
- ++i;
- }
-
- testObject_StoreDelAttrs->set_obj_attrs(dpp, NULL, &test_attrs_base, null_yield);
-
- ASSERT_EQ(nextObject->get_obj_attrs(null_yield, dpp, NULL), 0);
-
- /* Check that the attributes do not exist after deletion */
- driverAttrs = nextObject->get_attrs();
-
- EXPECT_EQ(driverAttrs.size(), (long unsigned int)1);
-
- pair<string, string> value(driverAttrs.begin()->first, driverAttrs.begin()->second.to_str());
-
- EXPECT_EQ(value, make_pair(string("test_attrs_key_StoreDelAttrs"), string("test_attrs_value_StoreDelAttrs")));
-}
-
-/* SAL object data storage check */
-TEST_F(D4NFilterFixture, DataCheck) {
- cpp_redis::client client;
- clientSetUp(&client);
-
- createUser();
- createBucket();
-
- /* Prepare, process, and complete object write */
- unique_ptr<rgw::sal::Object> obj = testBucket->get_object(rgw_obj_key("test_object_DataCheck"));
- rgw_user owner;
- rgw_placement_rule ptail_placement_rule;
- uint64_t olh_epoch = 123;
- string unique_tag;
-
- obj->get_obj_attrs(null_yield, dpp);
-
- testWriter = driver->get_atomic_writer(dpp,
- null_yield,
- obj.get(),
- owner,
- &ptail_placement_rule,
- olh_epoch,
- unique_tag);
-
- size_t accounted_size = 4;
- string etag("test_etag");
- ceph::real_time mtime;
- ceph::real_time set_mtime;
-
- buffer::list bl;
- string tmp = "test_attrs_value_DataCheck";
- bl.append("test_attrs_value_DataCheck");
- map<string, bufferlist> attrs{{"test_attrs_key_DataCheck", bl}};
- buffer::list data;
- data.append("test data");
-
- ceph::real_time delete_at;
- char if_match;
- char if_nomatch;
- string user_data;
- rgw_zone_set zones_trace;
- bool canceled;
-
- ASSERT_EQ(testWriter->prepare(null_yield), 0);
-
- ASSERT_EQ(testWriter->process(std::move(data), 0), 0);
-
- ASSERT_EQ(testWriter->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- rctx, rgw::sal::FLAG_LOG_OP), 0);
-
- client.hget("rgw-object:test_object_DataCheck:cache", "data", [&data](cpp_redis::reply& reply) {
- if (reply.is_string()) {
- EXPECT_EQ(reply.as_string(), data.to_str());
- }
- });
-
- client.sync_commit();
-
- /* Change data and ensure redis stores the new value */
- buffer::list dataNew;
- dataNew.append("new test data");
-
- ASSERT_EQ(testWriter->prepare(null_yield), 0);
-
- ASSERT_EQ(testWriter->process(std::move(dataNew), 0), 0);
-
- ASSERT_EQ(testWriter->complete(accounted_size, etag,
- &mtime, set_mtime,
- attrs,
- delete_at,
- &if_match, &if_nomatch,
- &user_data,
- &zones_trace, &canceled,
- rctx, rgw::sal::FLAG_LOG_OP), 0);
-
- client.hget("rgw-object:test_object_DataCheck:cache", "data", [&dataNew](cpp_redis::reply& reply) {
- if (reply.is_string()) {
- EXPECT_EQ(reply.as_string(), dataNew.to_str());
- }
- });
-
- client.sync_commit();
-
- clientReset(&client);
-}
-
-int main(int argc, char *argv[]) {
- ::testing::InitGoogleTest(&argc, argv);
-
- /* Other host and port can be passed to the program */
- if (argc == 1) {
- portStr = "6379";
- hostStr = "127.0.0.1";
- } else if (argc == 3) {
- hostStr = argv[1];
- portStr = argv[2];
- } else {
- std::cout << "Incorrect number of arguments." << std::endl;
- return -1;
- }
-
- redisHost = hostStr + ":" + portStr;
-
- env = new Environment();
- ::testing::AddGlobalTestEnvironment(env);
-
- return RUN_ALL_TESTS();
-}
--- /dev/null
+#include <boost/asio/io_context.hpp>
+#include <boost/asio/detached.hpp>
+#include <boost/redis/connection.hpp>
+
+#include "gtest/gtest.h"
+#include "common/ceph_argparse.h"
+#include "rgw_auth_registry.h"
+#include "rgw_redis_driver.h"
+
+namespace net = boost::asio;
+using boost::redis::config;
+using boost::redis::connection;
+using boost::redis::request;
+using boost::redis::response;
+
+class Environment* env;
+
+class Environment : public ::testing::Environment {
+ public:
+ Environment() {}
+
+ virtual ~Environment() {}
+
+ void SetUp() override {
+ std::vector<const char*> args;
+ std::string conf_file_list;
+ std::string cluster = "";
+ CephInitParameters iparams = ceph_argparse_early_args(
+ args, CEPH_ENTITY_TYPE_CLIENT,
+ &cluster, &conf_file_list);
+
+ cct = common_preinit(iparams, CODE_ENVIRONMENT_UTILITY, {});
+ dpp = new DoutPrefix(cct->get(), dout_subsys, "D4N Object Directory Test: ");
+
+ redisHost = cct->_conf->rgw_d4n_host + ":" + std::to_string(cct->_conf->rgw_d4n_port);
+ }
+
+ std::string redisHost;
+ CephContext* cct;
+ DoutPrefixProvider* dpp;
+};
+
+class RedisDriverFixture: public ::testing::Test {
+ protected:
+ virtual void SetUp() {
+ rgw::cache::Partition partition_info{ .location = "RedisCache" };
+ cacheDriver = new rgw::cache::RedisDriver{io, partition_info};
+
+ conn = new connection{boost::asio::make_strand(io)};
+
+ ASSERT_NE(cacheDriver, nullptr);
+ ASSERT_NE(conn, nullptr);
+
+ cacheDriver->initialize(env->cct, env->dpp);
+
+ bl.append("test data");
+ bufferlist attrVal;
+ attrVal.append("attrVal");
+ attrs.insert({"attr", attrVal});
+
+ /* Run fixture's connection */
+ config cfg;
+ cfg.addr.host = env->cct->_conf->rgw_d4n_host;
+ cfg.addr.port = std::to_string(env->cct->_conf->rgw_d4n_port);
+
+ conn->async_run(cfg, {}, net::detached);
+ }
+
+ virtual void TearDown() {
+ delete conn;
+ delete cacheDriver;
+ }
+
+ rgw::cache::RedisDriver* cacheDriver;
+
+ net::io_context io;
+ connection* conn;
+
+ bufferlist bl;
+ rgw::sal::Attrs attrs;
+};
+
+TEST_F(RedisDriverFixture, PutYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("HGET", "RedisCache/testName", "attr");
+ req.push("FLUSHALL");
+
+ response<std::string, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), "attrVal");
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, GetYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HSET", "RedisCache/testName", "data", "new data", "attr", "newVal");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ bufferlist ret;
+ rgw::sal::Attrs retAttrs;
+
+ ASSERT_EQ(0, cacheDriver->get(env->dpp, "testName", 0, bl.length(), ret, retAttrs, optional_yield{io, yield}));
+ EXPECT_EQ(ret.to_str(), "new data");
+ EXPECT_EQ(retAttrs.begin()->second.to_str(), "newVal");
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("FLUSHALL");
+ response<boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, DelYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "RedisCache/testName");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
+ }
+
+ ASSERT_EQ(0, cacheDriver->del(env->dpp, "testName", optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("EXISTS", "RedisCache/testName");
+ req.push("FLUSHALL");
+ response<int, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+// How can I test get_async? -Sam
+
+TEST_F(RedisDriverFixture, AppendDataYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HGET", "RedisCache/testName", "data");
+ response<std::string> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), "test data");
+ }
+
+ bufferlist val;
+ val.append(" has been written");
+
+ ASSERT_EQ(0, cacheDriver->append_data(env->dpp, "testName", val, optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HGET", "RedisCache/testName", "data");
+ req.push("FLUSHALL");
+ response<std::string, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), "test data has been written");
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, DeleteDataYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HEXISTS", "RedisCache/testName", "data");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
+ }
+
+ ASSERT_EQ(0, cacheDriver->delete_data(env->dpp, "testName", optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HEXISTS", "RedisCache/testName", "data");
+ req.push("FLUSHALL");
+ response<int, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, SetAttrsYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ rgw::sal::Attrs newAttrs;
+ bufferlist newVal;
+ newVal.append("newVal");
+ newAttrs.insert({"newAttr", newVal});
+
+ newVal.clear();
+ newVal.append("nextVal");
+ newAttrs.insert({"nextAttr", newVal});
+
+ ASSERT_EQ(0, cacheDriver->set_attrs(env->dpp, "testName", newAttrs, optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("HMGET", "RedisCache/testName", "newAttr", "nextAttr");
+ req.push("FLUSHALL");
+
+ response< std::vector<std::string>,
+ boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value()[0], "newVal");
+ EXPECT_EQ(std::get<0>(resp).value()[1], "nextVal");
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, GetAttrsYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ rgw::sal::Attrs nextAttrs = attrs;
+ bufferlist nextVal;
+ nextVal.append("nextVal");
+ nextAttrs.insert({"nextAttr", nextVal});
+
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), nextAttrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HSET", "RedisCache/testName", "attr", "newVal1", "nextAttr", "newVal2");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ rgw::sal::Attrs retAttrs;
+
+ ASSERT_EQ(0, cacheDriver->get_attrs(env->dpp, "testName", retAttrs, optional_yield{io, yield}));
+
+ auto it = retAttrs.begin();
+ EXPECT_EQ(it->second.to_str(), "newVal1");
+ ++it;
+ EXPECT_EQ(it->second.to_str(), "newVal2");
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("FLUSHALL");
+ response<boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, UpdateAttrsYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ rgw::sal::Attrs newAttrs;
+ bufferlist newVal;
+ newVal.append("newVal");
+ newAttrs.insert({"attr", newVal});
+
+ ASSERT_EQ(0, cacheDriver->update_attrs(env->dpp, "testName", newAttrs, optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("HGET", "RedisCache/testName", "attr");
+ req.push("FLUSHALL");
+ response<std::string, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), "newVal");
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, DeleteAttrsYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HEXISTS", "RedisCache/testName", "attr");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 1);
+ }
+
+ rgw::sal::Attrs delAttrs;
+ bufferlist delVal;
+ delAttrs.insert({"attr", delVal});
+
+ ASSERT_GE(cacheDriver->delete_attrs(env->dpp, "testName", delAttrs, optional_yield{io, yield}), 0);
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HEXISTS", "RedisCache/testName", "attr");
+ req.push("FLUSHALL");
+ response<int, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, SetAttrYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+ ASSERT_GE(cacheDriver->set_attr(env->dpp, "testName", "newAttr", "newVal", optional_yield{io, yield}), 0);
+ cacheDriver->shutdown();
+
+ boost::system::error_code ec;
+ request req;
+ req.push("HGET", "RedisCache/testName", "newAttr");
+ req.push("FLUSHALL");
+
+ response<std::string, boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), "newVal");
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+TEST_F(RedisDriverFixture, GetAttrYield)
+{
+ spawn::spawn(io, [this] (spawn::yield_context yield) {
+ ASSERT_EQ(0, cacheDriver->put(env->dpp, "testName", bl, bl.length(), attrs, optional_yield{io, yield}));
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("HSET", "RedisCache/testName", "attr", "newVal");
+ response<int> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ EXPECT_EQ(std::get<0>(resp).value(), 0);
+ }
+
+ ASSERT_EQ("newVal", cacheDriver->get_attr(env->dpp, "testName", "attr", optional_yield{io, yield}));
+ cacheDriver->shutdown();
+
+ {
+ boost::system::error_code ec;
+ request req;
+ req.push("FLUSHALL");
+ response<boost::redis::ignore_t> resp;
+
+ conn->async_exec(req, resp, yield[ec]);
+
+ ASSERT_EQ((bool)ec, false);
+ }
+
+ conn->cancel();
+ });
+
+ io.run();
+}
+
+
+int main(int argc, char *argv[]) {
+ ::testing::InitGoogleTest(&argc, argv);
+
+ env = new Environment();
+ ::testing::AddGlobalTestEnvironment(env);
+
+ return RUN_ALL_TESTS();
+}