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. 4 5 #include <algorithm> 6 #include <cstring> 7 #include <string> 8 9 #include "base/files/file_path.h" 10 #include "base/files/scoped_temp_dir.h" 11 #include "base/platform_file.h" 12 #include "base/strings/string16.h" 13 #include "base/strings/string_piece.h" 14 #include "content/browser/indexed_db/leveldb/leveldb_comparator.h" 15 #include "content/browser/indexed_db/leveldb/leveldb_database.h" 16 #include "content/browser/indexed_db/leveldb/leveldb_iterator.h" 17 #include "content/browser/indexed_db/leveldb/leveldb_transaction.h" 18 #include "testing/gtest/include/gtest/gtest.h" 19 20 namespace content { 21 22 namespace { 23 24 class SimpleComparator : public LevelDBComparator { 25 public: 26 virtual int Compare(const base::StringPiece& a, 27 const base::StringPiece& b) const OVERRIDE { 28 size_t len = std::min(a.size(), b.size()); 29 return memcmp(a.begin(), b.begin(), len); 30 } 31 virtual const char* Name() const OVERRIDE { return "temp_comparator"; } 32 }; 33 34 TEST(LevelDBDatabaseTest, CorruptionTest) { 35 base::ScopedTempDir temp_directory; 36 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); 37 38 const std::string key("key"); 39 const std::string value("value"); 40 std::string put_value; 41 std::string got_value; 42 SimpleComparator comparator; 43 44 scoped_ptr<LevelDBDatabase> leveldb; 45 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb); 46 EXPECT_TRUE(leveldb); 47 put_value = value; 48 bool success = leveldb->Put(key, &put_value); 49 EXPECT_TRUE(success); 50 leveldb.Pass(); 51 EXPECT_FALSE(leveldb); 52 53 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb); 54 EXPECT_TRUE(leveldb); 55 bool found = false; 56 success = leveldb->Get(key, &got_value, &found); 57 EXPECT_TRUE(success); 58 EXPECT_TRUE(found); 59 EXPECT_EQ(value, got_value); 60 leveldb.Pass(); 61 EXPECT_FALSE(leveldb); 62 63 base::FilePath file_path = temp_directory.path().AppendASCII("CURRENT"); 64 base::PlatformFile handle = base::CreatePlatformFile( 65 file_path, 66 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE, 67 NULL, 68 NULL); 69 base::TruncatePlatformFile(handle, 0); 70 base::ClosePlatformFile(handle); 71 72 leveldb::Status status = 73 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb); 74 EXPECT_FALSE(leveldb); 75 EXPECT_FALSE(status.ok()); 76 77 bool destroyed = LevelDBDatabase::Destroy(temp_directory.path()); 78 EXPECT_TRUE(destroyed); 79 80 status = LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb); 81 EXPECT_TRUE(status.ok()); 82 EXPECT_TRUE(leveldb); 83 success = leveldb->Get(key, &got_value, &found); 84 EXPECT_TRUE(success); 85 EXPECT_FALSE(found); 86 } 87 88 TEST(LevelDBDatabaseTest, Transaction) { 89 base::ScopedTempDir temp_directory; 90 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); 91 92 const std::string key("key"); 93 std::string got_value; 94 std::string put_value; 95 SimpleComparator comparator; 96 97 scoped_ptr<LevelDBDatabase> leveldb; 98 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb); 99 EXPECT_TRUE(leveldb); 100 101 const std::string old_value("value"); 102 put_value = old_value; 103 bool success = leveldb->Put(key, &put_value); 104 EXPECT_TRUE(success); 105 106 scoped_refptr<LevelDBTransaction> transaction = 107 new LevelDBTransaction(leveldb.get()); 108 109 const std::string new_value("new value"); 110 put_value = new_value; 111 success = leveldb->Put(key, &put_value); 112 EXPECT_TRUE(success); 113 114 bool found = false; 115 success = transaction->Get(key, &got_value, &found); 116 EXPECT_TRUE(success); 117 EXPECT_TRUE(found); 118 EXPECT_EQ(comparator.Compare(got_value, old_value), 0); 119 120 found = false; 121 success = leveldb->Get(key, &got_value, &found); 122 EXPECT_TRUE(success); 123 EXPECT_TRUE(found); 124 EXPECT_EQ(comparator.Compare(got_value, new_value), 0); 125 126 const std::string added_key("added key"); 127 const std::string added_value("added value"); 128 put_value = added_value; 129 success = leveldb->Put(added_key, &put_value); 130 EXPECT_TRUE(success); 131 132 success = leveldb->Get(added_key, &got_value, &found); 133 EXPECT_TRUE(success); 134 EXPECT_TRUE(found); 135 EXPECT_EQ(comparator.Compare(got_value, added_value), 0); 136 137 success = transaction->Get(added_key, &got_value, &found); 138 EXPECT_TRUE(success); 139 EXPECT_FALSE(found); 140 141 const std::string another_key("another key"); 142 const std::string another_value("another value"); 143 put_value = another_value; 144 transaction->Put(another_key, &put_value); 145 146 success = transaction->Get(another_key, &got_value, &found); 147 EXPECT_TRUE(success); 148 EXPECT_TRUE(found); 149 EXPECT_EQ(comparator.Compare(got_value, another_value), 0); 150 } 151 152 TEST(LevelDBDatabaseTest, TransactionIterator) { 153 base::ScopedTempDir temp_directory; 154 ASSERT_TRUE(temp_directory.CreateUniqueTempDir()); 155 156 const std::string key1("key1"); 157 const std::string value1("value1"); 158 const std::string key2("key2"); 159 const std::string value2("value2"); 160 std::string put_value; 161 SimpleComparator comparator; 162 bool success; 163 164 scoped_ptr<LevelDBDatabase> leveldb; 165 LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb); 166 EXPECT_TRUE(leveldb); 167 168 put_value = value1; 169 success = leveldb->Put(key1, &put_value); 170 EXPECT_TRUE(success); 171 put_value = value2; 172 success = leveldb->Put(key2, &put_value); 173 EXPECT_TRUE(success); 174 175 scoped_refptr<LevelDBTransaction> transaction = 176 new LevelDBTransaction(leveldb.get()); 177 178 success = leveldb->Remove(key2); 179 EXPECT_TRUE(success); 180 181 scoped_ptr<LevelDBIterator> it = transaction->CreateIterator(); 182 183 it->Seek(std::string()); 184 185 EXPECT_TRUE(it->IsValid()); 186 EXPECT_EQ(comparator.Compare(it->Key(), key1), 0); 187 EXPECT_EQ(comparator.Compare(it->Value(), value1), 0); 188 189 it->Next(); 190 191 EXPECT_TRUE(it->IsValid()); 192 EXPECT_EQ(comparator.Compare(it->Key(), key2), 0); 193 EXPECT_EQ(comparator.Compare(it->Value(), value2), 0); 194 195 it->Next(); 196 197 EXPECT_FALSE(it->IsValid()); 198 } 199 200 } // namespace 201 202 } // namespace content 203