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()
23       : env_(new MockEnv(Env::Default())) {
24   }
~MockEnvTest()25   ~MockEnvTest() override { delete env_; }
26 };
27 
TEST_F(MockEnvTest,Corrupt)28 TEST_F(MockEnvTest, Corrupt) {
29   const std::string kGood = "this is a good string, synced to disk";
30   const std::string kCorrupted = "this part may be corrupted";
31   const std::string kFileName = "/dir/f";
32   std::unique_ptr<WritableFile> writable_file;
33   ASSERT_OK(env_->NewWritableFile(kFileName, &writable_file, soptions_));
34   ASSERT_OK(writable_file->Append(kGood));
35   ASSERT_TRUE(writable_file->GetFileSize() == kGood.size());
36 
37   std::string scratch;
38   scratch.resize(kGood.size() + kCorrupted.size() + 16);
39   Slice result;
40   std::unique_ptr<RandomAccessFile> rand_file;
41   ASSERT_OK(env_->NewRandomAccessFile(kFileName, &rand_file, soptions_));
42   ASSERT_OK(rand_file->Read(0, kGood.size(), &result, &(scratch[0])));
43   ASSERT_EQ(result.compare(kGood), 0);
44 
45   // Sync + corrupt => no change
46   ASSERT_OK(writable_file->Fsync());
47   ASSERT_OK(dynamic_cast<MockEnv*>(env_)->CorruptBuffer(kFileName));
48   result.clear();
49   ASSERT_OK(rand_file->Read(0, kGood.size(), &result, &(scratch[0])));
50   ASSERT_EQ(result.compare(kGood), 0);
51 
52   // Add new data and corrupt it
53   ASSERT_OK(writable_file->Append(kCorrupted));
54   ASSERT_TRUE(writable_file->GetFileSize() == kGood.size() + kCorrupted.size());
55   result.clear();
56   ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(),
57             &result, &(scratch[0])));
58   ASSERT_EQ(result.compare(kCorrupted), 0);
59   // Corrupted
60   ASSERT_OK(dynamic_cast<MockEnv*>(env_)->CorruptBuffer(kFileName));
61   result.clear();
62   ASSERT_OK(rand_file->Read(kGood.size(), kCorrupted.size(),
63             &result, &(scratch[0])));
64   ASSERT_NE(result.compare(kCorrupted), 0);
65 }
66 
TEST_F(MockEnvTest,FakeSleeping)67 TEST_F(MockEnvTest, FakeSleeping) {
68   int64_t now = 0;
69   auto s = env_->GetCurrentTime(&now);
70   ASSERT_OK(s);
71   env_->FakeSleepForMicroseconds(3 * 1000 * 1000);
72   int64_t after_sleep = 0;
73   s = env_->GetCurrentTime(&after_sleep);
74   ASSERT_OK(s);
75   auto delta = after_sleep - now;
76   // this will be true unless test runs for 2 seconds
77   ASSERT_TRUE(delta == 3 || delta == 4);
78 }
79 
80 }  // namespace ROCKSDB_NAMESPACE
81 
main(int argc,char ** argv)82 int main(int argc, char** argv) {
83   ::testing::InitGoogleTest(&argc, argv);
84   return RUN_ALL_TESTS();
85 }
86