Home | History | Annotate | Download | only in leveldb
      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