]> git.proxmox.com Git - ceph.git/blame - ceph/src/rocksdb/db/wal_edit_test.cc
update ceph source to reef 18.1.2
[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))));
1e59de90 57 const auto wals1 = wals.GetWals();
20effc67 58 Status s = wals.AddWal(WalAddition(kNumber, WalMetadata(0)));
1e59de90
TL
59 const auto wals2 = wals.GetWals();
60 ASSERT_OK(s);
61 ASSERT_EQ(wals1, wals2);
20effc67
TL
62}
63
64TEST(WalSet, CreateTwice) {
65 constexpr WalNumber kNumber = 100;
66 WalSet wals;
67 ASSERT_OK(wals.AddWal(WalAddition(kNumber)));
68 Status s = wals.AddWal(WalAddition(kNumber));
69 ASSERT_TRUE(s.IsCorruption());
70 ASSERT_TRUE(s.ToString().find("WAL 100 is created more than once") !=
71 std::string::npos);
72}
73
74TEST(WalSet, DeleteAllWals) {
75 constexpr WalNumber kMaxWalNumber = 10;
76 WalSet wals;
77 for (WalNumber i = 1; i <= kMaxWalNumber; i++) {
78 wals.AddWal(WalAddition(i));
79 }
80 ASSERT_OK(wals.DeleteWalsBefore(kMaxWalNumber + 1));
81}
82
1e59de90
TL
83TEST(WalSet, AddObsoleteWal) {
84 constexpr WalNumber kNumber = 100;
85 WalSet wals;
86 ASSERT_OK(wals.DeleteWalsBefore(kNumber + 1));
87 ASSERT_OK(wals.AddWal(WalAddition(kNumber)));
88 ASSERT_TRUE(wals.GetWals().empty());
89}
90
91TEST(WalSet, MinWalNumberToKeep) {
92 constexpr WalNumber kNumber = 100;
93 WalSet wals;
94 ASSERT_EQ(wals.GetMinWalNumberToKeep(), 0);
95 ASSERT_OK(wals.DeleteWalsBefore(kNumber));
96 ASSERT_EQ(wals.GetMinWalNumberToKeep(), kNumber);
97 ASSERT_OK(wals.DeleteWalsBefore(kNumber - 1));
98 ASSERT_EQ(wals.GetMinWalNumberToKeep(), kNumber);
99 ASSERT_OK(wals.DeleteWalsBefore(kNumber + 1));
100 ASSERT_EQ(wals.GetMinWalNumberToKeep(), kNumber + 1);
101}
102
20effc67
TL
103class WalSetTest : public DBTestBase {
104 public:
105 WalSetTest() : DBTestBase("WalSetTest", /* env_do_fsync */ true) {}
106
107 void SetUp() override {
108 test_dir_ = test::PerThreadDBPath("wal_set_test");
109 ASSERT_OK(env_->CreateDir(test_dir_));
110 }
111
112 void TearDown() override {
113 EXPECT_OK(DestroyDir(env_, test_dir_));
114 logs_on_disk_.clear();
115 wals_.Reset();
116 }
117
118 void CreateWalOnDisk(WalNumber number, const std::string& fname,
119 uint64_t size_bytes) {
120 std::unique_ptr<WritableFile> f;
121 std::string fpath = Path(fname);
122 ASSERT_OK(env_->NewWritableFile(fpath, &f, EnvOptions()));
123 std::string content(size_bytes, '0');
124 ASSERT_OK(f->Append(content));
125 ASSERT_OK(f->Close());
126
127 logs_on_disk_[number] = fpath;
128 }
129
130 void AddWalToWalSet(WalNumber number, uint64_t size_bytes) {
131 // Create WAL.
132 ASSERT_OK(wals_.AddWal(WalAddition(number)));
133 // Close WAL.
134 WalMetadata wal(size_bytes);
135 ASSERT_OK(wals_.AddWal(WalAddition(number, wal)));
136 }
137
138 Status CheckWals() const { return wals_.CheckWals(env_, logs_on_disk_); }
139
140 private:
141 std::string test_dir_;
142 std::unordered_map<WalNumber, std::string> logs_on_disk_;
143 WalSet wals_;
144
145 std::string Path(const std::string& fname) { return test_dir_ + "/" + fname; }
146};
147
148TEST_F(WalSetTest, CheckEmptyWals) { ASSERT_OK(CheckWals()); }
149
150TEST_F(WalSetTest, CheckWals) {
151 for (int number = 1; number < 10; number++) {
152 uint64_t size = rand() % 100;
153 std::stringstream ss;
154 ss << "log" << number;
155 std::string fname = ss.str();
156 CreateWalOnDisk(number, fname, size);
157 // log 0 - 5 are obsolete.
158 if (number > 5) {
159 AddWalToWalSet(number, size);
160 }
161 }
162 ASSERT_OK(CheckWals());
163}
164
165TEST_F(WalSetTest, CheckMissingWals) {
166 for (int number = 1; number < 10; number++) {
167 uint64_t size = rand() % 100;
168 AddWalToWalSet(number, size);
169 // logs with even number are missing from disk.
170 if (number % 2) {
171 std::stringstream ss;
172 ss << "log" << number;
173 std::string fname = ss.str();
174 CreateWalOnDisk(number, fname, size);
175 }
176 }
177
178 Status s = CheckWals();
179 ASSERT_TRUE(s.IsCorruption()) << s.ToString();
180 // The first log with even number is missing.
181 std::stringstream expected_err;
182 expected_err << "Missing WAL with log number: " << 2;
183 ASSERT_TRUE(s.ToString().find(expected_err.str()) != std::string::npos)
184 << s.ToString();
185}
186
187TEST_F(WalSetTest, CheckWalsWithShrinkedSize) {
188 for (int number = 1; number < 10; number++) {
189 uint64_t size = rand() % 100 + 1;
190 AddWalToWalSet(number, size);
191 // logs with even number have shrinked size.
192 std::stringstream ss;
193 ss << "log" << number;
194 std::string fname = ss.str();
195 CreateWalOnDisk(number, fname, (number % 2) ? size : size - 1);
196 }
197
198 Status s = CheckWals();
199 ASSERT_TRUE(s.IsCorruption()) << s.ToString();
200 // The first log with even number has wrong size.
201 std::stringstream expected_err;
202 expected_err << "Size mismatch: WAL (log number: " << 2 << ")";
203 ASSERT_TRUE(s.ToString().find(expected_err.str()) != std::string::npos)
204 << s.ToString();
205}
206
207} // namespace ROCKSDB_NAMESPACE
208
209int main(int argc, char** argv) {
210 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
211 ::testing::InitGoogleTest(&argc, argv);
212 return RUN_ALL_TESTS();
213}