Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_metrics_provider.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 platform {
11namespace {
12
13class MetricsProviderTest : public ::testing::Test {
14 protected:
15 void SetUp() override {
17 }
18
19 std::unique_ptr<metrics_provider> provider_;
20};
21
22// Test factory creates appropriate provider
23TEST_F(MetricsProviderTest, FactoryCreatesProvider) {
24#if defined(__linux__) || defined(__APPLE__) || defined(_WIN32)
25 ASSERT_NE(provider_, nullptr);
26#else
27 // On unsupported platforms, provider may be nullptr
28 GTEST_SKIP() << "Unsupported platform";
29#endif
30}
31
32// Test platform name
33TEST_F(MetricsProviderTest, ReturnsCorrectPlatformName) {
34 if (!provider_) {
35 GTEST_SKIP() << "Provider not available on this platform";
36 }
37
38 std::string platform_name = provider_->get_platform_name();
39 EXPECT_FALSE(platform_name.empty());
40
41#if defined(__linux__)
42 EXPECT_EQ(platform_name, "linux");
43#elif defined(__APPLE__)
44 EXPECT_EQ(platform_name, "macos");
45#elif defined(_WIN32)
46 EXPECT_EQ(platform_name, "windows");
47#endif
48}
49
50// Test uptime info
51TEST_F(MetricsProviderTest, GetUptimeReturnsValidInfo) {
52 if (!provider_) {
53 GTEST_SKIP() << "Provider not available on this platform";
54 }
55
56 auto uptime = provider_->get_uptime();
57
58 // Uptime should be available on all supported platforms
59 EXPECT_TRUE(uptime.available);
60 EXPECT_GT(uptime.uptime_seconds, 0);
61}
62
63// Test context switches
64TEST_F(MetricsProviderTest, GetContextSwitchesReturnsInfo) {
65 if (!provider_) {
66 GTEST_SKIP() << "Provider not available on this platform";
67 }
68
69 auto ctx_switches = provider_->get_context_switches();
70
71 // On most systems, we should be able to get context switch info
72 // The availability flag indicates if the metric was successfully retrieved
73 if (ctx_switches.available) {
74 EXPECT_GT(ctx_switches.total_switches, 0ULL);
75 }
76}
77
78// Test file descriptor stats
79TEST_F(MetricsProviderTest, GetFdStatsReturnsInfo) {
80 if (!provider_) {
81 GTEST_SKIP() << "Provider not available on this platform";
82 }
83
84 auto fd_stats = provider_->get_fd_stats();
85
86 if (fd_stats.available) {
87 // There should be at least some open file descriptors
88 EXPECT_GT(fd_stats.open_fds, 0ULL);
89 EXPECT_GT(fd_stats.max_fds, 0ULL);
90 EXPECT_GE(fd_stats.usage_percent, 0.0);
91 EXPECT_LE(fd_stats.usage_percent, 100.0);
92 }
93}
94
95// Test inode stats
96TEST_F(MetricsProviderTest, GetInodeStatsReturnsInfo) {
97 if (!provider_) {
98 GTEST_SKIP() << "Provider not available on this platform";
99 }
100
101 auto inode_stats = provider_->get_inode_stats();
102
103 // Should return at least one filesystem on most systems
104 // (though some systems may have no traditional filesystems)
105 for (const auto& inode : inode_stats) {
106 if (inode.available) {
107 EXPECT_GT(inode.total_inodes, 0ULL);
108 }
109 }
110}
111
112// Test TCP states
113TEST_F(MetricsProviderTest, GetTcpStatesReturnsInfo) {
114 if (!provider_) {
115 GTEST_SKIP() << "Provider not available on this platform";
116 }
117
118 auto tcp_states = provider_->get_tcp_states();
119
120 if (tcp_states.available) {
121 // Total should be sum of all states
122 // At minimum, should have at least localhost listening sockets
123 EXPECT_GE(tcp_states.total, tcp_states.established);
124 }
125}
126
127// Test socket buffer stats
128TEST_F(MetricsProviderTest, GetSocketBufferStatsReturnsInfo) {
129 if (!provider_) {
130 GTEST_SKIP() << "Provider not available on this platform";
131 }
132
133 auto socket_stats = provider_->get_socket_buffer_stats();
134
135 // Just verify it doesn't crash and returns valid structure
136 if (socket_stats.available) {
137 // Buffer sizes should be non-negative
138 EXPECT_GE(socket_stats.rx_buffer_used, 0ULL);
139 EXPECT_GE(socket_stats.tx_buffer_used, 0ULL);
140 }
141}
142
143// Test interrupt stats
144TEST_F(MetricsProviderTest, GetInterruptStatsReturnsInfo) {
145 if (!provider_) {
146 GTEST_SKIP() << "Provider not available on this platform";
147 }
148
149 auto interrupt_stats = provider_->get_interrupt_stats();
150
151 // Should return at least total interrupts on Linux
152 for (const auto& irq : interrupt_stats) {
153 if (irq.available && irq.name == "total_interrupts") {
154 EXPECT_GT(irq.count, 0ULL);
155 }
156 }
157}
158
159// Test security info
160TEST_F(MetricsProviderTest, GetSecurityInfoReturnsInfo) {
161 if (!provider_) {
162 GTEST_SKIP() << "Provider not available on this platform";
163 }
164
165 auto security_info = provider_->get_security_info();
166
167 // Just verify it returns without crashing
168 // The availability and values depend on system configuration
169 SUCCEED();
170}
171
172// Test battery availability check
173TEST_F(MetricsProviderTest, BatteryAvailabilityCheck) {
174 if (!provider_) {
175 GTEST_SKIP() << "Provider not available on this platform";
176 }
177
178 // This should not crash regardless of whether battery is present
179 bool battery_available = provider_->is_battery_available();
180
181 // If battery is available, readings should return data
182 if (battery_available) {
183 auto readings = provider_->get_battery_readings();
184 EXPECT_FALSE(readings.empty());
185 }
186}
187
188// Test temperature availability check
189TEST_F(MetricsProviderTest, TemperatureAvailabilityCheck) {
190 if (!provider_) {
191 GTEST_SKIP() << "Provider not available on this platform";
192 }
193
194 // This should not crash regardless of whether sensors are present
195 bool temp_available = provider_->is_temperature_available();
196
197 // If temperature is available, readings should return data
198 if (temp_available) {
199 auto readings = provider_->get_temperature_readings();
200#if defined(_WIN32)
201 // On Windows, is_temperature_available() returns true when the WMI
202 // ROOT\WMI connection succeeds, but CI VMs typically have no thermal
203 // zones so get_temperature_readings() may return an empty vector.
204 // Just verify the call does not crash.
205 SUCCEED();
206#else
207 EXPECT_FALSE(readings.empty());
208#endif
209 }
210}
211
212// Test power availability check
213TEST_F(MetricsProviderTest, PowerAvailabilityCheck) {
214 if (!provider_) {
215 GTEST_SKIP() << "Provider not available on this platform";
216 }
217
218 // This should not crash regardless of whether power info is available
219 bool power_available = provider_->is_power_available();
220
221 // If power is available, info should have valid data
222 if (power_available) {
223 auto power_info = provider_->get_power_info();
224 EXPECT_TRUE(power_info.available);
225 }
226}
227
228// Test GPU availability check
229TEST_F(MetricsProviderTest, GpuAvailabilityCheck) {
230 if (!provider_) {
231 GTEST_SKIP() << "Provider not available on this platform";
232 }
233
234 // This should not crash regardless of whether GPU is present
235 bool gpu_available = provider_->is_gpu_available();
236
237 // If GPU is available, info should return data
238 if (gpu_available) {
239 auto gpu_info = provider_->get_gpu_info();
240 EXPECT_FALSE(gpu_info.empty());
241 }
242}
243
244// Test that multiple calls return consistent results
245TEST_F(MetricsProviderTest, MultipleCallsAreConsistent) {
246 if (!provider_) {
247 GTEST_SKIP() << "Provider not available on this platform";
248 }
249
250 // Get uptime twice - should be close
251 auto uptime1 = provider_->get_uptime();
252 auto uptime2 = provider_->get_uptime();
253
254 if (uptime1.available && uptime2.available) {
255 // Uptime should not decrease
256 EXPECT_GE(uptime2.uptime_seconds, uptime1.uptime_seconds);
257 // Should be within 1 second of each other
258 EXPECT_LE(uptime2.uptime_seconds - uptime1.uptime_seconds, 1);
259 }
260}
261
262} // namespace
263} // namespace platform
264} // namespace monitoring
265} // namespace kcenon
static std::unique_ptr< metrics_provider > create()
Create a platform-specific metrics provider.
Platform abstraction layer for system metrics collection.
@ platform
Platform/system power domain.
TEST_F(AdaptiveMonitoringTest, AdaptiveConfigDefaults)
std::unique_ptr< metrics_provider > provider_