Commit ca5a950a authored by shaktisahu's avatar shaktisahu Committed by Commit Bot

Download Service : Added leveldb proto layer

Added DownloadStore which is a layer around a leveldb ProtoDatabase that
stores download params, scheduling params, request headers and various
metadata as protos. Callers of DownloadStore expect a list of Entry's,
hence conversion utility methods were added to convert between Entry
and protodb::Entry.

Other details:
1- Moved NoopStore to download/internal/test/
2- Replaced usage of OnceCallback with repeated Callback, since the
proto database expects repeated Callback. In order to change ProtoDatabase
to use OnceCallback, it probably requires a larger change invloving
changing the client sites of ProtoDatabase.

BUG=722705

Review-Url: https://codereview.chromium.org/2881173003
Cr-Commit-Position: refs/heads/master@{#475750}
parent e2381bcb
...@@ -21,6 +21,8 @@ static_library("internal") { ...@@ -21,6 +21,8 @@ static_library("internal") {
"download_driver.h", "download_driver.h",
"download_service_impl.cc", "download_service_impl.cc",
"download_service_impl.h", "download_service_impl.h",
"download_store.cc",
"download_store.h",
"driver_entry.cc", "driver_entry.cc",
"driver_entry.h", "driver_entry.h",
"entry.cc", "entry.cc",
...@@ -28,8 +30,8 @@ static_library("internal") { ...@@ -28,8 +30,8 @@ static_library("internal") {
"model.h", "model.h",
"model_impl.cc", "model_impl.cc",
"model_impl.h", "model_impl.h",
"noop_store.cc", "proto_conversions.cc",
"noop_store.h", "proto_conversions.h",
"scheduler/battery_listener.cc", "scheduler/battery_listener.cc",
"scheduler/battery_listener.h", "scheduler/battery_listener.h",
"scheduler/network_listener.cc", "scheduler/network_listener.cc",
...@@ -39,7 +41,9 @@ static_library("internal") { ...@@ -39,7 +41,9 @@ static_library("internal") {
deps = [ deps = [
"//base", "//base",
"//components/download/internal/proto",
"//components/download/public", "//components/download/public",
"//components/leveldb_proto",
"//net", "//net",
] ]
} }
...@@ -50,7 +54,9 @@ source_set("unit_tests") { ...@@ -50,7 +54,9 @@ source_set("unit_tests") {
visibility = [ "//components/download:unit_tests" ] visibility = [ "//components/download:unit_tests" ]
sources = [ sources = [
"download_store_unittest.cc",
"model_impl_unittest.cc", "model_impl_unittest.cc",
"proto_conversions_unittest.cc",
"scheduler/battery_listener_unittest.cc", "scheduler/battery_listener_unittest.cc",
"scheduler/network_listener_unittest.cc", "scheduler/network_listener_unittest.cc",
] ]
...@@ -58,7 +64,9 @@ source_set("unit_tests") { ...@@ -58,7 +64,9 @@ source_set("unit_tests") {
deps = [ deps = [
":internal", ":internal",
"//base/test:test_support", "//base/test:test_support",
"//components/download/internal/proto",
"//components/download/internal/test:test_support", "//components/download/internal/test:test_support",
"//components/leveldb_proto:test_support",
"//testing/gmock", "//testing/gmock",
"//testing/gtest", "//testing/gtest",
] ]
......
include_rules = [ include_rules = [
"-components/download/content", "-components/download/content",
"-content", "-content",
"+components/leveldb_proto",
"+base", "+base",
"+net", "+net",
] ]
// Copyright 2017 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 "components/download/internal/download_store.h"
#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "components/download/internal/entry.h"
#include "components/download/internal/proto/entry.pb.h"
#include "components/download/internal/proto_conversions.h"
#include "components/leveldb_proto/proto_database_impl.h"
namespace download {
namespace {
const char kDatabaseClientName[] = "DownloadService";
using KeyVector = std::vector<std::string>;
using ProtoEntryVector = std::vector<protodb::Entry>;
using KeyProtoEntryVector = std::vector<std::pair<std::string, protodb::Entry>>;
} // namespace
DownloadStore::DownloadStore(
const base::FilePath& database_dir,
std::unique_ptr<leveldb_proto::ProtoDatabase<protodb::Entry>> db)
: db_(std::move(db)),
database_dir_(database_dir),
is_initialized_(false),
weak_factory_(this) {}
DownloadStore::~DownloadStore() = default;
bool DownloadStore::IsInitialized() {
return is_initialized_;
}
void DownloadStore::Initialize(InitCallback callback) {
DCHECK(!IsInitialized());
db_->InitWithOptions(
kDatabaseClientName, leveldb_proto::Options(database_dir_),
base::BindOnce(&DownloadStore::OnDatabaseInited,
weak_factory_.GetWeakPtr(), std::move(callback)));
}
void DownloadStore::OnDatabaseInited(InitCallback callback, bool success) {
if (!success) {
std::move(callback).Run(success, base::MakeUnique<std::vector<Entry>>());
return;
}
db_->LoadEntries(base::BindOnce(&DownloadStore::OnDatabaseLoaded,
weak_factory_.GetWeakPtr(),
std::move(callback)));
}
void DownloadStore::OnDatabaseLoaded(InitCallback callback,
bool success,
std::unique_ptr<ProtoEntryVector> protos) {
if (!success) {
std::move(callback).Run(success, base::MakeUnique<std::vector<Entry>>());
return;
}
auto entries = ProtoConversions::EntryVectorFromProto(std::move(protos));
is_initialized_ = true;
std::move(callback).Run(success, std::move(entries));
}
void DownloadStore::Update(const Entry& entry, StoreCallback callback) {
DCHECK(IsInitialized());
auto entries_to_save = base::MakeUnique<KeyProtoEntryVector>();
protodb::Entry proto = ProtoConversions::EntryToProto(entry);
entries_to_save->emplace_back(entry.guid, std::move(proto));
db_->UpdateEntries(std::move(entries_to_save), base::MakeUnique<KeyVector>(),
std::move(callback));
}
void DownloadStore::Remove(const std::string& guid, StoreCallback callback) {
DCHECK(IsInitialized());
auto keys_to_remove = base::MakeUnique<KeyVector>();
keys_to_remove->push_back(guid);
db_->UpdateEntries(base::MakeUnique<KeyProtoEntryVector>(),
std::move(keys_to_remove), std::move(callback));
}
} // namespace download
// Copyright 2017 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.
#ifndef COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_STORE_H_
#define COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_STORE_H_
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "base/macros.h"
#include "base/memory/weak_ptr.h"
#include "components/download/internal/store.h"
#include "components/leveldb_proto/proto_database.h"
namespace protodb {
class Entry;
} // namespace
namespace download {
// DownloadStore provides a layer around a LevelDB proto database that persists
// the download request, scheduling params and metadata to the disk. The data is
// read during initialization and presented to the caller after converting to
// Entry entries.
class DownloadStore : public Store {
public:
DownloadStore(
const base::FilePath& database_dir,
std::unique_ptr<leveldb_proto::ProtoDatabase<protodb::Entry>> db);
~DownloadStore() override;
// Store implementation.
bool IsInitialized() override;
void Initialize(InitCallback callback) override;
void Update(const Entry& entry, StoreCallback callback) override;
void Remove(const std::string& guid, StoreCallback callback) override;
private:
void OnDatabaseInited(InitCallback callback, bool success);
void OnDatabaseLoaded(InitCallback callback,
bool success,
std::unique_ptr<std::vector<protodb::Entry>> protos);
std::unique_ptr<leveldb_proto::ProtoDatabase<protodb::Entry>> db_;
base::FilePath database_dir_;
bool is_initialized_;
base::WeakPtrFactory<DownloadStore> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(DownloadStore);
};
} // namespace download
#endif // COMPONENTS_DOWNLOAD_INTERNAL_DOWNLOAD_STORE_H_
// Copyright 2017 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 "components/download/internal/download_store.h"
#include <algorithm>
#include "base/bind.h"
#include "base/callback.h"
#include "base/guid.h"
#include "base/memory/ptr_util.h"
#include "components/download/internal/entry.h"
#include "components/download/internal/proto/entry.pb.h"
#include "components/download/internal/proto_conversions.h"
#include "components/download/internal/test/entry_utils.h"
#include "components/leveldb_proto/testing/fake_db.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
using testing::_;
namespace download {
class DownloadStoreTest : public testing::Test {
public:
DownloadStoreTest() : db_(nullptr) {}
~DownloadStoreTest() override = default;
void CreateDatabase() {
auto db = base::MakeUnique<leveldb_proto::test::FakeDB<protodb::Entry>>(
&db_entries_);
db_ = db.get();
store_.reset(new DownloadStore(
base::FilePath(FILE_PATH_LITERAL("/test/db/fakepath")), std::move(db)));
}
void InitCallback(std::vector<Entry>* loaded_entries,
bool success,
std::unique_ptr<std::vector<Entry>> entries) {
loaded_entries->swap(*entries);
}
void LoadCallback(std::vector<protodb::Entry>* loaded_entries,
bool success,
std::unique_ptr<std::vector<protodb::Entry>> entries) {
loaded_entries->swap(*entries);
}
MOCK_METHOD1(StoreCallback, void(bool));
void PrepopulateSampleEntries() {
Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
Entry item2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
db_entries_.insert(
std::make_pair(item1.guid, ProtoConversions::EntryToProto(item1)));
db_entries_.insert(
std::make_pair(item2.guid, ProtoConversions::EntryToProto(item2)));
}
protected:
std::map<std::string, protodb::Entry> db_entries_;
leveldb_proto::test::FakeDB<protodb::Entry>* db_;
std::unique_ptr<DownloadStore> store_;
DISALLOW_COPY_AND_ASSIGN(DownloadStoreTest);
};
TEST_F(DownloadStoreTest, Initialize) {
PrepopulateSampleEntries();
CreateDatabase();
ASSERT_FALSE(store_->IsInitialized());
std::vector<Entry> preloaded_entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &preloaded_entries));
db_->InitCallback(true);
db_->LoadCallback(true);
ASSERT_TRUE(store_->IsInitialized());
ASSERT_EQ(2u, preloaded_entries.size());
}
TEST_F(DownloadStoreTest, Update) {
PrepopulateSampleEntries();
CreateDatabase();
std::vector<Entry> preloaded_entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &preloaded_entries));
db_->InitCallback(true);
db_->LoadCallback(true);
ASSERT_TRUE(store_->IsInitialized());
ASSERT_EQ(2u, preloaded_entries.size());
Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
Entry item2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
EXPECT_CALL(*this, StoreCallback(true)).Times(2);
store_->Update(item1, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(true);
store_->Update(item2, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(true);
// Query the database directly and check for the entry.
auto protos = base::MakeUnique<std::vector<protodb::Entry>>();
db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback,
base::Unretained(this), protos.get()));
db_->LoadCallback(true);
ASSERT_EQ(4u, protos->size());
ASSERT_TRUE(test::CompareEntryList(
{preloaded_entries[0], preloaded_entries[1], item1, item2},
*ProtoConversions::EntryVectorFromProto(std::move(protos))));
}
TEST_F(DownloadStoreTest, Remove) {
PrepopulateSampleEntries();
CreateDatabase();
std::vector<Entry> preloaded_entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &preloaded_entries));
db_->InitCallback(true);
db_->LoadCallback(true);
ASSERT_EQ(2u, preloaded_entries.size());
// Remove the entry.
EXPECT_CALL(*this, StoreCallback(true)).Times(1);
store_->Remove(
preloaded_entries[0].guid,
base::Bind(&DownloadStoreTest::StoreCallback, base::Unretained(this)));
db_->UpdateCallback(true);
// Query the database directly and check for the entry removed.
auto protos = base::MakeUnique<std::vector<protodb::Entry>>();
db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback,
base::Unretained(this), protos.get()));
db_->LoadCallback(true);
ASSERT_EQ(1u, protos->size());
ASSERT_TRUE(test::CompareEntryList(
{preloaded_entries[1]},
*ProtoConversions::EntryVectorFromProto(std::move(protos))));
}
TEST_F(DownloadStoreTest, InitializeFailed) {
PrepopulateSampleEntries();
CreateDatabase();
std::vector<Entry> preloaded_entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &preloaded_entries));
db_->InitCallback(false);
ASSERT_FALSE(store_->IsInitialized());
ASSERT_TRUE(preloaded_entries.empty());
}
TEST_F(DownloadStoreTest, InitialLoadFailed) {
PrepopulateSampleEntries();
CreateDatabase();
std::vector<Entry> preloaded_entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &preloaded_entries));
db_->InitCallback(true);
db_->LoadCallback(false);
ASSERT_FALSE(store_->IsInitialized());
ASSERT_TRUE(preloaded_entries.empty());
}
TEST_F(DownloadStoreTest, UnsuccessfulUpdateOrRemove) {
Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
CreateDatabase();
std::vector<Entry> entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &entries));
db_->InitCallback(true);
db_->LoadCallback(true);
ASSERT_TRUE(store_->IsInitialized());
ASSERT_TRUE(entries.empty());
// Update failed.
EXPECT_CALL(*this, StoreCallback(false)).Times(1);
store_->Update(item1, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(false);
// Remove failed.
EXPECT_CALL(*this, StoreCallback(false)).Times(1);
store_->Remove(item1.guid, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(false);
}
TEST_F(DownloadStoreTest, AddThenRemove) {
CreateDatabase();
std::vector<Entry> entries;
store_->Initialize(base::Bind(&DownloadStoreTest::InitCallback,
base::Unretained(this), &entries));
db_->InitCallback(true);
db_->LoadCallback(true);
ASSERT_TRUE(entries.empty());
Entry item1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
Entry item2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
EXPECT_CALL(*this, StoreCallback(true)).Times(2);
store_->Update(item1, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(true);
store_->Update(item2, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(true);
// Query the database directly and check for the entry.
auto protos = base::MakeUnique<std::vector<protodb::Entry>>();
db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback,
base::Unretained(this), protos.get()));
db_->LoadCallback(true);
ASSERT_EQ(2u, protos->size());
// Remove the entry.
EXPECT_CALL(*this, StoreCallback(true)).Times(1);
store_->Remove(item1.guid, base::Bind(&DownloadStoreTest::StoreCallback,
base::Unretained(this)));
db_->UpdateCallback(true);
// Query the database directly and check for the entry removed.
protos->clear();
db_->LoadEntries(base::Bind(&DownloadStoreTest::LoadCallback,
base::Unretained(this), protos.get()));
db_->LoadCallback(true);
ASSERT_EQ(1u, protos->size());
ASSERT_TRUE(test::CompareEntryList(
{item2}, *ProtoConversions::EntryVectorFromProto(std::move(protos))));
}
} // namespace download
...@@ -32,11 +32,6 @@ class Model { ...@@ -32,11 +32,6 @@ class Model {
// callback. If |success| is true it can be accessed now. // callback. If |success| is true it can be accessed now.
virtual void OnInitialized(bool success) = 0; virtual void OnInitialized(bool success) = 0;
// Called asynchronously in response to a Model::Destroy call. If |success|
// is |false|, destruction of the Model and/or the underlying Store failed.
// Destruction of the Model is effectively complete after this callback.
virtual void OnDestroyed(bool success) = 0;
// Called when an Entry addition is complete. |success| determines whether // Called when an Entry addition is complete. |success| determines whether
// or not the entry has been successfully persisted to the Store. // or not the entry has been successfully persisted to the Store.
virtual void OnItemAdded(bool success, virtual void OnItemAdded(bool success,
...@@ -64,9 +59,6 @@ class Model { ...@@ -64,9 +59,6 @@ class Model {
// The Model can be used after that call. // The Model can be used after that call.
virtual void Initialize() = 0; virtual void Initialize() = 0;
// Destroys the Model. Client::OnDestroyed() will be called in response.
virtual void Destroy() = 0;
// Adds |entry| to this Model and attempts to write |entry| to the Store. // Adds |entry| to this Model and attempts to write |entry| to the Store.
// Client::OnItemAdded() will be called in response asynchronously. // Client::OnItemAdded() will be called in response asynchronously.
virtual void Add(const Entry& entry) = 0; virtual void Add(const Entry& entry) = 0;
......
...@@ -20,13 +20,8 @@ ModelImpl::~ModelImpl() = default; ...@@ -20,13 +20,8 @@ ModelImpl::~ModelImpl() = default;
void ModelImpl::Initialize() { void ModelImpl::Initialize() {
DCHECK(!store_->IsInitialized()); DCHECK(!store_->IsInitialized());
store_->Initialize(base::Bind(&ModelImpl::OnInitializedFinished, store_->Initialize(base::BindOnce(&ModelImpl::OnInitializedFinished,
weak_ptr_factory_.GetWeakPtr())); weak_ptr_factory_.GetWeakPtr()));
}
void ModelImpl::Destroy() {
store_->Destroy(base::Bind(&ModelImpl::OnDestroyFinished,
weak_ptr_factory_.GetWeakPtr()));
} }
void ModelImpl::Add(const Entry& entry) { void ModelImpl::Add(const Entry& entry) {
...@@ -35,9 +30,9 @@ void ModelImpl::Add(const Entry& entry) { ...@@ -35,9 +30,9 @@ void ModelImpl::Add(const Entry& entry) {
entries_.emplace(entry.guid, base::MakeUnique<Entry>(entry)); entries_.emplace(entry.guid, base::MakeUnique<Entry>(entry));
store_->Update(entry, base::Bind(&ModelImpl::OnAddFinished, store_->Update(entry, base::BindOnce(&ModelImpl::OnAddFinished,
weak_ptr_factory_.GetWeakPtr(), entry.client, weak_ptr_factory_.GetWeakPtr(),
entry.guid)); entry.client, entry.guid));
} }
void ModelImpl::Update(const Entry& entry) { void ModelImpl::Update(const Entry& entry) {
...@@ -45,9 +40,9 @@ void ModelImpl::Update(const Entry& entry) { ...@@ -45,9 +40,9 @@ void ModelImpl::Update(const Entry& entry) {
DCHECK(entries_.find(entry.guid) != entries_.end()); DCHECK(entries_.find(entry.guid) != entries_.end());
entries_[entry.guid] = base::MakeUnique<Entry>(entry); entries_[entry.guid] = base::MakeUnique<Entry>(entry);
store_->Update(entry, base::Bind(&ModelImpl::OnUpdateFinished, store_->Update(entry, base::BindOnce(&ModelImpl::OnUpdateFinished,
weak_ptr_factory_.GetWeakPtr(), entry.client, weak_ptr_factory_.GetWeakPtr(),
entry.guid)); entry.client, entry.guid));
} }
void ModelImpl::Remove(const std::string& guid) { void ModelImpl::Remove(const std::string& guid) {
...@@ -59,8 +54,8 @@ void ModelImpl::Remove(const std::string& guid) { ...@@ -59,8 +54,8 @@ void ModelImpl::Remove(const std::string& guid) {
DownloadClient client = it->second->client; DownloadClient client = it->second->client;
entries_.erase(it); entries_.erase(it);
store_->Remove(guid, store_->Remove(guid,
base::Bind(&ModelImpl::OnRemoveFinished, base::BindOnce(&ModelImpl::OnRemoveFinished,
weak_ptr_factory_.GetWeakPtr(), client, guid)); weak_ptr_factory_.GetWeakPtr(), client, guid));
} }
Entry* ModelImpl::Get(const std::string& guid) { Entry* ModelImpl::Get(const std::string& guid) {
...@@ -90,12 +85,6 @@ void ModelImpl::OnInitializedFinished( ...@@ -90,12 +85,6 @@ void ModelImpl::OnInitializedFinished(
client_->OnInitialized(true); client_->OnInitialized(true);
} }
void ModelImpl::OnDestroyFinished(bool success) {
store_.reset();
entries_.clear();
client_->OnDestroyed(success);
}
void ModelImpl::OnAddFinished(DownloadClient client, void ModelImpl::OnAddFinished(DownloadClient client,
const std::string& guid, const std::string& guid,
bool success) { bool success) {
......
...@@ -28,7 +28,6 @@ class ModelImpl : public Model { ...@@ -28,7 +28,6 @@ class ModelImpl : public Model {
// Model implementation. // Model implementation.
void Initialize() override; void Initialize() override;
void Destroy() override;
void Add(const Entry& entry) override; void Add(const Entry& entry) override;
void Update(const Entry& entry) override; void Update(const Entry& entry) override;
void Remove(const std::string& guid) override; void Remove(const std::string& guid) override;
...@@ -40,7 +39,6 @@ class ModelImpl : public Model { ...@@ -40,7 +39,6 @@ class ModelImpl : public Model {
void OnInitializedFinished(bool success, void OnInitializedFinished(bool success,
std::unique_ptr<std::vector<Entry>> entries); std::unique_ptr<std::vector<Entry>> entries);
void OnDestroyFinished(bool success);
void OnAddFinished(DownloadClient client, void OnAddFinished(DownloadClient client,
const std::string& guid, const std::string& guid,
bool success); bool success);
......
...@@ -52,15 +52,10 @@ class DownloadServiceModelImplTest : public testing::Test { ...@@ -52,15 +52,10 @@ class DownloadServiceModelImplTest : public testing::Test {
TEST_F(DownloadServiceModelImplTest, SuccessfulLifecycle) { TEST_F(DownloadServiceModelImplTest, SuccessfulLifecycle) {
InSequence sequence; InSequence sequence;
EXPECT_CALL(client_, OnInitialized(true)).Times(1); EXPECT_CALL(client_, OnInitialized(true)).Times(1);
EXPECT_CALL(client_, OnDestroyed(true)).Times(1);
model_->Initialize(); model_->Initialize();
EXPECT_TRUE(store_->init_called()); EXPECT_TRUE(store_->init_called());
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>()); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
model_->Destroy();
EXPECT_TRUE(store_->destroy_called());
store_->TriggerDestroy(true);
} }
TEST_F(DownloadServiceModelImplTest, SuccessfulInitWithEntries) { TEST_F(DownloadServiceModelImplTest, SuccessfulInitWithEntries) {
...@@ -75,8 +70,8 @@ TEST_F(DownloadServiceModelImplTest, SuccessfulInitWithEntries) { ...@@ -75,8 +70,8 @@ TEST_F(DownloadServiceModelImplTest, SuccessfulInitWithEntries) {
EXPECT_TRUE(store_->init_called()); EXPECT_TRUE(store_->init_called());
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries)); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
EXPECT_TRUE(test::SuperficialEntryCompare(&entry1, model_->Get(entry1.guid))); EXPECT_TRUE(test::CompareEntry(&entry1, model_->Get(entry1.guid)));
EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid))); EXPECT_TRUE(test::CompareEntry(&entry2, model_->Get(entry2.guid)));
} }
TEST_F(DownloadServiceModelImplTest, BadInit) { TEST_F(DownloadServiceModelImplTest, BadInit) {
...@@ -87,20 +82,6 @@ TEST_F(DownloadServiceModelImplTest, BadInit) { ...@@ -87,20 +82,6 @@ TEST_F(DownloadServiceModelImplTest, BadInit) {
store_->TriggerInit(false, base::MakeUnique<std::vector<Entry>>()); store_->TriggerInit(false, base::MakeUnique<std::vector<Entry>>());
} }
TEST_F(DownloadServiceModelImplTest, BadDestroy) {
InSequence sequence;
EXPECT_CALL(client_, OnInitialized(true)).Times(1);
EXPECT_CALL(client_, OnDestroyed(false)).Times(1);
model_->Initialize();
EXPECT_TRUE(store_->init_called());
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
model_->Destroy();
EXPECT_TRUE(store_->destroy_called());
store_->TriggerDestroy(false);
}
TEST_F(DownloadServiceModelImplTest, Add) { TEST_F(DownloadServiceModelImplTest, Add) {
Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); Entry entry1 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
Entry entry2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()); Entry entry2 = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
...@@ -114,15 +95,13 @@ TEST_F(DownloadServiceModelImplTest, Add) { ...@@ -114,15 +95,13 @@ TEST_F(DownloadServiceModelImplTest, Add) {
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>()); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
model_->Add(entry1); model_->Add(entry1);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry1, model_->Get(entry1.guid))); EXPECT_TRUE(test::CompareEntry(&entry1, model_->Get(entry1.guid)));
EXPECT_TRUE( EXPECT_TRUE(test::CompareEntry(&entry1, store_->LastUpdatedEntry()));
test::SuperficialEntryCompare(&entry1, store_->LastUpdatedEntry()));
store_->TriggerUpdate(true); store_->TriggerUpdate(true);
model_->Add(entry2); model_->Add(entry2);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid))); EXPECT_TRUE(test::CompareEntry(&entry2, model_->Get(entry2.guid)));
EXPECT_TRUE( EXPECT_TRUE(test::CompareEntry(&entry2, store_->LastUpdatedEntry()));
test::SuperficialEntryCompare(&entry2, store_->LastUpdatedEntry()));
store_->TriggerUpdate(false); store_->TriggerUpdate(false);
EXPECT_EQ(nullptr, model_->Get(entry2.guid)); EXPECT_EQ(nullptr, model_->Get(entry2.guid));
...@@ -150,18 +129,16 @@ TEST_F(DownloadServiceModelImplTest, Update) { ...@@ -150,18 +129,16 @@ TEST_F(DownloadServiceModelImplTest, Update) {
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries)); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
model_->Update(entry2); model_->Update(entry2);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid))); EXPECT_TRUE(test::CompareEntry(&entry2, model_->Get(entry2.guid)));
EXPECT_TRUE( EXPECT_TRUE(test::CompareEntry(&entry2, store_->LastUpdatedEntry()));
test::SuperficialEntryCompare(&entry2, store_->LastUpdatedEntry()));
store_->TriggerUpdate(true); store_->TriggerUpdate(true);
model_->Update(entry3); model_->Update(entry3);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry3, model_->Get(entry3.guid))); EXPECT_TRUE(test::CompareEntry(&entry3, model_->Get(entry3.guid)));
EXPECT_TRUE( EXPECT_TRUE(test::CompareEntry(&entry3, store_->LastUpdatedEntry()));
test::SuperficialEntryCompare(&entry3, store_->LastUpdatedEntry()));
store_->TriggerUpdate(false); store_->TriggerUpdate(false);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry3, model_->Get(entry3.guid))); EXPECT_TRUE(test::CompareEntry(&entry3, model_->Get(entry3.guid)));
} }
TEST_F(DownloadServiceModelImplTest, Remove) { TEST_F(DownloadServiceModelImplTest, Remove) {
...@@ -201,7 +178,7 @@ TEST_F(DownloadServiceModelImplTest, Get) { ...@@ -201,7 +178,7 @@ TEST_F(DownloadServiceModelImplTest, Get) {
model_->Initialize(); model_->Initialize();
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries)); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
EXPECT_TRUE(test::SuperficialEntryCompare(&entry, model_->Get(entry.guid))); EXPECT_TRUE(test::CompareEntry(&entry, model_->Get(entry.guid)));
EXPECT_EQ(nullptr, model_->Get(base::GenerateGUID())); EXPECT_EQ(nullptr, model_->Get(base::GenerateGUID()));
} }
...@@ -218,8 +195,7 @@ TEST_F(DownloadServiceModelImplTest, PeekEntries) { ...@@ -218,8 +195,7 @@ TEST_F(DownloadServiceModelImplTest, PeekEntries) {
std::vector<Entry*> expected_peek = {&entry1, &entry2}; std::vector<Entry*> expected_peek = {&entry1, &entry2};
EXPECT_TRUE( EXPECT_TRUE(test::CompareEntryList(expected_peek, model_->PeekEntries()));
test::SuperficialEntryListCompare(expected_peek, model_->PeekEntries()));
} }
TEST_F(DownloadServiceModelImplTest, TestRemoveAfterAdd) { TEST_F(DownloadServiceModelImplTest, TestRemoveAfterAdd) {
...@@ -234,7 +210,7 @@ TEST_F(DownloadServiceModelImplTest, TestRemoveAfterAdd) { ...@@ -234,7 +210,7 @@ TEST_F(DownloadServiceModelImplTest, TestRemoveAfterAdd) {
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>()); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>());
model_->Add(entry); model_->Add(entry);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry, model_->Get(entry.guid))); EXPECT_TRUE(test::CompareEntry(&entry, model_->Get(entry.guid)));
model_->Remove(entry.guid); model_->Remove(entry.guid);
EXPECT_EQ(nullptr, model_->Get(entry.guid)); EXPECT_EQ(nullptr, model_->Get(entry.guid));
...@@ -259,10 +235,10 @@ TEST_F(DownloadServiceModelImplTest, TestRemoveAfterUpdate) { ...@@ -259,10 +235,10 @@ TEST_F(DownloadServiceModelImplTest, TestRemoveAfterUpdate) {
model_->Initialize(); model_->Initialize();
store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries)); store_->TriggerInit(true, base::MakeUnique<std::vector<Entry>>(entries));
EXPECT_TRUE(test::SuperficialEntryCompare(&entry1, model_->Get(entry1.guid))); EXPECT_TRUE(test::CompareEntry(&entry1, model_->Get(entry1.guid)));
model_->Update(entry2); model_->Update(entry2);
EXPECT_TRUE(test::SuperficialEntryCompare(&entry2, model_->Get(entry2.guid))); EXPECT_TRUE(test::CompareEntry(&entry2, model_->Get(entry2.guid)));
model_->Remove(entry2.guid); model_->Remove(entry2.guid);
EXPECT_EQ(nullptr, model_->Get(entry2.guid)); EXPECT_EQ(nullptr, model_->Get(entry2.guid));
......
# Copyright 2017 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.
import("//third_party/protobuf/proto_library.gni")
proto_library("proto") {
sources = [
"entry.proto",
"request.proto",
"scheduling.proto",
]
}
// Copyright 2017 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.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package protodb;
import "request.proto";
import "scheduling.proto";
// This should stay in sync with the DownloadClient enum
// (components/download/public/clients.h).
enum DownloadClient {
INVALID = 0;
TEST = 1;
OFFLINE_PAGE_PREFETCH = 2;
BOUNDARY = 3;
}
// Stores the request params, internal state, metrics and metadata associated
// with a download request.
message Entry {
// This should stay in sync with the State enum
// (components/download/internal/entry.h).
enum State {
NEW = 0;
AVAILABLE = 1;
ACTIVE = 2;
PAUSED = 3;
COMPLETE = 4;
WATCHDOG = 5;
}
// Identification Parameters.
optional DownloadClient name_space = 1;
optional string guid = 2;
// Requested Parameters.
optional SchedulingParams scheduling_params = 3;
optional RequestParams request_params = 4;
// Internal Tracking State.
optional State state = 5;
}
// Copyright 2017 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.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package protodb;
message RequestHeader {
optional string key = 1;
optional string value = 2;
}
// Stores the HTTP request params associated with a download request.
message RequestParams {
optional string url = 1;
optional string method = 2;
repeated RequestHeader headers = 3;
}
// Copyright 2017 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.
syntax = "proto2";
option optimize_for = LITE_RUNTIME;
package protodb;
// Stores the scheduling params associated with a download request.
message SchedulingParams {
// This should stay in sync with the NetworkRequirements enum
// (components/download/public/download_params.h).
enum NetworkRequirements {
NONE = 0;
OPTIMISTIC = 1;
UNMETERED = 2;
}
// This should stay in sync with the BatteryRequirements enum
// (components/download/public/download_params.h).
enum BatteryRequirements {
BATTERY_INSENSITIVE = 0;
BATTERY_SENSITIVE = 1;
}
// This should stay in sync with the Priority enum
// (components/download/public/download_params.h).
enum Priority {
LOW = 0;
NORMAL = 1;
HIGH = 2;
UI = 3;
}
// Uses internal time representation.
optional int64 cancel_time = 2;
optional Priority priority = 3;
optional NetworkRequirements network_requirements = 4;
optional BatteryRequirements battery_requirements = 5;
}
// Copyright 2017 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 <utility>
#include "base/memory/ptr_util.h"
#include "base/time/time.h"
#include "components/download/internal/proto_conversions.h"
#include "net/http/http_request_headers.h"
namespace download {
protodb::Entry_State ProtoConversions::RequestStateToProto(Entry::State state) {
switch (state) {
case Entry::State::NEW:
return protodb::Entry_State_NEW;
case Entry::State::AVAILABLE:
return protodb::Entry_State_AVAILABLE;
case Entry::State::ACTIVE:
return protodb::Entry_State_ACTIVE;
case Entry::State::PAUSED:
return protodb::Entry_State_PAUSED;
case Entry::State::COMPLETE:
return protodb::Entry_State_COMPLETE;
case Entry::State::WATCHDOG:
return protodb::Entry_State_WATCHDOG;
}
NOTREACHED();
return protodb::Entry_State_NEW;
}
Entry::State ProtoConversions::RequestStateFromProto(
protodb::Entry_State state) {
switch (state) {
case protodb::Entry_State_NEW:
return Entry::State::NEW;
case protodb::Entry_State_AVAILABLE:
return Entry::State::AVAILABLE;
case protodb::Entry_State_ACTIVE:
return Entry::State::ACTIVE;
case protodb::Entry_State_PAUSED:
return Entry::State::PAUSED;
case protodb::Entry_State_COMPLETE:
return Entry::State::COMPLETE;
case protodb::Entry_State_WATCHDOG:
return Entry::State::WATCHDOG;
}
NOTREACHED();
return Entry::State::NEW;
}
protodb::DownloadClient ProtoConversions::DownloadClientToProto(
DownloadClient client) {
switch (client) {
case DownloadClient::INVALID:
return protodb::DownloadClient::INVALID;
case DownloadClient::TEST:
return protodb::DownloadClient::TEST;
case DownloadClient::OFFLINE_PAGE_PREFETCH:
return protodb::DownloadClient::OFFLINE_PAGE_PREFETCH;
case DownloadClient::BOUNDARY:
return protodb::DownloadClient::BOUNDARY;
}
NOTREACHED();
return protodb::DownloadClient::INVALID;
}
DownloadClient ProtoConversions::DownloadClientFromProto(
protodb::DownloadClient client) {
switch (client) {
case protodb::DownloadClient::INVALID:
return DownloadClient::INVALID;
case protodb::DownloadClient::TEST:
return DownloadClient::TEST;
case protodb::DownloadClient::OFFLINE_PAGE_PREFETCH:
return DownloadClient::OFFLINE_PAGE_PREFETCH;
case protodb::DownloadClient::BOUNDARY:
return DownloadClient::BOUNDARY;
}
NOTREACHED();
return DownloadClient::INVALID;
}
SchedulingParams::NetworkRequirements
ProtoConversions::NetworkRequirementsFromProto(
protodb::SchedulingParams_NetworkRequirements network_requirements) {
switch (network_requirements) {
case protodb::SchedulingParams_NetworkRequirements_NONE:
return SchedulingParams::NetworkRequirements::NONE;
case protodb::SchedulingParams_NetworkRequirements_OPTIMISTIC:
return SchedulingParams::NetworkRequirements::OPTIMISTIC;
case protodb::SchedulingParams_NetworkRequirements_UNMETERED:
return SchedulingParams::NetworkRequirements::UNMETERED;
}
NOTREACHED();
return SchedulingParams::NetworkRequirements::NONE;
}
protodb::SchedulingParams_NetworkRequirements
ProtoConversions::NetworkRequirementsToProto(
SchedulingParams::NetworkRequirements network_requirements) {
switch (network_requirements) {
case SchedulingParams::NetworkRequirements::NONE:
return protodb::SchedulingParams_NetworkRequirements_NONE;
case SchedulingParams::NetworkRequirements::OPTIMISTIC:
return protodb::SchedulingParams_NetworkRequirements_OPTIMISTIC;
case SchedulingParams::NetworkRequirements::UNMETERED:
return protodb::SchedulingParams_NetworkRequirements_UNMETERED;
}
NOTREACHED();
return protodb::SchedulingParams_NetworkRequirements_NONE;
}
SchedulingParams::BatteryRequirements
ProtoConversions::BatteryRequirementsFromProto(
protodb::SchedulingParams_BatteryRequirements battery_requirements) {
switch (battery_requirements) {
case protodb::SchedulingParams_BatteryRequirements_BATTERY_INSENSITIVE:
return SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE;
case protodb::SchedulingParams_BatteryRequirements_BATTERY_SENSITIVE:
return SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE;
}
NOTREACHED();
return SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE;
}
protodb::SchedulingParams_BatteryRequirements
ProtoConversions::BatteryRequirementsToProto(
SchedulingParams::BatteryRequirements battery_requirements) {
switch (battery_requirements) {
case SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE:
return protodb::SchedulingParams_BatteryRequirements_BATTERY_INSENSITIVE;
case SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE:
return protodb::SchedulingParams_BatteryRequirements_BATTERY_SENSITIVE;
}
NOTREACHED();
return protodb::SchedulingParams_BatteryRequirements_BATTERY_INSENSITIVE;
}
SchedulingParams::Priority ProtoConversions::SchedulingPriorityFromProto(
protodb::SchedulingParams_Priority priority) {
switch (priority) {
case protodb::SchedulingParams_Priority_LOW:
return SchedulingParams::Priority::LOW;
case protodb::SchedulingParams_Priority_NORMAL:
return SchedulingParams::Priority::NORMAL;
case protodb::SchedulingParams_Priority_HIGH:
return SchedulingParams::Priority::HIGH;
case protodb::SchedulingParams_Priority_UI:
return SchedulingParams::Priority::UI;
}
NOTREACHED();
return SchedulingParams::Priority::LOW;
}
protodb::SchedulingParams_Priority ProtoConversions::SchedulingPriorityToProto(
SchedulingParams::Priority priority) {
switch (priority) {
case SchedulingParams::Priority::LOW:
return protodb::SchedulingParams_Priority_LOW;
case SchedulingParams::Priority::NORMAL:
return protodb::SchedulingParams_Priority_NORMAL;
case SchedulingParams::Priority::HIGH:
return protodb::SchedulingParams_Priority_HIGH;
case SchedulingParams::Priority::UI:
return protodb::SchedulingParams_Priority_UI;
}
NOTREACHED();
return protodb::SchedulingParams_Priority_LOW;
}
SchedulingParams ProtoConversions::SchedulingParamsFromProto(
const protodb::SchedulingParams& proto) {
SchedulingParams scheduling_params;
scheduling_params.cancel_time =
base::Time::FromInternalValue(proto.cancel_time());
scheduling_params.priority = SchedulingPriorityFromProto(proto.priority());
scheduling_params.network_requirements =
NetworkRequirementsFromProto(proto.network_requirements());
scheduling_params.battery_requirements =
BatteryRequirementsFromProto(proto.battery_requirements());
return scheduling_params;
}
void ProtoConversions::SchedulingParamsToProto(
const SchedulingParams& scheduling_params,
protodb::SchedulingParams* proto) {
proto->set_cancel_time(scheduling_params.cancel_time.ToInternalValue());
proto->set_priority(SchedulingPriorityToProto(scheduling_params.priority));
proto->set_network_requirements(
NetworkRequirementsToProto(scheduling_params.network_requirements));
proto->set_battery_requirements(
BatteryRequirementsToProto(scheduling_params.battery_requirements));
}
RequestParams ProtoConversions::RequestParamsFromProto(
const protodb::RequestParams& proto) {
RequestParams request_params;
request_params.url = GURL(proto.url());
request_params.method = proto.method();
for (int i = 0; i < proto.headers_size(); i++) {
protodb::RequestHeader header = proto.headers(i);
request_params.request_headers.SetHeader(header.key(), header.value());
}
return request_params;
}
void ProtoConversions::RequestParamsToProto(const RequestParams& request_params,
protodb::RequestParams* proto) {
proto->set_url(request_params.url.spec());
proto->set_method(request_params.method);
int i = 0;
net::HttpRequestHeaders::Iterator iter(request_params.request_headers);
while (iter.GetNext()) {
protodb::RequestHeader* header = proto->add_headers();
header->set_key(iter.name());
header->set_value(iter.value());
i++;
}
}
Entry ProtoConversions::EntryFromProto(const protodb::Entry& proto) {
Entry entry;
entry.guid = proto.guid();
entry.client = DownloadClientFromProto(proto.name_space());
entry.scheduling_params =
SchedulingParamsFromProto(proto.scheduling_params());
entry.request_params = RequestParamsFromProto(proto.request_params());
entry.state = RequestStateFromProto(proto.state());
return entry;
}
protodb::Entry ProtoConversions::EntryToProto(const Entry& entry) {
protodb::Entry proto;
proto.set_guid(entry.guid);
proto.set_name_space(DownloadClientToProto(entry.client));
SchedulingParamsToProto(entry.scheduling_params,
proto.mutable_scheduling_params());
RequestParamsToProto(entry.request_params, proto.mutable_request_params());
proto.set_state(RequestStateToProto(entry.state));
return proto;
}
std::unique_ptr<std::vector<Entry>> ProtoConversions::EntryVectorFromProto(
std::unique_ptr<std::vector<protodb::Entry>> protos) {
auto entries = base::MakeUnique<std::vector<Entry>>();
for (auto& proto : *protos) {
entries->push_back(EntryFromProto(proto));
}
return entries;
}
std::unique_ptr<std::vector<protodb::Entry>>
ProtoConversions::EntryVectorToProto(
std::unique_ptr<std::vector<Entry>> entries) {
auto protos = base::MakeUnique<std::vector<protodb::Entry>>();
for (auto& entry : *entries) {
protos->push_back(EntryToProto(entry));
}
return protos;
}
} // namespace download
// Copyright 2017 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.
#ifndef COMPONENTS_DOWNLOAD_INTERNAL_PROTO_CONVERSIONS_H_
#define COMPONENTS_DOWNLOAD_INTERNAL_PROTO_CONVERSIONS_H_
#include "components/download/internal/entry.h"
#include "components/download/internal/proto/entry.pb.h"
#include "components/download/internal/proto/request.pb.h"
#include "components/download/internal/proto/scheduling.pb.h"
namespace download {
class ProtoConversions {
public:
static Entry EntryFromProto(const protodb::Entry& proto);
static protodb::Entry EntryToProto(const Entry& entry);
static std::unique_ptr<std::vector<Entry>> EntryVectorFromProto(
std::unique_ptr<std::vector<protodb::Entry>> proto);
static std::unique_ptr<std::vector<protodb::Entry>> EntryVectorToProto(
std::unique_ptr<std::vector<Entry>> entries);
protected:
static protodb::Entry_State RequestStateToProto(Entry::State state);
static Entry::State RequestStateFromProto(protodb::Entry_State state);
static protodb::DownloadClient DownloadClientToProto(DownloadClient client);
static DownloadClient DownloadClientFromProto(protodb::DownloadClient client);
static SchedulingParams::NetworkRequirements NetworkRequirementsFromProto(
protodb::SchedulingParams_NetworkRequirements network_requirements);
static protodb::SchedulingParams_NetworkRequirements
NetworkRequirementsToProto(
SchedulingParams::NetworkRequirements network_requirements);
static SchedulingParams::BatteryRequirements BatteryRequirementsFromProto(
protodb::SchedulingParams_BatteryRequirements battery_requirements);
static protodb::SchedulingParams_BatteryRequirements
BatteryRequirementsToProto(
SchedulingParams::BatteryRequirements battery_requirements);
static SchedulingParams::Priority SchedulingPriorityFromProto(
protodb::SchedulingParams_Priority priority);
static protodb::SchedulingParams_Priority SchedulingPriorityToProto(
SchedulingParams::Priority priority);
static SchedulingParams SchedulingParamsFromProto(
const protodb::SchedulingParams& proto);
static void SchedulingParamsToProto(const SchedulingParams& scheduling_params,
protodb::SchedulingParams* proto);
static RequestParams RequestParamsFromProto(
const protodb::RequestParams& proto);
static void RequestParamsToProto(const RequestParams& request_params,
protodb::RequestParams* proto);
};
} // namespace download
#endif // COMPONENTS_DOWNLOAD_INTERNAL_PROTO_CONVERSIONS_H_
// Copyright 2017 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 <utility>
#include "base/guid.h"
#include "base/memory/ptr_util.h"
#include "components/download/internal/entry.h"
#include "components/download/internal/proto_conversions.h"
#include "components/download/internal/test/entry_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
std::string TEST_URL = "https://google.com";
} // namespace
namespace download {
class ProtoConversionsTest : public testing::Test, public ProtoConversions {
public:
~ProtoConversionsTest() override {}
};
TEST_F(ProtoConversionsTest, StateConversion) {
Entry::State states[] = {Entry::State::NEW, Entry::State::AVAILABLE,
Entry::State::ACTIVE, Entry::State::PAUSED,
Entry::State::COMPLETE, Entry::State::WATCHDOG};
for (auto state : states) {
ASSERT_EQ(state, RequestStateFromProto(RequestStateToProto(state)));
}
}
TEST_F(ProtoConversionsTest, DownloadClientConversion) {
DownloadClient clients[] = {DownloadClient::INVALID, DownloadClient::TEST,
DownloadClient::OFFLINE_PAGE_PREFETCH,
DownloadClient::BOUNDARY};
for (auto client : clients) {
ASSERT_EQ(client, DownloadClientFromProto(DownloadClientToProto(client)));
}
}
TEST_F(ProtoConversionsTest, NetworkRequirementsConversion) {
SchedulingParams::NetworkRequirements values[] = {
SchedulingParams::NetworkRequirements::NONE,
SchedulingParams::NetworkRequirements::OPTIMISTIC,
SchedulingParams::NetworkRequirements::UNMETERED};
for (auto value : values) {
ASSERT_EQ(value,
NetworkRequirementsFromProto(NetworkRequirementsToProto(value)));
}
}
TEST_F(ProtoConversionsTest, BatteryRequirementsConversion) {
SchedulingParams::BatteryRequirements values[] = {
SchedulingParams::BatteryRequirements::BATTERY_INSENSITIVE,
SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE};
for (auto value : values) {
ASSERT_EQ(value,
BatteryRequirementsFromProto(BatteryRequirementsToProto(value)));
}
}
TEST_F(ProtoConversionsTest, SchedulingPriorityConversion) {
SchedulingParams::Priority values[] = {
SchedulingParams::Priority::LOW, SchedulingParams::Priority::NORMAL,
SchedulingParams::Priority::HIGH, SchedulingParams::Priority::UI,
SchedulingParams::Priority::DEFAULT};
for (auto value : values) {
ASSERT_EQ(value,
SchedulingPriorityFromProto(SchedulingPriorityToProto(value)));
}
}
TEST_F(ProtoConversionsTest, SchedulingParamsConversion) {
SchedulingParams expected;
expected.cancel_time = base::Time::Now();
expected.priority = SchedulingParams::Priority::DEFAULT;
expected.network_requirements =
SchedulingParams::NetworkRequirements::OPTIMISTIC;
expected.battery_requirements =
SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE;
protodb::SchedulingParams proto;
SchedulingParamsToProto(expected, &proto);
SchedulingParams actual = SchedulingParamsFromProto(proto);
EXPECT_EQ(expected.cancel_time, actual.cancel_time);
EXPECT_EQ(SchedulingParams::Priority::DEFAULT, actual.priority);
EXPECT_EQ(SchedulingParams::NetworkRequirements::OPTIMISTIC,
actual.network_requirements);
EXPECT_EQ(SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE,
actual.battery_requirements);
}
TEST_F(ProtoConversionsTest, RequestParamsWithHeadersConversion) {
RequestParams expected;
expected.url = GURL(TEST_URL);
expected.method = "GET";
expected.request_headers.SetHeader("key1", "value1");
expected.request_headers.SetHeader("key2", "value2");
protodb::RequestParams proto;
RequestParamsToProto(expected, &proto);
RequestParams actual = RequestParamsFromProto(proto);
EXPECT_EQ(expected.url, actual.url);
EXPECT_EQ(expected.method, actual.method);
std::string out;
actual.request_headers.GetHeader("key1", &out);
EXPECT_EQ("value1", out);
actual.request_headers.GetHeader("key2", &out);
EXPECT_EQ("value2", out);
EXPECT_EQ(expected.request_headers.ToString(),
actual.request_headers.ToString());
}
TEST_F(ProtoConversionsTest, EntryConversion) {
Entry expected = test::BuildEntry(DownloadClient::TEST, base::GenerateGUID());
Entry actual = EntryFromProto(EntryToProto(expected));
EXPECT_TRUE(test::CompareEntry(&expected, &actual));
expected = test::BuildEntry(
DownloadClient::TEST, base::GenerateGUID(), base::Time::Now(),
SchedulingParams::NetworkRequirements::OPTIMISTIC,
SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE,
SchedulingParams::Priority::HIGH, GURL(TEST_URL), "GET",
Entry::State::ACTIVE);
actual = EntryFromProto(EntryToProto(expected));
EXPECT_TRUE(test::CompareEntry(&expected, &actual));
}
TEST_F(ProtoConversionsTest, EntryVectorConversion) {
std::vector<Entry> expected;
expected.push_back(
test::BuildEntry(DownloadClient::TEST, base::GenerateGUID()));
expected.push_back(test::BuildEntry(DownloadClient::OFFLINE_PAGE_PREFETCH,
base::GenerateGUID()));
expected.push_back(test::BuildEntry(
DownloadClient::TEST, base::GenerateGUID(), base::Time::Now(),
SchedulingParams::NetworkRequirements::OPTIMISTIC,
SchedulingParams::BatteryRequirements::BATTERY_SENSITIVE,
SchedulingParams::Priority::HIGH, GURL(TEST_URL), "GET",
Entry::State::ACTIVE));
auto actual = EntryVectorFromProto(
EntryVectorToProto(base::MakeUnique<std::vector<Entry>>(expected)));
EXPECT_TRUE(test::CompareEntryList(expected, *actual));
}
} // namespace download
...@@ -10,8 +10,6 @@ ...@@ -10,8 +10,6 @@
#include <vector> #include <vector>
#include "base/callback_forward.h" #include "base/callback_forward.h"
#include "base/memory/ref_counted.h"
#include "base/sequenced_task_runner.h"
namespace download { namespace download {
...@@ -36,10 +34,6 @@ class Store { ...@@ -36,10 +34,6 @@ class Store {
// Store. // Store.
virtual void Initialize(InitCallback callback) = 0; virtual void Initialize(InitCallback callback) = 0;
// Destroyes the store and asynchronously returns whether or not that
// destruction was successful.
virtual void Destroy(StoreCallback callback) = 0;
// Adds or updates |entry| in this Store asynchronously and returns whether or // Adds or updates |entry| in this Store asynchronously and returns whether or
// not that was successful. // not that was successful.
virtual void Update(const Entry& entry, StoreCallback callback) = 0; virtual void Update(const Entry& entry, StoreCallback callback) = 0;
......
...@@ -12,6 +12,8 @@ source_set("test_support") { ...@@ -12,6 +12,8 @@ source_set("test_support") {
"entry_utils.h", "entry_utils.h",
"mock_model_client.cc", "mock_model_client.cc",
"mock_model_client.h", "mock_model_client.h",
"noop_store.cc",
"noop_store.h",
"test_download_driver.cc", "test_download_driver.cc",
"test_download_driver.h", "test_download_driver.h",
"test_store.cc", "test_store.cc",
......
...@@ -9,19 +9,41 @@ ...@@ -9,19 +9,41 @@
namespace download { namespace download {
namespace test { namespace test {
bool SuperficialEntryCompare(const Entry* const& expected, bool CompareEntry(const Entry* const& expected, const Entry* const& actual) {
const Entry* const& actual) {
if (expected == nullptr || actual == nullptr) if (expected == nullptr || actual == nullptr)
return expected == actual; return expected == actual;
// TODO(shaktisahu): Add operator== in Entry.
return expected->client == actual->client && expected->guid == actual->guid && return expected->client == actual->client && expected->guid == actual->guid &&
expected->scheduling_params.cancel_time ==
actual->scheduling_params.cancel_time &&
expected->scheduling_params.network_requirements ==
actual->scheduling_params.network_requirements &&
expected->scheduling_params.battery_requirements ==
actual->scheduling_params.battery_requirements &&
expected->scheduling_params.priority ==
actual->scheduling_params.priority &&
expected->request_params.url == actual->request_params.url &&
expected->request_params.method == actual->request_params.method &&
expected->request_params.request_headers.ToString() ==
actual->request_params.request_headers.ToString() &&
expected->state == actual->state; expected->state == actual->state;
} }
bool SuperficialEntryListCompare(const std::vector<Entry*>& expected, bool CompareEntryList(const std::vector<Entry*>& expected,
const std::vector<Entry*>& actual) { const std::vector<Entry*>& actual) {
return std::is_permutation(actual.cbegin(), actual.cend(), expected.cbegin(), return std::is_permutation(actual.cbegin(), actual.cend(), expected.cbegin(),
SuperficialEntryCompare); CompareEntry);
}
bool EntryComparison(const Entry& expected, const Entry& actual) {
return CompareEntry(&expected, &actual);
}
bool CompareEntryList(const std::vector<Entry>& list1,
const std::vector<Entry>& list2) {
return std::is_permutation(list1.begin(), list1.end(), list2.begin(),
EntryComparison);
} }
Entry BuildEntry(DownloadClient client, const std::string& guid) { Entry BuildEntry(DownloadClient client, const std::string& guid) {
...@@ -31,5 +53,25 @@ Entry BuildEntry(DownloadClient client, const std::string& guid) { ...@@ -31,5 +53,25 @@ Entry BuildEntry(DownloadClient client, const std::string& guid) {
return entry; return entry;
} }
Entry BuildEntry(DownloadClient client,
const std::string& guid,
base::Time cancel_time,
SchedulingParams::NetworkRequirements network_requirements,
SchedulingParams::BatteryRequirements battery_requirements,
SchedulingParams::Priority priority,
const GURL& url,
const std::string& request_method,
Entry::State state) {
Entry entry = BuildEntry(client, guid);
entry.scheduling_params.cancel_time = cancel_time;
entry.scheduling_params.network_requirements = network_requirements;
entry.scheduling_params.battery_requirements = battery_requirements;
entry.scheduling_params.priority = priority;
entry.request_params.url = url;
entry.request_params.method = request_method;
entry.state = state;
return entry;
}
} // namespace test } // namespace test
} // namespace download } // namespace download
...@@ -13,14 +13,26 @@ ...@@ -13,14 +13,26 @@
namespace download { namespace download {
namespace test { namespace test {
bool SuperficialEntryCompare(const Entry* const& expected, bool CompareEntry(const Entry* const& expected, const Entry* const& actual);
const Entry* const& actual);
bool SuperficialEntryListCompare(const std::vector<Entry*>& a, bool CompareEntryList(const std::vector<Entry*>& a,
const std::vector<Entry*>& b); const std::vector<Entry*>& b);
bool CompareEntryList(const std::vector<Entry>& list1,
const std::vector<Entry>& list2);
Entry BuildEntry(DownloadClient client, const std::string& guid); Entry BuildEntry(DownloadClient client, const std::string& guid);
Entry BuildEntry(DownloadClient client,
const std::string& guid,
base::Time cancel_time,
SchedulingParams::NetworkRequirements network_requirements,
SchedulingParams::BatteryRequirements battery_requirements,
SchedulingParams::Priority priority,
const GURL& url,
const std::string& request_method,
Entry::State state);
} // namespace test } // namespace test
} // namespace download } // namespace download
......
...@@ -20,7 +20,6 @@ class MockModelClient : public Model::Client { ...@@ -20,7 +20,6 @@ class MockModelClient : public Model::Client {
// Model::Client implementation. // Model::Client implementation.
MOCK_METHOD1(OnInitialized, void(bool)); MOCK_METHOD1(OnInitialized, void(bool));
MOCK_METHOD1(OnDestroyed, void(bool));
MOCK_METHOD3(OnItemAdded, void(bool, DownloadClient, const std::string&)); MOCK_METHOD3(OnItemAdded, void(bool, DownloadClient, const std::string&));
MOCK_METHOD3(OnItemUpdated, void(bool, DownloadClient, const std::string&)); MOCK_METHOD3(OnItemUpdated, void(bool, DownloadClient, const std::string&));
MOCK_METHOD3(OnItemRemoved, void(bool, DownloadClient, const std::string&)); MOCK_METHOD3(OnItemRemoved, void(bool, DownloadClient, const std::string&));
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#include "components/download/internal/noop_store.h" #include "components/download/internal/test/noop_store.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/threading/thread_task_runner_handle.h" #include "base/threading/thread_task_runner_handle.h"
...@@ -27,11 +27,6 @@ void NoopStore::Initialize(InitCallback callback) { ...@@ -27,11 +27,6 @@ void NoopStore::Initialize(InitCallback callback) {
std::move(callback))); std::move(callback)));
} }
void NoopStore::Destroy(StoreCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), true /** success */));
}
void NoopStore::Update(const Entry& entry, StoreCallback callback) { void NoopStore::Update(const Entry& entry, StoreCallback callback) {
base::ThreadTaskRunnerHandle::Get()->PostTask( base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::BindOnce(std::move(callback), true /** success */)); FROM_HERE, base::BindOnce(std::move(callback), true /** success */));
......
...@@ -2,8 +2,8 @@ ...@@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
#ifndef COMPONENTS_DOWNLOAD_INTERNAL_NOOP_STORE_H_ #ifndef COMPONENTS_DOWNLOAD_INTERNAL_TEST_NOOP_STORE_H_
#define COMPONENTS_DOWNLOAD_INTERNAL_NOOP_STORE_H_ #define COMPONENTS_DOWNLOAD_INTERNAL_TEST_NOOP_STORE_H_
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
...@@ -25,7 +25,6 @@ class NoopStore : public Store { ...@@ -25,7 +25,6 @@ class NoopStore : public Store {
// Store implementation. // Store implementation.
bool IsInitialized() override; bool IsInitialized() override;
void Initialize(InitCallback callback) override; void Initialize(InitCallback callback) override;
void Destroy(StoreCallback callback) override;
void Update(const Entry& entry, StoreCallback callback) override; void Update(const Entry& entry, StoreCallback callback) override;
void Remove(const std::string& guid, StoreCallback callback) override; void Remove(const std::string& guid, StoreCallback callback) override;
...@@ -43,4 +42,4 @@ class NoopStore : public Store { ...@@ -43,4 +42,4 @@ class NoopStore : public Store {
} // namespace download } // namespace download
#endif // COMPONENTS_DOWNLOAD_INTERNAL_NOOP_STORE_H_ #endif // COMPONENTS_DOWNLOAD_INTERNAL_TEST_NOOP_STORE_H_
...@@ -9,8 +9,7 @@ ...@@ -9,8 +9,7 @@
namespace download { namespace download {
namespace test { namespace test {
TestStore::TestStore() TestStore::TestStore() : ready_(false), init_called_(false) {}
: ready_(false), init_called_(false), destroy_called_(false) {}
TestStore::~TestStore() {} TestStore::~TestStore() {}
...@@ -23,11 +22,6 @@ void TestStore::Initialize(InitCallback callback) { ...@@ -23,11 +22,6 @@ void TestStore::Initialize(InitCallback callback) {
init_callback_ = std::move(callback); init_callback_ = std::move(callback);
} }
void TestStore::Destroy(StoreCallback callback) {
destroy_called_ = true;
destroy_callback_ = std::move(callback);
}
void TestStore::Update(const Entry& entry, StoreCallback callback) { void TestStore::Update(const Entry& entry, StoreCallback callback) {
updated_entries_.push_back(entry); updated_entries_.push_back(entry);
update_callback_ = std::move(callback); update_callback_ = std::move(callback);
...@@ -46,11 +40,6 @@ void TestStore::TriggerInit(bool success, ...@@ -46,11 +40,6 @@ void TestStore::TriggerInit(bool success,
std::move(init_callback_).Run(success, std::move(entries)); std::move(init_callback_).Run(success, std::move(entries));
} }
void TestStore::TriggerDestroy(bool success) {
DCHECK(destroy_callback_);
std::move(destroy_callback_).Run(success);
}
void TestStore::TriggerUpdate(bool success) { void TestStore::TriggerUpdate(bool success) {
DCHECK(update_callback_); DCHECK(update_callback_);
std::move(update_callback_).Run(success); std::move(update_callback_).Run(success);
......
...@@ -8,6 +8,7 @@ ...@@ -8,6 +8,7 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include "base/callback.h"
#include "base/macros.h" #include "base/macros.h"
#include "components/download/internal/store.h" #include "components/download/internal/store.h"
...@@ -25,13 +26,11 @@ class TestStore : public Store { ...@@ -25,13 +26,11 @@ class TestStore : public Store {
// Store implementation. // Store implementation.
bool IsInitialized() override; bool IsInitialized() override;
void Initialize(InitCallback callback) override; void Initialize(InitCallback callback) override;
void Destroy(StoreCallback callback) override;
void Update(const Entry& entry, StoreCallback callback) override; void Update(const Entry& entry, StoreCallback callback) override;
void Remove(const std::string& guid, StoreCallback callback) override; void Remove(const std::string& guid, StoreCallback callback) override;
// Callback trigger methods. // Callback trigger methods.
void TriggerInit(bool success, std::unique_ptr<std::vector<Entry>> entries); void TriggerInit(bool success, std::unique_ptr<std::vector<Entry>> entries);
void TriggerDestroy(bool success);
void TriggerUpdate(bool success); void TriggerUpdate(bool success);
void TriggerRemove(bool success); void TriggerRemove(bool success);
...@@ -39,7 +38,6 @@ class TestStore : public Store { ...@@ -39,7 +38,6 @@ class TestStore : public Store {
const Entry* LastUpdatedEntry() const; const Entry* LastUpdatedEntry() const;
std::string LastRemovedEntry() const; std::string LastRemovedEntry() const;
bool init_called() const { return init_called_; } bool init_called() const { return init_called_; }
bool destroy_called() const { return destroy_called_; }
const std::vector<Entry>& updated_entries() const { return updated_entries_; } const std::vector<Entry>& updated_entries() const { return updated_entries_; }
const std::vector<std::string>& removed_entries() const { const std::vector<std::string>& removed_entries() const {
return removed_entries_; return removed_entries_;
...@@ -49,13 +47,11 @@ class TestStore : public Store { ...@@ -49,13 +47,11 @@ class TestStore : public Store {
bool ready_; bool ready_;
bool init_called_; bool init_called_;
bool destroy_called_;
std::vector<Entry> updated_entries_; std::vector<Entry> updated_entries_;
std::vector<std::string> removed_entries_; std::vector<std::string> removed_entries_;
InitCallback init_callback_; InitCallback init_callback_;
StoreCallback destroy_callback_;
StoreCallback update_callback_; StoreCallback update_callback_;
StoreCallback remove_callback_; StoreCallback remove_callback_;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment