Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_container_collector.cpp
Go to the documentation of this file.
1// BSD 3-Clause License
2// Copyright (c) 2021-2025, 🍀☀🌕🌥 🌊
3// See the LICENSE file in the project root for full license information.
4
5#include <gtest/gtest.h>
7
8namespace kcenon {
9namespace monitoring {
10namespace {
11
12// Test fixture for container collector tests
13class ContainerCollectorTest : public ::testing::Test {
14 protected:
15 void SetUp() override {
16 collector_ = std::make_unique<container_collector>();
17 std::unordered_map<std::string, std::string> config;
18 collector_->initialize(config);
19 }
20
21 std::unique_ptr<container_collector> collector_;
22};
23
24// Test basic initialization
25TEST_F(ContainerCollectorTest, InitializesSuccessfully) {
26 EXPECT_EQ(collector_->name(), "container");
27}
28
29// Test metric types returned
30TEST_F(ContainerCollectorTest, ReturnsCorrectMetricTypes) {
31 auto metric_types = collector_->get_metric_types();
32
33 // Should include all expected container metrics
34 EXPECT_FALSE(metric_types.empty());
35
36 // Check for expected metric types
37 auto contains = [&metric_types](const std::string& type) {
38 return std::find(metric_types.begin(), metric_types.end(), type) != metric_types.end();
39 };
40
41 EXPECT_TRUE(contains("container_cpu_usage_percent"));
42 EXPECT_TRUE(contains("container_memory_usage_bytes"));
43 EXPECT_TRUE(contains("container_memory_limit_bytes"));
44 EXPECT_TRUE(contains("container_pids_current"));
45}
46
47// Test configuration options
48TEST_F(ContainerCollectorTest, ConfigurationOptions) {
49 auto custom_collector = std::make_unique<container_collector>();
50
51 std::unordered_map<std::string, std::string> config = {
52 {"enabled", "true"}, {"collect_network", "true"}, {"collect_blkio", "true"}};
53
54 EXPECT_TRUE(custom_collector->initialize(config));
55}
56
57// Test disable collector
58TEST_F(ContainerCollectorTest, CanBeDisabled) {
59 auto custom_collector = std::make_unique<container_collector>();
60
61 std::unordered_map<std::string, std::string> config = {{"enabled", "false"}};
62
63 custom_collector->initialize(config);
64
65 // When disabled, collect should return empty
66 auto metrics = custom_collector->collect();
67 EXPECT_TRUE(metrics.empty());
68}
69
70// Test statistics
71TEST_F(ContainerCollectorTest, TracksStatistics) {
72 auto stats = collector_->get_statistics();
73
74 // Should have expected statistics keys
75 EXPECT_TRUE(stats.find("collection_count") != stats.end());
76 EXPECT_TRUE(stats.find("collection_errors") != stats.end());
77 EXPECT_TRUE(stats.find("containers_found") != stats.end());
78
79 // Initial values should be 0
80 EXPECT_EQ(stats["collection_count"], 0.0);
81 EXPECT_EQ(stats["collection_errors"], 0.0);
82}
83
84// Test collect returns metrics (graceful degradation outside containers)
85TEST_F(ContainerCollectorTest, CollectReturnsMetrics) {
86 auto metrics = collector_->collect();
87
88 // Outside of a container environment, this may return empty metrics
89 // This is expected behavior - graceful degradation
90 auto stats = collector_->get_statistics();
91 EXPECT_GE(stats["collection_count"], 0.0);
92}
93
94// Test get_last_metrics
95TEST_F(ContainerCollectorTest, GetLastMetrics) {
96 collector_->collect();
97 auto last_metrics = collector_->get_last_metrics();
98
99 // Should return vector (may be empty if not in container)
100 // No assertion - just verify it doesn't crash
101 (void)last_metrics;
102}
103
104// Test container_metrics structure
105TEST(ContainerMetricsTest, DefaultInitialization) {
106 container_metrics metrics;
107
108 EXPECT_TRUE(metrics.container_id.empty());
109 EXPECT_TRUE(metrics.container_name.empty());
110 EXPECT_EQ(metrics.cpu_usage_percent, 0.0);
111 EXPECT_EQ(metrics.memory_usage_bytes, 0);
112 EXPECT_EQ(metrics.network_rx_bytes, 0);
113 EXPECT_EQ(metrics.blkio_read_bytes, 0);
114 EXPECT_EQ(metrics.pids_current, 0);
115}
116
117// Test container_info structure
118TEST(ContainerInfoTest, DefaultInitialization) {
119 container_info info;
120
121 EXPECT_TRUE(info.container_id.empty());
122 EXPECT_TRUE(info.container_name.empty());
123 EXPECT_TRUE(info.cgroup_path.empty());
124 EXPECT_FALSE(info.is_running);
125}
126
127// Test cgroup_version enum
128TEST(CgroupVersionTest, EnumValues) {
129 EXPECT_EQ(static_cast<uint8_t>(cgroup_version::none), 0);
130 EXPECT_EQ(static_cast<uint8_t>(cgroup_version::v1), 1);
131 EXPECT_EQ(static_cast<uint8_t>(cgroup_version::v2), 2);
132}
133
134// Test container_info_collector platform detection
135TEST(ContainerInfoCollectorTest, BasicFunctionality) {
136 container_info_collector collector;
137
138 // Test cgroup version detection (should not crash)
139 auto version = collector.detect_cgroup_version();
140
141 // On non-Linux platforms, should return none
142#if !defined(__linux__)
143 EXPECT_EQ(version, cgroup_version::none);
144#else
145 // On Linux, may return v1, v2, or none depending on system
146 EXPECT_TRUE(version == cgroup_version::none || version == cgroup_version::v1 ||
147 version == cgroup_version::v2);
148#endif
149}
150
151// Test containerized detection
152TEST(ContainerInfoCollectorTest, IsContainerizedDetection) {
153 container_info_collector collector;
154
155 // Should not crash - returns true/false based on environment
156 bool is_containerized = collector.is_containerized();
157 (void)is_containerized; // Use the variable to avoid warning
158}
159
160// Test container enumeration (graceful degradation)
161TEST(ContainerInfoCollectorTest, EnumerateContainers) {
162 container_info_collector collector;
163
164 auto containers = collector.enumerate_containers();
165
166 // Should return a vector (may be empty if not in container environment)
167 // No assertion on size - just verify it doesn't crash
168 (void)containers;
169}
170
171} // namespace
172} // namespace monitoring
173} // namespace kcenon
Container metrics collector for Docker/cgroup monitoring.
@ v2
Unified cgroups v2 hierarchy.
@ none
Not in a cgroup or not Linux.
@ info
Informational, no action required.
TEST(AdapterFunctionalityTest, WorksWithoutLogger)
Test Scenario 1: Adapter with NULL logger.
TEST_F(AdaptiveMonitoringTest, AdaptiveConfigDefaults)
std::unique_ptr< battery_collector > collector_