blob: 6f4352c81bd96f73001934adcf475475856dd3eb [file] [log] [blame]
/*
* Copyright 2015 Google Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "cobalt/dom/local_storage_database.h"
#include <vector>
#include "base/file_path.h"
#include "base/message_loop.h"
#include "base/path_service.h"
#include "base/stringprintf.h"
#include "base/time.h"
#include "cobalt/base/cobalt_paths.h"
#include "cobalt/storage/savegame_fake.h"
#include "cobalt/storage/storage_manager.h"
#include "sql/connection.h"
#include "sql/statement.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace cobalt {
namespace dom {
namespace {
class CallbackWaiter {
public:
CallbackWaiter() : was_called_event_(true, false) {}
virtual ~CallbackWaiter() {}
bool TimedWait() {
return was_called_event_.TimedWait(base::TimeDelta::FromSeconds(5));
}
protected:
void Signal() { was_called_event_.Signal(); }
private:
base::WaitableEvent was_called_event_;
DISALLOW_COPY_AND_ASSIGN(CallbackWaiter);
};
class FlushWaiter : public CallbackWaiter {
public:
FlushWaiter() {}
void OnFlushDone() { Signal(); }
private:
DISALLOW_COPY_AND_ASSIGN(FlushWaiter);
};
class Reader : public CallbackWaiter {
public:
Reader() {}
~Reader() {}
void OnReadAll(scoped_ptr<StorageArea::StorageMap> data) {
data_ = *data;
Signal();
}
StorageArea::StorageMap data_;
private:
DISALLOW_COPY_AND_ASSIGN(Reader);
};
std::string GetSavePath() {
FilePath test_path;
CHECK(PathService::Get(paths::DIR_COBALT_TEST_OUT, &test_path));
return test_path.Append("local_storage_database_test.bin").value();
}
class DummyUpgradeHandler : public storage::StorageManager::UpgradeHandler {
void OnUpgrade(storage::StorageManager* /*storage*/, const char* /*data*/,
int /*size*/) OVERRIDE {}
};
class LocalStorageDatabaseTest : public ::testing::Test {
protected:
LocalStorageDatabaseTest()
: message_loop_(MessageLoop::TYPE_DEFAULT),
host_("https://www.example.com") {
scoped_ptr<storage::StorageManager::UpgradeHandler> upgrade_handler(
new DummyUpgradeHandler());
storage::StorageManager::Options options;
options.savegame_options.path_override = GetSavePath();
options.savegame_options.delete_on_destruction = true;
options.savegame_options.factory = &storage::SavegameFake::Create;
storage_manager_.reset(
new storage::StorageManager(upgrade_handler.Pass(), options));
db_.reset(new LocalStorageDatabase(storage_manager_.get()));
}
~LocalStorageDatabaseTest() {
db_.reset();
storage_manager_.reset();
}
MessageLoop message_loop_;
std::string host_;
scoped_ptr<storage::StorageManager> storage_manager_;
scoped_ptr<LocalStorageDatabase> db_;
};
} // namespace
TEST_F(LocalStorageDatabaseTest, EmptyRead) {
StorageArea::StorageMap empty;
Reader reader;
db_->ReadAll(host_,
base::Bind(&Reader::OnReadAll, base::Unretained(&reader)));
message_loop_.RunUntilIdle();
EXPECT_TRUE(reader.TimedWait());
EXPECT_EQ(empty, reader.data_);
}
TEST_F(LocalStorageDatabaseTest, WritePersists) {
StorageArea::StorageMap test_vals;
test_vals["key0"] = "value0";
test_vals["key1"] = "value1";
for (StorageArea::StorageMap::const_iterator it = test_vals.begin();
it != test_vals.end(); ++it) {
db_->Write(host_, it->first, it->second);
}
FlushWaiter waiter;
db_->Flush(base::Bind(&FlushWaiter::OnFlushDone, base::Unretained(&waiter)));
EXPECT_EQ(true, waiter.TimedWait());
// Ensure a Flush persists the data.
db_.reset(new LocalStorageDatabase(storage_manager_.get()));
Reader reader;
db_->ReadAll(host_,
base::Bind(&Reader::OnReadAll, base::Unretained(&reader)));
message_loop_.RunUntilIdle();
EXPECT_TRUE(reader.TimedWait());
EXPECT_EQ(test_vals, reader.data_);
}
TEST_F(LocalStorageDatabaseTest, Delete) {
StorageArea::StorageMap test_vals;
test_vals["key0"] = "value0";
test_vals["key1"] = "value1";
for (StorageArea::StorageMap::const_iterator it = test_vals.begin();
it != test_vals.end(); ++it) {
db_->Write(host_, it->first, it->second);
}
db_->Delete(host_, "key0");
StorageArea::StorageMap expected_vals;
expected_vals["key1"] = "value1";
Reader reader;
db_->ReadAll(host_,
base::Bind(&Reader::OnReadAll, base::Unretained(&reader)));
message_loop_.RunUntilIdle();
EXPECT_TRUE(reader.TimedWait());
EXPECT_EQ(expected_vals, reader.data_);
}
TEST_F(LocalStorageDatabaseTest, Clear) {
StorageArea::StorageMap test_vals;
test_vals["key0"] = "value0";
test_vals["key1"] = "value1";
for (StorageArea::StorageMap::const_iterator it = test_vals.begin();
it != test_vals.end(); ++it) {
db_->Write(host_, it->first, it->second);
}
db_->Clear(host_);
StorageArea::StorageMap expected_vals;
Reader reader;
db_->ReadAll(host_,
base::Bind(&Reader::OnReadAll, base::Unretained(&reader)));
message_loop_.RunUntilIdle();
EXPECT_TRUE(reader.TimedWait());
EXPECT_EQ(expected_vals, reader.data_);
}
} // namespace dom
} // namespace cobalt