Files

171 lines
4.4 KiB
C++
Raw Permalink Normal View History

2026-01-22 15:51:03 -05:00
#include <gtest/gtest.h>
2026-04-07 14:05:04 -04:00
#include "process_stats.h"
#include <nlohmann/json.hpp>
2026-04-07 14:05:04 -04:00
#include <chrono>
#include <csignal>
2026-01-22 15:51:03 -05:00
#include <cstring>
2026-04-07 14:05:04 -04:00
#include <thread>
#include <unordered_map>
#include <vector>
2026-01-22 15:51:03 -05:00
#include <unistd.h>
2026-04-07 14:05:04 -04:00
#include <sys/wait.h>
2026-01-22 15:51:03 -05:00
class ProcessStatsTest : public ::testing::Test {
protected:
2026-04-07 14:05:04 -04:00
std::vector<pid_t> m_childPids;
2026-03-24 16:50:23 -04:00
2026-04-07 14:05:04 -04:00
void SetUp() override
{
2026-03-24 16:50:23 -04:00
ProcessStats::clearHistory();
2026-01-22 15:51:03 -05:00
}
2026-03-24 16:50:23 -04:00
2026-04-07 14:05:04 -04:00
void TearDown() override
{
2026-03-24 16:50:23 -04:00
ProcessStats::clearHistory();
2026-04-07 14:05:04 -04:00
for (pid_t pid : m_childPids) {
if (pid > 0) {
kill(pid, SIGTERM);
int st = 0;
waitpid(pid, &st, 0);
2026-01-22 15:51:03 -05:00
}
}
2026-04-07 14:05:04 -04:00
m_childPids.clear();
2026-01-22 15:51:03 -05:00
}
};
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_ReturnsZeroedStatsForNegativePid)
{
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(-1);
2026-01-22 15:51:03 -05:00
EXPECT_EQ(stats.cpuPercent, 0.0);
EXPECT_EQ(stats.cpuTimeSeconds, 0.0);
EXPECT_EQ(stats.memoryMB, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_ReturnsZeroedStatsForZeroPid)
{
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(0);
2026-01-22 15:51:03 -05:00
EXPECT_EQ(stats.cpuPercent, 0.0);
EXPECT_EQ(stats.cpuTimeSeconds, 0.0);
EXPECT_EQ(stats.memoryMB, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_ReturnsValidStatsForCurrentProcess)
{
int64_t currentPid = static_cast<int64_t>(getpid());
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(currentPid);
2026-01-22 15:51:03 -05:00
EXPECT_GT(stats.memoryMB, 0.0);
EXPECT_GE(stats.cpuTimeSeconds, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_MemoryIsNonNegative)
{
int64_t currentPid = static_cast<int64_t>(getpid());
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(currentPid);
2026-01-22 15:51:03 -05:00
EXPECT_GE(stats.memoryMB, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_CpuTimeIsNonNegative)
{
int64_t currentPid = static_cast<int64_t>(getpid());
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(currentPid);
2026-01-22 15:51:03 -05:00
EXPECT_GE(stats.cpuTimeSeconds, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_CpuPercentIsZeroOnFirstCall)
{
int64_t currentPid = static_cast<int64_t>(getpid());
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(currentPid);
2026-01-22 15:51:03 -05:00
EXPECT_EQ(stats.cpuPercent, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetProcessStats_CpuPercentUpdatesOnSecondCall)
{
int64_t currentPid = static_cast<int64_t>(getpid());
2026-03-24 16:50:23 -04:00
2026-01-22 15:51:03 -05:00
ProcessStats::getProcessStats(currentPid);
2026-03-24 16:50:23 -04:00
2026-01-22 15:51:03 -05:00
volatile double sum = 0.0;
for (int i = 0; i < 1000000; ++i) {
sum += i * 0.1;
}
2026-03-24 16:50:23 -04:00
2026-04-07 14:05:04 -04:00
usleep(10000);
2026-03-24 16:50:23 -04:00
ProcessStats::ProcessStatsData stats = ProcessStats::getProcessStats(currentPid);
2026-01-22 15:51:03 -05:00
EXPECT_GE(stats.cpuPercent, 0.0);
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetModuleStats_ReturnsEmptyArrayWhenNoPlugins)
{
std::unordered_map<std::string, int64_t> processes;
2026-03-24 16:50:23 -04:00
char* result = ProcessStats::getModuleStats(processes);
2026-01-22 15:51:03 -05:00
ASSERT_NE(result, nullptr);
2026-03-24 16:50:23 -04:00
nlohmann::json doc = nlohmann::json::parse(result);
2026-03-24 16:50:23 -04:00
EXPECT_TRUE(doc.is_array());
2026-04-07 14:05:04 -04:00
EXPECT_EQ(doc.size(), 0u);
2026-03-24 16:50:23 -04:00
2026-01-22 15:51:03 -05:00
delete[] result;
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetModuleStats_ReturnsNonNullPointer)
{
std::unordered_map<std::string, int64_t> processes;
2026-03-24 16:50:23 -04:00
char* result = ProcessStats::getModuleStats(processes);
2026-01-22 15:51:03 -05:00
ASSERT_NE(result, nullptr);
2026-03-24 16:50:23 -04:00
2026-01-22 15:51:03 -05:00
delete[] result;
}
2026-04-07 14:05:04 -04:00
TEST_F(ProcessStatsTest, GetModuleStats_ReturnsValidJsonStructure)
{
pid_t pid = fork();
ASSERT_GE(pid, 0);
if (pid == 0) {
execlp("sleep", "sleep", "2", nullptr);
_exit(127);
}
m_childPids.push_back(pid);
2026-03-24 16:50:23 -04:00
2026-04-07 14:05:04 -04:00
std::this_thread::sleep_for(std::chrono::milliseconds(50));
2026-03-24 16:50:23 -04:00
2026-04-07 14:05:04 -04:00
std::unordered_map<std::string, int64_t> processes;
processes["test_plugin"] = static_cast<int64_t>(pid);
2026-03-24 16:50:23 -04:00
char* result = ProcessStats::getModuleStats(processes);
2026-01-22 15:51:03 -05:00
ASSERT_NE(result, nullptr);
2026-03-24 16:50:23 -04:00
nlohmann::json doc = nlohmann::json::parse(result);
2026-03-24 16:50:23 -04:00
EXPECT_TRUE(doc.is_array());
2026-04-07 14:05:04 -04:00
ASSERT_EQ(doc.size(), 1u);
2026-03-24 16:50:23 -04:00
auto moduleObj = doc[0];
2026-01-22 15:51:03 -05:00
EXPECT_TRUE(moduleObj.contains("name"));
EXPECT_TRUE(moduleObj.contains("cpu_percent"));
EXPECT_TRUE(moduleObj.contains("cpu_time_seconds"));
EXPECT_TRUE(moduleObj.contains("memory_mb"));
2026-03-24 16:50:23 -04:00
EXPECT_EQ(moduleObj["name"].get<std::string>(), "test_plugin");
EXPECT_GE(moduleObj["cpu_percent"].get<double>(), 0.0);
EXPECT_GE(moduleObj["cpu_time_seconds"].get<double>(), 0.0);
EXPECT_GE(moduleObj["memory_mb"].get<double>(), 0.0);
2026-03-24 16:50:23 -04:00
2026-01-22 15:51:03 -05:00
delete[] result;
}