This source file includes following definitions.
- kValue2
- InjectedCommitSequencingTask
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
- TEST_F
#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/message_loop/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "base/time/time.h"
#include "content/browser/dom_storage/dom_storage_area.h"
#include "content/browser/dom_storage/dom_storage_database.h"
#include "content/browser/dom_storage/dom_storage_database_adapter.h"
#include "content/browser/dom_storage/dom_storage_task_runner.h"
#include "content/browser/dom_storage/local_storage_database_adapter.h"
#include "content/common/dom_storage/dom_storage_types.h"
#include "testing/gtest/include/gtest/gtest.h"
using base::ASCIIToUTF16;
namespace content {
class DOMStorageAreaTest : public testing::Test {
public:
DOMStorageAreaTest()
: kOrigin(GURL("http://dom_storage/")),
kKey(ASCIIToUTF16("key")),
kValue(ASCIIToUTF16("value")),
kKey2(ASCIIToUTF16("key2")),
kValue2(ASCIIToUTF16("value2")) {
}
const GURL kOrigin;
const base::string16 kKey;
const base::string16 kValue;
const base::string16 kKey2;
const base::string16 kValue2;
void InjectedCommitSequencingTask(DOMStorageArea* area) {
EXPECT_EQ(1, area->commit_batches_in_flight_);
EXPECT_FALSE(area->commit_batch_.get());
EXPECT_TRUE(area->HasUncommittedChanges());
base::NullableString16 old_value;
EXPECT_TRUE(area->SetItem(kKey2, kValue2, &old_value));
EXPECT_TRUE(area->commit_batch_.get());
EXPECT_EQ(1, area->commit_batches_in_flight_);
EXPECT_TRUE(area->HasUncommittedChanges());
}
class VerifyChangesCommittedDatabase : public DOMStorageDatabase {
public:
VerifyChangesCommittedDatabase() {}
virtual ~VerifyChangesCommittedDatabase() {
const base::string16 kKey(ASCIIToUTF16("key"));
const base::string16 kValue(ASCIIToUTF16("value"));
DOMStorageValuesMap values;
ReadAllValues(&values);
EXPECT_EQ(1u, values.size());
EXPECT_EQ(kValue, values[kKey].string());
}
};
private:
base::MessageLoop message_loop_;
};
TEST_F(DOMStorageAreaTest, DOMStorageAreaBasics) {
scoped_refptr<DOMStorageArea> area(
new DOMStorageArea(1, std::string(), kOrigin, NULL, NULL));
base::string16 old_value;
base::NullableString16 old_nullable_value;
scoped_refptr<DOMStorageArea> copy;
EXPECT_EQ(kOrigin, area->origin());
EXPECT_EQ(1, area->namespace_id());
EXPECT_EQ(0u, area->Length());
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_nullable_value));
EXPECT_TRUE(area->SetItem(kKey2, kValue2, &old_nullable_value));
EXPECT_FALSE(area->HasUncommittedChanges());
copy = area->ShallowCopy(2, std::string());
EXPECT_EQ(kOrigin, copy->origin());
EXPECT_EQ(2, copy->namespace_id());
EXPECT_EQ(area->Length(), copy->Length());
EXPECT_EQ(area->GetItem(kKey).string(), copy->GetItem(kKey).string());
EXPECT_EQ(area->Key(0).string(), copy->Key(0).string());
EXPECT_EQ(copy->map_.get(), area->map_.get());
EXPECT_TRUE(area->RemoveItem(kKey, &old_value));
EXPECT_NE(copy->map_.get(), area->map_.get());
copy = area->ShallowCopy(2, std::string());
EXPECT_EQ(copy->map_.get(), area->map_.get());
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_nullable_value));
EXPECT_NE(copy->map_.get(), area->map_.get());
copy = area->ShallowCopy(2, std::string());
EXPECT_EQ(copy->map_.get(), area->map_.get());
EXPECT_NE(0u, area->Length());
EXPECT_TRUE(area->Clear());
EXPECT_EQ(0u, area->Length());
EXPECT_NE(copy->map_.get(), area->map_.get());
area->Shutdown();
EXPECT_TRUE(area->is_shutdown_);
EXPECT_FALSE(area->map_.get());
EXPECT_EQ(0u, area->Length());
EXPECT_TRUE(area->Key(0).is_null());
EXPECT_TRUE(area->GetItem(kKey).is_null());
EXPECT_FALSE(area->SetItem(kKey, kValue, &old_nullable_value));
EXPECT_FALSE(area->RemoveItem(kKey, &old_value));
EXPECT_FALSE(area->Clear());
}
TEST_F(DOMStorageAreaTest, BackingDatabaseOpened) {
const int64 kSessionStorageNamespaceId = kLocalStorageNamespaceId + 1;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
const base::FilePath kExpectedOriginFilePath = temp_dir.path().Append(
DOMStorageArea::DatabaseFileNameFromOrigin(kOrigin));
{
scoped_refptr<DOMStorageArea> area(
new DOMStorageArea(kOrigin, base::FilePath(), NULL));
EXPECT_EQ(NULL, area->backing_.get());
EXPECT_TRUE(area->is_initial_import_done_);
EXPECT_FALSE(base::PathExists(kExpectedOriginFilePath));
}
{
scoped_refptr<DOMStorageArea> area(
new DOMStorageArea(kSessionStorageNamespaceId, std::string(), kOrigin,
NULL, NULL));
EXPECT_EQ(NULL, area->backing_.get());
EXPECT_TRUE(area->is_initial_import_done_);
base::NullableString16 old_value;
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
ASSERT_TRUE(old_value.is_null());
EXPECT_EQ(NULL, area->backing_.get());
EXPECT_FALSE(base::PathExists(kExpectedOriginFilePath));
}
{
scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
kOrigin,
temp_dir.path(),
new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
EXPECT_TRUE(area->backing_.get());
DOMStorageDatabase* database = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
EXPECT_FALSE(database->IsOpen());
EXPECT_FALSE(area->is_initial_import_done_);
area->backing_.reset(new LocalStorageDatabaseAdapter());
base::NullableString16 old_value;
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
ASSERT_TRUE(old_value.is_null());
EXPECT_TRUE(area->is_initial_import_done_);
EXPECT_TRUE(area->commit_batch_.get());
EXPECT_EQ(0, area->commit_batches_in_flight_);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(area->commit_batch_.get());
EXPECT_EQ(0, area->commit_batches_in_flight_);
database = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
EXPECT_TRUE(database->IsOpen());
EXPECT_EQ(1u, area->Length());
EXPECT_EQ(kValue, area->GetItem(kKey).string());
DOMStorageValuesMap values;
area->backing_->ReadAllValues(&values);
EXPECT_EQ(1u, values.size());
EXPECT_EQ(kValue, values[kKey].string());
}
}
TEST_F(DOMStorageAreaTest, CommitTasks) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
kOrigin,
temp_dir.path(),
new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
area->backing_.reset(new LocalStorageDatabaseAdapter());
EXPECT_FALSE(area->is_initial_import_done_);
EXPECT_EQ(0u, area->Length());
EXPECT_TRUE(area->is_initial_import_done_);
DOMStorageValuesMap values;
base::NullableString16 old_value;
EXPECT_FALSE(area->commit_batch_.get());
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
EXPECT_TRUE(area->HasUncommittedChanges());
EXPECT_TRUE(area->commit_batch_.get());
EXPECT_FALSE(area->commit_batch_->clear_all_first);
EXPECT_EQ(1u, area->commit_batch_->changed_values.size());
EXPECT_TRUE(area->SetItem(kKey2, kValue2, &old_value));
EXPECT_TRUE(area->commit_batch_.get());
EXPECT_FALSE(area->commit_batch_->clear_all_first);
EXPECT_EQ(2u, area->commit_batch_->changed_values.size());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(area->HasUncommittedChanges());
EXPECT_FALSE(area->commit_batch_.get());
EXPECT_EQ(0, area->commit_batches_in_flight_);
values.clear();
area->backing_->ReadAllValues(&values);
EXPECT_EQ(2u, values.size());
EXPECT_EQ(kValue, values[kKey].string());
EXPECT_EQ(kValue2, values[kKey2].string());
EXPECT_TRUE(area->Clear());
EXPECT_TRUE(area->commit_batch_.get());
EXPECT_TRUE(area->commit_batch_->clear_all_first);
EXPECT_TRUE(area->commit_batch_->changed_values.empty());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(area->commit_batch_.get());
EXPECT_EQ(0, area->commit_batches_in_flight_);
values.clear();
area->backing_->ReadAllValues(&values);
EXPECT_TRUE(values.empty());
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
EXPECT_TRUE(area->HasUncommittedChanges());
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&DOMStorageAreaTest::InjectedCommitSequencingTask,
base::Unretained(this),
area));
base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(area->HasOneRef());
EXPECT_FALSE(area->HasUncommittedChanges());
values.clear();
area->backing_->ReadAllValues(&values);
EXPECT_EQ(2u, values.size());
EXPECT_EQ(kValue, values[kKey].string());
EXPECT_EQ(kValue2, values[kKey2].string());
}
TEST_F(DOMStorageAreaTest, CommitChangesAtShutdown) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
kOrigin,
temp_dir.path(),
new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
static_cast<LocalStorageDatabaseAdapter*>(area->backing_.get())->db_.reset(
new VerifyChangesCommittedDatabase());
DOMStorageValuesMap values;
base::NullableString16 old_value;
EXPECT_TRUE(area->SetItem(kKey, kValue, &old_value));
EXPECT_TRUE(area->HasUncommittedChanges());
area->backing_->ReadAllValues(&values);
EXPECT_TRUE(values.empty());
area->Shutdown();
base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(area->HasOneRef());
EXPECT_FALSE(area->backing_.get());
}
TEST_F(DOMStorageAreaTest, DeleteOrigin) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
kOrigin,
temp_dir.path(),
new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
base::FilePath db_file_path = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_->file_path();
base::FilePath db_journal_file_path =
DOMStorageDatabase::GetJournalFilePath(db_file_path);
area->DeleteOrigin();
EXPECT_FALSE(base::PathExists(db_file_path));
base::NullableString16 old_value;
area->SetItem(kKey, kValue, &old_value);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(base::PathExists(db_file_path));
area->DeleteOrigin();
EXPECT_EQ(0u, area->Length());
EXPECT_FALSE(base::PathExists(db_file_path));
EXPECT_FALSE(base::PathExists(db_journal_file_path));
area->SetItem(kKey, kValue, &old_value);
EXPECT_TRUE(area->HasUncommittedChanges());
EXPECT_EQ(1u, area->Length());
area->DeleteOrigin();
EXPECT_TRUE(area->HasUncommittedChanges());
EXPECT_EQ(0u, area->Length());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(area->HasUncommittedChanges());
EXPECT_FALSE(base::PathExists(db_file_path));
area->SetItem(kKey, kValue, &old_value);
base::MessageLoop::current()->RunUntilIdle();
EXPECT_TRUE(base::PathExists(db_file_path));
area->SetItem(kKey2, kValue2, &old_value);
EXPECT_TRUE(area->HasUncommittedChanges());
EXPECT_EQ(2u, area->Length());
area->DeleteOrigin();
EXPECT_TRUE(area->HasUncommittedChanges());
EXPECT_EQ(0u, area->Length());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(area->HasUncommittedChanges());
EXPECT_TRUE(base::PathExists(db_file_path));
area->Shutdown();
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(base::PathExists(db_file_path));
}
TEST_F(DOMStorageAreaTest, PurgeMemory) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DOMStorageArea> area(new DOMStorageArea(
kOrigin,
temp_dir.path(),
new MockDOMStorageTaskRunner(base::MessageLoopProxy::current().get())));
area->backing_.reset(new LocalStorageDatabaseAdapter());
DOMStorageDatabase* original_backing =
static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
DOMStorageMap* original_map = area->map_.get();
EXPECT_FALSE(area->is_initial_import_done_);
area->PurgeMemory();
EXPECT_FALSE(area->is_initial_import_done_);
DOMStorageDatabase* new_backing = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
EXPECT_EQ(original_backing, new_backing);
EXPECT_EQ(original_map, area->map_.get());
base::NullableString16 old_value;
area->SetItem(kKey, kValue, &old_value);
EXPECT_TRUE(area->is_initial_import_done_);
EXPECT_TRUE(area->HasUncommittedChanges());
area->PurgeMemory();
EXPECT_TRUE(area->is_initial_import_done_);
EXPECT_TRUE(area->HasUncommittedChanges());
new_backing = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
EXPECT_EQ(original_backing, new_backing);
EXPECT_EQ(original_map, area->map_.get());
base::MessageLoop::current()->RunUntilIdle();
EXPECT_FALSE(area->HasUncommittedChanges());
new_backing = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
EXPECT_EQ(original_backing, new_backing);
EXPECT_EQ(original_map, area->map_.get());
area->PurgeMemory();
EXPECT_FALSE(area->is_initial_import_done_);
new_backing = static_cast<LocalStorageDatabaseAdapter*>(
area->backing_.get())->db_.get();
EXPECT_NE(original_backing, new_backing);
EXPECT_NE(original_map, area->map_.get());
}
TEST_F(DOMStorageAreaTest, DatabaseFileNames) {
struct {
const char* origin;
const char* file_name;
const char* journal_file_name;
} kCases[] = {
{ "https://www.google.com/",
"https_www.google.com_0.localstorage",
"https_www.google.com_0.localstorage-journal" },
{ "http://www.google.com:8080/",
"http_www.google.com_8080.localstorage",
"http_www.google.com_8080.localstorage-journal" },
{ "file:///",
"file__0.localstorage",
"file__0.localstorage-journal" },
};
for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kCases); ++i) {
GURL origin = GURL(kCases[i].origin).GetOrigin();
base::FilePath file_name =
base::FilePath().AppendASCII(kCases[i].file_name);
base::FilePath journal_file_name =
base::FilePath().AppendASCII(kCases[i].journal_file_name);
EXPECT_EQ(file_name,
DOMStorageArea::DatabaseFileNameFromOrigin(origin));
EXPECT_EQ(origin,
DOMStorageArea::OriginFromDatabaseFileName(file_name));
EXPECT_EQ(journal_file_name,
DOMStorageDatabase::GetJournalFilePath(file_name));
}
base::FilePath parent = base::FilePath().AppendASCII("a").AppendASCII("b");
EXPECT_EQ(
parent.AppendASCII("file-journal"),
DOMStorageDatabase::GetJournalFilePath(parent.AppendASCII("file")));
EXPECT_EQ(
base::FilePath().AppendASCII("-journal"),
DOMStorageDatabase::GetJournalFilePath(base::FilePath()));
EXPECT_EQ(
base::FilePath().AppendASCII(".extensiononly-journal"),
DOMStorageDatabase::GetJournalFilePath(
base::FilePath().AppendASCII(".extensiononly")));
}
}