blob: eb5bcbb196f58ce2d99f7f8c83ab6d298dbe06cd [file] [log] [blame]
// Copyright 2019 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/bugreport/client/bug_report_handler.h"
#include <gtest/gtest.h>
#include <fstream>
namespace bugreport {
namespace {
std::optional<std::string> ReadWholeFile(const std::filesystem::path& path) {
std::ifstream ifs(path);
if (!ifs.good())
return std::nullopt;
std::string tmp((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
return tmp;
}
constexpr char kValidDocument[] = R"(
{
"annotations":
{
"annotation.1.key": "annotation.1.value",
"annotation.2.key": "annotation.2.value"
},
"attachments":
{
"attachment.1.key": "{\"embedded\": [\"array\"], \"another\": \"key\"}",
"attachment.2.key": "attachment.2.value"
}
}
)";
// The stream reader loads data in chunk, so a long document will be effectively split several times
// during load. This long (valid) document is meant to test that case.
constexpr char kValidDocumentLongDocument[] = R"(
{
"annotations":
{
"annotation.1.key": "annotation.1.value",
"annotation.2.key": "annotation.2.value"
},
"attachments":
{
"attachment.1.key": "{\"embedded\": [\"array\"], \"another\": \"key\",\"embedded\": [\"array\"], \"another\": \"key\",\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"\"embedded\": [\"array\"], \"another\": \"key\"}",
"attachment.2.key": "attachment.2.value"
}
}
)";
constexpr char kEmpty[] = R"(
{
"annotations": { },
"attachments": { }
}
)";
constexpr char kMissingAnnotations[] = R"(
{
"attachments":
{
"attachment.1.key": "{\"embedded\": [\"json\", \"array\"]}",
"attachment.2.key": "attachment.2.value"
}
}
)";
constexpr char kMissingAttachments[] = R"(
{
"annotations":
{
"annotation.1.key": "annotation.1.value",
"annotation.2.key": "annotation.2.value"
}
}
)";
constexpr char kWrongAnnotationType[] = R"(
{
"annotations":
{
"annotation.1.key": {"not": "string"},
"annotation.2.key": "annotation.2.value"
},
"attachments":
{
"attachment.1.key": "{\"embedded\": \"json\"}",
"attachment.2.key": "attachment.2.value"
}
}
)";
constexpr char kWrongAttachmentType[] = R"(
{
"annotations":
{
"annotation.1.key": "annotation.1.value",
"annotation.2.key": "annotation.2.value"
},
"attachments":
{
"attachment.1.key": {"not": "string"},
"attachment.2.key": "attachment.2.value"
}
}
)";
class BugReportClientTest : public ::testing::Test {
protected:
void TearDown() override {
// Best effort removal of test files.
for (auto& target : targets_) {
std::filesystem::remove(base_path_ / target.name);
}
}
bool SetupTempFiles() {
// Setup.
std::error_code ec;
auto test_path = std::filesystem::temp_directory_path(ec);
if (ec) {
ADD_FAILURE() << ec.message();
return false;
}
base_path_ = test_path;
return true;
}
std::filesystem::path base_path_;
std::vector<Target> targets_;
};
} // namespace
TEST_F(BugReportClientTest, ProcessBugReport_ValidDocument) {
auto targets = ProcessBugReport(kValidDocument);
ASSERT_TRUE(targets);
ASSERT_EQ(targets->size(), 3u);
auto& annotation = targets->at(0);
EXPECT_EQ(annotation.name, "annotations.json");
EXPECT_EQ(annotation.contents,
R"({
"annotation.1.key": "annotation.1.value",
"annotation.2.key": "annotation.2.value"
})");
auto attachment1 = targets->at(1);
EXPECT_EQ(attachment1.name, "attachment.1.key");
EXPECT_EQ(attachment1.contents,
R"({
"embedded": [
"array"
],
"another": "key"
})");
auto attachment2 = targets->at(2);
EXPECT_EQ(attachment2.name, "attachment.2.key");
EXPECT_EQ(attachment2.contents, "attachment.2.value");
}
TEST_F(BugReportClientTest, ProcessBugReport_EdgeCases) {
EXPECT_TRUE(ProcessBugReport(kEmpty));
EXPECT_FALSE(ProcessBugReport("{{{{"));
EXPECT_FALSE(ProcessBugReport(kMissingAnnotations));
EXPECT_FALSE(ProcessBugReport(kMissingAttachments));
EXPECT_FALSE(ProcessBugReport(kWrongAnnotationType));
EXPECT_FALSE(ProcessBugReport(kWrongAttachmentType));
}
TEST_F(BugReportClientTest, Export) {
ASSERT_TRUE(SetupTempFiles());
auto targets = ProcessBugReport(kValidDocument);
ASSERT_TRUE(targets);
ASSERT_EQ(targets->size(), 3u);
targets_ = std::move(*targets);
ASSERT_TRUE(Export(targets_, base_path_));
// Verify.
std::optional<std::string> contents;
contents = ReadWholeFile(base_path_ / targets_.at(0).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(0).name;
} else {
EXPECT_EQ(*contents, targets_.at(0).contents);
}
contents = ReadWholeFile(base_path_ / targets_.at(1).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(1).name;
} else {
EXPECT_EQ(*contents, targets_.at(1).contents);
}
contents = ReadWholeFile(base_path_ / targets_.at(2).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(2).name;
} else {
EXPECT_EQ(*contents, targets_.at(2).contents);
}
}
TEST_F(BugReportClientTest, HandleBugReport_ValidDocument) {
ASSERT_TRUE(SetupTempFiles());
std::istringstream iss(kValidDocument);
auto targets = HandleBugReport(base_path_, &iss);
ASSERT_TRUE(targets);
targets_ = std::move(*targets);
// Verify.
std::optional<std::string> contents;
contents = ReadWholeFile(base_path_ / targets_.at(0).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(0).name;
} else {
EXPECT_EQ(*contents, targets_.at(0).contents);
}
contents = ReadWholeFile(base_path_ / targets_.at(1).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(1).name;
} else {
EXPECT_EQ(*contents, targets_.at(1).contents);
}
contents = ReadWholeFile(base_path_ / targets_.at(2).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(2).name;
} else {
EXPECT_EQ(*contents, targets_.at(2).contents);
}
}
TEST_F(BugReportClientTest, HandleBugReport_LongDocument) {
ASSERT_TRUE(SetupTempFiles());
std::istringstream iss(kValidDocumentLongDocument);
auto targets = HandleBugReport(base_path_, &iss);
ASSERT_TRUE(targets);
targets_ = std::move(*targets);
// Verify.
std::optional<std::string> contents;
contents = ReadWholeFile(base_path_ / targets_.at(0).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(0).name;
} else {
EXPECT_EQ(*contents, targets_.at(0).contents);
}
contents = ReadWholeFile(base_path_ / targets_.at(1).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(1).name;
} else {
EXPECT_EQ(*contents, targets_.at(1).contents);
}
contents = ReadWholeFile(base_path_ / targets_.at(2).name);
if (!contents) {
ADD_FAILURE() << "Error for: " << targets_.at(2).name;
} else {
EXPECT_EQ(*contents, targets_.at(2).contents);
}
}
} // namespace bugreport