From fc4d5f5065d3e9059af7453295007dddacff3d1c Mon Sep 17 00:00:00 2001 From: Jay Zhuang Date: Tue, 14 Jul 2020 12:10:56 -0700 Subject: [PATCH] Add stress test for GetProperty (#7111) Summary: Add stress test coverage for `DB::GetProperty()`. Pull Request resolved: https://github.com/facebook/rocksdb/pull/7111 Test Plan: ``` ./db_stress -get_property_one_in=1 make crash_test ``` Reviewed By: ajkr Differential Revision: D22487906 Pulled By: jay-zhuang fbshipit-source-id: c118d95cc9b4e2fa669a06e6aa531541fa885dc5 --- db_stress_tool/db_stress_common.h | 1 + db_stress_tool/db_stress_gflags.cc | 5 +++ db_stress_tool/db_stress_test_base.cc | 61 +++++++++++++++++++++++++++ db_stress_tool/db_stress_test_base.h | 1 + tools/db_crashtest.py | 3 +- 5 files changed, 70 insertions(+), 1 deletion(-) diff --git a/db_stress_tool/db_stress_common.h b/db_stress_tool/db_stress_common.h index f4654cbb56e..37bd09e1e7a 100644 --- a/db_stress_tool/db_stress_common.h +++ b/db_stress_tool/db_stress_common.h @@ -221,6 +221,7 @@ DECLARE_bool(level_compaction_dynamic_level_bytes); DECLARE_int32(verify_checksum_one_in); DECLARE_int32(verify_db_one_in); DECLARE_int32(continuous_verification_interval); +DECLARE_int32(get_property_one_in); #ifndef ROCKSDB_LITE DECLARE_bool(use_blob_db); diff --git a/db_stress_tool/db_stress_gflags.cc b/db_stress_tool/db_stress_gflags.cc index 7a807753b55..992dd6d84dc 100644 --- a/db_stress_tool/db_stress_gflags.cc +++ b/db_stress_tool/db_stress_gflags.cc @@ -693,6 +693,11 @@ DEFINE_int32(approximate_size_one_in, 64, DEFINE_int32(read_fault_one_in, 1000, "On non-zero, enables fault injection on read"); +DEFINE_int32(get_property_one_in, 1000, + "If non-zero, then DB::GetProperty() will be called to get various" + " properties for every N ops on average. 0 indicates that" + " GetProperty() will be not be called."); + DEFINE_bool(sync_fault_injection, false, "If true, FaultInjectionTestFS will be used for write operations, " " and unsynced data in DB will lost after crash."); diff --git a/db_stress_tool/db_stress_test_base.cc b/db_stress_tool/db_stress_test_base.cc index 7235170401a..f49b8a7c376 100644 --- a/db_stress_tool/db_stress_test_base.cc +++ b/db_stress_tool/db_stress_test_base.cc @@ -653,6 +653,10 @@ void StressTest::OperateDb(ThreadState* thread) { VerificationAbort(shared, "VerifyChecksum status not OK", status); } } + + if (thread->rand.OneInOpt(FLAGS_get_property_one_in)) { + TestGetProperty(thread); + } #endif std::vector rand_keys = GenerateKeys(rand_key); @@ -1428,6 +1432,63 @@ Status StressTest::TestCheckpoint(ThreadState* thread, return s; } +void StressTest::TestGetProperty(ThreadState* thread) const { + std::unordered_set levelPropertyNames = { + DB::Properties::kAggregatedTablePropertiesAtLevel, + DB::Properties::kCompressionRatioAtLevelPrefix, + DB::Properties::kNumFilesAtLevelPrefix, + }; + std::unordered_set unknownPropertyNames = { + DB::Properties::kEstimateOldestKeyTime, + DB::Properties::kOptionsStatistics, + }; + unknownPropertyNames.insert(levelPropertyNames.begin(), + levelPropertyNames.end()); + + std::string prop; + for (const auto& ppt_name_and_info : InternalStats::ppt_name_to_info) { + bool res = db_->GetProperty(ppt_name_and_info.first, &prop); + if (unknownPropertyNames.find(ppt_name_and_info.first) == + unknownPropertyNames.end()) { + if (!res) { + fprintf(stderr, "Failed to get DB property: %s\n", + ppt_name_and_info.first.c_str()); + thread->shared->SetVerificationFailure(); + } + if (ppt_name_and_info.second.handle_int != nullptr) { + uint64_t prop_int; + if (!db_->GetIntProperty(ppt_name_and_info.first, &prop_int)) { + fprintf(stderr, "Failed to get Int property: %s\n", + ppt_name_and_info.first.c_str()); + thread->shared->SetVerificationFailure(); + } + } + } + } + + ROCKSDB_NAMESPACE::ColumnFamilyMetaData cf_meta_data; + db_->GetColumnFamilyMetaData(&cf_meta_data); + int level_size = static_cast(cf_meta_data.levels.size()); + for (int level = 0; level < level_size; level++) { + for (const auto& ppt_name : levelPropertyNames) { + bool res = db_->GetProperty(ppt_name + std::to_string(level), &prop); + if (!res) { + fprintf(stderr, "Failed to get DB property: %s\n", + (ppt_name + std::to_string(level)).c_str()); + thread->shared->SetVerificationFailure(); + } + } + } + + // Test for an invalid property name + if (thread->rand.OneIn(100)) { + if (db_->GetProperty("rocksdb.invalid_property_name", &prop)) { + fprintf(stderr, "Failed to return false for invalid property name\n"); + thread->shared->SetVerificationFailure(); + } + } +} + void StressTest::TestCompactFiles(ThreadState* thread, ColumnFamilyHandle* column_family) { ROCKSDB_NAMESPACE::ColumnFamilyMetaData cf_meta_data; diff --git a/db_stress_tool/db_stress_test_base.h b/db_stress_tool/db_stress_test_base.h index a5d1ab4fe15..426af3bd082 100644 --- a/db_stress_tool/db_stress_test_base.h +++ b/db_stress_tool/db_stress_test_base.h @@ -189,6 +189,7 @@ class StressTest { Status VerifyGetLiveFiles() const; Status VerifyGetSortedWalFiles() const; Status VerifyGetCurrentWalFile() const; + void TestGetProperty(ThreadState* thread) const; virtual Status TestApproximateSize( ThreadState* thread, uint64_t iteration, diff --git a/tools/db_crashtest.py b/tools/db_crashtest.py index 185daec6970..cd79bc94fb8 100644 --- a/tools/db_crashtest.py +++ b/tools/db_crashtest.py @@ -127,7 +127,8 @@ "max_key_len": 3, "key_len_percent_dist": "1,30,69", "read_fault_one_in": lambda: random.choice([0, 1000]), - "sync_fault_injection": False + "sync_fault_injection": False, + "get_property_one_in": 1000000, } _TEST_DIR_ENV_VAR = 'TEST_TMPDIR'