Skip to content

Commit

Permalink
add pkhash tests
Browse files Browse the repository at this point in the history
  • Loading branch information
lidongxu1 committed Sep 24, 2024
1 parent 8d150b6 commit 8ba7edd
Showing 1 changed file with 219 additions and 0 deletions.
219 changes: 219 additions & 0 deletions src/storage/tests/pkhashes_test.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,219 @@
// Copyright (c) 2017-present, Qihoo, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.

#include <dirent.h>
#include <gtest/gtest.h>
#include <unistd.h>
#include <iostream>
#include <iterator>
#include <thread>

#include "glog/logging.h"

#include "pstd/include/env.h"
#include "pstd/include/pika_codis_slot.h"
#include "storage/storage.h"
#include "storage/util.h"

using namespace storage;

class PKHashesTest : public ::testing::Test {
public:
PKHashesTest() = default;
~PKHashesTest() override = default;

void SetUp() override {
std::string path = "./db/pkhashes";
pstd::DeleteDirIfExist(path);
mkdir(path.c_str(), 0755);
storage_options.options.create_if_missing = true;
s = db.Open(storage_options, path);
}

void TearDown() override {
std::string path = "./db/pkhashes";
DeleteFiles(path.c_str());
}

static void SetUpTestSuite() {}
static void TearDownTestSuite() {}

StorageOptions storage_options;
storage::Storage db;
storage::Status s;
};

static bool field_value_match(storage::Storage* const db, const Slice& key,
const std::vector<FieldValue>& expect_field_value) {
std::vector<FieldValue> field_value_out;
Status s = db->HGetall(key, &field_value_out);
if (!s.ok() && !s.IsNotFound()) {
return false;
}
if (field_value_out.size() != expect_field_value.size()) {
return false;
}
if (s.IsNotFound() && expect_field_value.empty()) {
return true;
}
for (const auto& field_value : expect_field_value) {
if (find(field_value_out.begin(), field_value_out.end(), field_value) == field_value_out.end()) {
return false;
}
}
return true;
}

static bool field_value_match(const std::vector<FieldValue>& field_value_out,
const std::vector<FieldValue>& expect_field_value) {
if (field_value_out.size() != expect_field_value.size()) {
return false;
}
for (const auto& field_value : expect_field_value) {
if (find(field_value_out.begin(), field_value_out.end(), field_value) == field_value_out.end()) {
return false;
}
}
return true;
}

static bool size_match(storage::Storage* const db, const Slice& key, int32_t expect_size) {
int32_t size = 0;
Status s = db->HLen(key, &size);
if (!s.ok() && !s.IsNotFound()) {
return false;
}
if (s.IsNotFound() && (expect_size == 0)) {
return true;
}
return size == expect_size;
}

static bool make_expired(storage::Storage* const db, const Slice& key) {
std::map<storage::DataType, rocksdb::Status> type_status;
int ret = db->Expire(key, 1);
if ((ret == 0) || !type_status[storage::DataType::kHashes].ok()) {
return false;
}
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
return true;
}

// HDel
TEST_F(PKHashesTest, HDel) {
int32_t ret = 0;
std::vector<storage::FieldValue> fvs;
fvs.push_back({"TEST_FIELD1", "TEST_VALUE1"});
fvs.push_back({"TEST_FIELD2", "TEST_VALUE2"});
fvs.push_back({"TEST_FIELD3", "TEST_VALUE3"});
fvs.push_back({"TEST_FIELD4", "TEST_VALUE4"});

s = db.HMSet("HDEL_KEY", fvs);
ASSERT_TRUE(s.ok());

std::vector<std::string> fields{"TEST_FIELD1", "TEST_FIELD2", "TEST_FIELD3", "TEST_FIElD2", "TEST_NOT_EXIST_FIELD"};
s = db.HDel("HDEL_KEY", fields, &ret);
ASSERT_TRUE(s.ok());
ASSERT_EQ(ret, 3);

s = db.HLen("HDEL_KEY", &ret);
ASSERT_TRUE(s.ok());
ASSERT_EQ(ret, 1);

// Delete not exist hash table
s = db.HDel("HDEL_NOT_EXIST_KEY", fields, &ret);
ASSERT_TRUE(s.ok());
ASSERT_EQ(ret, 0);

// Delete timeout hash table
s = db.HMSet("HDEL_TIMEOUT_KEY", fvs);
ASSERT_TRUE(s.ok());

std::map<storage::DataType, rocksdb::Status> type_status;
db.Expire("HDEL_TIMEOUT_KEY", 1);
ASSERT_TRUE(type_status[storage::DataType::kHashes].ok());
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
s = db.HDel("HDEL_TIMEOUT_KEY", fields, &ret);
ASSERT_TRUE(s.ok());
ASSERT_EQ(ret, 0);
}

