// 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. // // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved. #include "env/mock_env.h" #include #include #include "rocksdb/env.h" #include "test_util/testharness.h" namespace ROCKSDB_NAMESPACE { class MockEnvTest : public testing::Test { public: MockEnv* env_; const EnvOptions soptions_; MockEnvTest() : env_(MockEnv::Create(Env::Default())) {} ~MockEnvTest() override { 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"; std::unique_ptr 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; std::unique_ptr rand_file; ASSERT_OK(env_->NewRandomAccessFile(kFileName, &rand_file, soptions_)); ASSERT_OK(rand_file->Read(0, kGood.size(), &result, scratch.data())); ASSERT_EQ(result.compare(kGood), 0); // Sync + corrupt => no change ASSERT_OK(writable_file->Fsync()); ASSERT_OK(dynamic_cast(env_)->CorruptBuffer(kFileName)); result.clear(); ASSERT_OK(rand_file->Read(0, kGood.size(), &result, scratch.data())); 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.data())); ASSERT_EQ(result.compare(kCorrupted), 0); // Corrupted ASSERT_OK(dynamic_cast(env_)->CorruptBuffer(kFileName)); result.clear(); ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(), &result, scratch.data())); ASSERT_NE(result.compare(kCorrupted), 0); } TEST_F(MockEnvTest, FakeSleeping) { int64_t now = 0; auto s = env_->GetCurrentTime(&now); ASSERT_OK(s); env_->SleepForMicroseconds(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_NAMESPACE int main(int argc, char** argv) { ROCKSDB_NAMESPACE::port::InstallStackTraceHandler(); ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }