]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/utilities/env_mirror_test.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / rocksdb / utilities / env_mirror_test.cc
1 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
2 // Copyright (c) 2015, Red Hat, Inc. All rights reserved.
3 // This source code is licensed under both the GPLv2 (found in the
4 // COPYING file in the root directory) and Apache 2.0 License
5 // (found in the LICENSE.Apache file in the root directory).
6
7 #ifndef ROCKSDB_LITE
8
9 #include "rocksdb/utilities/env_mirror.h"
10
11 #include "env/mock_env.h"
12 #include "test_util/testharness.h"
13
14 namespace ROCKSDB_NAMESPACE {
15
16 class EnvMirrorTest : public testing::Test {
17 public:
18 Env* default_;
19 MockEnv *a_, *b_;
20 EnvMirror* env_;
21 const EnvOptions soptions_;
22
23 EnvMirrorTest()
24 : default_(Env::Default()),
25 a_(new MockEnv(default_)),
26 b_(new MockEnv(default_)),
27 env_(new EnvMirror(a_, b_)) {}
28 ~EnvMirrorTest() {
29 delete env_;
30 delete a_;
31 delete b_;
32 }
33 };
34
35 TEST_F(EnvMirrorTest, Basics) {
36 uint64_t file_size;
37 std::unique_ptr<WritableFile> writable_file;
38 std::vector<std::string> children;
39
40 ASSERT_OK(env_->CreateDir("/dir"));
41
42 // Check that the directory is empty.
43 ASSERT_EQ(Status::NotFound(), env_->FileExists("/dir/non_existent"));
44 ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
45 ASSERT_OK(env_->GetChildren("/dir", &children));
46 ASSERT_EQ(0U, children.size());
47
48 // Create a file.
49 ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file, soptions_));
50 writable_file.reset();
51
52 // Check that the file exists.
53 ASSERT_OK(env_->FileExists("/dir/f"));
54 ASSERT_OK(a_->FileExists("/dir/f"));
55 ASSERT_OK(b_->FileExists("/dir/f"));
56 ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
57 ASSERT_EQ(0U, file_size);
58 ASSERT_OK(env_->GetChildren("/dir", &children));
59 ASSERT_EQ(1U, children.size());
60 ASSERT_EQ("f", children[0]);
61 ASSERT_OK(a_->GetChildren("/dir", &children));
62 ASSERT_EQ(1U, children.size());
63 ASSERT_EQ("f", children[0]);
64 ASSERT_OK(b_->GetChildren("/dir", &children));
65 ASSERT_EQ(1U, children.size());
66 ASSERT_EQ("f", children[0]);
67
68 // Write to the file.
69 ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file, soptions_));
70 ASSERT_OK(writable_file->Append("abc"));
71 writable_file.reset();
72
73 // Check for expected size.
74 ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
75 ASSERT_EQ(3U, file_size);
76 ASSERT_OK(a_->GetFileSize("/dir/f", &file_size));
77 ASSERT_EQ(3U, file_size);
78 ASSERT_OK(b_->GetFileSize("/dir/f", &file_size));
79 ASSERT_EQ(3U, file_size);
80
81 // Check that renaming works.
82 ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
83 ASSERT_OK(env_->RenameFile("/dir/f", "/dir/g"));
84 ASSERT_EQ(Status::NotFound(), env_->FileExists("/dir/f"));
85 ASSERT_OK(env_->FileExists("/dir/g"));
86 ASSERT_OK(env_->GetFileSize("/dir/g", &file_size));
87 ASSERT_EQ(3U, file_size);
88 ASSERT_OK(a_->FileExists("/dir/g"));
89 ASSERT_OK(a_->GetFileSize("/dir/g", &file_size));
90 ASSERT_EQ(3U, file_size);
91 ASSERT_OK(b_->FileExists("/dir/g"));
92 ASSERT_OK(b_->GetFileSize("/dir/g", &file_size));
93 ASSERT_EQ(3U, file_size);
94
95 // Check that opening non-existent file fails.
96 std::unique_ptr<SequentialFile> seq_file;
97 std::unique_ptr<RandomAccessFile> rand_file;
98 ASSERT_TRUE(
99 !env_->NewSequentialFile("/dir/non_existent", &seq_file, soptions_).ok());
100 ASSERT_TRUE(!seq_file);
101 ASSERT_TRUE(
102 !env_->NewRandomAccessFile("/dir/non_existent", &rand_file, soptions_)
103 .ok());
104 ASSERT_TRUE(!rand_file);
105
106 // Check that deleting works.
107 ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok());
108 ASSERT_OK(env_->DeleteFile("/dir/g"));
109 ASSERT_EQ(Status::NotFound(), env_->FileExists("/dir/g"));
110 ASSERT_OK(env_->GetChildren("/dir", &children));
111 ASSERT_EQ(0U, children.size());
112 ASSERT_OK(env_->DeleteDir("/dir"));
113 }
114
115 TEST_F(EnvMirrorTest, ReadWrite) {
116 std::unique_ptr<WritableFile> writable_file;
117 std::unique_ptr<SequentialFile> seq_file;
118 std::unique_ptr<RandomAccessFile> rand_file;
119 Slice result;
120 char scratch[100];
121
122 ASSERT_OK(env_->CreateDir("/dir"));
123
124 ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file, soptions_));
125 ASSERT_OK(writable_file->Append("hello "));
126 ASSERT_OK(writable_file->Append("world"));
127 writable_file.reset();
128
129 // Read sequentially.
130 ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file, soptions_));
131 ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
132 ASSERT_EQ(0, result.compare("hello"));
133 ASSERT_OK(seq_file->Skip(1));
134 ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
135 ASSERT_EQ(0, result.compare("world"));
136 ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
137 ASSERT_EQ(0U, result.size());
138 ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file.
139 ASSERT_OK(seq_file->Read(1000, &result, scratch));
140 ASSERT_EQ(0U, result.size());
141
142 // Random reads.
143 ASSERT_OK(env_->NewRandomAccessFile("/dir/f", &rand_file, soptions_));
144 ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
145 ASSERT_EQ(0, result.compare("world"));
146 ASSERT_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello".
147 ASSERT_EQ(0, result.compare("hello"));
148 ASSERT_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d".
149 ASSERT_EQ(0, result.compare("d"));
150
151 // Too high offset.
152 ASSERT_TRUE(!rand_file->Read(1000, 5, &result, scratch).ok());
153 }
154
155 TEST_F(EnvMirrorTest, Locks) {
156 FileLock* lock;
157
158 // These are no-ops, but we test they return success.
159 ASSERT_OK(env_->LockFile("some file", &lock));
160 ASSERT_OK(env_->UnlockFile(lock));
161 }
162
163 TEST_F(EnvMirrorTest, Misc) {
164 std::string test_dir;
165 ASSERT_OK(env_->GetTestDirectory(&test_dir));
166 ASSERT_TRUE(!test_dir.empty());
167
168 std::unique_ptr<WritableFile> writable_file;
169 ASSERT_OK(env_->NewWritableFile("/a/b", &writable_file, soptions_));
170
171 // These are no-ops, but we test they return success.
172 ASSERT_OK(writable_file->Sync());
173 ASSERT_OK(writable_file->Flush());
174 ASSERT_OK(writable_file->Close());
175 writable_file.reset();
176 }
177
178 TEST_F(EnvMirrorTest, LargeWrite) {
179 const size_t kWriteSize = 300 * 1024;
180 char* scratch = new char[kWriteSize * 2];
181
182 std::string write_data;
183 for (size_t i = 0; i < kWriteSize; ++i) {
184 write_data.append(1, static_cast<char>(i));
185 }
186
187 std::unique_ptr<WritableFile> writable_file;
188 ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file, soptions_));
189 ASSERT_OK(writable_file->Append("foo"));
190 ASSERT_OK(writable_file->Append(write_data));
191 writable_file.reset();
192
193 std::unique_ptr<SequentialFile> seq_file;
194 Slice result;
195 ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file, soptions_));
196 ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
197 ASSERT_EQ(0, result.compare("foo"));
198
199 size_t read = 0;
200 std::string read_data;
201 while (read < kWriteSize) {
202 ASSERT_OK(seq_file->Read(kWriteSize - read, &result, scratch));
203 read_data.append(result.data(), result.size());
204 read += result.size();
205 }
206 ASSERT_TRUE(write_data == read_data);
207 delete[] scratch;
208 }
209
210 } // namespace ROCKSDB_NAMESPACE
211
212 int main(int argc, char** argv) {
213 ROCKSDB_NAMESPACE::port::InstallStackTraceHandler();
214 ::testing::InitGoogleTest(&argc, argv);
215 return RUN_ALL_TESTS();
216 }
217
218 #else
219 #include <stdio.h>
220
221 int main(int argc, char** argv) {
222 fprintf(stderr, "SKIPPED as EnvMirror is not supported in ROCKSDB_LITE\n");
223 return 0;
224 }
225
226 #endif // !ROCKSDB_LITE