blob: 0be4f47f9b87eddc47ccdf8dee24822d7216130d [file] [log] [blame]
// Copyright 2020 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 "src/developer/shell/mirror/wire_format.h"
#include <fcntl.h>
#include <lib/async-loop/default.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <atomic>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include <gtest/gtest.h>
#include "src/developer/shell/mirror/common.h"
#include "src/developer/shell/mirror/test_shared.h"
namespace shell::mirror {
namespace {
class FilesTest : public ::testing::Test {
public:
FilesTest() = default;
protected:
std::unique_ptr<Files> file_files_;
};
TEST_F(FilesTest, BasicSerialization) {
// Spin up some temp storage
const std::string kRootDir = "/usr";
const std::string kDataDir = "/wire_format_test_tmp";
FileRepo repo(&kAsyncLoopConfigNoAttachToCurrentThread);
repo.InitMemRepo(kDataDir);
// Generate some fake files.
std::vector<std::pair<std::string, std::string>> golden = {
{kRootDir + "/z.txt", ""},
{kRootDir + "/a.txt", "Once upon a midnight dreary, while I pondered, weak and weary,"},
{kRootDir + "/b.txt", "Over many a quaint and curious volume of forgotten lore"},
{kRootDir + "/c.txt", "While I nodded, nearly napping, suddenly there came a tapping,"},
{kRootDir + "/d.txt", "As of some one gently rapping, rapping at my chamber door."}};
// Try serializing 0..5 files
for (size_t num_files = 0; num_files <= golden.size(); num_files++) {
Files golden_files(kRootDir);
for (size_t i = 0; i < num_files; i++) {
char* dup = new char[golden[i].second.length() + 1];
strcpy(dup, golden[i].second.c_str());
ASSERT_EQ(0,
golden_files.AddFile(golden[i].first, std::unique_ptr<char[]>(dup), strlen(dup)));
}
std::vector<char> dumped_files;
// Write files to temp storage.
ASSERT_EQ(0, golden_files.DumpFiles(&dumped_files));
const std::string kSimpleFile = kDataDir + "/simple" + std::to_string(num_files);
std::ofstream fout(kSimpleFile, std::ios::out | std::ios::binary);
fout.write(&dumped_files[0], dumped_files.size());
fout.close();
// Read the files from temp storage
int infd = open(kSimpleFile.c_str(), O_RDONLY);
ASSERT_NE(-1, infd);
shell::mirror::Err error;
Files out_files = Files::FilesFromFD(infd, &error);
ASSERT_EQ(0, error.code) << error.msg;
const auto& actual_files = out_files.GetFiles();
// Make sure what we read is the same as what we wrote.
ASSERT_EQ(actual_files.size(), num_files);
for (size_t i = 0; i < actual_files.size(); i++) {
bool found = false;
for (size_t j = 0; j < golden.size(); j++) {
if (golden[j].first == (kRootDir + "/" + actual_files[i].Name())) {
found = true;
ASSERT_EQ(golden[j].second, actual_files[i].View());
}
}
ASSERT_TRUE(found) << actual_files[i].Name() << " not found";
}
}
}
} // namespace
} // namespace shell::mirror