blob: fe6d7c3938777b5aae5c0a4ce16f778f80c1d47e [file] [log] [blame]
// Copyright 2017 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.
#ifndef SRC_LEDGER_BIN_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
#define SRC_LEDGER_BIN_STORAGE_IMPL_STORAGE_TEST_UTILS_H_
#include <lib/fsl/socket/strings.h>
#include <string>
#include "peridot/lib/rng/random.h"
#include "src/ledger/bin/storage/impl/btree/tree_node.h"
#include "src/ledger/bin/storage/public/page_storage.h"
#include "src/ledger/bin/storage/public/types.h"
#include "src/ledger/bin/testing/test_with_environment.h"
namespace storage {
// A sufficiently large delay, such that if a storagemethod posts a delayed
// task, the task will be due after associated amount of time.
inline constexpr zx::duration kSufficientDelay = zx::hour(1);
// Enum describing the expected behavior for identifier, allowing or preventing
// to be inlined values.
enum class InlineBehavior {
ALLOW,
PREVENT,
};
// This class stores an object, computes its identifier and
// provides accessor to transform into a data source and data chunks.
class ObjectData {
public:
explicit ObjectData(std::string value)
: ObjectData(value, InlineBehavior::ALLOW) {}
explicit ObjectData(std::string value, InlineBehavior inline_behavior)
: ObjectData(value, ObjectType::BLOB, inline_behavior) {}
explicit ObjectData(std::string value, ObjectType object_type,
InlineBehavior inline_behavior);
std::unique_ptr<DataSource> ToDataSource();
std::unique_ptr<DataSource::DataChunk> ToChunk();
std::unique_ptr<Piece> ToPiece();
const std::string value;
const size_t size;
const ObjectIdentifier object_identifier;
};
// Computes the object digest for the given content. If |inline_behavior| is
// InlineBehavior::PREVENT, resize |content| so that it cannot be inlined.
ObjectDigest MakeObjectDigest(
std::string content,
InlineBehavior inline_behavior = InlineBehavior::ALLOW);
// Computes the object identifier for the given content. If |inline_behavior| is
// InlineBehavior::PREVENT, resize |content| so that it cannot be inlined.
ObjectIdentifier MakeObjectIdentifier(
std::string content,
InlineBehavior inline_behavior = InlineBehavior::ALLOW);
// Splits the given content in chunks and calls the callback on each of them.
// Returns the object identifier for the root piece.
ObjectIdentifier ForEachPiece(
std::string content, ObjectType type,
fit::function<void(std::unique_ptr<const Piece>)> callback);
// Returns a random string of the given length.
std::string RandomString(rng::Random* random, size_t size);
// Create a new random commit id.
CommitId RandomCommitId(rng::Random* random);
// Create a new random object digest.
ObjectDigest RandomObjectDigest(rng::Random* random);
// Create a new random object identifier.
ObjectIdentifier RandomObjectIdentifier(rng::Random* random);
// Creates and returns a new EntryChange adding or updating the entry with the
// given information.
EntryChange NewEntryChange(std::string key, std::string object_digest,
KeyPriority priority);
// Creates and returns a new EntryChange removing the entry with the given key.
EntryChange NewRemoveEntryChange(std::string key);
// A TestLoopFixture providing some additional utility functions on PageStorage.
//
// All utility functions in this class return an |AssertionResult| meaning that
// they can be used in an EXPECT/ASSERT_TRUE: E.g.
// ASSERT_TRUE(AddObject("value", &object));
// or an EXPECT/ASSERT_FALSE if the function is expected to fail.
// ASSERT_FALSE(AddObject("value", &object));
class StorageTest : public ledger::TestWithEnvironment {
protected:
StorageTest();
~StorageTest() override;
virtual PageStorage* GetStorage() = 0;
// Adds a new BLOB object with the given value in the page storage and updates
// |object| with the new value.
::testing::AssertionResult AddObject(std::string value,
std::unique_ptr<const Object>* object);
// Creates a vector of entries, each of which has a key from "key00" to
// "keyXX" where XX is |size-1|. A new value is created for each entry and the
// corresponding object_digest is set on the entry. |entries| vector will be
// swapped with the result.
::testing::AssertionResult CreateEntries(size_t size,
std::vector<Entry>* entries);
// Creates a vector of entries, each of which has a key "keyXX", were "XX" is
// taken from the |values| vector. A new value is created for each entry and
// the corresponding object_digest is set on the entry. |entries| vector will
// be swapped with the result.
::testing::AssertionResult CreateEntries(std::vector<size_t> values,
std::vector<Entry>* entries);
// Creates a vector of entry changes adding or updating the given number of
// entries. See |CreateEntries| for information on the created entries.
// |changes| vector will be swapped with the result.
::testing::AssertionResult CreateEntryChanges(
size_t size, std::vector<EntryChange>* changes);
// Creates a vector of entry changes adding or updating the given number of
// entries. See |CreateEntries| for information on the created entries.
// |changes| vector will be swapped with the result. If |deletion| is true,
// the changes will be deletions, otherwise the changes will be updates.
::testing::AssertionResult CreateEntryChanges(
std::vector<size_t> values, std::vector<EntryChange>* changes,
bool deletion = false);
// Creates an empty tree node and updates |empty_node_identifier| with the
// result.
::testing::AssertionResult GetEmptyNodeIdentifier(
ObjectIdentifier* empty_node_identifier);
// Returns the tree node corresponding to the given id.
::testing::AssertionResult CreateNodeFromIdentifier(
ObjectIdentifier identifier,
std::unique_ptr<const btree::TreeNode>* node);
// Creates a new tree node from the given entries and children and updates
// |node| with the result.
::testing::AssertionResult CreateNodeFromEntries(
const std::vector<Entry>& entries,
const std::map<size_t, ObjectIdentifier>& children,
std::unique_ptr<const btree::TreeNode>* node);
// Creates a BTree applying changes from the base node and gives back the
// digest of its new root node.
::testing::AssertionResult CreateTreeFromChanges(
const ObjectIdentifier& base_node_identifier,
const std::vector<EntryChange>& entries,
ObjectIdentifier* new_root_identifier);
private:
FXL_DISALLOW_COPY_AND_ASSIGN(StorageTest);
};
} // namespace storage
#endif // SRC_LEDGER_BIN_STORAGE_IMPL_STORAGE_TEST_UTILS_H_