blob: 94ecbcef097bcd948df547f8351679af47ee4e31 [file]
#include "libpldmresponder/pdr_file.hpp"
#include "libpldmresponder/pdr_utils.hpp"
#include <libpldm/platform.h>
#include <nlohmann/json.hpp>
#include <filesystem>
#include <fstream>
#include <gmock/gmock.h>
#include <gtest/gtest.h>
using namespace pldm::responder::pdr_file;
using namespace pldm::responder::pdr_utils;
using ::testing::_;
using ::testing::Return;
using Json = nlohmann::json;
namespace fs = std::filesystem;
class MockRepo : public RepoInterface
{
public:
MockRepo() : RepoInterface(nullptr) {}
MOCK_METHOD(pldm_pdr*, getPdr, (), (const, override));
MOCK_METHOD(RecordHandle, addRecord, (const PdrEntry&), (override));
MOCK_METHOD(const pldm_pdr_record*, getFirstRecord, (PdrEntry&),
(override));
MOCK_METHOD(const pldm_pdr_record*, getNextRecord,
(const pldm_pdr_record*, PdrEntry&), (override));
MOCK_METHOD(uint32_t, getRecordHandle, (const pldm_pdr_record*),
(const, override));
MOCK_METHOD(uint32_t, getRecordCount, (), (override));
MOCK_METHOD(bool, empty, (), (override));
MOCK_METHOD(uint32_t, getRepositorySize, (), (override));
MOCK_METHOD(uint32_t, getLargestRecordSize, (), (override));
};
class GenerateFileDescriptorPDRTest : public ::testing::Test
{
protected:
void SetUp() override
{
// Create a temporary directory for test files.
char tmppldm[] = "/tmp/pldm_file_pdr_test.XXXXXX";
dir = fs::path(mkdtemp(tmppldm));
// Create a dummy file for the success case.
testFilePath = dir / "test_dir";
fs::create_directory(testFilePath);
std::ofstream(testFilePath / "test_file.bin").close();
}
void TearDown() override
{
for (const auto& pair : fileIdentifierToFileInfo)
{
if (pair.second.fp)
{
fclose(pair.second.fp);
}
}
fs::remove_all(dir);
}
fs::path dir;
fs::path testFilePath;
MockRepo repo;
std::map<uint16_t, FileInfo> fileIdentifierToFileInfo;
std::map<uint32_t, FileInfo> recordHandleToFileInfo;
};
TEST_F(GenerateFileDescriptorPDRTest, SuccessCase)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "placeholder",
"Files": [
{
"FileIdentifier": 1,
"FileName": "test_file.bin",
"FileSize": 1234
}
]
}
]
})"_json;
auto modifiedJson = json;
modifiedJson["entries"][0]["Path"] = testFilePath.string();
EXPECT_CALL(repo, addRecord(_)).WillOnce(Return(1));
generateFileDescriptorPDR(modifiedJson, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_EQ(fileIdentifierToFileInfo.size(), 1);
EXPECT_EQ(recordHandleToFileInfo.size(), 1);
EXPECT_TRUE(fileIdentifierToFileInfo.contains(1));
EXPECT_TRUE(recordHandleToFileInfo.contains(1));
const auto& fileInfo = fileIdentifierToFileInfo.at(1);
EXPECT_EQ(fileInfo.fileIdentifier, 1);
EXPECT_EQ(fileInfo.fileSize, 1234);
EXPECT_EQ(fileInfo.recordHandle, 1);
EXPECT_EQ(fileInfo.filePath, testFilePath / "test_file.bin");
EXPECT_NE(fileInfo.fp, nullptr);
}
TEST_F(GenerateFileDescriptorPDRTest, FailureMissingEntityType)
{
const Json json = R"({ "entries": [{ "Path": "p" }]})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureEntityTypeNotNumber)
{
const Json json =
R"({ "entries": [{ "EntityType": "abc", "Path": "p" }]})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureInvalidEntityType)
{
const Json json =
R"({ "entries": [{ "EntityType": 8, "Path": "p" }]})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureMissingPath)
{
const Json json = R"({ "entries": [{ "EntityType": 9 }]})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailurePathNotString)
{
const Json json =
R"({ "entries": [{ "EntityType": 9, "Path": 123 }]})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureMissingFileIdentifier)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": [ { "FileName": "f", "FileSize": 0 } ]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureFileIdentifierNotNumber)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": [ { "FileIdentifier": "abc", "FileName": "f", "FileSize": 0 } ]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureMissingFileName)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": [ { "FileIdentifier": 1, "FileSize": 0 } ]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureFileNameNotString)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": [ { "FileIdentifier": 1, "FileName": 123, "FileSize": 0 } ]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureMissingFileSize)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": [ { "FileIdentifier": 1, "FileName": "f" } ]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureFileSizeNotNumber)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": [ { "FileIdentifier": 1, "FileName": "f", "FileSize": "abc" } ]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureFileNameTooLong)
{
std::string longName(255, 'a');
Json json = {{"entries",
{{{"EntityType", 9},
{"Path", "p"},
{"Files",
{{{"FileIdentifier", 1},
{"FileName", longName},
{"FileSize", 0}}}}}}}};
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, FailureCannotOpenFile)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "nonexistent_dir",
"Files": [
{
"FileIdentifier": 1,
"FileName": "nonexistent_file.bin",
"FileSize": 0
}
]
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, CornerCaseEmptyEntries)
{
const Json json = R"({ "entries": [] })"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}
TEST_F(GenerateFileDescriptorPDRTest, CornerCaseEmptyFiles)
{
const Json json = R"(
{
"entries": [
{
"EntityType": 9,
"Path": "p",
"Files": []
}
]
})"_json;
generateFileDescriptorPDR(json, "", {}, fileIdentifierToFileInfo,
recordHandleToFileInfo, repo);
EXPECT_TRUE(fileIdentifierToFileInfo.empty());
EXPECT_TRUE(recordHandleToFileInfo.empty());
}