238 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			238 lines
		
	
	
		
			5.6 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /**
 | |
|  * Copyright (c) 2021 OceanBase
 | |
|  * OceanBase CE is licensed under Mulan PubL v2.
 | |
|  * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | |
|  * You may obtain a copy of Mulan PubL v2 at:
 | |
|  *          http://license.coscl.org.cn/MulanPubL-2.0
 | |
|  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | |
|  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | |
|  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | |
|  * See the Mulan PubL v2 for more details.
 | |
|  */
 | |
| 
 | |
| #include <gtest/gtest.h>
 | |
| #include <stdint.h>
 | |
| #include "storage/mock_tenant_module_env.h"
 | |
| #include "lib/file/file_directory_utils.h"
 | |
| #include "lib/ob_define.h"
 | |
| #include "logservice/palf/palf_env.h"
 | |
| #include "logservice/palf/palf_handle.h"
 | |
| #include "rpc/frame/ob_req_transport.h"
 | |
| #include "share/allocator/ob_tenant_mutil_allocator.h"
 | |
| 
 | |
| namespace oceanbase
 | |
| {
 | |
| namespace unittest
 | |
| {
 | |
| using namespace common;
 | |
| using namespace palf;
 | |
| 
 | |
| int thread_num = 100;
 | |
| int nbytes = 500;
 | |
| 
 | |
| class MockAppendCbWorker : public AppendCbWorker
 | |
| {
 | |
| public:
 | |
|   int push_append_cb(const int64_t id, AppendCb *cb, const LSN &end_lsn) override final
 | |
|   {
 | |
|     int ret = OB_SUCCESS;
 | |
|     UNUSED(id);
 | |
|     UNUSED(end_lsn);
 | |
|     cb->on_success();
 | |
|     return ret;
 | |
|   }
 | |
| };
 | |
| 
 | |
| class MockAppendCb : public AppendCb
 | |
| {
 | |
| public:
 | |
|   MockAppendCb()
 | |
|   {
 | |
|     is_called_ = true;
 | |
|   }
 | |
| 
 | |
|   int on_success() override final
 | |
|   {
 | |
|     ATOMIC_STORE(&is_called_, true);
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   int on_failure() override final
 | |
|   {
 | |
|     ATOMIC_STORE(&is_called_, true);
 | |
|     return true;
 | |
|   }
 | |
| 
 | |
|   void reset()
 | |
|   {
 | |
|     ATOMIC_STORE(&is_called_, false);
 | |
|   }
 | |
| 
 | |
|   bool is_called() const
 | |
|   {
 | |
|     return ATOMIC_LOAD(&is_called_);
 | |
|   }
 | |
| private:
 | |
|   bool is_called_;
 | |
| };
 | |
| 
 | |
| class StandalonePalfEnv : public ::testing::Test
 | |
| {
 | |
| public:
 | |
|   StandalonePalfEnv()
 | |
|     : self_(ObAddr::VER::IPV4, "127.0.0.1", 2021),
 | |
|       palf_env_(NULL),
 | |
|       transport_(NULL, NULL),
 | |
|       allocator_(500),
 | |
|       total_num_(0)
 | |
|   {
 | |
|   }
 | |
| public:
 | |
|   void SetUp()
 | |
|   {
 | |
|     EXPECT_EQ(OB_SUCCESS, MockTenantModuleEnv::get_instance().init());
 | |
| 
 | |
|     int ret = OB_SUCCESS;
 | |
| 
 | |
|     snprintf(log_dir_, OB_MAX_FILE_NAME_LENGTH, "./%s", "standalone_palf_bench");
 | |
| 
 | |
|     FileDirectoryUtils::delete_directory_rec(log_dir_);
 | |
|     FileDirectoryUtils::create_directory(log_dir_);
 | |
| 
 | |
|     PalfDiskOptions options;
 | |
|     options.log_disk_usage_limit_size_ = 500 * 1024 * 1024 * 1024LL;
 | |
| 
 | |
|     ObMemberList member_list;
 | |
|     EXPECT_EQ(OB_SUCCESS, member_list.add_server(self_));
 | |
| 
 | |
|     if (OB_FAIL(PalfEnv::create_palf_env(options, log_dir_, self_, &transport_,
 | |
|             &allocator_, palf_env_))) {
 | |
|       PALF_LOG(ERROR, "create_palf_env failed", K(ret));
 | |
|     } else if (OB_FAIL(palf_env_->create(1, handle_))) {
 | |
|       PALF_LOG(ERROR, "palf_env_ create failed", K(ret));
 | |
|     }
 | |
| 
 | |
|     EXPECT_EQ(OB_SUCCESS, handle_.set_initial_member_list(member_list, 1));
 | |
| 
 | |
|     while (true) {
 | |
|       ObRole role;
 | |
|       int64_t proposal_id = 0;
 | |
|       bool is_pending_state = false;
 | |
| 
 | |
|       handle_.get_role(role, proposal_id, is_pending_state);
 | |
| 
 | |
|       if (LEADER == role) {
 | |
|         break;
 | |
|       } else {
 | |
|         usleep(1000);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   void TearDown()
 | |
|   {
 | |
|     palf_env_->close(handle_);
 | |
|     PalfEnv::destroy_palf_env(palf_env_);
 | |
|     palf_env_ = NULL;
 | |
| 
 | |
|     MockTenantModuleEnv::get_instance().destroy();
 | |
|   }
 | |
| 
 | |
|   void smoke()
 | |
|   {
 | |
|     PalfAppendOptions options;
 | |
|     options.need_nonblock = false;
 | |
|     options.need_check_proposal_id = false;
 | |
| 
 | |
|     const int64_t NBYTES = 500;
 | |
|     char BUFFER[NBYTES];
 | |
|     memset(BUFFER, 'a', NBYTES);
 | |
| 
 | |
|     const int64_t CB_ARRAY_NUM = 1;
 | |
|     MockAppendCb cb_array[CB_ARRAY_NUM];
 | |
| 
 | |
|     while(true)
 | |
|     {
 | |
|       const int64_t begin_ts = ObTimeUtility::current_time();
 | |
|       for (int i = 0; i < CB_ARRAY_NUM; i++)
 | |
|       {
 | |
|         LSN lsn;
 | |
|         int64_t ts_ns = 0;
 | |
|         if (cb_array[i].is_called()) {
 | |
|           cb_array[i].reset();
 | |
|           EXPECT_EQ(OB_SUCCESS, handle_.append(options,
 | |
|                                                BUFFER,
 | |
|                                                nbytes,
 | |
|                                                0,
 | |
|                                                &cb_array[i],
 | |
|                                                lsn,
 | |
|                                                ts_ns));
 | |
| 
 | |
|           ATOMIC_INC(&total_num_);
 | |
|         }
 | |
|       }
 | |
|       const int64_t end_ts = ObTimeUtility::current_time();
 | |
| 
 | |
|       if (end_ts - begin_ts < 200) {
 | |
|         usleep(200 - (end_ts - begin_ts));
 | |
|       }
 | |
| 
 | |
|       if (REACH_TIME_INTERVAL(1000 * 1000)) {
 | |
|         PALF_LOG(ERROR, "total_num_", K(total_num_));
 | |
|         ATOMIC_STORE(&total_num_, 0);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
| public:
 | |
|   char log_dir_[OB_MAX_FILE_NAME_LENGTH];
 | |
|   ObAddr self_;
 | |
|   PalfEnv *palf_env_;
 | |
|   MockAppendCbWorker cb_worker_;
 | |
|   rpc::frame::ObReqTransport transport_;
 | |
|   ObTenantMutilAllocator allocator_;
 | |
| 
 | |
|   PalfHandle handle_;
 | |
|   int64_t total_num_;
 | |
| };
 | |
| 
 | |
| static void *append_thr_fn(void *arg)
 | |
| {
 | |
|   StandalonePalfEnv *p = reinterpret_cast<StandalonePalfEnv *>(arg);
 | |
| 
 | |
|   p->smoke();
 | |
| 
 | |
|   return (void *)0;
 | |
| }
 | |
| 
 | |
| TEST_F(StandalonePalfEnv, TestAppend)
 | |
| {
 | |
|   const int64_t THREAD_NUM = 2000;
 | |
|   pthread_t tids[THREAD_NUM];
 | |
| 
 | |
|   for (int64_t i = 0; i < thread_num; i++) {
 | |
|     EXPECT_EQ(0, pthread_create(&tids[i], NULL, append_thr_fn, this));
 | |
|   }
 | |
| 
 | |
|   for (int64_t i = 0; i < thread_num; i++) {
 | |
|     pthread_join(tids[i], NULL);
 | |
|   }
 | |
| }
 | |
| } // namespace unittest
 | |
| } // namespace oceanbase
 | |
| 
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
|   if (argc > 1) {
 | |
|     oceanbase::unittest::thread_num = strtol(argv[1], NULL, 10);
 | |
|     oceanbase::unittest::nbytes = strtol(argv[2], NULL, 10);
 | |
|   }
 | |
| 
 | |
|   OB_LOGGER.set_file_name("test_palf_bench.log", true);
 | |
|   OB_LOGGER.set_log_level("ERROR");
 | |
| 
 | |
|   PALF_LOG(INFO, "palf bench begin");
 | |
|   ::testing::InitGoogleTest(&argc, argv);
 | |
|   return RUN_ALL_TESTS();
 | |
| }
 | 
