]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/wal_edit_test.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / rocksdb / db / wal_edit_test.cc
CommitLineData
20effc67
TL
1// Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2// This source code is licensed under both the GPLv2 (found in the
3// COPYING file in the root directory) and Apache 2.0 License
4// (found in the LICENSE.Apache file in the root directory).
5
6#include "db/wal_edit.h"
7
8#include "db/db_test_util.h"
9#include "file/file_util.h"
10#include "port/port.h"
11#include "port/stack_trace.h"
12#include "test_util/testharness.h"
13#include "test_util/testutil.h"
14
15namespace ROCKSDB_NAMESPACE {
16
17TEST(WalSet, AddDeleteReset) {
18 WalSet wals;
19 ASSERT_TRUE(wals.GetWals().empty());
20
21 // Create WAL 1 - 10.
22 for (WalNumber log_number = 1; log_number <= 10; log_number++) {
23 wals.AddWal(WalAddition(log_number));
24 }
25 ASSERT_EQ(wals.GetWals().size(), 10);
26
27 // Delete WAL 1 - 5.
28 wals.DeleteWalsBefore(6);
29 ASSERT_EQ(wals.GetWals().size(), 5);
30
31 WalNumber expected_log_number = 6;
32 for (auto it : wals.GetWals()) {
33 WalNumber log_number = it.first;
34 ASSERT_EQ(log_number, expected_log_number++);
35 }
36
37 wals.Reset();
38 ASSERT_TRUE(wals.GetWals().empty());
39}
40
41TEST(WalSet, Overwrite) {
42 constexpr WalNumber kNumber = 100;
43 constexpr uint64_t kBytes = 200;
44 WalSet wals;
45 wals.AddWal(WalAddition(kNumber));
46 ASSERT_FALSE(wals.GetWals().at(kNumber).HasSyncedSize());
47 wals.AddWal(WalAddition(kNumber, WalMetadata(kBytes)));
48 ASSERT_TRUE(wals.GetWals().at(kNumber).HasSyncedSize());
49 ASSERT_EQ(wals.GetWals().at(kNumber).GetSyncedSizeInBytes(), kBytes);
50}
51
52TEST(WalSet, SmallerSyncedSize) {
53 constexpr WalNumber kNumber = 100;
54 constexpr uint64_t kBytes = 100;
55 WalSet wals;
56 ASSERT_OK(wals.AddWal(WalAddition(kNumber, WalMetadata(kBytes))));
57 Status s = wals.AddWal(WalAddition(kNumber, WalMetadata(0)));
58 ASSERT_TRUE(s.IsCorruption());
59 ASSERT_TRUE(
60 s.ToString().find(
61 "WAL 100 must not have smaller synced size than previous one") !=
62 std::string::npos);
63}
64
65TEST(WalSet, CreateTwice) {
66 constexpr WalNumber kNumber = 100;
67 WalSet wals;
68 ASSERT_OK(wals.AddWal(WalAddition(kNumber)));
69 Status s = wals.AddWal(WalAddition(kNumber));
70 ASSERT_TRUE(s.IsCorruption());
71 ASSERT_TRUE(s.ToString().find("WAL 100 is created more than once") !=
72 std::string::npos);
73}
74
75TEST(WalSet, DeleteAllWals) {
76 constexpr WalNumber kMaxWalNumber = 10;
77 WalSet wals;
78 for (WalNumber i = 1; i <= kMaxWalNumber; i++) {
79 wals.AddWal(WalAddition(i));
80 }
81 ASSERT_OK(wals.DeleteWalsBefore(kMaxWalNumber + 1));
82}
83
84class WalSetTest : public DBTestBase {
85 public:
86 WalSetTest() : DBTestBase("WalSetTest", /* env_do_fsync */ true) {}
87
88 void SetUp() override {
89 test_dir_ = test::PerThreadDBPath("wal_set_test");
90 ASSERT_OK(env_->CreateDir(test_dir_));
91 }
92
93 void TearDown() override {
94 EXPECT_OK(DestroyDir(env_, test_dir_));
95 logs_on_disk_.clear();
96 wals_.Reset();
97 }
98
99 void CreateWalOnDisk(WalNumber number, const std::string& fname,
100 uint64_t size_bytes) {
101 std::unique_ptr<WritableFile> f;
102 std::string fpath = Path(fname);
103 ASSERT_OK(env_->NewWritableFile(fpath, &f, EnvOptions()));
104 std::string content(size_bytes, '0');
105 ASSERT_OK(f->Append(content));
106 ASSERT_OK(f->Close());
107
108 logs_on_disk_[number] = fpath;
109 }
110
111 void AddWalToWalSet(WalNumber number, uint64_t size_bytes) {
112 // Create WAL.
113 ASSERT_OK(wals_.AddWal(WalAddition(number)));
114 // Close WAL.
115 WalMetadata wal(size_bytes);
116 ASSERT_OK(wals_.AddWal(WalAddition(number, wal)));
117 }
118
119 Status CheckWals() const { return wals_.CheckWals(env_, logs_on_disk_); }
120
121 private:
122 std::string test_dir_;
123 std::unordered_map<WalNumber, std::string> logs_on_disk_;
124 WalSet wals_;
125
126 std::string Path(const std::string& fname) { return test_dir_ + "/" + fname; }
127};
128
129TEST_F(WalSetTest, CheckEmptyWals) { ASSERT_OK(CheckWals()); }
130
131TEST_F(WalSetTest, CheckWals) {
132 for (int number = 1; number < 10; number++) {
133 uint64_t size = rand() % 100;
134 std::stringstream ss;
135 ss << "log" << number;
136 std::string fname = ss.str();
137 CreateWalOnDisk(number, fname, size);
138 // log 0 - 5 are obsolete.
139 if (number > 5) {
140 AddWalToWalSet(number, size);
141 }
142 }
143 ASSERT_OK(CheckWals());
144}
145
146TEST_F(WalSetTest, CheckMissingWals) {
147 for (int number = 1; number < 10; number++) {
148 uint64_t size = rand() % 100;
149 AddWalToWalSet(number, size);
150 // logs with even number are missing from disk.
151 if (number % 2) {
152 std::stringstream ss;
153 ss << "log" << number;
154 std::string fname = ss.str();
155 CreateWalOnDisk(number, fname, size);
156 }
157 }
158
159 Status s = CheckWals();
160 ASSERT_TRUE(s.IsCorruption()) << s.ToString();
161 // The first log with even number is missing.
162 std::stringstream expected_err;
163 expected_err << "Missing WAL with log number: " << 2;
164 ASSERT_TRUE(s.ToString().find(expected_err.str()) != std::string::npos)
165 << s.ToString();
166}
167
168TEST_F(WalSetTest, CheckWalsWithShrinkedSize) {
169 for (int number = 1; number < 10; number++) {
170 uint64_t size = rand() % 100 + 1;
171 AddWalToWalSet(number, size);
172 // logs with even number have shrinked size.
173 std::stringstream ss;
174 ss << "log" << number;
175 std::string fname = ss.str();
176 CreateWalOnDisk(number, fname, (number % 2) ? size : size - 1);
177 }
178
179 Status s = CheckWals();
180 ASSERT_TRUE(s.IsCorruption()) << s.ToString();
181 // The first log with even number has wrong size.
182 std::stringstream expected_err;
183 expected_err << "Size mismatch: WAL (log number: " << 2 << ")";
184 ASSERT_TRUE(s.ToString().find(expected_err.str()) != std::string::npos)
185 << s.ToString();
186}
187
188} // namespace ROCKSDB_NAMESPACE
189
190int main(int argc, char** argv) {
191 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
192 ::testing::InitGoogleTest(&argc, argv);
193 return RUN_ALL_TESTS();
194}