blob: 478819ce00d1a734ec90d2de58f5504fb9ada0b6 [file]
// Copyright 2021 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/forensics/feedback_data/namespace_init.h"
#include <lib/syslog/cpp/macros.h>
#include <lib/syslog/logger.h>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
#include "src/developer/forensics/feedback_data/system_log_recorder/encoding/production_encoding.h"
#include "src/developer/forensics/feedback_data/system_log_recorder/encoding/version.h"
#include "src/developer/forensics/feedback_data/system_log_recorder/reader.h"
#include "src/developer/forensics/testing/log_message.h"
#include "src/developer/forensics/testing/stubs/cobalt_logger_factory.h"
#include "src/developer/forensics/testing/unit_test_fixture.h"
#include "src/developer/forensics/utils/cobalt/logger.h"
#include "src/developer/forensics/utils/log_format.h"
#include "src/lib/files/directory.h"
#include "src/lib/files/file.h"
#include "src/lib/files/path.h"
#include "src/lib/files/scoped_temp_dir.h"
#include "src/lib/timekeeper/test_clock.h"
namespace forensics {
namespace feedback_data {
namespace {
using testing::BuildLogMessage;
using ::testing::UnorderedElementsAreArray;
MATCHER_P2(MatchesCobaltEvent, expected_type, expected_metric_id, "") {
return arg.type == expected_type && arg.metric_id == expected_metric_id;
}
void WriteFile(const std::string& filepath, const std::string& content) {
FX_CHECK(files::WriteFile(filepath, content.c_str(), content.size()));
}
std::string ReadFile(const std::string& filepath) {
std::string content;
FX_CHECK(files::ReadFileToString(filepath, &content));
return content;
}
std::string MakeFilepath(const std::string& dir, const size_t file_num) {
return files::JoinPath(dir, std::to_string(file_num));
}
const std::vector<std::string> CurrentLogFilePaths(const std::string& dir) {
return {MakeFilepath(dir, 0), MakeFilepath(dir, 1), MakeFilepath(dir, 2), MakeFilepath(dir, 3),
MakeFilepath(dir, 4), MakeFilepath(dir, 5), MakeFilepath(dir, 6), MakeFilepath(dir, 7)};
}
class NamespaceInitTest : public UnitTestFixture {
public:
NamespaceInitTest() : cobalt_(dispatcher(), services(), &clock_) {
SetUpCobaltServer(std::make_unique<stubs::CobaltLoggerFactory>());
}
protected:
timekeeper::TestClock clock_;
cobalt::Logger cobalt_;
files::ScopedTempDir temp_dir_;
};
TEST_F(NamespaceInitTest, CreatePreviousLogsFile) {
std::string logs_dir;
ASSERT_TRUE(temp_dir_.NewTempDir(&logs_dir));
std::string previous_log_contents = "";
for (const auto& filepath : CurrentLogFilePaths(logs_dir)) {
auto encoder = system_log_recorder::ProductionEncoder();
const std::string str = Format(BuildLogMessage(FX_LOG_INFO, "Log for file: " + filepath));
previous_log_contents = previous_log_contents + str;
WriteFile(filepath, encoder.Encode(str));
}
std::string log_file = files::JoinPath(temp_dir_.path(), "log.system.previous_boot.txt");
CreatePreviousLogsFile(&cobalt_, logs_dir, log_file);
RunLoopUntilIdle();
EXPECT_FALSE(files::IsDirectory(logs_dir));
EXPECT_EQ(previous_log_contents, ReadFile(log_file));
// Verify the event type and metric_id.
EXPECT_THAT(
ReceivedCobaltEvents(),
UnorderedElementsAreArray({
MatchesCobaltEvent(cobalt::EventType::kInteger,
cobalt_registry::kPreviousBootLogCompressionRatioMigratedMetricId),
}));
}
TEST_F(NamespaceInitTest, MoveAndRecordBootId) {
const std::string current_boot_id_path = files::JoinPath(temp_dir_.path(), "current_boot_id.txt");
const std::string previous_boot_id_path =
files::JoinPath(temp_dir_.path(), "previous_boot_id.txt");
const std::string previous_boot_id = "previous_boot_id";
WriteFile(current_boot_id_path, previous_boot_id);
MoveAndRecordBootId("current_boot_id", previous_boot_id_path, current_boot_id_path);
EXPECT_EQ("previous_boot_id", ReadFile(previous_boot_id_path));
EXPECT_EQ("current_boot_id", ReadFile(current_boot_id_path));
}
TEST_F(NamespaceInitTest, MoveAndRecordBuildVersion) {
const std::string current_build_version_path =
files::JoinPath(temp_dir_.path(), "current_build_version.txt");
const std::string previous_build_version_path =
files::JoinPath(temp_dir_.path(), "previous_build_version.txt");
const std::string previous_build_version = "previous_build_version";
WriteFile(current_build_version_path, previous_build_version);
MoveAndRecordBuildVersion("current_build_version", previous_build_version_path,
current_build_version_path);
EXPECT_EQ("previous_build_version", ReadFile(previous_build_version_path));
EXPECT_EQ("current_build_version", ReadFile(current_build_version_path));
}
} // namespace
} // namespace feedback_data
} // namespace forensics