// 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 "meta-service/meta_service.h"

#include <brpc/controller.h>
#include <bvar/window.h>
#include <fmt/core.h>
#include <gen_cpp/cloud.pb.h>
#include <gen_cpp/olap_file.pb.h>
#include <google/protobuf/repeated_field.h>
#include <gtest/gtest.h>

#include <atomic>
#include <chrono>
#include <condition_variable>
#include <cstdint>
#include <memory>
#include <random>
#include <string>
#include <thread>

#include "common/config.h"
#include "common/logging.h"
#include "common/util.h"
#include "cpp/sync_point.h"
#include "meta-service/meta_service_helper.h"
#include "meta-store/blob_message.h"
#include "meta-store/document_message.h"
#include "meta-store/keys.h"
#include "meta-store/mem_txn_kv.h"
#include "meta-store/txn_kv.h"
#include "meta-store/txn_kv_error.h"
#include "meta-store/versioned_value.h"
#include "mock_resource_manager.h"
#include "rate-limiter/rate_limiter.h"
#include "resource-manager/resource_manager.h"

int main(int argc, char** argv) {
    const std::string conf_file = "doris_cloud.conf";
    if (!doris::cloud::config::init(conf_file.c_str(), true)) {
        std::cerr << "failed to init config file, conf=" << conf_file << std::endl;
        return -1;
    }

    config::enable_retry_txn_conflict = false;
    config::enable_txn_store_retry = true;
    config::txn_store_retry_base_intervals_ms = 1;
    config::txn_store_retry_times = 20;
    config::enable_check_instance_id = false;

    if (!doris::cloud::init_glog("meta_service_test")) {
        std::cerr << "failed to init glog" << std::endl;
        return -1;
    }
    ::testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

namespace doris::cloud {

std::unique_ptr<MetaServiceProxy> get_meta_service(bool mock_resource_mgr) {
    int ret = 0;
    // MemKv
    auto txn_kv = std::dynamic_pointer_cast<TxnKv>(std::make_shared<MemTxnKv>());
    if (txn_kv != nullptr) {
        ret = txn_kv->init();
        [&] { ASSERT_EQ(ret, 0); }();
    }
    [&] { ASSERT_NE(txn_kv.get(), nullptr); }();

    // FdbKv
    //     config::fdb_cluster_file_path = "fdb.cluster";
    //     static auto txn_kv = std::dynamic_pointer_cast<TxnKv>(std::make_shared<FdbTxnKv>());
    //     static std::atomic<bool> init {false};
    //     bool tmp = false;
    //     if (init.compare_exchange_strong(tmp, true)) {
    //         int ret = txn_kv->init();
    //         [&] { ASSERT_EQ(ret, 0); ASSERT_NE(txn_kv.get(), nullptr); }();
    //     }

    std::unique_ptr<Transaction> txn;
    EXPECT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->remove("\x00", "\xfe"); // This is dangerous if the fdb is not correctly set
    EXPECT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto rs = mock_resource_mgr ? std::make_shared<MockResourceManager>(txn_kv)
                                : std::make_shared<ResourceManager>(txn_kv);
    auto rl = std::make_shared<RateLimiter>();
    auto snapshot = std::make_shared<SnapshotManager>(txn_kv);
    auto meta_service = std::make_unique<MetaServiceImpl>(txn_kv, rs, rl, snapshot);
    return std::make_unique<MetaServiceProxy>(std::move(meta_service));
}

std::unique_ptr<MetaServiceProxy> get_meta_service() {
    return get_meta_service(true);
}

std::unique_ptr<MetaServiceProxy> get_fdb_meta_service() {
    config::fdb_cluster_file_path = "fdb.cluster";
    static auto txn_kv = std::dynamic_pointer_cast<TxnKv>(std::make_shared<FdbTxnKv>());
    static std::atomic<bool> init {false};
    bool tmp = false;
    if (init.compare_exchange_strong(tmp, true)) {
        int ret = txn_kv->init();
        [&] {
            ASSERT_EQ(ret, 0);
            ASSERT_NE(txn_kv.get(), nullptr);
        }();
    }
    auto rs = std::make_shared<MockResourceManager>(txn_kv);
    auto rl = std::make_shared<RateLimiter>();
    auto snapshot = std::make_shared<SnapshotManager>(txn_kv);
    auto meta_service = std::make_unique<MetaServiceImpl>(txn_kv, rs, rl, snapshot);
    return std::make_unique<MetaServiceProxy>(std::move(meta_service));
}

static std::string next_rowset_id() {
    static int cnt = 0;
    return std::to_string(++cnt);
}

void add_tablet(CreateTabletsRequest& req, int64_t table_id, int64_t index_id, int64_t partition_id,
                int64_t tablet_id) {
    auto tablet = req.add_tablet_metas();
    tablet->set_table_id(table_id);
    tablet->set_index_id(index_id);
    tablet->set_partition_id(partition_id);
    tablet->set_tablet_id(tablet_id);
    auto schema = tablet->mutable_schema();
    schema->set_schema_version(0);
    auto first_rowset = tablet->add_rs_metas();
    first_rowset->set_rowset_id(0); // required
    first_rowset->set_rowset_id_v2(next_rowset_id());
    first_rowset->set_start_version(0);
    first_rowset->set_end_version(1);
    first_rowset->mutable_tablet_schema()->CopyFrom(*schema);
}

void create_tablet(MetaServiceProxy* meta_service, int64_t table_id, int64_t index_id,
                   int64_t partition_id, int64_t tablet_id) {
    brpc::Controller cntl;
    CreateTabletsRequest req;
    CreateTabletsResponse res;
    req.set_db_id(1); // default db_id
    add_tablet(req, table_id, index_id, partition_id, tablet_id);
    meta_service->create_tablets(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << tablet_id;
}

static void create_tablet_with_db_id(MetaServiceProxy* meta_service, int64_t db_id,
                                     int64_t table_id, int64_t index_id, int64_t partition_id,
                                     int64_t tablet_id) {
    brpc::Controller cntl;
    CreateTabletsRequest req;
    CreateTabletsResponse res;
    req.set_db_id(db_id);
    add_tablet(req, table_id, index_id, partition_id, tablet_id);
    meta_service->create_tablets(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << tablet_id;
}

static void begin_txn(MetaServiceProxy* meta_service, int64_t db_id, const std::string& label,
                      int64_t table_id, int64_t& txn_id) {
    brpc::Controller cntl;
    BeginTxnRequest req;
    BeginTxnResponse res;
    auto txn_info = req.mutable_txn_info();
    txn_info->set_db_id(db_id);
    txn_info->set_label(label);
    txn_info->add_table_ids(table_id);
    txn_info->set_timeout_ms(36000);
    meta_service->begin_txn(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
    ASSERT_TRUE(res.has_txn_id()) << label;
    txn_id = res.txn_id();
}

static void commit_txn(MetaServiceProxy* meta_service, int64_t db_id, int64_t txn_id,
                       const std::string& label) {
    brpc::Controller cntl;
    CommitTxnRequest req;
    CommitTxnResponse res;
    req.set_db_id(db_id);
    req.set_txn_id(txn_id);
    meta_service->commit_txn(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK)
            << label << ", res=" << res.ShortDebugString();
}

doris::RowsetMetaCloudPB create_rowset(int64_t txn_id, int64_t tablet_id, int partition_id = 10,
                                       int64_t version = -1, int num_rows = 100) {
    doris::RowsetMetaCloudPB rowset;
    rowset.set_rowset_id(0); // required
    rowset.set_rowset_id_v2(next_rowset_id());
    rowset.set_tablet_id(tablet_id);
    rowset.set_partition_id(partition_id);
    rowset.set_txn_id(txn_id);
    if (version > 0) {
        rowset.set_start_version(version);
        rowset.set_end_version(version);
    }
    rowset.set_num_segments(1);
    rowset.set_num_rows(num_rows);
    rowset.set_data_disk_size(num_rows * 100);
    rowset.set_index_disk_size(num_rows * 10);
    rowset.set_total_disk_size(num_rows * 110);
    rowset.mutable_tablet_schema()->set_schema_version(0);
    rowset.set_txn_expiration(::time(nullptr)); // Required by DCHECK
    return rowset;
}

static void prepare_rowset(MetaServiceProxy* meta_service, const doris::RowsetMetaCloudPB& rowset,
                           CreateRowsetResponse& res) {
    brpc::Controller cntl;
    auto arena = res.GetArena();
    auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
    req->mutable_rowset_meta()->CopyFrom(rowset);
    meta_service->prepare_rowset(&cntl, req, &res, nullptr);
    if (!arena) delete req;
}

void commit_rowset(MetaServiceProxy* meta_service, const doris::RowsetMetaCloudPB& rowset,
                   CreateRowsetResponse& res) {
    brpc::Controller cntl;
    auto arena = res.GetArena();
    auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
    req->mutable_rowset_meta()->CopyFrom(rowset);
    meta_service->commit_rowset(&cntl, req, &res, nullptr);
    if (!arena) delete req;
}

static void update_tmp_rowset(MetaServiceProxy* meta_service,
                              const doris::RowsetMetaCloudPB& rowset, CreateRowsetResponse& res) {
    brpc::Controller cntl;
    auto arena = res.GetArena();
    auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
    req->mutable_rowset_meta()->CopyFrom(rowset);
    meta_service->update_tmp_rowset(&cntl, req, &res, nullptr);
    if (!arena) delete req;
}

static void get_delete_bitmap_update_lock(MetaServiceProxy* meta_service,
                                          GetDeleteBitmapUpdateLockResponse& res, int64_t db_id,
                                          int64_t table_id, int64_t index_id,
                                          const std::vector<std::array<int64_t, 2>>& tablet_idxes,
                                          int64_t expiration, int64_t lock_id, int64_t initiator,
                                          bool require_compaction_stats) {
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest req;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_table_id(table_id);
    for (const auto& [partition_id, _] : tablet_idxes) {
        req.add_partition_ids(partition_id);
    }
    req.set_expiration(expiration);
    req.set_lock_id(lock_id);
    req.set_initiator(initiator);
    req.set_require_compaction_stats(require_compaction_stats);
    for (const auto& [partition_id, tablet_id] : tablet_idxes) {
        TabletIndexPB* idx = req.add_tablet_indexes();
        idx->set_db_id(db_id);
        idx->set_table_id(table_id);
        idx->set_index_id(index_id);
        idx->set_partition_id(partition_id);
        idx->set_tablet_id(tablet_id);
    }
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
}

void insert_rowset(MetaServiceProxy* meta_service, int64_t db_id, const std::string& label,
                   int64_t table_id, int64_t partition_id, int64_t tablet_id) {
    int64_t txn_id = 0;
    ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service, db_id, label, table_id, txn_id));
    CreateRowsetResponse res;
    auto rowset = create_rowset(txn_id, tablet_id, partition_id);
    prepare_rowset(meta_service, rowset, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
    res.Clear();
    ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service, rowset, res));
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
    commit_txn(meta_service, db_id, txn_id, label);
}

void insert_rowsets(MetaServiceProxy* meta_service, int64_t db_id, const std::string& label,
                    int64_t table_id, int64_t partition_id, std::vector<int64_t> tablet_ids) {
    int64_t txn_id = 0;
    ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service, db_id, label, table_id, txn_id));
    for (auto tablet_id : tablet_ids) {
        CreateRowsetResponse res;
        auto rowset = create_rowset(txn_id, tablet_id, partition_id);
        prepare_rowset(meta_service, rowset, res);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        res.Clear();
        ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service, rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
    }
    commit_txn(meta_service, db_id, txn_id, label);
}

static void add_tablet_metas(MetaServiceProxy* meta_service, std::string instance_id,
                             int64_t table_id, int64_t index_id,
                             const std::vector<std::array<int64_t, 2>>& tablet_idxes,
                             bool skip_tablet_meta = false) {
    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);

    for (const auto& idx : tablet_idxes) {
        int64_t partition_id = idx[0];
        int64_t tablet_id = idx[1];
        std::string stats_key =
                stats_tablet_key({instance_id, table_id, index_id, partition_id, tablet_id});
        TabletStatsPB stats;
        stats.set_base_compaction_cnt(10);
        stats.set_cumulative_compaction_cnt(20);
        stats.set_cumulative_point(30);
        txn->put(stats_key, stats.SerializeAsString());

        if (skip_tablet_meta) {
            continue;
        }
        doris::TabletMetaCloudPB tablet_pb;
        tablet_pb.set_table_id(table_id);
        tablet_pb.set_index_id(index_id);
        tablet_pb.set_partition_id(partition_id);
        tablet_pb.set_tablet_id(tablet_id);
        tablet_pb.set_tablet_state(doris::TabletStatePB::PB_RUNNING);
        auto tablet_meta_key =
                meta_tablet_key({instance_id, table_id, index_id, partition_id, tablet_id});
        auto tablet_meta_val = tablet_pb.SerializeAsString();
        txn->put(tablet_meta_key, tablet_meta_val);
    }
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
}

static void start_compaction_job(MetaService* meta_service, int64_t tablet_id,
                                 const std::string& job_id, const std::string& initiator,
                                 int base_compaction_cnt, int cumu_compaction_cnt,
                                 TabletCompactionJobPB::CompactionType type,
                                 StartTabletJobResponse& res,
                                 std::pair<int64_t, int64_t> input_version = {0, 0}) {
    brpc::Controller cntl;
    StartTabletJobRequest req;
    req.mutable_job()->mutable_idx()->set_tablet_id(tablet_id);
    auto compaction = req.mutable_job()->add_compaction();
    compaction->set_id(job_id);
    compaction->set_initiator(initiator);
    compaction->set_base_compaction_cnt(base_compaction_cnt);
    compaction->set_cumulative_compaction_cnt(cumu_compaction_cnt);
    compaction->set_type(type);
    long now = time(nullptr);
    compaction->set_expiration(now + 12);
    compaction->set_lease(now + 3);
    if (input_version.second > 0) {
        compaction->add_input_versions(input_version.first);
        compaction->add_input_versions(input_version.second);
        compaction->set_check_input_versions_range(true);
    }
    meta_service->start_tablet_job(&cntl, &req, &res, nullptr);
};

TEST(MetaServiceTest, GetInstanceIdTest) {
    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto meta_service = get_meta_service();
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id_err", [&](auto&& args) {
        std::string* err = try_any_cast<std::string*>(args[0]);
        *err = "can't find node from cache";
    });
    sp->enable_processing();

    auto instance_id =
            get_instance_id(meta_service->resource_mgr(), "1:ALBJLH4Q:m-n3qdpyal27rh8iprxx");
    ASSERT_EQ(instance_id, "ALBJLH4Q");

    // version not support
    instance_id = get_instance_id(meta_service->resource_mgr(), "2:ALBJLH4Q:m-n3qdpyal27rh8iprxx");
    ASSERT_EQ(instance_id, "");

    // degraded format err
    instance_id = get_instance_id(meta_service->resource_mgr(), "1:ALBJLH4Q");
    ASSERT_EQ(instance_id, "");

    // std::invalid_argument
    instance_id = get_instance_id(meta_service->resource_mgr(),
                                  "invalid_version:ALBJLH4Q:m-n3qdpyal27rh8iprxx");
    ASSERT_EQ(instance_id, "");

    // std::out_of_range
    instance_id = get_instance_id(meta_service->resource_mgr(),
                                  "12345678901:ALBJLH4Q:m-n3qdpyal27rh8iprxx");
    ASSERT_EQ(instance_id, "");

    config::enable_check_instance_id = true;
    auto ms = get_meta_service(false);
    instance_id =
            get_instance_id(ms->resource_mgr(), "1:ALBJLH4Q-check-invalid:m-n3qdpyal27rh8iprxx");
    ASSERT_EQ(instance_id, "");

    sp->set_call_back("is_instance_id_registered", [&](auto&& args) {
        TxnErrorCode* c0 = try_any_cast<TxnErrorCode*>(args[0]);
        *c0 = TxnErrorCode::TXN_OK;
    });
    instance_id =
            get_instance_id(ms->resource_mgr(), "1:ALBJLH4Q-check-invalid:m-n3qdpyal27rh8iprxx");
    ASSERT_EQ(instance_id, "ALBJLH4Q-check-invalid");
    config::enable_check_instance_id = false;

    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
}

TEST(MetaServiceTest, CreateInstanceTest) {
    auto meta_service = get_meta_service();

    // case: normal create instance with obj info
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        req.set_instance_id("test_instance");
        req.set_user_id("test_user");
        req.set_name("test_name");
        ObjectStoreInfoPB obj;
        obj.set_ak("123");
        obj.set_sk("321");
        obj.set_bucket("456");
        obj.set_prefix("654");
        obj.set_endpoint("789");
        obj.set_region("987");
        obj.set_external_endpoint("888");
        obj.set_provider(ObjectStoreInfoPB::BOS);
        req.mutable_obj_info()->CopyFrom(obj);

        auto sp = SyncPoint::get_instance();
        sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* key = try_any_cast<std::string*>(args[1]);
            *key = "test";
            auto* key_id = try_any_cast<int64_t*>(args[2]);
            *key_id = 1;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    // case: normal create instance without obj info and hdfs info
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        req.set_instance_id("test_instance_without_hdfs_and_obj");
        req.set_user_id("test_user");
        req.set_name("test_name");

        auto sp = SyncPoint::get_instance();
        sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* key = try_any_cast<std::string*>(args[1]);
            *key = "test";
            auto* key_id = try_any_cast<int64_t*>(args[2]);
            *key_id = 1;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    // case: normal create instance with hdfs info
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        req.set_instance_id("test_instance_with_hdfs_info");
        req.set_user_id("test_user");
        req.set_name("test_name");
        HdfsVaultInfo hdfs;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        conf.set_user("test_user");
        hdfs.mutable_build_conf()->CopyFrom(conf);
        StorageVaultPB vault;
        vault.mutable_hdfs_info()->CopyFrom(hdfs);
        req.mutable_vault()->CopyFrom(vault);

        auto sp = SyncPoint::get_instance();
        sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* key = try_any_cast<std::string*>(args[1]);
            *key = "test";
            auto* key_id = try_any_cast<int64_t*>(args[2]);
            *key_id = 1;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    // case: request has invalid argument
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // case: normal drop instance
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::DROP);
        req.set_instance_id("test_instance");
        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        InstanceKeyInfo key_info {"test_instance"};
        std::string key;
        std::string val;
        instance_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        InstanceInfoPB instance;
        instance.ParseFromString(val);
        ASSERT_EQ(instance.status(), InstanceInfoPB::DELETED);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // case: normal refresh instance
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::REFRESH);
        req.set_instance_id("test_instance");
        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // case: rpc get instance
    {
        brpc::Controller cntl;
        GetInstanceRequest req;
        GetInstanceResponse res;
        meta_service->get_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        req.set_cloud_unique_id("1:test_instance:m-n3qdpyal27rh8iprxx");
        meta_service->get_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
}

TEST(MetaServiceTest, AlterS3StorageVaultTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    std::pair<std::string, std::string> pair;
    sp->set_call_back("extract_object_storage_info:get_aksk_pair", [&](auto&& args) {
        auto* ret = try_any_cast<std::pair<std::string, std::string>*>(args[0]);
        pair = *ret;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("ak");
    obj_info.set_sk("sk");
    StorageVaultPB vault;
    constexpr char vault_name[] = "test_alter_s3_vault";
    vault.mutable_obj_info()->MergeFrom(obj_info);
    vault.set_name(vault_name);
    vault.set_id("2");
    InstanceInfoPB instance;
    instance.add_storage_vault_names(vault.name());
    instance.add_resource_ids(vault.id());
    instance.set_instance_id("GetObjStoreInfoTestInstance");
    val = instance.SerializeAsString();
    txn->put(key, val);
    txn->put(storage_vault_key({instance.instance_id(), "2"}), vault.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    txn = nullptr;

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
        StorageVaultPB vault;
        vault.mutable_obj_info()->set_ak("new_ak");
        vault.set_name(vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_NE(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                  TxnErrorCode::TXN_OK);
        StorageVaultPB get_obj;
        get_obj.ParseFromString(val);
        ASSERT_EQ(get_obj.obj_info().ak(), "ak") << get_obj.obj_info().ak();
    }

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
        StorageVaultPB vault;
        ObjectStoreInfoPB obj;
        obj_info.set_ak("new_ak");
        vault.mutable_obj_info()->MergeFrom(obj);
        vault.set_name("test_alter_s3_vault_non_exist");
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_NE(res.status().code(), MetaServiceCode::OK) << res.status().msg();
    }

    {
        AlterObjStoreInfoRequest req;
        constexpr char new_vault_name[] = "@!#vault_name";
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
        StorageVaultPB vault;
        vault.set_alter_name(new_vault_name);
        ObjectStoreInfoPB obj;
        obj_info.set_ak("new_ak");
        vault.mutable_obj_info()->MergeFrom(obj);
        vault.set_name(vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_NE(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        ASSERT_TRUE(res.status().msg().find("invalid storage vault name") != std::string::npos)
                << res.status().msg();
    }

    {
        AlterObjStoreInfoRequest req;
        constexpr char new_vault_name[] = "new_test_alter_s3_vault";
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
        StorageVaultPB vault;
        vault.set_alter_name(new_vault_name);
        ObjectStoreInfoPB obj;
        obj_info.set_ak("new_ak");
        obj_info.set_sk("new_sk");
        vault.mutable_obj_info()->MergeFrom(obj);
        vault.set_name(vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        {
            AlterObjStoreInfoRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
            StorageVaultPB vault;
            vault.set_alter_name(new_vault_name);
            ObjectStoreInfoPB obj;
            obj_info.set_ak("new_ak");
            obj_info.set_sk("new_sk");
            vault.mutable_obj_info()->MergeFrom(obj);
            vault.set_name(new_vault_name);
            req.mutable_vault()->CopyFrom(vault);
            meta_service->alter_storage_vault(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED) << res.status().msg();
        }

        InstanceInfoPB instance;
        get_test_instance(instance);

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                  TxnErrorCode::TXN_OK);
        StorageVaultPB get_obj;
        get_obj.ParseFromString(val);
        ASSERT_EQ(get_obj.name(), new_vault_name) << get_obj.obj_info().ak();
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, AlterHdfsStorageVaultTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    std::pair<std::string, std::string> pair;
    sp->set_call_back("extract_object_storage_info:get_aksk_pair", [&](auto&& args) {
        auto* ret = try_any_cast<std::pair<std::string, std::string>*>(args[0]);
        pair = *ret;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    HdfsBuildConf hdfs_build_conf;
    hdfs_build_conf.set_fs_name("fs_name");
    hdfs_build_conf.set_user("root");
    HdfsVaultInfo hdfs_info;
    hdfs_info.set_prefix("root_path");
    hdfs_info.mutable_build_conf()->MergeFrom(hdfs_build_conf);
    StorageVaultPB vault;
    constexpr char vault_name[] = "test_alter_hdfs_vault";
    vault.mutable_hdfs_info()->MergeFrom(hdfs_info);
    vault.set_name(vault_name);
    vault.set_id("2");
    InstanceInfoPB instance;
    instance.add_storage_vault_names(vault.name());
    instance.add_resource_ids(vault.id());
    instance.set_instance_id("GetObjStoreInfoTestInstance");
    val = instance.SerializeAsString();
    txn->put(key, val);
    txn->put(storage_vault_key({instance.instance_id(), "2"}), vault.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    txn = nullptr;

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
        StorageVaultPB vault;
        vault.mutable_hdfs_info()->mutable_build_conf()->set_user("hadoop");
        vault.set_name(vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                  TxnErrorCode::TXN_OK);
        StorageVaultPB get_obj;
        get_obj.ParseFromString(val);
        ASSERT_EQ(get_obj.hdfs_info().build_conf().user(), "hadoop")
                << get_obj.hdfs_info().build_conf().fs_name();
    }

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
        StorageVaultPB vault;
        auto* hdfs = vault.mutable_hdfs_info();
        hdfs->set_prefix("fake_one");
        vault.set_name("test_alter_hdfs_vault_non_exist");
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_NE(res.status().code(), MetaServiceCode::OK) << res.status().msg();
    }

    {
        AlterObjStoreInfoRequest req;
        constexpr char new_vault_name[] = "Thi213***@fakeVault";
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
        StorageVaultPB vault;
        vault.mutable_hdfs_info()->mutable_build_conf()->set_user("hadoop");
        vault.set_name(vault_name);
        vault.set_alter_name(new_vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_NE(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        ASSERT_TRUE(res.status().msg().find("invalid storage vault name") != std::string::npos)
                << res.status().msg();
    }

    {
        AlterObjStoreInfoRequest req;
        constexpr char new_vault_name[] = "new_test_alter_hdfs_vault";
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
        StorageVaultPB vault;
        vault.mutable_hdfs_info()->mutable_build_conf()->set_user("hadoop");
        vault.set_name(vault_name);
        vault.set_alter_name(new_vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        {
            AlterObjStoreInfoRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_op(AlterObjStoreInfoRequest::ALTER_HDFS_VAULT);
            StorageVaultPB vault;
            vault.mutable_hdfs_info()->mutable_build_conf()->set_user("hadoop");
            vault.set_name(new_vault_name);
            vault.set_alter_name(new_vault_name);
            req.mutable_vault()->CopyFrom(vault);

            brpc::Controller cntl;
            AlterObjStoreInfoResponse res;
            meta_service->alter_storage_vault(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED) << res.status().msg();
        }

        InstanceInfoPB instance;
        get_test_instance(instance);

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                  TxnErrorCode::TXN_OK);
        StorageVaultPB get_obj;
        get_obj.ParseFromString(val);
        ASSERT_EQ(get_obj.name(), new_vault_name) << get_obj.obj_info().ak();
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, AlterClusterTest) {
    auto meta_service = get_meta_service();
    ASSERT_NE(meta_service, nullptr);

    // case: normal add cluster
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_instance_id(mock_instance);
        req.mutable_cluster()->set_cluster_name(mock_cluster_name);
        req.set_op(AlterClusterRequest::ADD_CLUSTER);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // case: request has invalid argument
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_op(AlterClusterRequest::DROP_CLUSTER);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // add node
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_instance_id(mock_instance);
        req.set_op(AlterClusterRequest::ADD_NODE);
        req.mutable_cluster()->set_cluster_name(mock_cluster_name);
        req.mutable_cluster()->set_cluster_id(mock_cluster_id);
        req.mutable_cluster()->set_type(ClusterPB::COMPUTE);
        auto node = req.mutable_cluster()->add_nodes();
        node->set_ip("127.0.0.1");
        node->set_heartbeat_port(9999);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // drop node
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_instance_id(mock_instance);
        req.set_op(AlterClusterRequest::DROP_NODE);
        req.mutable_cluster()->set_cluster_name(mock_cluster_name);
        req.mutable_cluster()->set_cluster_id(mock_cluster_id);
        req.mutable_cluster()->set_type(ClusterPB::COMPUTE);
        auto node = req.mutable_cluster()->add_nodes();
        node->set_ip("127.0.0.1");
        node->set_heartbeat_port(9999);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // rename cluster
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_instance_id(mock_instance);
        req.mutable_cluster()->set_cluster_id(mock_cluster_id);
        req.mutable_cluster()->set_cluster_name("rename_cluster_name");
        req.set_op(AlterClusterRequest::RENAME_CLUSTER);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // set cluster status
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_instance_id(mock_instance);
        req.mutable_cluster()->set_cluster_id(mock_cluster_id);
        req.mutable_cluster()->set_cluster_status(ClusterStatus::SUSPENDED);
        req.set_op(AlterClusterRequest::SET_CLUSTER_STATUS);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // set UPDATE_CLUSTER_MYSQL_USER_NAME
    {
        brpc::Controller cntl;
        AlterClusterRequest req;
        req.set_instance_id(mock_instance);
        req.mutable_cluster()->set_cluster_id(mock_cluster_id);
        req.mutable_cluster()->add_mysql_user_name("test_user");
        req.set_op(AlterClusterRequest::UPDATE_CLUSTER_MYSQL_USER_NAME);
        AlterClusterResponse res;
        meta_service->alter_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
}

TEST(MetaServiceTest, GetClusterTest) {
    auto meta_service = get_meta_service();

    // add cluster first
    InstanceKeyInfo key_info {mock_instance};
    std::string key;
    std::string val;
    instance_key(key_info, &key);

    InstanceInfoPB instance;
    instance.set_instance_id(mock_instance);
    ClusterPB c1;
    c1.set_cluster_name(mock_cluster_name);
    c1.set_cluster_id(mock_cluster_id);
    c1.add_mysql_user_name()->append("m1");
    instance.add_clusters()->CopyFrom(c1);
    val = instance.SerializeAsString();

    std::unique_ptr<Transaction> txn;
    std::string get_val;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    // case: normal get
    {
        brpc::Controller cntl;
        GetClusterRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_cluster_id(mock_cluster_id);
        req.set_cluster_name("test_cluster");
        GetClusterResponse res;
        meta_service->get_cluster(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
}

TEST(MetaServiceTest, BeginTxnTest) {
    auto meta_service = get_meta_service();
    int64_t db_id = 666;
    int64_t table_id = 123;
    const std::string& label = "test_label";
    int64_t timeout_ms = 60 * 1000;

    // test invalid argument
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");

        TxnInfoPB txn_info;
        txn_info.set_db_id(db_id);
        txn_info.add_table_ids(table_id);
        txn_info.set_timeout_ms(timeout_ms);
        req.mutable_txn_info()->CopyFrom(txn_info);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");

        TxnInfoPB txn_info;
        txn_info.set_db_id(db_id);
        txn_info.set_label(label);
        txn_info.add_table_ids(table_id);
        txn_info.set_timeout_ms(timeout_ms);
        req.mutable_txn_info()->CopyFrom(txn_info);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // case: label already used
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        auto label_already_in_use = "test_label_already_in_use";

        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info;
        txn_info.set_db_id(888);
        txn_info.set_label(label_already_in_use);
        txn_info.add_table_ids(456);
        txn_info.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_LABEL_ALREADY_USED);
        auto found = res.status().msg().find(fmt::format(
                "Label [{}] has already been used, relate to txn", label_already_in_use));
        ASSERT_NE(found, std::string::npos);
    }

    // case: dup begin txn request
    {
        brpc::Controller cntl;
        BeginTxnRequest req;

        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info;
        txn_info.set_db_id(999);
        txn_info.set_label("test_label_dup_request");
        txn_info.add_table_ids(789);
        UniqueIdPB unique_id_pb;
        unique_id_pb.set_hi(100);
        unique_id_pb.set_lo(10);
        txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
        txn_info.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_DUPLICATED_REQ);
    }

    {
        // ===========================================================================
        // threads concurrent execution with sequence in begin_txn with same label:
        //
        //      thread1              thread2
        //         |                    |
        //         |                commit_txn1
        //         |                    |
        //         |                    |
        //         |                    |
        //       commit_txn2            |
        //         |                    |
        //         v                    v
        //

        std::mutex go_mutex;
        std::condition_variable go_cv;
        bool go = false;
        auto sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->clear_all_call_backs();
        };

        std::atomic<int32_t> count_txn1 = {0};
        std::atomic<int32_t> count_txn2 = {0};
        std::atomic<int32_t> count_txn3 = {0};

        int64_t db_id = 1928354123;
        int64_t table_id = 12131231231;
        std::string test_label = "test_race_with_same_label";

        std::atomic<int32_t> success_txn = {0};

        sp->set_call_back("begin_txn:before:commit_txn:1", [&](auto&& args) {
            const auto& label = *try_any_cast<std::string*>(args[0]);
            std::unique_lock<std::mutex> _lock(go_mutex);
            count_txn1++;
            LOG(INFO) << "count_txn1:" << count_txn1 << " label=" << label;
            if (count_txn1 == 1) {
                {
                    LOG(INFO) << "count_txn1:" << count_txn1 << " label=" << label << " go=" << go;
                    go_cv.wait(_lock);
                }
            }

            if (count_txn1 == 2) {
                {
                    LOG(INFO) << "count_txn1:" << count_txn1 << " label=" << label << " go=" << go;
                    go_cv.notify_all();
                }
            }
        });

        sp->set_call_back("begin_txn:after:commit_txn:1", [&](auto&& args) {
            const auto& label = *try_any_cast<std::string*>(args[0]);
            std::unique_lock<std::mutex> _lock(go_mutex);
            count_txn2++;
            LOG(INFO) << "count_txn2:" << count_txn2 << " label=" << label;
            if (count_txn2 == 1) {
                {
                    LOG(INFO) << "count_txn2:" << count_txn2 << " label=" << label << " go=" << go;
                    go_cv.wait(_lock);
                }
            }

            if (count_txn2 == 2) {
                {
                    LOG(INFO) << "count_txn2:" << count_txn2 << " label=" << label << " go=" << go;
                    go_cv.notify_all();
                }
            }
        });

        sp->set_call_back("begin_txn:after:commit_txn:2", [&](auto&& args) {
            int64_t txn_id = *try_any_cast<int64_t*>(args[0]);
            count_txn3++;
            LOG(INFO) << "count_txn3:" << count_txn3 << " txn_id=" << txn_id;
        });

        sp->enable_processing();

        std::thread thread1([&] {
            {
                std::unique_lock<std::mutex> _lock(go_mutex);
                go_cv.wait(_lock, [&] { return go; });
            }
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(test_label);
            txn_info.add_table_ids(table_id);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(1001);
            unique_id_pb.set_lo(11);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            txn_info.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            if (res.status().code() == MetaServiceCode::OK) {
                success_txn++;
            } else {
                ASSERT_EQ(res.status().code(), MetaServiceCode::KV_TXN_CONFLICT);
            }
        });

        std::thread thread2([&] {
            {
                std::unique_lock<std::mutex> _lock(go_mutex);
                go_cv.wait(_lock, [&] { return go; });
            }
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(test_label);
            txn_info.add_table_ids(table_id);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(100);
            unique_id_pb.set_lo(10);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            txn_info.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            if (res.status().code() == MetaServiceCode::OK) {
                success_txn++;
            } else {
                ASSERT_EQ(res.status().code(), MetaServiceCode::KV_TXN_CONFLICT);
            }
        });

        std::unique_lock<std::mutex> go_lock(go_mutex);
        go = true;
        go_lock.unlock();
        go_cv.notify_all();

        thread1.join();
        thread2.join();
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
        ASSERT_EQ(success_txn.load(), 1);
    }
    {
        // ===========================================================================
        // threads concurrent execution with sequence in begin_txn with different label:
        //
        //      thread1              thread2
        //         |                    |
        //         |                commit_txn1
        //         |                    |
        //         |                    |
        //         |                    |
        //       commit_txn2            |
        //         |                    |
        //         v                    v

        std::mutex go_mutex;
        std::condition_variable go_cv;
        bool go = false;
        auto sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->clear_all_call_backs();
        };

        std::atomic<int32_t> count_txn1 = {0};
        std::atomic<int32_t> count_txn2 = {0};
        std::mutex flow_mutex_1;
        std::condition_variable flow_cv_1;

        int64_t db_id = 19541231112;
        int64_t table_id = 312312321211;
        std::string test_label1 = "test_race_with_diff_label1";
        std::string test_label2 = "test_race_with_diff_label2";

        std::atomic<int32_t> success_txn = {0};

        sp->set_call_back("begin_txn:before:commit_txn:1", [&](auto&& args) {
            std::string label = *try_any_cast<std::string*>(args[0]);
            if (count_txn1.load() == 1) {
                std::unique_lock<std::mutex> flow_lock_1(flow_mutex_1);
                flow_cv_1.wait(flow_lock_1);
            }
            count_txn1++;
            LOG(INFO) << "count_txn1:" << count_txn1 << " label=" << label;
        });

        sp->set_call_back("begin_txn:after:commit_txn:2", [&](auto&& args) {
            int64_t txn_id = *try_any_cast<int64_t*>(args[0]);
            while (count_txn2.load() == 0 && count_txn1.load() == 1) {
                sleep(1);
                flow_cv_1.notify_all();
            }
            count_txn2++;
            LOG(INFO) << "count_txn2:" << count_txn2 << " txn_id=" << txn_id;
        });
        sp->enable_processing();

        std::thread thread1([&] {
            {
                std::unique_lock<std::mutex> _lock(go_mutex);
                go_cv.wait(_lock, [&] { return go; });
            }
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(test_label1);
            txn_info.add_table_ids(table_id);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(1001);
            unique_id_pb.set_lo(11);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            txn_info.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            if (res.status().code() == MetaServiceCode::OK) {
                success_txn++;
            } else {
                ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_LABEL_ALREADY_USED);
            }
        });

        std::thread thread2([&] {
            {
                std::unique_lock<std::mutex> _lock(go_mutex);
                go_cv.wait(_lock, [&] { return go; });
            }
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(test_label2);
            txn_info.add_table_ids(table_id);
            txn_info.set_timeout_ms(36000);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(100);
            unique_id_pb.set_lo(10);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            if (res.status().code() == MetaServiceCode::OK) {
                success_txn++;
            } else {
                ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_LABEL_ALREADY_USED);
            }
        });

        std::unique_lock<std::mutex> go_lock(go_mutex);
        go = true;
        go_lock.unlock();
        go_cv.notify_all();

        thread1.join();
        thread2.join();
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
        ASSERT_EQ(success_txn.load(), 2);
    }
    {
        // test reuse label
        // 1. beigin_txn
        // 2. abort_txn
        // 3. begin_txn again can successfully

        std::string cloud_unique_id = "test_cloud_unique_id";
        int64_t db_id = 124343989;
        int64_t table_id = 1231311;
        int64_t txn_id = -1;
        std::string label = "test_reuse_label";
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(label);
            txn_info.add_table_ids(table_id);
            txn_info.set_timeout_ms(36000);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(100);
            unique_id_pb.set_lo(10);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }
        // abort txn
        {
            brpc::Controller cntl;
            AbortTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            ASSERT_GT(txn_id, 0);
            req.set_txn_id(txn_id);
            req.set_reason("test");
            AbortTxnResponse res;
            meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().status(), TxnStatusPB::TXN_STATUS_ABORTED);
        }
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(label);
            txn_info.add_table_ids(table_id);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(100);
            unique_id_pb.set_lo(10);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            txn_info.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_GT(res.txn_id(), txn_id);
        }
    }

    {
        // test reuse label exceed max_num_aborted_txn

        std::string cloud_unique_id = "test_cloud_unique_id";
        int64_t db_id = 124343989;
        int64_t table_id = 12897811;
        int64_t txn_id = -1;
        std::string label = "test_max_num_aborted_txn_label";
        for (int i = 0; i < config::max_num_aborted_txn; i++) {
            {
                brpc::Controller cntl;
                BeginTxnRequest req;
                req.set_cloud_unique_id(cloud_unique_id);
                TxnInfoPB txn_info;
                txn_info.set_db_id(db_id);
                txn_info.set_label(label);
                txn_info.add_table_ids(table_id);
                txn_info.set_timeout_ms(36000);
                UniqueIdPB unique_id_pb;
                unique_id_pb.set_hi(100);
                unique_id_pb.set_lo(10);
                txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
                req.mutable_txn_info()->CopyFrom(txn_info);
                BeginTxnResponse res;
                meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
                ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                txn_id = res.txn_id();
            }
            // abort txn
            {
                brpc::Controller cntl;
                AbortTxnRequest req;
                req.set_cloud_unique_id(cloud_unique_id);
                ASSERT_GT(txn_id, 0);
                req.set_txn_id(txn_id);
                req.set_reason("test");
                AbortTxnResponse res;
                meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
                ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                ASSERT_EQ(res.txn_info().status(), TxnStatusPB::TXN_STATUS_ABORTED);
            }
        }
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            TxnInfoPB txn_info;
            txn_info.set_db_id(db_id);
            txn_info.set_label(label);
            txn_info.add_table_ids(table_id);
            UniqueIdPB unique_id_pb;
            unique_id_pb.set_hi(100);
            unique_id_pb.set_lo(10);
            txn_info.mutable_request_id()->CopyFrom(unique_id_pb);
            txn_info.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
            ASSERT_TRUE(res.status().msg().find("too many aborted txn for label") !=
                        std::string::npos);
        }
    }
}

TEST(MetaServiceTest, PrecommitTest1) {
    // PrecommitTestCase1: only use db_id for precommit_txn
    auto meta_service = get_meta_service();
    const int64_t db_id = 563413;
    const int64_t table_id = 417417878;
    const std::string& label = "label_123dae121das";
    int64_t txn_id = -1;
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info;
        txn_info.set_db_id(db_id);
        txn_info.set_label(label);
        txn_info.add_table_ids(table_id);
        txn_info.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
        ASSERT_GT(txn_id, -1);
    }

    {
        brpc::Controller cntl;
        PrecommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_precommit_timeout_ms(36000);
        PrecommitTxnResponse res;
        meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    {
        std::unique_ptr<Transaction> txn;
        TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        const std::string info_key = txn_info_key({mock_instance, db_id, txn_id});
        std::string info_val;
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_OK);
        TxnInfoPB txn_info;
        txn_info.ParseFromString(info_val);
        ASSERT_EQ(txn_info.status(), TxnStatusPB::TXN_STATUS_PREPARED);

        brpc::Controller cntl;
        PrecommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_txn_id(txn_id);
        req.set_precommit_timeout_ms(36000);
        PrecommitTxnResponse res;
        meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_OK);
        txn_info.ParseFromString(info_val);
        ASSERT_EQ(txn_info.status(), TxnStatusPB::TXN_STATUS_PRECOMMITTED);
    }
}

TEST(MetaServiceTest, PrecommitTxnTest2) {
    auto meta_service = get_meta_service();
    const int64_t db_id = 563413;
    const int64_t table_id = 417417878;
    const std::string& label = "label_123dae121das";
    int64_t txn_id = -1;
    // begin txn first
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info;
        txn_info.set_db_id(db_id);
        txn_info.set_label(label);
        txn_info.add_table_ids(table_id);
        txn_info.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
        ASSERT_GT(txn_id, -1);
    }

    // case: txn's status should be TXN_STATUS_PRECOMMITTED
    {
        std::unique_ptr<Transaction> txn;
        TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        const std::string info_key = txn_info_key({mock_instance, db_id, txn_id});
        std::string info_val;
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_OK);
        TxnInfoPB txn_info;
        txn_info.ParseFromString(info_val);
        // before call precommit_txn, txn's status is TXN_STATUS_PREPARED
        ASSERT_EQ(txn_info.status(), TxnStatusPB::TXN_STATUS_PREPARED);

        brpc::Controller cntl;
        PrecommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.set_txn_id(txn_id);
        req.set_precommit_timeout_ms(36000);
        PrecommitTxnResponse res;
        meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_OK);
        txn_info.ParseFromString(info_val);
        // after call precommit_txn, txn's status is TXN_STATUS_PRECOMMITTED
        ASSERT_EQ(txn_info.status(), TxnStatusPB::TXN_STATUS_PRECOMMITTED);
    }

    // case: when txn's status is TXN_STATUS_ABORTED/TXN_STATUS_VISIBLE/TXN_STATUS_PRECOMMITTED
    {
        // TXN_STATUS_ABORTED
        std::unique_ptr<Transaction> txn;
        TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        const std::string info_key = txn_info_key({mock_instance, db_id, txn_id});
        std::string info_val;
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_OK);
        TxnInfoPB txn_info;
        txn_info.ParseFromString(info_val);
        txn_info.set_status(TxnStatusPB::TXN_STATUS_ABORTED);
        info_val.clear();
        txn_info.SerializeToString(&info_val);
        txn->put(info_key, info_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        brpc::Controller cntl;
        PrecommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.set_txn_id(txn_id);
        req.set_precommit_timeout_ms(36000);
        PrecommitTxnResponse res;
        meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_ALREADY_ABORTED);

        // TXN_STATUS_VISIBLE
        txn_info.set_status(TxnStatusPB::TXN_STATUS_VISIBLE);
        info_val.clear();
        txn_info.SerializeToString(&info_val);
        txn->put(info_key, info_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_ALREADY_VISIBLE);

        // TXN_STATUS_PRECOMMITTED
        txn_info.set_status(TxnStatusPB::TXN_STATUS_PRECOMMITTED);
        info_val.clear();
        txn_info.SerializeToString(&info_val);
        txn->put(info_key, info_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_ALREADY_PRECOMMITED);
    }
}

TEST(MetaServiceTest, CommitTxnTest) {
    auto meta_service = get_meta_service();
    int64_t table_id = 1234;
    int64_t index_id = 1235;
    int64_t partition_id = 1236;

    // case: first version of rowset
    {
        int64_t txn_id = -1;
        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(666);
            txn_info_pb.set_label("test_label");
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // mock rowset and tablet
        int64_t tablet_id_base = 1103;
        for (int i = 0; i < 5; ++i) {
            create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id_base + i);
            auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i, partition_id);
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // precommit txn
        {
            brpc::Controller cntl;
            PrecommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(666);
            req.set_txn_id(txn_id);
            req.set_precommit_timeout_ms(36000);
            PrecommitTxnResponse res;
            meta_service->precommit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // commit txn
        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(666);
            req.set_txn_id(txn_id);
            CommitTxnResponse res;
            meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // doubly commit txn
        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            auto db_id = 666;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(txn_id);
            CommitTxnResponse res;
            meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            auto found = res.status().msg().find(fmt::format(
                    "transaction is already visible: db_id={} txn_id={}", db_id, txn_id));
            ASSERT_TRUE(found != std::string::npos);
        }

        // doubly commit txn(2pc)
        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(666);
            req.set_txn_id(txn_id);
            req.set_is_2pc(true);
            CommitTxnResponse res;
            meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_ALREADY_VISIBLE);
            auto found = res.status().msg().find(
                    fmt::format("transaction [{}] is already visible, not pre-committed.", txn_id));
            ASSERT_TRUE(found != std::string::npos);
        }
    }
}

TEST(MetaServiceTest, CommitTxnExpiredTest) {
    auto meta_service = get_meta_service();

    int64_t table_id = 1234789234;
    int64_t index_id = 1235;
    int64_t partition_id = 1236;

    // case: first version of rowset
    {
        int64_t txn_id = -1;
        int64_t db_id = 713232132;
        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label("test_commit_txn_expired");
            txn_info_pb.add_table_ids(1234789234);
            txn_info_pb.set_timeout_ms(1);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // mock rowset and tablet
        int64_t tablet_id_base = 1103;
        for (int i = 0; i < 5; ++i) {
            create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id_base + i);
            auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i, partition_id);
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }
        // sleep 1 second for txn timeout
        sleep(1);
        // commit txn
        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(txn_id);
            CommitTxnResponse res;
            meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::UNDEFINED_ERR);
            ASSERT_TRUE(res.status().msg().find("txn is expired, not allow to commit txn_id=") !=
                        std::string::npos);
        }
    }
}

void create_and_commit_rowset(MetaServiceProxy* meta_service, int64_t table_id, int64_t index_id,
                              int64_t partition_id, int64_t tablet_id, int64_t txn_id) {
    create_tablet(meta_service, table_id, index_id, partition_id, tablet_id);
    auto tmp_rowset = create_rowset(txn_id, tablet_id, partition_id);
    CreateRowsetResponse res;
    commit_rowset(meta_service, tmp_rowset, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
}

TEST(MetaServiceTest, CommitTxnWithSubTxnTest) {
    auto meta_service = get_meta_service();
    int64_t db_id = 98131;
    int64_t txn_id = -1;
    int64_t t1 = 10;
    int64_t t1_index = 100;
    int64_t t1_p1 = 11;
    int64_t t1_p1_t1 = 12;
    int64_t t1_p1_t2 = 13;
    int64_t t1_p2 = 14;
    int64_t t1_p2_t1 = 15;
    int64_t t2 = 16;
    int64_t t2_index = 101;
    int64_t t2_p3 = 17;
    int64_t t2_p3_t1 = 18;
    [[maybe_unused]] int64_t t2_p4 = 19;
    [[maybe_unused]] int64_t t2_p4_t1 = 20;
    std::string label = "test_label";
    std::string label2 = "test_label_0";
    // begin txn
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(db_id);
        txn_info_pb.set_label(label);
        txn_info_pb.add_table_ids(t1);
        txn_info_pb.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info_pb);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
    }

    // mock rowset and tablet: for sub_txn1
    int64_t sub_txn_id1 = txn_id;
    create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t1, sub_txn_id1);
    create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t2, sub_txn_id1);
    create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p2, t1_p2_t1, sub_txn_id1);

    // begin_sub_txn2
    int64_t sub_txn_id2 = -1;
    {
        brpc::Controller cntl;
        BeginSubTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_txn_id(txn_id);
        req.set_sub_txn_num(0);
        req.set_db_id(db_id);
        req.set_label(label2);
        req.mutable_table_ids()->Add(t1);
        req.mutable_table_ids()->Add(t2);
        BeginSubTxnResponse res;
        meta_service->begin_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.txn_info().table_ids().size(), 2);
        ASSERT_EQ(res.txn_info().sub_txn_ids().size(), 1);
        ASSERT_TRUE(res.has_sub_txn_id());
        sub_txn_id2 = res.sub_txn_id();
        ASSERT_EQ(sub_txn_id2, res.txn_info().sub_txn_ids()[0]);
    }
    // mock rowset and tablet: for sub_txn3
    create_and_commit_rowset(meta_service.get(), t2, t2_index, t2_p3, t2_p3_t1, sub_txn_id2);

    // begin_sub_txn3
    int64_t sub_txn_id3 = -1;
    {
        brpc::Controller cntl;
        BeginSubTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_txn_id(txn_id);
        req.set_sub_txn_num(1);
        req.set_db_id(db_id);
        req.set_label("test_label_1");
        req.mutable_table_ids()->Add(t1);
        req.mutable_table_ids()->Add(t2);
        req.mutable_table_ids()->Add(t1);
        BeginSubTxnResponse res;
        meta_service->begin_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.txn_info().table_ids().size(), 3);
        ASSERT_EQ(res.txn_info().sub_txn_ids().size(), 2);
        ASSERT_TRUE(res.has_sub_txn_id());
        sub_txn_id3 = res.sub_txn_id();
        ASSERT_EQ(sub_txn_id3, res.txn_info().sub_txn_ids()[1]);
    }
    // mock rowset and tablet: for sub_txn3
    create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t1, sub_txn_id3);
    create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t2, sub_txn_id3);

    // commit txn
    CommitTxnRequest req;
    {
        brpc::Controller cntl;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(666);
        req.set_txn_id(txn_id);
        req.set_is_txn_load(true);

        SubTxnInfo sub_txn_info1;
        sub_txn_info1.set_sub_txn_id(sub_txn_id1);
        sub_txn_info1.set_table_id(t1);
        sub_txn_info1.mutable_base_tablet_ids()->Add(t1_p1_t1);
        sub_txn_info1.mutable_base_tablet_ids()->Add(t1_p1_t2);
        sub_txn_info1.mutable_base_tablet_ids()->Add(t1_p2_t1);

        SubTxnInfo sub_txn_info2;
        sub_txn_info2.set_sub_txn_id(sub_txn_id2);
        sub_txn_info2.set_table_id(t2);
        sub_txn_info2.mutable_base_tablet_ids()->Add(t2_p3_t1);

        SubTxnInfo sub_txn_info3;
        sub_txn_info3.set_sub_txn_id(sub_txn_id3);
        sub_txn_info3.set_table_id(t1);
        sub_txn_info3.mutable_base_tablet_ids()->Add(t1_p1_t1);
        sub_txn_info3.mutable_base_tablet_ids()->Add(t1_p1_t2);

        req.mutable_sub_txn_infos()->Add(std::move(sub_txn_info1));
        req.mutable_sub_txn_infos()->Add(std::move(sub_txn_info2));
        req.mutable_sub_txn_infos()->Add(std::move(sub_txn_info3));
        CommitTxnResponse res;
        meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                 &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        // std::cout << res.DebugString() << std::endl;
        ASSERT_EQ(res.table_ids().size(), 3);

        ASSERT_EQ(res.table_ids()[0], t2);
        ASSERT_EQ(res.partition_ids()[0], t2_p3);
        ASSERT_EQ(res.versions()[0], 2);

        ASSERT_EQ(res.table_ids()[1], t1);
        ASSERT_EQ(res.partition_ids()[1], t1_p2);
        ASSERT_EQ(res.versions()[1], 2);

        ASSERT_EQ(res.table_ids()[2], t1);
        ASSERT_EQ(res.partition_ids()[2], t1_p1) << res.ShortDebugString();
        ASSERT_EQ(res.versions()[2], 3) << res.ShortDebugString();
    }

    // doubly commit txn
    {
        brpc::Controller cntl;
        CommitTxnResponse res;
        meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                 &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        auto found = res.status().msg().find(
                fmt::format("transaction is already visible: db_id={} txn_id={}", db_id, txn_id));
        ASSERT_TRUE(found != std::string::npos);
    }

    // check kv
    {
        std::unique_ptr<Transaction> txn;
        TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);

        // txn_info
        std::string info_key = txn_info_key({mock_instance, db_id, txn_id});
        std::string info_val;
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_OK);
        TxnInfoPB txn_info;
        txn_info.ParseFromString(info_val);
        ASSERT_EQ(txn_info.status(), TxnStatusPB::TXN_STATUS_VISIBLE);

        info_key = txn_info_key({mock_instance, db_id, sub_txn_id2});
        ASSERT_EQ(txn->get(info_key, &info_val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        // txn_index
        std::string index_key = txn_index_key({mock_instance, txn_id});
        std::string index_val;
        ASSERT_EQ(txn->get(index_key, &index_val), TxnErrorCode::TXN_OK);
        TxnIndexPB txn_index;
        txn_index.ParseFromString(index_val);
        ASSERT_TRUE(txn_index.has_tablet_index());

        index_key = txn_index_key({mock_instance, sub_txn_id3});
        ASSERT_EQ(txn->get(index_key, &index_val), TxnErrorCode::TXN_OK);
        txn_index.ParseFromString(index_val);
        ASSERT_TRUE(txn_index.has_tablet_index());

        // txn_label
        std::string label_key = txn_label_key({mock_instance, db_id, label});
        std::string label_val;
        ASSERT_EQ(txn->get(label_key, &label_val), TxnErrorCode::TXN_OK);

        label_key = txn_label_key({mock_instance, db_id, label2});
        ASSERT_EQ(txn->get(label_key, &label_val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        // txn_running
        std::string running_key = txn_running_key({mock_instance, db_id, txn_id});
        std::string running_val;
        ASSERT_EQ(txn->get(running_key, &running_val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        running_key = txn_running_key({mock_instance, db_id, sub_txn_id3});
        ASSERT_EQ(txn->get(running_key, &running_val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        // tmp rowset
        int64_t ids[] = {txn_id, sub_txn_id1, sub_txn_id2, sub_txn_id3};
        for (auto id : ids) {
            MetaRowsetTmpKeyInfo rs_tmp_key_info0 {mock_instance, id, 0};
            MetaRowsetTmpKeyInfo rs_tmp_key_info1 {mock_instance, id + 1, 0};
            std::string rs_tmp_key0;
            std::string rs_tmp_key1;
            meta_rowset_tmp_key(rs_tmp_key_info0, &rs_tmp_key0);
            meta_rowset_tmp_key(rs_tmp_key_info1, &rs_tmp_key1);
            std::unique_ptr<RangeGetIterator> it;
            ASSERT_EQ(txn->get(rs_tmp_key0, rs_tmp_key1, &it, true), TxnErrorCode::TXN_OK);
            ASSERT_FALSE(it->has_next());
        }

        // partition version
        std::string ver_key = partition_version_key({mock_instance, db_id, t2, t2_p3});
        std::string ver_val;
        ASSERT_EQ(txn->get(ver_key, &ver_val), TxnErrorCode::TXN_OK);
        VersionPB version;
        version.ParseFromString(ver_val);
        ASSERT_EQ(version.version(), 2);

        ver_key = partition_version_key({mock_instance, db_id, t1, t1_p2});
        ASSERT_EQ(txn->get(ver_key, &ver_val), TxnErrorCode::TXN_OK);
        version.ParseFromString(ver_val);
        ASSERT_EQ(version.version(), 2);

        ver_key = partition_version_key({mock_instance, db_id, t1, t1_p1});
        ASSERT_EQ(txn->get(ver_key, &ver_val), TxnErrorCode::TXN_OK);
        version.ParseFromString(ver_val);
        ASSERT_EQ(version.version(), 3);

        // table version
        std::string table_ver_key = table_version_key({mock_instance, db_id, t1});
        std::string table_ver_val;
        ASSERT_EQ(txn->get(table_ver_key, &table_ver_val), TxnErrorCode::TXN_OK);
        auto val_int = *reinterpret_cast<const int64_t*>(table_ver_val.data());
        ASSERT_EQ(val_int, 1);

        table_version_key({mock_instance, db_id, t2});
        ASSERT_EQ(txn->get(table_ver_key, &table_ver_val), TxnErrorCode::TXN_OK);
        val_int = *reinterpret_cast<const int64_t*>(table_ver_val.data());
        ASSERT_EQ(val_int, 1);
    }
}

TEST(MetaServiceTest, CommitTxnWithSubTxnTest2) {
    auto meta_service = get_meta_service();
    int64_t db_id = 99131;
    int64_t txn_id = -1;
    int64_t t1 = 20;
    int64_t t1_index = 200;
    int64_t t1_p1 = 21;
    int64_t t1_p1_t1 = 22;
    int64_t t1_p1_t2 = 23;
    int64_t t1_p2 = 24;
    int64_t t1_p2_t1 = 25;
    int64_t t2 = 26;
    int64_t t2_index = 201;
    int64_t t2_p3 = 27;
    int64_t t2_p3_t1 = 28;
    [[maybe_unused]] int64_t t2_p4 = 29;
    [[maybe_unused]] int64_t t2_p4_t1 = 30;
    std::string label = "test_label_10";
    std::string label2 = "test_label_11";
    // begin txn
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(db_id);
        txn_info_pb.set_label(label);
        txn_info_pb.add_table_ids(t1);
        txn_info_pb.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info_pb);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
    }

    std::vector<SubTxnInfo> sub_txn_infos;
    for (int i = 0; i < 500; i++) {
        int64_t sub_txn_id1 = -1;
        if (i == 0) {
            sub_txn_id1 = txn_id;
        } else {
            brpc::Controller cntl;
            BeginSubTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            req.set_sub_txn_num(sub_txn_infos.size() - 1);
            req.set_db_id(db_id);
            req.set_label(label2);
            req.mutable_table_ids()->Add(t1);
            if (i > 0) {
                req.mutable_table_ids()->Add(t2);
            }
            BeginSubTxnResponse res;
            meta_service->begin_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().table_ids().size(), i == 0 ? 1 : 2);
            ASSERT_EQ(res.txn_info().sub_txn_ids().size(), sub_txn_infos.size());
            ASSERT_TRUE(res.has_sub_txn_id());
            sub_txn_id1 = res.sub_txn_id();
            ASSERT_EQ(sub_txn_id1,
                      res.txn_info().sub_txn_ids()[res.txn_info().sub_txn_ids().size() - 1]);
        }
        // mock rowset and tablet: for
        create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t1, sub_txn_id1);
        create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t2, sub_txn_id1);
        create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p2, t1_p2_t1, sub_txn_id1);
        // generate sub_txn_info
        {
            SubTxnInfo sub_txn_info1;
            sub_txn_info1.set_sub_txn_id(sub_txn_id1);
            sub_txn_info1.set_table_id(t1);
            sub_txn_info1.mutable_base_tablet_ids()->Add(t1_p1_t1);
            sub_txn_info1.mutable_base_tablet_ids()->Add(t1_p1_t2);
            sub_txn_info1.mutable_base_tablet_ids()->Add(t1_p2_t1);
            sub_txn_infos.push_back(sub_txn_info1);
        }

        // begin_sub_txn2
        int64_t sub_txn_id2 = -1;
        {
            brpc::Controller cntl;
            BeginSubTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            req.set_sub_txn_num(sub_txn_infos.size() - 1);
            req.set_db_id(db_id);
            req.set_label(label2);
            req.mutable_table_ids()->Add(t1);
            req.mutable_table_ids()->Add(t2);
            BeginSubTxnResponse res;
            meta_service->begin_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().table_ids().size(), 2);
            ASSERT_EQ(res.txn_info().sub_txn_ids().size(), sub_txn_infos.size());
            ASSERT_TRUE(res.has_sub_txn_id());
            sub_txn_id2 = res.sub_txn_id();
        }
        // mock rowset and tablet: for sub_txn3
        create_and_commit_rowset(meta_service.get(), t2, t2_index, t2_p3, t2_p3_t1, sub_txn_id2);
        {
            SubTxnInfo sub_txn_info2;
            sub_txn_info2.set_sub_txn_id(sub_txn_id2);
            sub_txn_info2.set_table_id(t2);
            sub_txn_info2.mutable_base_tablet_ids()->Add(t2_p3_t1);
            sub_txn_infos.push_back(sub_txn_info2);
        }

        // begin_sub_txn3
        int64_t sub_txn_id3 = -1;
        {
            brpc::Controller cntl;
            BeginSubTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            req.set_sub_txn_num(sub_txn_infos.size() - 1);
            req.set_db_id(db_id);
            req.set_label(label2);
            req.mutable_table_ids()->Add(t1);
            req.mutable_table_ids()->Add(t2);
            BeginSubTxnResponse res;
            meta_service->begin_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().table_ids().size(), 2);
            ASSERT_EQ(res.txn_info().sub_txn_ids().size(), sub_txn_infos.size());
            ASSERT_TRUE(res.has_sub_txn_id());
            sub_txn_id3 = res.sub_txn_id();
        }
        // mock rowset and tablet: for sub_txn3
        create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t1, sub_txn_id3);
        create_and_commit_rowset(meta_service.get(), t1, t1_index, t1_p1, t1_p1_t2, sub_txn_id3);
        {
            SubTxnInfo sub_txn_info3;
            sub_txn_info3.set_sub_txn_id(sub_txn_id3);
            sub_txn_info3.set_table_id(t1);
            sub_txn_info3.mutable_base_tablet_ids()->Add(t1_p1_t1);
            sub_txn_info3.mutable_base_tablet_ids()->Add(t1_p1_t2);
            sub_txn_infos.push_back(sub_txn_info3);
        }
    }

    // commit txn
    CommitTxnRequest req;
    {
        brpc::Controller cntl;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(666);
        req.set_txn_id(txn_id);
        req.set_is_txn_load(true);

        for (const auto& sub_txn_info : sub_txn_infos) {
            req.add_sub_txn_infos()->CopyFrom(sub_txn_info);
        }
        CommitTxnResponse res;
        meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                 &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.table_ids().size(), 3);

        ASSERT_EQ(res.table_ids()[0], t2);
        ASSERT_EQ(res.partition_ids()[0], t2_p3);
        ASSERT_EQ(res.versions()[0], 501);

        ASSERT_EQ(res.table_ids()[1], t1);
        ASSERT_EQ(res.partition_ids()[1], t1_p2);
        ASSERT_EQ(res.versions()[1], 501);

        ASSERT_EQ(res.table_ids()[2], t1);
        ASSERT_EQ(res.partition_ids()[2], t1_p1);
        ASSERT_EQ(res.versions()[2], 1001);
    }
}

TEST(MetaServiceTest, BeginAndAbortSubTxnTest) {
    auto meta_service = get_meta_service();
    long db_id = 98762;
    int64_t txn_id = -1;
    // begin txn
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(db_id);
        txn_info_pb.set_label("test_label");
        txn_info_pb.add_table_ids(1234);
        txn_info_pb.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info_pb);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
    }
    // case: begin 2 sub txn
    int64_t sub_txn_id1 = -1;
    int64_t sub_txn_id2 = -1;
    for (int i = 0; i < 2; i++) {
        {
            brpc::Controller cntl;
            BeginSubTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            req.set_sub_txn_num(i);
            req.set_db_id(db_id);
            req.set_label("test_label_" + std::to_string(i));
            req.mutable_table_ids()->Add(1234);
            req.mutable_table_ids()->Add(1235);
            if (i == 1) {
                req.mutable_table_ids()->Add(1235);
            }
            BeginSubTxnResponse res;
            meta_service->begin_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().table_ids().size(), i == 0 ? 2 : 3);
            ASSERT_EQ(res.txn_info().sub_txn_ids().size(), i == 0 ? 1 : 2);
            ASSERT_TRUE(res.has_sub_txn_id());
            if (i == 0) {
                sub_txn_id1 = res.sub_txn_id();
                ASSERT_EQ(sub_txn_id1, res.txn_info().sub_txn_ids()[0]);
            } else {
                sub_txn_id2 = res.sub_txn_id();
                ASSERT_EQ(sub_txn_id1, res.txn_info().sub_txn_ids()[0]);
                ASSERT_EQ(sub_txn_id2, res.txn_info().sub_txn_ids()[1]);
            }
        }
        // get txn state
        {
            brpc::Controller cntl;
            GetTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            GetTxnResponse res;
            meta_service->get_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().table_ids().size(), i == 0 ? 2 : 3);
            ASSERT_EQ(res.txn_info().table_ids()[0], 1234);
            ASSERT_EQ(res.txn_info().table_ids()[1], 1235);
            if (i == 1) {
                ASSERT_EQ(res.txn_info().table_ids()[2], 1235);
            }
        }
    }
    // case: abort sub txn2 twice
    {
        for (int i = 0; i < 2; i++) {
            brpc::Controller cntl;
            AbortSubTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            req.set_sub_txn_id(sub_txn_id2);
            req.set_sub_txn_num(2);
            req.set_db_id(db_id);
            req.mutable_table_ids()->Add(1234);
            req.mutable_table_ids()->Add(1235);
            AbortSubTxnResponse res;
            meta_service->abort_sub_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            // check txn state
            ASSERT_EQ(res.txn_info().table_ids().size(), 2);
            ASSERT_EQ(res.txn_info().sub_txn_ids().size(), 2);
            ASSERT_EQ(sub_txn_id1, res.txn_info().sub_txn_ids()[0]);
            ASSERT_EQ(sub_txn_id2, res.txn_info().sub_txn_ids()[1]);
        }
        // get txn state
        {
            brpc::Controller cntl;
            GetTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            GetTxnResponse res;
            meta_service->get_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().table_ids().size(), 2);
            ASSERT_EQ(res.txn_info().table_ids()[0], 1234);
            ASSERT_EQ(res.txn_info().table_ids()[1], 1235);
        }
    }
    // check label key does not exist
    for (int i = 0; i < 2; i++) {
        std::string key =
                txn_label_key({"test_instance", db_id, "test_label_" + std::to_string(i)});
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
    // check txn index key exist
    for (auto i : {sub_txn_id1, sub_txn_id2}) {
        std::string key = txn_index_key({"test_instance", i});
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
    }
}

TEST(MetaServiceTest, AbortTxnTest) {
    auto meta_service = get_meta_service();

    // case: abort txn by txn_id
    {
        int64_t db_id = 666;
        int64_t table_id = 12345;
        std::string label = "abort_txn_by_txn_id";
        std::string cloud_unique_id = "test_cloud_unique_id";
        int64_t tablet_id_base = 1104;
        int64_t txn_id = -1;
        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(table_id);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // mock rowset and tablet
        for (int i = 0; i < 5; ++i) {
            create_tablet(meta_service.get(), 12345, 1235, 1236, tablet_id_base + i);
            auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // abort txn by txn_id
        {
            brpc::Controller cntl;
            AbortTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            req.set_txn_id(txn_id);
            req.set_reason("test");
            AbortTxnResponse res;
            meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().status(), TxnStatusPB::TXN_STATUS_ABORTED);
        }
    }

    // case: abort txn by db_id + label
    {
        int64_t db_id = 66631313131;
        int64_t table_id = 12345;
        std::string label = "abort_txn_by_db_id_and_label";
        std::string cloud_unique_id = "test_cloud_unique_id";
        int64_t tablet_id_base = 1104;
        int64_t txn_id = -1;
        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(table_id);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // mock rowset and tablet
        for (int i = 0; i < 5; ++i) {
            create_tablet(meta_service.get(), table_id, 1235, 1236, tablet_id_base + i);
            auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // abort txn by db_id and label
        {
            brpc::Controller cntl;
            AbortTxnRequest req;
            req.set_cloud_unique_id(cloud_unique_id);
            req.set_db_id(db_id);
            req.set_label(label);
            req.set_reason("test");
            AbortTxnResponse res;
            meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().status(), TxnStatusPB::TXN_STATUS_ABORTED);

            std::string recycle_txn_key_;
            std::string recycle_txn_val;
            RecycleTxnKeyInfo recycle_txn_key_info {mock_instance, db_id, txn_id};
            recycle_txn_key(recycle_txn_key_info, &recycle_txn_key_);
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            ASSERT_EQ(txn->get(recycle_txn_key_, &recycle_txn_val), TxnErrorCode::TXN_OK);
            ASSERT_NE(txn_id, -1);
        }
    }
}

TEST(MetaServiceTest, GetCurrentMaxTxnIdTest) {
    auto meta_service = get_meta_service();

    const int64_t db_id = 123;
    const std::string label = "test_label123";
    const std::string cloud_unique_id = "test_cloud_unique_id";

    brpc::Controller begin_txn_cntl;
    BeginTxnRequest begin_txn_req;
    BeginTxnResponse begin_txn_res;
    TxnInfoPB txn_info_pb;

    begin_txn_req.set_cloud_unique_id(cloud_unique_id);
    txn_info_pb.set_db_id(db_id);
    txn_info_pb.set_label(label);
    txn_info_pb.add_table_ids(12345);
    txn_info_pb.set_timeout_ms(36000);
    begin_txn_req.mutable_txn_info()->CopyFrom(txn_info_pb);

    meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
                            &begin_txn_req, &begin_txn_res, nullptr);
    ASSERT_EQ(begin_txn_res.status().code(), MetaServiceCode::OK);

    brpc::Controller max_txn_id_cntl;
    GetCurrentMaxTxnRequest max_txn_id_req;
    GetCurrentMaxTxnResponse max_txn_id_res;

    max_txn_id_req.set_cloud_unique_id(cloud_unique_id);

    meta_service->get_current_max_txn_id(
            reinterpret_cast<::google::protobuf::RpcController*>(&max_txn_id_cntl), &max_txn_id_req,
            &max_txn_id_res, nullptr);

    ASSERT_EQ(max_txn_id_res.status().code(), MetaServiceCode::OK);
    ASSERT_GE(max_txn_id_res.current_max_txn_id(), begin_txn_res.txn_id());
}

TEST(MetaServiceTest, AbortTxnWithCoordinatorTest) {
    auto meta_service = get_meta_service();

    const int64_t db_id = 666;
    const int64_t table_id = 777;
    const std::string label = "test_label";
    const std::string cloud_unique_id = "test_cloud_unique_id";
    const int64_t coordinator_id = 15623;
    int64_t cur_time = std::chrono::duration_cast<std::chrono::seconds>(
                               std::chrono::steady_clock::now().time_since_epoch())
                               .count();
    std::string host = "127.0.0.1:15586";
    int64_t txn_id = -1;

    brpc::Controller begin_txn_cntl;
    BeginTxnRequest begin_txn_req;
    BeginTxnResponse begin_txn_res;
    TxnInfoPB txn_info_pb;
    TxnCoordinatorPB coordinator;

    begin_txn_req.set_cloud_unique_id(cloud_unique_id);
    txn_info_pb.set_db_id(db_id);
    txn_info_pb.set_label(label);
    txn_info_pb.add_table_ids(table_id);
    txn_info_pb.set_timeout_ms(36000);
    coordinator.set_id(coordinator_id);
    coordinator.set_ip(host);
    coordinator.set_sourcetype(::doris::cloud::TxnSourceTypePB::TXN_SOURCE_TYPE_BE);
    coordinator.set_start_time(cur_time);
    txn_info_pb.mutable_coordinator()->CopyFrom(coordinator);
    begin_txn_req.mutable_txn_info()->CopyFrom(txn_info_pb);

    meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
                            &begin_txn_req, &begin_txn_res, nullptr);
    ASSERT_EQ(begin_txn_res.status().code(), MetaServiceCode::OK);
    txn_id = begin_txn_res.txn_id();
    ASSERT_GT(txn_id, -1);

    brpc::Controller abort_txn_cntl;
    AbortTxnWithCoordinatorRequest abort_txn_req;
    AbortTxnWithCoordinatorResponse abort_txn_resp;

    abort_txn_req.set_id(coordinator_id);
    abort_txn_req.set_ip(host);
    abort_txn_req.set_start_time(cur_time + 3600);

    // first time to check txn conflict
    meta_service->abort_txn_with_coordinator(
            reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl), &abort_txn_req,
            &abort_txn_resp, nullptr);
    ASSERT_EQ(abort_txn_resp.status().code(), MetaServiceCode::OK);

    brpc::Controller abort_txn_conflict_cntl;
    CheckTxnConflictRequest check_txn_conflict_req;
    CheckTxnConflictResponse check_txn_conflict_res;

    check_txn_conflict_req.set_cloud_unique_id(cloud_unique_id);
    check_txn_conflict_req.set_db_id(db_id);
    check_txn_conflict_req.set_end_txn_id(txn_id + 1);
    check_txn_conflict_req.add_table_ids(table_id);

    // first time to check txn conflict
    meta_service->check_txn_conflict(
            reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
            &check_txn_conflict_req, &check_txn_conflict_res, nullptr);

    ASSERT_EQ(check_txn_conflict_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(check_txn_conflict_res.finished(), true);
    ASSERT_EQ(check_txn_conflict_res.conflict_txns_size(), 0);
}

TEST(MetaServiceTest, CheckTxnConflictTest) {
    auto meta_service = get_meta_service();

    const int64_t db_id = 666;
    const int64_t table_id = 777;
    const std::string label = "test_label";
    const std::string cloud_unique_id = "test_cloud_unique_id";
    int64_t txn_id = -1;

    brpc::Controller begin_txn_cntl;
    BeginTxnRequest begin_txn_req;
    BeginTxnResponse begin_txn_res;
    TxnInfoPB txn_info_pb;

    begin_txn_req.set_cloud_unique_id(cloud_unique_id);
    txn_info_pb.set_db_id(db_id);
    txn_info_pb.set_label(label);
    txn_info_pb.add_table_ids(table_id);
    txn_info_pb.set_timeout_ms(36000);
    begin_txn_req.mutable_txn_info()->CopyFrom(txn_info_pb);

    meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
                            &begin_txn_req, &begin_txn_res, nullptr);
    ASSERT_EQ(begin_txn_res.status().code(), MetaServiceCode::OK);
    txn_id = begin_txn_res.txn_id();
    ASSERT_GT(txn_id, -1);

    brpc::Controller check_txn_conflict_cntl;
    CheckTxnConflictRequest check_txn_conflict_req;
    CheckTxnConflictResponse check_txn_conflict_res;

    check_txn_conflict_req.set_cloud_unique_id(cloud_unique_id);
    check_txn_conflict_req.set_db_id(db_id);
    check_txn_conflict_req.set_end_txn_id(txn_id + 1);
    check_txn_conflict_req.add_table_ids(table_id);

    // first time to check txn conflict
    meta_service->check_txn_conflict(
            reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
            &check_txn_conflict_req, &check_txn_conflict_res, nullptr);

    ASSERT_EQ(check_txn_conflict_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(check_txn_conflict_res.finished(), false);
    ASSERT_EQ(check_txn_conflict_res.conflict_txns_size(), 1);
    check_txn_conflict_res.clear_conflict_txns();

    // mock rowset and tablet
    int64_t tablet_id_base = 123456;
    for (int i = 0; i < 5; ++i) {
        create_tablet(meta_service.get(), table_id, 1235, 1236, tablet_id_base + i);
        auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
        CreateRowsetResponse res;
        commit_rowset(meta_service.get(), tmp_rowset, res);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    brpc::Controller commit_txn_cntl;
    CommitTxnRequest commit_txn_req;
    commit_txn_req.set_cloud_unique_id(cloud_unique_id);
    commit_txn_req.set_db_id(db_id);
    commit_txn_req.set_txn_id(txn_id);
    CommitTxnResponse commit_txn_res;
    meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&commit_txn_cntl),
                             &commit_txn_req, &commit_txn_res, nullptr);
    ASSERT_EQ(commit_txn_res.status().code(), MetaServiceCode::OK);

    // second time to check txn conflict
    meta_service->check_txn_conflict(
            reinterpret_cast<::google::protobuf::RpcController*>(&check_txn_conflict_cntl),
            &check_txn_conflict_req, &check_txn_conflict_res, nullptr);

    ASSERT_EQ(check_txn_conflict_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(check_txn_conflict_res.finished(), true);
    ASSERT_EQ(check_txn_conflict_res.conflict_txns_size(), 0);

    {
        std::string running_key = txn_running_key({mock_instance, db_id, txn_id});
        std::string running_value;
        std::unique_ptr<Transaction> txn;
        TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
        ASSERT_EQ(err, TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(running_key, &running_value), TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
}

TEST(MetaServiceTest, CheckNotTimeoutTxnConflictTest) {
    auto meta_service = get_meta_service();

    const int64_t db_id = 666;
    const int64_t table_id = 777;
    const std::string label = "test_label";
    const std::string cloud_unique_id = "test_cloud_unique_id";
    int64_t txn_id = -1;

    brpc::Controller begin_txn_cntl;
    BeginTxnRequest begin_txn_req;
    BeginTxnResponse begin_txn_res;
    TxnInfoPB txn_info_pb;

    begin_txn_req.set_cloud_unique_id(cloud_unique_id);
    txn_info_pb.set_db_id(db_id);
    txn_info_pb.set_label(label);
    txn_info_pb.add_table_ids(table_id);
    txn_info_pb.set_timeout_ms(3);
    begin_txn_req.mutable_txn_info()->CopyFrom(txn_info_pb);

    meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
                            &begin_txn_req, &begin_txn_res, nullptr);
    ASSERT_EQ(begin_txn_res.status().code(), MetaServiceCode::OK);
    txn_id = begin_txn_res.txn_id();
    ASSERT_GT(txn_id, -1);

    brpc::Controller check_txn_conflict_cntl;
    CheckTxnConflictRequest check_txn_conflict_req;
    CheckTxnConflictResponse check_txn_conflict_res;

    check_txn_conflict_req.set_cloud_unique_id(cloud_unique_id);
    check_txn_conflict_req.set_db_id(db_id);
    check_txn_conflict_req.set_end_txn_id(txn_id + 1);
    check_txn_conflict_req.add_table_ids(table_id);

    // wait txn timeout
    sleep(5);
    // first time to check txn conflict
    meta_service->check_txn_conflict(
            reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
            &check_txn_conflict_req, &check_txn_conflict_res, nullptr);

    ASSERT_EQ(check_txn_conflict_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(check_txn_conflict_res.finished(), true);
}

TEST(MetaServiceTest, CheckTxnConflictWithAbortLabelTest) {
    int ret = 0;

    auto txn_kv = std::dynamic_pointer_cast<TxnKv>(std::make_shared<MemTxnKv>());
    if (txn_kv != nullptr) {
        ret = txn_kv->init();
        [&] { ASSERT_EQ(ret, 0); }();
    }
    [&] { ASSERT_NE(txn_kv.get(), nullptr); }();

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->remove("\x00", "\xfe"); // This is dangerous if the fdb is not correctly set
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    auto rs = std::make_shared<MockResourceManager>(txn_kv);
    auto rl = std::make_shared<RateLimiter>();
    auto snapshot = std::make_shared<SnapshotManager>(txn_kv);
    auto meta_service = std::make_unique<MetaServiceProxy>(
            std::make_unique<MetaServiceImpl>(txn_kv, rs, rl, snapshot));

    const int64_t db_id = 666;
    const int64_t table_id = 777;
    const std::string label = "test_label";
    const std::string cloud_unique_id = "test_cloud_unique_id";
    int64_t txn_id = -1;

    brpc::Controller begin_txn_cntl;
    BeginTxnRequest begin_txn_req;
    BeginTxnResponse begin_txn_res;
    TxnInfoPB txn_info_pb;

    begin_txn_req.set_cloud_unique_id(cloud_unique_id);
    txn_info_pb.set_db_id(db_id);
    txn_info_pb.set_label(label);
    txn_info_pb.add_table_ids(table_id);
    txn_info_pb.set_timeout_ms(36000);
    begin_txn_req.mutable_txn_info()->CopyFrom(txn_info_pb);

    meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
                            &begin_txn_req, &begin_txn_res, nullptr);
    ASSERT_EQ(begin_txn_res.status().code(), MetaServiceCode::OK);
    txn_id = begin_txn_res.txn_id();
    ASSERT_GT(txn_id, -1);

    brpc::Controller check_txn_conflict_cntl;
    CheckTxnConflictRequest check_txn_conflict_req;
    CheckTxnConflictResponse check_txn_conflict_res;

    check_txn_conflict_req.set_cloud_unique_id(cloud_unique_id);
    check_txn_conflict_req.set_db_id(db_id);
    check_txn_conflict_req.set_end_txn_id(txn_id + 1);
    check_txn_conflict_req.add_table_ids(table_id);

    // first time to check txn conflict
    meta_service->check_txn_conflict(
            reinterpret_cast<::google::protobuf::RpcController*>(&begin_txn_cntl),
            &check_txn_conflict_req, &check_txn_conflict_res, nullptr);

    ASSERT_EQ(check_txn_conflict_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(check_txn_conflict_res.finished(), false);

    std::string running_key;
    std::string running_val;
    txn_running_key({mock_instance, db_id, txn_id}, &running_key);
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(running_key, &running_val), TxnErrorCode::TXN_OK);
    }

    brpc::Controller abort_txn_cntl;
    AbortTxnRequest abort_txn_req;
    abort_txn_req.set_cloud_unique_id(cloud_unique_id);
    abort_txn_req.set_db_id(db_id);
    abort_txn_req.set_label(label);
    AbortTxnResponse abort_txn_res;
    meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&abort_txn_cntl),
                            &abort_txn_req, &abort_txn_res, nullptr);
    ASSERT_EQ(abort_txn_res.status().code(), MetaServiceCode::OK);

    // second time to check txn conflict
    meta_service->check_txn_conflict(
            reinterpret_cast<::google::protobuf::RpcController*>(&check_txn_conflict_cntl),
            &check_txn_conflict_req, &check_txn_conflict_res, nullptr);

    ASSERT_EQ(check_txn_conflict_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(check_txn_conflict_res.finished(), true);

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(running_key, &running_val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    }
}

TEST(MetaServiceTest, CleanTxnLabelTest) {
    int ret = 0;
    auto txn_kv = std::dynamic_pointer_cast<TxnKv>(std::make_shared<MemTxnKv>());
    if (txn_kv != nullptr) {
        ret = txn_kv->init();
        [&] { ASSERT_EQ(ret, 0); }();
    }
    [&] { ASSERT_NE(txn_kv.get(), nullptr); }();

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->remove("\x00", "\xfe"); // This is dangerous if the fdb is not correctly set
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    auto rs = std::make_shared<MockResourceManager>(txn_kv);
    auto rl = std::make_shared<RateLimiter>();
    auto snapshot = std::make_shared<SnapshotManager>(txn_kv);
    auto meta_service = std::make_unique<MetaServiceProxy>(
            std::make_unique<MetaServiceImpl>(txn_kv, rs, rl, snapshot));

    // clean txn label by db_id and label
    {
        int64_t txn_id = -1;
        int64_t db_id = 1987211;
        const std::string& label = "test_clean_label";

        {
            brpc::Controller cntl;
            CleanTxnLabelRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.add_labels(label);
            CleanTxnLabelResponse res;
            meta_service->clean_txn_label(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        const std::string info_key = txn_info_key({mock_instance, db_id, txn_id});
        std::string info_val;

        const std::string label_key = txn_label_key({mock_instance, db_id, label});
        std::string label_val;

        const std::string index_key = txn_index_key({mock_instance, txn_id});
        std::string index_val;

        const std::string running_key = txn_running_key({mock_instance, db_id, txn_id});
        std::string running_val;

        const std::string recycle_key = recycle_txn_key({mock_instance, db_id, txn_id});
        std::string recycle_val;

        {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
            TxnErrorCode err = txn->get(info_key, &info_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            err = txn->get(label_key, &label_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            err = txn->get(index_key, &index_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            err = txn->get(running_key, &running_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            err = txn->get(recycle_key, &recycle_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
        }

        // mock rowset and tablet
        int64_t tablet_id_base = 110313131;
        for (int i = 0; i < 2; ++i) {
            create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id_base + i);
            auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // commit txn
        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(txn_id);
            CommitTxnResponse res;
            meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::TXN_LABEL_ALREADY_USED);
        }

        // clean txn label
        {
            brpc::Controller cntl;
            CleanTxnLabelRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            CleanTxnLabelResponse res;
            meta_service->clean_txn_label(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        }

        // clean txn label
        {
            brpc::Controller cntl;
            CleanTxnLabelRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.add_labels(label);
            CleanTxnLabelResponse res;
            meta_service->clean_txn_label(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
            TxnErrorCode err = txn->get(info_key, &info_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
            err = txn->get(label_key, &label_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
            err = txn->get(index_key, &index_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
            err = txn->get(running_key, &running_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
            err = txn->get(recycle_key, &recycle_val);
            ASSERT_EQ(err, TxnErrorCode::TXN_KEY_NOT_FOUND);
        }

        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // abort txn
        {
            brpc::Controller cntl;
            AbortTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            ASSERT_GT(txn_id, 0);
            req.set_txn_id(txn_id);
            req.set_reason("test");
            AbortTxnResponse res;
            meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().status(), TxnStatusPB::TXN_STATUS_ABORTED);
        }

        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // clean txn label
        {
            brpc::Controller cntl;
            CleanTxnLabelRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.add_labels(label);
            CleanTxnLabelResponse res;
            meta_service->clean_txn_label(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // abort txn
        {
            brpc::Controller cntl;
            AbortTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            ASSERT_GT(txn_id, 0);
            req.set_txn_id(txn_id);
            req.set_reason("test");
            AbortTxnResponse res;
            meta_service->abort_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(res.txn_info().status(), TxnStatusPB::TXN_STATUS_ABORTED);
        }

        // clean txn label
        {
            brpc::Controller cntl;
            CleanTxnLabelRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.add_labels(label);
            CleanTxnLabelResponse res;
            meta_service->clean_txn_label(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        {
            const std::string info_key = txn_info_key({mock_instance, db_id, txn_id});
            std::string info_val;

            const std::string label_key = txn_label_key({mock_instance, db_id, label});
            std::string label_val;

            const std::string index_key = txn_index_key({mock_instance, txn_id});
            std::string index_val;

            const std::string running_key = txn_running_key({mock_instance, db_id, txn_id});
            std::string running_val;

            const std::string recycle_key = recycle_txn_key({mock_instance, db_id, txn_id});
            std::string recycle_val;

            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
            TxnErrorCode ret = txn->get(info_key, &info_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);
            ret = txn->get(label_key, &label_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);
            ret = txn->get(index_key, &index_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);
            ret = txn->get(running_key, &running_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);
            ret = txn->get(recycle_key, &recycle_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);
        }
    }
    // clean txn label only by db_id
    {
        int64_t db_id = 1987211123;
        const std::string& label = "test_clean_label";

        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(db_id);
        txn_info_pb.add_table_ids(1234);
        txn_info_pb.set_timeout_ms(36000);
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");

        //clean not exist label
        {
            brpc::Controller cntl;
            CleanTxnLabelRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            CleanTxnLabelResponse res;
            meta_service->clean_txn_label(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                    nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // inject internal_clean_label err = TXN_CONFLICT
        {
            auto sp = SyncPoint::get_instance();
            sp->set_call_back("internal_clean_label:err", [&](auto&& args) {
                auto* err = try_any_cast<TxnErrorCode*>(args[0]);
                *err = TxnErrorCode::TXN_CONFLICT;
            });
            sp->enable_processing();
            int64_t txn_id = -1;
            for (int i = 100; i < 101; i++) {
                {
                    std::stringstream label_ss;
                    label_ss << label << i;
                    brpc::Controller cntl;
                    txn_info_pb.set_label(label_ss.str());
                    req.mutable_txn_info()->CopyFrom(txn_info_pb);
                    BeginTxnResponse res;
                    meta_service->begin_txn(
                            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                            nullptr);
                    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                    txn_id = res.txn_id();
                }

                {
                    // mock rowset and tablet
                    int64_t tablet_id_base = 110313131;
                    for (int i = 0; i < 1; ++i) {
                        create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id_base + i);
                        auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
                        CreateRowsetResponse res;
                        commit_rowset(meta_service.get(), tmp_rowset, res);
                        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                    }
                }

                // commit txn
                {
                    brpc::Controller cntl;
                    CommitTxnRequest req;
                    req.set_cloud_unique_id("test_cloud_unique_id");
                    req.set_db_id(db_id);
                    req.set_txn_id(txn_id);
                    CommitTxnResponse res;
                    meta_service->commit_txn(
                            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                            nullptr);
                    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                }
            }

            {
                brpc::Controller cntl;
                CleanTxnLabelRequest req;
                req.set_cloud_unique_id("test_cloud_unique_id");
                req.set_db_id(db_id);
                CleanTxnLabelResponse res;
                meta_service->clean_txn_label(
                        reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                        nullptr);
                ASSERT_EQ(res.status().code(), MetaServiceCode::KV_TXN_CONFLICT);
            }
            sp->clear_all_call_backs();
            sp->clear_trace();
            sp->disable_processing();
        }

        // create 12 committed txns and clean label by id
        {
            auto sp = SyncPoint::get_instance();
            sp->set_call_back("clean_txn_label:limit", [](auto&& args) {
                int* limit = try_any_cast<int*>(args[0]);
                *limit = 5;
            });
            sp->enable_processing();

            int64_t txn_id = -1;
            for (int i = 0; i < 12; i++) {
                {
                    std::stringstream label_ss;
                    label_ss << label << i;
                    brpc::Controller cntl;
                    txn_info_pb.set_label(label_ss.str());
                    req.mutable_txn_info()->CopyFrom(txn_info_pb);
                    BeginTxnResponse res;
                    meta_service->begin_txn(
                            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                            nullptr);
                    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                    txn_id = res.txn_id();
                }

                {
                    // mock rowset and tablet
                    int64_t tablet_id_base = 110313131;
                    for (int i = 0; i < 1; ++i) {
                        create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id_base + i);
                        auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
                        CreateRowsetResponse res;
                        commit_rowset(meta_service.get(), tmp_rowset, res);
                        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                    }
                }

                // commit txn
                {
                    brpc::Controller cntl;
                    CommitTxnRequest req;
                    req.set_cloud_unique_id("test_cloud_unique_id");
                    req.set_db_id(db_id);
                    req.set_txn_id(txn_id);
                    CommitTxnResponse res;
                    meta_service->commit_txn(
                            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                            nullptr);
                    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
                }
            }

            {
                brpc::Controller cntl;
                CleanTxnLabelRequest req;
                req.set_cloud_unique_id("test_cloud_unique_id");
                req.set_db_id(db_id);
                CleanTxnLabelResponse res;
                meta_service->clean_txn_label(
                        reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res,
                        nullptr);
                ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            }
            sp->clear_all_call_backs();
            sp->clear_trace();
            sp->disable_processing();
        }
    }
}

TEST(MetaServiceTest, GetTxnTest) {
    int ret = 0;
    auto txn_kv = std::dynamic_pointer_cast<TxnKv>(std::make_shared<MemTxnKv>());
    if (txn_kv != nullptr) {
        ret = txn_kv->init();
        [&] { ASSERT_EQ(ret, 0); }();
    }
    [&] { ASSERT_NE(txn_kv.get(), nullptr); }();

    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(txn_kv->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->remove("\x00", "\xfe"); // This is dangerous if the fdb is not correctly set
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    auto rs = std::make_shared<MockResourceManager>(txn_kv);
    auto rl = std::make_shared<RateLimiter>();
    auto snapshot = std::make_shared<SnapshotManager>(txn_kv);
    auto meta_service = std::make_unique<MetaServiceProxy>(
            std::make_unique<MetaServiceImpl>(txn_kv, rs, rl, snapshot));

    {
        int64_t txn_id = -1;
        int64_t db_id = 34521431231;
        const std::string& label = "test_get_txn";

        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(label);
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        {
            brpc::Controller cntl;
            GetTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(-1);
            GetTxnResponse res;
            meta_service->get_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        }

        {
            brpc::Controller cntl;
            GetTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(txn_id);
            GetTxnResponse res;
            meta_service->get_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        {
            brpc::Controller cntl;
            GetTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_txn_id(txn_id);
            GetTxnResponse res;
            meta_service->get_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }
    }
}
//

TEST(MetaServiceTest, CopyJobTest) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    auto cloud_unique_id = "test_cloud_unique_id";
    auto stage_id = "test_stage_id";
    int64_t table_id = 100;
    std::string instance_id = "copy_job_test_instance_id";

    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    // generate a begin copy request
    BeginCopyRequest begin_copy_request;
    begin_copy_request.set_cloud_unique_id(cloud_unique_id);
    begin_copy_request.set_stage_id(stage_id);
    begin_copy_request.set_stage_type(StagePB::EXTERNAL);
    begin_copy_request.set_table_id(table_id);
    begin_copy_request.set_copy_id("test_copy_id");
    begin_copy_request.set_group_id(0);
    begin_copy_request.set_start_time_ms(200);
    begin_copy_request.set_timeout_time_ms(300);
    for (int i = 0; i < 20; ++i) {
        ObjectFilePB object_file_pb;
        object_file_pb.set_relative_path("obj_" + std::to_string(i));
        object_file_pb.set_etag("obj_" + std::to_string(i) + "_etag");
        begin_copy_request.add_object_files()->CopyFrom(object_file_pb);
    }

    // generate a finish copy request
    FinishCopyRequest finish_copy_request;
    finish_copy_request.set_cloud_unique_id(cloud_unique_id);
    finish_copy_request.set_stage_id(stage_id);
    finish_copy_request.set_stage_type(StagePB::EXTERNAL);
    finish_copy_request.set_table_id(table_id);
    finish_copy_request.set_copy_id("test_copy_id");
    finish_copy_request.set_group_id(0);
    finish_copy_request.set_action(FinishCopyRequest::COMMIT);

    // generate a get copy files request
    GetCopyFilesRequest get_copy_file_req;
    get_copy_file_req.set_cloud_unique_id(cloud_unique_id);
    get_copy_file_req.set_stage_id(stage_id);
    get_copy_file_req.set_table_id(table_id);

    // generate a get copy job request
    GetCopyJobRequest get_copy_job_request;
    get_copy_job_request.set_cloud_unique_id(cloud_unique_id);
    get_copy_job_request.set_stage_id(stage_id);
    get_copy_job_request.set_table_id(table_id);
    get_copy_job_request.set_copy_id("test_copy_id");
    get_copy_job_request.set_group_id(0);

    // get copy job
    {
        GetCopyJobResponse res;
        meta_service->get_copy_job(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &get_copy_job_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.has_copy_job(), false);
    }
    // begin copy
    {
        BeginCopyResponse res;
        meta_service->begin_copy(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                 &begin_copy_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.filtered_object_files_size(), 20);
    }
    // get copy files
    {
        GetCopyFilesResponse res;
        meta_service->get_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &get_copy_file_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files_size(), 20);
    }
    // get copy job
    {
        GetCopyJobResponse res;
        meta_service->get_copy_job(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &get_copy_job_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.copy_job().object_files().size(), 20);
    }
    // begin copy with duplicate files
    {
        begin_copy_request.set_copy_id("test_copy_id_1");
        begin_copy_request.clear_object_files();
        for (int i = 15; i < 30; ++i) {
            ObjectFilePB object_file_pb;
            object_file_pb.set_relative_path("obj_" + std::to_string(i));
            object_file_pb.set_etag("obj_" + std::to_string(i) + "_etag");
            begin_copy_request.add_object_files()->CopyFrom(object_file_pb);
        }

        BeginCopyResponse res;
        meta_service->begin_copy(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                 &begin_copy_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.filtered_object_files_size(), 10);
    }
    // get copy files
    {
        GetCopyFilesResponse res;
        meta_service->get_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &get_copy_file_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files_size(), 30);
    }
    // finish the first copy job
    {
        FinishCopyResponse res;
        meta_service->finish_copy(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                  &finish_copy_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
    // get copy files
    {
        GetCopyFilesResponse res;
        meta_service->get_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &get_copy_file_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files_size(), 30);
    }
    // abort the second copy job
    {
        finish_copy_request.set_copy_id("test_copy_id_1");
        finish_copy_request.set_action(FinishCopyRequest::ABORT);

        FinishCopyResponse res;
        meta_service->finish_copy(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                  &finish_copy_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
    // get copy files
    {
        GetCopyFilesResponse res;
        meta_service->get_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &get_copy_file_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files_size(), 20);
    }
    {
        // begin a copy job whose files are all loaded, the copy job key should not be created
        begin_copy_request.set_copy_id("tmp_id");
        begin_copy_request.clear_object_files();
        for (int i = 0; i < 20; ++i) {
            ObjectFilePB object_file_pb;
            object_file_pb.set_relative_path("obj_" + std::to_string(i));
            object_file_pb.set_etag("obj_" + std::to_string(i) + "_etag");
            begin_copy_request.add_object_files()->CopyFrom(object_file_pb);
        }
        BeginCopyResponse res;
        meta_service->begin_copy(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                 &begin_copy_request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.filtered_object_files_size(), 0);
        // get copy job
        get_copy_job_request.set_copy_id("tmp_id");
        GetCopyJobResponse res2;
        meta_service->get_copy_job(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &get_copy_job_request, &res2, nullptr);
        ASSERT_EQ(res2.status().code(), MetaServiceCode::OK);
        ASSERT_FALSE(res2.has_copy_job());
    }
    // scan fdb
    {
        std::unique_ptr<Transaction> txn;
        std::string get_val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        // 20 copy files
        {
            CopyFileKeyInfo key_info0 {instance_id, stage_id, table_id, "", ""};
            CopyFileKeyInfo key_info1 {instance_id, stage_id, table_id + 1, "", ""};
            std::string key0;
            std::string key1;
            copy_file_key(key_info0, &key0);
            copy_file_key(key_info1, &key1);
            std::unique_ptr<RangeGetIterator> it;
            ASSERT_EQ(txn->get(key0, key1, &it), TxnErrorCode::TXN_OK);
            int file_cnt = 0;
            do {
                ASSERT_EQ(txn->get(key0, key1, &it), TxnErrorCode::TXN_OK);
                while (it->has_next()) {
                    auto [k, v] = it->next();
                    CopyFilePB copy_file;
                    ASSERT_TRUE(copy_file.ParseFromArray(v.data(), v.size()));
                    ASSERT_EQ(copy_file.copy_id(), "test_copy_id");
                    ++file_cnt;
                    if (!it->has_next()) {
                        key0 = k;
                    }
                }
                key0.push_back('\x00');
            } while (it->more());
            ASSERT_EQ(file_cnt, 20);
        }
        // 1 copy job with finish status
        {
            CopyJobKeyInfo key_info0 {instance_id, stage_id, table_id, "", 0};
            CopyJobKeyInfo key_info1 {instance_id, stage_id, table_id + 1, "", 0};
            std::string key0;
            std::string key1;
            copy_job_key(key_info0, &key0);
            copy_job_key(key_info1, &key1);
            std::unique_ptr<RangeGetIterator> it;
            int job_cnt = 0;
            do {
                ASSERT_EQ(txn->get(key0, key1, &it), TxnErrorCode::TXN_OK);
                while (it->has_next()) {
                    auto [k, v] = it->next();
                    CopyJobPB copy_job;
                    ASSERT_EQ(copy_job.ParseFromArray(v.data(), v.size()), true);
                    ASSERT_EQ(copy_job.object_files_size(), 20);
                    ASSERT_EQ(copy_job.job_status(), CopyJobPB::FINISH);
                    ++job_cnt;
                    if (!it->has_next()) {
                        key0 = k;
                    }
                }
                key0.push_back('\x00');
            } while (it->more());
            ASSERT_EQ(job_cnt, 1);
        }
    }
}

TEST(MetaServiceTest, FilterCopyFilesTest) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    auto cloud_unique_id = "test_cloud_unique_id";
    std::string instance_id = "stage_test_instance_id";
    auto stage_id = "test_stage_id";
    int64_t table_id = 100;
    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "test";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    sp->set_call_back("decrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* key = try_any_cast<std::string*>(args[0]);
        *key = "test";
        auto* ret = try_any_cast<int*>(args[1]);
        *ret = 0;
    });
    sp->enable_processing();

    FilterCopyFilesRequest request;
    request.set_cloud_unique_id(cloud_unique_id);
    request.set_stage_id(stage_id);
    request.set_table_id(table_id);
    for (int i = 0; i < 10; ++i) {
        ObjectFilePB object_file;
        object_file.set_relative_path("file" + std::to_string(i));
        object_file.set_etag("etag" + std::to_string(i));
        request.add_object_files()->CopyFrom(object_file);
    }

    // all files are not loaded
    {
        FilterCopyFilesResponse res;
        meta_service->filter_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files().size(), 10);
    }

    // some files are loaded
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        for (int i = 0; i < 4; ++i) {
            CopyFileKeyInfo key_info {instance_id, stage_id, table_id, "file" + std::to_string(i),
                                      "etag" + std::to_string(i)};
            std::string key;
            copy_file_key(key_info, &key);
            CopyFilePB copy_file;
            copy_file.set_copy_id("test_copy_id");
            std::string val;
            copy_file.SerializeToString(&val);
            txn->put(key, val);
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        FilterCopyFilesResponse res;
        meta_service->filter_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files().size(), 6);
        ASSERT_EQ(res.object_files().at(0).relative_path(), "file4");
    }

    // all files are loaded
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        for (int i = 4; i < 10; ++i) {
            CopyFileKeyInfo key_info {instance_id, stage_id, table_id, "file" + std::to_string(i),
                                      "etag" + std::to_string(i)};
            std::string key;
            copy_file_key(key_info, &key);
            CopyFilePB copy_file;
            copy_file.set_copy_id("test_copy_id");
            std::string val;
            copy_file.SerializeToString(&val);
            txn->put(key, val);
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        FilterCopyFilesResponse res;
        meta_service->filter_copy_files(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                        &request, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.object_files().size(), 0);
    }
}

extern std::vector<std::pair<int64_t, int64_t>> calc_sync_versions(
        int64_t req_bc_cnt, int64_t bc_cnt, int64_t req_cc_cnt, int64_t cc_cnt, int64_t req_cp,
        int64_t cp, int64_t req_fc_cnt, int64_t fc_cnt, int64_t req_start, int64_t req_end);

TEST(MetaServiceTest, CalcSyncVersionsTest) {
    using Versions = std::vector<std::pair<int64_t, int64_t>>;
    // * no compaction happened
    // req_cc_cnt == ms_cc_cnt && req_bc_cnt == ms_bc_cnt && req_cp == ms_cp
    // BE  [=][=][=][=][=====][=][=]<.......>
    //                  ^~~~~ req_cp
    // BE  [=][=][=][=][=====][=][=][=][=][=][=]
    //                  ^~~~~ ms_cp
    //                               ^_____^ versions_return: [req_start, req_end]
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 0};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 1};
        auto [req_cp, cp] = std::tuple {5, 5};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{8, 12}}));
    }
    // * only one CC happened and CP changed
    // req_cc_cnt == ms_cc_cnt - 1 && req_bc_cnt == ms_bc_cnt && req_cp < ms_cp
    // BE  [=][=][=][=][=====][=][=]<.......>
    //                  ^~~~~ req_cp
    // MS  [=][=][=][=][xxxxxxxxxxxxxx][=======][=][=]
    //                                  ^~~~~~~ ms_cp
    //                  ^__________________^ versions_return: [req_cp, ms_cp - 1] v [req_start, req_end]
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 0};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {5, 10};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{5, 12}})); // [5, 9] v [8, 12]
    }
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 0};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {5, 15};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{5, 14}})); // [5, 14] v [8, 12]
    }
    // * only one CC happened and CP remain unchanged
    // req_cc_cnt == ms_cc_cnt - 1 && req_bc_cnt == ms_bc_cnt && req_cp == ms_cp
    // BE  [=][=][=][=][=====][=][=]<.......>
    //                  ^~~~~ req_cp
    // MS  [=][=][=][=][xxxxxxxxxxxxxx][=][=][=][=][=]
    //                  ^~~~~~~~~~~~~~ ms_cp
    //                  ^__________________^ versions_return: [req_cp, max] v [req_start, req_end]
    //
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 0};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {5, 5};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{5, INT64_MAX - 1}})); // [5, max] v [8, 12]
    }
    // * more than one CC happened and CP remain unchanged
    // req_cc_cnt < ms_cc_cnt - 1 && req_bc_cnt == ms_bc_cnt && req_cp == ms_cp
    // BE  [=][=][=][=][=====][=][=]<.......>
    //                  ^~~~~ req_cp
    // MS  [=][=][=][=][xxxxxxxxxxxxxx][xxxxxxx][=][=]
    //                  ^~~~~~~~~~~~~~ ms_cp
    //                  ^_____________________^ versions_return: [req_cp, max] v [req_start, req_end]
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 0};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 3};
        auto [req_cp, cp] = std::tuple {5, 5};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{5, INT64_MAX - 1}})); // [5, max] v [8, 12]
    }
    // * more than one CC happened and CP changed
    // BE  [=][=][=][=][=====][=][=]
    //                  ^~~~~ req_cp
    // MS  [=][=][=][=][xxxxxxxxxxxxxx][xxxxxxx][=][=]
    //                                  ^~~~~~~ ms_cp
    //                  ^_____________________^ related_versions: [req_cp, max] v [req_start, req_end]
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 0};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 3};
        auto [req_cp, cp] = std::tuple {5, 15};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{5, INT64_MAX - 1}})); // [5, max] v [8, 12]
    }
    // * for any BC happended
    // req_bc_cnt < ms_bc_cnt
    // BE  [=][=][=][=][=====][=][=]<.......>
    //                  ^~~~~ req_cp
    // MS  [xxxxxxxxxx][xxxxxxxxxxxxxx][=======][=][=]
    //                                  ^~~~~~~ ms_cp
    //     ^_________________________^ versions_return: [0, ms_cp - 1] v versions_return_in_above_case
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 1};
        auto [req_cp, cp] = std::tuple {5, 5};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{0, 4}, {8, 12}}));
    }
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 1};
        auto [req_cp, cp] = std::tuple {8, 8};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{0, 12}})); // [0, 7] v [8, 12]
    }
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {5, 10};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{0, 12}})); // [0, 4] v [5, 9] v [8, 12]
    }
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {5, 15};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{0, 14}})); // [0, 4] v [5, 14] v [8, 12]
    }
    {
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {5, 5};
        auto [req_start, req_end] = std::tuple {8, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        // [0, 4] v [5, max] v [8, 12]
        ASSERT_EQ(versions, (Versions {{0, INT64_MAX - 1}}));
    }

    {
        // when there exists full compaction, we can't optimize by "* only one CC happened and CP changed"

        // * one CC happened and CP changed, and full compaction happened
        // BE  [=][=][=][=][=][=][=][=][=][=]
        //                  ^~~~~ req_cp
        // MS  [xxxxxxxxxxxxxx][xxxxxxxxxxxxxx][=======][=][=]
        //                      ^~~~~~~ ms_cp
        //                  ^___________________________^ related_versions: [req_cp, max]
        //
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {4, 7};
        auto [req_start, req_end] = std::tuple {9, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 1,
                                           req_start, req_end);
        ASSERT_EQ(versions, (Versions {{0, INT64_MAX - 1}}));
    }

    {
        // abnormal case:
        auto [req_bc_cnt, bc_cnt] = std::tuple {0, 1};
        auto [req_cc_cnt, cc_cnt] = std::tuple {1, 2};
        auto [req_cp, cp] = std::tuple {4, 7};
        auto [req_start, req_end] = std::tuple {9, 12};
        auto versions = calc_sync_versions(req_bc_cnt, bc_cnt, req_cc_cnt, cc_cnt, req_cp, cp, 0, 0,
                                           req_start, req_end);
        // when not considering full compaction, the returned versions is wrong becasue rowsets in [7-8] are missed
        ASSERT_EQ(versions, (Versions {{0, 6}, {9, 12}}));
    }
}

TEST(MetaServiceTest, StageTest) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    auto cloud_unique_id = "test_cloud_unique_id";
    std::string instance_id = "stage_test_instance_id";
    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "test";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    sp->set_call_back("decrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* key = try_any_cast<std::string*>(args[0]);
        *key = "test";
        auto* ret = try_any_cast<int*>(args[1]);
        *ret = 0;
    });
    sp->enable_processing();

    ObjectStoreInfoPB obj;
    obj.set_ak("123");
    obj.set_sk("321");
    obj.set_bucket("456");
    obj.set_prefix("654");
    obj.set_endpoint("789");
    obj.set_region("987");
    obj.set_external_endpoint("888");
    obj.set_provider(ObjectStoreInfoPB::BOS);

    RamUserPB ram_user;
    ram_user.set_user_id("test_user_id");
    ram_user.set_ak("test_ak");
    ram_user.set_sk("test_sk");
    EncryptionInfoPB encry_info;
    encry_info.set_encryption_method("encry_method_test");
    encry_info.set_key_id(1111);
    ram_user.mutable_encryption_info()->CopyFrom(encry_info);

    // create instance
    {
        CreateInstanceRequest req;
        req.set_instance_id(instance_id);
        req.set_user_id("test_user");
        req.set_name("test_name");
        req.mutable_ram_user()->CopyFrom(ram_user);
        req.mutable_obj_info()->CopyFrom(obj);

        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // test create and get internal stage
    {
        // get a non-existent internal stage
        GetStageRequest get_stage_req;
        GetStageResponse res;
        // no cloud_unique_id
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);

        get_stage_req.set_cloud_unique_id(cloud_unique_id);
        // no instance_id
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = "";
            ret->second = true;
        });
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        sp->clear_call_back("get_instance_id");
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });

        // no stage type
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        get_stage_req.set_type(StagePB::INTERNAL);

        // no internal stage user name
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        get_stage_req.set_mysql_user_name("root");

        // no internal stage user id
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        get_stage_req.set_mysql_user_id("root_id");
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::STAGE_NOT_FOUND);

        // create an internal stage
        CreateStageRequest create_stage_request;
        StagePB stage;
        stage.set_type(StagePB::INTERNAL);
        stage.add_mysql_user_name("root");
        stage.add_mysql_user_id("root_id");
        stage.set_stage_id("internal_stage_id");
        create_stage_request.set_cloud_unique_id(cloud_unique_id);
        create_stage_request.mutable_stage()->CopyFrom(stage);
        CreateStageResponse create_stage_response;
        meta_service->create_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &create_stage_request, &create_stage_response, nullptr);
        ASSERT_EQ(create_stage_response.status().code(), MetaServiceCode::OK);

        // get existent internal stage
        GetStageResponse res2;
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res2, nullptr);
        ASSERT_EQ(res2.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(1, res2.stage().size());

        // can't find user id's stage
        GetStageResponse res3;
        get_stage_req.set_mysql_user_id("not_root_id_exist");
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res3, nullptr);
        ASSERT_EQ(res3.status().code(), MetaServiceCode::STATE_ALREADY_EXISTED_FOR_USER);
        ASSERT_EQ(1, res3.stage().size());

        // drop internal stage
        DropStageRequest drop_stage_request;
        drop_stage_request.set_cloud_unique_id(cloud_unique_id);
        drop_stage_request.set_type(StagePB::INTERNAL);
        drop_stage_request.set_mysql_user_id("root_id");
        drop_stage_request.set_reason("Drop");
        DropStageResponse drop_stage_response;
        meta_service->drop_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                 &drop_stage_request, &drop_stage_response, nullptr);
        ASSERT_EQ(drop_stage_response.status().code(), MetaServiceCode::OK);
        // scan fdb has recycle_stage key
        {
            RecycleStageKeyInfo key_info0 {instance_id, ""};
            RecycleStageKeyInfo key_info1 {instance_id, "{"};
            std::string key0;
            std::string key1;
            recycle_stage_key(key_info0, &key0);
            recycle_stage_key(key_info1, &key1);
            std::unique_ptr<Transaction> txn;
            std::string get_val;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::unique_ptr<RangeGetIterator> it;
            ASSERT_EQ(txn->get(key0, key1, &it), TxnErrorCode::TXN_OK);
            int stage_cnt = 0;
            do {
                ASSERT_EQ(txn->get(key0, key1, &it), TxnErrorCode::TXN_OK);
                while (it->has_next()) {
                    auto [k, v] = it->next();
                    ++stage_cnt;
                    if (!it->has_next()) {
                        key0 = k;
                    }
                }
                key0.push_back('\x00');
            } while (it->more());
            ASSERT_EQ(stage_cnt, 1);
        }

        // get internal stage
        meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                &get_stage_req, &res2, nullptr);
        ASSERT_EQ(res2.status().code(), MetaServiceCode::STAGE_NOT_FOUND);

        // drop a non-exist internal stage
        drop_stage_request.set_mysql_user_id("root_id2");
        meta_service->drop_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                 &drop_stage_request, &drop_stage_response, nullptr);
        ASSERT_EQ(drop_stage_response.status().code(), MetaServiceCode::STAGE_NOT_FOUND);
    }

    // test create and get external stage
    {
        // get an external stage with name
        GetStageRequest get_stage_req;
        get_stage_req.set_cloud_unique_id(cloud_unique_id);
        get_stage_req.set_type(StagePB::EXTERNAL);
        get_stage_req.set_stage_name("ex_name_1");

        {
            GetStageResponse res;
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &get_stage_req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::STAGE_NOT_FOUND);
        }

        // create 4 stages
        for (auto i = 0; i < 4; ++i) {
            StagePB stage;
            stage.set_type(StagePB::EXTERNAL);
            stage.set_stage_id("ex_id_" + std::to_string(i));
            stage.set_name("ex_name_" + std::to_string(i));
            if (i == 2) {
                stage.set_access_type(StagePB::BUCKET_ACL);
            } else if (i == 3) {
                stage.set_access_type(StagePB::IAM);
            }
            stage.mutable_obj_info()->CopyFrom(obj);

            CreateStageRequest create_stage_req;
            create_stage_req.set_cloud_unique_id(cloud_unique_id);
            create_stage_req.mutable_stage()->CopyFrom(stage);

            CreateStageResponse create_stage_res;
            meta_service->create_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                       &create_stage_req, &create_stage_res, nullptr);
            ASSERT_EQ(create_stage_res.status().code(), MetaServiceCode::OK);
        }

        // stages number bigger than config
        {
            config::max_num_stages = 4;
            StagePB stage;
            stage.set_type(StagePB::INTERNAL);
            stage.add_mysql_user_name("root1");
            stage.add_mysql_user_id("root_id1");
            stage.set_stage_id("internal_stage_id1");
            CreateStageRequest create_stage_req;
            create_stage_req.set_cloud_unique_id(cloud_unique_id);
            create_stage_req.mutable_stage()->CopyFrom(stage);

            CreateStageResponse create_stage_res;
            meta_service->create_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                       &create_stage_req, &create_stage_res, nullptr);
            ASSERT_EQ(create_stage_res.status().code(), MetaServiceCode::UNDEFINED_ERR);
        }

        // get an external stage with name
        {
            GetStageResponse res;
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &get_stage_req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(1, res.stage().size());
            ASSERT_EQ("ex_id_1", res.stage().at(0).stage_id());
        }

        // get an external stage with name, type StagePB::BUCKET_ACL
        {
            get_stage_req.set_stage_name("ex_name_2");
            GetStageResponse res;
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &get_stage_req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(1, res.stage().size());
            ASSERT_EQ("ex_id_2", res.stage().at(0).stage_id());
        }

        // get an external stage with name, type StagePB::IAM
        {
            GetStageResponse res;
            get_stage_req.set_stage_name("ex_name_3");
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &get_stage_req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(1, res.stage().size());
            ASSERT_EQ("ex_id_3", res.stage().at(0).stage_id());

            GetStageResponse res1;
            std::unique_ptr<Transaction> txn;
            TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);

            RamUserPB iam_user;
            txn->put(system_meta_service_arn_info_key(), iam_user.SerializeAsString());
            err = txn->commit();
            ASSERT_EQ(err, TxnErrorCode::TXN_OK);
            LOG_INFO("err=", err);
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &get_stage_req, &res1, nullptr);
            ASSERT_EQ(res1.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(1, res1.stage().size());
            ASSERT_EQ("ex_id_3", res1.stage().at(0).stage_id());
        }

        GetStageRequest req;
        req.set_cloud_unique_id(cloud_unique_id);
        req.set_type(StagePB::EXTERNAL);
        // get all stages
        {
            GetStageResponse res;
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(4, res.stage().size());
            ASSERT_EQ("ex_id_0", res.stage().at(0).stage_id());
            ASSERT_EQ("ex_id_1", res.stage().at(1).stage_id());
        }

        // drop one stage
        {
            DropStageRequest drop_stage_req;
            drop_stage_req.set_cloud_unique_id(cloud_unique_id);
            drop_stage_req.set_type(StagePB::EXTERNAL);
            drop_stage_req.set_stage_name("tmp");
            DropStageResponse res;
            meta_service->drop_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &drop_stage_req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::STAGE_NOT_FOUND);

            drop_stage_req.set_stage_name("ex_name_1");
            meta_service->drop_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &drop_stage_req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

            // get all stage
            GetStageResponse get_stage_res;
            meta_service->get_stage(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &get_stage_res, nullptr);
            ASSERT_EQ(get_stage_res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(3, get_stage_res.stage().size());
            ASSERT_EQ("ex_name_0", get_stage_res.stage().at(0).name());
        }
    }
    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
}

TEST(MetaServiceTest, GetIamTest) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    auto cloud_unique_id = "test_cloud_unique_id";
    std::string instance_id = "get_iam_test_instance_id";
    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "test";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    sp->set_call_back("decrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* key = try_any_cast<std::string*>(args[0]);
        *key = "test";
        auto* ret = try_any_cast<int*>(args[1]);
        *ret = 0;
    });
    sp->enable_processing();

    config::arn_id = "iam_arn";
    config::arn_ak = "iam_ak";
    config::arn_sk = "iam_sk";

    // create instance
    {
        ObjectStoreInfoPB obj;
        obj.set_ak("123");
        obj.set_sk("321");
        obj.set_bucket("456");
        obj.set_prefix("654");
        obj.set_endpoint("789");
        obj.set_region("987");
        obj.set_external_endpoint("888");
        obj.set_provider(ObjectStoreInfoPB::BOS);

        RamUserPB ram_user;
        ram_user.set_user_id("test_user_id");
        ram_user.set_ak("test_ak");
        ram_user.set_sk("test_sk");

        CreateInstanceRequest req;
        req.set_instance_id(instance_id);
        req.set_user_id("test_user");
        req.set_name("test_name");
        req.mutable_ram_user()->CopyFrom(ram_user);
        req.mutable_obj_info()->CopyFrom(obj);

        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    GetIamRequest request;
    request.set_cloud_unique_id(cloud_unique_id);
    GetIamResponse response;
    meta_service->get_iam(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &request,
                          &response, nullptr);
    ASSERT_EQ(response.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(response.ram_user().user_id(), "test_user_id");
    ASSERT_EQ(response.ram_user().ak(), "test_ak");
    ASSERT_EQ(response.ram_user().sk(), "test_sk");
    ASSERT_TRUE(response.ram_user().external_id().empty());

    ASSERT_EQ(response.iam_user().user_id(), "iam_arn");
    ASSERT_EQ(response.iam_user().external_id(), instance_id);
    ASSERT_EQ(response.iam_user().ak(), "iam_ak");
    ASSERT_EQ(response.iam_user().sk(), "iam_sk");
    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
}

TEST(MetaServiceTest, AlterRamTest) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    auto cloud_unique_id = "test_cloud_unique_id";
    std::string instance_id = "alter_iam_test_instance_id";
    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "test";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    sp->set_call_back("decrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* key = try_any_cast<std::string*>(args[0]);
        *key = "test";
        auto* ret = try_any_cast<int*>(args[1]);
        *ret = 0;
    });
    sp->enable_processing();

    config::arn_id = "iam_arn";
    config::arn_ak = "iam_ak";
    config::arn_sk = "iam_sk";

    ObjectStoreInfoPB obj;
    obj.set_ak("123");
    obj.set_sk("321");
    obj.set_bucket("456");
    obj.set_prefix("654");
    obj.set_endpoint("789");
    obj.set_region("987");
    obj.set_external_endpoint("888");
    obj.set_provider(ObjectStoreInfoPB::BOS);

    // create instance without ram user
    CreateInstanceRequest create_instance_req;
    create_instance_req.set_instance_id(instance_id);
    create_instance_req.set_user_id("test_user");
    create_instance_req.set_name("test_name");
    create_instance_req.mutable_obj_info()->CopyFrom(obj);
    CreateInstanceResponse create_instance_res;
    meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                  &create_instance_req, &create_instance_res, nullptr);
    ASSERT_EQ(create_instance_res.status().code(), MetaServiceCode::OK);

    // get iam and ram user
    GetIamRequest request;
    request.set_cloud_unique_id(cloud_unique_id);
    GetIamResponse response;
    meta_service->get_iam(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &request,
                          &response, nullptr);
    ASSERT_EQ(response.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(response.has_ram_user(), false);
    ASSERT_EQ(response.iam_user().user_id(), "iam_arn");
    ASSERT_EQ(response.iam_user().ak(), "iam_ak");
    ASSERT_EQ(response.iam_user().sk(), "iam_sk");

    // alter ram user
    RamUserPB ram_user;
    ram_user.set_user_id("test_user_id");
    ram_user.set_ak("test_ak");
    ram_user.set_sk("test_sk");
    AlterRamUserRequest alter_ram_user_request;
    alter_ram_user_request.set_instance_id(instance_id);
    alter_ram_user_request.mutable_ram_user()->CopyFrom(ram_user);
    AlterRamUserResponse alter_ram_user_response;
    meta_service->alter_ram_user(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                 &alter_ram_user_request, &alter_ram_user_response, nullptr);

    // get iam and ram user
    meta_service->get_iam(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &request,
                          &response, nullptr);
    ASSERT_EQ(response.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(response.has_ram_user(), true);
    ASSERT_EQ(response.ram_user().user_id(), "test_user_id");
    ASSERT_EQ(response.ram_user().ak(), "test_ak");
    ASSERT_EQ(response.ram_user().sk(), "test_sk");
    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
}

std::string to_raw_string(std::string_view v) {
    std::string ret;
    ret.reserve(v.size() / 1.5);
    while (!v.empty()) {
        if (v[0] == '\\') {
            if (v[1] == 'x') {
                ret.push_back(unhex(std::string_view {v.data() + 2, 2})[0]);
                v.remove_prefix(4);
            } else if (v[1] == '\\') {
                ret.push_back('\\');
                v.remove_prefix(2);
            } else {
                std::abort();
            }
            continue;
        }
        ret.push_back(v[0]);
        v.remove_prefix(1);
    }
    return ret;
}

TEST(MetaServiceTest, DecodeTest) {
    // 504
    std::string v1 =
            R"(\x08\x00\x10\xa0[\x18\xb3[ \xde\xc5\xa4\x8e\xbd\xf0\x97\xc62(\xf4\x96\xe6\xb0\x070\x018\x02@\x02H\x0bX\x05`\xa0\x07h\xa0\x07p\xa0\x01\x88\x01\x00\xa0\x01\x86\x8b\x9a\x9b\x06\xaa\x01\x16\x08\xe6\x9e\x91\xa3\xfb\xbe\xf5\xf0\xc4\x01\x10\xfe\x8b\x90\xa7\xb5\xec\xd5\xc8\xbf\x01\xb0\x01\x01\xba\x0100200000000000071fb4aabb58c570cbcadb10857d3131b97\xc2\x01\x011\xc8\x01\x84\x8b\x9a\x9b\x06\xd0\x01\x85\x8b\x9a\x9b\x06\xda\x01\x04\x0a\x00\x12\x00\xe2\x01\xcd\x02\x08\x02\x121\x08\x00\x12\x06datek1\x1a\x04DATE \x01*\x04NONE0\x01:\x0a2022-01-01@\x00H\x00P\x03X\x03\x80\x01\x01\x12>\x08\x01\x12\x06datek2\x1a\x08DATETIME \x01*\x04NONE0\x01:\x132022-01-01 11:11:11@\x00H\x00P\x08X\x08\x80\x01\x01\x123\x08\x04\x12\x06datev3\x1a\x06DATEV2 \x01*\x04NONE0\x01:\x0a2022-01-01@\x00H\x00P\x04X\x04\x80\x01\x01\x120\x08\x02\x12\x06datev1\x1a\x04DATE \x00*\x03MAX0\x01:\x0a2022-01-01@\x00H\x00P\x03X\x03\x80\x01\x01\x12=\x08\x03\x12\x06datev2\x1a\x08DATETIME \x00*\x03MAX0\x01:\x132022-01-01 11:11:11@\x00H\x00P\x08X\x08\x80\x01\x01\x18\x03 \x80\x08(\x021\x00\x00\x00\x00\x00\x00\x00\x008\x00@\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01H\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01P\x00X\x02`\x05h\x00p\x00\xe8\x01\x85\xae\x9f\x9b\x06\x98\x03\x02)";
    std::string val1 = to_raw_string(v1);
    std::cout << "val1 size " << val1.size() << std::endl;

    // 525
    std::string v2 =
            R"(\x08\x00\x10\xa0[\x18\xb3[ \x80\xb0\x85\xe3\xda\xcc\x8c\x0f(\xf4\x96\xe6\xb0\x070\x018\x01@\x0cH\x0cX\x00`\x00h\x00p\x00\x82\x01\x1e\x08\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01\x12\x11datev3=2022-01-01\x88\x01\x01\x92\x01\x04\x08\x00\x10\x00\xa0\x01\x87\x8b\x9a\x9b\x06\xaa\x01\x16\x08\xe6\x9e\x91\xa3\xfb\xbe\xf5\xf0\xc4\x01\x10\xfe\x8b\x90\xa7\xb5\xec\xd5\xc8\xbf\x01\xb0\x01\x00\xba\x0100200000000000072fb4aabb58c570cbcadb10857d3131b97\xc8\x01\x87\x8b\x9a\x9b\x06\xd0\x01\x87\x8b\x9a\x9b\x06\xe2\x01\xcd\x02\x08\x02\x121\x08\x00\x12\x06datek1\x1a\x04DATE \x01*\x04NONE0\x01:\x0a2022-01-01@\x00H\x00P\x03X\x03\x80\x01\x01\x12>\x08\x01\x12\x06datek2\x1a\x08DATETIME \x01*\x04NONE0\x01:\x132022-01-01 11:11:11@\x00H\x00P\x08X\x08\x80\x01\x01\x123\x08\x04\x12\x06datev3\x1a\x06DATEV2 \x01*\x04NONE0\x01:\x0a2022-01-01@\x00H\x00P\x04X\x04\x80\x01\x01\x120\x08\x02\x12\x06datev1\x1a\x04DATE \x00*\x03MAX0\x01:\x0a2022-01-01@\x00H\x00P\x03X\x03\x80\x01\x01\x12=\x08\x03\x12\x06datev2\x1a\x08DATETIME \x00*\x03MAX0\x01:\x132022-01-01 11:11:11@\x00H\x00P\x08X\x08\x80\x01\x01\x18\x03 \x80\x08(\x021\x00\x00\x00\x00\x00\x00\x00\x008\x00@\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01H\xff\xff\xff\xff\xff\xff\xff\xff\xff\x01P\x00X\x02`\x05h\x00p\x00\xe8\x01\x00\x98\x03\x02)";
    std::string val2 = to_raw_string(v2);
    std::cout << "val2 size " << val2.size() << std::endl;

    [[maybe_unused]] std::string key1(
            "\x01\x10meta\x00\x01\x10selectdb-cloud-"
            "dev\x00\x01\x10rowset\x00\x01\x12\x00\x00\x00\x00\x00\x00-"
            "\xb3\x12\x00\x00\x00\x00\x00\x00\x00\x0b",
            56);
    [[maybe_unused]] std::string key2(
            "\x01\x10meta\x00\x01\x10selectdb-cloud-"
            "dev\x00\x01\x10rowset\x00\x01\x12\x00\x00\x00\x00\x00\x00-"
            "\xb3\x12\x00\x00\x00\x00\x00\x00\x00\x0c",
            56);
    std::cout << "key1 " << key1.size() << " " << hex(key1) << std::endl;
    std::cout << "key2 " << key2.size() << " " << hex(key2) << std::endl;

    doris::RowsetMetaCloudPB rowset1;
    doris::RowsetMetaCloudPB rowset2;

    rowset1.ParseFromString(val1);
    rowset2.ParseFromString(val2);
    std::cout << "rowset1=" << proto_to_json(rowset1) << std::endl;
    std::cout << "rowset2=" << proto_to_json(rowset2) << std::endl;
}

void get_tablet_stats(MetaServiceProxy* meta_service, int64_t table_id, int64_t index_id,
                      int64_t partition_id, int64_t tablet_id, GetTabletStatsResponse& res) {
    brpc::Controller cntl;
    GetTabletStatsRequest req;
    auto idx = req.add_tablet_idx();
    idx->set_table_id(table_id);
    idx->set_index_id(index_id);
    idx->set_partition_id(partition_id);
    idx->set_tablet_id(tablet_id);
    meta_service->get_tablet_stats(&cntl, &req, &res, nullptr);
}

TEST(MetaServiceTest, UpdateTablet) {
    auto meta_service = get_meta_service();
    std::string cloud_unique_id = "test_cloud_unique_id";
    constexpr auto table_id = 11231, index_id = 11232, partition_id = 11233, tablet_id1 = 11234,
                   tablet_id2 = 21234;
    ASSERT_NO_FATAL_FAILURE(
            create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id1));
    ASSERT_NO_FATAL_FAILURE(
            create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id2));
    auto get_and_check_tablet_meta = [&](int tablet_id, int64_t ttl_seconds, bool in_memory,
                                         bool is_persistent) {
        brpc::Controller cntl;
        GetTabletRequest req;
        req.set_cloud_unique_id(cloud_unique_id);
        req.set_tablet_id(tablet_id);
        GetTabletResponse resp;
        meta_service->get_tablet(&cntl, &req, &resp, nullptr);
        ASSERT_EQ(resp.status().code(), MetaServiceCode::OK) << tablet_id;
        EXPECT_EQ(resp.tablet_meta().ttl_seconds(), ttl_seconds);
        EXPECT_EQ(resp.tablet_meta().is_in_memory(), in_memory);
        EXPECT_EQ(resp.tablet_meta().is_persistent(), is_persistent);
    };
    get_and_check_tablet_meta(tablet_id1, 0, false, false);
    get_and_check_tablet_meta(tablet_id2, 0, false, false);
    {
        brpc::Controller cntl;
        UpdateTabletRequest req;
        UpdateTabletResponse resp;
        req.set_cloud_unique_id(cloud_unique_id);
        TabletMetaInfoPB* tablet_meta_info = req.add_tablet_meta_infos();
        tablet_meta_info->set_tablet_id(tablet_id1);
        tablet_meta_info->set_ttl_seconds(300);
        tablet_meta_info = req.add_tablet_meta_infos();
        tablet_meta_info->set_tablet_id(tablet_id2);
        tablet_meta_info->set_ttl_seconds(3000);
        meta_service->update_tablet(&cntl, &req, &resp, nullptr);
        ASSERT_EQ(resp.status().code(), MetaServiceCode::OK);
    }
    get_and_check_tablet_meta(tablet_id1, 300, false, false);
    get_and_check_tablet_meta(tablet_id2, 3000, false, false);
    {
        brpc::Controller cntl;
        UpdateTabletRequest req;
        UpdateTabletResponse resp;
        req.set_cloud_unique_id(cloud_unique_id);
        TabletMetaInfoPB* tablet_meta_info = req.add_tablet_meta_infos();
        tablet_meta_info->set_tablet_id(tablet_id1);
        tablet_meta_info->set_is_in_memory(true);
        meta_service->update_tablet(&cntl, &req, &resp, nullptr);
        ASSERT_EQ(resp.status().code(), MetaServiceCode::OK);
    }
    {
        brpc::Controller cntl;
        UpdateTabletRequest req;
        UpdateTabletResponse resp;
        req.set_cloud_unique_id(cloud_unique_id);
        TabletMetaInfoPB* tablet_meta_info = req.add_tablet_meta_infos();
        tablet_meta_info->set_tablet_id(tablet_id1);
        tablet_meta_info->set_is_persistent(true);
        meta_service->update_tablet(&cntl, &req, &resp, nullptr);
        ASSERT_EQ(resp.status().code(), MetaServiceCode::OK);
    }
    get_and_check_tablet_meta(tablet_id1, 300, true, true);
}

TEST(MetaServiceTest, GetTabletStatsTest) {
    auto meta_service = get_meta_service();

    constexpr auto table_id = 10001, index_id = 10002, partition_id = 10003, tablet_id = 10004;
    ASSERT_NO_FATAL_FAILURE(
            create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));
    GetTabletStatsResponse res;
    get_tablet_stats(meta_service.get(), table_id, index_id, partition_id, tablet_id, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(res.tablet_stats_size(), 1);
    EXPECT_EQ(res.tablet_stats(0).data_size(), 0);
    EXPECT_EQ(res.tablet_stats(0).num_rows(), 0);
    EXPECT_EQ(res.tablet_stats(0).num_rowsets(), 1);
    EXPECT_EQ(res.tablet_stats(0).num_segments(), 0);
    EXPECT_EQ(res.tablet_stats(0).index_size(), 0);
    EXPECT_EQ(res.tablet_stats(0).segment_size(), 0);
    // Insert rowset
    config::split_tablet_stats = false;
    ASSERT_NO_FATAL_FAILURE(
            insert_rowset(meta_service.get(), 10000, "label1", table_id, partition_id, tablet_id));
    ASSERT_NO_FATAL_FAILURE(
            insert_rowset(meta_service.get(), 10000, "label2", table_id, partition_id, tablet_id));
    config::split_tablet_stats = true;
    ASSERT_NO_FATAL_FAILURE(
            insert_rowset(meta_service.get(), 10000, "label3", table_id, partition_id, tablet_id));
    ASSERT_NO_FATAL_FAILURE(
            insert_rowset(meta_service.get(), 10000, "label4", table_id, partition_id, tablet_id));
    // Check tablet stats kv
    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string data_size_key, data_size_val;
    stats_tablet_data_size_key({mock_instance, table_id, index_id, partition_id, tablet_id},
                               &data_size_key);
    ASSERT_EQ(txn->get(data_size_key, &data_size_val), TxnErrorCode::TXN_OK);
    EXPECT_EQ(*(int64_t*)data_size_val.data(), 22000);
    std::string index_size_key, index_size_val;
    stats_tablet_index_size_key({mock_instance, table_id, index_id, partition_id, tablet_id},
                                &index_size_key);
    ASSERT_EQ(txn->get(index_size_key, &index_size_val), TxnErrorCode::TXN_OK);
    EXPECT_EQ(*(int64_t*)index_size_val.data(), 2000);
    std::string segment_size_key, segment_size_val;
    stats_tablet_segment_size_key({mock_instance, table_id, index_id, partition_id, tablet_id},
                                  &segment_size_key);
    ASSERT_EQ(txn->get(segment_size_key, &segment_size_val), TxnErrorCode::TXN_OK);
    EXPECT_EQ(*(int64_t*)segment_size_val.data(), 20000);
    std::string num_rows_key, num_rows_val;
    stats_tablet_num_rows_key({mock_instance, table_id, index_id, partition_id, tablet_id},
                              &num_rows_key);
    ASSERT_EQ(txn->get(num_rows_key, &num_rows_val), TxnErrorCode::TXN_OK);
    EXPECT_EQ(*(int64_t*)num_rows_val.data(), 200);
    std::string num_rowsets_key, num_rowsets_val;
    stats_tablet_num_rowsets_key({mock_instance, table_id, index_id, partition_id, tablet_id},
                                 &num_rowsets_key);
    ASSERT_EQ(txn->get(num_rowsets_key, &num_rowsets_val), TxnErrorCode::TXN_OK);
    EXPECT_EQ(*(int64_t*)num_rowsets_val.data(), 2);
    std::string num_segs_key, num_segs_val;
    stats_tablet_num_segs_key({mock_instance, table_id, index_id, partition_id, tablet_id},
                              &num_segs_key);
    ASSERT_EQ(txn->get(num_segs_key, &num_segs_val), TxnErrorCode::TXN_OK);
    EXPECT_EQ(*(int64_t*)num_segs_val.data(), 2);
    // Get tablet stats
    res.Clear();
    get_tablet_stats(meta_service.get(), table_id, index_id, partition_id, tablet_id, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(res.tablet_stats_size(), 1);
    EXPECT_EQ(res.tablet_stats(0).data_size(), 44000);
    EXPECT_EQ(res.tablet_stats(0).num_rows(), 400);
    EXPECT_EQ(res.tablet_stats(0).num_rowsets(), 5);
    EXPECT_EQ(res.tablet_stats(0).num_segments(), 4);
    EXPECT_EQ(res.tablet_stats(0).index_size(), 4000);
    EXPECT_EQ(res.tablet_stats(0).segment_size(), 40000);
}

void remove_delete_bitmap_lock(MetaServiceProxy* meta_service, int64_t table_id) {
    std::string lock_key = meta_delete_bitmap_update_lock_key({"test_instance", table_id, -1});
    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->remove(lock_key);
    std::string tablet_job_key_begin = mow_tablet_job_key({"test_instance", table_id, 0});
    std::string tablet_job_key_end = mow_tablet_job_key({"test_instance", table_id, INT64_MAX});
    txn->remove(tablet_job_key_begin, tablet_job_key_end);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
}

void testGetDeleteBitmapUpdateLock(int lock_version, int job_lock_id) {
    config::delete_bitmap_lock_v2_white_list = lock_version == 1 ? "" : "*";
    auto meta_service = get_meta_service();
    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    remove_delete_bitmap_lock(meta_service.get(), 1);
    remove_delete_bitmap_lock(meta_service.get(), 2);
    int64_t table_id = 9;

    // case 1: lock key does not exist, get and remove load lock
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest req;
    GetDeleteBitmapUpdateLockResponse res;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_table_id(table_id);
    req.add_partition_ids(123);
    req.set_expiration(5);
    req.set_lock_id(888);
    req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    RemoveDeleteBitmapUpdateLockRequest remove_req;
    RemoveDeleteBitmapUpdateLockResponse remove_res;
    remove_req.set_cloud_unique_id("test_cloud_unique_id");
    remove_req.set_table_id(table_id);
    remove_req.set_lock_id(888);
    remove_req.set_initiator(-1);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 2: lock key does not exist, get and remove compaction lock
    req.add_partition_ids(123);
    req.set_expiration(600);
    req.set_lock_id(job_lock_id);
    req.set_initiator(100);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    remove_req.set_tablet_id(2);
    remove_req.set_lock_id(job_lock_id);
    remove_req.set_initiator(100);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 3: lock key owned by load1, load2 get lock
    req.add_partition_ids(123);
    req.set_expiration(600);
    req.set_lock_id(888);
    req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    req.set_lock_id(889);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_CONFLICT);

    // case 4: lock key owned by load1, compaction1 get lock
    req.set_lock_id(job_lock_id);
    req.set_initiator(100);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_CONFLICT);

    remove_req.set_tablet_id(2);
    remove_req.set_lock_id(888);
    remove_req.set_initiator(-1);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 5: lock key owned by load1 but expired, load2 get lock
    req.add_partition_ids(123);
    req.set_expiration(1);
    req.set_lock_id(888);
    req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    sleep(2);
    req.set_lock_id(889);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    remove_req.set_lock_id(889);
    remove_req.set_initiator(-1);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 6: lock key owned by load1 but expired, compaction1 get lock
    req.add_partition_ids(123);
    req.set_expiration(1);
    req.set_lock_id(888);
    req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    sleep(2);
    req.set_lock_id(job_lock_id);
    req.set_initiator(888);
    req.set_expiration(1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    remove_req.set_lock_id(job_lock_id);
    remove_req.set_initiator(888);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 7: lock key owned by compaction, new compaction get lock
    req.set_lock_id(job_lock_id);
    req.set_initiator(100);
    req.set_expiration(100);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    req.set_lock_id(job_lock_id);
    req.set_initiator(101);
    req.set_expiration(1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    // new compaction get lock again
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    // case 8: lock key owned by compaction, load1 get lock
    req.set_lock_id(888);
    req.set_initiator(-1);
    req.set_expiration(60);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_CONFLICT);

    remove_req.set_lock_id(job_lock_id);
    remove_req.set_initiator(100);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 9: lock key owned by compaction but all expired (101 900), load1 get lock
    req.set_table_id(table_id);
    req.set_lock_id(job_lock_id);
    req.set_initiator(900);
    req.set_expiration(1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    sleep(2);
    req.set_table_id(table_id);
    req.set_lock_id(888);
    req.set_initiator(-1);
    req.set_expiration(60);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    remove_req.set_lock_id(888);
    remove_req.set_initiator(-1);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 10: lock key owned by compaction but all expired (101 900), schema change get lock
    req.set_table_id(table_id);
    req.set_lock_id(job_lock_id);
    req.set_initiator(900);
    req.set_expiration(1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    sleep(2);
    req.set_table_id(table_id);
    int other_job_lock_id = job_lock_id == COMPACTION_DELETE_BITMAP_LOCK_ID
                                    ? SCHEMA_CHANGE_DELETE_BITMAP_LOCK_ID
                                    : COMPACTION_DELETE_BITMAP_LOCK_ID;
    req.set_lock_id(other_job_lock_id);
    req.set_initiator(100);
    req.set_expiration(1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    remove_req.set_lock_id(other_job_lock_id);
    remove_req.set_initiator(100);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 11: lock by schema change but expired, compaction get lock but txn commit conflict, do fast retry
    sp->set_call_back("get_delete_bitmap_update_lock:commit:conflict", [&](auto&& args) {
        auto* first_retry = try_any_cast<bool*>(args[0]);
        auto lock_id = (try_any_cast<const GetDeleteBitmapUpdateLockRequest*>(args[1]))->lock_id();
        if (*first_retry && is_job_delete_bitmap_lock_id(lock_id)) {
            *try_any_cast<TxnErrorCode*>(args[2]) = TxnErrorCode::TXN_CONFLICT;
        } else {
            *try_any_cast<TxnErrorCode*>(args[2]) = TxnErrorCode::TXN_OK;
        }
    });
    sp->enable_processing();
    req.set_lock_id(job_lock_id);
    req.set_initiator(100);
    req.set_expiration(10);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    remove_req.set_lock_id(job_lock_id);
    remove_req.set_initiator(100);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // case 12: lock by load but expired, compaction get lock but txn commit conflict, do fast retry
    req.set_lock_id(300);
    req.set_initiator(-1);
    req.set_expiration(1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    sleep(2);
    req.set_lock_id(job_lock_id);
    req.set_initiator(100);
    req.set_expiration(10);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    remove_delete_bitmap_lock(meta_service.get(), table_id);

    // case 13: lock key does not exist, compaction get lock but txn commit conflict, do fast retry
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
    remove_delete_bitmap_lock(meta_service.get(), table_id);
}

TEST(MetaServiceTest, GetDeleteBitmapUpdateLock) {
    testGetDeleteBitmapUpdateLock(2, COMPACTION_DELETE_BITMAP_LOCK_ID);
    testGetDeleteBitmapUpdateLock(2, SCHEMA_CHANGE_DELETE_BITMAP_LOCK_ID);
    testGetDeleteBitmapUpdateLock(1, COMPACTION_DELETE_BITMAP_LOCK_ID);
    testGetDeleteBitmapUpdateLock(1, SCHEMA_CHANGE_DELETE_BITMAP_LOCK_ID);
}

TEST(MetaServiceTest, GetDeleteBitmapUpdateLockNoReadStats) {
    auto meta_service = get_meta_service();

    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest req;
    GetDeleteBitmapUpdateLockResponse res;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_table_id(111);
    req.add_partition_ids(123);
    req.set_expiration(5);
    req.set_lock_id(888);
    req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    // same lock_id
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    // different lock_id
    req.set_lock_id(999);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_CONFLICT);

    // lock expired
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_table_id(222);
    req.set_expiration(0);
    req.set_lock_id(666);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    sleep(1);
    req.set_lock_id(667);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
}

TEST(MetaServiceTest, GetDeleteBitmapUpdateLockTabletStatsNormal) {
    auto meta_service = get_meta_service();

    bool enable_batch_get_mow_tablet_stats_and_meta_vals[] = {false, true};
    for (bool val : enable_batch_get_mow_tablet_stats_and_meta_vals) {
        config::enable_batch_get_mow_tablet_stats_and_meta = val;

        std::string instance_id = "test_get_delete_bitmap_update_lock_normal";
        [[maybe_unused]] auto* sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->disable_processing();
            SyncPoint::get_instance()->clear_all_call_backs();
        };
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });
        sp->enable_processing();

        int64_t db_id = 1000;
        int64_t table_id = 2001;
        int64_t index_id = 3001;
        // [(partition_id, tablet_id)]
        std::vector<std::array<int64_t, 2>> tablet_idxes {
                {70001, 12345}, {80001, 3456}, {90001, 6789}};

        add_tablet_metas(meta_service.get(), instance_id, table_id, index_id, tablet_idxes);

        GetDeleteBitmapUpdateLockResponse res;
        get_delete_bitmap_update_lock(meta_service.get(), res, db_id, table_id, index_id,
                                      tablet_idxes, 5, 999999, -1, true);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        ASSERT_EQ(res.base_compaction_cnts().size(), tablet_idxes.size());
        for (const auto& base_compaction_cnt : res.base_compaction_cnts()) {
            ASSERT_EQ(base_compaction_cnt, 10);
        }
        ASSERT_EQ(res.cumulative_compaction_cnts().size(), tablet_idxes.size());
        for (const auto& cumu_compaction_cnt : res.cumulative_compaction_cnts()) {
            ASSERT_EQ(cumu_compaction_cnt, 20);
        }
        ASSERT_EQ(res.cumulative_points().size(), tablet_idxes.size());
        for (const auto& cumulative_point : res.cumulative_points()) {
            ASSERT_EQ(cumulative_point, 30);
        }
    }
}

TEST(MetaServiceTest, GetDeleteBitmapUpdateLockTabletStatsLockExpired) {
    auto meta_service = get_meta_service();

    bool enable_batch_get_mow_tablet_stats_and_meta_vals[] = {false, true};
    for (bool val : enable_batch_get_mow_tablet_stats_and_meta_vals) {
        config::enable_batch_get_mow_tablet_stats_and_meta = val;
        // 2.1 abnormal path, lock has been expired and taken by another load/compaction during
        // the reading of tablet stats
        std::string instance_id = "test_get_delete_bitmap_update_lock_abnormal1";
        [[maybe_unused]] auto* sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->disable_processing();
            SyncPoint::get_instance()->clear_all_call_backs();
        };
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });
        sp->set_call_back("check_delete_bitmap_lock.set_lock_info", [&](auto&& args) {
            auto* lock_info = try_any_cast<DeleteBitmapUpdateLockPB*>(args[0]);
            // simulate that lock_id has been modified by another load
            lock_info->set_lock_id(345);
            LOG(INFO) << "change lock_info.lock_id to 345, lock_info=" << lock_info->DebugString();
        });

        sp->enable_processing();

        int64_t db_id = 1000;
        int64_t table_id = 2001;
        int64_t index_id = 3001;
        // [(partition_id, tablet_id)]
        std::vector<std::array<int64_t, 2>> tablet_idxes {
                {70001, 12345}, {80001, 3456}, {90001, 6789}};

        add_tablet_metas(meta_service.get(), instance_id, table_id, index_id, tablet_idxes);

        GetDeleteBitmapUpdateLockResponse res;
        get_delete_bitmap_update_lock(meta_service.get(), res, db_id, table_id, index_id,
                                      tablet_idxes, 5, 999999, -1, true);
        EXPECT_EQ(res.status().code(), MetaServiceCode::LOCK_EXPIRED);
        EXPECT_EQ(res.base_compaction_cnts().size(), 3);
        EXPECT_EQ(res.cumulative_compaction_cnts().size(), 3);
        EXPECT_EQ(res.cumulative_points().size(), 3);
    }

    for (bool val : enable_batch_get_mow_tablet_stats_and_meta_vals) {
        config::enable_batch_get_mow_tablet_stats_and_meta = val;

        // 2.2 abnormal path, lock has been taken by another load/compaction and been released during
        // the reading of tablet stats
        std::string instance_id = "test_get_delete_bitmap_update_lock_abnormal2";
        [[maybe_unused]] auto* sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->disable_processing();
            SyncPoint::get_instance()->clear_all_call_backs();
        };
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });
        sp->set_call_back("check_delete_bitmap_lock.inject_get_lock_key_err", [&](auto&& args) {
            auto* err = try_any_cast<TxnErrorCode*>(args[0]);
            // the lock has been taken by another load and been released,
            // so the delete bitmap update lock KV will be removed
            *err = TxnErrorCode::TXN_KEY_NOT_FOUND;
        });

        sp->enable_processing();

        int64_t db_id = 1000;
        int64_t table_id = 2001;
        int64_t index_id = 3001;
        // [(partition_id, tablet_id)]
        std::vector<std::array<int64_t, 2>> tablet_idxes {
                {70001, 12345}, {80001, 3456}, {90001, 6789}};

        add_tablet_metas(meta_service.get(), instance_id, table_id, index_id, tablet_idxes);

        GetDeleteBitmapUpdateLockResponse res;
        get_delete_bitmap_update_lock(meta_service.get(), res, db_id, table_id, index_id,
                                      tablet_idxes, 5, 999999, -1, true);
        ASSERT_EQ(res.status().code(), MetaServiceCode::LOCK_EXPIRED);
    }
}

TEST(MetaServiceTest, GetDeleteBitmapUpdateLockTabletStatsError) {
    auto meta_service = get_meta_service();

    bool enable_batch_get_mow_tablet_stats_and_meta_vals[] = {false, true};
    for (bool val : enable_batch_get_mow_tablet_stats_and_meta_vals) {
        config::enable_batch_get_mow_tablet_stats_and_meta = val;
        // 2.3 abnormal path, meeting error when reading tablets' stats
        std::string instance_id = "test_get_delete_bitmap_update_lock_abnormal3";
        [[maybe_unused]] auto* sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->disable_processing();
            SyncPoint::get_instance()->clear_all_call_backs();
        };
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });

        TxnErrorCode injected_error_code {TxnErrorCode::TXN_KEY_NOT_FOUND};
        sp->set_call_back("get_delete_bitmap_update_lock.get_compaction_cnts_inject_error",
                          [&](auto&& args) {
                              auto* err = try_any_cast<TxnErrorCode*>(args[0]);
                              *err = injected_error_code;
                          });

        sp->enable_processing();

        int64_t db_id = 1000;
        int64_t table_id = 2001;
        int64_t index_id = 3001;
        // [(partition_id, tablet_id)]
        std::vector<std::array<int64_t, 2>> tablet_idxes {
                {70001, 12345}, {80001, 3456}, {90001, 6789}};

        add_tablet_metas(meta_service.get(), instance_id, table_id, index_id, tablet_idxes);

        GetDeleteBitmapUpdateLockResponse res;
        get_delete_bitmap_update_lock(meta_service.get(), res, db_id, table_id, index_id,
                                      tablet_idxes, 5, 999999, -1, true);
        ASSERT_EQ(res.status().code(), MetaServiceCode::KV_TXN_GET_ERR);
    }

    for (bool val : enable_batch_get_mow_tablet_stats_and_meta_vals) {
        config::enable_batch_get_mow_tablet_stats_and_meta = val;
        // 2.4 abnormal path, meeting TXN_TOO_OLD error when reading tablets' stats,
        // this should not fail if lock is not expired
        std::string instance_id = "test_get_delete_bitmap_update_lock_abnormal4";
        [[maybe_unused]] auto* sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->disable_processing();
            SyncPoint::get_instance()->clear_all_call_backs();
        };
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });

        int counter = 0;
        sp->set_call_back("get_delete_bitmap_update_lock.get_compaction_cnts_inject_error",
                          [&](auto&& args) {
                              if (counter++ % 2 == 0) {
                                  auto* err = try_any_cast<TxnErrorCode*>(args[0]);
                                  *err = TxnErrorCode::TXN_TOO_OLD;
                              }
                          });

        sp->enable_processing();

        int64_t db_id = 1000;
        int64_t table_id = 2001;
        int64_t index_id = 3001;
        // [(partition_id, tablet_id)]
        std::vector<std::array<int64_t, 2>> tablet_idxes;
        for (int i = 0; i < 20; i++) {
            int64_t partition_id = 70000 + i;
            int64_t tablet_id = 80000 + i;
            tablet_idxes.push_back({partition_id, tablet_id});
        }

        add_tablet_metas(meta_service.get(), instance_id, table_id, index_id, tablet_idxes);

        GetDeleteBitmapUpdateLockResponse res;
        get_delete_bitmap_update_lock(meta_service.get(), res, db_id, table_id, index_id,
                                      tablet_idxes, 5, 999999, -1, true);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.base_compaction_cnts().size(), tablet_idxes.size());
        for (const auto& base_compaction_cnt : res.base_compaction_cnts()) {
            ASSERT_EQ(base_compaction_cnt, 10);
        }
        ASSERT_EQ(res.cumulative_compaction_cnts().size(), tablet_idxes.size());
        for (const auto& cumu_compaction_cnt : res.cumulative_compaction_cnts()) {
            ASSERT_EQ(cumu_compaction_cnt, 20);
        }
        ASSERT_EQ(res.cumulative_points().size(), tablet_idxes.size());
        for (const auto& cumulative_point : res.cumulative_points()) {
            ASSERT_EQ(cumulative_point, 30);
        }
    }

    for (bool val : enable_batch_get_mow_tablet_stats_and_meta_vals) {
        config::enable_batch_get_mow_tablet_stats_and_meta = val;
        // 2.5 abnormal path, meeting error when reading tablets' meta
        std::string instance_id = "test_get_delete_bitmap_update_lock_abnormal5";
        [[maybe_unused]] auto* sp = SyncPoint::get_instance();
        DORIS_CLOUD_DEFER {
            SyncPoint::get_instance()->disable_processing();
            SyncPoint::get_instance()->clear_all_call_backs();
        };
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = instance_id;
            ret->second = true;
        });

        sp->enable_processing();

        int64_t db_id = 1000;
        int64_t table_id = 2001;
        int64_t index_id = 3001;
        // [(partition_id, tablet_id)]
        std::vector<std::array<int64_t, 2>> tablet_idxes {
                {70001, 12345}, {80001, 3456}, {90001, 6789}};

        add_tablet_metas(meta_service.get(), instance_id, table_id, index_id, tablet_idxes, true);

        GetDeleteBitmapUpdateLockResponse res;
        get_delete_bitmap_update_lock(meta_service.get(), res, db_id, table_id, index_id,
                                      tablet_idxes, 5, 999999, -1, true);
        ASSERT_EQ(res.status().code(), MetaServiceCode::TABLET_NOT_FOUND);
    }
}

static std::string generate_random_string(int length) {
    std::string char_set = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
    std::random_device rd;
    std::mt19937 generator(rd());
    std::uniform_int_distribution<int> distribution(0, char_set.length() - 1);

    std::string randomString;
    for (int i = 0; i < length; ++i) {
        randomString += char_set[distribution(generator)];
    }
    return randomString;
}

TEST(MetaServiceTest, UpdateDeleteBitmapWithBigKeys) {
    auto meta_service = get_meta_service();
    // get delete bitmap update lock
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(1999);
    get_lock_req.add_partition_ids(123);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(-1);
    get_lock_req.set_initiator(100);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
    // v1 update delete bitmap
    UpdateDeleteBitmapRequest update_delete_bitmap_req;
    UpdateDeleteBitmapResponse update_delete_bitmap_res;
    update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    update_delete_bitmap_req.set_table_id(1999);
    update_delete_bitmap_req.set_partition_id(123);
    update_delete_bitmap_req.set_lock_id(-1);
    update_delete_bitmap_req.set_initiator(100);
    update_delete_bitmap_req.set_tablet_id(333);
    std::string large_value = generate_random_string(300 * 1000 * 3);
    DeleteBitmapPB delete_bitmap_pb;
    auto num = 100000;
    for (int i = 0; i < num; i++) {
        update_delete_bitmap_req.add_rowset_ids("0200000003ea308a3647dbea83220ed4b8897f2288244a91");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(i);
        update_delete_bitmap_req.add_segment_delete_bitmaps(i % 500 == 0 ? large_value : "1");

        delete_bitmap_pb.add_rowset_ids("0200000003ea308a3647dbea83220ed4b8897f2288244a91");
        delete_bitmap_pb.add_segment_ids(0);
        delete_bitmap_pb.add_versions(i);
        delete_bitmap_pb.add_segment_delete_bitmaps(i % 500 == 0 ? large_value : "1");
    }
    // v2 update delete bitmap
    DeleteBitmapStoragePB delete_bitmap_storage_pb;
    delete_bitmap_storage_pb.set_store_in_fdb(true);
    *(delete_bitmap_storage_pb.mutable_delete_bitmap()) = std::move(delete_bitmap_pb);
    *(update_delete_bitmap_req.add_delete_bitmap_storages()) = std::move(delete_bitmap_storage_pb);
    update_delete_bitmap_req.add_delta_rowset_ids(
            "0200000003ea308a3647dbea83220ed4b8897f2288244a91");

    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
    ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

    // get delete bitmap v1
    GetDeleteBitmapRequest get_delete_bitmap_req;
    get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    get_delete_bitmap_req.set_tablet_id(333);
    get_delete_bitmap_req.add_rowset_ids("0200000003ea308a3647dbea83220ed4b8897f2288244a91");
    get_delete_bitmap_req.add_begin_versions(0);
    get_delete_bitmap_req.add_end_versions(num);
    {
        // get exceed max_get_delete_bitmap_byte limit
        auto max_get_delete_bitmap_byte = config::max_get_delete_bitmap_byte;
        config::max_get_delete_bitmap_byte = 1;
        GetDeleteBitmapResponse get_delete_bitmap_res;
        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::KV_TXN_GET_ERR);
        config::max_get_delete_bitmap_byte = max_get_delete_bitmap_byte;
    }
    {
        GetDeleteBitmapResponse get_delete_bitmap_res;
        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), num);
        ASSERT_EQ(get_delete_bitmap_res.versions_size(), num);
        ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), num);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), num);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), large_value);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(1), "1");
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(500), large_value);
    }

    // get delete bitmap v2
    {
        GetDeleteBitmapResponse get_delete_bitmap_res;
        get_delete_bitmap_req.set_store_version(2);
        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.delete_bitmap_storages_size(), 1);
        auto& delete_bitmap_storage = get_delete_bitmap_res.delete_bitmap_storages(0);
        ASSERT_TRUE(delete_bitmap_storage.store_in_fdb());
        auto& delete_bitmap_pb = delete_bitmap_storage.delete_bitmap();
        ASSERT_EQ(delete_bitmap_pb.rowset_ids_size(), num);
        ASSERT_EQ(delete_bitmap_pb.versions_size(), num);
        ASSERT_EQ(delete_bitmap_pb.segment_ids_size(), num);
        ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps_size(), num);
        ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(0), large_value);
        ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(1), "1");
        ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(500), large_value);
    }
}

static void set_partition_version(MetaServiceProxy* meta_service, std::string_view instance_id,
                                  int64_t db_id, int64_t table_id, int64_t partition_id,
                                  int64_t version, std::vector<int64_t> pending_txn_ids = {}) {
    std::string ver_key = partition_version_key({instance_id, db_id, table_id, partition_id});
    std::string ver_val;
    VersionPB version_pb;
    version_pb.set_version(version);
    if (!pending_txn_ids.empty()) {
        for (auto txn_id : pending_txn_ids) {
            version_pb.add_pending_txn_ids(txn_id);
        }
    }
    ASSERT_TRUE(version_pb.SerializeToString(&ver_val));
    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(ver_key, ver_val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
}

static void begin_txn_and_commit_rowset(MetaServiceProxy* meta_service, const std::string& label,
                                        int64_t db_id, int64_t table_id, int64_t partition_id,
                                        int64_t tablet_id, int64_t* txn_id) {
    begin_txn(meta_service, db_id, label, table_id, *txn_id);
    CreateRowsetResponse res;
    auto rowset = create_rowset(*txn_id, tablet_id, partition_id);
    prepare_rowset(meta_service, rowset, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    res.Clear();
    commit_rowset(meta_service, rowset, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
}

static void get_delete_bitmap_update_lock(MetaServiceProxy* meta_service, int64_t table_id,
                                          int64_t partition_id, int64_t lock_id,
                                          int64_t initiator) {
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(table_id);
    get_lock_req.add_partition_ids(partition_id);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(lock_id);
    get_lock_req.set_initiator(initiator);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
}

static void update_delete_bitmap(MetaServiceProxy* meta_service,
                                 UpdateDeleteBitmapRequest& update_delete_bitmap_req,
                                 UpdateDeleteBitmapResponse& update_delete_bitmap_res,
                                 int64_t table_id, int64_t partition_id, int64_t lock_id,
                                 int64_t initiator, int64_t tablet_id, int64_t txn_id,
                                 int64_t next_visible_version, std::string data = "1111") {
    brpc::Controller cntl;
    update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    update_delete_bitmap_req.set_table_id(table_id);
    update_delete_bitmap_req.set_partition_id(partition_id);
    update_delete_bitmap_req.set_lock_id(lock_id);
    update_delete_bitmap_req.set_initiator(initiator);
    update_delete_bitmap_req.set_tablet_id(tablet_id);
    update_delete_bitmap_req.set_txn_id(txn_id);
    update_delete_bitmap_req.set_next_visible_version(next_visible_version);
    update_delete_bitmap_req.add_rowset_ids("123");
    update_delete_bitmap_req.add_segment_ids(0);
    update_delete_bitmap_req.add_versions(next_visible_version);
    update_delete_bitmap_req.add_segment_delete_bitmaps(data);
    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
}

TEST(MetaServiceTest, UpdateDeleteBitmapCheckPartitionVersion) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;

    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");

    {
        // 1. normal path
        // 1.1 has partition version and request version matches
        int64_t db_id = 999;
        int64_t table_id = 1001;
        int64_t index_id = 4001;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t initiator = -1;
        int64_t cur_max_version = 100;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label11", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = txn_id;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);
        set_partition_version(meta_service.get(), instance_id, db_id, table_id, t1p1,
                              cur_max_version);

        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                             table_id, t1p1, lock_id, initiator, tablet_id, txn_id,
                             cur_max_version + 1);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    }

    {
        // 1. normal path
        // 1.2 does not have partition version KV and request version matches
        int64_t db_id = 999;
        int64_t table_id = 1002;
        int64_t index_id = 4001;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t initiator = -1;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label12", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = txn_id;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);

        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                             table_id, t1p1, lock_id, initiator, tablet_id, txn_id, 2);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    }

    {
        // 1. normal path
        // 1.3 has partition version and pending txn, and request version matches
        int64_t db_id = 999;
        int64_t table_id = 1003;
        int64_t index_id = 4001;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t initiator = -1;
        int64_t cur_max_version = 120;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label13", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = txn_id;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);
        set_partition_version(meta_service.get(), instance_id, db_id, table_id, t1p1,
                              cur_max_version, {12345});

        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                             table_id, t1p1, lock_id, initiator, tablet_id, txn_id,
                             cur_max_version + 2);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    }
}

TEST(MetaServiceTest, UpdateDeleteBitmapCheckPartitionVersionFail) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;

    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");

    {
        // 2. abnormal path
        // 2.1 has partition version but request version does not match
        int64_t db_id = 999;
        int64_t table_id = 2001;
        int64_t index_id = 4001;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t initiator = -1;
        int64_t cur_max_version = 100;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label21", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = txn_id;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);
        set_partition_version(meta_service.get(), instance_id, db_id, table_id, t1p1,
                              cur_max_version);

        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        // wrong version
        update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                             table_id, t1p1, lock_id, initiator, tablet_id, txn_id,
                             cur_max_version + 2);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::VERSION_NOT_MATCH);
    }

    {
        // 2. abnormal path
        // 2.2 does not have partition version KV and request version does not match
        int64_t db_id = 999;
        int64_t table_id = 2002;
        int64_t index_id = 4001;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t initiator = -1;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label22", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = txn_id;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);

        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        // first load, wrong version
        update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                             table_id, t1p1, lock_id, initiator, tablet_id, txn_id, 10);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::VERSION_NOT_MATCH);
    }

    {
        // 2. abnormal path
        // 2.3 has partition version and pending txn, and request version matches
        int64_t db_id = 999;
        int64_t table_id = 2003;
        int64_t index_id = 4001;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t initiator = -1;
        int64_t cur_max_version = 120;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label23", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = txn_id;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);
        set_partition_version(meta_service.get(), instance_id, db_id, table_id, t1p1,
                              cur_max_version, {12345});

        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        // wrong version
        update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                             table_id, t1p1, lock_id, initiator, tablet_id, txn_id,
                             cur_max_version + 1);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::VERSION_NOT_MATCH);
    }
}

TEST(MetaServiceTest, UpdateDeleteBitmapFailCase) {
    // simulate the situation described in https://github.com/apache/doris/pull/49710
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");

    int64_t db_id = 1999;
    int64_t table_id = 1001;
    int64_t index_id = 4001;
    int64_t t1p1 = 2001;
    int64_t tablet_id = 3001;
    int64_t initiator = -1;
    int64_t cur_max_version = 100;
    set_partition_version(meta_service.get(), instance_id, db_id, table_id, t1p1, cur_max_version);
    ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id, index_id,
                                                     t1p1, tablet_id));

    // txn1 begins
    int64_t txn_id1;
    begin_txn_and_commit_rowset(meta_service.get(), "label31", db_id, table_id, t1p1, tablet_id,
                                &txn_id1);
    int64_t txn1_version_to_publish = cur_max_version + 1;
    // txn1 gains the lock and try to publish with version 101
    int64_t lock_id = txn_id1;
    get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);

    // txn1 failed due to calculation timeout and removes the delete bitmap lock
    RemoveDeleteBitmapUpdateLockRequest remove_req;
    RemoveDeleteBitmapUpdateLockResponse remove_res;
    remove_req.set_cloud_unique_id("test_cloud_unique_id");
    remove_req.set_table_id(table_id);
    remove_req.set_lock_id(lock_id);
    remove_req.set_initiator(-1);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_req, &remove_res,
            nullptr);
    ASSERT_EQ(remove_res.status().code(), MetaServiceCode::OK);

    // txn2 gains the lock and succeeds to publish with version 101
    int64_t txn_id2;
    begin_txn_and_commit_rowset(meta_service.get(), "label32", db_id, table_id, t1p1, tablet_id,
                                &txn_id2);
    lock_id = txn_id2;
    get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);

    int64_t txn2_version_to_publish = cur_max_version + 1;
    UpdateDeleteBitmapRequest update_delete_bitmap_req;
    UpdateDeleteBitmapResponse update_delete_bitmap_res;
    std::string data1 = "1234";
    update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                         table_id, t1p1, lock_id, initiator, tablet_id, txn_id2,
                         txn2_version_to_publish, data1);

    CommitTxnRequest req;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_db_id(db_id);
    req.set_txn_id(txn_id2);
    req.add_mow_table_ids(table_id);
    CommitTxnResponse res;
    meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                             &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string ver_key = partition_version_key({instance_id, db_id, table_id, t1p1});
    std::string ver_val;
    VersionPB version_pb;
    auto ret = txn->get(ver_key, &ver_val);
    ASSERT_EQ(ret, TxnErrorCode::TXN_OK);
    ASSERT_TRUE(version_pb.ParseFromString(ver_val));
    ASSERT_EQ(version_pb.version(), cur_max_version + 1);

    std::string lock_key = meta_delete_bitmap_update_lock_key({instance_id, table_id, -1});
    std::string lock_val;
    ret = txn->get(lock_key, &lock_val);
    ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);

    // txn1 retries to publish and gains the lock, try to publish with version 102
    lock_id = txn_id1;
    get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);

    // txn1's previous calculation task finshes and try to update delete bitmap with version 101
    std::string data2 = "5678";
    update_delete_bitmap(meta_service.get(), update_delete_bitmap_req, update_delete_bitmap_res,
                         table_id, t1p1, lock_id, initiator, tablet_id, txn_id1,
                         txn1_version_to_publish, data2);
    // this should fail
    ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::VERSION_NOT_MATCH);

    GetDeleteBitmapRequest get_delete_bitmap_req;
    GetDeleteBitmapResponse get_delete_bitmap_res;
    get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    get_delete_bitmap_req.set_tablet_id(tablet_id);
    get_delete_bitmap_req.add_rowset_ids("123");
    get_delete_bitmap_req.add_begin_versions(0);
    get_delete_bitmap_req.add_end_versions(cur_max_version + 1);
    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
    ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.versions_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), data1);
}

TEST(MetaServiceTest, UpdateDeleteBitmapScOverrideExistingKey) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    size_t split_size = 90 * 1000; // see cloud/src/common/util.h

    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");

    {
        // schema change should use pending delete bitmap to clear previous failed trials
        int64_t db_id = 99999;
        int64_t table_id = 1801;
        int64_t index_id = 4801;
        int64_t t1p1 = 2001;
        int64_t tablet_id = 3001;
        int64_t txn_id;
        ASSERT_NO_FATAL_FAILURE(create_tablet_with_db_id(meta_service.get(), db_id, table_id,
                                                         index_id, t1p1, tablet_id));
        begin_txn_and_commit_rowset(meta_service.get(), "label11", db_id, table_id, t1p1, tablet_id,
                                    &txn_id);
        int64_t lock_id = -2;
        int64_t initiator = 1009;
        int64_t version = 100;

        get_delete_bitmap_update_lock(meta_service.get(), table_id, t1p1, lock_id, initiator);

        {
            UpdateDeleteBitmapRequest update_delete_bitmap_req;
            UpdateDeleteBitmapResponse update_delete_bitmap_res;
            // will be splited and stored in 5 KVs
            std::string data1(split_size * 5, 'c');
            update_delete_bitmap(meta_service.get(), update_delete_bitmap_req,
                                 update_delete_bitmap_res, table_id, t1p1, lock_id, initiator,
                                 tablet_id, txn_id, version, data1);
            ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

            GetDeleteBitmapRequest get_delete_bitmap_req;
            GetDeleteBitmapResponse get_delete_bitmap_res;
            get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
            get_delete_bitmap_req.set_tablet_id(tablet_id);
            get_delete_bitmap_req.add_rowset_ids("123");
            get_delete_bitmap_req.add_begin_versions(0);
            get_delete_bitmap_req.add_end_versions(version);
            meta_service->get_delete_bitmap(
                    reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
            ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.versions_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), data1);
        }

        {
            std::string pending_key = meta_pending_delete_bitmap_key({instance_id, tablet_id});
            std::string pending_val;
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            ASSERT_EQ(txn->get(pending_key, &pending_val), TxnErrorCode::TXN_OK);
            PendingDeleteBitmapPB pending_info;
            ASSERT_TRUE(pending_info.ParseFromString(pending_val));
            ASSERT_EQ(pending_info.delete_bitmap_keys_size(), 1);

            std::string_view k1 = pending_info.delete_bitmap_keys(0);
            k1.remove_prefix(1);
            std::vector<std::tuple<std::variant<int64_t, std::string>, int, int>> out;
            decode_key(&k1, &out);
            // 0x01 "meta" ${instance_id} "delete_bitmap" ${tablet_id} ${rowset_id} ${version} ${segment_id} -> roaringbitmap
            auto encoded_tablet_id = std::get<std::int64_t>(std::get<0>(out[3]));
            ASSERT_EQ(encoded_tablet_id, tablet_id);
            auto encoded_rowset_id = std::get<std::string>(std::get<0>(out[4]));
            ASSERT_EQ(encoded_rowset_id, "123");
            auto encoded_version = std::get<std::int64_t>(std::get<0>(out[5]));
            ASSERT_EQ(encoded_version, version);
            auto encoded_segment_id = std::get<std::int64_t>(std::get<0>(out[6]));
            ASSERT_EQ(encoded_segment_id, 0);
        }

        {
            UpdateDeleteBitmapRequest update_delete_bitmap_req;
            UpdateDeleteBitmapResponse update_delete_bitmap_res;
            // will be splited and stored in 3 KVs
            // if we don't remove previous splited KVs, will crash when reading
            std::string data2(split_size * 3, 'a');
            update_delete_bitmap(meta_service.get(), update_delete_bitmap_req,
                                 update_delete_bitmap_res, table_id, t1p1, lock_id, initiator,
                                 tablet_id, txn_id, version, data2);
            ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

            GetDeleteBitmapRequest get_delete_bitmap_req;
            GetDeleteBitmapResponse get_delete_bitmap_res;
            get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
            get_delete_bitmap_req.set_tablet_id(tablet_id);
            get_delete_bitmap_req.add_rowset_ids("123");
            get_delete_bitmap_req.add_begin_versions(0);
            get_delete_bitmap_req.add_end_versions(version);
            meta_service->get_delete_bitmap(
                    reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
            ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.versions_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), data2);
        }
    }
}

void testUpdateDeleteBitmap(int lock_version) {
    config::delete_bitmap_lock_v2_white_list = lock_version == 1 ? "" : "*";
    auto meta_service = get_meta_service();
    remove_delete_bitmap_lock(meta_service.get(), 112);

    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");

    // get delete bitmap update lock
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(112);
    get_lock_req.add_partition_ids(123);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(888);
    get_lock_req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);

    // first update delete bitmap
    std::vector<std::string> delete_bitmap_keys;
    {
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(888);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc0");
        delete_bitmap_keys.emplace_back(meta_delete_bitmap_key({instance_id, 333, "123", 2, 1}));

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(3);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc1");
        delete_bitmap_keys.emplace_back(meta_delete_bitmap_key({instance_id, 333, "123", 3, 0}));

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(3);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc2");
        delete_bitmap_keys.emplace_back(meta_delete_bitmap_key({instance_id, 333, "123", 3, 1}));

        update_delete_bitmap_req.add_rowset_ids("124");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc3");
        delete_bitmap_keys.emplace_back(meta_delete_bitmap_key({instance_id, 333, "124", 2, 0}));

        std::string large_value = generate_random_string(300 * 1000);
        update_delete_bitmap_req.add_rowset_ids("124");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);
        delete_bitmap_keys.emplace_back(meta_delete_bitmap_key({instance_id, 333, "124", 2, 1}));

        update_delete_bitmap_req.add_rowset_ids("124");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(3);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc4");
        delete_bitmap_keys.emplace_back(meta_delete_bitmap_key({instance_id, 333, "124", 3, 0}));

        // v2 update delete bitmap
        {
            DeleteBitmapPB delete_bitmap;
            delete_bitmap.add_rowset_ids("123");
            delete_bitmap.add_segment_ids(1);
            delete_bitmap.add_versions(2);
            delete_bitmap.add_segment_delete_bitmaps("abc0");

            delete_bitmap.add_rowset_ids("123");
            delete_bitmap.add_segment_ids(0);
            delete_bitmap.add_versions(3);
            delete_bitmap.add_segment_delete_bitmaps("abc1");

            delete_bitmap.add_rowset_ids("123");
            delete_bitmap.add_segment_ids(1);
            delete_bitmap.add_versions(3);
            delete_bitmap.add_segment_delete_bitmaps("abc2");

            DeleteBitmapStoragePB delete_bitmap_storage_pb;
            delete_bitmap_storage_pb.set_store_in_fdb(true);
            *(delete_bitmap_storage_pb.mutable_delete_bitmap()) = std::move(delete_bitmap);
            *(update_delete_bitmap_req.add_delete_bitmap_storages()) =
                    std::move(delete_bitmap_storage_pb);
            update_delete_bitmap_req.add_delta_rowset_ids("124");
            delete_bitmap_keys.emplace_back(
                    versioned::meta_delete_bitmap_key({instance_id, 333, "124"}));
        }
        {
            DeleteBitmapPB delete_bitmap;
            delete_bitmap.add_rowset_ids("124");
            delete_bitmap.add_segment_ids(0);
            delete_bitmap.add_versions(2);
            delete_bitmap.add_segment_delete_bitmaps("abc3");

            delete_bitmap.add_rowset_ids("124");
            delete_bitmap.add_segment_ids(1);
            delete_bitmap.add_versions(2);
            delete_bitmap.add_segment_delete_bitmaps(large_value);

            delete_bitmap.add_rowset_ids("124");
            delete_bitmap.add_segment_ids(0);
            delete_bitmap.add_versions(3);
            delete_bitmap.add_segment_delete_bitmaps("abc4");

            DeleteBitmapStoragePB delete_bitmap_storage_pb;
            delete_bitmap_storage_pb.set_store_in_fdb(true);
            *(delete_bitmap_storage_pb.mutable_delete_bitmap()) = std::move(delete_bitmap);
            *(update_delete_bitmap_req.add_delete_bitmap_storages()) =
                    std::move(delete_bitmap_storage_pb);
            update_delete_bitmap_req.add_delta_rowset_ids("125");
            delete_bitmap_keys.emplace_back(
                    versioned::meta_delete_bitmap_key({instance_id, 333, "125"}));
        }

        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

        // first get delete bitmap
        GetDeleteBitmapRequest get_delete_bitmap_req;
        GetDeleteBitmapResponse get_delete_bitmap_res;
        get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        get_delete_bitmap_req.set_tablet_id(333);

        get_delete_bitmap_req.add_rowset_ids("123");
        get_delete_bitmap_req.add_begin_versions(3);
        get_delete_bitmap_req.add_end_versions(3);

        get_delete_bitmap_req.add_rowset_ids("124");
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(3);

        get_delete_bitmap_req.add_rowset_ids("125");
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(3);

        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        auto check_v1_delete_bitmap = [&](GetDeleteBitmapResponse get_delete_bitmap_res) {
            ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 5);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 5);
            ASSERT_EQ(get_delete_bitmap_res.versions_size(), 5);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 5);

            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(0), "123");
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(0), 0);
            ASSERT_EQ(get_delete_bitmap_res.versions(0), 3);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), "abc1");

            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(1), "123");
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(1), 1);
            ASSERT_EQ(get_delete_bitmap_res.versions(1), 3);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(1), "abc2");

            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(2), "124");
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(2), 0);
            ASSERT_EQ(get_delete_bitmap_res.versions(2), 2);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(2), "abc3");

            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(3), "124");
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(3), 1);
            ASSERT_EQ(get_delete_bitmap_res.versions(3), 2);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(3), large_value);

            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(4), "124");
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(4), 0);
            ASSERT_EQ(get_delete_bitmap_res.versions(4), 3);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(4), "abc4");
        };
        check_v1_delete_bitmap(get_delete_bitmap_res);

        // v2 get delete bitmap
        auto check_v2_delete_bitmap = [&](GetDeleteBitmapResponse& get_delete_bitmap_res2) {
            ASSERT_EQ(get_delete_bitmap_res2.status().code(), MetaServiceCode::OK);
            ASSERT_EQ(get_delete_bitmap_res2.delete_bitmap_storages_size(), 2);
            {
                auto& delete_bitmap_storage = get_delete_bitmap_res2.delete_bitmap_storages(0);
                ASSERT_TRUE(delete_bitmap_storage.store_in_fdb());
                auto& delete_bitmap_pb = delete_bitmap_storage.delete_bitmap();
                ASSERT_EQ(delete_bitmap_pb.rowset_ids_size(), 3);
                ASSERT_EQ(delete_bitmap_pb.versions_size(), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_ids_size(), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps_size(), 3);

                ASSERT_EQ(delete_bitmap_pb.rowset_ids(0), "123");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(0), 1);
                ASSERT_EQ(delete_bitmap_pb.versions(0), 2);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(0), "abc0");

                ASSERT_EQ(delete_bitmap_pb.rowset_ids(1), "123");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(1), 0);
                ASSERT_EQ(delete_bitmap_pb.versions(1), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(1), "abc1");

                ASSERT_EQ(delete_bitmap_pb.rowset_ids(2), "123");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(2), 1);
                ASSERT_EQ(delete_bitmap_pb.versions(2), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(2), "abc2");
            }
            {
                auto& delete_bitmap_storage = get_delete_bitmap_res2.delete_bitmap_storages(1);
                ASSERT_TRUE(delete_bitmap_storage.store_in_fdb());
                auto& delete_bitmap_pb = delete_bitmap_storage.delete_bitmap();
                ASSERT_EQ(delete_bitmap_pb.rowset_ids_size(), 3);
                ASSERT_EQ(delete_bitmap_pb.versions_size(), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_ids_size(), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps_size(), 3);

                ASSERT_EQ(delete_bitmap_pb.rowset_ids(0), "124");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(0), 0);
                ASSERT_EQ(delete_bitmap_pb.versions(0), 2);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(0), "abc3");

                ASSERT_EQ(delete_bitmap_pb.rowset_ids(1), "124");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(1), 1);
                ASSERT_EQ(delete_bitmap_pb.versions(1), 2);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(1), large_value);

                ASSERT_EQ(delete_bitmap_pb.rowset_ids(2), "124");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(2), 0);
                ASSERT_EQ(delete_bitmap_pb.versions(2), 3);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(2), "abc4");
            }
        };
        {
            GetDeleteBitmapResponse get_delete_bitmap_res2;
            get_delete_bitmap_req.set_store_version(2);

            meta_service->get_delete_bitmap(
                    reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                    &get_delete_bitmap_req, &get_delete_bitmap_res2, nullptr);
            check_v2_delete_bitmap(get_delete_bitmap_res2);
        }

        // v1 and v2 get delete bitmap
        {
            GetDeleteBitmapResponse get_delete_bitmap_res3;
            get_delete_bitmap_req.set_store_version(3);

            meta_service->get_delete_bitmap(
                    reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                    &get_delete_bitmap_req, &get_delete_bitmap_res3, nullptr);
            check_v1_delete_bitmap(get_delete_bitmap_res3);
            check_v2_delete_bitmap(get_delete_bitmap_res3);
        }

        // check pending delete bitmap key
        {
            std::string pending_key = meta_pending_delete_bitmap_key({instance_id, 333});
            std::string pending_val;
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            ASSERT_EQ(txn->get(pending_key, &pending_val), TxnErrorCode::TXN_OK);
            PendingDeleteBitmapPB pending_info;
            ASSERT_TRUE(pending_info.ParseFromString(pending_val));
            ASSERT_EQ(pending_info.delete_bitmap_keys_size(), delete_bitmap_keys.size());
            for (size_t i = 0; i < delete_bitmap_keys.size(); ++i) {
                ASSERT_EQ(pending_info.delete_bitmap_keys(i), delete_bitmap_keys[i]);
            }
        }
    }

    // second update delete bitmap
    {
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(888);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);

        std::string large_value = generate_random_string(200 * 1000);
        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("bbb0");

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(3);
        update_delete_bitmap_req.add_segment_delete_bitmaps("bbb1");

        update_delete_bitmap_req.add_rowset_ids("124");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(3);
        update_delete_bitmap_req.add_segment_delete_bitmaps("bbb2");

        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

        // second get delete bitmap
        GetDeleteBitmapRequest get_delete_bitmap_req;
        GetDeleteBitmapResponse get_delete_bitmap_res;
        get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        get_delete_bitmap_req.set_tablet_id(333);

        get_delete_bitmap_req.add_rowset_ids("123");
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(3);

        get_delete_bitmap_req.add_rowset_ids("124");
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(3);

        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 4);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 4);
        ASSERT_EQ(get_delete_bitmap_res.versions_size(), 4);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 4);

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(0), "123");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(0), 0);
        ASSERT_EQ(get_delete_bitmap_res.versions(0), 2);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), large_value);

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(1), "123");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(1), 1);
        ASSERT_EQ(get_delete_bitmap_res.versions(1), 2);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(1), "bbb0");

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(2), "123");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(2), 1);
        ASSERT_EQ(get_delete_bitmap_res.versions(2), 3);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(2), "bbb1");

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(3), "124");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(3), 1);
        ASSERT_EQ(get_delete_bitmap_res.versions(3), 3);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(3), "bbb2");
    }

    // large size txn
    {
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(888);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);

        std::string large_value = generate_random_string(300 * 1000);
        for (size_t i = 0; i < 100; ++i) {
            update_delete_bitmap_req.add_rowset_ids("123");
            update_delete_bitmap_req.add_segment_ids(1);
            update_delete_bitmap_req.add_versions(i);
            update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);
        }

        update_delete_bitmap_req.add_rowset_ids("124");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(3);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abcd4");

        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

        GetDeleteBitmapRequest get_delete_bitmap_req;
        GetDeleteBitmapResponse get_delete_bitmap_res;
        get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        get_delete_bitmap_req.set_tablet_id(333);

        get_delete_bitmap_req.add_rowset_ids("123");
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(101);

        get_delete_bitmap_req.add_rowset_ids("124");
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(3);

        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 101);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 101);
        ASSERT_EQ(get_delete_bitmap_res.versions_size(), 101);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 101);

        for (size_t i = 0; i < 100; ++i) {
            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(i), "123");
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(i), 1);
            ASSERT_EQ(get_delete_bitmap_res.versions(i), i);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(i), large_value);
        }

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(100), "124");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(100), 0);
        ASSERT_EQ(get_delete_bitmap_res.versions(100), 3);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(100), "abcd4");
    }

    // update existing delete bitmap key
    {
        //first update new key
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(888);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);
        std::string large_value = generate_random_string(300 * 1000 * 3);
        update_delete_bitmap_req.add_rowset_ids("456");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);
        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

        GetDeleteBitmapRequest get_delete_bitmap_req;
        GetDeleteBitmapResponse get_delete_bitmap_res;
        get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        get_delete_bitmap_req.set_tablet_id(333);

        get_delete_bitmap_req.add_rowset_ids("456");
        get_delete_bitmap_req.add_begin_versions(2);
        get_delete_bitmap_req.add_end_versions(2);

        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 1);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);
        ASSERT_EQ(get_delete_bitmap_res.versions_size(), 1);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(0), "456");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(0), 0);
        ASSERT_EQ(get_delete_bitmap_res.versions(0), 2);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), large_value);
    }

    RemoveDeleteBitmapUpdateLockRequest remove_lock_req;
    RemoveDeleteBitmapUpdateLockResponse remove_lock_res;
    remove_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    remove_lock_req.set_table_id(112);
    remove_lock_req.set_lock_id(888);
    remove_lock_req.set_initiator(-1);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_lock_req,
            &remove_lock_res, nullptr);
    ASSERT_EQ(remove_lock_res.status().code(), MetaServiceCode::OK);

    for (int i = 0; i < 2; ++i) {
        auto lock_id =
                i == 0 ? COMPACTION_DELETE_BITMAP_LOCK_ID : SCHEMA_CHANGE_DELETE_BITMAP_LOCK_ID;
        // case: compaction or schema_change update delete bitmap
        get_lock_req.set_lock_id(lock_id);
        get_lock_req.set_initiator(800);
        meta_service->get_delete_bitmap_update_lock(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
                &get_lock_res, nullptr);
        ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
        // update delete bitmap
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(lock_id);
        update_delete_bitmap_req.set_initiator(800);
        update_delete_bitmap_req.set_tablet_id(333);
        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("compaction0");
        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        // remove lock
        remove_lock_req.set_lock_id(lock_id);
        remove_lock_req.set_initiator(800);
        meta_service->remove_delete_bitmap_update_lock(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_lock_req,
                &remove_lock_res, nullptr);
        ASSERT_EQ(remove_lock_res.status().code(), MetaServiceCode::OK);

        // case: compaction or schema_change update delete bitmap with lock expired
        get_lock_req.set_lock_id(lock_id);
        get_lock_req.set_initiator(800);
        get_lock_req.set_expiration(1);
        meta_service->get_delete_bitmap_update_lock(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
                &get_lock_res, nullptr);
        ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
        // load get lock
        sleep(2);
        get_lock_req.set_lock_id(100);
        get_lock_req.set_initiator(-1);
        get_lock_req.set_expiration(1);
        meta_service->get_delete_bitmap_update_lock(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
                &get_lock_res, nullptr);
        ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
        // compaction update delete bitmap
        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::LOCK_EXPIRED);

        // case: compaction2 or schema_change2 get lock
        sleep(2);
        get_lock_req.set_lock_id(lock_id);
        get_lock_req.set_initiator(810);
        get_lock_req.set_expiration(1);
        meta_service->get_delete_bitmap_update_lock(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
                &get_lock_res, nullptr);
        ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
        // compaction1 update delete bitmap
        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::LOCK_EXPIRED);
        // remove compaction2 or or schema_change2 lock
        remove_lock_req.set_lock_id(lock_id);
        remove_lock_req.set_initiator(810);
        meta_service->remove_delete_bitmap_update_lock(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_lock_req,
                &remove_lock_res, nullptr);
        ASSERT_EQ(remove_lock_res.status().code(), MetaServiceCode::OK);
    }

    {
        //compaction update delete bitmap without lock
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_without_lock(true);
        update_delete_bitmap_req.set_lock_id(-3);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);
        std::string large_value = generate_random_string(300 * 1000);
        update_delete_bitmap_req.add_rowset_ids("456");
        update_delete_bitmap_req.add_segment_ids(0);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);
        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

        GetDeleteBitmapRequest get_delete_bitmap_req;
        GetDeleteBitmapResponse get_delete_bitmap_res;
        get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        get_delete_bitmap_req.set_tablet_id(333);

        get_delete_bitmap_req.add_rowset_ids("456");
        get_delete_bitmap_req.add_begin_versions(2);
        get_delete_bitmap_req.add_end_versions(2);

        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 1);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);
        ASSERT_EQ(get_delete_bitmap_res.versions_size(), 1);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);

        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(0), "456");
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(0), 0);
        ASSERT_EQ(get_delete_bitmap_res.versions(0), 2);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), large_value);
    }

    remove_delete_bitmap_lock(meta_service.get(), 112);
}

TEST(MetaServiceTest, UpdateDeleteBitmap) {
    testUpdateDeleteBitmap(2);
    testUpdateDeleteBitmap(1);
}

TEST(MetaServiceTest, UpdateDeleteBitmapWithException) {
    auto meta_service = get_meta_service();
    brpc::Controller cntl;

    {
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(888);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc0");

        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::LOCK_EXPIRED);
    }

    // get delete bitmap update lock
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(112);
    get_lock_req.add_partition_ids(123);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(888);
    get_lock_req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);

    {
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(222);
        update_delete_bitmap_req.set_initiator(-1);
        update_delete_bitmap_req.set_tablet_id(333);

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc0");

        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::LOCK_EXPIRED);
    }

    {
        UpdateDeleteBitmapRequest update_delete_bitmap_req;
        UpdateDeleteBitmapResponse update_delete_bitmap_res;
        update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
        update_delete_bitmap_req.set_table_id(112);
        update_delete_bitmap_req.set_partition_id(123);
        update_delete_bitmap_req.set_lock_id(888);
        update_delete_bitmap_req.set_initiator(-2);
        update_delete_bitmap_req.set_tablet_id(333);

        update_delete_bitmap_req.add_rowset_ids("123");
        update_delete_bitmap_req.add_segment_ids(1);
        update_delete_bitmap_req.add_versions(2);
        update_delete_bitmap_req.add_segment_delete_bitmaps("abc0");

        meta_service->update_delete_bitmap(
                reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
        ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::LOCK_EXPIRED);
    }
}

void update_delete_bitmap_with_remove_pre(MetaServiceProxy* meta_service, int64_t table_id,
                                          int64_t tablet_id, bool inject = false,
                                          bool rowset_non_exist = false) {
    // create rowset, if `rowset_non_exist` enabled, only r4 exists
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        if (rowset_non_exist) {
            std::string rs_key, rs_val;
            doris::RowsetMetaCloudPB rs;
            rs.set_rowset_id(0);

            rs_key = meta_rowset_key({"test_instance", tablet_id, 3});
            rs.set_rowset_id_v2("r2-3");
            ASSERT_TRUE(rs.SerializeToString(&rs_val));
            txn->put(rs_key, rs_val);

            rs_key = meta_rowset_key({"test_instance", tablet_id, 4});
            rs.set_rowset_id_v2("r4");
            ASSERT_TRUE(rs.SerializeToString(&rs_val));
            txn->put(rs_key, rs_val);
        } else {
            for (int i = 2; i <= 4; i++) {
                std::string rs_key, rs_val;
                MetaRowsetKeyInfo rs_key_info {"test_instance", tablet_id, i};
                meta_rowset_key(rs_key_info, &rs_key);
                doris::RowsetMetaCloudPB rs;
                rs.set_rowset_id(0);
                rs.set_rowset_id_v2("r" + std::to_string(i));
                ASSERT_TRUE(rs.SerializeToString(&rs_val));
                txn->put(rs_key, rs_val);
            }
        }
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }
    brpc::Controller cntl;
    // compaction update delete bitmap with remove pre rowset delete bitmaps
    // get update lock
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(table_id);
    get_lock_req.set_lock_id(-1);
    get_lock_req.set_initiator(203);
    get_lock_req.set_expiration(10);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);
    // write delete bitmap
    UpdateDeleteBitmapRequest update_delete_bitmap_req;
    UpdateDeleteBitmapResponse update_delete_bitmap_res;
    update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    update_delete_bitmap_req.set_table_id(table_id);
    update_delete_bitmap_req.set_partition_id(201);
    update_delete_bitmap_req.set_tablet_id(tablet_id);
    update_delete_bitmap_req.set_lock_id(-1);
    update_delete_bitmap_req.set_initiator(203);
    std::string large_value = generate_random_string(300 * 1000);
    std::vector<std::tuple<std::string, int64_t, int64_t>> rowset_segment_version_vector = {
            /* r2-0 */ {"r2", 0, 3}, {"r2", 0, 4}, {"r2", 0, 5}, {"r2", 0, 6},
            /* r3-0 */ {"r3", 0, 4}, {"r3", 0, 5}, {"r3", 0, 6},
            /* r3-1 */ {"r3", 1, 4}, {"r3", 1, 5},
            /* r3-2 */ {"r3", 2, 4}, {"r3", 2, 6},
            /* r4-0 */ {"r4", 0, 5}, {"r4", 0, 6}};
    for (const auto& [rowset, segment, version] : rowset_segment_version_vector) {
        update_delete_bitmap_req.add_rowset_ids(rowset);
        update_delete_bitmap_req.add_segment_ids(segment);
        update_delete_bitmap_req.add_versions(version);
        update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);
    }
    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
    ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    // remove delete bitmap lock
    RemoveDeleteBitmapUpdateLockRequest remove_lock_req;
    RemoveDeleteBitmapUpdateLockResponse remove_lock_res;
    remove_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    remove_lock_req.set_table_id(table_id);
    remove_lock_req.set_lock_id(-1);
    remove_lock_req.set_initiator(203);
    meta_service->remove_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &remove_lock_req,
            &remove_lock_res, nullptr);
    ASSERT_EQ(remove_lock_res.status().code(), MetaServiceCode::OK);
    // get delete bitmap
    GetDeleteBitmapRequest get_delete_bitmap_req;
    GetDeleteBitmapResponse get_delete_bitmap_res;
    get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    get_delete_bitmap_req.set_tablet_id(tablet_id);
    std::vector<std::string> rowset_vector = {"r2", "r3", "r4"};
    for (const auto& rowset : rowset_vector) {
        get_delete_bitmap_req.add_rowset_ids(rowset);
        get_delete_bitmap_req.add_begin_versions(0);
        get_delete_bitmap_req.add_end_versions(6);
    }
    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
    ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    auto size = rowset_segment_version_vector.size();
    ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), size);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), size);
    ASSERT_EQ(get_delete_bitmap_res.versions_size(), size);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), size);
    // update pre rowset delete bitmap
    update_delete_bitmap_req.clear_rowset_ids();
    update_delete_bitmap_req.clear_segment_ids();
    update_delete_bitmap_req.clear_versions();
    update_delete_bitmap_req.clear_segment_delete_bitmaps();
    update_delete_bitmap_req.set_lock_id(-3);
    update_delete_bitmap_req.set_without_lock(true);
    update_delete_bitmap_req.set_initiator(tablet_id);
    update_delete_bitmap_req.set_pre_rowset_agg_start_version(4);
    update_delete_bitmap_req.set_pre_rowset_agg_end_version(6);
    std::vector<std::tuple<std::string, int64_t, int64_t, int64_t>>
            new_rowset_segment_version_vector = {/* r2-0 */ {"r2", 0, 6, 2},
                                                 /* r3-0 */ {"r3", 0, 6, 3},
                                                 /* r3-1 */ {"r3", 1, 6, 3},
                                                 /* r3-2 */ {"r3", 2, 6, 3},
                                                 /* r4-0 */ {"r4", 0, 6, 4}};
    std::string new_large_value = generate_random_string(300 * 1000);
    for (const auto& [rowset, segment, version, rowset_version] :
         new_rowset_segment_version_vector) {
        update_delete_bitmap_req.add_rowset_ids(rowset);
        update_delete_bitmap_req.add_segment_ids(segment);
        update_delete_bitmap_req.add_versions(version);
        update_delete_bitmap_req.add_segment_delete_bitmaps(new_large_value);
        update_delete_bitmap_req.add_pre_rowset_versions(rowset_version);
    }
    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
    ASSERT_EQ(update_delete_bitmap_res.status().code(),
              inject ? MetaServiceCode::KV_TXN_CONFLICT : MetaServiceCode::OK);
    // get delete bitmap again
    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
    ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    size = 6;
    if (inject) {
        size = 13;
    } else if (rowset_non_exist) {
        size = 12;
    }
    ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), size);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), size);
    ASSERT_EQ(get_delete_bitmap_res.versions_size(), size);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), size);
    std::vector<std::tuple<std::string, int64_t, int64_t, std::string>> expected_dm;
    if (inject) {
        expected_dm = {/* r2-0 */ {"r2", 0, 3, large_value},
                       {"r2", 0, 4, large_value},
                       {"r2", 0, 5, large_value},
                       {"r2", 0, 6, new_large_value},
                       /* r3-0 is agg */ {"r3", 0, 4, large_value},
                       {"r3", 1, 4, large_value},
                       {"r3", 2, 4, large_value},
                       {"r3", 0, 5, large_value},
                       {"r3", 1, 5, large_value},
                       {"r3", 0, 6, new_large_value},
                       {"r3", 2, 6, large_value},
                       /* r4-0 */ {"r4", 0, 5, large_value},
                       {"r4", 0, 6, large_value}};
    } else if (rowset_non_exist) {
        expected_dm = {/* r2-0 */ {"r2", 0, 3, large_value},
                       {"r2", 0, 4, large_value},
                       {"r2", 0, 5, large_value},
                       {"r2", 0, 6, large_value},
                       /* r3-0 */ {"r3", 0, 4, large_value},
                       {"r3", 1, 4, large_value},
                       {"r3", 2, 4, large_value},
                       {"r3", 0, 5, large_value},
                       {"r3", 1, 5, large_value},
                       {"r3", 0, 6, large_value},
                       {"r3", 2, 6, large_value},
                       /* r4-0 */ {"r4", 0, 6, new_large_value}};
    } else {
        expected_dm = {/* r2-0 */ {"r2", 0, 3, large_value},
                       {"r2", 0, 6, new_large_value},
                       /* r3-0 */ {"r3", 0, 6, new_large_value},
                       /* r3-1 */ {"r3", 1, 6, new_large_value},
                       /* r3-2 */ {"r3", 2, 6, new_large_value},
                       /* r4-0 */ {"r4", 0, 6, new_large_value}};
    }
    for (size_t i = 0; i < get_delete_bitmap_res.rowset_ids_size(); i++) {
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(i), std::get<0>(expected_dm[i]));
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(i), std::get<1>(expected_dm[i]));
        ASSERT_EQ(get_delete_bitmap_res.versions(i), std::get<2>(expected_dm[i]));
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(i), std::get<3>(expected_dm[i]));
    }
}

TEST(MetaServiceTest, UpdateDeleteBitmapWithRemovePreDeleteBitmap) {
    auto meta_service = get_meta_service();
    [[maybe_unused]] auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };

    update_delete_bitmap_with_remove_pre(meta_service.get(), 200, 202);

    int64_t max_txn_commit_byte = config::max_txn_commit_byte;
    config::max_txn_commit_byte = 1000;
    update_delete_bitmap_with_remove_pre(meta_service.get(), 300, 302);

    sp->set_call_back("update_delete_bitmap:commit:err", [&](auto&& args) {
        auto initiator = try_any_cast<int64_t>(args[0]);
        auto i = try_any_cast<size_t>(args[1]);
        if (initiator == 402 && i == 2) {
            *try_any_cast<TxnErrorCode*>(args[2]) = TxnErrorCode::TXN_CONFLICT;
        }
    });
    sp->enable_processing();
    update_delete_bitmap_with_remove_pre(meta_service.get(), 400, 402, true);
    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
    config::max_txn_commit_byte = max_txn_commit_byte;

    update_delete_bitmap_with_remove_pre(meta_service.get(), 500, 502, false, true);
}

TEST(MetaServiceTest, GetDeleteBitmapWithIdx) {
    auto meta_service = get_meta_service();
    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");
    int64_t db_id = 1;
    int64_t table_id = 1;
    int64_t index_id = 1;
    int64_t partition_id = 1;
    int64_t tablet_id = 123;

    brpc::Controller cntl;
    GetDeleteBitmapRequest req;
    GetDeleteBitmapResponse res;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_tablet_id(tablet_id);
    TabletIndexPB idx;
    idx.set_tablet_id(tablet_id);
    idx.set_index_id(index_id);
    idx.set_db_id(db_id);
    idx.set_partition_id(partition_id);
    idx.set_table_id(table_id);
    *(req.mutable_idx()) = idx;
    req.set_base_compaction_cnt(9);
    req.set_cumulative_compaction_cnt(19);
    req.set_cumulative_point(21);

    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl), &req,
                                    &res, nullptr);
    EXPECT_EQ(res.status().code(), MetaServiceCode::TABLET_NOT_FOUND);

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string stats_key =
            stats_tablet_key({instance_id, table_id, index_id, partition_id, tablet_id});
    TabletStatsPB stats;
    stats.set_base_compaction_cnt(9);
    stats.set_cumulative_compaction_cnt(19);
    stats.set_cumulative_point(20);
    txn->put(stats_key, stats.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl), &req,
                                    &res, nullptr);
    EXPECT_EQ(res.status().code(), MetaServiceCode::ROWSETS_EXPIRED);

    req.set_cumulative_point(20);
    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl), &req,
                                    &res, nullptr);
    EXPECT_EQ(res.status().code(), MetaServiceCode::OK);

    req.add_rowset_ids("1234");
    req.add_begin_versions(1);
    req.add_end_versions(2);
    req.add_end_versions(3);
    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl), &req,
                                    &res, nullptr);
    EXPECT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
}

TEST(MetaServiceTest, DeleteBimapCommitTxnTest) {
    auto meta_service = get_meta_service();
    extern std::string get_instance_id(const std::shared_ptr<ResourceManager>& rc_mgr,
                                       const std::string& cloud_unique_id);
    auto instance_id = get_instance_id(meta_service->resource_mgr(), "test_cloud_unique_id");

    // case: first version of rowset
    {
        int64_t txn_id = 98765;
        int64_t table_id = 123456; // same as table_id of tmp rowset
        int64_t db_id = 222;
        int64_t tablet_id_base = 8113;
        int64_t partition_id = 1234;
        // begin txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label("test_label");
            txn_info_pb.add_table_ids(table_id);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                    &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // mock rowset and tablet
        for (int i = 0; i < 5; ++i) {
            create_tablet(meta_service.get(), table_id, 1235, partition_id, tablet_id_base + i);
            auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
            tmp_rowset.set_partition_id(partition_id);
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // update delete bitmap
        {
            // get delete bitmap update lock
            brpc::Controller cntl;
            GetDeleteBitmapUpdateLockRequest get_lock_req;
            GetDeleteBitmapUpdateLockResponse get_lock_res;
            get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
            get_lock_req.set_table_id(table_id);
            get_lock_req.add_partition_ids(partition_id);
            get_lock_req.set_expiration(5);
            get_lock_req.set_lock_id(txn_id);
            get_lock_req.set_initiator(-1);
            meta_service->get_delete_bitmap_update_lock(
                    reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
                    &get_lock_res, nullptr);
            ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);

            // first update delete bitmap
            UpdateDeleteBitmapRequest update_delete_bitmap_req;
            UpdateDeleteBitmapResponse update_delete_bitmap_res;
            update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
            update_delete_bitmap_req.set_table_id(table_id);
            update_delete_bitmap_req.set_partition_id(partition_id);
            update_delete_bitmap_req.set_lock_id(txn_id);
            update_delete_bitmap_req.set_initiator(-1);
            update_delete_bitmap_req.set_tablet_id(tablet_id_base);

            update_delete_bitmap_req.add_rowset_ids("123");
            update_delete_bitmap_req.add_segment_ids(1);
            update_delete_bitmap_req.add_versions(2);
            update_delete_bitmap_req.add_segment_delete_bitmaps("abc0");

            meta_service->update_delete_bitmap(
                    reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                    &update_delete_bitmap_req, &update_delete_bitmap_res, nullptr);
            ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        }

        // check delete bitmap update lock and pending delete bitmap
        {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string lock_key = meta_delete_bitmap_update_lock_key({instance_id, table_id, -1});
            std::string lock_val;
            auto ret = txn->get(lock_key, &lock_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_OK);
            DeleteBitmapUpdateLockPB lock_info;
            ASSERT_TRUE(lock_info.ParseFromString(lock_val));

            std::string pending_key = meta_pending_delete_bitmap_key({instance_id, tablet_id_base});
            std::string pending_val;
            ret = txn->get(pending_key, &pending_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_OK);
            PendingDeleteBitmapPB pending_info;
            ASSERT_TRUE(pending_info.ParseFromString(pending_val));
        }

        // commit txn
        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(txn_id);
            req.add_mow_table_ids(table_id);
            CommitTxnResponse res;
            meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        // check delete bitmap update lock and pending delete bitmap
        {
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string lock_key = meta_delete_bitmap_update_lock_key({instance_id, table_id, -1});
            std::string lock_val;
            auto ret = txn->get(lock_key, &lock_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);

            std::string pending_key = meta_pending_delete_bitmap_key({instance_id, tablet_id_base});
            std::string pending_val;
            ret = txn->get(pending_key, &pending_val);
            ASSERT_EQ(ret, TxnErrorCode::TXN_KEY_NOT_FOUND);
        }
    }
}

TEST(MetaServiceTest, GetDeleteBitmapWithRetryTest1) {
    auto meta_service = get_meta_service();
    SyncPoint::get_instance()->enable_processing();
    size_t index = 0;
    SyncPoint::get_instance()->set_call_back("get_delete_bitmap_code", [&](auto&& args) {
        LOG(INFO) << "GET_DELETE_BITMAP_CODE,index=" << index;
        if (++index < 2) {
            *doris::try_any_cast<MetaServiceCode*>(args[0]) = MetaServiceCode::KV_TXN_TOO_OLD;
        }
    });

    // get delete bitmap update lock
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(100);
    get_lock_req.add_partition_ids(123);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(888);
    get_lock_req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);

    //first update new key
    UpdateDeleteBitmapRequest update_delete_bitmap_req;
    UpdateDeleteBitmapResponse update_delete_bitmap_res;
    update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    update_delete_bitmap_req.set_table_id(100);
    update_delete_bitmap_req.set_partition_id(123);
    update_delete_bitmap_req.set_lock_id(888);
    update_delete_bitmap_req.set_initiator(-1);
    update_delete_bitmap_req.set_tablet_id(333);
    std::string large_value = generate_random_string(300 * 1000 * 3);
    update_delete_bitmap_req.add_rowset_ids("456");
    update_delete_bitmap_req.add_segment_ids(0);
    update_delete_bitmap_req.add_versions(2);
    update_delete_bitmap_req.add_segment_delete_bitmaps(large_value);
    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
    ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

    GetDeleteBitmapRequest get_delete_bitmap_req;
    GetDeleteBitmapResponse get_delete_bitmap_res;
    get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    get_delete_bitmap_req.set_tablet_id(333);

    get_delete_bitmap_req.add_rowset_ids("456");
    get_delete_bitmap_req.add_begin_versions(2);
    get_delete_bitmap_req.add_end_versions(2);

    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
    ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.versions_size(), 1);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), 1);

    ASSERT_EQ(get_delete_bitmap_res.rowset_ids(0), "456");
    ASSERT_EQ(get_delete_bitmap_res.segment_ids(0), 0);
    ASSERT_EQ(get_delete_bitmap_res.versions(0), 2);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(0), large_value);

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, GetDeleteBitmapWithRetryTest2) {
    auto meta_service = get_meta_service();
    SyncPoint::get_instance()->enable_processing();
    size_t index = 0;
    int store_version = 1;
    SyncPoint::get_instance()->set_call_back("get_delete_bitmap_test", [&](auto&& args) {
        auto* test = try_any_cast<bool*>(args[0]);
        *test = true;
        LOG(INFO) << "GET_DELETE_BITMAP_TEST, test=" << *test;
    });
    SyncPoint::get_instance()->set_call_back("get_delete_bitmap_err", [&](auto&& args) {
        auto* round = try_any_cast<int64_t*>(args[0]);
        LOG(INFO) << "GET_DELETE_BITMAP_CODE,index=" << index << ",round=" << *round;
        if (*round > 2 && ++index < 2) {
            *try_any_cast<TxnErrorCode*>(args[1]) = TxnErrorCode::TXN_TOO_OLD;
        }
        if (store_version == 2 && *round < 3) {
            *try_any_cast<TxnErrorCode*>(args[1]) = TxnErrorCode::TXN_TOO_OLD;
        }
    });

    // get delete bitmap update lock
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(100);
    get_lock_req.add_partition_ids(123);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(888);
    get_lock_req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);

    //first update new key
    UpdateDeleteBitmapRequest update_delete_bitmap_req;
    UpdateDeleteBitmapResponse update_delete_bitmap_res;
    update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    update_delete_bitmap_req.set_table_id(100);
    update_delete_bitmap_req.set_partition_id(123);
    update_delete_bitmap_req.set_lock_id(888);
    update_delete_bitmap_req.set_initiator(-1);
    update_delete_bitmap_req.set_tablet_id(333);
    std::string rowset_id = "456";
    std::string segment_delete_bitmaps[5];
    for (int i = 0; i < 5; i++) {
        segment_delete_bitmaps[i] = generate_random_string(300 * 1000 * 3);
    }
    int count = 5;
    DeleteBitmapPB delete_bitmap;
    for (int i = 0; i < count; i++) {
        update_delete_bitmap_req.add_rowset_ids(rowset_id);
        update_delete_bitmap_req.add_segment_ids(i);
        update_delete_bitmap_req.add_versions(i + 1);
        update_delete_bitmap_req.add_segment_delete_bitmaps(segment_delete_bitmaps[i]);

        delete_bitmap.add_rowset_ids(rowset_id);
        delete_bitmap.add_segment_ids(i);
        delete_bitmap.add_versions(i + 1);
        delete_bitmap.add_segment_delete_bitmaps(segment_delete_bitmaps[i]);
    }
    // v2 update delete bitmap
    DeleteBitmapStoragePB delete_bitmap_storage_pb;
    delete_bitmap_storage_pb.set_store_in_fdb(true);
    *(delete_bitmap_storage_pb.mutable_delete_bitmap()) = std::move(delete_bitmap);
    *(update_delete_bitmap_req.add_delete_bitmap_storages()) = std::move(delete_bitmap_storage_pb);
    update_delete_bitmap_req.add_delta_rowset_ids(rowset_id);
    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
    ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

    // v1 get delete bitmap
    GetDeleteBitmapRequest get_delete_bitmap_req;
    get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    get_delete_bitmap_req.set_tablet_id(333);

    // add a rowset which does not exist
    get_delete_bitmap_req.add_rowset_ids(rowset_id + "_non");
    get_delete_bitmap_req.add_begin_versions(0);
    get_delete_bitmap_req.add_end_versions(count);

    get_delete_bitmap_req.add_rowset_ids(rowset_id);
    get_delete_bitmap_req.add_begin_versions(0);
    get_delete_bitmap_req.add_end_versions(count);
    {
        GetDeleteBitmapResponse get_delete_bitmap_res;
        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), count);
        ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), count);
        ASSERT_EQ(get_delete_bitmap_res.versions_size(), count);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), count);

        for (int i = 0; i < count; i++) {
            ASSERT_EQ(get_delete_bitmap_res.rowset_ids(i), rowset_id);
            ASSERT_EQ(get_delete_bitmap_res.segment_ids(i), i);
            ASSERT_EQ(get_delete_bitmap_res.versions(i), i + 1);
            ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(i), segment_delete_bitmaps[i]);
        }
    }

    // v2 get delete bitmap
    {
        store_version = 2;
        get_delete_bitmap_req.set_store_version(2);
        GetDeleteBitmapResponse get_delete_bitmap_res;
        meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                        &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
        ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(get_delete_bitmap_res.delete_bitmap_storages_size(), 1);
        auto& delete_bitmap_storage = get_delete_bitmap_res.delete_bitmap_storages(0);
        ASSERT_TRUE(delete_bitmap_storage.store_in_fdb());
        auto& delete_bitmap_pb = delete_bitmap_storage.delete_bitmap();
        ASSERT_EQ(delete_bitmap_pb.rowset_ids_size(), count);
        ASSERT_EQ(delete_bitmap_pb.segment_ids_size(), count);
        ASSERT_EQ(delete_bitmap_pb.versions_size(), count);
        ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps_size(), count);

        for (int i = 0; i < count; i++) {
            ASSERT_EQ(delete_bitmap_pb.rowset_ids(i), rowset_id);
            ASSERT_EQ(delete_bitmap_pb.segment_ids(i), i);
            ASSERT_EQ(delete_bitmap_pb.versions(i), i + 1);
            ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(i), segment_delete_bitmaps[i]);
        }
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, GetDeleteBitmapWithRetryTest3) {
    auto meta_service = get_meta_service();
    SyncPoint::get_instance()->enable_processing();
    size_t index = 0;
    SyncPoint::get_instance()->set_call_back("get_delete_bitmap_err", [&](auto&& args) {
        auto* round = try_any_cast<int64_t*>(args[0]);
        LOG(INFO) << "GET_DELETE_BITMAP_CODE,index=" << index << ",round=" << *round;
        if (*round > 2 && ++index < 2) {
            *try_any_cast<TxnErrorCode*>(args[1]) = TxnErrorCode::TXN_TOO_OLD;
        }
    });

    // get delete bitmap update lock
    brpc::Controller cntl;
    GetDeleteBitmapUpdateLockRequest get_lock_req;
    GetDeleteBitmapUpdateLockResponse get_lock_res;
    get_lock_req.set_cloud_unique_id("test_cloud_unique_id");
    get_lock_req.set_table_id(100);
    get_lock_req.add_partition_ids(123);
    get_lock_req.set_expiration(5);
    get_lock_req.set_lock_id(888);
    get_lock_req.set_initiator(-1);
    meta_service->get_delete_bitmap_update_lock(
            reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &get_lock_req,
            &get_lock_res, nullptr);
    ASSERT_EQ(get_lock_res.status().code(), MetaServiceCode::OK);

    //first update new key
    UpdateDeleteBitmapRequest update_delete_bitmap_req;
    UpdateDeleteBitmapResponse update_delete_bitmap_res;
    update_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    update_delete_bitmap_req.set_table_id(100);
    update_delete_bitmap_req.set_partition_id(123);
    update_delete_bitmap_req.set_lock_id(888);
    update_delete_bitmap_req.set_initiator(-1);
    update_delete_bitmap_req.set_tablet_id(333);
    std::string rowset_id = "456";
    std::string segment_delete_bitmaps[5];
    for (int i = 0; i < 5; i++) {
        segment_delete_bitmaps[i] = generate_random_string(300 * 1000 * 3);
    }
    int count = 5;
    for (int i = 0; i < count; i++) {
        update_delete_bitmap_req.add_rowset_ids(rowset_id);
        update_delete_bitmap_req.add_segment_ids(i);
        update_delete_bitmap_req.add_versions(i + 1);
        update_delete_bitmap_req.add_segment_delete_bitmaps(segment_delete_bitmaps[i]);
    }
    meta_service->update_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                       &update_delete_bitmap_req, &update_delete_bitmap_res,
                                       nullptr);
    ASSERT_EQ(update_delete_bitmap_res.status().code(), MetaServiceCode::OK);

    GetDeleteBitmapRequest get_delete_bitmap_req;
    GetDeleteBitmapResponse get_delete_bitmap_res;
    get_delete_bitmap_req.set_cloud_unique_id("test_cloud_unique_id");
    get_delete_bitmap_req.set_tablet_id(333);

    get_delete_bitmap_req.add_rowset_ids(rowset_id);
    get_delete_bitmap_req.add_begin_versions(1);
    get_delete_bitmap_req.add_end_versions(count);

    meta_service->get_delete_bitmap(reinterpret_cast<google::protobuf::RpcController*>(&cntl),
                                    &get_delete_bitmap_req, &get_delete_bitmap_res, nullptr);
    ASSERT_EQ(get_delete_bitmap_res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(get_delete_bitmap_res.rowset_ids_size(), count);
    ASSERT_EQ(get_delete_bitmap_res.segment_ids_size(), count);
    ASSERT_EQ(get_delete_bitmap_res.versions_size(), count);
    ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps_size(), count);

    for (int i = 0; i < count; i++) {
        ASSERT_EQ(get_delete_bitmap_res.rowset_ids(i), rowset_id);
        ASSERT_EQ(get_delete_bitmap_res.segment_ids(i), i);
        ASSERT_EQ(get_delete_bitmap_res.versions(i), i + 1);
        ASSERT_EQ(get_delete_bitmap_res.segment_delete_bitmaps(i), segment_delete_bitmaps[i]);
    }
    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, GetVersion) {
    auto service = get_meta_service();

    int64_t table_id = 1;
    int64_t partition_id = 1;
    int64_t tablet_id = 1;

    // INVALID_ARGUMENT
    {
        brpc::Controller ctrl;
        GetVersionRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_table_id(table_id);
        req.set_partition_id(partition_id);

        GetVersionResponse resp;
        service->get_version(&ctrl, &req, &resp, nullptr);

        ASSERT_EQ(resp.status().code(), MetaServiceCode::INVALID_ARGUMENT)
                << " status is " << resp.status().DebugString();
    }

    {
        brpc::Controller ctrl;
        GetVersionRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(1);
        req.set_table_id(table_id);
        req.set_partition_id(partition_id);

        GetVersionResponse resp;
        service->get_version(&ctrl, &req, &resp, nullptr);

        ASSERT_EQ(resp.status().code(), MetaServiceCode::VERSION_NOT_FOUND)
                << " status is " << resp.status().DebugString();
    }

    create_tablet(service.get(), table_id, 1, partition_id, tablet_id);
    insert_rowset(service.get(), 1, "get_version_label_1", table_id, partition_id, tablet_id);

    {
        brpc::Controller ctrl;
        GetVersionRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(1);
        req.set_table_id(table_id);
        req.set_partition_id(partition_id);

        GetVersionResponse resp;
        service->get_version(&ctrl, &req, &resp, nullptr);

        ASSERT_EQ(resp.status().code(), MetaServiceCode::OK)
                << " status is " << resp.status().DebugString();
        ASSERT_EQ(resp.version(), 2);
    }
}

TEST(MetaServiceTest, BatchGetVersion) {
    struct TestCase {
        std::vector<int64_t> table_ids;
        std::vector<int64_t> partition_ids;
        std::vector<int64_t> expected_versions;
        std::vector<
                std::tuple<int64_t /*table_id*/, int64_t /*partition_id*/, int64_t /*tablet_id*/>>
                insert_rowsets;
    };

    // table ids: 2, 3, 4, 5
    // partition ids: 6, 7, 8, 9
    std::vector<TestCase> cases = {
            // all version are missing
            {{1, 2, 3, 4}, {6, 7, 8, 9}, {-1, -1, -1, -1}, {}},
            // update table 1, partition 6
            {{1, 2, 3, 4}, {6, 7, 8, 9}, {2, -1, -1, -1}, {{1, 6, 1}}},
            // update table 2, partition 6
            // update table 3, partition 7
            {{1, 2, 3, 4}, {6, 7, 8, 9}, {2, -1, 2, 2}, {{3, 8, 3}, {4, 9, 4}}},
            // update table 1, partition 7 twice
            {{1, 2, 3, 4}, {6, 7, 8, 9}, {2, 3, 2, 2}, {{2, 7, 2}, {2, 7, 2}}},
    };

    auto service = get_meta_service();
    create_tablet(service.get(), 1, 1, 6, 1);
    create_tablet(service.get(), 2, 1, 7, 2);
    create_tablet(service.get(), 3, 1, 8, 3);
    create_tablet(service.get(), 4, 1, 9, 4);

    size_t num_cases = cases.size();
    size_t label_index = 0;
    for (size_t i = 0; i < num_cases; ++i) {
        auto& [table_ids, partition_ids, expected_versions, insert_rowsets] = cases[i];
        for (auto [table_id, partition_id, tablet_id] : insert_rowsets) {
            LOG(INFO) << "insert rowset for table " << table_id << " partition " << partition_id
                      << " tablet_id " << tablet_id;
            insert_rowset(service.get(), 1, std::to_string(++label_index), table_id, partition_id,
                          tablet_id);
        }

        brpc::Controller ctrl;
        GetVersionRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(-1);
        req.set_table_id(-1);
        req.set_partition_id(-1);
        req.set_batch_mode(true);
        for (size_t i = 0; i < table_ids.size(); ++i) req.add_db_ids(1);
        std::copy(table_ids.begin(), table_ids.end(),
                  google::protobuf::RepeatedFieldBackInserter(req.mutable_table_ids()));
        std::copy(partition_ids.begin(), partition_ids.end(),
                  google::protobuf::RepeatedFieldBackInserter(req.mutable_partition_ids()));

        GetVersionResponse resp;
        service->get_version(&ctrl, &req, &resp, nullptr);

        ASSERT_EQ(resp.status().code(), MetaServiceCode::OK)
                << "case " << i << " status is " << resp.status().msg()
                << ", code=" << resp.status().code();

        std::vector<int64_t> versions(resp.versions().begin(), resp.versions().end());
        EXPECT_EQ(versions, expected_versions) << "case " << i;
    }

    // INVALID_ARGUMENT
    {
        brpc::Controller ctrl;
        GetVersionRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_batch_mode(true);
        GetVersionResponse resp;
        service->get_version(&ctrl, &req, &resp, nullptr);
        ASSERT_EQ(resp.status().code(), MetaServiceCode::INVALID_ARGUMENT)
                << " status is " << resp.status().msg() << ", code=" << resp.status().code();
    }
}

TEST(MetaServiceTest, BatchGetVersionFallback) {
    constexpr size_t N = 100;
    size_t i = 0;
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("batch_get_version_err", [&](auto&& args) {
        if (i++ == N / 10) {
            *try_any_cast<TxnErrorCode*>(args) = TxnErrorCode::TXN_TOO_OLD;
        }
    });

    sp->enable_processing();

    auto service = get_meta_service();
    for (int64_t i = 1; i <= N; ++i) {
        create_tablet(service.get(), 1, 1, i, i);
        insert_rowset(service.get(), 1, std::to_string(i), 1, i, i);
    }

    brpc::Controller ctrl;
    GetVersionRequest req;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_db_id(-1);
    req.set_table_id(-1);
    req.set_partition_id(-1);
    req.set_batch_mode(true);
    for (size_t i = 1; i <= N; ++i) {
        req.add_db_ids(1);
        req.add_table_ids(1);
        req.add_partition_ids(i);
    }

    GetVersionResponse resp;
    service->get_version(&ctrl, &req, &resp, nullptr);

    ASSERT_EQ(resp.status().code(), MetaServiceCode::OK)
            << "case " << i << " status is " << resp.status().msg()
            << ", code=" << resp.status().code();

    ASSERT_EQ(resp.versions_size(), N);
}

extern bool is_dropped_tablet(Transaction* txn, const std::string& instance_id, int64_t index_id,
                              int64_t partition_id);

TEST(MetaServiceTest, IsDroppedTablet) {
    auto meta_service = get_meta_service();
    std::string instance_id = "IsDroppedTablet";
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    meta_service = get_meta_service();
    auto reset_meta_service = [&meta_service] { meta_service = get_meta_service(); };

    constexpr int64_t index_id = 10002;
    constexpr int64_t partition_id = 10003;

    std::unique_ptr<Transaction> txn;
    RecycleIndexPB index_pb;
    auto index_key = recycle_index_key({instance_id, index_id});
    RecyclePartitionPB partition_pb;
    auto partition_key = recycle_partition_key({instance_id, partition_id});
    std::string val;
    // No recycle index and partition kv
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_FALSE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
    // Tablet in PREPARED index
    index_pb.set_state(RecycleIndexPB::PREPARED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_FALSE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
    // Tablet in DROPPED/RECYCLING index
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::DROPPED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_TRUE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::RECYCLING);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_TRUE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
    // Tablet in PREPARED partition
    reset_meta_service();
    partition_pb.set_state(RecyclePartitionPB::PREPARED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_FALSE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
    // Tablet in DROPPED/RECYCLING partition
    reset_meta_service();
    partition_pb.set_state(RecyclePartitionPB::DROPPED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_TRUE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
    reset_meta_service();
    partition_pb.set_state(RecyclePartitionPB::RECYCLING);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    EXPECT_TRUE(is_dropped_tablet(txn.get(), instance_id, index_id, partition_id));
}

TEST(MetaServiceTest, IndexRequest) {
    auto meta_service = get_meta_service();
    std::string instance_id = "IndexRequest";
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    auto reset_meta_service = [&meta_service] { meta_service = get_meta_service(); };
    constexpr int64_t table_id = 10001;
    constexpr int64_t index_id = 10002;
    constexpr int64_t partition_id = 10003;
    constexpr int64_t tablet_id = 10004;

    std::unique_ptr<Transaction> txn;
    doris::TabletMetaCloudPB tablet_pb;
    tablet_pb.set_table_id(table_id);
    tablet_pb.set_index_id(index_id);
    tablet_pb.set_partition_id(partition_id);
    tablet_pb.set_tablet_id(tablet_id);
    auto tablet_key = meta_tablet_key({instance_id, table_id, index_id, partition_id, tablet_id});
    auto tablet_val = tablet_pb.SerializeAsString();
    RecycleIndexPB index_pb;
    auto index_key = recycle_index_key({instance_id, index_id});
    int64_t val_int = 0;
    auto tbl_version_key = table_version_key({instance_id, 1, table_id});
    std::string val;

    // ------------Test prepare index------------
    brpc::Controller ctrl;
    IndexRequest req;
    IndexResponse res;
    meta_service->prepare_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    req.set_db_id(1);
    req.set_table_id(table_id);
    req.add_index_ids(index_id);
    req.set_is_new_table(true);
    // Last state UNKNOWN
    res.Clear();
    meta_service->prepare_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::PREPARED);
    // Last state PREPARED
    res.Clear();
    meta_service->prepare_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::PREPARED);
    // Last state DROPPED
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::DROPPED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->prepare_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::DROPPED);
    // Last state RECYCLING
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::RECYCLING);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->prepare_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::RECYCLING);
    // Last state UNKNOWN but tablet meta existed
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->remove(index_key);
    txn->put(tablet_key, tablet_val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->prepare_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // Prepare index should not init table version
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // ------------Test commit index------------
    reset_meta_service();
    req.Clear();
    meta_service->commit_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    req.set_db_id(1);
    req.set_table_id(table_id);
    req.add_index_ids(index_id);
    req.set_is_new_table(true);
    // Last state UNKNOWN
    res.Clear();
    meta_service->commit_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // Last state PREPARED
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::PREPARED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // First commit index should init table version
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state DROPPED
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::DROPPED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::DROPPED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // Last state RECYCLING
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::RECYCLING);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::RECYCLING);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // Last state UNKNOWN but tablet meta existed
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(tablet_key, tablet_val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // ------------Test drop index------------
    reset_meta_service();
    req.Clear();
    meta_service->drop_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    req.set_db_id(1);
    req.set_table_id(table_id);
    req.add_index_ids(index_id);
    req.set_is_new_table(true);
    // Last state UNKNOWN
    res.Clear();
    meta_service->drop_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::DROPPED);
    // Last state PREPARED
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::PREPARED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::DROPPED);
    // Last state DROPPED
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::DROPPED);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::DROPPED);
    // Last state RECYCLING
    reset_meta_service();
    index_pb.set_state(RecycleIndexPB::RECYCLING);
    val = index_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(index_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_index(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(index_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(index_pb.ParseFromString(val));
    ASSERT_EQ(index_pb.state(), RecycleIndexPB::RECYCLING);
    // Drop index should not init table version
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
}

TEST(MetaServiceTest, PartitionRequest) {
    auto meta_service = get_meta_service();
    std::string instance_id = "PartitionRequest";
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    auto reset_meta_service = [&meta_service] { meta_service = get_meta_service(); };
    constexpr int64_t table_id = 10001;
    constexpr int64_t index_id = 10002;
    constexpr int64_t partition_id = 10003;
    constexpr int64_t tablet_id = 10004;

    std::unique_ptr<Transaction> txn;
    doris::TabletMetaCloudPB tablet_pb;
    tablet_pb.set_table_id(table_id);
    tablet_pb.set_index_id(index_id);
    tablet_pb.set_partition_id(partition_id);
    tablet_pb.set_tablet_id(tablet_id);
    auto tablet_key = meta_tablet_key({instance_id, table_id, index_id, partition_id, tablet_id});
    auto tablet_val = tablet_pb.SerializeAsString();
    RecyclePartitionPB partition_pb;
    auto partition_key = recycle_partition_key({instance_id, partition_id});
    int64_t val_int = 0;
    auto tbl_version_key = table_version_key({instance_id, 1, table_id});
    std::string val;
    // ------------Test prepare partition------------
    brpc::Controller ctrl;
    PartitionRequest req;
    PartitionResponse res;
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    req.set_db_id(1);
    req.set_table_id(table_id);
    req.add_index_ids(index_id);
    req.add_partition_ids(partition_id);
    // Last state UNKNOWN
    res.Clear();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::PREPARED);
    // Prepare partition should not update table version
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state PREPARED
    res.Clear();
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::PREPARED);
    // Last state DROPPED
    reset_meta_service();
    partition_pb.set_state(RecyclePartitionPB::DROPPED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::DROPPED);
    // Last state RECYCLING
    reset_meta_service();
    partition_pb.set_state(RecyclePartitionPB::RECYCLING);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::RECYCLING);
    // Last state UNKNOWN but tablet meta existed
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->remove(partition_key);
    txn->put(tablet_key, tablet_val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // ------------Test commit partition------------
    reset_meta_service();
    req.Clear();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    req.set_db_id(1);
    req.set_table_id(table_id);
    req.add_index_ids(index_id);
    req.add_partition_ids(partition_id);
    // Last state UNKNOWN
    res.Clear();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // Last state PREPARED
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::PREPARED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    // Commit partition should update table version
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 2);
    // Last state DROPPED
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::DROPPED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::DROPPED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state RECYCLING
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::RECYCLING);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::RECYCLING);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state UNKNOWN but tablet meta existed
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(tablet_key, tablet_val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state UNKNOWN and tablet meta existed, but request has no index ids
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(tablet_key, tablet_val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    req.clear_index_ids();
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    req.add_index_ids(index_id);
    // ------------Test check partition-----------
    // Normal
    req.set_db_id(1);
    req.set_table_id(table_id + 1);
    req.add_index_ids(index_id + 1);
    req.add_partition_ids(partition_id + 1);
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    meta_service->commit_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    CheckKVRequest req_check;
    CheckKVResponse res_check;
    meta_service->check_kv(&ctrl, &req_check, &res_check, nullptr);
    ASSERT_EQ(res_check.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    res_check.Clear();
    req_check.set_op(CheckKVRequest::CREATE_PARTITION_AFTER_FE_COMMIT);
    CheckKeyInfos check_keys_pb;
    check_keys_pb.add_table_ids(table_id + 1);
    check_keys_pb.add_index_ids(index_id + 1);
    check_keys_pb.add_partition_ids(partition_id + 1);
    req_check.mutable_check_keys()->CopyFrom(check_keys_pb);
    meta_service->check_kv(&ctrl, &req_check, &res_check, nullptr);
    ASSERT_EQ(res_check.status().code(), MetaServiceCode::OK);
    res_check.Clear();
    // AbNomal not commit
    req.Clear();
    req.set_db_id(1);
    req.set_table_id(table_id + 2);
    req.add_index_ids(index_id + 2);
    req.add_partition_ids(partition_id + 2);
    meta_service->prepare_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    req_check.Clear();
    req_check.set_op(CheckKVRequest::CREATE_PARTITION_AFTER_FE_COMMIT);
    check_keys_pb.Clear();
    check_keys_pb.add_table_ids(table_id + 2);
    check_keys_pb.add_index_ids(index_id + 2);
    check_keys_pb.add_partition_ids(partition_id + 2);
    req_check.mutable_check_keys()->CopyFrom(check_keys_pb);
    meta_service->check_kv(&ctrl, &req_check, &res_check, nullptr);
    ASSERT_EQ(res_check.status().code(), MetaServiceCode::UNDEFINED_ERR);

    // ------------Test check index-----------
    // Normal
    IndexRequest req_index;
    IndexResponse res_index;
    req_index.set_db_id(1);
    req_index.set_table_id(table_id + 3);
    req_index.add_index_ids(index_id + 3);
    meta_service->prepare_index(&ctrl, &req_index, &res_index, nullptr);
    ASSERT_EQ(res_index.status().code(), MetaServiceCode::OK);
    meta_service->commit_index(&ctrl, &req_index, &res_index, nullptr);
    ASSERT_EQ(res_index.status().code(), MetaServiceCode::OK);
    req_check.Clear();
    res_check.Clear();
    req_check.set_op(CheckKVRequest::CREATE_INDEX_AFTER_FE_COMMIT);
    check_keys_pb.Clear();
    check_keys_pb.add_table_ids(table_id + 3);
    check_keys_pb.add_index_ids(index_id + 3);
    req_check.mutable_check_keys()->CopyFrom(check_keys_pb);
    meta_service->check_kv(&ctrl, &req_check, &res_check, nullptr);
    ASSERT_EQ(res_check.status().code(), MetaServiceCode::OK);
    res_check.Clear();

    // ------------Test drop partition------------
    reset_meta_service();
    req.Clear();
    meta_service->drop_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    req.set_db_id(1);
    req.set_table_id(table_id);
    req.add_index_ids(index_id);
    req.add_partition_ids(partition_id);
    req.set_need_update_table_version(true);
    // Last state UNKNOWN
    res.Clear();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    meta_service->drop_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::DROPPED);
    // Drop partition should update table version
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 2);
    // Last state PREPARED
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::PREPARED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::DROPPED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 2);
    // Last state PREPARED but drop an empty partition
    req.set_need_update_table_version(false);
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::PREPARED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::DROPPED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state DROPPED
    reset_meta_service();
    req.set_need_update_table_version(true);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::DROPPED);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::DROPPED);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
    // Last state RECYCLING
    reset_meta_service();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->atomic_add(tbl_version_key, 1);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    partition_pb.set_state(RecyclePartitionPB::RECYCLING);
    val = partition_pb.SerializeAsString();
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    txn->put(partition_key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    res.Clear();
    meta_service->drop_partition(&ctrl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(partition_key, &val), TxnErrorCode::TXN_OK);
    ASSERT_TRUE(partition_pb.ParseFromString(val));
    ASSERT_EQ(partition_pb.state(), RecyclePartitionPB::RECYCLING);
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    ASSERT_EQ(txn->get(tbl_version_key, &val), TxnErrorCode::TXN_OK);
    val_int = *reinterpret_cast<const int64_t*>(val.data());
    ASSERT_EQ(val_int, 1);
}

TEST(MetaServiceTxnStoreRetryableTest, MockGetVersion) {
    size_t index = 0;
    SyncPoint::get_instance()->set_call_back("get_version_code", [&](auto&& args) {
        LOG(INFO) << "GET_VERSION_CODE";
        if (++index < 2) {
            *doris::try_any_cast<MetaServiceCode*>(args[0]) =
                    MetaServiceCode::KV_TXN_STORE_GET_RETRYABLE;
        }
    });
    SyncPoint::get_instance()->enable_processing();

    auto service = get_meta_service();
    create_tablet(service.get(), 1, 1, 1, 1);
    insert_rowset(service.get(), 1, std::to_string(1), 1, 1, 1);

    brpc::Controller ctrl;
    GetVersionRequest req;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_db_id(1);
    req.set_table_id(1);
    req.set_partition_id(1);

    GetVersionResponse resp;
    service->get_version(&ctrl, &req, &resp, nullptr);

    ASSERT_EQ(resp.status().code(), MetaServiceCode::OK)
            << " status is " << resp.status().msg() << ", code=" << resp.status().code();
    EXPECT_EQ(resp.version(), 2);
    EXPECT_GE(index, 2);

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTxnStoreRetryableTest, DoNotReturnRetryableCode) {
    SyncPoint::get_instance()->set_call_back("get_version_code", [&](auto&& args) {
        *doris::try_any_cast<MetaServiceCode*>(args[0]) =
                MetaServiceCode::KV_TXN_STORE_GET_RETRYABLE;
    });
    SyncPoint::get_instance()->enable_processing();
    int32_t retry_times = config::txn_store_retry_times;
    config::txn_store_retry_times = 3;

    auto service = get_meta_service();
    create_tablet(service.get(), 1, 1, 1, 1);
    insert_rowset(service.get(), 1, std::to_string(1), 1, 1, 1);

    brpc::Controller ctrl;
    GetVersionRequest req;
    req.set_cloud_unique_id("test_cloud_unique_id");
    req.set_db_id(1);
    req.set_table_id(1);
    req.set_partition_id(1);

    GetVersionResponse resp;
    service->get_version(&ctrl, &req, &resp, nullptr);

    ASSERT_EQ(resp.status().code(), MetaServiceCode::KV_TXN_GET_ERR)
            << " status is " << resp.status().msg() << ", code=" << resp.status().code();

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
    config::txn_store_retry_times = retry_times;
}

TEST(MetaServiceTest, GetClusterStatusTest) {
    auto meta_service = get_meta_service();

    // add cluster first
    InstanceKeyInfo key_info {mock_instance};
    std::string key;
    std::string val;
    instance_key(key_info, &key);

    InstanceInfoPB instance;
    instance.set_instance_id(mock_instance);
    ClusterPB c1;
    c1.set_type(ClusterPB::COMPUTE);
    c1.set_cluster_name(mock_cluster_name);
    c1.set_cluster_id(mock_cluster_id);
    c1.add_mysql_user_name()->append("m1");
    c1.set_cluster_status(ClusterStatus::NORMAL);
    ClusterPB c2;
    c2.set_type(ClusterPB::COMPUTE);
    c2.set_cluster_name(mock_cluster_name + "2");
    c2.set_cluster_id(mock_cluster_id + "2");
    c2.add_mysql_user_name()->append("m2");
    c2.set_cluster_status(ClusterStatus::SUSPENDED);
    ClusterPB c3;
    c3.set_type(ClusterPB::COMPUTE);
    c3.set_cluster_name(mock_cluster_name + "3");
    c3.set_cluster_id(mock_cluster_id + "3");
    c3.add_mysql_user_name()->append("m3");
    c3.set_cluster_status(ClusterStatus::TO_RESUME);
    instance.add_clusters()->CopyFrom(c1);
    instance.add_clusters()->CopyFrom(c2);
    instance.add_clusters()->CopyFrom(c3);
    val = instance.SerializeAsString();

    std::unique_ptr<Transaction> txn;
    std::string get_val;
    TxnErrorCode err = meta_service->txn_kv()->create_txn(&txn);
    ASSERT_EQ(err, TxnErrorCode::TXN_OK);
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    // case: get all cluster
    {
        brpc::Controller cntl;
        GetClusterStatusRequest req;
        req.add_instance_ids(mock_instance);
        GetClusterStatusResponse res;
        meta_service->get_cluster_status(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.details().at(0).clusters().size(), 3);
    }

    // get normal cluster
    {
        brpc::Controller cntl;
        GetClusterStatusRequest req;
        req.add_instance_ids(mock_instance);
        req.set_status(NORMAL);
        GetClusterStatusResponse res;
        meta_service->get_cluster_status(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        ASSERT_EQ(res.details().at(0).clusters().size(), 1);
    }
}

TEST(MetaServiceTest, DecryptInfoTest) {
    auto meta_service = get_meta_service();
    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("decrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* key = try_any_cast<std::string*>(args[0]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* ret = try_any_cast<int*>(args[1]);
        *ret = 0;
    });
    InstanceInfoPB instance;

    EncryptionInfoPB encryption_info;
    encryption_info.set_encryption_method("AES_256_ECB");
    encryption_info.set_key_id(1);

    std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
    std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";
    ObjectStoreInfoPB obj_info;
    obj_info.mutable_encryption_info()->CopyFrom(encryption_info);
    obj_info.set_ak("akak1");
    obj_info.set_sk(cipher_sk);
    instance.add_obj_info()->CopyFrom(obj_info);

    RamUserPB ram_user;
    ram_user.set_ak("akak2");
    ram_user.set_sk(cipher_sk);
    ram_user.mutable_encryption_info()->CopyFrom(encryption_info);
    instance.mutable_ram_user()->CopyFrom(ram_user);

    StagePB stage;
    stage.mutable_obj_info()->CopyFrom(obj_info);
    instance.add_stages()->CopyFrom(stage);

    auto checkcheck = [&](const InstanceInfoPB& instance) {
        ASSERT_EQ(instance.obj_info(0).ak(), "akak1");
        ASSERT_EQ(instance.obj_info(0).sk(), plain_sk);

        ASSERT_EQ(instance.ram_user().ak(), "akak2");
        ASSERT_EQ(instance.ram_user().sk(), plain_sk);

        ASSERT_EQ(instance.stages(0).obj_info().ak(), "akak1");
        ASSERT_EQ(instance.stages(0).obj_info().sk(), plain_sk);
    };

    std::string instance_id = "i1";
    MetaServiceCode code;
    std::string msg;
    // No system_meta_service_arn_info_key
    {
        std::unique_ptr<Transaction> txn0;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn0), TxnErrorCode::TXN_OK);
        std::shared_ptr<Transaction> txn(txn0.release());
        InstanceInfoPB decrypt_instance;
        decrypt_instance.CopyFrom(instance);
        int ret = decrypt_instance_info(decrypt_instance, instance_id, code, msg, txn);
        ASSERT_EQ(ret, 0);
        checkcheck(decrypt_instance);
        ASSERT_EQ(decrypt_instance.iam_user().user_id(), config::arn_id);
        ASSERT_EQ(decrypt_instance.iam_user().external_id(), instance_id);
        ASSERT_EQ(decrypt_instance.iam_user().ak(), config::arn_ak);
        ASSERT_EQ(decrypt_instance.iam_user().sk(), config::arn_sk);
    }

    // With system_meta_service_arn_info_key
    {
        std::string key = system_meta_service_arn_info_key();
        std::string val;
        std::unique_ptr<Transaction> txn2;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn2), TxnErrorCode::TXN_OK);
        RamUserPB iam_user;
        iam_user.set_user_id("1234");
        iam_user.set_ak("aksk3");
        iam_user.set_sk(cipher_sk);
        iam_user.set_external_id(instance_id);
        iam_user.mutable_encryption_info()->CopyFrom(encryption_info);
        val = iam_user.SerializeAsString();
        txn2->put(key, val);
        ASSERT_EQ(txn2->commit(), TxnErrorCode::TXN_OK);
        std::unique_ptr<Transaction> txn0;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn0), TxnErrorCode::TXN_OK);
        std::shared_ptr<Transaction> txn(txn0.release());
        InstanceInfoPB decrypt_instance;
        decrypt_instance.CopyFrom(instance);
        int ret = decrypt_instance_info(decrypt_instance, instance_id, code, msg, txn);
        ASSERT_EQ(ret, 0);
        checkcheck(decrypt_instance);
        ASSERT_EQ(decrypt_instance.iam_user().user_id(), "1234");
        ASSERT_EQ(decrypt_instance.iam_user().external_id(), instance_id);
        ASSERT_EQ(decrypt_instance.iam_user().ak(), "aksk3");
        ASSERT_EQ(decrypt_instance.iam_user().sk(), plain_sk);
    }
    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, LegacyUpdateAkSkTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();

    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("ak");
    obj_info.set_sk("sk");
    InstanceInfoPB instance;
    instance.add_obj_info()->CopyFrom(obj_info);
    val = instance.SerializeAsString();
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
    std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";

    // update failed
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::LEGACY_UPDATE_AK_SK);
        req.mutable_obj()->set_id("2");
        req.mutable_obj()->set_ak("new_ak");
        req.mutable_obj()->set_sk(plain_sk);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.obj_info(0).id(), "1");
        ASSERT_EQ(instance.obj_info(0).ak(), "ak");
        ASSERT_EQ(instance.obj_info(0).sk(), "sk");
    }

    // update successful
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::LEGACY_UPDATE_AK_SK);
        req.mutable_obj()->set_id("1");
        req.mutable_obj()->set_ak("new_ak");
        req.mutable_obj()->set_sk(plain_sk);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.obj_info(0).id(), "1");
        ASSERT_EQ(instance.obj_info(0).ak(), "new_ak");
        ASSERT_EQ(instance.obj_info(0).sk(), cipher_sk);
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

namespace detail {
bool normalize_hdfs_prefix(std::string& prefix);
bool normalize_hdfs_fs_name(std::string& fs_name);
} // namespace detail

TEST(MetaServiceTest, NormalizeHdfsConfTest) {
    using namespace detail;
    std::string prefix = "hdfs://127.0.0.1:8020/test";
    EXPECT_FALSE(normalize_hdfs_prefix(prefix));
    prefix = "test";
    EXPECT_TRUE(normalize_hdfs_prefix(prefix));
    EXPECT_EQ(prefix, "test");
    prefix = "   test ";
    EXPECT_TRUE(normalize_hdfs_prefix(prefix));
    EXPECT_EQ(prefix, "test");
    prefix = "  /test// ";
    EXPECT_TRUE(normalize_hdfs_prefix(prefix));
    EXPECT_EQ(prefix, "test");
    prefix = "/";
    EXPECT_TRUE(normalize_hdfs_prefix(prefix));
    EXPECT_EQ(prefix, "");

    std::string fs_name;
    EXPECT_FALSE(normalize_hdfs_fs_name(prefix));
    fs_name = " hdfs://127.0.0.1:8020/  ";
    EXPECT_TRUE(normalize_hdfs_fs_name(fs_name));
    EXPECT_EQ(fs_name, "hdfs://127.0.0.1:8020");
}

TEST(MetaServiceTest, AddObjInfoTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();

    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    InstanceInfoPB instance;
    val = instance.SerializeAsString();
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // update failed
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_OBJ_INFO);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().msg();
    }

    // update successful
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_OBJ_INFO);
        auto sp = SyncPoint::get_instance();
        sp->set_call_back("create_object_info_with_encrypt", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
        });
        sp->enable_processing();

        ObjectStoreInfoPB obj_info;
        obj_info.set_ak("ak");
        obj_info.set_sk("sk");
        obj_info.set_bucket("bucket");
        obj_info.set_prefix("prefix");
        obj_info.set_endpoint("endpoint");
        obj_info.set_region("region");
        obj_info.set_provider(ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_COS);
        obj_info.set_external_endpoint("external");
        req.mutable_obj()->MergeFrom(obj_info);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);
        const auto& obj = instance.obj_info().at(0);
        ASSERT_EQ(obj.id(), "1");

        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, AddHdfsInfoTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("ak");
    obj_info.set_sk("sk");
    InstanceInfoPB instance;
    instance.add_obj_info()->CopyFrom(obj_info);
    val = instance.SerializeAsString();
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // update failed
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().msg();
    }

    // update successful
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info");
        HdfsVaultInfo params;

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        // Invalid fs name
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().msg();
        req.mutable_vault()->mutable_hdfs_info()->mutable_build_conf()->set_fs_name(
                "hdfs://ip:port");
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(*(instance.resource_ids().begin()), "2");
        ASSERT_EQ(*(instance.storage_vault_names().begin()), "test_alter_add_hdfs_info");
    }

    // update failed because duplicate name
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info");
        HdfsVaultInfo params;
        params.mutable_build_conf()->set_fs_name("hdfs://ip:port");

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED) << res.status().msg();
    }

    // to test if the vault id is expected
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info_1");
        HdfsVaultInfo params;
        params.mutable_build_conf()->set_fs_name("hdfs://ip:port");

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(*(instance.resource_ids().begin() + 1), "3");
        ASSERT_EQ(*(instance.storage_vault_names().begin() + 1), "test_alter_add_hdfs_info_1");
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, DropHdfsInfoTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("ak");
    obj_info.set_sk("sk");
    StorageVaultPB vault;
    vault.set_name("test_hdfs_vault");
    vault.set_id("2");
    InstanceInfoPB instance;
    instance.add_obj_info()->CopyFrom(obj_info);
    instance.add_storage_vault_names(vault.name());
    instance.add_resource_ids(vault.id());
    val = instance.SerializeAsString();
    txn->put(key, val);
    txn->put(storage_vault_key({instance.instance_id(), "2"}), vault.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    txn = nullptr;

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // update failed because has no storage vault set
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::DROP_HDFS_INFO);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().msg();
    }

    // update failed because vault name does not exist
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::DROP_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_hdfs_vault_not_found");
        HdfsVaultInfo params;

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::STORAGE_VAULT_NOT_FOUND)
                << res.status().msg();
    }

    // update successfully
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::DROP_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_hdfs_vault");
        HdfsVaultInfo params;

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.resource_ids().size(), 0);
        ASSERT_EQ(instance.storage_vault_names().size(), 0);
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        // To test we can not read the storage vault anymore
        std::string vault_key = storage_vault_key({instance.instance_id(), "2"});
        std::string vault_value;
        auto code = txn->get(vault_key, &vault_value);
        ASSERT_TRUE(code != TxnErrorCode::TXN_OK);
    }

    {
        // Try to add one new hdfs info and then check the vault id is expected
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info");
        HdfsVaultInfo params;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        params.mutable_build_conf()->MergeFrom(conf);

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(*(instance.resource_ids().begin()), "2");
        ASSERT_EQ(*(instance.storage_vault_names().begin()), "test_alter_add_hdfs_info");
    }

    // Add two more vaults
    {
        // Try to add one new hdfs info and then check the vault id is expected
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info_1");
        HdfsVaultInfo params;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        params.mutable_build_conf()->MergeFrom(conf);

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.resource_ids().at(1), "3");
        ASSERT_EQ(instance.storage_vault_names().at(1), "test_alter_add_hdfs_info_1");
    }

    {
        // Try to add one new hdfs info and then check the vault id is expected
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info_2");
        HdfsVaultInfo params;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        params.mutable_build_conf()->MergeFrom(conf);

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.resource_ids().at(2), "4");
        ASSERT_EQ(instance.storage_vault_names().at(2), "test_alter_add_hdfs_info_2");
    }

    // Remove one vault among three vaults
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::DROP_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info_1");
        HdfsVaultInfo params;

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.resource_ids().size(), 2);
        ASSERT_EQ(instance.storage_vault_names().size(), 2);
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        // To test we can not read the storage vault anymore
        std::string vault_key = storage_vault_key({instance.instance_id(), "3"});
        std::string vault_value;
        auto code = txn->get(vault_key, &vault_value);
        ASSERT_TRUE(code != TxnErrorCode::TXN_OK);
        ASSERT_EQ(2, instance.resource_ids().size());
        ASSERT_EQ(2, instance.storage_vault_names().size());
        ASSERT_EQ(instance.resource_ids().at(0), "2");
        ASSERT_EQ(instance.storage_vault_names().at(0), "test_alter_add_hdfs_info");
        ASSERT_EQ(instance.resource_ids().at(1), "4");
        ASSERT_EQ(instance.storage_vault_names().at(1), "test_alter_add_hdfs_info_2");
    }

    {
        // Try to add one new hdfs info and then check the vault id is expected
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("test_alter_add_hdfs_info_3");
        HdfsVaultInfo params;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        params.mutable_build_conf()->MergeFrom(conf);

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.resource_ids().at(2), "5");
        ASSERT_EQ(instance.storage_vault_names().at(2), "test_alter_add_hdfs_info_3");
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, GetDefaultVaultTest) {
    auto meta_service = get_meta_service();

    auto get_test_instance = [&](InstanceInfoPB& i, std::string instance_id) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {std::move(instance_id)};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // case: normal create instance with hdfs info
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        std::string instance_id = "test_instance_with_hdfs_info";
        req.set_instance_id(instance_id);
        req.set_user_id("test_user");
        req.set_name("test_name");
        HdfsVaultInfo hdfs;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        conf.set_user("test_user");
        hdfs.mutable_build_conf()->CopyFrom(conf);
        StorageVaultPB vault;
        vault.mutable_hdfs_info()->CopyFrom(hdfs);
        req.mutable_vault()->CopyFrom(vault);

        auto sp = SyncPoint::get_instance();
        sp->set_call_back("create_object_info_with_encrypt", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        InstanceInfoPB i;
        get_test_instance(i, instance_id);
        // It wouldn't be set
        ASSERT_EQ(i.default_storage_vault_id(), "");
        ASSERT_EQ(i.default_storage_vault_name(), "");
        ASSERT_EQ(i.resource_ids().at(0), "1");
        ASSERT_EQ(i.storage_vault_names().at(0), "built_in_storage_vault");
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    // case: normal create instance with obj info
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        std::string instance_id = "test_instance_with_s3_info";
        req.set_instance_id(instance_id);
        req.set_user_id("test_user");
        req.set_name("test_name");
        InstanceInfoPB instance;

        EncryptionInfoPB encryption_info;
        encryption_info.set_encryption_method("AES_256_ECB");
        encryption_info.set_key_id(1);

        std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
        std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";
        ObjectStoreInfoPB obj_info;
        obj_info.mutable_encryption_info()->CopyFrom(encryption_info);
        obj_info.set_ak("akak1");
        obj_info.set_sk(cipher_sk);
        obj_info.set_endpoint("selectdb");
        obj_info.set_external_endpoint("velodb");
        obj_info.set_bucket("gavin");
        obj_info.set_region("American");
        obj_info.set_provider(ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        instance.add_obj_info()->CopyFrom(obj_info);
        req.mutable_obj_info()->CopyFrom(obj_info);

        auto sp = SyncPoint::get_instance();
        sp->set_call_back("create_object_info_with_encrypt", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* code = try_any_cast<MetaServiceCode*>(args[1]);
            *code = MetaServiceCode::OK;
            auto* msg = try_any_cast<std::string*>(args[2]);
            *msg = "";
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        InstanceInfoPB i;
        get_test_instance(i, instance_id);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }
}

TEST(MetaServiceTest, SetDefaultVaultTest) {
    auto meta_service = get_meta_service();
    std::string instance_id = "test_instance";

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {instance_id};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    brpc::Controller cntl;
    CreateInstanceRequest req;
    req.set_instance_id(instance_id);
    req.set_user_id("test_user");
    req.set_name("test_name");
    HdfsVaultInfo hdfs;
    HdfsBuildConf conf;
    conf.set_fs_name("hdfs://127.0.0.1:8020");
    conf.set_user("test_user");
    hdfs.mutable_build_conf()->CopyFrom(conf);
    StorageVaultPB vault;
    vault.mutable_hdfs_info()->CopyFrom(hdfs);
    req.mutable_vault()->CopyFrom(vault);

    auto sp = SyncPoint::get_instance();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "test";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    sp->enable_processing();
    CreateInstanceResponse res;
    meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                  &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    InstanceInfoPB i;
    get_test_instance(i);
    ASSERT_EQ(i.default_storage_vault_id(), "");
    ASSERT_EQ(i.default_storage_vault_name(), "");
    ASSERT_EQ(i.resource_ids().at(0), "1");
    ASSERT_EQ(i.storage_vault_names().at(0), "built_in_storage_vault");

    for (size_t i = 0; i < 20; i++) {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        auto name = fmt::format("test_alter_add_hdfs_info_{}", i);
        hdfs.set_name(name);
        HdfsVaultInfo params;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        params.mutable_build_conf()->MergeFrom(conf);

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        AlterObjStoreInfoRequest set_default_req;
        set_default_req.set_cloud_unique_id("test_cloud_unique_id");
        set_default_req.set_op(AlterObjStoreInfoRequest::SET_DEFAULT_VAULT);
        set_default_req.mutable_vault()->CopyFrom(hdfs);
        AlterObjStoreInfoResponse set_default_res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &set_default_req,
                &set_default_res, nullptr);
        ASSERT_EQ(set_default_res.status().code(), MetaServiceCode::OK)
                << set_default_res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(std::to_string(i + 2), instance.default_storage_vault_id());
    }

    // Try to set one non-existent vault as default
    {
        StorageVaultPB hdfs;
        auto name = "test_alter_add_hdfs_info_no";
        hdfs.set_name(name);
        HdfsVaultInfo params;

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        AlterObjStoreInfoRequest set_default_req;
        set_default_req.set_cloud_unique_id("test_cloud_unique_id");
        set_default_req.set_op(AlterObjStoreInfoRequest::SET_DEFAULT_VAULT);
        set_default_req.mutable_vault()->CopyFrom(hdfs);
        AlterObjStoreInfoResponse set_default_res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &set_default_req,
                &set_default_res, nullptr);
        ASSERT_NE(set_default_res.status().code(), MetaServiceCode::OK)
                << set_default_res.status().msg();
    }

    sp->clear_all_call_backs();
    sp->clear_trace();
    sp->disable_processing();
}

TEST(MetaServiceTest, GetObjStoreInfoTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("ak");
    obj_info.set_sk("sk");
    StorageVaultPB vault;
    vault.set_name("test_hdfs_vault");
    vault.set_id("2");
    InstanceInfoPB instance;
    instance.add_obj_info()->CopyFrom(obj_info);
    instance.add_storage_vault_names(vault.name());
    instance.add_resource_ids(vault.id());
    instance.set_instance_id("GetObjStoreInfoTestInstance");
    val = instance.SerializeAsString();
    txn->put(key, val);
    txn->put(storage_vault_key({instance.instance_id(), "2"}), vault.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    txn = nullptr;

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    for (size_t i = 0; i < 20; i++) {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        auto name = fmt::format("test_alter_add_hdfs_info_{}", i);
        hdfs.set_name(name);
        HdfsVaultInfo params;
        HdfsBuildConf conf;
        conf.set_fs_name("hdfs://127.0.0.1:8020");
        params.mutable_build_conf()->MergeFrom(conf);

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_TRUE(std::find_if(instance.resource_ids().begin(), instance.resource_ids().end(),
                                 [&](const auto& id) { return id == std::to_string(i + 3); }) !=
                    instance.resource_ids().end());
        ASSERT_TRUE(std::find_if(instance.storage_vault_names().begin(),
                                 instance.storage_vault_names().end(), [&](const auto& vault_name) {
                                     return name == vault_name;
                                 }) != instance.storage_vault_names().end());
    }

    {
        brpc::Controller cntl;
        GetObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        GetObjStoreInfoResponse res;
        meta_service->get_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        ASSERT_EQ(res.storage_vault().size(), 21);
        const auto& vaults = res.storage_vault();
        for (size_t i = 0; i < 20; i++) {
            auto id = std::to_string(i + 3);
            auto name = fmt::format("test_alter_add_hdfs_info_{}", i);
            ASSERT_TRUE(std::find_if(vaults.begin(), vaults.end(), [&](const auto& vault) {
                            return id == vault.id();
                        }) != vaults.end());
            ASSERT_TRUE(std::find_if(vaults.begin(), vaults.end(), [&](const auto& vault) {
                            return name == vault.name();
                        }) != vaults.end());
        }
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, CreateVersionedTablet) {
    auto meta_service = get_meta_service(false);

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::string instance_id = "test_instance";
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key;
        std::string val;
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);

        InstanceInfoPB instance;
        instance.set_multi_version_status(MultiVersionStatus::MULTI_VERSION_WRITE_ONLY);
        val = instance.SerializeAsString();
        txn->put(key, val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        meta_service->resource_mgr()->refresh_instance(instance_id);
    }

    int64_t db_id = 1, table_id = 2, index_id = 3, partition_id = 4, tablet_id = 5;

    {
        brpc::Controller cntl;
        CreateTabletsRequest req;
        CreateTabletsResponse res;
        req.set_cloud_unique_id(fmt::format("1:{}:1", instance_id));
        req.set_db_id(db_id);
        add_tablet(req, table_id, index_id, partition_id, tablet_id);
        meta_service->create_tablets(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << tablet_id;
    }

    Versionstamp commit_versionstamp;
    {
        // verify versioned tablet meta is written
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        std::string key = versioned::meta_tablet_key({instance_id, tablet_id});
        ASSERT_EQ(versioned_get(txn.get(), key, &commit_versionstamp, &val), TxnErrorCode::TXN_OK)
                << hex(key);
        TabletMetaCloudPB versioned_tablet_meta;
        versioned_tablet_meta.ParseFromString(val);
        ASSERT_EQ(versioned_tablet_meta.table_id(), table_id);
        ASSERT_EQ(versioned_tablet_meta.index_id(), index_id)
                << versioned_tablet_meta.ShortDebugString();
        ASSERT_EQ(versioned_tablet_meta.partition_id(), partition_id);
        ASSERT_EQ(versioned_tablet_meta.tablet_id(), tablet_id);
    }

    {
        // verify versioned tablet index/inverted index is written
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key = versioned::tablet_index_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        TabletIndexPB tablet_index;
        tablet_index.ParseFromString(val);
        ASSERT_EQ(tablet_index.db_id(), db_id);
        ASSERT_EQ(tablet_index.table_id(), table_id);
        ASSERT_EQ(tablet_index.index_id(), index_id);
        ASSERT_EQ(tablet_index.partition_id(), partition_id);
        ASSERT_EQ(tablet_index.tablet_id(), tablet_id);

        key = versioned::tablet_inverted_index_key(
                {instance_id, db_id, table_id, index_id, partition_id, tablet_id});
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
    }

    {
        // verify the first versioned rowset meta is written
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        int64_t end_version = 1; // from add_tablet
        std::string key = versioned::meta_rowset_load_key({instance_id, tablet_id, end_version});
        RowsetMetaCloudPB rowset_meta;
        Versionstamp versionstamp;
        ASSERT_EQ(versioned::document_get(txn.get(), key, &rowset_meta, &versionstamp),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(versionstamp, commit_versionstamp);
    }

    {
        // verify the tablet load stats is written
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key = versioned::tablet_load_stats_key({instance_id, tablet_id});
        TabletStatsPB load_stats;
        Versionstamp versionstamp;
        ASSERT_EQ(versioned::document_get(txn.get(), key, &load_stats, &versionstamp),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(versionstamp, commit_versionstamp);
    }

    {
        // verify the tablet compact stats is written
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key = versioned::tablet_compact_stats_key({instance_id, tablet_id});
        TabletStatsPB compact_stats;
        Versionstamp versionstamp;
        ASSERT_EQ(versioned::document_get(txn.get(), key, &compact_stats, &versionstamp),
                  TxnErrorCode::TXN_OK);
        ASSERT_EQ(versionstamp, commit_versionstamp);
        EXPECT_EQ(compact_stats.cumulative_point(), 2);
    }

    {
        // verify the tablet schema is written
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key = versioned::meta_schema_key({instance_id, index_id, 0});
        doris::TabletSchemaCloudPB schema;
        ASSERT_EQ(document_get(txn.get(), key, &schema), TxnErrorCode::TXN_OK);
        EXPECT_EQ(schema.schema_version(), 0);
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, CreateTabletsVaultsTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    InstanceInfoPB instance;
    instance.set_enable_storage_vault(true);
    val = instance.SerializeAsString();
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // tablet_metas_size is 0
    {
        CreateTabletsRequest request;
        request.set_cloud_unique_id("test_cloud_unique_id");

        brpc::Controller cntl;
        CreateTabletsResponse response;
        meta_service->create_tablets(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &request, &response, nullptr);
        ASSERT_EQ(response.status().code(), MetaServiceCode::INVALID_ARGUMENT)
                << response.status().msg();
    }

    // try to use default
    {
        CreateTabletsRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_storage_vault_name("");
        req.add_tablet_metas();

        brpc::Controller cntl;
        CreateTabletsResponse res;
        meta_service->create_tablets(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        // failed because no default
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().msg();
    }

    // Create One Hdfs info as built_in vault
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_HDFS_INFO);
        StorageVaultPB hdfs;
        hdfs.set_name("built_in_storage_vault");
        HdfsVaultInfo params;
        params.mutable_build_conf()->set_fs_name("hdfs://ip:port");

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        req.mutable_vault()->CopyFrom(hdfs);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB i;
        get_test_instance(i);
        ASSERT_EQ(i.default_storage_vault_id(), "");
        ASSERT_EQ(i.default_storage_vault_name(), "");
        ASSERT_EQ(i.resource_ids().at(0), "1");
        ASSERT_EQ(i.storage_vault_names().at(0), "built_in_storage_vault");
    }

    // Try to set built_in_storage_vault vault as default
    {
        StorageVaultPB hdfs;
        std::string name = "built_in_storage_vault";
        hdfs.set_name(std::move(name));
        HdfsVaultInfo params;

        hdfs.mutable_hdfs_info()->CopyFrom(params);
        AlterObjStoreInfoRequest set_default_req;
        set_default_req.set_cloud_unique_id("test_cloud_unique_id");
        set_default_req.set_op(AlterObjStoreInfoRequest::SET_DEFAULT_VAULT);
        set_default_req.mutable_vault()->CopyFrom(hdfs);
        AlterObjStoreInfoResponse set_default_res;
        brpc::Controller cntl;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &set_default_req,
                &set_default_res, nullptr);
        ASSERT_EQ(set_default_res.status().code(), MetaServiceCode::OK)
                << set_default_res.status().msg();
    }

    // try to use default vault
    {
        CreateTabletsRequest req;
        req.set_db_id(1);
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_storage_vault_name("");
        req.add_tablet_metas();

        auto sp = SyncPoint::get_instance();
        sp->set_call_back("create_tablets",
                          [](auto&& args) { *try_any_cast<bool*>(args.back()) = true; });
        sp->enable_processing();

        brpc::Controller cntl;
        CreateTabletsResponse res;
        meta_service->create_tablets(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        ASSERT_EQ(res.storage_vault_id(), "1");
        ASSERT_EQ(res.storage_vault_name(), "built_in_storage_vault");

        sp->clear_call_back("create_tablets");
    }

    // try to use one non-existent vault
    {
        CreateTabletsRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_storage_vault_name("non-existent");
        req.add_tablet_metas();

        auto sp = SyncPoint::get_instance();
        SyncPoint::CallbackGuard guard;
        sp->set_call_back(
                "create_tablets", [](auto&& args) { *try_any_cast<bool*>(args.back()) = true; },
                &guard);
        sp->enable_processing();

        brpc::Controller cntl;
        CreateTabletsResponse res;
        meta_service->create_tablets(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().msg();
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, UpdateAkSkTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
    std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";

    auto update = [&](bool with_user_id, bool with_wrong_user_id) {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string key;
        std::string val;
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);

        ObjectStoreInfoPB obj_info;
        if (with_user_id) {
            obj_info.set_user_id("111");
        }
        obj_info.set_ak("ak");
        obj_info.set_sk("sk");
        InstanceInfoPB instance;
        instance.add_obj_info()->CopyFrom(obj_info);
        val = instance.SerializeAsString();
        txn->put(key, val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        UpdateAkSkRequest req;
        req.set_instance_id("test_instance");
        RamUserPB ram_user;
        if (with_wrong_user_id) {
            ram_user.set_user_id("222");
        } else {
            ram_user.set_user_id("111");
        }
        ram_user.set_ak("new_ak");
        ram_user.set_sk(plain_sk);
        req.add_internal_bucket_user()->CopyFrom(ram_user);

        brpc::Controller cntl;
        UpdateAkSkResponse res;
        meta_service->update_ak_sk(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &req, &res, nullptr);
        if (with_wrong_user_id) {
            ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        } else {
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            InstanceInfoPB update_instance;
            get_test_instance(update_instance);
            ASSERT_EQ(update_instance.obj_info(0).user_id(), "111");
            ASSERT_EQ(update_instance.obj_info(0).ak(), "new_ak");
            ASSERT_EQ(update_instance.obj_info(0).sk(), cipher_sk);
        }
    };

    update(false, false);
    update(true, false);
    update(true, true);
}

TEST(MetaServiceTest, AlterIamTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
    std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";

    auto get_arn_info_key = [&](RamUserPB& i) {
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(system_meta_service_arn_info_key(), &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // add new system_meta_service_arn_info_key
    {
        AlterIamRequest req;
        req.set_account_id("123");
        req.set_ak("ak1");
        req.set_sk(plain_sk);

        brpc::Controller cntl;
        AlterIamResponse res;
        meta_service->alter_iam(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        RamUserPB ram_user;
        get_arn_info_key(ram_user);
        ASSERT_EQ(ram_user.user_id(), "123");
        ASSERT_EQ(ram_user.ak(), "ak1");
        ASSERT_EQ(ram_user.sk(), cipher_sk);
    }
    // with old system_meta_service_arn_info_key
    {
        AlterIamRequest req;
        req.set_account_id("321");
        req.set_ak("ak2");
        req.set_sk(plain_sk);

        brpc::Controller cntl;
        AlterIamResponse res;
        meta_service->alter_iam(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        RamUserPB ram_user;
        get_arn_info_key(ram_user);
        ASSERT_EQ(ram_user.user_id(), "321");
        ASSERT_EQ(ram_user.ak(), "ak2");
        ASSERT_EQ(ram_user.sk(), cipher_sk);
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, UpdateTmpRowsetTest) {
    auto meta_service = get_meta_service();

    std::string instance_id = "update_rowset_meta_test_instance_id";
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    {
        // 1. normal path
        constexpr auto db_id = 10000, table_id = 10001, index_id = 10002, partition_id = 10003,
                       tablet_id = 10004;
        int64_t txn_id = 0;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service.get(), db_id, label, table_id, txn_id));
        auto rowset = create_rowset(txn_id, tablet_id, partition_id);
        ASSERT_NO_FATAL_FAILURE(prepare_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        res.Clear();

        rowset.set_rowset_state(doris::BEGIN_PARTIAL_UPDATE);
        ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        res.Clear();

        // simulate that there are new segments added to this rowset
        rowset.set_num_segments(rowset.num_segments() + 3);
        rowset.set_num_rows(rowset.num_rows() + 1000);
        rowset.set_total_disk_size(rowset.total_disk_size() + 11000);
        rowset.set_index_disk_size(rowset.index_disk_size() + 1000);
        rowset.set_data_disk_size(rowset.data_disk_size() + 10000);

        ASSERT_NO_FATAL_FAILURE(update_tmp_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;

        std::string key;
        std::string val;
        MetaRowsetTmpKeyInfo key_info {instance_id, txn_id, tablet_id};
        meta_rowset_tmp_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB fetchedRowsetMeta;
        ASSERT_TRUE(fetchedRowsetMeta.ParseFromString(val));

        ASSERT_EQ(doris::BEGIN_PARTIAL_UPDATE, fetchedRowsetMeta.rowset_state());
        ASSERT_EQ(rowset.num_segments(), fetchedRowsetMeta.num_segments());
        ASSERT_EQ(rowset.num_rows(), fetchedRowsetMeta.num_rows());
        ASSERT_EQ(rowset.total_disk_size(), fetchedRowsetMeta.total_disk_size());
        ASSERT_EQ(rowset.index_disk_size(), fetchedRowsetMeta.index_disk_size());
        ASSERT_EQ(rowset.data_disk_size(), fetchedRowsetMeta.data_disk_size());

        ASSERT_NO_FATAL_FAILURE(commit_txn(meta_service.get(), db_id, txn_id, label));
    }

    {
        // 2. rpc retryies due to network error will success
        constexpr auto db_id = 20000, table_id = 20001, index_id = 20002, partition_id = 20003,
                       tablet_id = 20004;
        int64_t txn_id = 0;
        std::string label = "update_rowset_meta_test_label2";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service.get(), db_id, label, table_id, txn_id));
        auto rowset = create_rowset(txn_id, tablet_id, partition_id);
        ASSERT_NO_FATAL_FAILURE(prepare_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        res.Clear();

        rowset.set_rowset_state(doris::BEGIN_PARTIAL_UPDATE);
        ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        res.Clear();

        // simulate that there are new segments added to this rowset
        rowset.set_num_segments(rowset.num_segments() + 3);
        rowset.set_num_rows(rowset.num_rows() + 1000);
        rowset.set_total_disk_size(rowset.total_disk_size() + 11000);
        rowset.set_index_disk_size(rowset.index_disk_size() + 1000);
        rowset.set_data_disk_size(rowset.data_disk_size() + 10000);

        // repeated calls to update_tmp_rowset will all success
        ASSERT_NO_FATAL_FAILURE(update_tmp_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        ASSERT_NO_FATAL_FAILURE(update_tmp_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        ASSERT_NO_FATAL_FAILURE(update_tmp_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        ASSERT_NO_FATAL_FAILURE(update_tmp_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;

        std::string key;
        std::string val;
        MetaRowsetTmpKeyInfo key_info {instance_id, txn_id, tablet_id};
        meta_rowset_tmp_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        doris::RowsetMetaCloudPB fetchedRowsetMeta;
        ASSERT_TRUE(fetchedRowsetMeta.ParseFromString(val));

        ASSERT_EQ(doris::BEGIN_PARTIAL_UPDATE, fetchedRowsetMeta.rowset_state());
        ASSERT_EQ(rowset.num_segments(), fetchedRowsetMeta.num_segments());
        ASSERT_EQ(rowset.num_rows(), fetchedRowsetMeta.num_rows());
        ASSERT_EQ(rowset.total_disk_size(), fetchedRowsetMeta.total_disk_size());
        ASSERT_EQ(rowset.index_disk_size(), fetchedRowsetMeta.index_disk_size());
        ASSERT_EQ(rowset.data_disk_size(), fetchedRowsetMeta.data_disk_size());

        ASSERT_NO_FATAL_FAILURE(commit_txn(meta_service.get(), db_id, txn_id, label));
    }

    {
        // 3. call update_tmp_rowset without commit_rowset first will fail
        constexpr auto db_id = 30000, table_id = 30001, index_id = 30002, partition_id = 30003,
                       tablet_id = 30004;
        int64_t txn_id = 0;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service.get(), db_id, label, table_id, txn_id));
        auto rowset = create_rowset(txn_id, tablet_id, partition_id);
        ASSERT_NO_FATAL_FAILURE(prepare_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
        res.Clear();

        // simulate that there are new segments added to this rowset
        rowset.set_num_segments(rowset.num_segments() + 3);
        rowset.set_num_rows(rowset.num_rows() + 1000);
        rowset.set_total_disk_size(rowset.total_disk_size() + 11000);
        rowset.set_index_disk_size(rowset.index_disk_size() + 1000);
        rowset.set_data_disk_size(rowset.data_disk_size() + 10000);

        ASSERT_NO_FATAL_FAILURE(update_tmp_rowset(meta_service.get(), rowset, res));
        ASSERT_EQ(res.status().code(), MetaServiceCode::ROWSET_META_NOT_FOUND) << label;
    }
}

TEST(MetaServiceTest, CreateS3VaultWithIamRole) {
    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    std::pair<std::string, std::string> pair;
    sp->set_call_back("extract_object_storage_info:get_aksk_pair", [&](auto&& args) {
        auto* ret = try_any_cast<std::pair<std::string, std::string>*>(args[0]);
        pair = *ret;
    });

    auto meta_service = get_meta_service();

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("ak");
    obj_info.set_sk("sk");
    StorageVaultPB vault;
    constexpr char vault_name[] = "test_alter_s3_vault";
    vault.mutable_obj_info()->MergeFrom(obj_info);
    vault.set_name(vault_name);
    vault.set_id("2");
    InstanceInfoPB instance;
    instance.add_storage_vault_names(vault.name());
    instance.add_resource_ids(vault.id());
    instance.set_instance_id("GetObjStoreInfoTestInstance");
    instance.set_enable_storage_vault(true);
    val = instance.SerializeAsString();
    txn->put(key, val);
    txn->put(storage_vault_key({instance.instance_id(), "2"}), vault.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    txn = nullptr;

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_S3_VAULT);
        StorageVaultPB vault;
        vault.mutable_obj_info()->set_endpoint("s3.us-east-1.amazonaws.com");
        vault.mutable_obj_info()->set_region("us-east-1");
        vault.mutable_obj_info()->set_bucket("test_bucket");
        vault.mutable_obj_info()->set_prefix("test_prefix");
        vault.mutable_obj_info()->set_ak("new_ak");
        vault.mutable_obj_info()->set_sk("new_sk");
        vault.mutable_obj_info()->set_provider(
                ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);

        vault.set_name("ak_sk_s3_vault");
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        {
            InstanceInfoPB instance;
            get_test_instance(instance);
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string val;
            ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                      TxnErrorCode::TXN_OK);
            StorageVaultPB get_obj;
            get_obj.ParseFromString(val);
            ASSERT_EQ(get_obj.obj_info().ak(), "ak") << get_obj.obj_info().ak();
        }

        {
            InstanceInfoPB instance;
            get_test_instance(instance);
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string val;
            ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "3"}), &val),
                      TxnErrorCode::TXN_OK);
            StorageVaultPB get_obj;
            get_obj.ParseFromString(val);
            ASSERT_EQ(get_obj.obj_info().ak(), "new_ak") << get_obj.obj_info().ak();
            ASSERT_NE(get_obj.obj_info().sk(), "new_sk") << get_obj.obj_info().sk();
        }
    }

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_S3_VAULT);
        StorageVaultPB vault;
        vault.mutable_obj_info()->set_endpoint("s3.us-east-1.amazonaws.com");
        vault.mutable_obj_info()->set_region("us-east-1");
        vault.mutable_obj_info()->set_bucket("test_bucket");
        vault.mutable_obj_info()->set_prefix("test_prefix");
        vault.mutable_obj_info()->set_role_arn("arn:aws:iam::123456789012:role/test-role");
        vault.mutable_obj_info()->set_external_id("external_id");
        vault.mutable_obj_info()->set_provider(
                ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        vault.mutable_obj_info()->set_cred_provider_type(CredProviderTypePB::INSTANCE_PROFILE);

        vault.set_name("ak_sk_s3_vault_with_role");
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        {
            InstanceInfoPB instance;
            get_test_instance(instance);
            std::unique_ptr<Transaction> txn;
            ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
            std::string val;
            ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "4"}), &val),
                      TxnErrorCode::TXN_OK);
            StorageVaultPB get_obj;
            get_obj.ParseFromString(val);
            ASSERT_EQ(get_obj.obj_info().ak().empty(), true) << get_obj.obj_info().ak();
            ASSERT_EQ(get_obj.obj_info().sk().empty(), true) << get_obj.obj_info().sk();

            ASSERT_EQ(get_obj.obj_info().role_arn(), "arn:aws:iam::123456789012:role/test-role")
                    << get_obj.obj_info().role_arn();
            ASSERT_EQ(get_obj.obj_info().external_id(), "external_id")
                    << get_obj.obj_info().external_id();

            ASSERT_EQ(get_obj.obj_info().endpoint(), "s3.us-east-1.amazonaws.com")
                    << get_obj.obj_info().endpoint();
            ASSERT_EQ(get_obj.obj_info().region(), "us-east-1") << get_obj.obj_info().region();
            ASSERT_EQ(get_obj.obj_info().bucket(), "test_bucket") << get_obj.obj_info().bucket();
            ASSERT_EQ(get_obj.obj_info().prefix(), "test_prefix") << get_obj.obj_info().prefix();
            ASSERT_EQ(get_obj.obj_info().provider(),
                      ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3)
                    << get_obj.obj_info().provider();
            ASSERT_EQ(get_obj.name(), "ak_sk_s3_vault_with_role") << get_obj.name();
            ASSERT_EQ(get_obj.id(), "4") << get_obj.id();
            ASSERT_EQ(get_obj.obj_info().cred_provider_type(), CredProviderTypePB::INSTANCE_PROFILE)
                    << get_obj.obj_info().cred_provider_type();
        }
    }

    LOG(INFO) << "instance:" << instance.ShortDebugString();
    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, AddObjInfoWithRole) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();

    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    InstanceInfoPB instance;
    val = instance.SerializeAsString();
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ADD_OBJ_INFO);
        auto sp = SyncPoint::get_instance();
        sp->set_call_back("create_object_info_with_encrypt", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
        });
        sp->enable_processing();

        ObjectStoreInfoPB obj_info;
        obj_info.set_endpoint("s3.us-east-1.amazonaws.com");
        obj_info.set_region("us-east-1");
        obj_info.set_bucket("test_bucket");
        obj_info.set_prefix("test_prefix");
        obj_info.set_role_arn("arn:aws:iam::123456789012:role/test-role");
        obj_info.set_external_id("external_id");
        obj_info.set_provider(ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        obj_info.set_cred_provider_type(CredProviderTypePB::INSTANCE_PROFILE);

        req.mutable_obj()->MergeFrom(obj_info);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);
        const auto& obj = instance.obj_info().at(0);
        ASSERT_EQ(obj.id(), "1");
        ASSERT_EQ(obj.ak().empty(), true) << obj.ak();
        ASSERT_EQ(obj.sk().empty(), true) << obj.sk();

        ASSERT_EQ(obj.role_arn(), "arn:aws:iam::123456789012:role/test-role") << obj.role_arn();
        ASSERT_EQ(obj.external_id(), "external_id") << obj.external_id();

        ASSERT_EQ(obj.endpoint(), "s3.us-east-1.amazonaws.com") << obj.endpoint();
        ASSERT_EQ(obj.region(), "us-east-1") << obj.region();
        ASSERT_EQ(obj.bucket(), "test_bucket") << obj.bucket();
        ASSERT_EQ(obj.prefix(), "test_prefix") << obj.prefix();
        ASSERT_EQ(obj.provider(), ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3)
                << obj.provider();
        ASSERT_EQ(obj.cred_provider_type(), CredProviderTypePB::INSTANCE_PROFILE)
                << obj.cred_provider_type();

        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, CheckJobExisted) {
    auto meta_service = get_meta_service();

    std::string instance_id = "check_job_existed_instance_id";
    auto sp = SyncPoint::get_instance();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
    };
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    // OK
    {
        constexpr auto table_id = 952701, index_id = 952702, partition_id = 952703,
                       tablet_id = 952704;
        int64_t txn_id = 952705;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("compaction1");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->prepare_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        res.Clear();
    }

    // job does not exist,
    {
        constexpr auto table_id = 952801, index_id = 952802, partition_id = 952803,
                       tablet_id = 952804;
        int64_t txn_id = 952805;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("compaction1");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->prepare_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::STALE_PREPARE_ROWSET) << res.status().msg();
        res.Clear();
    }

    // compaction job exists, job id not match
    {
        constexpr auto table_id = 952901, index_id = 952902, partition_id = 952903,
                       tablet_id = 952904;
        int64_t txn_id = 952905;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("compaction2");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->prepare_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::STALE_PREPARE_ROWSET) << res.status().msg();
        res.Clear();
    }

    // do not set job id
    {
        constexpr auto table_id = 953501, index_id = 953502, partition_id = 953503,
                       tablet_id = 953504;
        int64_t txn_id = 953505;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->prepare_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        res.Clear();
    }

    // job id is empty string
    {
        constexpr auto table_id = 953601, index_id = 953602, partition_id = 953603,
                       tablet_id = 953604;
        int64_t txn_id = 953605;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->prepare_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        res.Clear();
    }

    // commit rowset OK
    {
        constexpr auto table_id = 953001, index_id = 953002, partition_id = 953003,
                       tablet_id = 953004;
        int64_t txn_id = 953005;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("compaction1");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->commit_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        res.Clear();
    }

    // commit rowset, job does not exist,
    {
        constexpr auto table_id = 953101, index_id = 953102, partition_id = 953103,
                       tablet_id = 953104;
        int64_t txn_id = 952805;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("compaction1");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->commit_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::STALE_PREPARE_ROWSET) << res.status().msg();
        res.Clear();
    }

    // commit rowset, compaction job exists, job id not match
    {
        constexpr auto table_id = 953201, index_id = 953202, partition_id = 953203,
                       tablet_id = 953204;
        int64_t txn_id = 952905;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("compaction2");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->commit_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::STALE_PREPARE_ROWSET) << res.status().msg();
        res.Clear();
    }

    // do not set job id when commit rowset
    {
        constexpr auto table_id = 953301, index_id = 953302, partition_id = 953303,
                       tablet_id = 953304;
        int64_t txn_id = 953305;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->commit_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        res.Clear();
    }

    // job id is empty string when commit rowset
    {
        constexpr auto table_id = 953401, index_id = 953402, partition_id = 953403,
                       tablet_id = 953404;
        int64_t txn_id = 953405;
        std::string label = "update_rowset_meta_test_label1";
        CreateRowsetResponse res;

        ASSERT_NO_FATAL_FAILURE(
                create_tablet(meta_service.get(), table_id, index_id, partition_id, tablet_id));

        auto rowset = create_rowset(txn_id, tablet_id, partition_id);

        {
            StartTabletJobResponse res;
            start_compaction_job(meta_service.get(), tablet_id, "compaction1", "ip:port", 0, 0,
                                 TabletCompactionJobPB::BASE, res);
        }

        brpc::Controller cntl;
        auto arena = res.GetArena();
        auto req = google::protobuf::Arena::CreateMessage<CreateRowsetRequest>(arena);
        req->set_tablet_job_id("");
        req->mutable_rowset_meta()->CopyFrom(rowset);
        meta_service->commit_rowset(&cntl, req, &res, nullptr);
        if (!arena) delete req;

        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        res.Clear();
    }
}

TEST(MetaServiceTest, StalePrepareRowset) {
    auto meta_service = get_meta_service();

    int64_t table_id = 1;
    int64_t partition_id = 1;
    int64_t tablet_id = 1;
    int64_t db_id = 100201;
    std::string label = "test_prepare_rowset";
    create_tablet(meta_service.get(), table_id, 1, partition_id, tablet_id);

    int64_t txn_id = 0;
    ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service.get(), db_id, label, table_id, txn_id));
    CreateRowsetResponse res;
    auto rowset = create_rowset(txn_id, tablet_id, partition_id);
    rowset.mutable_load_id()->set_hi(123);
    rowset.mutable_load_id()->set_lo(456);
    prepare_rowset(meta_service.get(), rowset, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
    res.Clear();
    ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service.get(), rowset, res));
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;

    prepare_rowset(meta_service.get(), rowset, res);
    ASSERT_TRUE(res.status().msg().find("rowset already exists") != std::string::npos)
            << res.status().msg();
    ASSERT_EQ(res.status().code(), MetaServiceCode::ALREADY_EXISTED) << res.status().code();

    commit_txn(meta_service.get(), db_id, txn_id, label);
    prepare_rowset(meta_service.get(), rowset, res);
    ASSERT_TRUE(res.status().msg().find("txn is not in") != std::string::npos)
            << res.status().msg();
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().code();
}

TEST(MetaServiceTest, StaleCommitRowset) {
    auto meta_service = get_meta_service();

    int64_t table_id = 1;
    int64_t partition_id = 1;
    int64_t tablet_id = 1;
    int64_t db_id = 100201;
    std::string label = "test_prepare_rowset";
    create_tablet(meta_service.get(), table_id, 1, partition_id, tablet_id);

    int64_t txn_id = 0;
    ASSERT_NO_FATAL_FAILURE(begin_txn(meta_service.get(), db_id, label, table_id, txn_id));
    CreateRowsetResponse res;
    auto rowset = create_rowset(txn_id, tablet_id, partition_id);
    rowset.mutable_load_id()->set_hi(123);
    rowset.mutable_load_id()->set_lo(456);
    prepare_rowset(meta_service.get(), rowset, res);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;
    res.Clear();
    ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service.get(), rowset, res));
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;

    ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service.get(), rowset, res));
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << label;

    commit_txn(meta_service.get(), db_id, txn_id, label);
    ASSERT_NO_FATAL_FAILURE(commit_rowset(meta_service.get(), rowset, res));
    ASSERT_TRUE(res.status().msg().find("txn is not in") != std::string::npos)
            << res.status().msg();
    ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.status().code();
}

TEST(MetaServiceTest, AlterObjInfoTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();

    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("access_key_132131");
    obj_info.set_sk("secret_key_434124");
    obj_info.set_provider(ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
    InstanceInfoPB instance;
    instance.add_obj_info()->CopyFrom(obj_info);
    val = instance.SerializeAsString();
    txn->put(key, val);
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
    std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";

    // update failed
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_OBJ_INFO);
        req.mutable_obj()->set_id("2");
        req.mutable_obj()->set_ak("new_ak");
        req.mutable_obj()->set_sk(plain_sk);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        InstanceInfoPB instance;
        get_test_instance(instance);
        ASSERT_EQ(instance.obj_info(0).id(), "1");
        ASSERT_EQ(instance.obj_info(0).ak(), "access_key_132131");
        ASSERT_EQ(instance.obj_info(0).sk(), "secret_key_434124");
    }

    // update ak/sk successful
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_OBJ_INFO);
        req.mutable_obj()->set_id("1");
        req.mutable_obj()->set_ak("new_access_key_132131");
        req.mutable_obj()->set_sk(plain_sk);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        InstanceInfoPB instance;
        get_test_instance(instance);
        LOG(INFO) << "instance:" << instance.ShortDebugString();
        ASSERT_EQ(instance.obj_info(0).id(), "1");
        ASSERT_EQ(instance.obj_info(0).ak(), "new_access_key_132131");
        ASSERT_EQ(instance.obj_info(0).sk(), cipher_sk);
    }

    // update from ak/sk to role_arn
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_OBJ_INFO);
        req.mutable_obj()->set_id("1");
        req.mutable_obj()->set_role_arn("arn:aws:iam::1453123012:role/test-role");
        req.mutable_obj()->set_external_id("external_id_13123");
        req.mutable_obj()->set_cred_provider_type(CredProviderTypePB::INSTANCE_PROFILE);
        req.mutable_obj()->set_provider(ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        InstanceInfoPB instance;
        get_test_instance(instance);
        LOG(INFO) << "instance:" << instance.ShortDebugString();
        ASSERT_EQ(instance.obj_info(0).id(), "1");
        ASSERT_EQ(instance.obj_info(0).role_arn(), "arn:aws:iam::1453123012:role/test-role");
        ASSERT_EQ(instance.obj_info(0).external_id(), "external_id_13123");
        ASSERT_EQ(instance.obj_info(0).provider(),
                  ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        ASSERT_EQ(instance.obj_info(0).cred_provider_type(), CredProviderTypePB::INSTANCE_PROFILE);
        ASSERT_TRUE(instance.obj_info(0).ak().empty());
        ASSERT_TRUE(instance.obj_info(0).sk().empty());
        ASSERT_FALSE(instance.obj_info(0).has_encryption_info());
    }

    // update from role_arn to ak/sk
    {
        AlterObjStoreInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_OBJ_INFO);
        req.mutable_obj()->set_id("1");
        req.mutable_obj()->set_ak("new_access_key_132131");
        req.mutable_obj()->set_sk(plain_sk);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_obj_store_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        InstanceInfoPB instance;
        get_test_instance(instance);
        LOG(INFO) << "instance:" << instance.ShortDebugString();
        ASSERT_EQ(instance.obj_info(0).id(), "1");
        ASSERT_EQ(instance.obj_info(0).ak(), "new_access_key_132131");
        ASSERT_EQ(instance.obj_info(0).sk(), cipher_sk);
        ASSERT_EQ(instance.obj_info(0).provider(),
                  ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        ASSERT_FALSE(instance.obj_info(0).has_cred_provider_type());
        ASSERT_FALSE(instance.obj_info(0).has_role_arn());
        ASSERT_FALSE(instance.obj_info(0).has_external_id());
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

TEST(MetaServiceTest, AlterS3StorageVaultWithRoleArnTest) {
    auto meta_service = get_meta_service();

    auto sp = SyncPoint::get_instance();
    sp->enable_processing();
    sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
        auto* ret = try_any_cast<int*>(args[0]);
        *ret = 0;
        auto* key = try_any_cast<std::string*>(args[1]);
        *key = "selectdbselectdbselectdbselectdb";
        auto* key_id = try_any_cast<int64_t*>(args[2]);
        *key_id = 1;
    });
    std::pair<std::string, std::string> pair;
    sp->set_call_back("extract_object_storage_info:get_aksk_pair", [&](auto&& args) {
        auto* ret = try_any_cast<std::pair<std::string, std::string>*>(args[0]);
        pair = *ret;
    });

    std::unique_ptr<Transaction> txn;
    ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
    std::string key;
    std::string val;
    InstanceKeyInfo key_info {"test_instance"};
    instance_key(key_info, &key);

    ObjectStoreInfoPB obj_info;
    obj_info.set_id("1");
    obj_info.set_ak("123456ab");
    obj_info.set_sk("@ak$");
    obj_info.set_provider(ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
    StorageVaultPB vault;
    constexpr char vault_name[] = "test_alter_s3_vault_111";
    vault.mutable_obj_info()->MergeFrom(obj_info);
    vault.set_name(vault_name);
    vault.set_id("2");
    InstanceInfoPB instance;
    instance.add_storage_vault_names(vault.name());
    instance.add_resource_ids(vault.id());
    instance.set_instance_id("GetObjStoreInfoTestInstance");
    val = instance.SerializeAsString();
    txn->put(key, val);
    txn->put(storage_vault_key({instance.instance_id(), "2"}), vault.SerializeAsString());
    ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    txn = nullptr;

    auto get_test_instance = [&](InstanceInfoPB& i) {
        std::string key;
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        InstanceKeyInfo key_info {"test_instance"};
        instance_key(key_info, &key);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        i.ParseFromString(val);
    };

    // update from ak/sk to role_arn
    {
        AlterObjStoreInfoRequest req;
        constexpr char new_vault_name[] = "new_test_alter_s3_vault_111";
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
        StorageVaultPB vault;
        vault.set_alter_name(new_vault_name);
        ObjectStoreInfoPB obj;
        obj.set_role_arn("arn:aws:iam::12311321:role/test-alter-role");
        obj.set_external_id("external_id_123123");
        vault.mutable_obj_info()->MergeFrom(obj);
        vault.set_name(vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);
        LOG(INFO) << "instance:" << instance.ShortDebugString();

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                  TxnErrorCode::TXN_OK);
        StorageVaultPB get_obj;
        get_obj.ParseFromString(val);
        ASSERT_EQ(get_obj.id(), "2");
        ASSERT_EQ(get_obj.obj_info().role_arn(), "arn:aws:iam::12311321:role/test-alter-role");
        ASSERT_EQ(get_obj.obj_info().external_id(), "external_id_123123");
        ASSERT_EQ(get_obj.obj_info().provider(),
                  ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        ASSERT_EQ(get_obj.obj_info().cred_provider_type(), CredProviderTypePB::INSTANCE_PROFILE);
        ASSERT_TRUE(get_obj.obj_info().ak().empty());
        ASSERT_TRUE(get_obj.obj_info().sk().empty());
        ASSERT_FALSE(get_obj.obj_info().has_encryption_info());
        ASSERT_EQ(get_obj.name(), new_vault_name) << get_obj.obj_info().ShortDebugString();
    }

    std::string cipher_sk = "JUkuTDctR+ckJtnPkLScWaQZRcOtWBhsLLpnCRxQLxr734qB8cs6gNLH6grE1FxO";
    std::string plain_sk = "Hx60p12123af234541nsVsffdfsdfghsdfhsdf34t";

    // update from role_arn to ak_sk
    {
        AlterObjStoreInfoRequest req;
        constexpr char new_vault_name[] = "new_test_alter_s3_vault_111";
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_op(AlterObjStoreInfoRequest::ALTER_S3_VAULT);
        StorageVaultPB vault;
        ObjectStoreInfoPB obj;
        obj.set_ak("123456ab");
        obj.set_sk(plain_sk);
        vault.mutable_obj_info()->MergeFrom(obj);
        vault.set_name(new_vault_name);
        req.mutable_vault()->CopyFrom(vault);

        brpc::Controller cntl;
        AlterObjStoreInfoResponse res;
        meta_service->alter_storage_vault(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        InstanceInfoPB instance;
        get_test_instance(instance);
        LOG(INFO) << "instance:" << instance.ShortDebugString();

        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(storage_vault_key({instance.instance_id(), "2"}), &val),
                  TxnErrorCode::TXN_OK);
        StorageVaultPB get_obj;
        get_obj.ParseFromString(val);
        ASSERT_EQ(get_obj.id(), "2");
        ASSERT_EQ(get_obj.obj_info().provider(),
                  ObjectStoreInfoPB::Provider::ObjectStoreInfoPB_Provider_S3);
        ASSERT_EQ(get_obj.obj_info().ak(), "123456ab");
        ASSERT_EQ(get_obj.obj_info().sk(), cipher_sk);
        ASSERT_TRUE(get_obj.obj_info().role_arn().empty());
        ASSERT_TRUE(get_obj.obj_info().external_id().empty());
        ASSERT_TRUE(get_obj.obj_info().has_encryption_info());
        ASSERT_FALSE(get_obj.obj_info().has_cred_provider_type());
        ASSERT_EQ(get_obj.name(), new_vault_name) << get_obj.obj_info().ShortDebugString();
    }

    SyncPoint::get_instance()->disable_processing();
    SyncPoint::get_instance()->clear_all_call_backs();
}

void scan_restore_job_rowset(
        Transaction* txn, const std::string& instance_id, int64_t tablet_id, MetaServiceCode& code,
        std::string& msg,
        std::vector<std::pair<std::string, doris::RowsetMetaCloudPB>>* restore_job_rs_metas);

TEST(MetaServiceTest, RestoreJobTest) {
    auto meta_service = get_meta_service();
    ASSERT_NE(meta_service, nullptr);

    std::string instance_id = "test_prepare_restore_job_instance_id";
    auto sp = SyncPoint::get_instance();
    std::unique_ptr<int, std::function<void(int*)>> defer(
            (int*)0x01, [](int*) { SyncPoint::get_instance()->clear_all_call_backs(); });
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();

    auto reset_meta_service = [&meta_service] { meta_service = get_meta_service(); };
    constexpr int64_t table_id = 10001;
    constexpr int64_t index_id = 10002;
    constexpr int64_t partition_id = 10003;
    constexpr int64_t tablet_id = 10004;
    constexpr int64_t version = 1;
    constexpr int64_t txn_id = 0;

    TabletIndexPB tablet_idx;
    tablet_idx.set_table_id(table_id);
    tablet_idx.set_index_id(index_id);
    tablet_idx.set_partition_id(partition_id);
    tablet_idx.set_tablet_id(tablet_id);
    std::string tablet_idx_val;
    tablet_idx.SerializeToString(&tablet_idx_val);

    std::unique_ptr<Transaction> txn;
    brpc::Controller cntl;
    RestoreJobRequest req;
    RestoreJobResponse res;

    // ------------Test prepare restore job------------
    // invalid args prepare restore job
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        // empty action
        meta_service->prepare_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("invalid action") != std::string::npos);
        req.set_action(RestoreJobRequest::PREPARE);

        // empty tablet id
        meta_service->prepare_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_EQ(res.status().msg(), "empty tablet_id");

        // restore with empty tablet meta
        req.set_tablet_id(tablet_id);
        res.Clear();
        meta_service->prepare_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_EQ(res.status().msg(), "no tablet meta");

        // check key existence
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        req.Clear();
        res.Clear();
    }
    // normal prepare restore job
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        req.set_tablet_id(tablet_id);
        req.set_expiration(time(nullptr) + 3600);
        req.set_action(RestoreJobRequest::PREPARE);

        // set tablet meta
        auto* tablet_meta = req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);
        auto* rs_meta = tablet_meta->add_rs_metas();
        *rs_meta = create_rowset(txn_id, tablet_id, partition_id, version);

        meta_service->prepare_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);

        RestoreJobCloudPB restore_job_pb;
        ASSERT_TRUE(restore_job_pb.ParseFromString(val));
        ASSERT_EQ(restore_job_pb.tablet_id(), tablet_id);
        ASSERT_EQ(restore_job_pb.state(), RestoreJobCloudPB::PREPARED);
        ASSERT_EQ(restore_job_pb.tablet_meta().schema_version(), 1);

        std::string restore_job_rs_key = job_restore_rowset_key({instance_id, tablet_id, version});
        ASSERT_EQ(txn->get(restore_job_rs_key, &val), TxnErrorCode::TXN_OK);
        RowsetMetaCloudPB rs_meta_pb;
        ASSERT_TRUE(rs_meta_pb.ParseFromString(val));
        ASSERT_EQ(rs_meta_pb.tablet_id(), tablet_id);
        ASSERT_EQ(rs_meta_pb.rowset_id_v2(), rs_meta->rowset_id_v2());
        req.Clear();
        res.Clear();
    }
    // duplicate prepare restore job
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::PREPARE);

        // set tablet meta
        auto* tablet_meta = req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);
        auto* rs_meta = tablet_meta->add_rs_metas();
        *rs_meta = create_rowset(txn_id, tablet_id, partition_id, version);

        // first request
        meta_service->prepare_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);

        RestoreJobCloudPB restore_job_pb;
        ASSERT_TRUE(restore_job_pb.ParseFromString(val));
        ASSERT_EQ(restore_job_pb.tablet_id(), tablet_id);
        ASSERT_EQ(restore_job_pb.state(), RestoreJobCloudPB::PREPARED);
        ASSERT_EQ(restore_job_pb.version(), 0);

        // second request
        meta_service->prepare_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);

        restore_job_pb.Clear();
        ASSERT_TRUE(restore_job_pb.ParseFromString(val));
        ASSERT_EQ(restore_job_pb.tablet_id(), tablet_id);
        ASSERT_EQ(restore_job_pb.state(), RestoreJobCloudPB::PREPARED);
        ASSERT_EQ(restore_job_pb.version(), 1);
        req.Clear();
        res.Clear();
    }
    // ------------Test commit restore job------------
    // invalid args commit restore job
    {
        reset_meta_service();
        // empty action
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("invalid action") != std::string::npos);
        req.set_action(RestoreJobRequest::COMMIT);

        // empty tablet_id
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_EQ(res.status().msg(), "empty tablet_id");

        // check key existence
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        req.Clear();
        res.Clear();
    }
    // commit restore job not exits
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMMIT);
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_EQ(res.status().msg(), "restore job not exists or has been recycled");
        req.Clear();
        res.Clear();
    }
    // normal commit restore job
    for (int store_version = 0; store_version < 4; store_version++) {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // prepare restore job
        RestoreJobRequest make_req;
        RestoreJobResponse make_res;
        make_req.set_tablet_id(tablet_id);
        make_req.set_expiration(time(nullptr) + 3600);
        make_req.set_action(RestoreJobRequest::PREPARE);
        auto* tablet_meta = make_req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);
        auto* rs_meta = tablet_meta->add_rs_metas();
        *rs_meta = create_rowset(txn_id, tablet_id, partition_id, version);
        auto* delete_bitmap = tablet_meta->mutable_delete_bitmap();
        // 1
        delete_bitmap->add_rowset_ids(rs_meta->rowset_id_v2());
        delete_bitmap->add_versions(1);
        delete_bitmap->add_segment_ids(1);
        delete_bitmap->add_segment_delete_bitmaps("test_bitmap");
        // 2
        delete_bitmap->add_rowset_ids(rs_meta->rowset_id_v2());
        delete_bitmap->add_versions(1);
        delete_bitmap->add_segment_ids(2);
        delete_bitmap->add_segment_delete_bitmaps("test_bitmap2");
        // 3
        delete_bitmap->add_rowset_ids(rs_meta->rowset_id_v2() + "2");
        delete_bitmap->add_versions(1);
        delete_bitmap->add_segment_ids(1);
        delete_bitmap->add_segment_delete_bitmaps("test_bitmap3");

        meta_service->prepare_restore_job(&cntl, &make_req, &make_res, nullptr);
        ASSERT_EQ(make_res.status().code(), MetaServiceCode::OK);
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        std::string restore_job_rs_key = job_restore_rowset_key({instance_id, tablet_id, version});
        ASSERT_EQ(txn->get(restore_job_rs_key, &val), TxnErrorCode::TXN_OK);

        // commit_restore_job
        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMMIT);
        if (store_version > 0) {
            req.set_store_version(store_version);
        }
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        std::string tablet_key =
                meta_tablet_key({instance_id, table_id, index_id, partition_id, tablet_id});
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(tablet_key, &val), TxnErrorCode::TXN_OK);
        TabletMetaCloudPB saved_tablet_meta;
        ASSERT_TRUE(saved_tablet_meta.ParseFromString(val));
        ASSERT_EQ(saved_tablet_meta.tablet_id(), tablet_id);
        ASSERT_EQ(saved_tablet_meta.schema_version(), 1);
        std::string rs_key = meta_rowset_key({instance_id, tablet_id, version});
        ASSERT_EQ(txn->get(rs_key, &val), TxnErrorCode::TXN_OK);
        RowsetMetaCloudPB saved_rs_meta;
        ASSERT_TRUE(saved_rs_meta.ParseFromString(val));
        ASSERT_EQ(saved_rs_meta.tablet_id(), tablet_id);
        ASSERT_EQ(saved_rs_meta.rowset_id_v2(), rs_meta->rowset_id_v2());
        // check delete bitmap
        {
            TxnErrorCode err = (store_version == 0 || store_version == 1 || store_version == 3)
                                       ? TxnErrorCode::TXN_OK
                                       : TxnErrorCode::TXN_KEY_NOT_FOUND;
            std::string bitmap_key =
                    meta_delete_bitmap_key({instance_id, tablet_id, rs_meta->rowset_id_v2(), 1, 1});
            ASSERT_EQ(txn->get(bitmap_key, &val), err);
            if (err == TxnErrorCode::TXN_OK) {
                ASSERT_EQ(val, "test_bitmap");
            }
            bitmap_key =
                    meta_delete_bitmap_key({instance_id, tablet_id, rs_meta->rowset_id_v2(), 1, 2});
            ASSERT_EQ(txn->get(bitmap_key, &val), err);
            if (err == TxnErrorCode::TXN_OK) {
                ASSERT_EQ(val, "test_bitmap2");
            }
            bitmap_key = meta_delete_bitmap_key(
                    {instance_id, tablet_id, rs_meta->rowset_id_v2() + "2", 1, 1});
            ASSERT_EQ(txn->get(bitmap_key, &val), err);
            if (err == TxnErrorCode::TXN_OK) {
                ASSERT_EQ(val, "test_bitmap3");
            }
        }
        {
            TxnErrorCode err = (store_version == 2 || store_version == 3)
                                       ? TxnErrorCode::TXN_OK
                                       : TxnErrorCode::TXN_KEY_NOT_FOUND;
            std::string bitmap_key = versioned::meta_delete_bitmap_key(
                    {instance_id, tablet_id, rs_meta->rowset_id_v2()});
            ValueBuf val_buf;
            ASSERT_EQ(cloud::blob_get(txn.get(), bitmap_key, &val_buf), err);
            if (err == TxnErrorCode::TXN_OK) {
                DeleteBitmapStoragePB delete_bitmap_storage;
                ASSERT_TRUE(val_buf.to_pb(&delete_bitmap_storage));
                ASSERT_TRUE(delete_bitmap_storage.store_in_fdb());
                auto& delete_bitmap_pb = delete_bitmap_storage.delete_bitmap();
                ASSERT_EQ(delete_bitmap_pb.rowset_ids_size(), 2);
                ASSERT_EQ(delete_bitmap_pb.rowset_ids(0), rs_meta->rowset_id_v2());
                ASSERT_EQ(delete_bitmap_pb.segment_ids(0), 1);
                ASSERT_EQ(delete_bitmap_pb.versions(0), 1);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(0), "test_bitmap");
                ASSERT_EQ(delete_bitmap_pb.rowset_ids(1), rs_meta->rowset_id_v2());
                ASSERT_EQ(delete_bitmap_pb.segment_ids(1), 2);
                ASSERT_EQ(delete_bitmap_pb.versions(1), 1);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(1), "test_bitmap2");
            }
            bitmap_key = versioned::meta_delete_bitmap_key(
                    {instance_id, tablet_id, rs_meta->rowset_id_v2() + "2"});
            ASSERT_EQ(cloud::blob_get(txn.get(), bitmap_key, &val_buf), err);
            if (err == TxnErrorCode::TXN_OK) {
                DeleteBitmapStoragePB delete_bitmap_storage;
                ASSERT_TRUE(val_buf.to_pb(&delete_bitmap_storage));
                ASSERT_TRUE(delete_bitmap_storage.store_in_fdb());
                auto& delete_bitmap_pb = delete_bitmap_storage.delete_bitmap();
                ASSERT_EQ(delete_bitmap_pb.rowset_ids_size(), 1);
                ASSERT_EQ(delete_bitmap_pb.rowset_ids(0), rs_meta->rowset_id_v2() + "2");
                ASSERT_EQ(delete_bitmap_pb.segment_ids(0), 1);
                ASSERT_EQ(delete_bitmap_pb.versions(0), 1);
                ASSERT_EQ(delete_bitmap_pb.segment_delete_bitmaps(0), "test_bitmap3");
            }
        }

        // ths restore job key should not be removed, restore job rowset key should be found
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        std::vector<std::pair<std::string, doris::RowsetMetaCloudPB>> restore_job_rs_metas;
        MetaServiceCode code;
        std::string msg;
        scan_restore_job_rowset(txn.get(), instance_id, tablet_id, code, msg,
                                &restore_job_rs_metas);
        ASSERT_EQ(code, MetaServiceCode::OK) << msg;
        ASSERT_EQ(restore_job_rs_metas.size(), 1);
        req.Clear();
        res.Clear();
    }
    // large commit restore job request with 10000 rowset meta
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // prepare restore job
        RestoreJobRequest make_req;
        RestoreJobResponse make_res;
        make_req.set_tablet_id(tablet_id);
        make_req.set_expiration(time(nullptr) + 3600);
        make_req.set_action(RestoreJobRequest::PREPARE);

        auto* tablet_meta = make_req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);

        // add 10000 rowset meta
        constexpr int LARGE_ROWSET_COUNT = 10000;
        for (int64_t ver = 1; ver <= LARGE_ROWSET_COUNT; ver++) {
            auto* rs_meta = tablet_meta->add_rs_metas();
            *rs_meta = create_rowset(txn_id, tablet_id, partition_id, ver);
        }

        meta_service->prepare_restore_job(&cntl, &make_req, &make_res, nullptr);
        ASSERT_EQ(make_res.status().code(), MetaServiceCode::OK) << make_res.status().msg();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        for (int64_t ver = 1; ver <= LARGE_ROWSET_COUNT; ver++) {
            std::string restore_job_rs_key = job_restore_rowset_key({instance_id, tablet_id, ver});
            std::string val;
            ASSERT_EQ(txn->get(restore_job_rs_key, &val), TxnErrorCode::TXN_OK);
            RowsetMetaCloudPB rs_meta_pb;
            ASSERT_TRUE(rs_meta_pb.ParseFromString(val));
            ASSERT_EQ(rs_meta_pb.tablet_id(), tablet_id);
            ASSERT_EQ(rs_meta_pb.start_version(), ver);
            ASSERT_EQ(rs_meta_pb.end_version(), ver);
        }

        // commit_restore_job
        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMMIT);
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        for (int64_t ver = 1; ver <= LARGE_ROWSET_COUNT; ver++) {
            std::string rs_key = meta_rowset_key({instance_id, tablet_id, ver});
            std::string val;
            ASSERT_EQ(txn->get(rs_key, &val), TxnErrorCode::TXN_OK);
            RowsetMetaCloudPB saved_rs_meta;
            ASSERT_TRUE(saved_rs_meta.ParseFromString(val));
            ASSERT_EQ(saved_rs_meta.tablet_id(), tablet_id);
            ASSERT_EQ(saved_rs_meta.start_version(), ver);
            ASSERT_EQ(saved_rs_meta.end_version(), ver);
        }

        // ths restore job key should not be removed, restore job rowset key should be found
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        std::vector<std::pair<std::string, doris::RowsetMetaCloudPB>> restore_job_rs_metas;
        MetaServiceCode code;
        std::string msg;
        scan_restore_job_rowset(txn.get(), instance_id, tablet_id, code, msg,
                                &restore_job_rs_metas);
        ASSERT_EQ(code, MetaServiceCode::OK) << msg;
        ASSERT_EQ(restore_job_rs_metas.size(), 10000);
        req.Clear();
        res.Clear();
    }
    // ------------Test finish restore job------------
    // invalid args finish restore job
    {
        reset_meta_service();
        // empty action
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("invalid action") != std::string::npos);
        req.set_action(RestoreJobRequest::COMPLETE);

        // empty tablet_id
        meta_service->finish_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_EQ(res.status().msg(), "empty tablet_id");

        // check key existence
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);

        req.Clear();
        res.Clear();
    }
    // finish restore job not exists
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMPLETE);
        meta_service->finish_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_EQ(res.status().msg(), "restore job not exists or has been recycled");
        req.Clear();
        res.Clear();
    }
    // finish restore job COMMITTED -> COMPLETED
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // prepare restore job
        RestoreJobRequest make_req;
        RestoreJobResponse make_res;
        make_req.set_tablet_id(tablet_id);
        make_req.set_expiration(time(nullptr) + 3600);
        make_req.set_action(RestoreJobRequest::PREPARE);

        auto* tablet_meta = make_req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);
        auto* rs_meta = tablet_meta->add_rs_metas();
        *rs_meta = create_rowset(txn_id, tablet_id, partition_id, version);
        auto* delete_bitmap = tablet_meta->mutable_delete_bitmap();
        delete_bitmap->add_rowset_ids(rs_meta->rowset_id_v2());
        delete_bitmap->add_versions(1);
        delete_bitmap->add_segment_ids(1);
        delete_bitmap->add_segment_delete_bitmaps("test_bitmap");

        meta_service->prepare_restore_job(&cntl, &make_req, &make_res, nullptr);
        ASSERT_EQ(make_res.status().code(), MetaServiceCode::OK);
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        std::string restore_job_rs_key = job_restore_rowset_key({instance_id, tablet_id, version});
        ASSERT_EQ(txn->get(restore_job_rs_key, &val), TxnErrorCode::TXN_OK);

        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMMIT);
        meta_service->commit_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_rs_key, &val), TxnErrorCode::TXN_OK);

        // finish_restore_job to COMPLETED
        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMPLETE);
        meta_service->finish_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        // this restore job key should be in COMPLETED state
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        RestoreJobCloudPB restore_job_pb;
        ASSERT_TRUE(restore_job_pb.ParseFromString(val));
        ASSERT_EQ(restore_job_pb.state(), RestoreJobCloudPB::COMPLETED);
        ASSERT_EQ(restore_job_pb.need_recycle_data(), false);
        std::vector<std::pair<std::string, doris::RowsetMetaCloudPB>> restore_job_rs_metas;
        MetaServiceCode code;
        std::string msg;
        scan_restore_job_rowset(txn.get(), instance_id, tablet_id, code, msg,
                                &restore_job_rs_metas);
        ASSERT_EQ(code, MetaServiceCode::OK) << msg;
        ASSERT_EQ(restore_job_rs_metas.size(), 1);
        req.Clear();
        res.Clear();
    }
    // finish restore job state PREPARED -> DROPPED
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // prepare restore job
        RestoreJobRequest make_req;
        RestoreJobResponse make_res;
        make_req.set_tablet_id(tablet_id);
        make_req.set_expiration(time(nullptr) + 3600);
        make_req.set_action(RestoreJobRequest::PREPARE);

        auto* tablet_meta = make_req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);
        auto* rs_meta = tablet_meta->add_rs_metas();
        *rs_meta = create_rowset(txn_id, tablet_id, partition_id, version);

        meta_service->prepare_restore_job(&cntl, &make_req, &make_res, nullptr);
        ASSERT_EQ(make_res.status().code(), MetaServiceCode::OK);
        std::string restore_job_key = job_restore_tablet_key({instance_id, tablet_id});
        std::string val;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        std::string restore_job_rs_key = job_restore_rowset_key({instance_id, tablet_id, version});
        ASSERT_EQ(txn->get(restore_job_rs_key, &val), TxnErrorCode::TXN_OK);

        // finish_restore_job to DROPPED
        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::ABORT);
        meta_service->finish_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK) << res.status().msg();

        // this restore job key should be in DROPPED state
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(restore_job_key, &val), TxnErrorCode::TXN_OK);
        RestoreJobCloudPB restore_job_pb;
        ASSERT_TRUE(restore_job_pb.ParseFromString(val));
        ASSERT_EQ(restore_job_pb.state(), RestoreJobCloudPB::DROPPED);
        ASSERT_EQ(restore_job_pb.need_recycle_data(), true);
        std::vector<std::pair<std::string, doris::RowsetMetaCloudPB>> restore_job_rs_metas;
        MetaServiceCode code;
        std::string msg;
        scan_restore_job_rowset(txn.get(), instance_id, tablet_id, code, msg,
                                &restore_job_rs_metas);
        ASSERT_EQ(code, MetaServiceCode::OK) << msg;
        ASSERT_EQ(restore_job_rs_metas.size(), 1);
        req.Clear();
        res.Clear();
    }
    // finish restore job invalid state PREPARED -> COMPLETED
    {
        reset_meta_service();
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(meta_tablet_idx_key({instance_id, tablet_id}), tablet_idx_val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);

        // prepare restore job
        RestoreJobRequest make_req;
        RestoreJobResponse make_res;
        make_req.set_tablet_id(tablet_id);
        make_req.set_expiration(time(nullptr) + 3600);
        make_req.set_action(RestoreJobRequest::PREPARE);

        // set tablet meta
        auto* tablet_meta = make_req.mutable_tablet_meta();
        tablet_meta->set_table_id(table_id);
        tablet_meta->set_index_id(index_id);
        tablet_meta->set_partition_id(partition_id);
        tablet_meta->set_tablet_id(tablet_id);
        tablet_meta->set_schema_version(1);
        auto* rs_meta = tablet_meta->add_rs_metas();
        *rs_meta = create_rowset(txn_id, tablet_id, partition_id, version);

        meta_service->prepare_restore_job(&cntl, &make_req, &make_res, nullptr);
        ASSERT_EQ(make_res.status().code(), MetaServiceCode::OK);

        // finish_restore_job to COMPLETED
        req.set_tablet_id(tablet_id);
        req.set_action(RestoreJobRequest::COMPLETE);
        meta_service->finish_restore_job(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("invalid state to complete") != std::string::npos);
    }
}

TEST(MetaServiceTest, SetSnapshotPropertyTest) {
    auto meta_service = get_meta_service();

    // Create a test instance first
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        req.set_instance_id("test_snapshot_instance");
        req.set_user_id("test_user");
        req.set_name("test_name");

        auto* sp = SyncPoint::get_instance();
        sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* key = try_any_cast<std::string*>(args[1]);
            *key = "test";
            auto* key_id = try_any_cast<int64_t*>(args[2]);
            *key_id = 1;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    auto* sp = SyncPoint::get_instance();
    sp->set_call_back("notify_refresh_instance_return",
                      [](auto&& args) { *try_any_cast<bool*>(args.back()) = true; });
    sp->enable_processing();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
        SyncPoint::get_instance()->disable_processing();
    };

    // Test case 1: Snapshot not ready (SNAPSHOT_SWITCH_DISABLED) - should fail
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("Snapshot is not ready") != std::string::npos);
    }

    // Initialize snapshot switch status to OFF so we can test snapshot functionality
    {
        InstanceKeyInfo key_info {"test_snapshot_instance"};
        std::string key;
        std::string val;
        instance_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        InstanceInfoPB instance;
        instance.ParseFromString(val);
        instance.set_snapshot_switch_status(SNAPSHOT_SWITCH_OFF);
        instance.set_multi_version_status(MULTI_VERSION_READ_WRITE);
        val = instance.SerializeAsString();
        txn->put(key, val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    // Test case 2: Valid "enabled" property with "true" value (after initialization)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 3: Valid "enabled" property with "false" value
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "false";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 4: Invalid "enabled" property value
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "invalid";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 5: Valid "max_reserved_snapshots" property (minimum value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "0";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 6: Valid "max_reserved_snapshots" property (maximum value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "35";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 7: Valid "max_reserved_snapshots" property (middle value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "10";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 8: Invalid "max_reserved_snapshots" property (negative value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "-1";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 9: Invalid "max_reserved_snapshots" property (too large value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "36";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 10: Invalid "max_reserved_snapshots" property (non-numeric value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "abc";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 11: Valid "snapshot_interval_seconds" property (minimum value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "3600";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 12: Valid "snapshot_interval_seconds" property (large value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "14400";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 13: Invalid "snapshot_interval_seconds" property (too small value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "3599";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 14: Invalid "snapshot_interval_seconds" property (non-numeric value)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "invalid";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 15: Unsupported property key
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())["unsupported_property"] = "value";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 16: Empty properties map
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        // Don't add any properties - properties map will be empty

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
    }

    // Test case 17: Multiple valid properties in single request
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "20";
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "12000";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 18: Mixed valid and invalid properties (should fail on first invalid)
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "10";
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "12000";
        (*req.mutable_properties())["unsupported_property"] = "value";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT) << res.ShortDebugString();
    }

    // Test case 19: Non-existent instance ID
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("non_existent_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::CLUSTER_NOT_FOUND);
    }
}

TEST(MetaServiceTest, SnapshotConfigLimitsTest) {
    auto meta_service = get_meta_service();

    // Create a test instance first
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        req.set_instance_id("test_snapshot_config_instance");
        req.set_user_id("test_user");
        req.set_name("test_name");

        auto* sp = SyncPoint::get_instance();
        sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* key = try_any_cast<std::string*>(args[1]);
            *key = "test";
            auto* key_id = try_any_cast<int64_t*>(args[2]);
            *key_id = 1;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    auto* sp = SyncPoint::get_instance();
    sp->set_call_back("notify_refresh_instance_return",
                      [](auto&& args) { *try_any_cast<bool*>(args.back()) = true; });
    sp->enable_processing();
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
        SyncPoint::get_instance()->disable_processing();
    };

    // Initialize snapshot switch status to OFF so we can test snapshot functionality
    {
        InstanceKeyInfo key_info {"test_snapshot_config_instance"};
        std::string key;
        std::string val;
        instance_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        InstanceInfoPB instance;
        instance.ParseFromString(val);
        instance.set_snapshot_switch_status(SNAPSHOT_SWITCH_OFF);
        val = instance.SerializeAsString();
        txn->put(key, val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    {
        brpc::Controller cntl;
        AlterInstanceRequest alter_req;
        AlterInstanceResponse alter_res;
        alter_req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        alter_req.set_instance_id("test_snapshot_config_instance");
        (*alter_req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &alter_req, &alter_res, nullptr);
        ASSERT_EQ(alter_res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(alter_res.status().msg().find("MULTI_VERSION_READ_WRITE") != std::string::npos);
    }

    // Set multi-version status to READ_WRITE
    {
        InstanceKeyInfo key_info {"test_snapshot_config_instance"};
        std::string key;
        std::string val;
        instance_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        InstanceInfoPB instance;
        instance.ParseFromString(val);
        instance.set_multi_version_status(MULTI_VERSION_READ_WRITE);
        val = instance.SerializeAsString();
        txn->put(key, val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    // Enable snapshot for this instance
    {
        brpc::Controller cntl;
        AlterInstanceRequest alter_req;
        AlterInstanceResponse alter_res;
        alter_req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        alter_req.set_instance_id("test_snapshot_config_instance");
        (*alter_req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &alter_req, &alter_res, nullptr);
        ASSERT_EQ(alter_res.status().code(), MetaServiceCode::OK);
    }

    // Save original config values
    int32_t orig_min_interval = config::snapshot_min_interval_seconds;
    int32_t orig_max_reserved = config::snapshot_max_reserved_num;

    // Temporarily modify config for testing
    config::snapshot_min_interval_seconds = 1800; // 30 minutes
    config::snapshot_max_reserved_num = 20;

    // Test case 1: interval below minimum limit
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_config_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "1799"; // Below min limit

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("minimum is 1800") != std::string::npos);
    }

    // Test case 2: interval within limits should succeed
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_config_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::SNAPSHOT_INTERVAL_SECONDS)] = "3600"; // Within limits

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 3: max_reserved_snapshots above maximum limit
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_config_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "21"; // Above max limit

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("maximum is 20") != std::string::npos);
    }

    // Test case 4: max_reserved_snapshots within limits should succeed
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_config_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::MAX_RESERVED_SNAPSHOTS)] = "10"; // Within limits

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Test case 5: unknown property should fail
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_snapshot_config_instance");
        (*req.mutable_properties())["unknown_property"] = "value";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("unknown snapshot property: unknown_property") !=
                    std::string::npos);
    }

    // Restore original config values
    config::snapshot_min_interval_seconds = orig_min_interval;
    config::snapshot_max_reserved_num = orig_max_reserved;
}

TEST(MetaServiceTest, SnapshotDefaultValuesTest) {
    auto meta_service = get_meta_service();

    // Create a test instance first
    {
        brpc::Controller cntl;
        CreateInstanceRequest req;
        req.set_instance_id("test_instance");
        req.set_user_id("test_user");
        req.set_name("test_name");

        auto* sp = SyncPoint::get_instance();
        sp->set_call_back("encrypt_ak_sk:get_encryption_key", [](auto&& args) {
            auto* ret = try_any_cast<int*>(args[0]);
            *ret = 0;
            auto* key = try_any_cast<std::string*>(args[1]);
            *key = "test";
            auto* key_id = try_any_cast<int64_t*>(args[2]);
            *key_id = 1;
        });
        sp->set_call_back("get_instance_id", [&](auto&& args) {
            auto* ret = try_any_cast_ret<std::string>(args);
            ret->first = "test_instance";
            ret->second = true;
        });
        sp->enable_processing();
        CreateInstanceResponse res;
        meta_service->create_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                      &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        sp->clear_all_call_backs();
        sp->clear_trace();
        sp->disable_processing();
    }

    // Initialize snapshot switch status to OFF so we can test snapshot functionality
    {
        InstanceKeyInfo key_info {"test_instance"};
        std::string key;
        std::string val;
        instance_key(key_info, &key);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(key, &val), TxnErrorCode::TXN_OK);
        InstanceInfoPB instance;
        instance.ParseFromString(val);
        instance.set_snapshot_switch_status(SNAPSHOT_SWITCH_OFF);
        instance.set_multi_version_status(MULTI_VERSION_READ_WRITE);
        val = instance.SerializeAsString();
        txn->put(key, val);
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    // First enable snapshot - should set default values
    {
        brpc::Controller cntl;
        AlterInstanceRequest req;
        AlterInstanceResponse res;
        req.set_op(AlterInstanceRequest::SET_SNAPSHOT_PROPERTY);
        req.set_instance_id("test_instance");
        (*req.mutable_properties())[AlterInstanceRequest_SnapshotProperty_Name(
                AlterInstanceRequest::ENABLE_SNAPSHOT)] = "true";

        meta_service->alter_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                     &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // Verify default values were set by checking instance
    {
        brpc::Controller cntl;
        GetInstanceRequest req;
        GetInstanceResponse res;
        req.set_instance_id("test_instance");
        req.set_cloud_unique_id("test_snapshot_defaults_unique_id");

        meta_service->get_instance(reinterpret_cast<::google::protobuf::RpcController*>(&cntl),
                                   &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

        const auto& instance = res.instance();
        ASSERT_EQ(instance.snapshot_switch_status(), SnapshotSwitchStatus::SNAPSHOT_SWITCH_ON);
        ASSERT_EQ(instance.snapshot_interval_seconds(), config::snapshot_min_interval_seconds);
        ASSERT_EQ(instance.max_reserved_snapshot(), 0);
    }
}

TEST(MetaServiceTest, CreateTabletIdempotentAndHandlingError) {
    DORIS_CLOUD_DEFER {
        SyncPoint::get_instance()->clear_all_call_backs();
        SyncPoint::get_instance()->disable_processing();
    };

    size_t case_num = 0;
    auto* sp = SyncPoint::get_instance();
    sp->set_call_back("meta_service_test:get_meta_tablet_key_error", [&case_num](auto&& args) {
        if (++case_num == 3) {
            auto* code = try_any_cast<TxnErrorCode*>(args[0]);
            *code = TxnErrorCode::TXN_INVALID_DATA;
        }
    });
    sp->enable_processing();

    auto meta_service = get_meta_service();
    brpc::Controller cntl;
    CreateTabletsRequest req;
    CreateTabletsResponse res;
    int64_t table_id = 100;
    int64_t index_id = 200;
    int64_t partition_id = 300;
    int64_t tablet_id = 400;
    req.set_db_id(1); // default db_id
    add_tablet(req, table_id, index_id, partition_id, tablet_id);
    // normal create
    meta_service->create_tablets(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    // idempotent
    meta_service->create_tablets(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::OK);

    // error handling
    meta_service->create_tablets(&cntl, &req, &res, nullptr);
    ASSERT_EQ(res.status().code(), MetaServiceCode::KV_TXN_GET_ERR);
}

TEST(MetaServiceTest, RowsetVisibleTimeTest) {
    auto meta_service = get_meta_service();
    using namespace std::chrono;
    int64_t txn_id = -1;
    // begin txn
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(666);
        txn_info_pb.set_label("test_label");
        txn_info_pb.add_table_ids(1234);
        txn_info_pb.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info_pb);
        BeginTxnResponse res;
        meta_service->begin_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
    }

    // mock rowset and tablet
    int64_t tablet_id_base = 1103;
    for (int i = 0; i < 5; ++i) {
        create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id_base + i);
        auto tmp_rowset = create_rowset(txn_id, tablet_id_base + i);
        CreateRowsetResponse res;
        commit_rowset(meta_service.get(), tmp_rowset, res);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
    {
        brpc::Controller cntl;
        CommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(666);
        req.set_txn_id(txn_id);
        CommitTxnResponse res;
        meta_service->commit_txn(reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req,
                                 &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    for (int i = 0; i < 5; ++i) {
        int64_t tablet_id = tablet_id_base + i;
        int64_t ver = 2;
        std::string rowset_key = meta_rowset_key({mock_instance, tablet_id, ver});
        std::string val;
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        ASSERT_EQ(txn->get(rowset_key, &val), TxnErrorCode::TXN_OK);
        RowsetMetaCloudPB rowset_pb;
        ASSERT_TRUE(rowset_pb.ParseFromString(val));
        ASSERT_TRUE(rowset_pb.has_visible_ts_ms());
        std::cout << rowset_pb.visible_ts_ms() << "\n";
        ASSERT_GT(rowset_pb.visible_ts_ms(), 0);
        auto visible_tp = time_point<system_clock>(milliseconds(rowset_pb.visible_ts_ms()));
        std::time_t visible_time = system_clock::to_time_t(visible_tp);
        std::cout << "visible time: "
                  << std::put_time(std::localtime(&visible_time), "%Y%m%d %H:%M:%S") << "\n";
    }
}

TEST(MetaServiceTest, UpdatePackedFileInfoTest) {
    auto meta_service = get_meta_service();

    // case: normal update merge file info - success case
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_packed_file_path("/path/to/packed/file1");

        // Set packed file info
        auto* packed_info = req.mutable_packed_file_info();
        packed_info->set_ref_cnt(5);
        packed_info->set_total_slice_num(10);
        packed_info->set_total_slice_bytes(1024000);
        packed_info->set_remaining_slice_bytes(819200);
        packed_info->set_created_at_sec(1666666666);
        packed_info->set_corrected(false);
        packed_info->set_state(PackedFileInfoPB::NORMAL);

        // Add small files
        auto* small_file = packed_info->add_slices();
        small_file->set_path("/small/file1.txt");
        small_file->set_offset(0);
        small_file->set_size(512);
        small_file->set_deleted(false);

        small_file = packed_info->add_slices();
        small_file->set_path("/small/file2.txt");
        small_file->set_offset(512);
        small_file->set_size(1024);
        small_file->set_deleted(false);

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // case: missing cloud_unique_id - should fail
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        // req.set_cloud_unique_id("test_cloud_unique_id"); // missing cloud_unique_id
        req.set_packed_file_path("/path/to/packed/file");

        auto* packed_info = req.mutable_packed_file_info();
        packed_info->set_ref_cnt(1);
        packed_info->set_total_slice_num(1);

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("cloud_unique_id is required") != std::string::npos);
    }

    // case: empty cloud_unique_id - should fail
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        req.set_cloud_unique_id(""); // empty cloud_unique_id
        req.set_packed_file_path("/path/to/merged/file");

        auto* merge_info = req.mutable_packed_file_info();
        merge_info->set_ref_cnt(1);

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("cloud_unique_id is required") != std::string::npos);
    }

    // case: missing packed_file_path - should fail
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        // req.set_packed_file_path("/path/to/merged/file"); // missing packed_file_path

        auto* merge_info = req.mutable_packed_file_info();
        merge_info->set_ref_cnt(1);

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("packed_file_path is required") != std::string::npos);
    }

    // case: empty packed_file_path - should fail
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_packed_file_path(""); // empty packed_file_path

        auto* merge_info = req.mutable_packed_file_info();
        merge_info->set_ref_cnt(1);

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("packed_file_path is required") != std::string::npos);
    }

    // case: missing packed_file_info - should fail
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_packed_file_path("/path/to/merged/file");
        // No packed_file_info set

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::INVALID_ARGUMENT);
        ASSERT_TRUE(res.status().msg().find("packed_file_info is required") != std::string::npos);
    }

    // case: test multiple operations - success case
    {
        brpc::Controller cntl;
        UpdatePackedFileInfoRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id_multi");
        req.set_packed_file_path("/path/to/merged/file_multi");

        // Set merge file info with multiple small files
        auto* merge_info = req.mutable_packed_file_info();
        merge_info->set_ref_cnt(3);
        merge_info->set_total_slice_num(5);
        merge_info->set_total_slice_bytes(2048000);
        merge_info->set_remaining_slice_bytes(1638400);
        merge_info->set_created_at_sec(1666666777);
        merge_info->set_corrected(true);
        merge_info->set_state(PackedFileInfoPB::NORMAL);

        // Add multiple small files
        for (int i = 1; i <= 5; ++i) {
            auto* small_file = merge_info->add_slices();
            small_file->set_path("/small/file" + std::to_string(i) + ".txt");
            small_file->set_offset(i * 1000);
            small_file->set_size(1000);
            small_file->set_deleted(i > 3); // Mark some as deleted
        }

        UpdatePackedFileInfoResponse res;
        meta_service->update_packed_file_info(
                reinterpret_cast<::google::protobuf::RpcController*>(&cntl), &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }
}

// Test: In versioned write mode, clean_txn_label should skip txn when recycle_key not found
TEST(MetaServiceTest, CleanTxnLabelVersionedWriteSkipWithoutRecycleKey) {
    auto meta_service = get_meta_service(false);
    std::string instance_id = "clean_txn_label_versioned_write_skip_test";
    int64_t db_id = 19872001;
    std::string label = "test_versioned_write_skip_label";

    // 1. Create versioned write instance
    {
        InstanceInfoPB instance_info;
        instance_info.set_instance_id(instance_id);
        instance_info.set_multi_version_status(MULTI_VERSION_WRITE_ONLY);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(instance_key(instance_id), instance_info.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        meta_service->resource_mgr()->refresh_instance(instance_id);
        ASSERT_TRUE(meta_service->resource_mgr()->is_version_write_enabled(instance_id));
    }

    // Mock get_instance_id to return versioned write instance
    auto sp = SyncPoint::get_instance();
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();
    DORIS_CLOUD_DEFER {
        sp->clear_all_call_backs();
        sp->disable_processing();
    };

    int64_t txn_id = -1;

    // 2. begin_txn
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(db_id);
        txn_info_pb.set_label(label);
        txn_info_pb.add_table_ids(1234);
        txn_info_pb.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info_pb);
        BeginTxnResponse res;
        meta_service->begin_txn(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
    }

    // 3. Create tablet and rowset, then commit_txn
    int64_t tablet_id = 110001;
    create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id);
    auto tmp_rowset = create_rowset(txn_id, tablet_id);
    {
        CreateRowsetResponse res;
        commit_rowset(meta_service.get(), tmp_rowset, res);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    {
        brpc::Controller cntl;
        CommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.set_txn_id(txn_id);
        CommitTxnResponse res;
        meta_service->commit_txn(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // 4. Verify recycle_key does NOT exist (versioned write mode doesn't write it during commit)
    std::string recycle_key_str = recycle_txn_key({instance_id, db_id, txn_id});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(recycle_key_str, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    // 5. Call clean_txn_label
    {
        brpc::Controller cntl;
        CleanTxnLabelRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.add_labels(label);
        CleanTxnLabelResponse res;
        meta_service->clean_txn_label(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // 6. Verify txn_info still exists (should NOT be deleted because recycle_key not found)
    std::string info_key = txn_info_key({instance_id, db_id, txn_id});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(info_key, &val), TxnErrorCode::TXN_OK); // Still exists
    }

    // 7. Verify label still contains this txn_id (txn was skipped, added to survival_txn_ids)
    std::string label_key_str = txn_label_key({instance_id, db_id, label});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(label_key_str, &val), TxnErrorCode::TXN_OK);
        TxnLabelPB label_pb;
        ASSERT_TRUE(label_pb.ParseFromArray(val.data(), val.size() - VERSION_STAMP_LEN));
        ASSERT_EQ(label_pb.txn_ids_size(), 1);
        ASSERT_EQ(label_pb.txn_ids(0), txn_id);
    }
}

// Test: In versioned write mode, clean_txn_label should delete txn when recycle_key exists
TEST(MetaServiceTest, CleanTxnLabelVersionedWriteDeleteWithRecycleKey) {
    auto meta_service = get_meta_service(false);
    std::string instance_id = "clean_txn_label_versioned_write_delete_test";
    int64_t db_id = 19872002;
    std::string label = "test_versioned_write_delete_label";

    // 1. Create versioned write instance
    {
        InstanceInfoPB instance_info;
        instance_info.set_instance_id(instance_id);
        instance_info.set_multi_version_status(MULTI_VERSION_WRITE_ONLY);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(instance_key(instance_id), instance_info.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        meta_service->resource_mgr()->refresh_instance(instance_id);
        ASSERT_TRUE(meta_service->resource_mgr()->is_version_write_enabled(instance_id));
    }

    // Mock get_instance_id
    auto sp = SyncPoint::get_instance();
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();
    DORIS_CLOUD_DEFER {
        sp->clear_all_call_backs();
        sp->disable_processing();
    };

    int64_t txn_id = -1;

    // 2. begin_txn
    {
        brpc::Controller cntl;
        BeginTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        TxnInfoPB txn_info_pb;
        txn_info_pb.set_db_id(db_id);
        txn_info_pb.set_label(label);
        txn_info_pb.add_table_ids(1234);
        txn_info_pb.set_timeout_ms(36000);
        req.mutable_txn_info()->CopyFrom(txn_info_pb);
        BeginTxnResponse res;
        meta_service->begin_txn(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        txn_id = res.txn_id();
    }

    // 3. Create tablet and rowset, then commit_txn
    int64_t tablet_id = 110002;
    create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id);
    auto tmp_rowset = create_rowset(txn_id, tablet_id);
    {
        CreateRowsetResponse res;
        commit_rowset(meta_service.get(), tmp_rowset, res);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    {
        brpc::Controller cntl;
        CommitTxnRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.set_txn_id(txn_id);
        CommitTxnResponse res;
        meta_service->commit_txn(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // 4. Manually write recycle_txn_key (simulate recycler has processed commit_txn_log)
    std::string recycle_key_str = recycle_txn_key({instance_id, db_id, txn_id});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        RecycleTxnPB recycle_pb;
        recycle_pb.set_creation_time(std::chrono::duration_cast<std::chrono::milliseconds>(
                                             std::chrono::system_clock::now().time_since_epoch())
                                             .count());
        recycle_pb.set_label(label);
        txn->put(recycle_key_str, recycle_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    // Verify recycle_key exists now
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(recycle_key_str, &val), TxnErrorCode::TXN_OK);
    }

    // 5. Call clean_txn_label
    {
        brpc::Controller cntl;
        CleanTxnLabelRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.add_labels(label);
        CleanTxnLabelResponse res;
        meta_service->clean_txn_label(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // 6. Verify txn_info is deleted
    std::string info_key = txn_info_key({instance_id, db_id, txn_id});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(info_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND); // Deleted
    }

    // 7. Verify txn_index is deleted
    std::string index_key_str = txn_index_key({instance_id, txn_id});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(index_key_str, &val), TxnErrorCode::TXN_KEY_NOT_FOUND); // Deleted
    }

    // 8. Verify recycle_key is deleted
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(recycle_key_str, &val), TxnErrorCode::TXN_KEY_NOT_FOUND); // Deleted
    }

    // 9. Verify label is deleted (all txns cleaned)
    std::string label_key_str = txn_label_key({instance_id, db_id, label});
    {
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(label_key_str, &val), TxnErrorCode::TXN_KEY_NOT_FOUND); // Deleted
    }
}

// Test: In versioned write mode with mixed txns, only txns with recycle_key are cleaned
TEST(MetaServiceTest, CleanTxnLabelVersionedWriteMixedTxns) {
    auto meta_service = get_meta_service(false);
    std::string instance_id = "clean_txn_label_versioned_write_mixed_test";
    int64_t db_id = 19872003;
    std::string label = "test_versioned_write_mixed_label";

    // 1. Create versioned write instance
    {
        InstanceInfoPB instance_info;
        instance_info.set_instance_id(instance_id);
        instance_info.set_multi_version_status(MULTI_VERSION_WRITE_ONLY);
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        txn->put(instance_key(instance_id), instance_info.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
        meta_service->resource_mgr()->refresh_instance(instance_id);
        ASSERT_TRUE(meta_service->resource_mgr()->is_version_write_enabled(instance_id));
    }

    // Mock get_instance_id
    auto sp = SyncPoint::get_instance();
    sp->set_call_back("get_instance_id", [&](auto&& args) {
        auto* ret = try_any_cast_ret<std::string>(args);
        ret->first = instance_id;
        ret->second = true;
    });
    sp->enable_processing();
    DORIS_CLOUD_DEFER {
        sp->clear_all_call_backs();
        sp->disable_processing();
    };

    // Create 3 txns with different labels
    std::vector<int64_t> txn_ids;
    std::vector<std::string> labels;
    for (int i = 0; i < 3; ++i) {
        int64_t txn_id = -1;
        std::string txn_label = label + "_" + std::to_string(i);
        labels.push_back(txn_label);

        // begin_txn
        {
            brpc::Controller cntl;
            BeginTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            TxnInfoPB txn_info_pb;
            txn_info_pb.set_db_id(db_id);
            txn_info_pb.set_label(txn_label);
            txn_info_pb.add_table_ids(1234);
            txn_info_pb.set_timeout_ms(36000);
            req.mutable_txn_info()->CopyFrom(txn_info_pb);
            BeginTxnResponse res;
            meta_service->begin_txn(&cntl, &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
            txn_id = res.txn_id();
        }

        // Create tablet and commit
        int64_t tablet_id = 110010 + i;
        create_tablet(meta_service.get(), 1234, 1235, 1236, tablet_id);
        auto tmp_rowset = create_rowset(txn_id, tablet_id);
        {
            CreateRowsetResponse res;
            commit_rowset(meta_service.get(), tmp_rowset, res);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        {
            brpc::Controller cntl;
            CommitTxnRequest req;
            req.set_cloud_unique_id("test_cloud_unique_id");
            req.set_db_id(db_id);
            req.set_txn_id(txn_id);
            CommitTxnResponse res;
            meta_service->commit_txn(&cntl, &req, &res, nullptr);
            ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
        }

        txn_ids.push_back(txn_id);
    }

    ASSERT_EQ(txn_ids.size(), 3);

    // 2. Manually write recycle_key for txn_ids[0] and txn_ids[2] only (not txn_ids[1])
    for (int i : {0, 2}) {
        std::string recycle_key_str = recycle_txn_key({instance_id, db_id, txn_ids[i]});
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        RecycleTxnPB recycle_pb;
        recycle_pb.set_creation_time(std::chrono::duration_cast<std::chrono::milliseconds>(
                                             std::chrono::system_clock::now().time_since_epoch())
                                             .count());
        recycle_pb.set_label(labels[i]);
        txn->put(recycle_key_str, recycle_pb.SerializeAsString());
        ASSERT_EQ(txn->commit(), TxnErrorCode::TXN_OK);
    }

    // 3. Call clean_txn_label for each label
    for (int i = 0; i < 3; ++i) {
        brpc::Controller cntl;
        CleanTxnLabelRequest req;
        req.set_cloud_unique_id("test_cloud_unique_id");
        req.set_db_id(db_id);
        req.add_labels(labels[i]);
        CleanTxnLabelResponse res;
        meta_service->clean_txn_label(&cntl, &req, &res, nullptr);
        ASSERT_EQ(res.status().code(), MetaServiceCode::OK);
    }

    // 4. Verify txn_ids[0] and txn_ids[2] are deleted (have recycle_key)
    for (int i : {0, 2}) {
        std::string info_key = txn_info_key({instance_id, db_id, txn_ids[i]});
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(info_key, &val), TxnErrorCode::TXN_KEY_NOT_FOUND);
    }

    // 5. Verify txn_ids[1] still exists (no recycle_key)
    {
        std::string info_key = txn_info_key({instance_id, db_id, txn_ids[1]});
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(info_key, &val), TxnErrorCode::TXN_OK); // Still exists
    }

    // 6. Verify labels[0] and labels[2] are deleted, labels[1] still exists
    for (int i : {0, 2}) {
        std::string label_key_str = txn_label_key({instance_id, db_id, labels[i]});
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(label_key_str, &val), TxnErrorCode::TXN_KEY_NOT_FOUND); // Deleted
    }

    {
        std::string label_key_str = txn_label_key({instance_id, db_id, labels[1]});
        std::unique_ptr<Transaction> txn;
        ASSERT_EQ(meta_service->txn_kv()->create_txn(&txn), TxnErrorCode::TXN_OK);
        std::string val;
        ASSERT_EQ(txn->get(label_key_str, &val), TxnErrorCode::TXN_OK); // Still exists
        TxnLabelPB label_pb;
        ASSERT_TRUE(label_pb.ParseFromArray(val.data(), val.size() - VERSION_STAMP_LEN));
        ASSERT_EQ(label_pb.txn_ids_size(), 1);
        ASSERT_EQ(label_pb.txn_ids(0), txn_ids[1]);
    }
}

} // namespace doris::cloud
