This source file includes following definitions.
- observe_scheduled_deletions_
- observe_scheduled_deletions_
- OnDatabaseSizeChanged
- OnDatabaseScheduledForDeletion
- DidReceiveNewNotification
- GetNotificationOriginIdentifier
- GetNotificationDatabaseName
- GetNotificationDatabaseSize
- CheckNotificationReceived
- registered_client_
- RegisterClient
- NotifyStorageAccessed
- NotifyStorageModified
- NotifyOriginInUse
- NotifyOriginNoLongerInUse
- SetUsageCacheEnabled
- GetUsageAndQuota
- SimulateQuotaManagerDestroyed
- WasAccessNotified
- WasModificationNotified
- reset
- EnsureFileOfSize
- TestDeleteOpenDatabase
- TestDatabaseTracker
- DatabaseTrackerQuotaIntegration
- DatabaseTrackerClearSessionOnlyDatabasesOnExit
- DatabaseTrackerSetForceKeepSessionState
- EmptyDatabaseNameIsValid
- HandleSqliteError
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
- TEST
#include "base/file_util.h"
#include "base/files/file.h"
#include "base/files/file_path.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/scoped_ptr.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/time/time.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/sqlite/sqlite3.h"
#include "webkit/browser/database/database_tracker.h"
#include "webkit/browser/quota/mock_special_storage_policy.h"
#include "webkit/browser/quota/quota_manager_proxy.h"
#include "webkit/common/database/database_identifier.h"
using base::ASCIIToUTF16;
namespace {
const char kOrigin1Url[] = "http://origin1";
const char kOrigin2Url[] = "http://protected_origin2";
class TestObserver : public webkit_database::DatabaseTracker::Observer {
public:
TestObserver()
: new_notification_received_(false),
observe_size_changes_(true),
observe_scheduled_deletions_(true) {
}
TestObserver(bool observe_size_changes, bool observe_scheduled_deletions)
: new_notification_received_(false),
observe_size_changes_(observe_size_changes),
observe_scheduled_deletions_(observe_scheduled_deletions) {
}
virtual ~TestObserver() {}
virtual void OnDatabaseSizeChanged(const std::string& origin_identifier,
const base::string16& database_name,
int64 database_size) OVERRIDE {
if (!observe_size_changes_)
return;
new_notification_received_ = true;
origin_identifier_ = origin_identifier;
database_name_ = database_name;
database_size_ = database_size;
}
virtual void OnDatabaseScheduledForDeletion(
const std::string& origin_identifier,
const base::string16& database_name) OVERRIDE {
if (!observe_scheduled_deletions_)
return;
new_notification_received_ = true;
origin_identifier_ = origin_identifier;
database_name_ = database_name;
}
bool DidReceiveNewNotification() {
bool temp_new_notification_received = new_notification_received_;
new_notification_received_ = false;
return temp_new_notification_received;
}
std::string GetNotificationOriginIdentifier() {
return origin_identifier_;
}
base::string16 GetNotificationDatabaseName() { return database_name_; }
int64 GetNotificationDatabaseSize() { return database_size_; }
private:
bool new_notification_received_;
bool observe_size_changes_;
bool observe_scheduled_deletions_;
std::string origin_identifier_;
base::string16 database_name_;
int64 database_size_;
};
void CheckNotificationReceived(TestObserver* observer,
const std::string& expected_origin_identifier,
const base::string16& expected_database_name,
int64 expected_database_size) {
EXPECT_TRUE(observer->DidReceiveNewNotification());
EXPECT_EQ(expected_origin_identifier,
observer->GetNotificationOriginIdentifier());
EXPECT_EQ(expected_database_name,
observer->GetNotificationDatabaseName());
EXPECT_EQ(expected_database_size,
observer->GetNotificationDatabaseSize());
}
class TestQuotaManagerProxy : public quota::QuotaManagerProxy {
public:
TestQuotaManagerProxy()
: QuotaManagerProxy(NULL, NULL),
registered_client_(NULL) {
}
virtual void RegisterClient(quota::QuotaClient* client) OVERRIDE {
EXPECT_FALSE(registered_client_);
registered_client_ = client;
}
virtual void NotifyStorageAccessed(quota::QuotaClient::ID client_id,
const GURL& origin,
quota::StorageType type) OVERRIDE {
EXPECT_EQ(quota::QuotaClient::kDatabase, client_id);
EXPECT_EQ(quota::kStorageTypeTemporary, type);
accesses_[origin] += 1;
}
virtual void NotifyStorageModified(quota::QuotaClient::ID client_id,
const GURL& origin,
quota::StorageType type,
int64 delta) OVERRIDE {
EXPECT_EQ(quota::QuotaClient::kDatabase, client_id);
EXPECT_EQ(quota::kStorageTypeTemporary, type);
modifications_[origin].first += 1;
modifications_[origin].second += delta;
}
virtual void NotifyOriginInUse(const GURL& origin) OVERRIDE {}
virtual void NotifyOriginNoLongerInUse(const GURL& origin) OVERRIDE {}
virtual void SetUsageCacheEnabled(quota::QuotaClient::ID client_id,
const GURL& origin,
quota::StorageType type,
bool enabled) OVERRIDE {}
virtual void GetUsageAndQuota(
base::SequencedTaskRunner* original_task_runner,
const GURL& origin,
quota::StorageType type,
const GetUsageAndQuotaCallback& callback) OVERRIDE {}
void SimulateQuotaManagerDestroyed() {
if (registered_client_) {
registered_client_->OnQuotaManagerDestroyed();
registered_client_ = NULL;
}
}
bool WasAccessNotified(const GURL& origin) {
return accesses_[origin] != 0;
}
bool WasModificationNotified(const GURL& origin, int64 amount) {
return modifications_[origin].first != 0 &&
modifications_[origin].second == amount;
}
void reset() {
accesses_.clear();
modifications_.clear();
}
quota::QuotaClient* registered_client_;
std::map<GURL, int> accesses_;
std::map<GURL, std::pair<int, int64> > modifications_;
protected:
virtual ~TestQuotaManagerProxy() {
EXPECT_FALSE(registered_client_);
}
};
bool EnsureFileOfSize(const base::FilePath& file_path, int64 length) {
base::File file(file_path,
base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE);
if (!file.IsValid())
return false;
return file.SetLength(length);
}
}
namespace webkit_database {
class DatabaseTracker_TestHelper_Test {
public:
static void TestDeleteOpenDatabase(bool incognito_mode) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
new quota::MockSpecialStoragePolicy;
special_storage_policy->AddProtected(GURL(kOrigin2Url));
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(),
incognito_mode,
special_storage_policy.get(),
NULL,
NULL));
int64 database_size = 0;
const std::string kOrigin1 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin2Url));
const base::string16 kDB1 = ASCIIToUTF16("db1");
const base::string16 kDB2 = ASCIIToUTF16("db2");
const base::string16 kDB3 = ASCIIToUTF16("db3");
const base::string16 kDescription = ASCIIToUTF16("database_description");
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
&database_size);
tracker->DatabaseOpened(kOrigin2, kDB3, kDescription, 0,
&database_size);
EXPECT_TRUE(base::CreateDirectory(
tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
tracker->GetOriginDirectory(kOrigin1)))));
EXPECT_TRUE(base::CreateDirectory(
tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
tracker->GetOriginDirectory(kOrigin2)))));
EXPECT_EQ(1, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1));
EXPECT_EQ(2, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2));
EXPECT_EQ(3, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin2, kDB3), "aaa", 3));
tracker->DatabaseModified(kOrigin1, kDB1);
tracker->DatabaseModified(kOrigin2, kDB2);
tracker->DatabaseModified(kOrigin2, kDB3);
TestObserver observer;
tracker->AddObserver(&observer);
net::TestCompletionCallback callback;
int result = tracker->DeleteDatabase(kOrigin1, kDB1, callback.callback());
EXPECT_EQ(net::ERR_IO_PENDING, result);
ASSERT_FALSE(callback.have_result());
EXPECT_TRUE(observer.DidReceiveNewNotification());
EXPECT_EQ(kOrigin1, observer.GetNotificationOriginIdentifier());
EXPECT_EQ(kDB1, observer.GetNotificationDatabaseName());
tracker->DatabaseClosed(kOrigin1, kDB1);
result = callback.GetResult(result);
EXPECT_EQ(net::OK, result);
EXPECT_FALSE(base::PathExists(
tracker->DatabaseDirectory().AppendASCII(kOrigin1)));
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_TRUE(base::CreateDirectory(
tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
tracker->GetOriginDirectory(kOrigin1)))));
EXPECT_EQ(1, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1));
tracker->DatabaseModified(kOrigin1, kDB1);
base::Time now = base::Time::Now();
EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin1, kDB1),
now, now));
EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB2),
now, now));
base::Time three_days_ago = now - base::TimeDelta::FromDays(3);
EXPECT_TRUE(base::TouchFile(tracker->GetFullDBFilePath(kOrigin2, kDB3),
three_days_ago, three_days_ago));
base::Time yesterday = base::Time::Now();
yesterday -= base::TimeDelta::FromDays(1);
result = tracker->DeleteDataModifiedSince(
yesterday, callback.callback());
EXPECT_EQ(net::ERR_IO_PENDING, result);
ASSERT_FALSE(callback.have_result());
EXPECT_TRUE(observer.DidReceiveNewNotification());
tracker->DatabaseClosed(kOrigin1, kDB1);
tracker->DatabaseClosed(kOrigin2, kDB2);
result = callback.GetResult(result);
EXPECT_EQ(net::OK, result);
EXPECT_FALSE(base::PathExists(
tracker->DatabaseDirectory().AppendASCII(kOrigin1)));
EXPECT_TRUE(
base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2)));
EXPECT_TRUE(
base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB3)));
tracker->DatabaseClosed(kOrigin2, kDB3);
tracker->RemoveObserver(&observer);
}
static void TestDatabaseTracker(bool incognito_mode) {
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
new quota::MockSpecialStoragePolicy;
special_storage_policy->AddProtected(GURL(kOrigin2Url));
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(),
incognito_mode,
special_storage_policy.get(),
NULL,
NULL));
TestObserver observer1;
TestObserver observer2;
tracker->AddObserver(&observer1);
tracker->AddObserver(&observer2);
int64 database_size = 0;
const std::string kOrigin1 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin2Url));
const base::string16 kDB1 = ASCIIToUTF16("db1");
const base::string16 kDB2 = ASCIIToUTF16("db2");
const base::string16 kDB3 = ASCIIToUTF16("db3");
const base::string16 kDescription = ASCIIToUTF16("database_description");
DatabaseTracker::CachedOriginInfo* origin1_info =
tracker->GetCachedOriginInfo(kOrigin1);
DatabaseTracker::CachedOriginInfo* origin2_info =
tracker->GetCachedOriginInfo(kOrigin1);
EXPECT_TRUE(origin1_info);
EXPECT_TRUE(origin2_info);
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
EXPECT_TRUE(base::CreateDirectory(
tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
tracker->GetOriginDirectory(kOrigin1)))));
EXPECT_TRUE(base::CreateDirectory(
tracker->DatabaseDirectory().Append(base::FilePath::FromUTF16Unsafe(
tracker->GetOriginDirectory(kOrigin2)))));
EXPECT_EQ(1, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin1, kDB1), "a", 1));
EXPECT_EQ(2, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin2, kDB2), "aa", 2));
EXPECT_EQ(4, base::WriteFile(
tracker->GetFullDBFilePath(kOrigin1, kDB3), "aaaa", 4));
tracker->DatabaseModified(kOrigin1, kDB1);
CheckNotificationReceived(&observer1, kOrigin1, kDB1, 1);
CheckNotificationReceived(&observer2, kOrigin1, kDB1, 1);
tracker->DatabaseModified(kOrigin2, kDB2);
CheckNotificationReceived(&observer1, kOrigin2, kDB2, 2);
CheckNotificationReceived(&observer2, kOrigin2, kDB2, 2);
tracker->DatabaseModified(kOrigin1, kDB3);
CheckNotificationReceived(&observer1, kOrigin1, kDB3, 4);
CheckNotificationReceived(&observer2, kOrigin1, kDB3, 4);
tracker->DatabaseClosed(kOrigin1, kDB1);
tracker->DatabaseClosed(kOrigin2, kDB2);
tracker->DatabaseClosed(kOrigin1, kDB3);
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_EQ(1, database_size);
tracker->DatabaseClosed(kOrigin1, kDB1);
tracker->RemoveObserver(&observer2);
tracker->CloseTrackerDatabaseAndClearCaches();
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_EQ(1, database_size);
tracker->DatabaseClosed(kOrigin1, kDB1);
tracker->RemoveObserver(&observer1);
tracker->DatabaseOpened(kOrigin1, kDB3, kDescription, 0,
&database_size);
EXPECT_FALSE(tracker->DeleteClosedDatabase(kOrigin1, kDB3));
origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
EXPECT_TRUE(origin1_info);
EXPECT_EQ(4, origin1_info->GetDatabaseSize(kDB3));
tracker->DatabaseClosed(kOrigin1, kDB3);
EXPECT_TRUE(tracker->DeleteClosedDatabase(kOrigin1, kDB3));
origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
EXPECT_TRUE(origin1_info);
EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1));
EXPECT_EQ(0, origin1_info->GetDatabaseSize(kDB3));
std::vector<OriginInfo> origins_info;
EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
EXPECT_EQ(size_t(2), origins_info.size());
EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier());
EXPECT_EQ(1, origins_info[0].TotalSize());
EXPECT_EQ(1, origins_info[0].GetDatabaseSize(kDB1));
EXPECT_EQ(0, origins_info[0].GetDatabaseSize(kDB3));
EXPECT_EQ(kOrigin2, origins_info[1].GetOriginIdentifier());
EXPECT_EQ(2, origins_info[1].TotalSize());
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_FALSE(tracker->DeleteOrigin(kOrigin1, false));
origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
EXPECT_TRUE(origin1_info);
EXPECT_EQ(1, origin1_info->GetDatabaseSize(kDB1));
tracker->DatabaseClosed(kOrigin1, kDB1);
EXPECT_TRUE(tracker->DeleteOrigin(kOrigin1, false));
origins_info.clear();
EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
EXPECT_EQ(size_t(1), origins_info.size());
EXPECT_EQ(kOrigin2, origins_info[0].GetOriginIdentifier());
origin1_info = tracker->GetCachedOriginInfo(kOrigin1);
EXPECT_TRUE(origin1_info);
EXPECT_EQ(0, origin1_info->TotalSize());
}
static void DatabaseTrackerQuotaIntegration() {
const GURL kOrigin(kOrigin1Url);
const std::string kOriginId =
webkit_database::GetIdentifierFromOrigin(kOrigin);
const base::string16 kName = ASCIIToUTF16("name");
const base::string16 kDescription = ASCIIToUTF16("description");
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<TestQuotaManagerProxy> test_quota_proxy(
new TestQuotaManagerProxy);
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(),
false ,
NULL,
test_quota_proxy.get(),
NULL));
EXPECT_TRUE(test_quota_proxy->registered_client_);
int64 database_size = 0;
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
test_quota_proxy->reset();
base::FilePath db_file(tracker->GetFullDBFilePath(kOriginId, kName));
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 10));
tracker->DatabaseModified(kOriginId, kName);
EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 10));
test_quota_proxy->reset();
EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
tracker->DatabaseModified(kOriginId, kName);
EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 90));
test_quota_proxy->reset();
tracker->DatabaseClosed(kOriginId, kName);
EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
EXPECT_EQ(net::OK, tracker->DeleteDatabase(
kOriginId, kName, net::CompletionCallback()));
EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100));
test_quota_proxy->reset();
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
test_quota_proxy->reset();
db_file = tracker->GetFullDBFilePath(kOriginId, kName);
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
tracker->DatabaseModified(kOriginId, kName);
EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100));
test_quota_proxy->reset();
EXPECT_EQ(net::ERR_IO_PENDING,
tracker->DeleteDatabase(kOriginId, kName,
net::CompletionCallback()));
EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, -100));
tracker->DatabaseClosed(kOriginId, kName);
EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, -100));
test_quota_proxy->reset();
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
EXPECT_TRUE(test_quota_proxy->WasAccessNotified(kOrigin));
test_quota_proxy->reset();
db_file = tracker->GetFullDBFilePath(kOriginId, kName);
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 100));
DatabaseConnections crashed_renderer_connections;
crashed_renderer_connections.AddConnection(kOriginId, kName);
EXPECT_FALSE(test_quota_proxy->WasModificationNotified(kOrigin, 100));
tracker->CloseDatabases(crashed_renderer_connections);
EXPECT_TRUE(test_quota_proxy->WasModificationNotified(kOrigin, 100));
crashed_renderer_connections.RemoveAllConnections();
test_quota_proxy->SimulateQuotaManagerDestroyed();
}
static void DatabaseTrackerClearSessionOnlyDatabasesOnExit() {
int64 database_size = 0;
const std::string kOrigin1 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin2Url));
const base::string16 kDB1 = ASCIIToUTF16("db1");
const base::string16 kDB2 = ASCIIToUTF16("db2");
const base::string16 kDescription = ASCIIToUTF16("database_description");
base::MessageLoop message_loop;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath origin1_db_dir;
base::FilePath origin2_db_dir;
{
scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
new quota::MockSpecialStoragePolicy;
special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(),
false,
special_storage_policy.get(),
NULL,
base::MessageLoopProxy::current().get()));
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
base::FilePath db_file;
db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 1));
db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 2));
origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();
tracker->DatabaseModified(kOrigin1, kDB1);
tracker->DatabaseModified(kOrigin2, kDB2);
tracker->DatabaseClosed(kOrigin1, kDB1);
tracker->DatabaseClosed(kOrigin2, kDB2);
tracker->Shutdown();
}
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(), false, NULL, NULL, NULL));
std::vector<OriginInfo> origins_info;
EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
EXPECT_EQ(size_t(1), origins_info.size());
EXPECT_EQ(kOrigin1, origins_info[0].GetOriginIdentifier());
EXPECT_TRUE(
base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
EXPECT_EQ(base::FilePath(), tracker->GetFullDBFilePath(kOrigin2, kDB2));
EXPECT_TRUE(base::PathExists(origin1_db_dir));
EXPECT_FALSE(base::PathExists(origin2_db_dir));
}
static void DatabaseTrackerSetForceKeepSessionState() {
int64 database_size = 0;
const std::string kOrigin1 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin1Url));
const std::string kOrigin2 =
webkit_database::GetIdentifierFromOrigin(GURL(kOrigin2Url));
const base::string16 kDB1 = ASCIIToUTF16("db1");
const base::string16 kDB2 = ASCIIToUTF16("db2");
const base::string16 kDescription = ASCIIToUTF16("database_description");
base::MessageLoop message_loop;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
base::FilePath origin1_db_dir;
base::FilePath origin2_db_dir;
{
scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
new quota::MockSpecialStoragePolicy;
special_storage_policy->AddSessionOnly(GURL(kOrigin2Url));
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(),
false,
special_storage_policy.get(),
NULL,
base::MessageLoopProxy::current().get()));
tracker->SetForceKeepSessionState();
tracker->DatabaseOpened(kOrigin1, kDB1, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
tracker->DatabaseOpened(kOrigin2, kDB2, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
base::FilePath db_file;
db_file = tracker->GetFullDBFilePath(kOrigin1, kDB1);
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 1));
db_file = tracker->GetFullDBFilePath(kOrigin2, kDB2);
EXPECT_TRUE(base::CreateDirectory(db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(db_file, 2));
origin1_db_dir = tracker->GetFullDBFilePath(kOrigin1, kDB1).DirName();
origin2_db_dir = tracker->GetFullDBFilePath(kOrigin2, kDB2).DirName();
tracker->DatabaseModified(kOrigin1, kDB1);
tracker->DatabaseModified(kOrigin2, kDB2);
tracker->DatabaseClosed(kOrigin1, kDB1);
tracker->DatabaseClosed(kOrigin2, kDB2);
tracker->Shutdown();
}
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(), false, NULL, NULL, NULL));
std::vector<OriginInfo> origins_info;
EXPECT_TRUE(tracker->GetAllOriginsInfo(&origins_info));
EXPECT_EQ(size_t(2), origins_info.size());
EXPECT_TRUE(
base::PathExists(tracker->GetFullDBFilePath(kOrigin1, kDB1)));
EXPECT_TRUE(
base::PathExists(tracker->GetFullDBFilePath(kOrigin2, kDB2)));
EXPECT_TRUE(base::PathExists(origin1_db_dir));
EXPECT_TRUE(base::PathExists(origin2_db_dir));
}
static void EmptyDatabaseNameIsValid() {
const GURL kOrigin(kOrigin1Url);
const std::string kOriginId =
webkit_database::GetIdentifierFromOrigin(kOrigin);
const base::string16 kEmptyName;
const base::string16 kDescription(ASCIIToUTF16("description"));
const base::string16 kChangedDescription(
ASCIIToUTF16("changed_description"));
const bool kUseInMemoryTrackerDatabase = true;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(), kUseInMemoryTrackerDatabase,
NULL, NULL, NULL));
std::vector<OriginInfo> infos;
EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
EXPECT_TRUE(infos.empty());
int64 database_size = -1;
tracker->DatabaseOpened(kOriginId, kEmptyName, kDescription, 0,
&database_size);
EXPECT_EQ(0, database_size);
tracker->DatabaseModified(kOriginId, kEmptyName);
EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
EXPECT_EQ(1u, infos.size());
EXPECT_EQ(kDescription, infos[0].GetDatabaseDescription(kEmptyName));
EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kEmptyName).empty());
tracker->DatabaseOpened(kOriginId, kEmptyName, kChangedDescription, 0,
&database_size);
infos.clear();
EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
EXPECT_EQ(1u, infos.size());
EXPECT_EQ(kChangedDescription, infos[0].GetDatabaseDescription(kEmptyName));
tracker->DatabaseClosed(kOriginId, kEmptyName);
tracker->DatabaseClosed(kOriginId, kEmptyName);
EXPECT_EQ(net::OK, tracker->DeleteDatabase(kOriginId, kEmptyName,
net::CompletionCallback()));
infos.clear();
EXPECT_TRUE(tracker->GetAllOriginsInfo(&infos));
EXPECT_TRUE(infos.empty());
}
static void HandleSqliteError() {
const GURL kOrigin(kOrigin1Url);
const std::string kOriginId =
webkit_database::GetIdentifierFromOrigin(kOrigin);
const base::string16 kName(ASCIIToUTF16("name"));
const base::string16 kDescription(ASCIIToUTF16("description"));
const bool kUseInMemoryTrackerDatabase = true;
base::ScopedTempDir temp_dir;
ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
scoped_refptr<DatabaseTracker> tracker(
new DatabaseTracker(temp_dir.path(), kUseInMemoryTrackerDatabase,
NULL, NULL, NULL));
TestObserver observer(false, true);
tracker->AddObserver(&observer);
tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
EXPECT_FALSE(observer.DidReceiveNewNotification());
int64 database_size = 0;
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
base::FilePath spoof_db_file = tracker->GetFullDBFilePath(kOriginId, kName);
EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
EXPECT_TRUE(base::CreateDirectory(spoof_db_file.DirName()));
EXPECT_TRUE(EnsureFileOfSize(spoof_db_file, 1));
tracker->HandleSqliteError(kOriginId, kName, SQLITE_OK);
EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
EXPECT_FALSE(observer.DidReceiveNewNotification());
tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
EXPECT_TRUE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
EXPECT_TRUE(observer.DidReceiveNewNotification());
EXPECT_TRUE(base::PathExists(spoof_db_file));
tracker->DatabaseClosed(kOriginId, kName);
EXPECT_FALSE(base::PathExists(spoof_db_file));
EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
tracker->DatabaseOpened(kOriginId, kName, kDescription, 0,
&database_size);
base::FilePath spoof_db_file2 = tracker->GetFullDBFilePath(kOriginId, kName);
EXPECT_FALSE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
EXPECT_NE(spoof_db_file, spoof_db_file2);
EXPECT_TRUE(base::CreateDirectory(spoof_db_file2.DirName()));
EXPECT_TRUE(EnsureFileOfSize(spoof_db_file2, 1));
tracker->DatabaseClosed(kOriginId, kName);
tracker->HandleSqliteError(kOriginId, kName, SQLITE_CORRUPT);
EXPECT_FALSE(tracker->IsDatabaseScheduledForDeletion(kOriginId, kName));
EXPECT_FALSE(observer.DidReceiveNewNotification());
EXPECT_TRUE(tracker->GetFullDBFilePath(kOriginId, kName).empty());
EXPECT_FALSE(base::PathExists(spoof_db_file2));
tracker->RemoveObserver(&observer);
}
};
TEST(DatabaseTrackerTest, DeleteOpenDatabase) {
DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(false);
}
TEST(DatabaseTrackerTest, DeleteOpenDatabaseIncognitoMode) {
DatabaseTracker_TestHelper_Test::TestDeleteOpenDatabase(true);
}
TEST(DatabaseTrackerTest, DatabaseTracker) {
DatabaseTracker_TestHelper_Test::TestDatabaseTracker(false);
}
TEST(DatabaseTrackerTest, DatabaseTrackerIncognitoMode) {
DatabaseTracker_TestHelper_Test::TestDatabaseTracker(true);
}
TEST(DatabaseTrackerTest, DatabaseTrackerQuotaIntegration) {
DatabaseTracker_TestHelper_Test::DatabaseTrackerQuotaIntegration();
}
TEST(DatabaseTrackerTest, DatabaseTrackerClearSessionOnlyDatabasesOnExit) {
DatabaseTracker_TestHelper_Test::
DatabaseTrackerClearSessionOnlyDatabasesOnExit();
}
TEST(DatabaseTrackerTest, DatabaseTrackerSetForceKeepSessionState) {
DatabaseTracker_TestHelper_Test::DatabaseTrackerSetForceKeepSessionState();
}
TEST(DatabaseTrackerTest, EmptyDatabaseNameIsValid) {
DatabaseTracker_TestHelper_Test::EmptyDatabaseNameIsValid();
}
TEST(DatabaseTrackerTest, HandleSqliteError) {
DatabaseTracker_TestHelper_Test::HandleSqliteError();
}
}