232 рядки
6.7 KiB

  1. // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file. See the AUTHORS file for names of contributors.
  4. #include "helpers/memenv/memenv.h"
  5. #include "db/db_impl.h"
  6. #include "leveldb/db.h"
  7. #include "leveldb/env.h"
  8. #include "util/testharness.h"
  9. #include <string>
  10. #include <vector>
  11. namespace leveldb {
  12. class MemEnvTest {
  13. public:
  14. Env* env_;
  15. MemEnvTest()
  16. : env_(NewMemEnv(Env::Default())) {
  17. }
  18. ~MemEnvTest() {
  19. delete env_;
  20. }
  21. };
  22. TEST(MemEnvTest, Basics) {
  23. uint64_t file_size;
  24. WritableFile* writable_file;
  25. std::vector<std::string> children;
  26. ASSERT_OK(env_->CreateDir("/dir"));
  27. // Check that the directory is empty.
  28. ASSERT_TRUE(!env_->FileExists("/dir/non_existent"));
  29. ASSERT_TRUE(!env_->GetFileSize("/dir/non_existent", &file_size).ok());
  30. ASSERT_OK(env_->GetChildren("/dir", &children));
  31. ASSERT_EQ(0, children.size());
  32. // Create a file.
  33. ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
  34. delete writable_file;
  35. // Check that the file exists.
  36. ASSERT_TRUE(env_->FileExists("/dir/f"));
  37. ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
  38. ASSERT_EQ(0, file_size);
  39. ASSERT_OK(env_->GetChildren("/dir", &children));
  40. ASSERT_EQ(1, children.size());
  41. ASSERT_EQ("f", children[0]);
  42. // Write to the file.
  43. ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
  44. ASSERT_OK(writable_file->Append("abc"));
  45. delete writable_file;
  46. // Check for expected size.
  47. ASSERT_OK(env_->GetFileSize("/dir/f", &file_size));
  48. ASSERT_EQ(3, file_size);
  49. // Check that renaming works.
  50. ASSERT_TRUE(!env_->RenameFile("/dir/non_existent", "/dir/g").ok());
  51. ASSERT_OK(env_->RenameFile("/dir/f", "/dir/g"));
  52. ASSERT_TRUE(!env_->FileExists("/dir/f"));
  53. ASSERT_TRUE(env_->FileExists("/dir/g"));
  54. ASSERT_OK(env_->GetFileSize("/dir/g", &file_size));
  55. ASSERT_EQ(3, file_size);
  56. // Check that opening non-existent file fails.
  57. SequentialFile* seq_file;
  58. RandomAccessFile* rand_file;
  59. ASSERT_TRUE(!env_->NewSequentialFile("/dir/non_existent", &seq_file).ok());
  60. ASSERT_TRUE(!seq_file);
  61. ASSERT_TRUE(!env_->NewRandomAccessFile("/dir/non_existent", &rand_file).ok());
  62. ASSERT_TRUE(!rand_file);
  63. // Check that deleting works.
  64. ASSERT_TRUE(!env_->DeleteFile("/dir/non_existent").ok());
  65. ASSERT_OK(env_->DeleteFile("/dir/g"));
  66. ASSERT_TRUE(!env_->FileExists("/dir/g"));
  67. ASSERT_OK(env_->GetChildren("/dir", &children));
  68. ASSERT_EQ(0, children.size());
  69. ASSERT_OK(env_->DeleteDir("/dir"));
  70. }
  71. TEST(MemEnvTest, ReadWrite) {
  72. WritableFile* writable_file;
  73. SequentialFile* seq_file;
  74. RandomAccessFile* rand_file;
  75. Slice result;
  76. char scratch[100];
  77. ASSERT_OK(env_->CreateDir("/dir"));
  78. ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
  79. ASSERT_OK(writable_file->Append("hello "));
  80. ASSERT_OK(writable_file->Append("world"));
  81. delete writable_file;
  82. // Read sequentially.
  83. ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
  84. ASSERT_OK(seq_file->Read(5, &result, scratch)); // Read "hello".
  85. ASSERT_EQ(0, result.compare("hello"));
  86. ASSERT_OK(seq_file->Skip(1));
  87. ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Read "world".
  88. ASSERT_EQ(0, result.compare("world"));
  89. ASSERT_OK(seq_file->Read(1000, &result, scratch)); // Try reading past EOF.
  90. ASSERT_EQ(0, result.size());
  91. ASSERT_OK(seq_file->Skip(100)); // Try to skip past end of file.
  92. ASSERT_OK(seq_file->Read(1000, &result, scratch));
  93. ASSERT_EQ(0, result.size());
  94. delete seq_file;
  95. // Random reads.
  96. ASSERT_OK(env_->NewRandomAccessFile("/dir/f", &rand_file));
  97. ASSERT_OK(rand_file->Read(6, 5, &result, scratch)); // Read "world".
  98. ASSERT_EQ(0, result.compare("world"));
  99. ASSERT_OK(rand_file->Read(0, 5, &result, scratch)); // Read "hello".
  100. ASSERT_EQ(0, result.compare("hello"));
  101. ASSERT_OK(rand_file->Read(10, 100, &result, scratch)); // Read "d".
  102. ASSERT_EQ(0, result.compare("d"));
  103. // Too high offset.
  104. ASSERT_TRUE(!rand_file->Read(1000, 5, &result, scratch).ok());
  105. delete rand_file;
  106. }
  107. TEST(MemEnvTest, Locks) {
  108. FileLock* lock;
  109. // These are no-ops, but we test they return success.
  110. ASSERT_OK(env_->LockFile("some file", &lock));
  111. ASSERT_OK(env_->UnlockFile(lock));
  112. }
  113. TEST(MemEnvTest, Misc) {
  114. std::string test_dir;
  115. ASSERT_OK(env_->GetTestDirectory(&test_dir));
  116. ASSERT_TRUE(!test_dir.empty());
  117. WritableFile* writable_file;
  118. ASSERT_OK(env_->NewWritableFile("/a/b", &writable_file));
  119. // These are no-ops, but we test they return success.
  120. ASSERT_OK(writable_file->Sync());
  121. ASSERT_OK(writable_file->Flush());
  122. ASSERT_OK(writable_file->Close());
  123. delete writable_file;
  124. }
  125. TEST(MemEnvTest, LargeWrite) {
  126. const size_t kWriteSize = 300 * 1024;
  127. char* scratch = new char[kWriteSize * 2];
  128. std::string write_data;
  129. for (size_t i = 0; i < kWriteSize; ++i) {
  130. write_data.append(1, static_cast<char>(i));
  131. }
  132. WritableFile* writable_file;
  133. ASSERT_OK(env_->NewWritableFile("/dir/f", &writable_file));
  134. ASSERT_OK(writable_file->Append("foo"));
  135. ASSERT_OK(writable_file->Append(write_data));
  136. delete writable_file;
  137. SequentialFile* seq_file;
  138. Slice result;
  139. ASSERT_OK(env_->NewSequentialFile("/dir/f", &seq_file));
  140. ASSERT_OK(seq_file->Read(3, &result, scratch)); // Read "foo".
  141. ASSERT_EQ(0, result.compare("foo"));
  142. size_t read = 0;
  143. std::string read_data;
  144. while (read < kWriteSize) {
  145. ASSERT_OK(seq_file->Read(kWriteSize - read, &result, scratch));
  146. read_data.append(result.data(), result.size());
  147. read += result.size();
  148. }
  149. ASSERT_TRUE(write_data == read_data);
  150. delete seq_file;
  151. delete [] scratch;
  152. }
  153. TEST(MemEnvTest, DBTest) {
  154. Options options;
  155. options.create_if_missing = true;
  156. options.env = env_;
  157. DB* db;
  158. const Slice keys[] = {Slice("aaa"), Slice("bbb"), Slice("ccc")};
  159. const Slice vals[] = {Slice("foo"), Slice("bar"), Slice("baz")};
  160. ASSERT_OK(DB::Open(options, "/dir/db", &db));
  161. for (size_t i = 0; i < 3; ++i) {
  162. ASSERT_OK(db->Put(WriteOptions(), keys[i], vals[i]));
  163. }
  164. for (size_t i = 0; i < 3; ++i) {
  165. std::string res;
  166. ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));
  167. ASSERT_TRUE(res == vals[i]);
  168. }
  169. Iterator* iterator = db->NewIterator(ReadOptions());
  170. iterator->SeekToFirst();
  171. for (size_t i = 0; i < 3; ++i) {
  172. ASSERT_TRUE(iterator->Valid());
  173. ASSERT_TRUE(keys[i] == iterator->key());
  174. ASSERT_TRUE(vals[i] == iterator->value());
  175. iterator->Next();
  176. }
  177. ASSERT_TRUE(!iterator->Valid());
  178. delete iterator;
  179. DBImpl* dbi = reinterpret_cast<DBImpl*>(db);
  180. ASSERT_OK(dbi->TEST_CompactMemTable());
  181. for (size_t i = 0; i < 3; ++i) {
  182. std::string res;
  183. ASSERT_OK(db->Get(ReadOptions(), keys[i], &res));
  184. ASSERT_TRUE(res == vals[i]);
  185. }
  186. delete db;
  187. }
  188. } // namespace leveldb
  189. int main(int argc, char** argv) {
  190. return leveldb::test::RunAllTests();
  191. }