Co-authored-by: obdev <obdev@oceanbase.com> Co-authored-by: obdev <obdev@oceanbase.com> Co-authored-by: obdev <obdev@oceanbase.com> Co-authored-by: obdev <obdev@oceanbase.com> Co-authored-by: obdev <obdev@oceanbase.com>
		
			
				
	
	
		
			258 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			258 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/**
 | 
						|
 * Copyright (c) 2021 OceanBase
 | 
						|
 * OceanBase CE is licensed under Mulan PubL v2.
 | 
						|
 * You can use this software according to the terms and conditions of the Mulan PubL v2.
 | 
						|
 * You may obtain a copy of Mulan PubL v2 at:
 | 
						|
 *          http://license.coscl.org.cn/MulanPubL-2.0
 | 
						|
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 | 
						|
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 | 
						|
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 | 
						|
 * See the Mulan PubL v2 for more details.
 | 
						|
 */
 | 
						|
 | 
						|
#define USING_LOG_PREFIX TABLELOCK
 | 
						|
 | 
						|
#include <gtest/gtest.h>
 | 
						|
#define protected public
 | 
						|
#define private public
 | 
						|
 | 
						|
#include "common/rowkey/ob_store_rowkey.h"
 | 
						|
#include "storage/ls/ob_freezer.h"
 | 
						|
#include "storage/memtable/ob_memtable_util.h"
 | 
						|
#include "mtlenv/mock_tenant_module_env.h"
 | 
						|
#include "storage/meta_mem/ob_tenant_meta_mem_mgr.h"
 | 
						|
#include "storage/tablelock/ob_lock_memtable.h"
 | 
						|
#include "storage/tablelock/ob_mem_ctx_table_lock.h"
 | 
						|
#include "table_lock_common_env.h"
 | 
						|
 | 
						|
