diff --git a/db_stress_tool/db_stress_common.h b/db_stress_tool/db_stress_common.h index f4654cbb5..37bd09e1e 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 7a807753b..992dd6d84 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 723517040..f49b8a7c3 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 a5d1ab4fe..426af3bd0 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 185daec69..cd79bc94f 100644 --- a/tools/db_crashtest.py +++ b/tools/db_crashtest.py @@ -127,7 +127,8 @@ default_params = { "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'