1 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. See the AUTHORS file for names of contributors.
4 //
5 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
6 
7 #include "env/mock_env.h"
8 
9 #include <memory>
10 #include <string>
11 
12 #include "rocksdb/env.h"
13 #include "test_util/testharness.h"
14 
15 namespace ROCKSDB_NAMESPACE {
16 
17 class MockEnvTest : public testing::Test {
18  public:
19   MockEnv* env_;
20   const EnvOptions soptions_;
21 
MockEnvTest()22   MockEnvTest() : env_(MockEnv::Create(Env::Default())) {}
~MockEnvTest()23   ~MockEnvTest() override { delete env_; }
24 };
25 
TEST_F(MockEnvTest,Corrupt)26 TEST_F(MockEnvTest, Corrupt) {
27   const std::string kGood = "this is a good string, synced to disk";
28   const std::string kCorrupted = "this part may be corrupted";
29   const std::string kFileName = "/dir/f";
30   std::unique_ptr<WritableFile> writable_file;
31   ASSERT_OK(env_->NewWritableFile(kFileName, &writable_file, soptions_));
32   ASSERT_OK(writable_file->Append(kGood));
33   ASSERT_TRUE(writable_file->GetFileSize() == kGood.size());
34 
35   std::string scratch;
36   scratch.resize(kGood.size() + kCorrupted.size() + 16);
37   Slice result;
38   std::unique_ptr<RandomAccessFile> rand_file;
39   ASSERT_OK(env_->NewRandomAccessFile(kFileName, &rand_file, soptions_));
40   ASSERT_OK(rand_file->Read(0, kGood.size(), &result, &(scratch[0])));
41   ASSERT_EQ(result.compare(kGood), 0);
42 
43   // Sync + corrupt => no change
44   ASSERT_OK(writable_file->Fsync());
45   ASSERT_OK(dynamic_cast<MockEnv*>(env_)->CorruptBuffer(kFileName));
46   result.clear();
47   ASSERT_OK(rand_file->Read(0, kGood.size(), &result, &(scratch[0])));
48   ASSERT_EQ(result.compare(kGood), 0);
49 
50   // Add new data and corrupt it
51   ASSERT_OK(writable_file->Append(kCorrupted));
52   ASSERT_TRUE(writable_file->GetFileSize() == kGood.size() + kCorrupted.size());
53   result.clear();
54   ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(),
55             &result, &(scratch[0])));
56   ASSERT_EQ(result.compare(kCorrupted), 0);
57   // Corrupted
58   ASSERT_OK(dynamic_cast<MockEnv*>(env_)->CorruptBuffer(kFileName));
59   result.clear();
60   ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(),
61             &result, &(scratch[0])));
62   ASSERT_NE(result.compare(kCorrupted), 0);
63 }
64 
TEST_F(MockEnvTest,FakeSleeping)65 TEST_F(MockEnvTest, FakeSleeping) {
66   int64_t now = 0;
67   auto s = env_->GetCurrentTime(&now);
68   ASSERT_OK(s);
69   env_->SleepForMicroseconds(3 * 1000 * 1000);
70   int64_t after_sleep = 0;
71   s = env_->GetCurrentTime(&after_sleep);
72   ASSERT_OK(s);
73   auto delta = after_sleep - now;
74   // this will be true unless test runs for 2 seconds
75   ASSERT_TRUE(delta == 3 || delta == 4);
76 }
77 
78 }  // namespace ROCKSDB_NAMESPACE
79 
main(int argc,char ** argv)80 int main(int argc, char** argv) {
81   ::testing::InitGoogleTest(&argc, argv);
82   return RUN_ALL_TESTS();
83 }
84