sst_dump_test.cc 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282
  1. // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. //
  6. // Copyright (c) 2012 The LevelDB Authors. All rights reserved.
  7. // Use of this source code is governed by a BSD-style license that can be
  8. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  9. #ifndef ROCKSDB_LITE
  10. #include <stdint.h>
  11. #include "rocksdb/sst_dump_tool.h"
  12. #include "file/random_access_file_reader.h"
  13. #include "port/stack_trace.h"
  14. #include "rocksdb/filter_policy.h"
  15. #include "table/block_based/block_based_table_factory.h"
  16. #include "table/table_builder.h"
  17. #include "test_util/testharness.h"
  18. #include "test_util/testutil.h"
  19. namespace ROCKSDB_NAMESPACE {
  20. const uint32_t optLength = 100;
  21. namespace {
  22. static std::string MakeKey(int i) {
  23. char buf[100];
  24. snprintf(buf, sizeof(buf), "k_%04d", i);
  25. InternalKey key(std::string(buf), 0, ValueType::kTypeValue);
  26. return key.Encode().ToString();
  27. }
  28. static std::string MakeValue(int i) {
  29. char buf[100];
  30. snprintf(buf, sizeof(buf), "v_%04d", i);
  31. InternalKey key(std::string(buf), 0, ValueType::kTypeValue);
  32. return key.Encode().ToString();
  33. }
  34. void createSST(const Options& opts, const std::string& file_name) {
  35. Env* env = opts.env;
  36. EnvOptions env_options(opts);
  37. ReadOptions read_options;
  38. const ImmutableCFOptions imoptions(opts);
  39. const MutableCFOptions moptions(opts);
  40. ROCKSDB_NAMESPACE::InternalKeyComparator ikc(opts.comparator);
  41. std::unique_ptr<TableBuilder> tb;
  42. std::unique_ptr<WritableFile> file;
  43. ASSERT_OK(env->NewWritableFile(file_name, &file, env_options));
  44. std::vector<std::unique_ptr<IntTblPropCollectorFactory> >
  45. int_tbl_prop_collector_factories;
  46. std::unique_ptr<WritableFileWriter> file_writer(new WritableFileWriter(
  47. NewLegacyWritableFileWrapper(std::move(file)), file_name, EnvOptions()));
  48. std::string column_family_name;
  49. int unknown_level = -1;
  50. tb.reset(opts.table_factory->NewTableBuilder(
  51. TableBuilderOptions(
  52. imoptions, moptions, ikc, &int_tbl_prop_collector_factories,
  53. CompressionType::kNoCompression, 0 /* sample_for_compression */,
  54. CompressionOptions(), false /* skip_filters */, column_family_name,
  55. unknown_level),
  56. TablePropertiesCollectorFactory::Context::kUnknownColumnFamily,
  57. file_writer.get()));
  58. // Populate slightly more than 1K keys
  59. uint32_t num_keys = 1024;
  60. for (uint32_t i = 0; i < num_keys; i++) {
  61. tb->Add(MakeKey(i), MakeValue(i));
  62. }
  63. tb->Finish();
  64. file_writer->Close();
  65. }
  66. void cleanup(const Options& opts, const std::string& file_name) {
  67. Env* env = opts.env;
  68. env->DeleteFile(file_name);
  69. std::string outfile_name = file_name.substr(0, file_name.length() - 4);
  70. outfile_name.append("_dump.txt");
  71. env->DeleteFile(outfile_name);
  72. }
  73. } // namespace
  74. // Test for sst dump tool "raw" mode
  75. class SSTDumpToolTest : public testing::Test {
  76. std::string test_dir_;
  77. Env* env_;
  78. std::shared_ptr<Env> env_guard_;
  79. public:
  80. SSTDumpToolTest() : env_(Env::Default()) {
  81. const char* test_env_uri = getenv("TEST_ENV_URI");
  82. if (test_env_uri) {
  83. Env::LoadEnv(test_env_uri, &env_, &env_guard_);
  84. }
  85. test_dir_ = test::PerThreadDBPath(env_, "sst_dump_test_db");
  86. Status s = env_->CreateDirIfMissing(test_dir_);
  87. EXPECT_OK(s);
  88. }
  89. ~SSTDumpToolTest() override {
  90. if (getenv("KEEP_DB")) {
  91. fprintf(stdout, "Data is still at %s\n", test_dir_.c_str());
  92. } else {
  93. EXPECT_OK(env_->DeleteDir(test_dir_));
  94. }
  95. }
  96. Env* env() { return env_; }
  97. std::string MakeFilePath(const std::string& file_name) const {
  98. std::string path(test_dir_);
  99. path.append("/").append(file_name);
  100. return path;
  101. }
  102. template <std::size_t N>
  103. void PopulateCommandArgs(const std::string& file_path, const char* command,
  104. char* (&usage)[N]) const {
  105. for (int i = 0; i < static_cast<int>(N); ++i) {
  106. usage[i] = new char[optLength];
  107. }
  108. snprintf(usage[0], optLength, "./sst_dump");
  109. snprintf(usage[1], optLength, "%s", command);
  110. snprintf(usage[2], optLength, "--file=%s", file_path.c_str());
  111. }
  112. };
  113. TEST_F(SSTDumpToolTest, EmptyFilter) {
  114. Options opts;
  115. opts.env = env();
  116. std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
  117. createSST(opts, file_path);
  118. char* usage[3];
  119. PopulateCommandArgs(file_path, "--command=raw", usage);
  120. ROCKSDB_NAMESPACE::SSTDumpTool tool;
  121. ASSERT_TRUE(!tool.Run(3, usage, opts));
  122. cleanup(opts, file_path);
  123. for (int i = 0; i < 3; i++) {
  124. delete[] usage[i];
  125. }
  126. }
  127. TEST_F(SSTDumpToolTest, FilterBlock) {
  128. Options opts;
  129. opts.env = env();
  130. BlockBasedTableOptions table_opts;
  131. table_opts.filter_policy.reset(
  132. ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, true));
  133. opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
  134. std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
  135. createSST(opts, file_path);
  136. char* usage[3];
  137. PopulateCommandArgs(file_path, "--command=raw", usage);
  138. ROCKSDB_NAMESPACE::SSTDumpTool tool;
  139. ASSERT_TRUE(!tool.Run(3, usage, opts));
  140. cleanup(opts, file_path);
  141. for (int i = 0; i < 3; i++) {
  142. delete[] usage[i];
  143. }
  144. }
  145. TEST_F(SSTDumpToolTest, FullFilterBlock) {
  146. Options opts;
  147. opts.env = env();
  148. BlockBasedTableOptions table_opts;
  149. table_opts.filter_policy.reset(
  150. ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
  151. opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
  152. std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
  153. createSST(opts, file_path);
  154. char* usage[3];
  155. PopulateCommandArgs(file_path, "--command=raw", usage);
  156. ROCKSDB_NAMESPACE::SSTDumpTool tool;
  157. ASSERT_TRUE(!tool.Run(3, usage, opts));
  158. cleanup(opts, file_path);
  159. for (int i = 0; i < 3; i++) {
  160. delete[] usage[i];
  161. }
  162. }
  163. TEST_F(SSTDumpToolTest, GetProperties) {
  164. Options opts;
  165. opts.env = env();
  166. BlockBasedTableOptions table_opts;
  167. table_opts.filter_policy.reset(
  168. ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
  169. opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
  170. std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
  171. createSST(opts, file_path);
  172. char* usage[3];
  173. PopulateCommandArgs(file_path, "--show_properties", usage);
  174. ROCKSDB_NAMESPACE::SSTDumpTool tool;
  175. ASSERT_TRUE(!tool.Run(3, usage, opts));
  176. cleanup(opts, file_path);
  177. for (int i = 0; i < 3; i++) {
  178. delete[] usage[i];
  179. }
  180. }
  181. TEST_F(SSTDumpToolTest, CompressedSizes) {
  182. Options opts;
  183. opts.env = env();
  184. BlockBasedTableOptions table_opts;
  185. table_opts.filter_policy.reset(
  186. ROCKSDB_NAMESPACE::NewBloomFilterPolicy(10, false));
  187. opts.table_factory.reset(new BlockBasedTableFactory(table_opts));
  188. std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
  189. createSST(opts, file_path);
  190. char* usage[3];
  191. PopulateCommandArgs(file_path, "--command=recompress", usage);
  192. ROCKSDB_NAMESPACE::SSTDumpTool tool;
  193. ASSERT_TRUE(!tool.Run(3, usage, opts));
  194. cleanup(opts, file_path);
  195. for (int i = 0; i < 3; i++) {
  196. delete[] usage[i];
  197. }
  198. }
  199. TEST_F(SSTDumpToolTest, MemEnv) {
  200. std::unique_ptr<Env> mem_env(NewMemEnv(env()));
  201. Options opts;
  202. opts.env = mem_env.get();
  203. std::string file_path = MakeFilePath("rocksdb_sst_test.sst");
  204. createSST(opts, file_path);
  205. char* usage[3];
  206. PopulateCommandArgs(file_path, "--command=verify_checksum", usage);
  207. ROCKSDB_NAMESPACE::SSTDumpTool tool;
  208. ASSERT_TRUE(!tool.Run(3, usage, opts));
  209. cleanup(opts, file_path);
  210. for (int i = 0; i < 3; i++) {
  211. delete[] usage[i];
  212. }
  213. }
  214. } // namespace ROCKSDB_NAMESPACE
  215. #ifdef ROCKSDB_UNITTESTS_WITH_CUSTOM_OBJECTS_FROM_STATIC_LIBS
  216. extern "C" {
  217. void RegisterCustomObjects(int argc, char** argv);
  218. }
  219. #else
  220. void RegisterCustomObjects(int /*argc*/, char** /*argv*/) {}
  221. #endif // !ROCKSDB_UNITTESTS_WITH_CUSTOM_OBJECTS_FROM_STATIC_LIBS
  222. int main(int argc, char** argv) {
  223. ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
  224. ::testing::InitGoogleTest(&argc, argv);
  225. RegisterCustomObjects(argc, argv);
  226. return RUN_ALL_TESTS();
  227. }
  228. #else
  229. #include <stdio.h>
  230. int main(int /*argc*/, char** /*argv*/) {
  231. fprintf(stderr, "SKIPPED as SSTDumpTool is not supported in ROCKSDB_LITE\n");
  232. return 0;
  233. }
  234. #endif // !ROCKSDB_LITE return RUN_ALL_TESTS();