267 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			8.2 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2021 OceanBase
 | |
|  * OceanBase CE is licensed under Mulan PubL v2.
 | |
|  * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | |
|  * You may obtain a copy of Mulan PubL v2 at:
 | |
|  *          http://license.coscl.org.cn/MulanPubL-2.0
 | |
|  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | |
|  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | |
|  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | |
|  * See the Mulan PubL v2 for more details.
 | |
|  */
 | |
| 
 | |
| #include "clog/ob_log_task.h"
 | |
| #include <gtest/gtest.h>
 | |
| #include "lib/allocator/ob_concurrent_fifo_allocator.h"
 | |
| #include "share/allocator/ob_tenant_mutil_allocator.h"
 | |
| #include "clog/ob_clog_config.h"
 | |
| #include "clog/ob_clog_mgr.h"
 | |
| #include "clog/ob_partition_log_service.h"
 | |
| #include "clog_mock_container/mock_submit_log_cb.h"
 | |
| #include "clog_mock_container/mock_log_sliding_window.h"
 | |
| namespace oceanbase {
 | |
| using namespace common;
 | |
| namespace clog {
 | |
| class MockSlidingCallBack : public MockObSlidingCallBack {
 | |
| public:
 | |
|   MockSlidingCallBack() : err_no_(OB_SUCCESS)
 | |
|   {}
 | |
|   virtual ~MockSlidingCallBack()
 | |
|   {}
 | |
|   int sliding_cb(const ObLogTask& log_task)
 | |
|   {
 | |
|     UNUSED(log_task);
 | |
|     return err_no_;
 | |
|   }
 | |
|   void set_err_no(const int err_no)
 | |
|   {
 | |
|     err_no_ = err_no;
 | |
|   }
 | |
| 
 | |
| private:
 | |
|   int err_no_;
 | |
| };
 | |
| }  // namespace clog
 | |
| namespace unittest {
 | |
| class ObLogTaskTest : public ::testing::Test {
 | |
| protected:
 | |
|   ObLogTaskTest() : log_task_(NULL), alloc_mgr_(NULL)
 | |
|   {}
 | |
|   virtual ~ObLogTaskTest()
 | |
|   {}
 | |
| 
 | |
| protected:
 | |
|   virtual void SetUp()
 | |
|   {
 | |
|     const uint64_t TABLE_ID = 15;
 | |
|     const uint32_t PARTITION_IDX = 5;
 | |
|     const int32_t PARTITION_CNT = 3;
 | |
|     partition_key_.init(TABLE_ID, PARTITION_IDX, PARTITION_CNT);
 | |
|     const uint64_t tenant_id = OB_SERVER_TENANT_ID;
 | |
| 
 | |
|     ObMemAttr attr(tenant_id, ObModIds::OB_TENANT_MUTIL_ALLOCATOR);
 | |
|     void* buf = ob_malloc(sizeof(common::ObTenantMutilAllocator), attr);
 | |
|     if (NULL == buf) {
 | |
|       CLOG_LOG(WARN, "alloc memory failed");
 | |
|       OB_ASSERT(FALSE);
 | |
|     }
 | |
|     alloc_mgr_ = new (buf) common::ObTenantMutilAllocator(tenant_id);
 | |
|     if (NULL == alloc_mgr_) {
 | |
|       CLOG_LOG(WARN, "alloc_mgr_ construct failed");
 | |
|       OB_ASSERT(FALSE);
 | |
|     }
 | |
|     if (NULL != (log_task_ = static_cast<clog::ObLogTask*>(alloc_mgr_->alloc_log_task_buf()))) {
 | |
|       new (log_task_) clog::ObLogTask();
 | |
|     } else {
 | |
|       CLOG_LOG(INFO, "log_task_ init fail");
 | |
|       OB_ASSERT(false);
 | |
|     }
 | |
|   }
 | |
|   virtual void TearDown()
 | |
|   {
 | |
|     ob_free(alloc_mgr_);
 | |
|     alloc_mgr_ = NULL;
 | |
|   }
 | |
| 
 | |
| protected:
 | |
|   clog::ObLogTask* log_task_;
 | |
|   clog::MockSlidingCallBack mock_sliding_cb_;
 | |
|   common::ObTenantMutilAllocator* alloc_mgr_;
 | |
|   common::ObPartitionKey partition_key_;
 | |
|   common::ObMemberList curr_member_list_;
 | |
|   common::ObVersion freeze_version_;
 | |
| };
 | |
| 
 | |
| // test for init, reset and destroy
 | |
| TEST_F(ObLogTaskTest, init_reset_destroy_test)
 | |
| {
 | |
|   // test for init and reset
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = true;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
| 
 | |
|   EXPECT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
| 
 | |
|   // log_task_ -> reset();
 | |
|   // EXPECT_EQ(OB_SUCCESS, log_task_ -> init(alloc_mgr_, &mock_sliding_cb_, submit_cb,REPLICA_NUM, curr_member_list_));
 | |
| 
 | |
|   OB_ASSERT(log_task_ != NULL);
 | |
|   log_task_->destroy();
 | |
| }
 | |
| // set_log
 | |
| TEST_F(ObLogTaskTest, set_log_test)
 | |
| {
 | |
|   clog::ObLogEntryHeader header;
 | |
|   clog::ObConfirmedInfo confirmed_info;
 | |
|   const ObProposalID PROPOSAL_ID;
 | |
|   const uint64_t LOG_ID = 150;
 | |
|   const char* BUF = "abc";
 | |
|   const int64_t DATA_LEN = 18;
 | |
|   const int64_t GENERATION_TIMESTAMP = 1000;
 | |
|   const int64_t EPOCH_ID = 800;
 | |
|   const int64_t SUBMIT_TS = 1300;
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = true;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
|   ASSERT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
| 
 | |
|   const char* buff = "This is a test log";
 | |
|   ASSERT_EQ(OB_SUCCESS,
 | |
|       header.generate_header(clog::OB_LOG_SUBMIT,
 | |
|           partition_key_,
 | |
|           LOG_ID,
 | |
|           BUF,
 | |
|           DATA_LEN,
 | |
|           GENERATION_TIMESTAMP,
 | |
|           EPOCH_ID,
 | |
|           PROPOSAL_ID,
 | |
|           SUBMIT_TS,
 | |
|           freeze_version_,
 | |
|           true));
 | |
|   EXPECT_EQ(OB_SUCCESS, log_task_->set_log(header, buff, true));
 | |
|   log_task_->set_log_confirmed();
 | |
|   log_task_->set_confirmed_info(confirmed_info);
 | |
| 
 | |
|   EXPECT_TRUE(log_task_->is_submit_log_exist());
 | |
|   EXPECT_TRUE(log_task_->is_confirmed_info_exist());
 | |
|   EXPECT_TRUE(log_task_->is_submit_log_body_exist());
 | |
|   log_task_->destroy();
 | |
| }
 | |
| 
 | |
| // log_cursor
 | |
| TEST_F(ObLogTaskTest, log_cursor_test)
 | |
| {
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = true;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
|   ASSERT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
|   clog::ObLogCursor log_cursor;
 | |
|   log_cursor.file_id_ = 1;
 | |
|   log_cursor.offset_ = 1000;
 | |
|   log_task_->set_log_cursor(log_cursor);
 | |
|   log_task_->get_log_cursor();
 | |
|   log_task_->destroy();
 | |
| }
 | |
| 
 | |
| TEST_F(ObLogTaskTest, cb_test)
 | |
| {
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = true;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
|   ASSERT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
|   common::ObPartitionKey pkey;
 | |
|   uint64_t log_id = 0;
 | |
|   const bool batch_committed = false;
 | |
|   const bool batch_last_succeed = false;
 | |
|   EXPECT_EQ(OB_SUCCESS, log_task_->submit_log_succ_cb(pkey, log_id, batch_committed, batch_last_succeed));
 | |
|   clog::MockObSubmitLogCb submit_cb_obj;
 | |
|   // log_task_ -> reset();
 | |
|   // ASSERT_EQ(OB_SUCCESS, log_task_ -> init(alloc_mgr_, &mock_sliding_cb_, &submit_cb_obj,
 | |
|   // REPLICA_NUM,curr_member_list_)); EXPECT_EQ(OB_SUCCESS, log_task_ -> submit_log_succ_cb()); EXPECT_TRUE(log_task_ ->
 | |
|   // is_on_success_cb_called()); log_task_ -> destroy();
 | |
| }
 | |
| 
 | |
| TEST_F(ObLogTaskTest, ack_majority_test)
 | |
| {
 | |
|   common::ObAddr member1;
 | |
|   common::ObAddr member2;
 | |
|   common::ObAddr member3;
 | |
|   common::ObAddr member4;  // not include
 | |
|   member1.parse_from_cstring("127.0.0.1:8000");
 | |
|   member2.parse_from_cstring("127.0.0.1:8001");
 | |
|   member3.parse_from_cstring("127.0.0.1:8002");
 | |
|   curr_member_list_.add_server(member1);
 | |
|   curr_member_list_.add_server(member2);
 | |
|   curr_member_list_.add_server(member3);
 | |
| 
 | |
|   EXPECT_EQ(0, log_task_->ack_log(member3));
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = true;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
|   ASSERT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
|   EXPECT_EQ(OB_SUCCESS, log_task_->ack_log(member1));
 | |
|   EXPECT_EQ(OB_SUCCESS, log_task_->ack_log(member2));
 | |
|   EXPECT_EQ(OB_SUCCESS, log_task_->ack_log(member3));
 | |
| 
 | |
|   log_task_->set_flush_local_finished();
 | |
|   log_task_->set_flush_local_finished();
 | |
|   EXPECT_TRUE(log_task_->try_set_majority_finished());
 | |
|   ASSERT_TRUE(log_task_->is_majority_finished());
 | |
|   log_task_->destroy();
 | |
| }
 | |
| 
 | |
| TEST_F(ObLogTaskTest, on_pop_test)
 | |
| {
 | |
|   mock_sliding_cb_.set_err_no(OB_SUCCESS);
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = true;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
|   ASSERT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
|   // EXPECT_EQ(OB_SUCCESS, log_task_ -> on_pop());
 | |
|   log_task_->destroy();
 | |
| }
 | |
| 
 | |
| TEST_F(ObLogTaskTest, misc_test)
 | |
| {
 | |
|   const int64_t REPLICA_NUM = 3;
 | |
|   const bool need_replay = false;
 | |
|   clog::ObISubmitLogCb* submit_cb = NULL;
 | |
|   clog::ObConfirmedInfo confirmed_info;
 | |
|   ASSERT_EQ(OB_SUCCESS, log_task_->init(submit_cb, REPLICA_NUM, need_replay));
 | |
| 
 | |
|   // CONFIRM_SUBMITTED
 | |
|   log_task_->set_log_confirmed();
 | |
|   ASSERT_TRUE(log_task_->is_log_confirmed());
 | |
| 
 | |
|   // can be removed = CONFIRM_SUBMITTED + LOCAL_FLUSHED
 | |
|   EXPECT_FALSE(log_task_->can_be_removed());
 | |
|   log_task_->set_confirmed_info(confirmed_info);
 | |
|   log_task_->set_index_log_submitted();
 | |
|   EXPECT_TRUE(log_task_->can_be_removed());
 | |
| 
 | |
|   clog::ObILogExtRingBufferData* log_task = NULL;
 | |
|   ASSERT_FALSE(log_task_->can_overwrite(log_task));
 | |
| 
 | |
|   ASSERT_FALSE(log_task_->need_replay());
 | |
|   log_task_->try_set_need_replay(false);
 | |
|   ASSERT_FALSE(log_task_->need_replay());
 | |
|   log_task_->try_set_need_replay(true);
 | |
|   ASSERT_TRUE(log_task_->need_replay());
 | |
| 
 | |
|   // reset_state
 | |
|   log_task_->reset_state(false);
 | |
| 
 | |
|   // reset_log_cursor
 | |
|   log_task_->reset_log_cursor();
 | |
|   log_task_->destroy();
 | |
| }
 | |
| 
 | |
| }  // namespace unittest
 | |
| }  // namespace oceanbase
 | |
| int main(int argc, char** argv)
 | |
| {
 | |
|   oceanbase::common::ObLogger::get_logger().set_log_level("DEBUG");
 | |
|   ::testing::InitGoogleTest(&argc, argv);
 | |
|   return RUN_ALL_TESTS();
 | |
| }
 | 
