2014-10-31 23:08:10 +01:00
|
|
|
// 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.
|
2019-04-18 19:51:19 +02:00
|
|
|
//
|
|
|
|
// Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
|
2014-10-31 23:08:10 +01:00
|
|
|
|
2017-04-06 04:02:00 +02:00
|
|
|
#include "env/mock_env.h"
|
2016-06-04 00:13:03 +02:00
|
|
|
|
2014-10-31 23:08:10 +01:00
|
|
|
#include <memory>
|
|
|
|
#include <string>
|
2016-06-04 00:13:03 +02:00
|
|
|
|
2014-10-31 23:08:10 +01:00
|
|
|
#include "rocksdb/env.h"
|
2019-05-30 20:21:38 +02:00
|
|
|
#include "test_util/testharness.h"
|
2014-10-31 23:08:10 +01:00
|
|
|
|
2020-02-20 21:07:53 +01:00
|
|
|
namespace ROCKSDB_NAMESPACE {
|
2014-10-31 23:08:10 +01:00
|
|
|
|
2015-03-17 22:08:00 +01:00
|
|
|
class MockEnvTest : public testing::Test {
|
2014-10-31 23:08:10 +01:00
|
|
|
public:
|
2015-04-14 01:15:05 +02:00
|
|
|
MockEnv* env_;
|
2014-10-31 23:08:10 +01:00
|
|
|
const EnvOptions soptions_;
|
|
|
|
|
|
|
|
MockEnvTest()
|
|
|
|
: env_(new MockEnv(Env::Default())) {
|
|
|
|
}
|
2019-02-19 22:36:04 +01:00
|
|
|
~MockEnvTest() override { delete env_; }
|
2014-10-31 23:08:10 +01:00
|
|
|
};
|
|
|
|
|
2015-03-17 22:08:00 +01:00
|
|
|
TEST_F(MockEnvTest, Corrupt) {
|
2014-10-31 23:16:31 +01:00
|
|
|
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";
|
2018-11-09 20:17:34 +01:00
|
|
|
std::unique_ptr<WritableFile> writable_file;
|
2014-10-31 23:16:31 +01:00
|
|
|
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;
|
2018-11-09 20:17:34 +01:00
|
|
|
std::unique_ptr<RandomAccessFile> rand_file;
|
2014-10-31 23:16:31 +01:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-04-14 01:15:05 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2020-02-20 21:07:53 +01:00
|
|
|
} // namespace ROCKSDB_NAMESPACE
|
2014-10-31 23:08:10 +01:00
|
|
|
|
|
|
|
int main(int argc, char** argv) {
|
2015-03-17 22:08:00 +01:00
|
|
|
::testing::InitGoogleTest(&argc, argv);
|
|
|
|
return RUN_ALL_TESTS();
|
2014-10-31 23:08:10 +01:00
|
|
|
}
|