// HKeys
TEST_F(PKHashesTest, HKeys) {
int32_t ret = 0;
std::vector<storage::FieldValue> mid_fvs_in;
mid_fvs_in.push_back({"MID_TEST_FIELD1", "MID_TEST_VALUE1"});
mid_fvs_in.push_back({"MID_TEST_FIELD2", "MID_TEST_VALUE2"});
mid_fvs_in.push_back({"MID_TEST_FIELD3", "MID_TEST_VALUE3"});
s = db.HMSet("B_HKEYS_KEY", mid_fvs_in);
ASSERT_TRUE(s.ok());

std::vector<std::string> fields;
s = db.HKeys("B_HKEYS_KEY", &fields);
ASSERT_TRUE(s.ok());
ASSERT_EQ(fields.size(), 3);
ASSERT_EQ(fields[0], "MID_TEST_FIELD1");
ASSERT_EQ(fields[1], "MID_TEST_FIELD2");
ASSERT_EQ(fields[2], "MID_TEST_FIELD3");

// Insert some kv who's position above "mid kv"
std::vector<storage::FieldValue> pre_fvs_in;
pre_fvs_in.push_back({"PRE_TEST_FIELD1", "PRE_TEST_VALUE1"});
pre_fvs_in.push_back({"PRE_TEST_FIELD2", "PRE_TEST_VALUE2"});
pre_fvs_in.push_back({"PRE_TEST_FIELD3", "PRE_TEST_VALUE3"});
s = db.HMSet("A_HKEYS_KEY", pre_fvs_in);
ASSERT_TRUE(s.ok());
fields.clear();
s = db.HKeys("B_HKEYS_KEY", &fields);
ASSERT_TRUE(s.ok());
ASSERT_EQ(fields.size(), 3);
ASSERT_EQ(fields[0], "MID_TEST_FIELD1");
ASSERT_EQ(fields[1], "MID_TEST_FIELD2");
ASSERT_EQ(fields[2], "MID_TEST_FIELD3");

// Insert some kv who's position below "mid kv"
std::vector<storage::FieldValue> suf_fvs_in;
suf_fvs_in.push_back({"SUF_TEST_FIELD1", "SUF_TEST_VALUE1"});
suf_fvs_in.push_back({"SUF_TEST_FIELD2", "SUF_TEST_VALUE2"});
suf_fvs_in.push_back({"SUF_TEST_FIELD3", "SUF_TEST_VALUE3"});
s = db.HMSet("A_HKEYS_KEY", suf_fvs_in);
ASSERT_TRUE(s.ok());
fields.clear();
s = db.HKeys("B_HKEYS_KEY", &fields);
ASSERT_TRUE(s.ok());
ASSERT_EQ(fields.size(), 3);
ASSERT_EQ(fields[0], "MID_TEST_FIELD1");
ASSERT_EQ(fields[1], "MID_TEST_FIELD2");
ASSERT_EQ(fields[2], "MID_TEST_FIELD3");

// HKeys timeout hash table
fields.clear();
std::map<storage::DataType, rocksdb::Status> type_status;
db.Expire("B_HKEYS_KEY", 1);
ASSERT_TRUE(type_status[storage::DataType::kHashes].ok());
std::this_thread::sleep_for(std::chrono::milliseconds(2000));
s = db.HKeys("B_HKEYS_KEY", &fields);
ASSERT_TRUE(s.IsNotFound());
ASSERT_EQ(fields.size(), 0);

// HKeys not exist hash table
fields.clear();
s = db.HKeys("HKEYS_NOT_EXIST_KEY", &fields);
ASSERT_TRUE(s.IsNotFound());
ASSERT_EQ(fields.size(), 0);
}

int main(int argc, char** argv) {
if (!pstd::FileExists("./log")) {
pstd::CreatePath("./log");
}
FLAGS_log_dir = "./log";
FLAGS_minloglevel = 0;
FLAGS_max_log_size = 1800;
FLAGS_logbufsecs = 0;
::google::InitGoogleLogging("hashes_test");
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

0 comments on commit 8ba7edd

Please sign in to comment.