Files
oceanbase/unittest/storage/transaction/test_ob_gc_partition_adapter.cpp
gm 4a92b6d7df reformat source code
according to code styles, 'AccessModifierOffset' should be -2.
2021-06-17 10:40:36 +08:00

545 lines
15 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#include "share/ob_errno.h"
#include "lib/oblog/ob_log.h"
#include "lib/container/ob_se_array.h"
#include "lib/mysqlclient/ob_mysql_proxy.h"
#include "lib/mysqlclient/ob_isql_connection_pool.h"
#include "lib/mysqlclient/ob_isql_connection.h"
#include "lib/mysqlclient/ob_isql_result_handler.h"
#include "lib/mysqlclient/ob_mysql_result.h"
#include "common/ob_partition_key.h"
#include "storage/transaction/ob_gc_partition_adapter.h"
#include "observer/ob_server_struct.h"
namespace oceanbase {
using namespace common;
using namespace common::sqlclient;
using namespace transaction;
namespace unittest {
class MyConnectionPool : public ObISQLConnectionPool {
public:
MyConnectionPool()
{}
~MyConnectionPool()
{}
public:
// sql string escape
int escape(const char* from, const int64_t from_size, char* to, const int64_t to_size, int64_t& out_size)
{
UNUSEDx(from, from_size, to, to_size, out_size);
return OB_SUCCESS;
}
// acquired connection must be released
int acquire(ObISQLConnection*& conn, void* client_addr)
{
UNUSEDx(conn, client_addr);
return OB_SUCCESS;
}
int release(ObISQLConnection* conn, const bool success)
{
UNUSEDx(conn, success);
return OB_SUCCESS;
}
int on_client_inactive(void* client_addr)
{
UNUSEDx(client_addr);
return OB_SUCCESS;
}
};
class MyPartitionInfo {
public:
MyPartitionInfo() : tenant_id_(0), table_id_(0), partition_id_(0)
{}
MyPartitionInfo(const int64_t tenant_id, const int64_t table_id, const int64_t partition_id)
: tenant_id_(tenant_id), table_id_(table_id), partition_id_(partition_id)
{}
explicit MyPartitionInfo(const ObPartitionKey& pkey)
: tenant_id_(pkey.get_tenant_id()), table_id_(pkey.get_table_id()), partition_id_(pkey.get_partition_id())
{}
~MyPartitionInfo()
{}
int64_t get_tenant_id() const
{
return tenant_id_;
}
int64_t get_table_id() const
{
return table_id_;
}
int64_t get_partition_id() const
{
return partition_id_;
}
TO_STRING_KV(K_(tenant_id), K_(table_id), K_(partition_id));
private:
int64_t tenant_id_;
int64_t table_id_;
int64_t partition_id_;
};
class MyResult : public ObMySQLResult {
public:
MyResult() : index_(-1)
{}
~MyResult()
{}
public:
void reset()
{
array_.reset();
index_ = -1;
}
int push(const MyPartitionInfo& info)
{
return array_.push_back(info);
}
void rewind()
{
index_ = -1;
}
TO_STRING_KV(K_(array), K_(index));
public:
int close()
{
return OB_SUCCESS;
}
int next()
{
int ret = OB_SUCCESS;
index_++;
if (array_.count() <= index_) {
ret = OB_ITER_END;
}
return ret;
}
int print_info() const
{
return OB_SUCCESS;
}
int get_int(const int64_t col_idx, int64_t& int_val) const
{
int ret = OB_SUCCESS;
if (0 > index_) {
ret = OB_ERR_UNEXPECTED;
} else if (array_.count() <= index_) {
ret = OB_ITER_END;
} else {
const MyPartitionInfo& info = array_.at(index_);
if (0 == col_idx) {
int_val = info.get_tenant_id();
} else if (1 == col_idx) {
int_val = info.get_table_id();
} else if (2 == col_idx) {
int_val = info.get_partition_id();
} else {
ret = OB_ERR_UNEXPECTED;
}
}
return ret;
}
int get_uint(const int64_t col_idx, uint64_t& int_val) const
{
UNUSEDx(col_idx, int_val);
return OB_NOT_SUPPORTED;
}
int get_datetime(const int64_t col_idx, int64_t& datetime) const
{
UNUSEDx(col_idx, datetime);
return OB_NOT_SUPPORTED;
}
int get_date(const int64_t col_idx, int32_t& date) const
{
UNUSEDx(col_idx, date);
return OB_NOT_SUPPORTED;
}
int get_time(const int64_t col_idx, int64_t& time) const
{
UNUSEDx(col_idx, time);
return OB_NOT_SUPPORTED;
}
int get_year(const int64_t col_idx, uint8_t& year) const
{
UNUSEDx(col_idx, year);
return OB_NOT_SUPPORTED;
}
int get_bool(const int64_t col_idx, bool& bool_val) const
{
UNUSEDx(col_idx, bool_val);
return OB_NOT_SUPPORTED;
}
int get_varchar(const int64_t col_idx, common::ObString& varchar_val) const
{
UNUSEDx(col_idx, varchar_val);
return OB_NOT_SUPPORTED;
}
int get_raw(const int64_t col_idx, common::ObString& raw_val) const
{
UNUSEDx(col_idx, raw_val);
return OB_NOT_SUPPORTED;
}
int get_float(const int64_t col_idx, float& float_val) const
{
UNUSEDx(col_idx, float_val);
return OB_NOT_SUPPORTED;
}
int get_double(const int64_t col_idx, double& double_val) const
{
UNUSEDx(col_idx, double_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp(const int64_t col_idx, const common::ObTimeZoneInfo* tz_info, int64_t& int_val) const
{
UNUSEDx(col_idx, tz_info, int_val);
return OB_NOT_SUPPORTED;
}
int get_otimestamp_value(const int64_t col_idx, const common::ObTimeZoneInfo& tz_info, const common::ObObjType type,
common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_idx, tz_info, type, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp_tz(
const int64_t col_idx, const common::ObTimeZoneInfo& tz_info, common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_idx, tz_info, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp_ltz(
const int64_t col_idx, const common::ObTimeZoneInfo& tz_info, common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_idx, tz_info, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp_nano(
const int64_t col_idx, const common::ObTimeZoneInfo& tz_info, common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_idx, tz_info, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_interval_ym(const int64_t col_idx, common::ObIntervalYMValue& val) const
{
UNUSEDx(col_idx, val);
return OB_NOT_SUPPORTED;
}
int get_interval_ds(const int64_t col_idx, common::ObIntervalDSValue& val) const
{
UNUSEDx(col_idx, val);
return OB_NOT_SUPPORTED;
}
int get_nvarchar2(const int64_t col_idx, ObString& val) const
{
UNUSEDx(col_idx, val);
return OB_NOT_SUPPORTED;
}
int get_nchar(const int64_t col_idx, ObString& val) const
{
UNUSEDx(col_idx, val);
return OB_NOT_SUPPORTED;
}
int get_int(const char* col_name, int64_t& int_val) const
{
UNUSEDx(col_name, int_val);
return OB_NOT_SUPPORTED;
}
int get_uint(const char* col_name, uint64_t& int_val) const
{
UNUSEDx(col_name, int_val);
return OB_NOT_SUPPORTED;
}
int get_datetime(const char* col_name, int64_t& datetime) const
{
UNUSEDx(col_name, datetime);
return OB_NOT_SUPPORTED;
}
int get_date(const char* col_name, int32_t& date) const
{
UNUSEDx(col_name, date);
return OB_NOT_SUPPORTED;
}
int get_time(const char* col_name, int64_t& time) const
{
UNUSEDx(col_name, time);
return OB_NOT_SUPPORTED;
}
int get_year(const char* col_name, uint8_t& year) const
{
UNUSEDx(col_name, year);
return OB_NOT_SUPPORTED;
}
int get_bool(const char* col_name, bool& bool_val) const
{
UNUSEDx(col_name, bool_val);
return OB_NOT_SUPPORTED;
}
int get_varchar(const char* col_name, common::ObString& varchar_val) const
{
UNUSEDx(col_name, varchar_val);
return OB_NOT_SUPPORTED;
}
int get_raw(const char* col_name, common::ObString& raw_val) const
{
UNUSEDx(col_name, raw_val);
return OB_NOT_SUPPORTED;
}
int get_float(const char* col_name, float& float_val) const
{
UNUSEDx(col_name, float_val);
return OB_NOT_SUPPORTED;
}
int get_double(const char* col_name, double& double_val) const
{
UNUSEDx(col_name, double_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp(const char* col_name, const common::ObTimeZoneInfo* tz_info, int64_t& int_val) const
{
UNUSEDx(col_name, tz_info, int_val);
return OB_NOT_SUPPORTED;
}
int get_otimestamp_value(const char* col_name, const common::ObTimeZoneInfo& tz_info, const common::ObObjType type,
common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_name, tz_info, type, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp_tz(
const char* col_name, const common::ObTimeZoneInfo& tz_info, common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_name, tz_info, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp_ltz(
const char* col_name, const common::ObTimeZoneInfo& tz_info, common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_name, tz_info, otimestamp_val);
return OB_NOT_SUPPORTED;
}
int get_timestamp_nano(
const char* col_name, const common::ObTimeZoneInfo& tz_info, common::ObOTimestampData& otimestamp_val) const
{
UNUSEDx(col_name, tz_info, otimestamp_val);
return OB_NOT_SUPPORTED;
}
virtual int get_type(const int64_t col_idx, ObObjMeta& type) const override
{
UNUSEDx(col_idx, type);
return OB_NOT_SUPPORTED;
}
virtual int get_obj(const int64_t col_idx, ObObj& obj, const common::ObTimeZoneInfo* tz_info = NULL,
common::ObIAllocator* allocator = NULL) const override
{
UNUSEDx(col_idx, obj, tz_info, allocator);
return OB_NOT_SUPPORTED;
}
virtual int get_type(const char* col_name, ObObjMeta& type) const override
{
UNUSEDx(col_name, type);
return OB_NOT_SUPPORTED;
}
virtual int get_obj(const char* col_name, ObObj& obj) const override
{
UNUSEDx(col_name, obj);
return OB_NOT_SUPPORTED;
}
int get_interval_ym(const char* col_name, common::ObIntervalYMValue& val) const
{
UNUSEDx(col_name, val);
return OB_NOT_SUPPORTED;
}
int get_interval_ds(const char* col_name, common::ObIntervalDSValue& val) const
{
UNUSEDx(col_name, val);
return OB_NOT_SUPPORTED;
}
int get_nvarchar2(const char* col_name, ObString& val) const
{
UNUSEDx(col_name, val);
return OB_NOT_SUPPORTED;
}
int get_nchar(const char* col_name, ObString& val) const
{
UNUSEDx(col_name, val);
return OB_NOT_SUPPORTED;
}
private:
int inner_get_number(const int64_t col_idx, common::number::ObNumber& nmb_val, IAllocator& allocator) const
{
UNUSEDx(col_idx, nmb_val, allocator);
return OB_NOT_SUPPORTED;
}
int inner_get_number(const char* col_name, common::number::ObNumber& nmb_val, IAllocator& allocator) const
{
UNUSEDx(col_name, nmb_val, allocator);
return OB_NOT_SUPPORTED;
}
int inner_get_urowid(const int64_t, common::ObURowIDData&, common::ObIAllocator&) const
{
return OB_NOT_SUPPORTED;
}
int inner_get_urowid(const char*, common::ObURowIDData&, common::ObIAllocator&) const
{
return OB_NOT_SUPPORTED;
}
int inner_get_lob_locator(const char*, common::ObLobLocator*&, common::ObIAllocator&) const
{
return OB_NOT_SUPPORTED;
}
int inner_get_lob_locator(const int64_t, common::ObLobLocator*&, common::ObIAllocator&) const
{
return OB_NOT_SUPPORTED;
}
private:
ObSEArray<MyPartitionInfo, 16> array_;
int64_t index_;
};
class MyResultHandler : public ObISQLResultHandler {
public:
explicit MyResultHandler(MyResult& my_result) : my_result_(my_result)
{}
~MyResultHandler()
{}
public:
ObMySQLResult* mysql_result()
{
return &my_result_;
}
private:
MyResult& my_result_;
};
class MyProxy : public ObMySQLProxy {
public:
MyProxy()
{}
~MyProxy()
{}
public:
MyResult& get_result()
{
return my_result_;
}
public:
int read(ReadResult& res, const uint64_t tenant_id, const char* sql) override
{
int ret = OB_SUCCESS;
UNUSEDx(tenant_id, sql);
my_result_.rewind();
MyResultHandler* my_handler = NULL;
if (OB_FAIL(res.create_handler(my_handler, my_result_))) {
TRANS_LOG(ERROR, "create handler failed", K(ret));
}
return ret;
}
private:
MyResult my_result_;
};
class TestObGcPartitionAdapter : public ::testing::Test {
public:
virtual void SetUp()
{
GCTX.split_schema_version_ = OB_INVALID_VERSION;
}
virtual void TearDown()
{}
};
//////////////////////basic function test//////////////////////////////////////////
TEST_F(TestObGcPartitionAdapter, check_partition_exist)
{
TRANS_LOG(INFO, "called", "func", test_info_->name());
MyProxy my_proxy;
ObGCPartitionAdapter gc_adapter;
EXPECT_EQ(OB_SUCCESS, gc_adapter.init(&my_proxy));
EXPECT_EQ(OB_SUCCESS, gc_adapter.start());
MyResult& my_result = my_proxy.get_result();
const int64_t tenant_id1 = 1001;
const int64_t tenant_id2 = 1002;
const int64_t pure_id = 50011;
const int64_t table_id1 = combine_id(tenant_id1, pure_id);
const int64_t table_id2 = combine_id(tenant_id2, pure_id);
const int64_t partition_id = 0;
const int64_t partition_cnt = 0;
const ObPartitionKey pkey1(table_id1, partition_id, partition_cnt);
const ObPartitionKey pkey2(table_id1, partition_id + 1, partition_cnt);
const ObPartitionKey pkey3(table_id2, partition_id, partition_cnt);
const ObPartitionKey pkey4(table_id2, partition_id, partition_cnt + 1);
bool exist1 = false;
bool exist2 = false;
bool exist3 = false;
bool exist4 = false;
EXPECT_EQ(OB_SUCCESS, my_result.push(MyPartitionInfo(pkey1)));
EXPECT_EQ(OB_SUCCESS, my_result.push(MyPartitionInfo(pkey3)));
EXPECT_EQ(OB_EAGAIN, gc_adapter.check_partition_exist(pkey1, exist1));
EXPECT_EQ(OB_EAGAIN, gc_adapter.check_partition_exist(pkey2, exist2));
EXPECT_EQ(OB_EAGAIN, gc_adapter.check_partition_exist(pkey3, exist3));
EXPECT_EQ(OB_EAGAIN, gc_adapter.check_partition_exist(pkey4, exist4));
sleep(1);
EXPECT_EQ(OB_SUCCESS, gc_adapter.check_partition_exist(pkey1, exist1));
EXPECT_EQ(OB_SUCCESS, gc_adapter.check_partition_exist(pkey2, exist2));
EXPECT_EQ(OB_SUCCESS, gc_adapter.check_partition_exist(pkey3, exist3));
EXPECT_EQ(OB_SUCCESS, gc_adapter.check_partition_exist(pkey4, exist4));
EXPECT_TRUE(exist1);
EXPECT_FALSE(exist2);
EXPECT_TRUE(exist3);
EXPECT_TRUE(exist4);
gc_adapter.stop();
gc_adapter.wait();
}
//////////////////////////boundary test/////////////////////////////////////////
} // namespace unittest
} // namespace oceanbase
using namespace oceanbase;
using namespace oceanbase::common;
int main(int argc, char** argv)
{
int ret = 1;
ObLogger& logger = ObLogger::get_logger();
logger.set_file_name("test_ob_gc_partition_adapter.log", true);
logger.set_log_level(OB_LOG_LEVEL_INFO);
testing::InitGoogleTest(&argc, argv);
ret = RUN_ALL_TESTS();
return ret;
}