blob: 9ce06641c611809154269b690c4252ee3807072e [file] [log] [blame]
// Copyright (c) 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <cstring>
#include <string>
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/platform_file.h"
#include "base/strings/string16.h"
#include "base/strings/string_piece.h"
#include "content/browser/indexed_db/leveldb/leveldb_comparator.h"
#include "content/browser/indexed_db/leveldb/leveldb_database.h"
#include "content/browser/indexed_db/leveldb/leveldb_iterator.h"
#include "content/browser/indexed_db/leveldb/leveldb_transaction.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace content {
namespace {
class SimpleComparator : public LevelDBComparator {
public:
virtual int Compare(const base::StringPiece& a,
const base::StringPiece& b) const OVERRIDE {
size_t len = std::min(a.size(), b.size());
return memcmp(a.begin(), b.begin(), len);
}
virtual const char* Name() const OVERRIDE { return "temp_comparator"; }
};
TEST(LevelDBDatabaseTest, CorruptionTest) {
base::ScopedTempDir temp_directory;
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const std::string key("key");
const std::string value("value");
std::string put_value;
std::string got_value;
SimpleComparator comparator;
scoped_ptr<LevelDBDatabase> leveldb;
LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
EXPECT_TRUE(leveldb);
put_value = value;
bool success = leveldb->Put(key, &put_value);
EXPECT_TRUE(success);
leveldb.Pass();
EXPECT_FALSE(leveldb);
LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
EXPECT_TRUE(leveldb);
bool found = false;
success = leveldb->Get(key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_TRUE(found);
EXPECT_EQ(value, got_value);
leveldb.Pass();
EXPECT_FALSE(leveldb);
base::FilePath file_path = temp_directory.path().AppendASCII("CURRENT");
base::PlatformFile handle = base::CreatePlatformFile(
file_path,
base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_WRITE,
NULL,
NULL);
base::TruncatePlatformFile(handle, 0);
base::ClosePlatformFile(handle);
leveldb::Status status =
LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
EXPECT_FALSE(leveldb);
EXPECT_FALSE(status.ok());
bool destroyed = LevelDBDatabase::Destroy(temp_directory.path());
EXPECT_TRUE(destroyed);
status = LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
EXPECT_TRUE(status.ok());
EXPECT_TRUE(leveldb);
success = leveldb->Get(key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_FALSE(found);
}
TEST(LevelDBDatabaseTest, Transaction) {
base::ScopedTempDir temp_directory;
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const std::string key("key");
std::string got_value;
std::string put_value;
SimpleComparator comparator;
scoped_ptr<LevelDBDatabase> leveldb;
LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
EXPECT_TRUE(leveldb);
const std::string old_value("value");
put_value = old_value;
bool success = leveldb->Put(key, &put_value);
EXPECT_TRUE(success);
scoped_refptr<LevelDBTransaction> transaction =
new LevelDBTransaction(leveldb.get());
const std::string new_value("new value");
put_value = new_value;
success = leveldb->Put(key, &put_value);
EXPECT_TRUE(success);
bool found = false;
success = transaction->Get(key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_TRUE(found);
EXPECT_EQ(comparator.Compare(got_value, old_value), 0);
found = false;
success = leveldb->Get(key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_TRUE(found);
EXPECT_EQ(comparator.Compare(got_value, new_value), 0);
const std::string added_key("added key");
const std::string added_value("added value");
put_value = added_value;
success = leveldb->Put(added_key, &put_value);
EXPECT_TRUE(success);
success = leveldb->Get(added_key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_TRUE(found);
EXPECT_EQ(comparator.Compare(got_value, added_value), 0);
success = transaction->Get(added_key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_FALSE(found);
const std::string another_key("another key");
const std::string another_value("another value");
put_value = another_value;
transaction->Put(another_key, &put_value);
success = transaction->Get(another_key, &got_value, &found);
EXPECT_TRUE(success);
EXPECT_TRUE(found);
EXPECT_EQ(comparator.Compare(got_value, another_value), 0);
}
TEST(LevelDBDatabaseTest, TransactionIterator) {
base::ScopedTempDir temp_directory;
ASSERT_TRUE(temp_directory.CreateUniqueTempDir());
const std::string key1("key1");
const std::string value1("value1");
const std::string key2("key2");
const std::string value2("value2");
std::string put_value;
SimpleComparator comparator;
bool success;
scoped_ptr<LevelDBDatabase> leveldb;
LevelDBDatabase::Open(temp_directory.path(), &comparator, &leveldb);
EXPECT_TRUE(leveldb);
put_value = value1;
success = leveldb->Put(key1, &put_value);
EXPECT_TRUE(success);
put_value = value2;
success = leveldb->Put(key2, &put_value);
EXPECT_TRUE(success);
scoped_refptr<LevelDBTransaction> transaction =
new LevelDBTransaction(leveldb.get());
success = leveldb->Remove(key2);
EXPECT_TRUE(success);
scoped_ptr<LevelDBIterator> it = transaction->CreateIterator();
it->Seek(std::string());
EXPECT_TRUE(it->IsValid());
EXPECT_EQ(comparator.Compare(it->Key(), key1), 0);
EXPECT_EQ(comparator.Compare(it->Value(), value1), 0);
it->Next();
EXPECT_TRUE(it->IsValid());
EXPECT_EQ(comparator.Compare(it->Key(), key2), 0);
EXPECT_EQ(comparator.Compare(it->Value(), value2), 0);
it->Next();
EXPECT_FALSE(it->IsValid());
}
} // namespace
} // namespace content