| // Copyright (c) 2011 The LevelDB Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. See the AUTHORS file for names of contributors. |
| |
| #include "env/mock_env.h" |
| |
| #include <memory> |
| #include <string> |
| |
| #include "rocksdb/env.h" |
| #include "util/testharness.h" |
| |
| namespace rocksdb { |
| |
| class MockEnvTest : public testing::Test { |
| public: |
| MockEnv* env_; |
| const EnvOptions soptions_; |
| |
| MockEnvTest() |
| : env_(new MockEnv(Env::Default())) { |
| } |
| ~MockEnvTest() { |
| delete env_; |
| } |
| }; |
| |
| TEST_F(MockEnvTest, Corrupt) { |
| const std::string kGood = "this is a good string, synced to disk"; |
| const std::string kCorrupted = "this part may be corrupted"; |
| const std::string kFileName = "/dir/f"; |
| unique_ptr<WritableFile> writable_file; |
| ASSERT_OK(env_->NewWritableFile(kFileName, &writable_file, soptions_)); |
| ASSERT_OK(writable_file->Append(kGood)); |
| ASSERT_TRUE(writable_file->GetFileSize() == kGood.size()); |
| |
| std::string scratch; |
| scratch.resize(kGood.size() + kCorrupted.size() + 16); |
| Slice result; |
| unique_ptr<RandomAccessFile> rand_file; |
| ASSERT_OK(env_->NewRandomAccessFile(kFileName, &rand_file, soptions_)); |
| ASSERT_OK(rand_file->Read(0, kGood.size(), &result, &(scratch[0]))); |
| ASSERT_EQ(result.compare(kGood), 0); |
| |
| // Sync + corrupt => no change |
| ASSERT_OK(writable_file->Fsync()); |
| ASSERT_OK(dynamic_cast<MockEnv*>(env_)->CorruptBuffer(kFileName)); |
| result.clear(); |
| ASSERT_OK(rand_file->Read(0, kGood.size(), &result, &(scratch[0]))); |
| ASSERT_EQ(result.compare(kGood), 0); |
| |
| // Add new data and corrupt it |
| ASSERT_OK(writable_file->Append(kCorrupted)); |
| ASSERT_TRUE(writable_file->GetFileSize() == kGood.size() + kCorrupted.size()); |
| result.clear(); |
| ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(), |
| &result, &(scratch[0]))); |
| ASSERT_EQ(result.compare(kCorrupted), 0); |
| // Corrupted |
| ASSERT_OK(dynamic_cast<MockEnv*>(env_)->CorruptBuffer(kFileName)); |
| result.clear(); |
| ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(), |
| &result, &(scratch[0]))); |
| ASSERT_NE(result.compare(kCorrupted), 0); |
| } |
| |
| TEST_F(MockEnvTest, FakeSleeping) { |
| int64_t now = 0; |
| auto s = env_->GetCurrentTime(&now); |
| ASSERT_OK(s); |
| env_->FakeSleepForMicroseconds(3 * 1000 * 1000); |
| int64_t after_sleep = 0; |
| s = env_->GetCurrentTime(&after_sleep); |
| ASSERT_OK(s); |
| auto delta = after_sleep - now; |
| // this will be true unless test runs for 2 seconds |
| ASSERT_TRUE(delta == 3 || delta == 4); |
| } |
| |
| } // namespace rocksdb |
| |
| int main(int argc, char** argv) { |
| ::testing::InitGoogleTest(&argc, argv); |
| return RUN_ALL_TESTS(); |
| } |