oceanbase/unittest/libobcdc/test_log_utils.cpp
ZenoWang ccde264e06 [FEAT MERGE] Improve the inner implementation of tx table
Co-authored-by: kongfy <njukongfy@gmail.com>
2023-05-07 07:38:34 +00:00

377 lines
11 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_define.h"
#include "deps/oblib/src/lib/container/ob_array_iterator.h"
#include "logservice/libobcdc/src/ob_log_utils.h"
using namespace oceanbase;
using namespace common;
using namespace libobcdc;
namespace oceanbase
{
namespace unittest
{
/*
* TEST1.
* Test split.
*/
TEST(utils, split)
{
int err = OB_SUCCESS;
char str[] = "tt1.database1";
const char *delimiter = ".";
const char *res[16];
int64_t res_cnt = 0;
err = split(str, delimiter, 2, res, res_cnt);
EXPECT_EQ(OB_SUCCESS, err);
EXPECT_EQ(2, res_cnt);
EXPECT_STREQ("tt1", res[0]);
EXPECT_STREQ("database1", res[1]);
char str1[] = "tt2.database2.test";
err = split(str1, delimiter, 3, res, res_cnt);
EXPECT_EQ(OB_SUCCESS, err);
EXPECT_EQ(3, res_cnt);
EXPECT_STREQ("tt2", res[0]);
EXPECT_STREQ("database2", res[1]);
EXPECT_STREQ("test", res[2]);
}
/*
* TEST2.
* Test split. Boundary tests
*/
TEST(utils, split_boundary)
{
int err = OB_SUCCESS;
char str[] = "tt1.database1";
const char *delimiter = ".";
const char *res[16];
int64_t res_cnt = 0;
err = split(NULL, delimiter, 2, res, res_cnt);
EXPECT_EQ(OB_INVALID_ARGUMENT, err);
EXPECT_EQ(0, res_cnt);
char str1[] = "";
err = split(str1, delimiter, 2, res, res_cnt);
EXPECT_EQ(OB_INVALID_ARGUMENT, err);
EXPECT_EQ(0, res_cnt);
err = split(str, NULL, 2, res, res_cnt);
EXPECT_EQ(OB_INVALID_ARGUMENT, err);
EXPECT_EQ(0, res_cnt);
const char *delimiter1 = "";
err = split(str, delimiter1, 2, res, res_cnt);
EXPECT_EQ(OB_INVALID_ARGUMENT, err);
EXPECT_EQ(0, res_cnt);
// Test for incoming length errors
err = split(str, delimiter, 1, res, res_cnt);
EXPECT_EQ(OB_INVALID_ARGUMENT, err);
EXPECT_EQ(1, res_cnt);
}
TEST(utils, split_int64_all)
{
char delimiter = '|';
ObString str;
const char *ptr = NULL;
ObSEArray<int64_t, 8> ret_array;
// Store a single number
ptr = "100";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(1, ret_array.count());
EXPECT_EQ(100, ret_array.at(0));
// Store multi numbers
ptr = "100|2000|30000|400000";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(4, ret_array.count());
EXPECT_EQ(100, ret_array.at(0));
EXPECT_EQ(2000, ret_array.at(1));
EXPECT_EQ(30000, ret_array.at(2));
EXPECT_EQ(400000, ret_array.at(3));
// Store multiple numbers with a separator at the end
ptr = "100|2000|30000|400000|";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(4, ret_array.count());
EXPECT_EQ(100, ret_array.at(0));
EXPECT_EQ(2000, ret_array.at(1));
EXPECT_EQ(30000, ret_array.at(2));
EXPECT_EQ(400000, ret_array.at(3));
// no number
ptr = "";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(0, ret_array.count());
// obly seperator
ptr = "|";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(0, ret_array.count());
// There are no numbers, only invalid content
ptr = ",";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_INVALID_DATA, split_int64(str, delimiter, ret_array));
EXPECT_EQ(0, ret_array.count());
// Numerical limit values
char max_int[100];
snprintf(max_int, sizeof(max_int), "%ld", INT64_MAX);
str.assign_ptr(max_int, (ObString::obstr_size_t)strlen(max_int));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(1, ret_array.count());
EXPECT_EQ(INT64_MAX, ret_array.at(0));
// Exceeding numerical limits
std::string over_size_int(100, '9');
str.assign_ptr(over_size_int.c_str(), (ObString::obstr_size_t)strlen(over_size_int.c_str()));
ret_array.reuse();
EXPECT_EQ(OB_INVALID_DATA, split_int64(str, delimiter, ret_array));
// Use other delimite characters
// Only the first one can be parsed
ptr = "100,200,300";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_INVALID_DATA, split_int64(str, delimiter, ret_array));
// constains other char
ptr = "100a|200b|300c";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_INVALID_DATA, split_int64(str, delimiter, ret_array));
// delimite at first pos
ptr = "|100|200|";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(2, ret_array.count());
EXPECT_EQ(100, ret_array.at(0));
EXPECT_EQ(200, ret_array.at(1));
// The separator appears several times in succession
ptr = "300||400|||500|";
str.assign_ptr(ptr, (ObString::obstr_size_t)strlen(ptr));
ret_array.reuse();
EXPECT_EQ(OB_SUCCESS, split_int64(str, delimiter, ret_array));
EXPECT_EQ(3, ret_array.count());
EXPECT_EQ(300, ret_array.at(0));
EXPECT_EQ(400, ret_array.at(1));
EXPECT_EQ(500, ret_array.at(2));
}
TEST(utils, kv_pair)
{
int ret = OB_SUCCESS;
char kv_str[] = "test:999";
const char *delimiter1 = ":";
const char *delimiter2 = "%";
ObLogKVCollection::KVPair kvpair;
ret = kvpair.init(delimiter1);
EXPECT_EQ(OB_SUCCESS, ret);
ret = kvpair.deserialize(kv_str);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_STREQ("test", kvpair.get_key());
EXPECT_STREQ("999", kvpair.get_value());
kvpair.reset();
char key[] = "kjdngasdey";
char value[] = "vaksahgasfashjlue";
ret = kvpair.init(delimiter2);
EXPECT_EQ(OB_SUCCESS, ret);
ret = kvpair.set_key_and_value(key, value);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_STREQ("kjdngasdey", kvpair.get_key());
EXPECT_STREQ("vaksahgasfashjlue", kvpair.get_value());
int64_t pos = 0;
int64_t len = kvpair.length();
EXPECT_EQ(strlen(key) + strlen(value) + strlen(delimiter2), len);
char buf[len+1];
ret = kvpair.serialize(buf, len+1, pos);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_STREQ("kjdngasdey%vaksahgasfashjlue", buf);
}
TEST(utils, kv_collection)
{
int ret = OB_SUCCESS;
char kv_str[] = "data:2346234;test:5asdfgasf; time:21354213";
int64_t origin_len = strlen(kv_str);
const char *pair_delimiter = "; ";
const char *kv_delimiter = ":";
ObLogKVCollection kv_c;
ret = kv_c.init(kv_delimiter, pair_delimiter);
EXPECT_EQ(OB_SUCCESS, ret);
ret = kv_c.deserialize(kv_str);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(3, kv_c.size());
int64_t len = kv_c.length();
EXPECT_EQ(origin_len, len-1);
bool contain = false;
ret = kv_c.contains_key("data", contain);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(true, contain);
ret = kv_c.contains_key("versin", contain);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(false, contain);
const char *value_time = NULL;
ret = kv_c.get_value_of_key("time", value_time);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_STREQ("21354213", value_time);
kv_c.reset();
// test append
kv_c.init(kv_delimiter, pair_delimiter);
ObLogKVCollection::KVPair kvpair;
char key[] = "jakds";
char value[] = "dsagads";
ret = kvpair.init(kv_delimiter);
EXPECT_EQ(OB_SUCCESS, ret);
ret = kvpair.set_key_and_value(key, value);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(true, kvpair.is_valid());
ret = kv_c.append_kv_pair(kvpair);
EXPECT_EQ(OB_SUCCESS, ret);
kvpair.reset();
char key1[] = "time";
char value1[] = "1237851204";
ret = kvpair.init(kv_delimiter);
EXPECT_EQ(OB_SUCCESS, ret);
ret = kvpair.set_key_and_value(key1, value1);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(true, kvpair.is_valid());
ret = kv_c.append_kv_pair(kvpair);
EXPECT_EQ(OB_SUCCESS, ret);
kvpair.reset();
ret = kv_c.contains_key("time1", contain);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(false, contain);
origin_len = strlen(key) + strlen(value) + strlen(key1) + strlen(value1)
+ 2 * strlen(kv_delimiter) + strlen(pair_delimiter);
len = kv_c.length();
EXPECT_EQ(origin_len, len);
char buf[len+1];
int64_t pos = 0;
ret = kv_c.serialize(buf, len+1, pos);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_STREQ("jakds:dsagads; time:1237851204", buf);
}
TEST(utils, cstring_to_num)
{
char numstr1[] = "123412";
char numstr2[] = "-683251";
char numstr3[] = "0";
char numstr4[] = "a123";
char numstr5[] = " 123";
char numstr6[] = "";
int64_t val = 0;
int ret = c_str_to_int(numstr1, val);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(123412, val);
ret = c_str_to_int(numstr2, val);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(-683251, val);
ret = c_str_to_int(numstr3, val);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(0, val);
ret = c_str_to_int(numstr4, val);
EXPECT_EQ(OB_INVALID_DATA, ret);
ret = c_str_to_int(numstr5, val);
EXPECT_EQ(OB_SUCCESS, ret);
EXPECT_EQ(123, val);
ret = c_str_to_int(numstr6, val);
EXPECT_EQ(OB_INVALID_ARGUMENT, ret);
}
TEST(utils, unique_arr_uint64)
{
auto fn = [](uint64_t &a, uint64_t &b) { return a < b; };
ObArray<uint64_t> arr;
EXPECT_EQ(OB_SUCCESS, arr.push_back(0));
EXPECT_EQ(OB_SUCCESS, arr.push_back(2));
EXPECT_EQ(OB_SUCCESS, arr.push_back(1));
EXPECT_EQ(OB_SUCCESS, arr.push_back(3));
EXPECT_EQ(OB_SUCCESS, arr.push_back(1));
EXPECT_EQ(OB_SUCCESS, arr.push_back(2));
EXPECT_EQ(OB_SUCCESS, arr.push_back(3));
EXPECT_EQ(OB_SUCCESS, arr.push_back(2));
EXPECT_EQ(OB_SUCCESS, sort_and_unique_array(arr, fn));
EXPECT_EQ(4, arr.count());
EXPECT_EQ(0, arr.at(0));
EXPECT_EQ(1, arr.at(1));
EXPECT_EQ(2, arr.at(2));
EXPECT_EQ(3, arr.at(3));
}
TEST(utils, unique_arr_lsn)
{
auto fn = [](palf::LSN &a, palf::LSN &b) { return a < b; };
ObSEArray<palf::LSN, 8> arr;
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(0)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(2)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(1)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(3)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(1)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(2)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(3)));
EXPECT_EQ(OB_SUCCESS, arr.push_back(palf::LSN(2)));
EXPECT_EQ(OB_SUCCESS, sort_and_unique_array(arr, fn));
EXPECT_EQ(4, arr.count());
EXPECT_EQ(palf::LSN(0), arr.at(0));
EXPECT_EQ(palf::LSN(1), arr.at(1));
EXPECT_EQ(palf::LSN(2), arr.at(2));
EXPECT_EQ(palf::LSN(3), arr.at(3));
}
}
}
int main(int argc, char **argv)
{
system("rm -f test_log_utils.log");
ObLogger &logger = ObLogger::get_logger();
bool not_output_obcdc_log = true;
logger.set_file_name("test_log_utils.log", not_output_obcdc_log, false);
logger.set_log_level(OB_LOG_LEVEL_DEBUG);
logger.set_mod_log_levels("ALL.*:DEBUG");
logger.set_enable_async_log(false);
testing::InitGoogleTest(&argc,argv);
// testing::FLAGS_gtest_filter = "DO_NOT_RUN";
return RUN_ALL_TESTS();
}