377 lines
11 KiB
C++
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();
|
|
}
|