blob: c66e120b660042cbd19f714c44231459310a2c8e [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 "peridot/bin/ledger/storage/impl/object_impl.h"
#include <lib/fsl/vmo/strings.h>
#include <zircon/syscalls.h>
#include "gtest/gtest.h"
#include "peridot/bin/ledger/storage/impl/object_digest.h"
#include "peridot/bin/ledger/testing/test_with_environment.h"
#include "peridot/lib/scoped_tmpfs/scoped_tmpfs.h"
#include "third_party/leveldb/include/leveldb/db.h"
#include "util/env_fuchsia.h"
namespace storage {
namespace {
ObjectIdentifier CreateObjectIdentifier(ObjectDigest digest) {
return {1u, 2u, std::move(digest)};
}
::testing::AssertionResult CheckObjectValue(const Object& object,
ObjectIdentifier identifier,
fxl::StringView data) {
if (object.GetIdentifier() != identifier) {
return ::testing::AssertionFailure()
<< "Expected id: " << identifier
<< ", but got: " << object.GetIdentifier();
}
fxl::StringView found_data;
Status status = object.GetData(&found_data);
if (status != Status::OK) {
return ::testing::AssertionFailure()
<< "Unable to call GetData on object, status: " << status;
}
if (data != found_data) {
return ::testing::AssertionFailure()
<< "Expected data: " << convert::ToHex(data)
<< ", but got: " << convert::ToHex(found_data);
}
fsl::SizedVmo vmo;
status = object.GetVmo(&vmo);
if (status != Status::OK) {
return ::testing::AssertionFailure()
<< "Unable to call GetVmo on object, status: " << status;
}
std::string found_data_in_vmo;
if (!fsl::StringFromVmo(vmo, &found_data_in_vmo)) {
return ::testing::AssertionFailure() << "Unable to read from VMO.";
}
if (data != found_data_in_vmo) {
return ::testing::AssertionFailure()
<< "Expected data in vmo: " << convert::ToHex(data)
<< ", but got: " << convert::ToHex(found_data_in_vmo);
}
return ::testing::AssertionSuccess();
}
class ObjectImplTest : public ledger::TestWithEnvironment {
public:
std::string RandomString(size_t size) {
std::string result;
result.resize(size);
environment_.random()->Draw(&result);
return result;
}
};
TEST_F(ObjectImplTest, InlinedObject) {
std::string data = RandomString(12);
ObjectIdentifier identifier = CreateObjectIdentifier(
ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
InlinedObject object(identifier);
EXPECT_TRUE(CheckObjectValue(object, identifier, data));
}
TEST_F(ObjectImplTest, StringObject) {
std::string data = RandomString(256);
ObjectIdentifier identifier = CreateObjectIdentifier(
ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
StringObject object(identifier, data);
EXPECT_TRUE(CheckObjectValue(object, identifier, data));
}
TEST_F(ObjectImplTest, LevelDBObject) {
scoped_tmpfs::ScopedTmpFS tmpfs;
auto env = leveldb::MakeFuchsiaEnv(tmpfs.root_fd());
leveldb::DB* db = nullptr;
leveldb::Options options;
options.env = env.get();
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options, "db", &db);
ASSERT_TRUE(status.ok());
std::unique_ptr<leveldb::DB> db_ptr(db);
leveldb::WriteOptions write_options_;
leveldb::ReadOptions read_options_;
std::string data = RandomString(256);
ObjectIdentifier identifier = CreateObjectIdentifier(
ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
status = db_ptr->Put(write_options_, "", data);
ASSERT_TRUE(status.ok());
std::unique_ptr<leveldb::Iterator> iterator(
db_ptr->NewIterator(read_options_));
iterator->Seek("");
ASSERT_TRUE(iterator->Valid());
ASSERT_TRUE(iterator->key() == "");
LevelDBObject object(identifier, std::move(iterator));
EXPECT_TRUE(CheckObjectValue(object, identifier, data));
}
TEST_F(ObjectImplTest, VmoObject) {
std::string data = RandomString(256);
ObjectIdentifier identifier = CreateObjectIdentifier(
ComputeObjectDigest(PieceType::CHUNK, ObjectType::BLOB, data));
fsl::SizedVmo vmo;
ASSERT_TRUE(fsl::VmoFromString(data, &vmo));
VmoObject object(identifier, std::move(vmo));
EXPECT_TRUE(CheckObjectValue(object, identifier, data));
}
} // namespace
} // namespace storage