rocksdb/table/merger_test.cc
Igor Sugak b4b69e4f77 rocksdb: switch to gtest
Summary:
Our existing test notation is very similar to what is used in gtest. It makes it easy to adopt what is different.
In this diff I modify existing [[ https://code.google.com/p/googletest/wiki/Primer#Test_Fixtures:_Using_the_Same_Data_Configuration_for_Multiple_Te | test fixture ]] classes to inherit from `testing::Test`. Also for unit tests that use fixture class, `TEST` is replaced with `TEST_F` as required in gtest.

There are several custom `main` functions in our existing tests. To make this transition easier, I modify all `main` functions to fallow gtest notation. But eventually we can remove them and use implementation of `main` that gtest provides.

```lang=bash
% cat ~/transform
#!/bin/sh
files=$(git ls-files '*test\.cc')
for file in $files
do
  if grep -q "rocksdb::test::RunAllTests()" $file
  then
    if grep -Eq '^class \w+Test {' $file
    then
      perl -pi -e 's/^(class \w+Test) {/${1}: public testing::Test {/g' $file
      perl -pi -e 's/^(TEST)/${1}_F/g' $file
    fi
    perl -pi -e 's/(int main.*\{)/${1}::testing::InitGoogleTest(&argc, argv);/g' $file
    perl -pi -e 's/rocksdb::test::RunAllTests/RUN_ALL_TESTS/g' $file
  fi
done
% sh ~/transform
% make format
```

Second iteration of this diff contains only scripted changes.

Third iteration contains manual changes to fix last errors and make it compilable.

Test Plan:
Build and notice no errors.
```lang=bash
% USE_CLANG=1 make check -j55
```
Tests are still testing.

Reviewers: meyering, sdong, rven, igor

Reviewed By: igor

Subscribers: dhruba, leveldb

Differential Revision: https://reviews.facebook.net/D35157
2015-03-17 14:08:00 -07:00

202 lines
5.2 KiB
C++

// Copyright (c) 2013, Facebook, Inc. All rights reserved.
// This source code is licensed under the BSD-style license found in the
// LICENSE file in the root directory of this source tree. An additional grant
// of patent rights can be found in the PATENTS file in the same directory.
#include <vector>
#include <string>
#include <algorithm>
#include "rocksdb/iterator.h"
#include "table/merger.h"
#include "util/testharness.h"
#include "util/testutil.h"
namespace rocksdb {
class VectorIterator : public Iterator {
public:
explicit VectorIterator(const std::vector<std::string>& keys)
: keys_(keys), current_(keys.size()) {
std::sort(keys_.begin(), keys_.end());
}
virtual bool Valid() const override { return current_ < keys_.size(); }
virtual void SeekToFirst() override { current_ = 0; }
virtual void SeekToLast() override { current_ = keys_.size() - 1; }
virtual void Seek(const Slice& target) override {
current_ = std::lower_bound(keys_.begin(), keys_.end(), target.ToString()) -
keys_.begin();
}
virtual void Next() override { current_++; }
virtual void Prev() override { current_--; }
virtual Slice key() const override { return Slice(keys_[current_]); }
virtual Slice value() const override { return Slice(); }
virtual Status status() const override { return Status::OK(); }
private:
std::vector<std::string> keys_;
size_t current_;
};
class MergerTest : public testing::Test {
public:
MergerTest()
: rnd_(3), merging_iterator_(nullptr), single_iterator_(nullptr) {}
~MergerTest() = default;
std::vector<std::string> GenerateStrings(size_t len, int string_len) {
std::vector<std::string> ret;
for (size_t i = 0; i < len; ++i) {
ret.push_back(test::RandomHumanReadableString(&rnd_, string_len));
}
return ret;
}
void AssertEquivalence() {
auto a = merging_iterator_.get();
auto b = single_iterator_.get();
if (!a->Valid()) {
ASSERT_TRUE(!b->Valid());
} else {
ASSERT_TRUE(b->Valid());
ASSERT_EQ(b->key().ToString(), a->key().ToString());
ASSERT_EQ(b->value().ToString(), a->value().ToString());
}
}
void SeekToRandom() { Seek(test::RandomHumanReadableString(&rnd_, 5)); }
void Seek(std::string target) {
merging_iterator_->Seek(target);
single_iterator_->Seek(target);
}
void SeekToFirst() {
merging_iterator_->SeekToFirst();
single_iterator_->SeekToFirst();
}
void SeekToLast() {
merging_iterator_->SeekToLast();
single_iterator_->SeekToLast();
}
void Next(int times) {
for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
AssertEquivalence();
merging_iterator_->Next();
single_iterator_->Next();
}
AssertEquivalence();
}
void Prev(int times) {
for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
AssertEquivalence();
merging_iterator_->Prev();
single_iterator_->Prev();
}
AssertEquivalence();
}
void NextAndPrev(int times) {
for (int i = 0; i < times && merging_iterator_->Valid(); ++i) {
AssertEquivalence();
if (rnd_.OneIn(2)) {
merging_iterator_->Prev();
single_iterator_->Prev();
} else {
merging_iterator_->Next();
single_iterator_->Next();
}
}
AssertEquivalence();
}
void Generate(size_t num_iterators, size_t strings_per_iterator,
int letters_per_string) {
std::vector<Iterator*> small_iterators;
for (size_t i = 0; i < num_iterators; ++i) {
auto strings = GenerateStrings(strings_per_iterator, letters_per_string);
small_iterators.push_back(new VectorIterator(strings));
all_keys_.insert(all_keys_.end(), strings.begin(), strings.end());
}
merging_iterator_.reset(
NewMergingIterator(BytewiseComparator(), &small_iterators[0],
static_cast<int>(small_iterators.size())));
single_iterator_.reset(new VectorIterator(all_keys_));
}
Random rnd_;
std::unique_ptr<Iterator> merging_iterator_;
std::unique_ptr<Iterator> single_iterator_;
std::vector<std::string> all_keys_;
};
TEST_F(MergerTest, SeekToRandomNextTest) {
Generate(1000, 50, 50);
for (int i = 0; i < 10; ++i) {
SeekToRandom();
AssertEquivalence();
Next(50000);
}
}
TEST_F(MergerTest, SeekToRandomNextSmallStringsTest) {
Generate(1000, 50, 2);
for (int i = 0; i < 10; ++i) {
SeekToRandom();
AssertEquivalence();
Next(50000);
}
}
TEST_F(MergerTest, SeekToRandomPrevTest) {
Generate(1000, 50, 50);
for (int i = 0; i < 10; ++i) {
SeekToRandom();
AssertEquivalence();
Prev(50000);
}
}
TEST_F(MergerTest, SeekToRandomRandomTest) {
Generate(200, 50, 50);
for (int i = 0; i < 3; ++i) {
SeekToRandom();
AssertEquivalence();
NextAndPrev(5000);
}
}
TEST_F(MergerTest, SeekToFirstTest) {
Generate(1000, 50, 50);
for (int i = 0; i < 10; ++i) {
SeekToFirst();
AssertEquivalence();
Next(50000);
}
}
TEST_F(MergerTest, SeekToLastTest) {
Generate(1000, 50, 50);
for (int i = 0; i < 10; ++i) {
SeekToLast();
AssertEquivalence();
Prev(50000);
}
}
} // namespace rocksdb
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}