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