590 lines
25 KiB
C++
590 lines
25 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.
|
|
*/
|
|
|
|
#define USING_LOG_PREFIX SHARE
|
|
#include <gtest/gtest.h>
|
|
#include <gmock/gmock.h>
|
|
#define private public
|
|
#include "lib/oblog/ob_log.h"
|
|
#include "lib/time/ob_time_utility.h"
|
|
#include "lib/random/ob_random.h"
|
|
#include "lib/container/ob_array.h"
|
|
#include "lib/container/ob_array_iterator.h"
|
|
#include "lib/allocator/page_arena.h"
|
|
#define private public
|
|
#include "share/schema/ob_schema_cache.h"
|
|
#include "share/schema/ob_schema_service_sql_impl.h"
|
|
#include "schema_test_utils.h"
|
|
|
|
namespace oceanbase {
|
|
using namespace common;
|
|
namespace share {
|
|
namespace schema {
|
|
|
|
class GetBatchSchemasFuncs0 {
|
|
public:
|
|
// return non schema
|
|
int get_batch_tenants(const int64_t schema_version, ObArray<uint64_t>& tenant_ids, ObISQLClient& client,
|
|
ObIArray<ObTenantSchema>& tenant_infos)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(tenant_ids);
|
|
UNUSED(client);
|
|
UNUSED(tenant_infos);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_users(
|
|
const int64_t schema_version, ObArray<uint64_t>& user_ids, ObISQLClient& client, ObIArray<ObUserInfo>& user_infos)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(user_ids);
|
|
UNUSED(client);
|
|
UNUSED(user_infos);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_databases(const int64_t schema_version, ObArray<uint64_t>& db_ids, ObISQLClient& client,
|
|
ObIArray<ObDatabaseSchema>& db_schemas)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(db_ids);
|
|
UNUSED(client);
|
|
UNUSED(db_schemas);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_tablegroups(const int64_t schema_version, ObArray<uint64_t>& tg_ids, ObISQLClient& client,
|
|
ObIArray<ObTablegroupSchema>& tg_schemas)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(tg_ids);
|
|
UNUSED(client);
|
|
UNUSED(tg_schemas);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_outlines(const int64_t schema_version, ObArray<uint64_t>& outline_ids, ObISQLClient& client,
|
|
ObIArray<ObOutlineInfo>& outline_infos)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(outline_ids);
|
|
UNUSED(client);
|
|
UNUSED(outline_infos);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_table_schema(const uint64_t table_id, const int64_t schema_version, ObISQLClient& client,
|
|
ObIAllocator& allocator, ObTableSchema*& table_schema)
|
|
{
|
|
UNUSED(table_id);
|
|
UNUSED(schema_version);
|
|
UNUSED(client);
|
|
UNUSED(allocator);
|
|
UNUSED(table_schema);
|
|
return OB_SUCCESS;
|
|
}
|
|
|
|
int get_tablegroup_schema(const uint64_t tablegroup_id, const int64_t schema_version,
|
|
common::ObISQLClient& sql_client, common::ObIAllocator& allocator, ObTablegroupSchema*& tablegroup_schema)
|
|
{
|
|
UNUSED(tablegroup_id);
|
|
UNUSED(schema_version);
|
|
UNUSED(sql_client);
|
|
UNUSED(allocator);
|
|
UNUSED(tablegroup_schema);
|
|
return OB_SUCCESS;
|
|
}
|
|
};
|
|
|
|
class GetBatchSchemasFuncs1 {
|
|
public:
|
|
// return one schema
|
|
int get_batch_tenants(const int64_t schema_version, ObArray<uint64_t>& tenant_ids, ObISQLClient& client,
|
|
ObIArray<ObTenantSchema>& tenant_infos)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(tenant_ids);
|
|
UNUSED(client);
|
|
ObTenantSchema tenant_schema;
|
|
tenant_schema.set_tenant_id(1);
|
|
tenant_schema.set_tenant_name("tenant");
|
|
tenant_infos.push_back(tenant_schema);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_users(
|
|
const int64_t schema_version, ObArray<uint64_t>& user_ids, ObISQLClient& client, ObIArray<ObUserInfo>& user_infos)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(user_ids);
|
|
UNUSED(client);
|
|
ObUserInfo user_info;
|
|
user_info.set_tenant_id(1);
|
|
user_info.set_user_id(combine_id(1, 1));
|
|
user_info.set_user_name("user");
|
|
user_info.set_host(OB_DEFAULT_HOST_NAME);
|
|
user_infos.push_back(user_info);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_databases(const int64_t schema_version, ObArray<uint64_t>& db_ids, ObISQLClient& client,
|
|
ObIArray<ObDatabaseSchema>& db_schemas)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(db_ids);
|
|
UNUSED(client);
|
|
ObDatabaseSchema db_schema;
|
|
db_schema.set_tenant_id(1);
|
|
db_schema.set_database_id(combine_id(1, 1));
|
|
db_schema.set_database_name("db");
|
|
db_schemas.push_back(db_schema);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_tablegroups(const int64_t schema_version, ObArray<uint64_t>& tg_ids, ObISQLClient& client,
|
|
ObIArray<ObTablegroupSchema>& tg_schemas)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(tg_ids);
|
|
UNUSED(client);
|
|
ObTablegroupSchema tg_schema;
|
|
tg_schema.set_tenant_id(1);
|
|
tg_schema.set_tablegroup_id(combine_id(1, 1));
|
|
tg_schema.set_tablegroup_name("tg");
|
|
tg_schemas.push_back(tg_schema);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_table_schema(const uint64_t table_id, const int64_t schema_version, ObISQLClient& client,
|
|
ObIAllocator& allocator, ObTableSchema*& table_schema)
|
|
{
|
|
UNUSED(table_id);
|
|
UNUSED(schema_version);
|
|
UNUSED(client);
|
|
UNUSED(allocator);
|
|
ObTableSchema table;
|
|
// table_info.set_tenant_id(1);
|
|
// table_info.set_table_id(combine_id(1,1));
|
|
// table_info.set_table_name("table");
|
|
table_schema = &table;
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_batch_outlines(const int64_t schema_version, ObArray<uint64_t>& outline_ids, ObISQLClient& client,
|
|
ObIArray<ObOutlineInfo>& outline_infos)
|
|
{
|
|
UNUSED(schema_version);
|
|
UNUSED(outline_ids);
|
|
UNUSED(client);
|
|
ObOutlineInfo outline_info;
|
|
outline_info.set_tenant_id(1);
|
|
outline_info.set_outline_id(combine_id(1, 1));
|
|
outline_info.set_name("outline");
|
|
outline_infos.push_back(outline_info);
|
|
return OB_SUCCESS;
|
|
}
|
|
int get_tablegroup_schema(const uint64_t tablegroup_id, const int64_t schema_version,
|
|
common::ObISQLClient& sql_client, common::ObIAllocator& allocator, ObTablegroupSchema*& tablegroup_schema)
|
|
{
|
|
UNUSED(tablegroup_id);
|
|
UNUSED(schema_version);
|
|
UNUSED(sql_client);
|
|
UNUSED(allocator);
|
|
ObTablegroupSchema tg_schema;
|
|
tablegroup_schema = &tg_schema;
|
|
return OB_SUCCESS;
|
|
}
|
|
};
|
|
|
|
class TestSchemaCache : public ::testing::Test {
|
|
public:
|
|
virtual void SetUp();
|
|
virtual void TearDown();
|
|
|
|
private:
|
|
GetBatchSchemasFuncs0 get_batch_schemas_funcs0;
|
|
GetBatchSchemasFuncs1 get_batch_schemas_funcs1;
|
|
};
|
|
|
|
void TestSchemaCache::TearDown()
|
|
{
|
|
ObKVGlobalCache::get_instance().destroy();
|
|
}
|
|
|
|
void TestSchemaCache::SetUp()
|
|
{
|
|
const int64_t bucket_num = 1024;
|
|
const int64_t max_cache_size = 1024 * 1024 * 512;
|
|
const int64_t block_size = OB_MALLOC_BIG_BLOCK_SIZE;
|
|
ObKVGlobalCache::get_instance().init(bucket_num, max_cache_size, block_size);
|
|
}
|
|
|
|
TEST_F(TestSchemaCache, schema_key)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
// hash && operator ==
|
|
ObSchemaCacheKey cache_key_a(TENANT_SCHEMA, 1, 1);
|
|
ObSchemaCacheKey cache_key_b(TENANT_SCHEMA, 1, 1);
|
|
ObSchemaCacheKey cache_key_c(TENANT_SCHEMA, 2, 1);
|
|
ASSERT_TRUE(cache_key_a.hash() == cache_key_b.hash());
|
|
ASSERT_TRUE(cache_key_a == cache_key_b);
|
|
ASSERT_FALSE(cache_key_a.hash() == cache_key_c.hash());
|
|
ASSERT_FALSE(cache_key_a == cache_key_c);
|
|
// get_tenant_id
|
|
ASSERT_EQ(OB_SYS_TENANT_ID, cache_key_a.get_tenant_id());
|
|
// size
|
|
ASSERT_EQ(sizeof(ObSchemaCacheKey), cache_key_a.size());
|
|
// deep_copy
|
|
char* buf = new char[cache_key_a.size()];
|
|
ObIKVCacheKey* tmp_cache_key = NULL;
|
|
ret = cache_key_a.deep_copy(buf, cache_key_a.size(), tmp_cache_key);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != tmp_cache_key);
|
|
ASSERT_EQ(cache_key_a, *static_cast<ObSchemaCacheKey*>(tmp_cache_key));
|
|
// to_string
|
|
LOG_INFO("test schema key to_string", K(cache_key_a));
|
|
}
|
|
|
|
TEST_F(TestSchemaCache, schema_value)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
#define DEEP_COPY(xx_schema, SCHEMA, SCHEMA_TYPE_ENUM, SCHEMA_TYPE) \
|
|
{ \
|
|
ObSchemaCacheValue cache_value(SCHEMA_TYPE_ENUM, &xx_schema); \
|
|
LOG_INFO("test schema value to_string", K(cache_value)); \
|
|
ASSERT_EQ(sizeof(ObSchemaCacheValue) + xx_schema.get_convert_size() + sizeof(ObDataBuffer), cache_value.size()); \
|
|
char* buf = new char[cache_value.size()]; \
|
|
ObIKVCacheValue* tmp_cache_value = NULL; \
|
|
ret = cache_value.deep_copy(buf, cache_value.size(), tmp_cache_value); \
|
|
ASSERT_EQ(OB_SUCCESS, ret); \
|
|
ASSERT_TRUE(NULL != tmp_cache_value); \
|
|
const ObSchemaCacheValue* tmp_schema_cache_value = static_cast<ObSchemaCacheValue*>(tmp_cache_value); \
|
|
ASSERT_TRUE(SchemaTestUtils::equal_##SCHEMA##_schema( \
|
|
xx_schema, *static_cast<SCHEMA_TYPE*>(tmp_schema_cache_value->schema_))); \
|
|
}
|
|
// tenant
|
|
ObTenantSchema tenant_schema;
|
|
tenant_schema.set_tenant_id(1);
|
|
tenant_schema.set_tenant_name("tenant");
|
|
DEEP_COPY(tenant_schema, tenant, TENANT_SCHEMA, ObTenantSchema);
|
|
// user
|
|
ObUserInfo user_schema;
|
|
user_schema.set_tenant_id(1);
|
|
user_schema.set_user_id(combine_id(1, 1));
|
|
user_schema.set_user_name("user");
|
|
user_schema.set_host(OB_DEFAULT_HOST_NAME);
|
|
DEEP_COPY(user_schema, user, USER_SCHEMA, ObUserInfo);
|
|
// database
|
|
ObDatabaseSchema database_schema;
|
|
database_schema.set_tenant_id(1);
|
|
database_schema.set_database_id(combine_id(1, 1));
|
|
database_schema.set_database_name("database");
|
|
DEEP_COPY(database_schema, database, DATABASE_SCHEMA, ObDatabaseSchema);
|
|
// tablegroup
|
|
ObTablegroupSchema tablegroup_schema;
|
|
tablegroup_schema.set_tenant_id(1);
|
|
tablegroup_schema.set_tablegroup_id(combine_id(1, 1));
|
|
tablegroup_schema.set_tablegroup_name("tablegroup");
|
|
DEEP_COPY(tablegroup_schema, tablegroup, TABLEGROUP_SCHEMA, ObTablegroupSchema);
|
|
// table
|
|
ObTableSchema table_schema;
|
|
table_schema.set_tenant_id(1);
|
|
table_schema.set_database_id(combine_id(1, 1));
|
|
table_schema.set_table_id(combine_id(1, 1));
|
|
table_schema.set_table_name("table");
|
|
DEEP_COPY(table_schema, table, TABLE_SCHEMA, ObTableSchema);
|
|
// outline
|
|
ObOutlineInfo outline_schema;
|
|
outline_schema.set_tenant_id(1);
|
|
outline_schema.set_database_id(combine_id(1, 1));
|
|
outline_schema.set_outline_id(combine_id(1, 1));
|
|
outline_schema.set_name("outline");
|
|
outline_schema.set_signature("sig");
|
|
DEEP_COPY(outline_schema, outline, OUTLINE_SCHEMA, ObOutlineInfo);
|
|
}
|
|
|
|
TEST_F(TestSchemaCache, is_valid_key)
|
|
{
|
|
ObSchemaCache schema_cache;
|
|
ASSERT_EQ(OB_SUCCESS, schema_cache.init());
|
|
ASSERT_FALSE(schema_cache.is_valid_key(OB_MAX_SCHEMA, OB_INVALID_VERSION, -1));
|
|
ASSERT_FALSE(schema_cache.is_valid_key(TABLE_SCHEMA, OB_INVALID_VERSION, -1));
|
|
ASSERT_FALSE(schema_cache.is_valid_key(TABLE_SCHEMA, 1, -1));
|
|
ASSERT_TRUE(schema_cache.is_valid_key(TABLE_SCHEMA, 1, 1));
|
|
}
|
|
|
|
TEST_F(TestSchemaCache, need_use_sys_cache)
|
|
{
|
|
ObSchemaCache schema_cache;
|
|
ASSERT_EQ(OB_SUCCESS, schema_cache.init());
|
|
ObSchemaCacheKey cache_key;
|
|
ASSERT_TRUE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TENANT_SCHEMA, 1, 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TENANT_SCHEMA, 2, 1)));
|
|
ASSERT_TRUE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(USER_SCHEMA, combine_id(1, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(USER_SCHEMA, combine_id(2, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(DATABASE_SCHEMA, combine_id(1, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(DATABASE_SCHEMA, combine_id(2, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TABLEGROUP_SCHEMA, combine_id(1, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TABLEGROUP_SCHEMA, combine_id(2, 1), 1)));
|
|
ASSERT_TRUE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TABLE_SCHEMA, combine_id(1, 1), 1)));
|
|
ASSERT_TRUE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TABLE_SCHEMA, combine_id(1, 50000), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TABLE_SCHEMA, combine_id(1, 50001), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(TABLE_SCHEMA, combine_id(2, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(OUTLINE_SCHEMA, combine_id(1, 1), 1)));
|
|
ASSERT_FALSE(schema_cache.need_use_sys_cache(cache_key = ObSchemaCacheKey(OUTLINE_SCHEMA, combine_id(1, 2), 1)));
|
|
}
|
|
|
|
TEST_F(TestSchemaCache, schema_cache)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObSchemaCache schema_cache;
|
|
ObKVCacheHandle handle;
|
|
const ObSchema* dst_schema = NULL;
|
|
// not init when get
|
|
ret = schema_cache.get_schema(TENANT_SCHEMA, 1, 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
ASSERT_EQ(OB_SUCCESS, schema_cache.init());
|
|
// invalid arg when get
|
|
ret = schema_cache.get_schema(OB_MAX_SCHEMA, 1, 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_cache.get_schema(TENANT_SCHEMA, OB_INVALID_ID, 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_cache.get_schema(TENANT_SCHEMA, 1, -1, handle, dst_schema);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
// not exist
|
|
ret = schema_cache.get_schema(TENANT_SCHEMA, 1, 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret);
|
|
ASSERT_TRUE(NULL == dst_schema);
|
|
// sys cache
|
|
ObTenantSchema tenant_schema;
|
|
tenant_schema.set_tenant_id(1);
|
|
tenant_schema.set_tenant_name("fds");
|
|
tenant_schema.set_schema_version(1);
|
|
// not init when put
|
|
schema_cache.is_inited_ = false;
|
|
ret = schema_cache.put_schema(TENANT_SCHEMA, 1, 1, tenant_schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
schema_cache.is_inited_ = true;
|
|
// invalid arg when put
|
|
ret = schema_cache.put_schema(OB_MAX_SCHEMA, 1, 1, tenant_schema);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_cache.put_schema(TENANT_SCHEMA, OB_INVALID_ID, 1, tenant_schema);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_cache.put_schema(TENANT_SCHEMA, 1, -1, tenant_schema);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_cache.put_schema(TENANT_SCHEMA, 1, 1, tenant_schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ret = schema_cache.get_schema(TENANT_SCHEMA, 1, 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != dst_schema);
|
|
ASSERT_TRUE(SchemaTestUtils::equal_tenant_schema(tenant_schema, *static_cast<const ObTenantSchema*>(dst_schema)));
|
|
// no sys cache
|
|
ret = schema_cache.get_schema(DATABASE_SCHEMA, combine_id(1, 1), 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_ENTRY_NOT_EXIST, ret);
|
|
ASSERT_TRUE(NULL == dst_schema);
|
|
ObDatabaseSchema db_schema;
|
|
db_schema.set_tenant_id(1);
|
|
db_schema.set_database_id(combine_id(1, 1));
|
|
db_schema.set_database_name("fds");
|
|
db_schema.set_schema_version(1);
|
|
ret = schema_cache.put_schema(DATABASE_SCHEMA, combine_id(1, 1), 1, db_schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ret = schema_cache.get_schema(DATABASE_SCHEMA, combine_id(1, 1), 1, handle, dst_schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != dst_schema);
|
|
ASSERT_TRUE(SchemaTestUtils::equal_database_schema(db_schema, *static_cast<const ObDatabaseSchema*>(dst_schema)));
|
|
}
|
|
|
|
using ::testing::_;
|
|
using ::testing::Invoke;
|
|
using ::testing::Return;
|
|
class MockSchemaServiceSQLImpl : public ObSchemaServiceSQLImpl {
|
|
public:
|
|
MOCK_METHOD4(get_batch_tenants, int(const int64_t, ObArray<uint64_t>&, ObISQLClient&, ObIArray<ObTenantSchema>&));
|
|
MOCK_METHOD4(get_batch_users, int(const int64_t, ObArray<uint64_t>&, ObISQLClient&, ObIArray<ObUserInfo>&));
|
|
MOCK_METHOD4(get_batch_databases, int(const int64_t, ObArray<uint64_t>&, ObISQLClient&, ObIArray<ObDatabaseSchema>&));
|
|
MOCK_METHOD4(
|
|
get_batch_tablegroups, int(const int64_t, ObArray<uint64_t>&, ObISQLClient&, ObIArray<ObTablegroupSchema>&));
|
|
MOCK_METHOD4(get_batch_outlines, int(const int64_t, ObArray<uint64_t>&, ObISQLClient&, ObIArray<ObOutlineInfo>&));
|
|
MOCK_METHOD5(get_table_schema, int(const uint64_t, const int64_t, ObISQLClient&, ObIAllocator&, ObTableSchema*&));
|
|
MOCK_METHOD5(
|
|
get_tablegroup_schema, int(const uint64_t, const int64_t, ObISQLClient&, ObIAllocator&, ObTablegroupSchema*&));
|
|
virtual int can_read_schema_version(int64_t expected_version)
|
|
{
|
|
UNUSED(expected_version);
|
|
return common::OB_SUCCESS;
|
|
}
|
|
};
|
|
|
|
TEST_F(TestSchemaCache, schema_fetcher)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObArenaAllocator allocator;
|
|
ObSchemaFetcher schema_fetcher;
|
|
MockSchemaServiceSQLImpl schema_service;
|
|
ObSchema* schema = NULL;
|
|
// mock sql_clent for init
|
|
ObISQLClient* sql_client = reinterpret_cast<ObISQLClient*>(this);
|
|
|
|
// schema_fetcher is not inited
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, OB_INVALID_ID, -1, allocator, schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
ret = schema_fetcher.fetch_schema(USER_SCHEMA, OB_INVALID_ID, -1, allocator, schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
ret = schema_fetcher.fetch_schema(DATABASE_SCHEMA, OB_INVALID_ID, -1, allocator, schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
ret = schema_fetcher.fetch_schema(TABLEGROUP_SCHEMA, OB_INVALID_ID, -1, allocator, schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
ret = schema_fetcher.fetch_schema(TABLE_SCHEMA, OB_INVALID_ID, -1, allocator, schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
ret = schema_fetcher.fetch_schema(OUTLINE_SCHEMA, OB_INVALID_ID, -1, allocator, schema);
|
|
ASSERT_EQ(OB_INNER_STAT_ERROR, ret);
|
|
|
|
ret = schema_fetcher.init(NULL, sql_client);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_fetcher.init(&schema_service, NULL);
|
|
ASSERT_EQ(OB_INVALID_ARGUMENT, ret);
|
|
ret = schema_fetcher.init(&schema_service, sql_client);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// invalid arg
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, OB_INVALID_ID, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, 1, -1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(USER_SCHEMA, OB_INVALID_ID, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(USER_SCHEMA, 1, -1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(DATABASE_SCHEMA, OB_INVALID_ID, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(DATABASE_SCHEMA, 1, -1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(TABLEGROUP_SCHEMA, OB_INVALID_ID, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(TABLEGROUP_SCHEMA, 1, -1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(TABLE_SCHEMA, OB_INVALID_ID, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(TABLE_SCHEMA, 1, -1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(OUTLINE_SCHEMA, OB_INVALID_ID, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
ret = schema_fetcher.fetch_schema(OUTLINE_SCHEMA, 1, -1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_INVALID_ARGUMENT);
|
|
|
|
// schema_serice's get batch funcs failed
|
|
ON_CALL(schema_service, get_batch_tenants(_, _, _, _)).WillByDefault(Return(OB_ERROR));
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_ERROR);
|
|
ON_CALL(schema_service, get_batch_users(_, _, _, _)).WillByDefault(Return(OB_ERROR));
|
|
ret = schema_fetcher.fetch_schema(USER_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_ERROR);
|
|
ON_CALL(schema_service, get_batch_databases(_, _, _, _)).WillByDefault(Return(OB_ERROR));
|
|
ret = schema_fetcher.fetch_schema(DATABASE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_ERROR);
|
|
ON_CALL(schema_service, get_tablegroup_schema(_, _, _, _, _)).WillByDefault(Return(OB_ERROR));
|
|
ret = schema_fetcher.fetch_schema(TABLEGROUP_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_ERROR);
|
|
ON_CALL(schema_service, get_table_schema(_, _, _, _, _)).WillByDefault(Return(OB_ERROR));
|
|
ret = schema_fetcher.fetch_schema(TABLE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_ERROR);
|
|
ON_CALL(schema_service, get_batch_outlines(_, _, _, _)).WillByDefault(Return(OB_ERROR));
|
|
ret = schema_fetcher.fetch_schema(OUTLINE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(ret, OB_ERROR);
|
|
|
|
// schema_service's get batch func succeed, but no schema return
|
|
ON_CALL(schema_service, get_batch_databases(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs0, &GetBatchSchemasFuncs0::get_batch_databases));
|
|
ret = schema_fetcher.fetch_schema(DATABASE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
ON_CALL(schema_service, get_tablegroup_schema(_, _, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs0, &GetBatchSchemasFuncs0::get_tablegroup_schema));
|
|
ret = schema_fetcher.fetch_schema(TABLEGROUP_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
ON_CALL(schema_service, get_batch_users(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs0, &GetBatchSchemasFuncs0::get_batch_users));
|
|
ret = schema_fetcher.fetch_schema(USER_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
ON_CALL(schema_service, get_batch_tenants(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs0, &GetBatchSchemasFuncs0::get_batch_tenants));
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
ON_CALL(schema_service, get_batch_outlines(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs0, &GetBatchSchemasFuncs0::get_batch_outlines));
|
|
ret = schema_fetcher.fetch_schema(OUTLINE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
ON_CALL(schema_service, get_table_schema(_, _, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs0, &GetBatchSchemasFuncs0::get_table_schema));
|
|
ret = schema_fetcher.fetch_schema(TABLE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_ERR_UNEXPECTED, ret);
|
|
|
|
// schema_service's get batch func succeed
|
|
ON_CALL(schema_service, get_batch_tenants(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_batch_tenants));
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != schema);
|
|
ON_CALL(schema_service, get_batch_users(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_batch_users));
|
|
ret = schema_fetcher.fetch_schema(USER_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != schema);
|
|
ON_CALL(schema_service, get_batch_databases(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_batch_databases));
|
|
ret = schema_fetcher.fetch_schema(DATABASE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != schema);
|
|
ON_CALL(schema_service, get_tablegroup_schema(_, _, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_tablegroup_schema));
|
|
ret = schema_fetcher.fetch_schema(TABLEGROUP_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != schema);
|
|
ON_CALL(schema_service, get_table_schema(_, _, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_table_schema));
|
|
ret = schema_fetcher.fetch_schema(TABLE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != schema);
|
|
ON_CALL(schema_service, get_batch_outlines(_, _, _, _))
|
|
.WillByDefault(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_batch_outlines));
|
|
ret = schema_fetcher.fetch_schema(OUTLINE_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
ASSERT_TRUE(NULL != schema);
|
|
}
|
|
|
|
TEST_F(TestSchemaCache, schema_fetcher_connect_error)
|
|
{
|
|
int ret = OB_SUCCESS;
|
|
ObArenaAllocator allocator;
|
|
ObSchemaFetcher schema_fetcher;
|
|
MockSchemaServiceSQLImpl schema_service;
|
|
ObSchema* schema = NULL;
|
|
// mock sql_client for init
|
|
ObISQLClient* sql_client = reinterpret_cast<ObISQLClient*>(this);
|
|
|
|
ret = schema_fetcher.init(&schema_service, sql_client);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
|
|
// schema_service return OB_CONNECT_ERROR
|
|
// EXPECT_CALL(schema_service,
|
|
// get_batch_tenants(_,_,_,_)).Times(2).WillOnce(Return(OB_CONNECT_ERROR)).WillOnce(Return(OB_SUCCESS));
|
|
EXPECT_CALL(schema_service, get_batch_tenants(_, _, _, _))
|
|
.Times(2)
|
|
.WillOnce(Return(OB_CONNECT_ERROR))
|
|
.WillOnce(Invoke(&get_batch_schemas_funcs1, &GetBatchSchemasFuncs1::get_batch_tenants));
|
|
ret = schema_fetcher.fetch_schema(TENANT_SCHEMA, 1, 1, allocator, schema);
|
|
ASSERT_EQ(OB_SUCCESS, ret);
|
|
}
|
|
|
|
} // namespace schema
|
|
} // namespace share
|
|
} // namespace oceanbase
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
oceanbase::common::ObLogger::get_logger().set_log_level("INFO");
|
|
OB_LOGGER.set_file_name("test_schema_cache.log", true);
|
|
testing::InitGoogleTest(&argc, argv);
|
|
return RUN_ALL_TESTS();
|
|
}
|