blob: c1743dd23a789bcfe00336bab91726399cbf8649 [file] [log] [blame]
// SPDX-License-Identifier: Apache-2.0
#include "../functions.hpp"
#include <stdlib.h>
#include <array>
#include <cerrno>
#include <filesystem>
#include <fstream>
#include <map>
#include <string>
#include <vector>
#include <gtest/gtest.h>
using namespace std::string_literals;
TEST(GetExtensionsForIbmCompatibleSystem, testSingleMatch)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-foo"s, {".EXT"s}},
}};
std::vector<std::string> compatibleSystem{"system-foo"s}, extensions;
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".EXT"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testSingleNoMatchNoModify)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-bar"s, {".EXT"s}},
}};
std::vector<std::string> compatibleSystem{"system-foo"s},
extensions{"foo"s};
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_FALSE(found);
EXPECT_EQ(extensions, std::vector<std::string>{"foo"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testMatchModify)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-bar"s, {".BAR"s}},
{"system-foo"s, {".FOO"s}},
}};
std::vector<std::string> compatibleSystem{"system-foo"s},
extensions{"foo"s};
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testEmpty)
{
std::map<std::string, std::vector<std::string>> extensionMap;
std::vector<std::string> compatibleSystem{"system-foo"s},
extensions{"foo"s};
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_FALSE(found);
EXPECT_EQ(extensions, std::vector<std::string>{"foo"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testEmptyEmpty)
{
std::map<std::string, std::vector<std::string>> extensionMap;
std::vector<std::string> compatibleSystem, extensions{"foo"s};
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_FALSE(found);
EXPECT_EQ(extensions, std::vector<std::string>{"foo"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testMatchMultiCompat)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-bar"s, {".BAR"s}},
{"system-foo"s, {".FOO"s}},
}};
std::vector<std::string> compatibleSystem{"system-foo"s, "system"},
extensions;
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-bar"s, {".BAR"s}},
{"system-foo"s, {".FOO"s}},
}};
std::vector<std::string> compatibleSystem{"system-foo"s, "system-bar"},
extensions;
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat2)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-foo"s, {".FOO"s}},
{"system-bar"s, {".BAR"s}},
}};
std::vector<std::string> compatibleSystem{"system-foo"s, "system-bar"},
extensions;
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".FOO"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat3)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-bar"s, {".BAR"s}},
{"system-foo"s, {".FOO"s}},
}};
std::vector<std::string> compatibleSystem{"system-bar", "system-foo"s},
extensions;
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".BAR"s});
}
TEST(GetExtensionsForIbmCompatibleSystem, testMultiMatchMultiCompat4)
{
std::map<std::string, std::vector<std::string>> extensionMap{{
{"system-foo"s, {".FOO"s}},
{"system-bar"s, {".BAR"s}},
}};
std::vector<std::string> compatibleSystem{"system-bar", "system-foo"s},
extensions;
auto found =
functions::process_hostfirmware::getExtensionsForIbmCompatibleSystem(
extensionMap, compatibleSystem, extensions);
EXPECT_TRUE(found);
EXPECT_EQ(extensions, std::vector<std::string>{".BAR"s});
}
TEST(MaybeCall, noMatch)
{
bool called = false;
auto callback = [&called](const auto&) { called = true; };
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces{{
{"foo"s, {{"bar"s, std::vector<std::string>{"foo"s}}}},
}};
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::move(callback));
EXPECT_FALSE(found);
EXPECT_FALSE(called);
}
TEST(MaybeCall, match)
{
bool called = false;
std::vector<std::string> sys;
auto callback = [&called, &sys](const auto& system) {
sys = system;
called = true;
};
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces{{
{"xyz.openbmc_project.Inventory.Decorator.Compatible"s,
{{"Names"s, std::vector<std::string>{"foo"s}}}},
}};
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::move(callback));
EXPECT_TRUE(found);
EXPECT_TRUE(called);
EXPECT_EQ(sys, std::vector<std::string>{"foo"s});
}
TEST(MaybeCall, missingNames)
{
bool called = false;
auto callback = [&called](const auto&) { called = true; };
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces{{
{"xyz.openbmc_project.Inventory.Decorator.Compatible"s, {}},
}};
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::move(callback));
EXPECT_TRUE(found);
EXPECT_FALSE(called);
}
TEST(MaybeCall, emptyCallbackFound)
{
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces{{
{"xyz.openbmc_project.Inventory.Decorator.Compatible"s,
{{"Names"s, std::vector<std::string>{"foo"s}}}},
}};
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::function<void(std::vector<std::string>)>());
EXPECT_TRUE(found);
}
TEST(MaybeCall, emptyCallbackNotFound)
{
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces{{
{"foo"s, {{"Names"s, std::vector<std::string>{"foo"s}}}},
}};
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::function<void(std::vector<std::string>)>());
EXPECT_FALSE(found);
}
TEST(MaybeCall, emptyInterfaces)
{
bool called = false;
auto callback = [&called](const auto&) { called = true; };
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces;
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::move(callback));
EXPECT_FALSE(found);
EXPECT_FALSE(called);
}
TEST(MaybeCall, emptyInterfacesEmptyCallback)
{
std::map<std::string,
std::map<std::string, std::variant<std::vector<std::string>>>>
interfaces;
auto found = functions::process_hostfirmware::maybeCall(
interfaces, std::function<void(std::vector<std::string>)>());
EXPECT_FALSE(found);
}
TEST(WriteLink, testLinkNoDelete)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
bool called = false;
auto callback = [&called](const auto&, auto&) { called = true; };
std::filesystem::path linkPath = workdir / "link";
std::filesystem::path targetPath = workdir / "target";
std::ofstream link{linkPath};
functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
callback);
std::filesystem::remove_all(workdir);
EXPECT_FALSE(called);
}
TEST(WriteLink, testLinkDelete)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
bool called = false;
auto callback = [&called](const auto&, auto&) { called = true; };
auto linkPath = workdir / "link";
auto targetPath = workdir / "target";
std::ofstream link{linkPath}, target{targetPath};
functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
callback);
std::filesystem::remove_all(workdir);
EXPECT_FALSE(called);
}
TEST(WriteLink, testLinkFailDeleteDir)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
std::error_code ec;
std::filesystem::path callbackPath;
auto callback = [&ec, &callbackPath](const auto& p, auto& _ec) {
ec = _ec;
callbackPath = p;
};
auto targetPath = workdir / "target";
std::filesystem::create_directory(targetPath);
auto linkPath = workdir / "link";
auto filePath = targetPath / "file";
std::ofstream link{linkPath}, file{filePath};
functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
callback);
std::filesystem::remove_all(workdir);
EXPECT_EQ(ec.value(), ENOTEMPTY);
EXPECT_EQ(callbackPath, targetPath);
}
TEST(WriteLink, testLinkPathNotExist)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
std::error_code ec;
std::filesystem::path callbackPath;
auto callback = [&ec, &callbackPath](const auto& p, auto& _ec) {
ec = _ec;
callbackPath = p;
};
auto linkPath = workdir / "baz";
auto targetPath = workdir / "foo/bar/foo";
functions::process_hostfirmware::writeLink(linkPath.filename(), targetPath,
callback);
std::filesystem::remove_all(workdir);
EXPECT_EQ(ec.value(), ENOENT);
EXPECT_EQ(callbackPath, targetPath);
}
TEST(FindLinks, testNoLinks)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
bool callbackCalled = false, errorCallbackCalled = false;
auto callback = [&callbackCalled](const auto&, const auto&, const auto&) {
callbackCalled = true;
};
auto errorCallback = [&errorCallbackCalled](const auto&, auto&) {
errorCallbackCalled = true;
};
std::vector<std::string> extensions;
functions::process_hostfirmware::findLinks(workdir, extensions,
errorCallback, callback);
std::filesystem::remove_all(workdir);
EXPECT_FALSE(errorCallbackCalled);
EXPECT_FALSE(callbackCalled);
}
TEST(FindLinks, testOneFound)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
std::filesystem::path callbackPath, callbackLink;
bool errorCallbackCalled = false;
auto callback = [&callbackPath, &callbackLink](
const auto& p1, const auto& p2, const auto&) {
callbackPath = p1;
callbackLink = p2;
};
auto errorCallback = [&errorCallbackCalled](const auto&, auto&) {
errorCallbackCalled = true;
};
auto filePath = workdir / "foo.foo";
std::ofstream file{filePath};
std::vector<std::string> extensions{".foo"s};
functions::process_hostfirmware::findLinks(workdir, extensions,
errorCallback, callback);
std::filesystem::remove_all(workdir);
EXPECT_FALSE(errorCallbackCalled);
EXPECT_EQ(callbackLink, workdir / "foo");
EXPECT_EQ(callbackPath, filePath.filename());
}
TEST(FindLinks, testNoExtensions)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
std::filesystem::path callbackPath, callbackLink;
bool errorCallbackCalled = false, callbackCalled = false;
auto callback = [&callbackCalled](const auto&, const auto&, const auto&) {
callbackCalled = true;
};
auto errorCallback = [&errorCallbackCalled](const auto&, auto&) {
errorCallbackCalled = true;
};
auto filePath = workdir / "foo.foo";
std::ofstream file{filePath};
std::vector<std::string> extensions;
functions::process_hostfirmware::findLinks(workdir, extensions,
errorCallback, callback);
std::filesystem::remove_all(workdir);
EXPECT_FALSE(errorCallbackCalled);
EXPECT_FALSE(callbackCalled);
}
TEST(FindLinks, testEnoent)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
std::error_code ec;
bool called = false;
std::filesystem::path callbackPath;
auto callback = [&called](const auto&, const auto&, const auto&) {
called = true;
};
auto errorCallback = [&ec, &callbackPath](const auto& p, auto& _ec) {
ec = _ec;
callbackPath = p;
};
std::vector<std::string> extensions;
auto dir = workdir / "baz";
functions::process_hostfirmware::findLinks(dir, extensions, errorCallback,
callback);
std::filesystem::remove_all(workdir);
EXPECT_EQ(ec.value(), ENOENT);
EXPECT_EQ(callbackPath, dir);
EXPECT_FALSE(called);
}
TEST(FindLinks, testEmptyCallback)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
bool called = false;
std::filesystem::path callbackPath;
auto errorCallback = [&called](const auto&, auto&) { called = true; };
auto filePath = workdir / "foo.foo";
std::ofstream file{filePath};
std::vector<std::string> extensions{".foo"s};
functions::process_hostfirmware::findLinks(
workdir, extensions, errorCallback,
functions::process_hostfirmware::LinkCallbackType());
std::filesystem::remove_all(workdir);
EXPECT_FALSE(called);
EXPECT_NO_THROW();
}
TEST(FindLinks, testEmptyErrorCallback)
{
std::array<char, 15> tmpl{"/tmp/tmpXXXXXX"};
std::filesystem::path workdir = mkdtemp(&tmpl[0]);
bool called = false;
auto callback = [&called](const auto&, const auto&, const auto&) {
called = true;
};
std::vector<std::string> extensions;
auto dir = workdir / "baz";
functions::process_hostfirmware::findLinks(
dir, extensions, functions::process_hostfirmware::ErrorCallbackType(),
callback);
std::filesystem::remove_all(workdir);
EXPECT_FALSE(called);
EXPECT_NO_THROW();
}