Skip to content

Commit

Permalink
17299 Windows agent reports the version of custom exe plugin as n/a
Browse files Browse the repository at this point in the history
For any exe plugin the version is reported as n/a.

Change-Id: Iebbe84bb69b14d8ce5ba2bedd078f525d43da2be
  • Loading branch information
s-kipnis committed Jan 14, 2025
1 parent 37a726f commit 7c2ec9c
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 34 deletions.
10 changes: 10 additions & 0 deletions .werks/17299
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Title: Windows agent reports the version of custom exe plugin as n/a
Class: feature
Compatible: compat
Component: checks
Date: 1736844398
Edition: cre
Level: 1
Version: 2.2.0p39

For any exe plugin the version is reported as n/a.
89 changes: 55 additions & 34 deletions agents/wnx/src/engine/providers/agent_plugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,29 +18,38 @@ using namespace std::string_literals;

namespace cma::provider {
namespace {
enum class FileType { ps1, cmd, vbs, py, other };
enum class FileType { ps1, cmd, vbs, py, exe, other };

size_t GetLength(std::ifstream &ifs) {
ifs.seekg(0, std::ios_base::end);
const auto length = ifs.tellg();
ifs.seekg(0, std::ios_base::beg);
return static_cast<size_t>(length);
std::optional<size_t> GetLength(std::ifstream &ifs) {
try {
ifs.seekg(0, std::ios_base::end);
const auto length = ifs.tellg();
ifs.seekg(0, std::ios_base::beg);
return {static_cast<size_t>(length)};
} catch (const std::ios_base::failure &e) {
XLOG::d("Can't get length exception '{}'", e.what());
return {};
}
}

std::string ReadFileToString(const fs::path &file) {
std::string ret;
std::ifstream ifs(file, std::ifstream::in);
if (ifs) {
const auto length = GetLength(ifs);
ret.resize(length);
ifs.read(ret.data(), static_cast<std::streamsize>(length));
if (ifs.good() || ifs.eof()) {
return ret;
}
XLOG::d("Can't read '{}'", file.u8string());
} else {
if (!ifs) {
XLOG::d("Can't open '{}'", file.u8string());
return {};
}
const auto length = GetLength(ifs);
if (!length.has_value()) {
return {};
}

ret.resize(*length);
ifs.read(ret.data(), static_cast<std::streamsize>(*length));
if (ifs.good() || ifs.eof()) {
return ret;
}
XLOG::d("Can't read '{}'", file.u8string());
return {};
}

Expand All @@ -55,6 +64,7 @@ std::string Marker(FileType file_type) {
case FileType::py:
return "__version__ = "s;
case FileType::other:
case FileType::exe:
return {};
}
// unreachable
Expand All @@ -63,24 +73,36 @@ std::string Marker(FileType file_type) {

std::string FindVersionInfo(const fs::path &file, FileType file_type) {
try {
std::string ret = ReadFileToString(file);
auto marker = Marker(file_type);
if (marker.empty()) {
XLOG::t("This file type '{}' is not supported", file);
return {};
}
const auto offset = ret.find(marker);
if (offset == std::string::npos) {
return fmt::format("{}:CMK_VERSION = unversioned", file);
}
const auto end = ret.find('\n', offset);
if (end == std::string::npos) {
XLOG::t("This file type '{}' strange!", file);
return {};
switch (file_type) {
case FileType::exe:
return fmt::format("{}:CMK_VERSION = n/a", file);
case FileType::ps1:
case FileType::cmd: // also bat
case FileType::py:
case FileType::vbs: {
const auto ret = ReadFileToString(file);
const auto marker = Marker(file_type);
if (marker.empty()) {
XLOG::t("This file type '{}' is not supported", file);
return {};
}
const auto offset = ret.find(marker);
if (offset == std::string::npos) {
return fmt::format("{}:CMK_VERSION = unversioned", file);
}
const auto end = ret.find('\n', offset);
if (end == std::string::npos) {
XLOG::t("This file type '{}' strange!", file);
return {};
}
auto version_text = ret.substr(offset + marker.length(),
end - offset - marker.length());
return fmt::format("{}:CMK_VERSION = {}", file, version_text);
}
case FileType::other:
XLOG::t("This file type '{}' not supported", file);
return {};
}
auto version_text = ret.substr(offset + marker.length(),
end - offset - marker.length());
return fmt::format("{}:CMK_VERSION = {}", file, version_text);

} catch (const std::exception &e) {
XLOG::d("Can't access '{}', exception '{}'", file.u8string(), e.what());
Expand All @@ -102,8 +124,7 @@ std::vector<std::string> ScanDir(const fs::path &dir) {
const std::unordered_map<std::wstring, FileType> map = {
{L".ps1", FileType::ps1}, {L".cmd", FileType::cmd},
{L".bat", FileType::cmd}, {L".vbs", FileType::vbs},
{L".py", FileType::py},
};
{L".py", FileType::py}, {L".exe", FileType::exe}};
const auto type =
map.contains(extension) ? map.at(extension) : FileType::other;
auto version_text = FindVersionInfo(file, type);
Expand Down
21 changes: 21 additions & 0 deletions agents/wnx/watest/test-section_agent_plugins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,27 @@ TEST_F(AgentPluginsTest, File) {
}));
}

TEST_F(AgentPluginsTest, JustExe) {
auto ps_file = fs::path{cfg::GetUserPluginsDir()} / "empty.exe";
tst::CreateTextFile(ps_file, "");
auto rows = getRows();
ASSERT_EQ(rows.size(), 4);
EXPECT_TRUE(std::ranges::any_of(rows, [&](const std::string &row) {
return row == fmt::format("{}:CMK_VERSION = n/a", ps_file);
}));
}

TEST_F(AgentPluginsTest, DISABLED_Exe) {
// Test is disabled because we need a binary to build: not appropriate for
// unit testing. You may enable this test manually
auto v_file = tst::GetSolutionRoot() / "test_files" / "tools" / "v" /
"target" / "release" / "v.exe";
fs::copy(v_file, fs::path{cfg::GetUserPluginsDir()} / "mk-sql.exe");
auto rows = getRows();
ASSERT_EQ(rows.size(), 4);
EXPECT_TRUE(rows[3].ends_with("v.exe:CMK_VERSION = \"0.1.0\""));
}

TEST_F(AgentPluginsTest, FileMix) {
const std::vector<std::tuple<fs::path, std::string, std::string>>
to_create = {
Expand Down

0 comments on commit 7c2ec9c

Please sign in to comment.