blob: 752f0a2ea4a62445a1e3861fe6e674b3d5f9802e [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 <lib/callback/capture.h>
#include <lib/callback/set_when_called.h>
#include <lib/gtest/test_loop_fixture.h>
#include <algorithm>
#include <memory>
#include <set>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
#include "src/ledger/bin/encryption/fake/fake_encryption_service.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/lib/fxl/macros.h"
namespace storage {
namespace {
using ::testing::ElementsAreArray;
using ::testing::IsEmpty;
class LedgerStorageTest : public ledger::TestWithEnvironment {
public:
LedgerStorageTest()
: encryption_service_(dispatcher()),
db_factory_(dispatcher()),
storage_(&environment_, &encryption_service_, &db_factory_,
ledger::DetachedPath(tmpfs_.root_fd()), CommitPruningPolicy::NEVER) {}
~LedgerStorageTest() override {}
// ledger::TestWithEnvironment:
void SetUp() override {
ledger::TestWithEnvironment::SetUp();
ASSERT_EQ(Status::OK, storage_.Init());
}
private:
scoped_tmpfs::ScopedTmpFS tmpfs_;
encryption::FakeEncryptionService encryption_service_;
protected:
fake::FakeDbFactory db_factory_;
LedgerStorageImpl storage_;
FXL_DISALLOW_COPY_AND_ASSIGN(LedgerStorageTest);
};
TEST_F(LedgerStorageTest, CreateGetCreatePageStorage) {
PageId page_id = "1234";
Status status;
std::unique_ptr<PageStorage> page_storage;
bool called;
storage_.GetPageStorage(
page_id, callback::Capture(callback::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::PAGE_NOT_FOUND, status);
EXPECT_EQ(nullptr, page_storage);
storage_.CreatePageStorage(
page_id, callback::Capture(callback::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
ASSERT_NE(nullptr, page_storage);
ASSERT_EQ(page_id, page_storage->GetId());
page_storage.reset();
storage_.GetPageStorage(
page_id, callback::Capture(callback::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::OK, status);
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, callback::Capture(callback::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
ASSERT_NE(nullptr, page_storage);
ASSERT_EQ(page_id, page_storage->GetId());
page_storage.reset();
storage_.GetPageStorage(
page_id, callback::Capture(callback::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::OK, status);
EXPECT_NE(nullptr, page_storage);
storage_.DeletePageStorage(page_id, callback::Capture(callback::SetWhenCalled(&called), &status));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::OK, status);
storage_.GetPageStorage(
page_id, callback::Capture(callback::SetWhenCalled(&called), &status, &page_storage));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::PAGE_NOT_FOUND, status);
EXPECT_EQ(nullptr, page_storage);
}
TEST_F(LedgerStorageTest, DeletePageStorageNotFound) {
PageId page_id = "1234";
Status status;
bool called;
storage_.DeletePageStorage(page_id, callback::Capture(callback::SetWhenCalled(&called), &status));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::PAGE_NOT_FOUND, status);
}
TEST_F(LedgerStorageTest, ListNoPages) {
Status status;
bool called;
std::set<PageId> listed_page_ids;
storage_.ListPages(
callback::Capture(callback::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
EXPECT_EQ(Status::OK, status);
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], callback::Capture(callback::SetWhenCalled(&called),
&status, &page_storages[i]));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
ASSERT_NE(nullptr, page_storages[i]);
expected_page_ids.push_back(all_page_ids[i]);
std::set<PageId> listed_page_ids;
storage_.ListPages(
callback::Capture(callback::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
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(
callback::Capture(callback::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
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,
callback::Capture(callback::SetWhenCalled(&called), &status));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
expected_page_ids.erase(expected_page_ids.begin());
std::set<PageId> listed_page_ids;
storage_.ListPages(
callback::Capture(callback::SetWhenCalled(&called), &status, &listed_page_ids));
RunLoopUntilIdle();
ASSERT_TRUE(called);
ASSERT_EQ(Status::OK, status);
ASSERT_THAT(listed_page_ids, ElementsAreArray(expected_page_ids));
}
}
} // namespace
} // namespace storage