blob: ce28d5c354231363488d7ed4f8e94b7a43c032dc [file] [log] [blame]
// Copyright 2016 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include <algorithm>
#include <memory>
#include <set>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "src/ledger/bin/clocks/testing/device_id_manager_empty_impl.h"
#include "src/ledger/bin/encryption/fake/fake_encryption_service.h"
#include "src/ledger/bin/platform/scoped_tmp_location.h"
#include "src/ledger/bin/storage/fake/fake_db_factory.h"
#include "src/ledger/bin/storage/impl/ledger_storage_impl.h"
#include "src/ledger/bin/storage/impl/storage_test_utils.h"
#include "src/ledger/bin/storage/public/db_factory.h"
#include "src/ledger/bin/testing/test_with_environment.h"
#include "src/ledger/lib/callback/capture.h"
#include "src/ledger/lib/callback/set_when_called.h"
namespace storage {
namespace {
using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
class LedgerStorageTest : public ledger::TestWithEnvironment {
public:
LedgerStorageTest()
: tmp_location_(environment_.file_system()->CreateScopedTmpLocation()),
encryption_service_(dispatcher()),
db_factory_(environment_.file_system(), dispatcher()),
storage_(&environment_, &encryption_service_, &db_factory_, tmp_location_->path(),
CommitPruningPolicy::NEVER, &device_id_manager_) {}
LedgerStorageTest(const LedgerStorageTest&) = delete;
LedgerStorageTest& operator=(const LedgerStorageTest&) = delete;
~LedgerStorageTest() override = default;
// ledger::TestWithEnvironment:
void SetUp() override {
ledger::TestWithEnvironment::SetUp();
ASSERT_EQ(storage_.Init(), Status::OK);
}
private:
std::unique_ptr<ledger::ScopedTmpLocation> tmp_location_;
encryption::FakeEncryptionService encryption_service_;
protected:
fake::FakeDbFactory db_factory_;
clocks::DeviceIdManagerEmptyImpl device_id_manager_;
LedgerStorageImpl storage_;
};
TEST_F(LedgerStorageTest, CreateGetCreatePageStorage) {
PageId page_id = "1234";
Status status;
std::unique_ptr<PageStorage> page_storage;
bool called;
storage_.GetPageStorage(page_id,
ledger::Capture(ledger::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::PAGE_NOT_FOUND);
EXPECT_EQ(page_storage, nullptr);
storage_.CreatePageStorage(
page_id, ledger::Capture(ledger::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
ASSERT_NE(nullptr, page_storage);
ASSERT_EQ(page_storage->GetId(), page_id);
page_storage.reset();
storage_.GetPageStorage(page_id,
ledger::Capture(ledger::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::OK);
EXPECT_NE(nullptr, page_storage);
}
TEST_F(LedgerStorageTest, CreateDeletePageStorage) {
PageId page_id = "1234";
Status status;
bool called;
std::unique_ptr<PageStorage> page_storage;
storage_.CreatePageStorage(
page_id, ledger::Capture(ledger::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
ASSERT_NE(nullptr, page_storage);
ASSERT_EQ(page_storage->GetId(), page_id);
page_storage.reset();
storage_.GetPageStorage(page_id,
ledger::Capture(ledger::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::OK);
EXPECT_NE(nullptr, page_storage);
storage_.DeletePageStorage(page_id, ledger::Capture(ledger::SetWhenCalled(&called), &status));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::OK);
storage_.GetPageStorage(page_id,
ledger::Capture(ledger::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::PAGE_NOT_FOUND);
EXPECT_EQ(page_storage, nullptr);
}
TEST_F(LedgerStorageTest, DeletePageStorageNotFound) {
PageId page_id = "1234";
Status status;
bool called;
storage_.DeletePageStorage(page_id, ledger::Capture(ledger::SetWhenCalled(&called), &status));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::PAGE_NOT_FOUND);
}
TEST_F(LedgerStorageTest, ListNoPages) {
Status status;
bool called;
std::set<PageId> listed_page_ids;
storage_.ListPages(ledger::Capture(ledger::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(status, Status::OK);
EXPECT_THAT(listed_page_ids, IsEmpty());
}
TEST_F(LedgerStorageTest, ListPages) {
std::vector<PageId> all_page_ids({"1234", "5678", "90AB"});
Status status;
bool called;
// The pages storages are listed after they are created...
std::vector<std::unique_ptr<PageStorage>> page_storages(all_page_ids.size());
std::vector<PageId> expected_page_ids;
for (size_t i = 0; i < all_page_ids.size(); i++) {
storage_.CreatePageStorage(all_page_ids[i], ledger::Capture(ledger::SetWhenCalled(&called),
&status, &page_storages[i]));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
ASSERT_NE(nullptr, page_storages[i]);
expected_page_ids.push_back(all_page_ids[i]);
std::set<PageId> listed_page_ids;
storage_.ListPages(ledger::Capture(ledger::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
ASSERT_THAT(listed_page_ids, ElementsAreArray(expected_page_ids));
}
// ... destroying the |PageStorage| pointers that were returned on creation
// does not cause the page storages to be "lost" and not listed...
for (size_t i = 0; i < all_page_ids.size(); i++) {
page_storages[i].reset();
std::set<PageId> listed_page_ids;
storage_.ListPages(ledger::Capture(ledger::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
ASSERT_THAT(listed_page_ids, ElementsAreArray(all_page_ids));
}
// ... deleting the page storages does cause them to no longer be listed.
for (const auto& page_id : all_page_ids) {
storage_.DeletePageStorage(page_id, ledger::Capture(ledger::SetWhenCalled(&called), &status));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
expected_page_ids.erase(expected_page_ids.begin());
std::set<PageId> listed_page_ids;
storage_.ListPages(ledger::Capture(ledger::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(status, Status::OK);
ASSERT_THAT(listed_page_ids, ElementsAreArray(expected_page_ids));
}
}
} // namespace
} // namespace storage