blob: c74959a0f7bfbbd18a2a14dd28404f310a71b4d5 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <fstream>
#include <sstream>
#include <string>
#include "boost/filesystem.hpp"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "json2pb/json_to_pb.h"
#include "olap/olap_meta.h"
#include "olap/rowset/alpha_rowset.h"
#include "olap/rowset/alpha_rowset_meta.h"
#include "olap/rowset/rowset_meta_manager.h"
#include "olap/storage_engine.h"
#include "olap/tablet_meta_manager.h"
#include "olap/txn_manager.h"
#include "util/file_utils.h"
#ifndef BE_TEST
#define BE_TEST
#endif
using ::testing::_;
using ::testing::Return;
using ::testing::SetArgPointee;
using std::string;
namespace doris {
static StorageEngine* k_engine = nullptr;
class TabletMgrTest : public testing::Test {
public:
virtual void SetUp() {
string test_engine_data_path = "./be/test/olap/test_data/converter_test_data/data";
_engine_data_path = "./be/test/olap/test_data/converter_test_data/tmp";
boost::filesystem::remove_all(_engine_data_path);
FileUtils::create_dir(_engine_data_path);
FileUtils::create_dir(_engine_data_path + "/meta");
config::tablet_map_shard_size = 1;
config::txn_map_shard_size = 1;
config::txn_shard_size = 1;
EngineOptions options;
// won't open engine, options.path is needless
options.backend_uid = UniqueId::gen_uid();
if (k_engine == nullptr) {
k_engine = new StorageEngine(options);
}
_data_dir = new DataDir(_engine_data_path, 1000000000);
_data_dir->init();
string tmp_data_path = _engine_data_path + "/data";
if (boost::filesystem::exists(tmp_data_path)) {
boost::filesystem::remove_all(tmp_data_path);
}
copy_dir(test_engine_data_path, tmp_data_path);
_tablet_id = 15007;
_schema_hash = 368169781;
_tablet_data_path = tmp_data_path + "/" + std::to_string(0) + "/" +
std::to_string(_tablet_id) + "/" + std::to_string(_schema_hash);
_tablet_mgr.reset(new TabletManager(1));
}
virtual void TearDown() {
delete _data_dir;
if (boost::filesystem::exists(_engine_data_path)) {
ASSERT_TRUE(boost::filesystem::remove_all(_engine_data_path));
}
}
private:
DataDir* _data_dir;
std::string _json_rowset_meta;
std::string _engine_data_path;
int64_t _tablet_id;
int32_t _schema_hash;
string _tablet_data_path;
std::unique_ptr<TabletManager> _tablet_mgr;
};
TEST_F(TabletMgrTest, CreateTablet) {
TColumnType col_type;
col_type.__set_type(TPrimitiveType::SMALLINT);
TColumn col1;
col1.__set_column_name("col1");
col1.__set_column_type(col_type);
col1.__set_is_key(true);
std::vector<TColumn> cols;
cols.push_back(col1);
TTabletSchema tablet_schema;
tablet_schema.__set_short_key_column_count(1);
tablet_schema.__set_schema_hash(3333);
tablet_schema.__set_keys_type(TKeysType::AGG_KEYS);
tablet_schema.__set_storage_type(TStorageType::COLUMN);
tablet_schema.__set_columns(cols);
TCreateTabletReq create_tablet_req;
create_tablet_req.__set_tablet_schema(tablet_schema);
create_tablet_req.__set_tablet_id(111);
create_tablet_req.__set_version(2);
create_tablet_req.__set_version_hash(3333);
std::vector<DataDir*> data_dirs;
data_dirs.push_back(_data_dir);
OLAPStatus create_st = _tablet_mgr->create_tablet(create_tablet_req, data_dirs);
ASSERT_TRUE(create_st == OLAP_SUCCESS);
TabletSharedPtr tablet = _tablet_mgr->get_tablet(111, 3333);
ASSERT_TRUE(tablet != nullptr);
// check dir exist
bool dir_exist = FileUtils::check_exist(tablet->tablet_path());
ASSERT_TRUE(dir_exist);
// check meta has this tablet
TabletMetaSharedPtr new_tablet_meta(new TabletMeta());
OLAPStatus check_meta_st = TabletMetaManager::get_meta(_data_dir, 111, 3333, new_tablet_meta);
ASSERT_TRUE(check_meta_st == OLAP_SUCCESS);
// retry create should be successfully
create_st = _tablet_mgr->create_tablet(create_tablet_req, data_dirs);
ASSERT_TRUE(create_st == OLAP_SUCCESS);
// create tablet with different schema hash should be error
tablet_schema.__set_schema_hash(4444);
create_tablet_req.__set_tablet_schema(tablet_schema);
create_st = _tablet_mgr->create_tablet(create_tablet_req, data_dirs);
ASSERT_TRUE(create_st == OLAP_ERR_CE_TABLET_ID_EXIST);
}
TEST_F(TabletMgrTest, CreateTabletWithSequence) {
std::vector<TColumn> cols;
TColumn col1;
col1.column_type.type = TPrimitiveType::SMALLINT;
col1.__set_column_name("col1");
col1.__set_is_key(true);
cols.push_back(col1);
TColumn col2;
col2.column_type.type = TPrimitiveType::INT;
col2.__set_column_name(SEQUENCE_COL);
col2.__set_is_key(false);
col2.__set_aggregation_type(TAggregationType::REPLACE);
cols.push_back(col2);
TColumn col3;
col3.column_type.type = TPrimitiveType::INT;
col3.__set_column_name("v1");
col3.__set_is_key(false);
col3.__set_aggregation_type(TAggregationType::REPLACE);
cols.push_back(col3);
TTabletSchema tablet_schema;
tablet_schema.__set_short_key_column_count(1);
tablet_schema.__set_schema_hash(3333);
tablet_schema.__set_keys_type(TKeysType::UNIQUE_KEYS);
tablet_schema.__set_storage_type(TStorageType::COLUMN);
tablet_schema.__set_columns(cols);
tablet_schema.__set_sequence_col_idx(1);
TCreateTabletReq create_tablet_req;
create_tablet_req.__set_tablet_schema(tablet_schema);
create_tablet_req.__set_tablet_id(111);
create_tablet_req.__set_version(2);
create_tablet_req.__set_version_hash(3333);
std::vector<DataDir*> data_dirs;
data_dirs.push_back(_data_dir);
OLAPStatus create_st = _tablet_mgr->create_tablet(create_tablet_req, data_dirs);
ASSERT_TRUE(create_st == OLAP_SUCCESS);
TabletSharedPtr tablet = _tablet_mgr->get_tablet(111, 3333);
ASSERT_TRUE(tablet != nullptr);
// check dir exist
bool dir_exist = FileUtils::check_exist(tablet->tablet_path());
ASSERT_TRUE(dir_exist);
// check meta has this tablet
TabletMetaSharedPtr new_tablet_meta(new TabletMeta());
OLAPStatus check_meta_st = TabletMetaManager::get_meta(_data_dir, 111, 3333, new_tablet_meta);
ASSERT_TRUE(check_meta_st == OLAP_SUCCESS);
}
TEST_F(TabletMgrTest, DropTablet) {
TColumnType col_type;
col_type.__set_type(TPrimitiveType::SMALLINT);
TColumn col1;
col1.__set_column_name("col1");
col1.__set_column_type(col_type);
col1.__set_is_key(true);
std::vector<TColumn> cols;
cols.push_back(col1);
TTabletSchema tablet_schema;
tablet_schema.__set_short_key_column_count(1);
tablet_schema.__set_schema_hash(3333);
tablet_schema.__set_keys_type(TKeysType::AGG_KEYS);
tablet_schema.__set_storage_type(TStorageType::COLUMN);
tablet_schema.__set_columns(cols);
TCreateTabletReq create_tablet_req;
create_tablet_req.__set_tablet_schema(tablet_schema);
create_tablet_req.__set_tablet_id(111);
create_tablet_req.__set_version(2);
create_tablet_req.__set_version_hash(3333);
std::vector<DataDir*> data_dirs;
data_dirs.push_back(_data_dir);
OLAPStatus create_st = _tablet_mgr->create_tablet(create_tablet_req, data_dirs);
ASSERT_TRUE(create_st == OLAP_SUCCESS);
TabletSharedPtr tablet = _tablet_mgr->get_tablet(111, 3333);
ASSERT_TRUE(tablet != nullptr);
// drop unexist tablet will be success
OLAPStatus drop_st = _tablet_mgr->drop_tablet(111, 4444, false);
ASSERT_TRUE(drop_st == OLAP_SUCCESS);
tablet = _tablet_mgr->get_tablet(111, 3333);
ASSERT_TRUE(tablet != nullptr);
// drop exist tablet will be success
drop_st = _tablet_mgr->drop_tablet(111, 3333, false);
ASSERT_TRUE(drop_st == OLAP_SUCCESS);
tablet = _tablet_mgr->get_tablet(111, 3333);
ASSERT_TRUE(tablet == nullptr);
tablet = _tablet_mgr->get_tablet(111, 3333, true);
ASSERT_TRUE(tablet != nullptr);
// check dir exist
std::string tablet_path = tablet->tablet_path();
bool dir_exist = FileUtils::check_exist(tablet_path);
ASSERT_TRUE(dir_exist);
// do trash sweep, tablet will not be garbage collected
// because tablet ptr referenced it
OLAPStatus trash_st = _tablet_mgr->start_trash_sweep();
ASSERT_TRUE(trash_st == OLAP_SUCCESS);
tablet = _tablet_mgr->get_tablet(111, 3333, true);
ASSERT_TRUE(tablet != nullptr);
dir_exist = FileUtils::check_exist(tablet_path);
ASSERT_TRUE(dir_exist);
// reset tablet ptr
tablet.reset();
trash_st = _tablet_mgr->start_trash_sweep();
ASSERT_TRUE(trash_st == OLAP_SUCCESS);
tablet = _tablet_mgr->get_tablet(111, 3333, true);
ASSERT_TRUE(tablet == nullptr);
dir_exist = FileUtils::check_exist(tablet_path);
ASSERT_TRUE(!dir_exist);
}
TEST_F(TabletMgrTest, GetRowsetId) {
// normal case
{
std::string path = _engine_data_path + "/data/0/15007/368169781";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_TRUE(_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
ASSERT_EQ(15007, tid);
ASSERT_EQ(368169781, schema_hash);
}
{
std::string path = _engine_data_path + "/data/0/15007/368169781/";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_TRUE(_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
ASSERT_EQ(15007, tid);
ASSERT_EQ(368169781, schema_hash);
}
// normal case
{
std::string path =
_engine_data_path +
"/data/0/15007/368169781/020000000000000100000000000000020000000000000003_0_0.dat";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_TRUE(_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
ASSERT_EQ(15007, tid);
ASSERT_EQ(368169781, schema_hash);
RowsetId id;
ASSERT_TRUE(_tablet_mgr->get_rowset_id_from_path(path, &id));
EXPECT_EQ(2UL << 56 | 1, id.hi);
ASSERT_EQ(2, id.mi);
ASSERT_EQ(3, id.lo);
}
// empty tablet directory
{
std::string path = _engine_data_path + "/data/0/15007";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_TRUE(_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
ASSERT_EQ(15007, tid);
ASSERT_EQ(0, schema_hash);
RowsetId id;
ASSERT_FALSE(_tablet_mgr->get_rowset_id_from_path(path, &id));
}
// empty tablet directory
{
std::string path = _engine_data_path + "/data/0/15007/";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_TRUE(_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
ASSERT_EQ(15007, tid);
ASSERT_EQ(0, schema_hash);
}
// empty tablet directory
{
std::string path = _engine_data_path + "/data/0/15007abc";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_FALSE(
_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
}
// not match pattern
{
std::string path =
_engine_data_path +
"/data/0/15007/123abc/020000000000000100000000000000020000000000000003_0_0.dat";
TTabletId tid;
TSchemaHash schema_hash;
ASSERT_FALSE(
_tablet_mgr->get_tablet_id_and_schema_hash_from_path(path, &tid, &schema_hash));
RowsetId id;
ASSERT_FALSE(_tablet_mgr->get_rowset_id_from_path(path, &id));
}
}
} // namespace doris
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}