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