| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- // Copyright (c) Meta Platforms, Inc. and affiliates.
- //
- // This source code is licensed under both the GPLv2 (found in the
- // COPYING file in the root directory) and Apache 2.0 License
- // (found in the LICENSE.Apache file in the root directory).
- #pragma once
- #include "file/file_util.h"
- #include "rocksdb/utilities/transaction_db.h"
- #include "test_util/testharness.h"
- #include "utilities/transactions/lock/point/point_lock_manager.h"
- #include "utilities/transactions/lock/point/point_lock_manager_test_common.h"
- #include "utilities/transactions/pessimistic_transaction_db.h"
- namespace ROCKSDB_NAMESPACE {
- class PointLockManagerTest : public testing::Test {
- public:
- void init() {
- env_ = Env::Default();
- db_dir_ = test::PerThreadDBPath("point_lock_manager_test");
- ASSERT_OK(env_->CreateDir(db_dir_));
- Options opt;
- opt.create_if_missing = true;
- // Reduce the number of stripes to 4 to increase contention in test
- txndb_opt_.num_stripes = 4;
- txndb_opt_.transaction_lock_timeout = 0;
- ASSERT_OK(TransactionDB::Open(opt, txndb_opt_, db_dir_, &db_));
- wait_sync_point_name_ = "PointLockManager::AcquireWithTimeout:WaitingTxn";
- }
- void SetUp() override {
- init();
- // CAUTION: This test creates a separate lock manager object (right, NOT
- // the one that the TransactionDB is using!), and runs tests on it.
- locker_.reset(new PointLockManager(
- static_cast<PessimisticTransactionDB*>(db_), txndb_opt_));
- }
- void TearDown() override {
- std::string errmsg;
- auto no_lock_held = verifyNoLocksHeld(locker_, errmsg);
- ASSERT_TRUE(no_lock_held) << errmsg;
- delete db_;
- EXPECT_OK(DestroyDir(env_, db_dir_));
- }
- PessimisticTransaction* NewTxn(
- TransactionOptions txn_opt = TransactionOptions()) {
- // override deadlock_timeout_us;
- txn_opt.deadlock_timeout_us = deadlock_timeout_us;
- Transaction* txn = db_->BeginTransaction(WriteOptions(), txn_opt);
- return static_cast<PessimisticTransaction*>(txn);
- }
- int64_t deadlock_timeout_us = 0;
- void UsePerKeyPointLockManager() {
- locker_.reset(new PerKeyPointLockManager(
- static_cast<PessimisticTransactionDB*>(db_), txndb_opt_));
- }
- protected:
- Env* env_;
- TransactionDBOptions txndb_opt_;
- std::shared_ptr<LockManager> locker_;
- const char* wait_sync_point_name_;
- friend void PointLockManagerTestExternalSetup(PointLockManagerTest*);
- std::string db_dir_;
- TransactionDB* db_;
- };
- void BlockUntilWaitingTxn(const char* sync_point_name, port::Thread& t,
- std::function<void()> f) {
- std::atomic<bool> reached(false);
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->SetCallBack(
- sync_point_name, [&](void* /*arg*/) { reached.store(true); });
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->EnableProcessing();
- t = port::Thread(f);
- // timeout after 30 seconds, so test does not hang forever
- // 30 seconds should be enough for the test to reach the expected state
- // without causing too much flakiness
- for (int i = 0; i < 3000; i++) {
- if (reached.load()) {
- break;
- }
- std::this_thread::sleep_for(std::chrono::milliseconds(10));
- }
- ASSERT_TRUE(reached.load());
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->DisableProcessing();
- ROCKSDB_NAMESPACE::SyncPoint::GetInstance()->ClearAllCallBacks();
- }
- } // namespace ROCKSDB_NAMESPACE
|