Roll src/third_party/WebKit c63b89c:29324ab (svn 202546:202547)
[chromium-blink-merge.git] / third_party / leveldatabase / env_chromium_unittest.cc
blob070e893f6613c5ba27b537cdea9712fd6b1ec6a9
1 // Copyright (c) 2013 The Chromium 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.
5 #include "base/files/file.h"
6 #include "base/files/file_enumerator.h"
7 #include "base/files/file_path.h"
8 #include "base/files/file_util.h"
9 #include "base/files/scoped_temp_dir.h"
10 #include "base/lazy_instance.h"
11 #include "base/test/test_suite.h"
12 #include "testing/gtest/include/gtest/gtest.h"
13 #include "third_party/leveldatabase/env_chromium.h"
14 #include "third_party/leveldatabase/src/include/leveldb/db.h"
16 #define FPL FILE_PATH_LITERAL
18 using leveldb::DB;
19 using leveldb::Env;
20 using leveldb::Options;
21 using leveldb::ReadOptions;
22 using leveldb::Slice;
23 using leveldb::Status;
24 using leveldb::WritableFile;
25 using leveldb::WriteOptions;
26 using leveldb_env::ChromiumEnv;
27 using leveldb_env::MethodID;
29 TEST(ErrorEncoding, OnlyAMethod) {
30 const MethodID in_method = leveldb_env::kSequentialFileRead;
31 const Status s = MakeIOError("Somefile.txt", "message", in_method);
32 MethodID method;
33 base::File::Error error = base::File::FILE_ERROR_MAX;
34 EXPECT_EQ(leveldb_env::METHOD_ONLY, ParseMethodAndError(s, &method, &error));
35 EXPECT_EQ(in_method, method);
36 EXPECT_EQ(base::File::FILE_ERROR_MAX, error);
39 TEST(ErrorEncoding, FileError) {
40 const MethodID in_method = leveldb_env::kWritableFileClose;
41 const base::File::Error fe = base::File::FILE_ERROR_INVALID_OPERATION;
42 const Status s = MakeIOError("Somefile.txt", "message", in_method, fe);
43 MethodID method;
44 base::File::Error error;
45 EXPECT_EQ(leveldb_env::METHOD_AND_BFE,
46 ParseMethodAndError(s, &method, &error));
47 EXPECT_EQ(in_method, method);
48 EXPECT_EQ(fe, error);
51 TEST(ErrorEncoding, NoEncodedMessage) {
52 Status s = Status::IOError("Some message", "from leveldb itself");
53 MethodID method = leveldb_env::kRandomAccessFileRead;
54 base::File::Error error = base::File::FILE_ERROR_MAX;
55 EXPECT_EQ(leveldb_env::NONE, ParseMethodAndError(s, &method, &error));
56 EXPECT_EQ(leveldb_env::kRandomAccessFileRead, method);
57 EXPECT_EQ(base::File::FILE_ERROR_MAX, error);
60 template <typename T>
61 class ChromiumEnvMultiPlatformTests : public ::testing::Test {
62 public:
65 typedef ::testing::Types<ChromiumEnv> ChromiumEnvMultiPlatformTestsTypes;
66 TYPED_TEST_CASE(ChromiumEnvMultiPlatformTests,
67 ChromiumEnvMultiPlatformTestsTypes);
69 int CountFilesWithExtension(const base::FilePath& dir,
70 const base::FilePath::StringType& extension) {
71 int matching_files = 0;
72 base::FileEnumerator dir_reader(
73 dir, false, base::FileEnumerator::FILES);
74 for (base::FilePath fname = dir_reader.Next(); !fname.empty();
75 fname = dir_reader.Next()) {
76 if (fname.MatchesExtension(extension))
77 matching_files++;
79 return matching_files;
82 bool GetFirstLDBFile(const base::FilePath& dir, base::FilePath* ldb_file) {
83 base::FileEnumerator dir_reader(
84 dir, false, base::FileEnumerator::FILES);
85 for (base::FilePath fname = dir_reader.Next(); !fname.empty();
86 fname = dir_reader.Next()) {
87 if (fname.MatchesExtension(FPL(".ldb"))) {
88 *ldb_file = fname;
89 return true;
92 return false;
95 class BackupEnv : public ChromiumEnv {
96 public:
97 BackupEnv() : ChromiumEnv("BackupEnv", true /* backup tables */) {}
100 base::LazyInstance<BackupEnv>::Leaky backup_env = LAZY_INSTANCE_INITIALIZER;
102 TEST(ChromiumEnv, BackupTables) {
103 Options options;
104 options.create_if_missing = true;
105 options.env = backup_env.Pointer();
107 base::ScopedTempDir scoped_temp_dir;
108 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
109 base::FilePath dir = scoped_temp_dir.path();
111 DB* db;
112 Status status = DB::Open(options, dir.AsUTF8Unsafe(), &db);
113 EXPECT_TRUE(status.ok()) << status.ToString();
114 status = db->Put(WriteOptions(), "key", "value");
115 EXPECT_TRUE(status.ok()) << status.ToString();
116 Slice a = "a";
117 Slice z = "z";
118 db->CompactRange(&a, &z);
119 int ldb_files = CountFilesWithExtension(dir, FPL(".ldb"));
120 int bak_files = CountFilesWithExtension(dir, FPL(".bak"));
121 EXPECT_GT(ldb_files, 0);
122 EXPECT_EQ(ldb_files, bak_files);
123 base::FilePath ldb_file;
124 EXPECT_TRUE(GetFirstLDBFile(dir, &ldb_file));
125 delete db;
126 EXPECT_TRUE(base::DeleteFile(ldb_file, false));
127 EXPECT_EQ(ldb_files - 1, CountFilesWithExtension(dir, FPL(".ldb")));
129 // The ldb file deleted above should be restored in Open.
130 status = leveldb::DB::Open(options, dir.AsUTF8Unsafe(), &db);
131 EXPECT_TRUE(status.ok()) << status.ToString();
132 std::string value;
133 status = db->Get(ReadOptions(), "key", &value);
134 EXPECT_TRUE(status.ok()) << status.ToString();
135 EXPECT_EQ("value", value);
136 delete db;
138 // Ensure that deleting an ldb file also deletes its backup.
139 int orig_ldb_files = CountFilesWithExtension(dir, FPL(".ldb"));
140 EXPECT_GT(ldb_files, 0);
141 EXPECT_EQ(ldb_files, bak_files);
142 EXPECT_TRUE(GetFirstLDBFile(dir, &ldb_file));
143 options.env->DeleteFile(ldb_file.AsUTF8Unsafe());
144 ldb_files = CountFilesWithExtension(dir, FPL(".ldb"));
145 bak_files = CountFilesWithExtension(dir, FPL(".bak"));
146 EXPECT_EQ(orig_ldb_files - 1, ldb_files);
147 EXPECT_EQ(bak_files, ldb_files);
150 TEST(ChromiumEnv, GetChildrenEmptyDir) {
151 base::ScopedTempDir scoped_temp_dir;
152 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
153 base::FilePath dir = scoped_temp_dir.path();
155 Env* env = Env::Default();
156 std::vector<std::string> result;
157 leveldb::Status status = env->GetChildren(dir.AsUTF8Unsafe(), &result);
158 EXPECT_TRUE(status.ok());
159 EXPECT_EQ(0U, result.size());
162 TEST(ChromiumEnv, GetChildrenPriorResults) {
163 base::ScopedTempDir scoped_temp_dir;
164 ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
165 base::FilePath dir = scoped_temp_dir.path();
167 base::FilePath new_file_dir = dir.Append(FPL("tmp_file"));
168 FILE* f = fopen(new_file_dir.AsUTF8Unsafe().c_str(), "w");
169 if (f) {
170 fputs("Temp file contents", f);
171 fclose(f);
174 Env* env = Env::Default();
175 std::vector<std::string> result;
176 leveldb::Status status = env->GetChildren(dir.AsUTF8Unsafe(), &result);
177 EXPECT_TRUE(status.ok());
178 EXPECT_EQ(1U, result.size());
180 // And a second time should also return one result
181 status = env->GetChildren(dir.AsUTF8Unsafe(), &result);
182 EXPECT_TRUE(status.ok());
183 EXPECT_EQ(1U, result.size());
186 int main(int argc, char** argv) { return base::TestSuite(argc, argv).Run(); }