blob: 71446187ddca6d2db255aa1af28c5040f0625997 [file]
#include "fw-update/condition_collector.hpp"
#include <filesystem>
#include <fstream>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using namespace pldm::fw_update;
namespace fs = std::filesystem;
class ConditionCollectorTest : public testing::Test
{
protected:
void SetUp() override
{
testConfigPath = "test_condition_config.json";
}
void TearDown() override
{
if (fs::exists(testConfigPath))
{
fs::remove(testConfigPath);
}
}
fs::path testConfigPath;
};
TEST_F(ConditionCollectorTest, EmptyPathReturnsEmpty)
{
ConditionConfigManager manager("");
EXPECT_EQ(manager.preCondition("BIC"), "");
EXPECT_EQ(manager.postCondition("BIC"), "");
EXPECT_EQ(manager.conditions("BIC"), ConditionPaths());
}
TEST_F(ConditionCollectorTest, NonExistentFileReturnsEmpty)
{
fs::path nonExistentPath = "/nonexistent/path/config.json";
ConditionConfigManager manager(nonExistentPath);
EXPECT_EQ(manager.preCondition("BIC"), "");
EXPECT_EQ(manager.postCondition("BIC"), "");
}
TEST_F(ConditionCollectorTest, ValidConfigParsingPreCondition)
{
const std::string configContent = R"(
{
"Components": [
{
"Component": "BIC",
"PreUpdateTarget": "bic-pre-update.service",
"PostUpdateTarget": "bic-post-update@.service"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIC"), "bic-pre-update.service");
EXPECT_EQ(manager.postCondition("BIC"), "bic-post-update@.service");
auto [pre, post] = manager.conditions("BIC");
EXPECT_EQ(pre, "bic-pre-update.service");
EXPECT_EQ(post, "bic-post-update@.service");
}
TEST_F(ConditionCollectorTest, GenerateArgFromBoardName)
{
EXPECT_EQ(generateArg("board1"), "boardName=board1");
EXPECT_EQ(generateArg(""), "");
}
// The schema requires a non-empty unit name and omission of the property to
// skip a condition. An empty name is still tolerated at runtime and reported as
// no condition.
TEST_F(ConditionCollectorTest, EmptyConditionStrings)
{
const std::string configContent = R"(
{
"Components": [
{
"Component": "NIC",
"PreUpdateTarget": "",
"PostUpdateTarget": ""
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("NIC"), "");
EXPECT_EQ(manager.postCondition("NIC"), "");
}
TEST_F(ConditionCollectorTest, MultipleComponentsParsing)
{
const std::string configContent = R"(
{
"Components": [
{
"Component": "BIOS",
"PreUpdateTarget": "bios-pre.service",
"PostUpdateTarget": "bios-post.service"
},
{
"Component": "BIOS_VR",
"PostUpdateTarget": "vr-post.service"
},
{
"Component": "EC",
"PreUpdateTarget": "ec-pre.service"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIOS"), "bios-pre.service");
EXPECT_EQ(manager.postCondition("BIOS"), "bios-post.service");
EXPECT_EQ(manager.preCondition("BIOS_VR"), "");
EXPECT_EQ(manager.postCondition("BIOS_VR"), "vr-post.service");
EXPECT_EQ(manager.preCondition("EC"), "ec-pre.service");
EXPECT_EQ(manager.postCondition("EC"), "");
}
TEST_F(ConditionCollectorTest, NonExistentComponentReturnsEmpty)
{
const std::string configContent = R"(
{
"Components": [
{
"Component": "BIC",
"PreUpdateTarget": "bic-pre.service",
"PostUpdateTarget": "bic-post.service"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("UNKNOWN"), "");
EXPECT_EQ(manager.postCondition("UNKNOWN"), "");
EXPECT_EQ(manager.conditions("UNKNOWN"), ConditionPaths());
}
TEST_F(ConditionCollectorTest, InvalidJsonFormat)
{
const std::string configContent = R"({invalid json})";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
// Should not throw, just handle gracefully
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIC"), "");
}
TEST_F(ConditionCollectorTest, MissingComponentsKey)
{
const std::string configContent = R"(
{
"NotComponents": []
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIC"), "");
}
TEST_F(ConditionCollectorTest, MissingComponentNameField)
{
const std::string configContent = R"(
{
"Components": [
{
"PreUpdateTarget": "pre.service",
"PostUpdateTarget": "post.service"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
// Should skip invalid entry and not crash
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIC"), "");
}
TEST_F(ConditionCollectorTest, BothTargetFieldsAbsent)
{
// Neither PreUpdateTarget nor PostUpdateTarget is present —
// entry should be skipped and queries should return empty string
const std::string configContent = R"(
{
"Components": [
{
"Component": "BIC"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIC"), "");
EXPECT_EQ(manager.postCondition("BIC"), "");
}
TEST_F(ConditionCollectorTest, OnlyPreTargetAbsent)
{
// PostUpdateTarget is present but PreUpdateTarget is absent —
// pre should default to empty string, post should be populated
const std::string configContent = R"(
{
"Components": [
{
"Component": "BIOS",
"PostUpdateTarget": "bios-post.service"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("BIOS"), "");
EXPECT_EQ(manager.postCondition("BIOS"), "bios-post.service");
}
TEST_F(ConditionCollectorTest, OnlyPostTargetAbsent)
{
// PreUpdateTarget is present but PostUpdateTarget is absent —
// post should default to empty string, pre should be populated
const std::string configContent = R"(
{
"Components": [
{
"Component": "NIC",
"PreUpdateTarget": "nic-pre.service"
}
]
}
)";
std::ofstream configFile(testConfigPath);
configFile << configContent;
configFile.close();
ConditionConfigManager manager(testConfigPath);
EXPECT_EQ(manager.preCondition("NIC"), "nic-pre.service");
EXPECT_EQ(manager.postCondition("NIC"), "");
}