testutil.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802
  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) 2011 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. #pragma once
  10. #include <algorithm>
  11. #include <deque>
  12. #include <string>
  13. #include <vector>
  14. #include "env/composite_env_wrapper.h"
  15. #include "file/writable_file_writer.h"
  16. #include "rocksdb/compaction_filter.h"
  17. #include "rocksdb/env.h"
  18. #include "rocksdb/iterator.h"
  19. #include "rocksdb/merge_operator.h"
  20. #include "rocksdb/options.h"
  21. #include "rocksdb/slice.h"
  22. #include "rocksdb/table.h"
  23. #include "table/block_based/block_based_table_factory.h"
  24. #include "table/internal_iterator.h"
  25. #include "table/plain/plain_table_factory.h"
  26. #include "util/mutexlock.h"
  27. #include "util/random.h"
  28. namespace ROCKSDB_NAMESPACE {
  29. class SequentialFile;
  30. class SequentialFileReader;
  31. namespace test {
  32. extern const uint32_t kDefaultFormatVersion;
  33. extern const uint32_t kLatestFormatVersion;
  34. // Store in *dst a random string of length "len" and return a Slice that
  35. // references the generated data.
  36. extern Slice RandomString(Random* rnd, int len, std::string* dst);
  37. extern std::string RandomHumanReadableString(Random* rnd, int len);
  38. // Return a random key with the specified length that may contain interesting
  39. // characters (e.g. \x00, \xff, etc.).
  40. enum RandomKeyType : char { RANDOM, LARGEST, SMALLEST, MIDDLE };
  41. extern std::string RandomKey(Random* rnd, int len,
  42. RandomKeyType type = RandomKeyType::RANDOM);
  43. // Store in *dst a string of length "len" that will compress to
  44. // "N*compressed_fraction" bytes and return a Slice that references
  45. // the generated data.
  46. extern Slice CompressibleString(Random* rnd, double compressed_fraction,
  47. int len, std::string* dst);
  48. // A wrapper that allows injection of errors.
  49. class ErrorEnv : public EnvWrapper {
  50. public:
  51. bool writable_file_error_;
  52. int num_writable_file_errors_;
  53. ErrorEnv() : EnvWrapper(Env::Default()),
  54. writable_file_error_(false),
  55. num_writable_file_errors_(0) { }
  56. virtual Status NewWritableFile(const std::string& fname,
  57. std::unique_ptr<WritableFile>* result,
  58. const EnvOptions& soptions) override {
  59. result->reset();
  60. if (writable_file_error_) {
  61. ++num_writable_file_errors_;
  62. return Status::IOError(fname, "fake error");
  63. }
  64. return target()->NewWritableFile(fname, result, soptions);
  65. }
  66. };
  67. #ifndef NDEBUG
  68. // An internal comparator that just forward comparing results from the
  69. // user comparator in it. Can be used to test entities that have no dependency
  70. // on internal key structure but consumes InternalKeyComparator, like
  71. // BlockBasedTable.
  72. class PlainInternalKeyComparator : public InternalKeyComparator {
  73. public:
  74. explicit PlainInternalKeyComparator(const Comparator* c)
  75. : InternalKeyComparator(c) {}
  76. virtual ~PlainInternalKeyComparator() {}
  77. virtual int Compare(const Slice& a, const Slice& b) const override {
  78. return user_comparator()->Compare(a, b);
  79. }
  80. };
  81. #endif
  82. // A test comparator which compare two strings in this way:
  83. // (1) first compare prefix of 8 bytes in alphabet order,
  84. // (2) if two strings share the same prefix, sort the other part of the string
  85. // in the reverse alphabet order.
  86. // This helps simulate the case of compounded key of [entity][timestamp] and
  87. // latest timestamp first.
  88. class SimpleSuffixReverseComparator : public Comparator {
  89. public:
  90. SimpleSuffixReverseComparator() {}
  91. virtual const char* Name() const override {
  92. return "SimpleSuffixReverseComparator";
  93. }
  94. virtual int Compare(const Slice& a, const Slice& b) const override {
  95. Slice prefix_a = Slice(a.data(), 8);
  96. Slice prefix_b = Slice(b.data(), 8);
  97. int prefix_comp = prefix_a.compare(prefix_b);
  98. if (prefix_comp != 0) {
  99. return prefix_comp;
  100. } else {
  101. Slice suffix_a = Slice(a.data() + 8, a.size() - 8);
  102. Slice suffix_b = Slice(b.data() + 8, b.size() - 8);
  103. return -(suffix_a.compare(suffix_b));
  104. }
  105. }
  106. virtual void FindShortestSeparator(std::string* /*start*/,
  107. const Slice& /*limit*/) const override {}
  108. virtual void FindShortSuccessor(std::string* /*key*/) const override {}
  109. };
  110. // Returns a user key comparator that can be used for comparing two uint64_t
  111. // slices. Instead of comparing slices byte-wise, it compares all the 8 bytes
  112. // at once. Assumes same endian-ness is used though the database's lifetime.
  113. // Symantics of comparison would differ from Bytewise comparator in little
  114. // endian machines.
  115. extern const Comparator* Uint64Comparator();
  116. // Iterator over a vector of keys/values
  117. class VectorIterator : public InternalIterator {
  118. public:
  119. explicit VectorIterator(const std::vector<std::string>& keys)
  120. : keys_(keys), current_(keys.size()) {
  121. std::sort(keys_.begin(), keys_.end());
  122. values_.resize(keys.size());
  123. }
  124. VectorIterator(const std::vector<std::string>& keys,
  125. const std::vector<std::string>& values)
  126. : keys_(keys), values_(values), current_(keys.size()) {
  127. assert(keys_.size() == values_.size());
  128. }
  129. virtual bool Valid() const override { return current_ < keys_.size(); }
  130. virtual void SeekToFirst() override { current_ = 0; }
  131. virtual void SeekToLast() override { current_ = keys_.size() - 1; }
  132. virtual void Seek(const Slice& target) override {
  133. current_ = std::lower_bound(keys_.begin(), keys_.end(), target.ToString()) -
  134. keys_.begin();
  135. }
  136. virtual void SeekForPrev(const Slice& target) override {
  137. current_ = std::upper_bound(keys_.begin(), keys_.end(), target.ToString()) -
  138. keys_.begin();
  139. if (!Valid()) {
  140. SeekToLast();
  141. } else {
  142. Prev();
  143. }
  144. }
  145. virtual void Next() override { current_++; }
  146. virtual void Prev() override { current_--; }
  147. virtual Slice key() const override { return Slice(keys_[current_]); }
  148. virtual Slice value() const override { return Slice(values_[current_]); }
  149. virtual Status status() const override { return Status::OK(); }
  150. virtual bool IsKeyPinned() const override { return true; }
  151. virtual bool IsValuePinned() const override { return true; }
  152. private:
  153. std::vector<std::string> keys_;
  154. std::vector<std::string> values_;
  155. size_t current_;
  156. };
  157. extern WritableFileWriter* GetWritableFileWriter(WritableFile* wf,
  158. const std::string& fname);
  159. extern RandomAccessFileReader* GetRandomAccessFileReader(RandomAccessFile* raf);
  160. extern SequentialFileReader* GetSequentialFileReader(SequentialFile* se,
  161. const std::string& fname);
  162. class StringSink: public WritableFile {
  163. public:
  164. std::string contents_;
  165. explicit StringSink(Slice* reader_contents = nullptr) :
  166. WritableFile(),
  167. contents_(""),
  168. reader_contents_(reader_contents),
  169. last_flush_(0) {
  170. if (reader_contents_ != nullptr) {
  171. *reader_contents_ = Slice(contents_.data(), 0);
  172. }
  173. }
  174. const std::string& contents() const { return contents_; }
  175. virtual Status Truncate(uint64_t size) override {
  176. contents_.resize(static_cast<size_t>(size));
  177. return Status::OK();
  178. }
  179. virtual Status Close() override { return Status::OK(); }
  180. virtual Status Flush() override {
  181. if (reader_contents_ != nullptr) {
  182. assert(reader_contents_->size() <= last_flush_);
  183. size_t offset = last_flush_ - reader_contents_->size();
  184. *reader_contents_ = Slice(
  185. contents_.data() + offset,
  186. contents_.size() - offset);
  187. last_flush_ = contents_.size();
  188. }
  189. return Status::OK();
  190. }
  191. virtual Status Sync() override { return Status::OK(); }
  192. virtual Status Append(const Slice& slice) override {
  193. contents_.append(slice.data(), slice.size());
  194. return Status::OK();
  195. }
  196. void Drop(size_t bytes) {
  197. if (reader_contents_ != nullptr) {
  198. contents_.resize(contents_.size() - bytes);
  199. *reader_contents_ = Slice(
  200. reader_contents_->data(), reader_contents_->size() - bytes);
  201. last_flush_ = contents_.size();
  202. }
  203. }
  204. private:
  205. Slice* reader_contents_;
  206. size_t last_flush_;
  207. };
  208. // A wrapper around a StringSink to give it a RandomRWFile interface
  209. class RandomRWStringSink : public RandomRWFile {
  210. public:
  211. explicit RandomRWStringSink(StringSink* ss) : ss_(ss) {}
  212. Status Write(uint64_t offset, const Slice& data) override {
  213. if (offset + data.size() > ss_->contents_.size()) {
  214. ss_->contents_.resize(static_cast<size_t>(offset) + data.size(), '\0');
  215. }
  216. char* pos = const_cast<char*>(ss_->contents_.data() + offset);
  217. memcpy(pos, data.data(), data.size());
  218. return Status::OK();
  219. }
  220. Status Read(uint64_t offset, size_t n, Slice* result,
  221. char* /*scratch*/) const override {
  222. *result = Slice(nullptr, 0);
  223. if (offset < ss_->contents_.size()) {
  224. size_t str_res_sz =
  225. std::min(static_cast<size_t>(ss_->contents_.size() - offset), n);
  226. *result = Slice(ss_->contents_.data() + offset, str_res_sz);
  227. }
  228. return Status::OK();
  229. }
  230. Status Flush() override { return Status::OK(); }
  231. Status Sync() override { return Status::OK(); }
  232. Status Close() override { return Status::OK(); }
  233. const std::string& contents() const { return ss_->contents(); }
  234. private:
  235. StringSink* ss_;
  236. };
  237. // Like StringSink, this writes into a string. Unlink StringSink, it
  238. // has some initial content and overwrites it, just like a recycled
  239. // log file.
  240. class OverwritingStringSink : public WritableFile {
  241. public:
  242. explicit OverwritingStringSink(Slice* reader_contents)
  243. : WritableFile(),
  244. contents_(""),
  245. reader_contents_(reader_contents),
  246. last_flush_(0) {}
  247. const std::string& contents() const { return contents_; }
  248. virtual Status Truncate(uint64_t size) override {
  249. contents_.resize(static_cast<size_t>(size));
  250. return Status::OK();
  251. }
  252. virtual Status Close() override { return Status::OK(); }
  253. virtual Status Flush() override {
  254. if (last_flush_ < contents_.size()) {
  255. assert(reader_contents_->size() >= contents_.size());
  256. memcpy((char*)reader_contents_->data() + last_flush_,
  257. contents_.data() + last_flush_, contents_.size() - last_flush_);
  258. last_flush_ = contents_.size();
  259. }
  260. return Status::OK();
  261. }
  262. virtual Status Sync() override { return Status::OK(); }
  263. virtual Status Append(const Slice& slice) override {
  264. contents_.append(slice.data(), slice.size());
  265. return Status::OK();
  266. }
  267. void Drop(size_t bytes) {
  268. contents_.resize(contents_.size() - bytes);
  269. if (last_flush_ > contents_.size()) last_flush_ = contents_.size();
  270. }
  271. private:
  272. std::string contents_;
  273. Slice* reader_contents_;
  274. size_t last_flush_;
  275. };
  276. class StringSource: public RandomAccessFile {
  277. public:
  278. explicit StringSource(const Slice& contents, uint64_t uniq_id = 0,
  279. bool mmap = false)
  280. : contents_(contents.data(), contents.size()),
  281. uniq_id_(uniq_id),
  282. mmap_(mmap),
  283. total_reads_(0) {}
  284. virtual ~StringSource() { }
  285. uint64_t Size() const { return contents_.size(); }
  286. virtual Status Read(uint64_t offset, size_t n, Slice* result,
  287. char* scratch) const override {
  288. total_reads_++;
  289. if (offset > contents_.size()) {
  290. return Status::InvalidArgument("invalid Read offset");
  291. }
  292. if (offset + n > contents_.size()) {
  293. n = contents_.size() - static_cast<size_t>(offset);
  294. }
  295. if (!mmap_) {
  296. memcpy(scratch, &contents_[static_cast<size_t>(offset)], n);
  297. *result = Slice(scratch, n);
  298. } else {
  299. *result = Slice(&contents_[static_cast<size_t>(offset)], n);
  300. }
  301. return Status::OK();
  302. }
  303. virtual size_t GetUniqueId(char* id, size_t max_size) const override {
  304. if (max_size < 20) {
  305. return 0;
  306. }
  307. char* rid = id;
  308. rid = EncodeVarint64(rid, uniq_id_);
  309. rid = EncodeVarint64(rid, 0);
  310. return static_cast<size_t>(rid-id);
  311. }
  312. int total_reads() const { return total_reads_; }
  313. void set_total_reads(int tr) { total_reads_ = tr; }
  314. private:
  315. std::string contents_;
  316. uint64_t uniq_id_;
  317. bool mmap_;
  318. mutable int total_reads_;
  319. };
  320. inline StringSink* GetStringSinkFromLegacyWriter(
  321. const WritableFileWriter* writer) {
  322. LegacyWritableFileWrapper* file =
  323. static_cast<LegacyWritableFileWrapper*>(writer->writable_file());
  324. return static_cast<StringSink*>(file->target());
  325. }
  326. class NullLogger : public Logger {
  327. public:
  328. using Logger::Logv;
  329. virtual void Logv(const char* /*format*/, va_list /*ap*/) override {}
  330. virtual size_t GetLogFileSize() const override { return 0; }
  331. };
  332. // Corrupts key by changing the type
  333. extern void CorruptKeyType(InternalKey* ikey);
  334. extern std::string KeyStr(const std::string& user_key,
  335. const SequenceNumber& seq, const ValueType& t,
  336. bool corrupt = false);
  337. class SleepingBackgroundTask {
  338. public:
  339. SleepingBackgroundTask()
  340. : bg_cv_(&mutex_),
  341. should_sleep_(true),
  342. done_with_sleep_(false),
  343. sleeping_(false) {}
  344. bool IsSleeping() {
  345. MutexLock l(&mutex_);
  346. return sleeping_;
  347. }
  348. void DoSleep() {
  349. MutexLock l(&mutex_);
  350. sleeping_ = true;
  351. bg_cv_.SignalAll();
  352. while (should_sleep_) {
  353. bg_cv_.Wait();
  354. }
  355. sleeping_ = false;
  356. done_with_sleep_ = true;
  357. bg_cv_.SignalAll();
  358. }
  359. void WaitUntilSleeping() {
  360. MutexLock l(&mutex_);
  361. while (!sleeping_ || !should_sleep_) {
  362. bg_cv_.Wait();
  363. }
  364. }
  365. // Waits for the status to change to sleeping,
  366. // otherwise times out.
  367. // wait_time is in microseconds.
  368. // Returns true when times out, false otherwise.
  369. bool TimedWaitUntilSleeping(uint64_t wait_time) {
  370. auto abs_time = Env::Default()->NowMicros() + wait_time;
  371. MutexLock l(&mutex_);
  372. while (!sleeping_ || !should_sleep_) {
  373. if (bg_cv_.TimedWait(abs_time)) {
  374. return true;
  375. }
  376. }
  377. return false;
  378. }
  379. void WakeUp() {
  380. MutexLock l(&mutex_);
  381. should_sleep_ = false;
  382. bg_cv_.SignalAll();
  383. }
  384. void WaitUntilDone() {
  385. MutexLock l(&mutex_);
  386. while (!done_with_sleep_) {
  387. bg_cv_.Wait();
  388. }
  389. }
  390. // Similar to TimedWaitUntilSleeping.
  391. // Waits until the task is done.
  392. bool TimedWaitUntilDone(uint64_t wait_time) {
  393. auto abs_time = Env::Default()->NowMicros() + wait_time;
  394. MutexLock l(&mutex_);
  395. while (!done_with_sleep_) {
  396. if (bg_cv_.TimedWait(abs_time)) {
  397. return true;
  398. }
  399. }
  400. return false;
  401. }
  402. bool WokenUp() {
  403. MutexLock l(&mutex_);
  404. return should_sleep_ == false;
  405. }
  406. void Reset() {
  407. MutexLock l(&mutex_);
  408. should_sleep_ = true;
  409. done_with_sleep_ = false;
  410. }
  411. static void DoSleepTask(void* arg) {
  412. reinterpret_cast<SleepingBackgroundTask*>(arg)->DoSleep();
  413. }
  414. private:
  415. port::Mutex mutex_;
  416. port::CondVar bg_cv_; // Signalled when background work finishes
  417. bool should_sleep_;
  418. bool done_with_sleep_;
  419. bool sleeping_;
  420. };
  421. // Filters merge operands and values that are equal to `num`.
  422. class FilterNumber : public CompactionFilter {
  423. public:
  424. explicit FilterNumber(uint64_t num) : num_(num) {}
  425. std::string last_merge_operand_key() { return last_merge_operand_key_; }
  426. bool Filter(int /*level*/, const ROCKSDB_NAMESPACE::Slice& /*key*/,
  427. const ROCKSDB_NAMESPACE::Slice& value, std::string* /*new_value*/,
  428. bool* /*value_changed*/) const override {
  429. if (value.size() == sizeof(uint64_t)) {
  430. return num_ == DecodeFixed64(value.data());
  431. }
  432. return true;
  433. }
  434. bool FilterMergeOperand(
  435. int /*level*/, const ROCKSDB_NAMESPACE::Slice& key,
  436. const ROCKSDB_NAMESPACE::Slice& value) const override {
  437. last_merge_operand_key_ = key.ToString();
  438. if (value.size() == sizeof(uint64_t)) {
  439. return num_ == DecodeFixed64(value.data());
  440. }
  441. return true;
  442. }
  443. const char* Name() const override { return "FilterBadMergeOperand"; }
  444. private:
  445. mutable std::string last_merge_operand_key_;
  446. uint64_t num_;
  447. };
  448. inline std::string EncodeInt(uint64_t x) {
  449. std::string result;
  450. PutFixed64(&result, x);
  451. return result;
  452. }
  453. class SeqStringSource : public SequentialFile {
  454. public:
  455. SeqStringSource(const std::string& data, std::atomic<int>* read_count)
  456. : data_(data), offset_(0), read_count_(read_count) {}
  457. ~SeqStringSource() override {}
  458. Status Read(size_t n, Slice* result, char* scratch) override {
  459. std::string output;
  460. if (offset_ < data_.size()) {
  461. n = std::min(data_.size() - offset_, n);
  462. memcpy(scratch, data_.data() + offset_, n);
  463. offset_ += n;
  464. *result = Slice(scratch, n);
  465. } else {
  466. return Status::InvalidArgument(
  467. "Attemp to read when it already reached eof.");
  468. }
  469. (*read_count_)++;
  470. return Status::OK();
  471. }
  472. Status Skip(uint64_t n) override {
  473. if (offset_ >= data_.size()) {
  474. return Status::InvalidArgument(
  475. "Attemp to read when it already reached eof.");
  476. }
  477. // TODO(yhchiang): Currently doesn't handle the overflow case.
  478. offset_ += static_cast<size_t>(n);
  479. return Status::OK();
  480. }
  481. private:
  482. std::string data_;
  483. size_t offset_;
  484. std::atomic<int>* read_count_;
  485. };
  486. class StringEnv : public EnvWrapper {
  487. public:
  488. class StringSink : public WritableFile {
  489. public:
  490. explicit StringSink(std::string* contents)
  491. : WritableFile(), contents_(contents) {}
  492. virtual Status Truncate(uint64_t size) override {
  493. contents_->resize(static_cast<size_t>(size));
  494. return Status::OK();
  495. }
  496. virtual Status Close() override { return Status::OK(); }
  497. virtual Status Flush() override { return Status::OK(); }
  498. virtual Status Sync() override { return Status::OK(); }
  499. virtual Status Append(const Slice& slice) override {
  500. contents_->append(slice.data(), slice.size());
  501. return Status::OK();
  502. }
  503. private:
  504. std::string* contents_;
  505. };
  506. explicit StringEnv(Env* t) : EnvWrapper(t) {}
  507. ~StringEnv() override {}
  508. const std::string& GetContent(const std::string& f) { return files_[f]; }
  509. const Status WriteToNewFile(const std::string& file_name,
  510. const std::string& content) {
  511. std::unique_ptr<WritableFile> r;
  512. auto s = NewWritableFile(file_name, &r, EnvOptions());
  513. if (!s.ok()) {
  514. return s;
  515. }
  516. r->Append(content);
  517. r->Flush();
  518. r->Close();
  519. assert(files_[file_name] == content);
  520. return Status::OK();
  521. }
  522. // The following text is boilerplate that forwards all methods to target()
  523. Status NewSequentialFile(const std::string& f,
  524. std::unique_ptr<SequentialFile>* r,
  525. const EnvOptions& /*options*/) override {
  526. auto iter = files_.find(f);
  527. if (iter == files_.end()) {
  528. return Status::NotFound("The specified file does not exist", f);
  529. }
  530. r->reset(new SeqStringSource(iter->second, &num_seq_file_read_));
  531. return Status::OK();
  532. }
  533. Status NewRandomAccessFile(const std::string& /*f*/,
  534. std::unique_ptr<RandomAccessFile>* /*r*/,
  535. const EnvOptions& /*options*/) override {
  536. return Status::NotSupported();
  537. }
  538. Status NewWritableFile(const std::string& f,
  539. std::unique_ptr<WritableFile>* r,
  540. const EnvOptions& /*options*/) override {
  541. auto iter = files_.find(f);
  542. if (iter != files_.end()) {
  543. return Status::IOError("The specified file already exists", f);
  544. }
  545. r->reset(new StringSink(&files_[f]));
  546. return Status::OK();
  547. }
  548. virtual Status NewDirectory(
  549. const std::string& /*name*/,
  550. std::unique_ptr<Directory>* /*result*/) override {
  551. return Status::NotSupported();
  552. }
  553. Status FileExists(const std::string& f) override {
  554. if (files_.find(f) == files_.end()) {
  555. return Status::NotFound();
  556. }
  557. return Status::OK();
  558. }
  559. Status GetChildren(const std::string& /*dir*/,
  560. std::vector<std::string>* /*r*/) override {
  561. return Status::NotSupported();
  562. }
  563. Status DeleteFile(const std::string& f) override {
  564. files_.erase(f);
  565. return Status::OK();
  566. }
  567. Status CreateDir(const std::string& /*d*/) override {
  568. return Status::NotSupported();
  569. }
  570. Status CreateDirIfMissing(const std::string& /*d*/) override {
  571. return Status::NotSupported();
  572. }
  573. Status DeleteDir(const std::string& /*d*/) override {
  574. return Status::NotSupported();
  575. }
  576. Status GetFileSize(const std::string& f, uint64_t* s) override {
  577. auto iter = files_.find(f);
  578. if (iter == files_.end()) {
  579. return Status::NotFound("The specified file does not exist:", f);
  580. }
  581. *s = iter->second.size();
  582. return Status::OK();
  583. }
  584. Status GetFileModificationTime(const std::string& /*fname*/,
  585. uint64_t* /*file_mtime*/) override {
  586. return Status::NotSupported();
  587. }
  588. Status RenameFile(const std::string& /*s*/,
  589. const std::string& /*t*/) override {
  590. return Status::NotSupported();
  591. }
  592. Status LinkFile(const std::string& /*s*/,
  593. const std::string& /*t*/) override {
  594. return Status::NotSupported();
  595. }
  596. Status LockFile(const std::string& /*f*/, FileLock** /*l*/) override {
  597. return Status::NotSupported();
  598. }
  599. Status UnlockFile(FileLock* /*l*/) override {
  600. return Status::NotSupported();
  601. }
  602. std::atomic<int> num_seq_file_read_;
  603. protected:
  604. std::unordered_map<std::string, std::string> files_;
  605. };
  606. // Randomly initialize the given DBOptions
  607. void RandomInitDBOptions(DBOptions* db_opt, Random* rnd);
  608. // Randomly initialize the given ColumnFamilyOptions
  609. // Note that the caller is responsible for releasing non-null
  610. // cf_opt->compaction_filter.
  611. void RandomInitCFOptions(ColumnFamilyOptions* cf_opt, DBOptions&, Random* rnd);
  612. // A dummy merge operator which can change its name
  613. class ChanglingMergeOperator : public MergeOperator {
  614. public:
  615. explicit ChanglingMergeOperator(const std::string& name)
  616. : name_(name + "MergeOperator") {}
  617. ~ChanglingMergeOperator() {}
  618. void SetName(const std::string& name) { name_ = name; }
  619. virtual bool FullMergeV2(const MergeOperationInput& /*merge_in*/,
  620. MergeOperationOutput* /*merge_out*/) const override {
  621. return false;
  622. }
  623. virtual bool PartialMergeMulti(const Slice& /*key*/,
  624. const std::deque<Slice>& /*operand_list*/,
  625. std::string* /*new_value*/,
  626. Logger* /*logger*/) const override {
  627. return false;
  628. }
  629. virtual const char* Name() const override { return name_.c_str(); }
  630. protected:
  631. std::string name_;
  632. };
  633. // Returns a dummy merge operator with random name.
  634. MergeOperator* RandomMergeOperator(Random* rnd);
  635. // A dummy compaction filter which can change its name
  636. class ChanglingCompactionFilter : public CompactionFilter {
  637. public:
  638. explicit ChanglingCompactionFilter(const std::string& name)
  639. : name_(name + "CompactionFilter") {}
  640. ~ChanglingCompactionFilter() {}
  641. void SetName(const std::string& name) { name_ = name; }
  642. bool Filter(int /*level*/, const Slice& /*key*/,
  643. const Slice& /*existing_value*/, std::string* /*new_value*/,
  644. bool* /*value_changed*/) const override {
  645. return false;
  646. }
  647. const char* Name() const override { return name_.c_str(); }
  648. private:
  649. std::string name_;
  650. };
  651. // Returns a dummy compaction filter with a random name.
  652. CompactionFilter* RandomCompactionFilter(Random* rnd);
  653. // A dummy compaction filter factory which can change its name
  654. class ChanglingCompactionFilterFactory : public CompactionFilterFactory {
  655. public:
  656. explicit ChanglingCompactionFilterFactory(const std::string& name)
  657. : name_(name + "CompactionFilterFactory") {}
  658. ~ChanglingCompactionFilterFactory() {}
  659. void SetName(const std::string& name) { name_ = name; }
  660. std::unique_ptr<CompactionFilter> CreateCompactionFilter(
  661. const CompactionFilter::Context& /*context*/) override {
  662. return std::unique_ptr<CompactionFilter>();
  663. }
  664. // Returns a name that identifies this compaction filter factory.
  665. const char* Name() const override { return name_.c_str(); }
  666. protected:
  667. std::string name_;
  668. };
  669. CompressionType RandomCompressionType(Random* rnd);
  670. void RandomCompressionTypeVector(const size_t count,
  671. std::vector<CompressionType>* types,
  672. Random* rnd);
  673. CompactionFilterFactory* RandomCompactionFilterFactory(Random* rnd);
  674. const SliceTransform* RandomSliceTransform(Random* rnd, int pre_defined = -1);
  675. TableFactory* RandomTableFactory(Random* rnd, int pre_defined = -1);
  676. std::string RandomName(Random* rnd, const size_t len);
  677. Status DestroyDir(Env* env, const std::string& dir);
  678. bool IsDirectIOSupported(Env* env, const std::string& dir);
  679. // Return the number of lines where a given pattern was found in a file.
  680. size_t GetLinesCount(const std::string& fname, const std::string& pattern);
  681. } // namespace test
  682. } // namespace ROCKSDB_NAMESPACE