revision-id: b7ef984c04343bd9a5db167ab3c54cba6170eeef (v5.8-1035-gb7ef984c0) parent(s): 7348e2db12ef63966daa917402abad5102e77cd2 author: Sergei Petrunia committer: Sergei Petrunia timestamp: 2019-03-05 01:54:26 +0300 message: Range Locking: add a basic unit test --- CMakeLists.txt | 1 + Makefile | 1 + TARGETS | 5 + src.mk | 1 + utilities/transactions/range_locking_test.cc | 157 +++++++++++++++++++++++++++ 5 files changed, 165 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9795083ef..57d5d6180 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1009,6 +1009,7 @@ if(WITH_TESTS) utilities/transactions/transaction_test.cc utilities/transactions/write_prepared_transaction_test.cc utilities/transactions/write_unprepared_transaction_test.cc + utilities/transactions/range_locking_test.cc utilities/ttl/ttl_test.cc utilities/write_batch_with_index/write_batch_with_index_test.cc ) diff --git a/Makefile b/Makefile index 074194b32..9ece4310c 100644 --- a/Makefile +++ b/Makefile @@ -537,6 +537,7 @@ TESTS = \ db_universal_compaction_test \ trace_analyzer_test \ repeatable_thread_test \ + range_locking_test \ PARALLEL_TEST = \ backupable_db_test \ diff --git a/TARGETS b/TARGETS index 2fff0edbd..e06f38771 100644 --- a/TARGETS +++ b/TARGETS @@ -930,6 +930,11 @@ ROCKS_TESTS = [ "db/range_del_aggregator_test.cc", "serial", ], + [ + "range_locking_test", + "utilities/transactions/range_locking_test.cc", + "serial", + ], [ "rate_limiter_test", "util/rate_limiter_test.cc", diff --git a/src.mk b/src.mk index f3372258f..de0644cac 100644 --- a/src.mk +++ b/src.mk @@ -425,6 +425,7 @@ MAIN_SOURCES = \ utilities/spatialdb/spatial_db_test.cc \ utilities/table_properties_collectors/compact_on_deletion_collector_test.cc \ utilities/transactions/optimistic_transaction_test.cc \ + utilities/transactions/range_locking_test.cc \ utilities/transactions/transaction_test.cc \ utilities/transactions/write_prepared_transaction_test.cc \ utilities/transactions/write_unprepared_transaction_test.cc \ diff --git a/utilities/transactions/range_locking_test.cc b/utilities/transactions/range_locking_test.cc new file mode 100644 index 000000000..fff4a0e26 --- /dev/null +++ b/utilities/transactions/range_locking_test.cc @@ -0,0 +1,157 @@ +#ifndef ROCKSDB_LITE + +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif + +#include "utilities/transactions/transaction_test.h" + +#include <algorithm> +#include <functional> +#include <string> +#include <thread> + +#include "db/db_impl.h" +#include "rocksdb/db.h" +#include "rocksdb/options.h" +#include "rocksdb/perf_context.h" +#include "rocksdb/utilities/transaction.h" +#include "rocksdb/utilities/transaction_db.h" +#include "table/mock_table.h" +#include "util/fault_injection_test_env.h" +#include "util/random.h" +#include "util/string_util.h" +#include "util/sync_point.h" +#include "util/testharness.h" +#include "util/testutil.h" +#include "util/transaction_test_util.h" +#include "utilities/merge_operators.h" +#include "utilities/merge_operators/string_append/stringappend.h" +#include "utilities/transactions/pessimistic_transaction_db.h" + +#include "port/port.h" + +using std::string; + +namespace rocksdb { + + +void range_endpoint_convert_same(const rocksdb::Slice &key, + std::string *res) +{ + res->clear(); + res->append(key.data(), key.size()); +} + +int range_endpoints_compare_default(const char *a, size_t a_len, + const char *b, size_t b_len) +{ + return Slice(a, a_len).compare(Slice(b, b_len)); +} + +class RangeLockingTest : public ::testing::Test { + public: + TransactionDB* db; + std::string dbname; + Options options; + + TransactionDBOptions txn_db_options; + bool use_stackable_db_; + + RangeLockingTest() + : db(nullptr) { + options.create_if_missing = true; + dbname = test::PerThreadDBPath("transaction_testdb"); + + DestroyDB(dbname, options); + Status s; + s = TransactionDB::Open(options, txn_db_options, dbname, &db); + assert(s.ok()); + + db->use_range_locking= true; + rocksdb::RangeLockMgrControl *mgr= db->get_range_lock_manager(); + assert(mgr); + + mgr->set_endpoint_cmp_functions(range_endpoint_convert_same, + range_endpoints_compare_default); + // can also: mgr->set_max_lock_memory(rocksdb_max_lock_memory); + } + + ~RangeLockingTest() { + delete db; + db = nullptr; + // This is to skip the assert statement in FaultInjectionTestEnv. There + // seems to be a bug in btrfs that the makes readdir return recently + // unlink-ed files. By using the default fs we simply ignore errors resulted + // from attempting to delete such files in DestroyDB. + DestroyDB(dbname, options); + } +}; + +// TODO: set a smaller lock wait timeout so that the test runs faster. +TEST_F(RangeLockingTest, BasicRangeLocking) { + WriteOptions write_options; + TransactionOptions txn_options; + std::string value; + ReadOptions read_options; + + Transaction* txn0 = db->BeginTransaction(write_options, txn_options); + Transaction* txn1 = db->BeginTransaction(write_options, txn_options); + + // Get a range lock + { + auto s= txn0->GetRangeLock(db->DefaultColumnFamily(), + Slice("a"), Slice("c")); + ASSERT_EQ(s, Status::OK()); + } + + + // Check that range Lock inhibits an overlapping range lock + { + auto s= txn1->GetRangeLock(db->DefaultColumnFamily(), + Slice("b"), Slice("z")); + ASSERT_TRUE(s.IsTimedOut()); + } + + // Check that range Lock inhibits an overlapping point lock + { + auto s= txn1->GetForUpdate(read_options, db->DefaultColumnFamily(), + Slice("b"), &value); + ASSERT_TRUE(s.IsTimedOut()); + } + + // Get a point lock, check that it inhibits range locks + { + auto s= txn0->Put(db->DefaultColumnFamily(), + Slice("d"), Slice("value")); + ASSERT_EQ(s, Status::OK()); + + auto s2= txn1->GetRangeLock(db->DefaultColumnFamily(), + Slice("c"), Slice("e")); + ASSERT_TRUE(s2.IsTimedOut()); + } + + ASSERT_OK(txn0->Commit()); + txn1->Rollback(); + + delete txn0; + delete txn1; +} + +} // namespace rocksdb + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +#else +#include <stdio.h> + +int main(int /*argc*/, char** /*argv*/) { + fprintf(stderr, + "SKIPPED as Transactions are not supported in ROCKSDB_LITE\n"); + return 0; +} + +#endif // ROCKSDB_LITE