namespace oceanbase
 | 
						|
{
 | 
						|
using namespace common;
 | 
						|
using namespace share;
 | 
						|
using namespace storage;
 | 
						|
using namespace memtable;
 | 
						|
 | 
						|
namespace memtable
 | 
						|
{
 | 
						|
 | 
						|
void ObMemtableCtx::update_max_submitted_seq_no(const int64_t seq_no)
 | 
						|
{
 | 
						|
  UNUSEDx(seq_no);
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
namespace transaction
 | 
						|
{
 | 
						|
namespace tablelock
 | 
						|
{
 | 
						|
 | 
						|
int ObLockMemtable::update_lock_status(
 | 
						|
    const ObTableLockOp &op_info,
 | 
						|
    const share::SCN &commit_version,
 | 
						|
    const share::SCN &commit_scn,
 | 
						|
    const ObTableLockOpStatus status)
 | 
						|
{
 | 
						|
  UNUSEDx(op_info, commit_version, commit_scn, status);
 | 
						|
  return OB_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
class TestLockTableCallback : public ::testing::Test
 | 
						|
{
 | 
						|
public:
 | 
						|
  TestLockTableCallback()
 | 
						|
    : ls_id_(1),
 | 
						|
      fake_t3m_(common::OB_SERVER_TENANT_ID)
 | 
						|
  {
 | 
						|
    LOG_INFO("construct TestLockTableCallback");
 | 
						|
  }
 | 
						|
  ~TestLockTableCallback() {}
 | 
						|
 | 
						|
  static void SetUpTestCase();
 | 
						|
  static void TearDownTestCase();
 | 
						|
  virtual void SetUp() override
 | 
						|
  {
 | 
						|
    create_memtable();
 | 
						|
    init_mem_ctx(handle_);
 | 
						|
    LOG_INFO("set up success");
 | 
						|
  }
 | 
						|
  virtual void TearDown() override
 | 
						|
  {
 | 
						|
    LOG_INFO("tear down success");
 | 
						|
  }
 | 
						|
private:
 | 
						|
  void create_memtable()
 | 
						|
  {
 | 
						|
    ObITable::TableKey table_key;
 | 
						|
    table_key.table_type_ = ObITable::LOCK_MEMTABLE;
 | 
						|
    table_key.tablet_id_ = LS_LOCK_TABLET;
 | 
						|
    table_key.scn_range_.start_scn_.convert_for_gts(1); // fake
 | 
						|
    table_key.scn_range_.end_scn_.convert_for_gts(2); // fake
 | 
						|
 | 
						|
    ASSERT_EQ(OB_SUCCESS, memtable_.init(table_key, ls_id_, &freezer_));
 | 
						|
    ASSERT_EQ(OB_SUCCESS, handle_.set_table(&memtable_, &fake_t3m_, ObITable::LOCK_MEMTABLE));
 | 
						|
  }
 | 
						|
 | 
						|
  void init_mem_ctx(ObTableHandleV2 &lock_memtable_handle)
 | 
						|
  {
 | 
						|
    mt_ctx_.is_inited_ = true;
 | 
						|
    mt_ctx_.ctx_cb_allocator_.init(common::OB_SERVER_TENANT_ID);
 | 
						|
    ASSERT_EQ(OB_SUCCESS, mt_ctx_.enable_lock_table(lock_memtable_handle));
 | 
						|
  }
 | 
						|
 | 
						|
  void create_callback(const ObTableLockOp &lock_op, ObOBJLockCallback *&cb)
 | 
						|
  {
 | 
						|
    int ret = OB_SUCCESS;
 | 
						|
    bool is_replay = false;
 | 
						|
    ObMemCtxLockOpLinkNode *lock_op_node = nullptr;
 | 
						|
    static ObFakeStoreRowKey tablelock_fake_rowkey("tbl", 3);
 | 
						|
    const ObStoreRowkey &rowkey = tablelock_fake_rowkey.get_rowkey();
 | 
						|
    ObMemtableKey mt_key;
 | 
						|
    ret = mt_ctx_.lock_mem_ctx_.add_lock_record(lock_op,
 | 
						|
                                                lock_op_node,
 | 
						|
                                                is_replay);
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
    cb = mt_ctx_.alloc_table_lock_callback(mt_ctx_,
 | 
						|
                                           &memtable_);
 | 
						|
    ASSERT_NE(nullptr, cb);
 | 
						|
    ret = mt_key.encode(&rowkey);
 | 
						|
    ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
    cb->set(mt_key, lock_op_node);
 | 
						|
  }
 | 
						|
 | 
						|
private:
 | 
						|
  ObLSID ls_id_;
 | 
						|
  ObLockMemtable memtable_;
 | 
						|
  ObTableHandleV2 handle_;
 | 
						|
  ObTenantMetaMemMgr fake_t3m_;
 | 
						|
  ObFreezer freezer_;
 | 
						|
 | 
						|
  ObMemtableCtx mt_ctx_;
 | 
						|
};
 | 
						|
 | 
						|
void TestLockTableCallback::SetUpTestCase()
 | 
						|
{
 | 
						|
  LOG_INFO("SetUpTestCase");
 | 
						|
  init_default_lock_test_value();
 | 
						|
}
 | 
						|
 | 
						|
void TestLockTableCallback::TearDownTestCase()
 | 
						|
{
 | 
						|
  LOG_INFO("TearDownTestCase");
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(TestLockTableCallback, callback)
 | 
						|
{
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  bool lock_exist = false;
 | 
						|
  unsigned char lock_mode_in_same_trans = 0x0;
 | 
						|
  const bool for_replay = false;
 | 
						|
  ObIMemtable *memtable = nullptr;
 | 
						|
  ObOBJLockCallback *cb = nullptr;
 | 
						|
  // 1. UNNSED CALLBACK TYPE
 | 
						|
  LOG_INFO("TestLockTableCallback::callback 1.");
 | 
						|
  static const int UNUSED_TYPE_NUM = 4;
 | 
						|
  create_callback(DEFAULT_IN_TRANS_LOCK_OP, cb);
 | 
						|
  ret = cb->elr_trans_preparing();
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  // 2. TCB_PRINT_CALLBACK
 | 
						|
  LOG_INFO("TestLockTableCallback::callback 2.");
 | 
						|
  ret = cb->print_callback();
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  // 3. IN_TRANS_LOCK
 | 
						|
  // 3.1 intrans commit
 | 
						|
  LOG_INFO("TestLockTableCallback::callback 3.1");
 | 
						|
  ret = mt_ctx_.check_lock_exist(DEFAULT_IN_TRANS_LOCK_OP.lock_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.owner_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.lock_mode_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.op_type_,
 | 
						|
                                 lock_exist,
 | 
						|
                                 lock_mode_in_same_trans);
 | 
						|
  ASSERT_EQ(lock_exist, true);
 | 
						|
  ret = cb->trans_commit();
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ret = mt_ctx_.check_lock_exist(DEFAULT_IN_TRANS_LOCK_OP.lock_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.owner_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.lock_mode_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.op_type_,
 | 
						|
                                 lock_exist,
 | 
						|
                                 lock_mode_in_same_trans);
 | 
						|
  ASSERT_EQ(lock_exist, false);
 | 
						|
  // 3.2 intrans abort
 | 
						|
  LOG_INFO("TestLockTableCallback::callback 3.2");
 | 
						|
  create_callback(DEFAULT_IN_TRANS_LOCK_OP, cb);
 | 
						|
  ret = mt_ctx_.check_lock_exist(DEFAULT_IN_TRANS_LOCK_OP.lock_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.owner_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.lock_mode_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.op_type_,
 | 
						|
                                 lock_exist,
 | 
						|
                                 lock_mode_in_same_trans);
 | 
						|
  ASSERT_EQ(lock_exist, true);
 | 
						|
  ret = cb->trans_abort();
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ret = mt_ctx_.check_lock_exist(DEFAULT_IN_TRANS_LOCK_OP.lock_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.owner_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.lock_mode_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.op_type_,
 | 
						|
                                 lock_exist,
 | 
						|
                                 lock_mode_in_same_trans);
 | 
						|
  ASSERT_EQ(lock_exist, false);
 | 
						|
  // 3.3 intrans stmt abort
 | 
						|
  LOG_INFO("TestLockTableCallback::callback 3.3");
 | 
						|
  create_callback(DEFAULT_IN_TRANS_LOCK_OP, cb);
 | 
						|
  ret = mt_ctx_.check_lock_exist(DEFAULT_IN_TRANS_LOCK_OP.lock_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.owner_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.lock_mode_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.op_type_,
 | 
						|
                                 lock_exist,
 | 
						|
                                 lock_mode_in_same_trans);
 | 
						|
  ASSERT_EQ(lock_exist, true);
 | 
						|
  ret = cb->rollback_callback();
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ret = mt_ctx_.check_lock_exist(DEFAULT_IN_TRANS_LOCK_OP.lock_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.owner_id_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.lock_mode_,
 | 
						|
                                 DEFAULT_IN_TRANS_LOCK_OP.op_type_,
 | 
						|
                                 lock_exist,
 | 
						|
                                 lock_mode_in_same_trans);
 | 
						|
  ASSERT_EQ(lock_exist, false);
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(TestLockTableCallback, basic)
 | 
						|
{
 | 
						|
  LOG_INFO("TestLockTableCallback::basic");
 | 
						|
  int ret = OB_SUCCESS;
 | 
						|
  ObOBJLockCallback *cb = nullptr;
 | 
						|
 | 
						|
  ObTableLockOp lock_op = DEFAULT_IN_TRANS_LOCK_OP;
 | 
						|
  create_callback(lock_op, cb);
 | 
						|
  ASSERT_EQ(lock_op.lock_seq_no_, cb->get_seq_no());
 | 
						|
  ASSERT_EQ(false, cb->must_log());
 | 
						|
  ASSERT_EQ(false, cb->log_synced());
 | 
						|
  share::SCN scn_10;
 | 
						|
  scn_10.convert_for_logservice(10);
 | 
						|
  ret = cb->log_sync(scn_10);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(true, cb->log_synced());
 | 
						|
  ASSERT_EQ(LS_LOCK_TABLET, cb->get_tablet_id());
 | 
						|
 | 
						|
  TableLockRedoDataNode redo_node;
 | 
						|
  ret = cb->get_redo(redo_node);
 | 
						|
  ASSERT_EQ(OB_SUCCESS, ret);
 | 
						|
  ASSERT_EQ(redo_node.lock_id_, DEFAULT_IN_TRANS_LOCK_OP.lock_id_);
 | 
						|
}
 | 
						|
 | 
						|
} // tablelock
 | 
						|
} // transaction
 | 
						|
} // oceanbase
 | 
						|
 | 
						|
int main(int argc, char **argv)
 | 
						|
{
 | 
						|
  system("rm -f test_lock_table_callback.log*");
 | 
						|
  oceanbase::common::ObLogger::get_logger().set_file_name("test_lock_table_callback.log", true);
 | 
						|
  oceanbase::common::ObLogger::get_logger().set_log_level("DEBUG");
 | 
						|
  oceanbase::common::ObLogger::get_logger().set_enable_async_log(false);
 | 
						|
  ::testing::InitGoogleTest(&argc, argv);
 | 
						|
  return RUN_ALL_TESTS();
 | 
						|
}
 |