5#include <gtest/gtest.h>
15class BatteryCollectorTest :
public ::testing::Test {
17 void SetUp()
override {
18 collector_ = std::make_unique<battery_collector>();
19 std::unordered_map<std::string, std::string> config;
27TEST_F(BatteryCollectorTest, InitializesSuccessfully) {
33TEST_F(BatteryCollectorTest, ReturnsCorrectMetricTypes) {
35 EXPECT_FALSE(types.empty());
38 std::vector<std::string> expected = {
39 "battery_level_percent",
41 "battery_time_to_empty_seconds",
42 "battery_time_to_full_seconds",
43 "battery_health_percent",
44 "battery_voltage_volts",
45 "battery_power_watts",
46 "battery_cycle_count",
47 "battery_temperature_celsius"
50 for (
const auto& expected_type : expected) {
51 EXPECT_NE(std::find(types.begin(), types.end(), expected_type), types.end())
52 <<
"Missing metric type: " << expected_type;
57TEST_F(BatteryCollectorTest, ConfigurationOptions) {
58 auto collector = std::make_unique<battery_collector>();
59 std::unordered_map<std::string, std::string> config;
60 config[
"collect_health"] =
"false";
61 config[
"collect_thermal"] =
"false";
62 EXPECT_TRUE(collector->initialize(config));
64 auto stats = collector->get_statistics();
65 EXPECT_DOUBLE_EQ(stats[
"collect_health"], 0.0);
66 EXPECT_DOUBLE_EQ(stats[
"collect_thermal"], 0.0);
70TEST_F(BatteryCollectorTest, CanBeDisabled) {
71 auto collector = std::make_unique<battery_collector>();
72 std::unordered_map<std::string, std::string> config;
73 config[
"enabled"] =
"false";
74 collector->initialize(config);
76 auto metrics = collector->collect();
77 EXPECT_TRUE(metrics.empty());
79 auto stats = collector->get_statistics();
80 EXPECT_DOUBLE_EQ(stats[
"enabled"], 0.0);
84TEST_F(BatteryCollectorTest, TracksStatistics) {
90 EXPECT_GE(stats[
"collection_count"], 2.0);
91 EXPECT_GE(stats[
"collection_errors"], 0.0);
95TEST_F(BatteryCollectorTest, CollectDoesNotThrow) {
101TEST_F(BatteryCollectorTest, GetLastReadings) {
103 auto readings =
collector_->get_last_readings();
107 for (
const auto& reading : readings) {
109 auto now = std::chrono::system_clock::now();
110 auto diff = std::chrono::duration_cast<std::chrono::seconds>(now - reading.timestamp);
111 EXPECT_LT(diff.count(), 10);
116TEST_F(BatteryCollectorTest, BatteryAvailabilityCheck) {
119 EXPECT_NO_THROW(
collector_->is_battery_available());
123TEST(BatteryInfoTest, DefaultInitialization) {
125 EXPECT_TRUE(
info.id.empty());
126 EXPECT_TRUE(
info.name.empty());
127 EXPECT_TRUE(
info.path.empty());
128 EXPECT_TRUE(
info.manufacturer.empty());
129 EXPECT_TRUE(
info.model.empty());
130 EXPECT_TRUE(
info.serial.empty());
131 EXPECT_TRUE(
info.technology.empty());
135TEST(BatteryReadingTest, DefaultInitialization) {
136 battery_reading reading;
137 EXPECT_DOUBLE_EQ(reading.level_percent, 0.0);
139 EXPECT_FALSE(reading.is_charging);
140 EXPECT_FALSE(reading.ac_connected);
141 EXPECT_EQ(reading.time_to_empty_seconds, -1);
142 EXPECT_EQ(reading.time_to_full_seconds, -1);
143 EXPECT_DOUBLE_EQ(reading.design_capacity_wh, 0.0);
144 EXPECT_DOUBLE_EQ(reading.full_charge_capacity_wh, 0.0);
145 EXPECT_DOUBLE_EQ(reading.current_capacity_wh, 0.0);
146 EXPECT_DOUBLE_EQ(reading.health_percent, 0.0);
147 EXPECT_DOUBLE_EQ(reading.voltage_volts, 0.0);
148 EXPECT_DOUBLE_EQ(reading.current_amps, 0.0);
149 EXPECT_DOUBLE_EQ(reading.power_watts, 0.0);
150 EXPECT_DOUBLE_EQ(reading.temperature_celsius, 0.0);
151 EXPECT_FALSE(reading.temperature_available);
152 EXPECT_EQ(reading.cycle_count, -1);
153 EXPECT_FALSE(reading.battery_present);
154 EXPECT_FALSE(reading.metrics_available);
158TEST(BatteryStatusTest, ToStringConversion) {
167TEST(BatteryInfoCollectorTest, BasicFunctionality) {
168 battery_info_collector collector;
171 EXPECT_NO_THROW(collector.is_battery_available());
174 EXPECT_NO_THROW(collector.enumerate_batteries());
177 EXPECT_NO_THROW(collector.read_all_batteries());
181TEST_F(BatteryCollectorTest, MultipleCollectionsAreStable) {
182 for (
int i = 0; i < 10; ++i) {
185 EXPECT_NO_THROW(
collector_->get_statistics());
189 EXPECT_GE(stats[
"collection_count"], 10.0);
193TEST_F(BatteryCollectorTest, MetricsHaveCorrectTags) {
196 for (
const auto& m : metrics) {
198 auto it = m.tags.find(
"collector");
199 if (it != m.tags.end()) {
200 EXPECT_EQ(it->second,
"battery_collector");
206TEST_F(BatteryCollectorTest, IsAvailableReflectsState) {
211 auto disabled_collector = std::make_unique<battery_collector>();
212 std::unordered_map<std::string, std::string> config;
213 config[
"enabled"] =
"false";
214 disabled_collector->initialize(config);
215 EXPECT_NO_THROW(disabled_collector->is_available());
219TEST_F(BatteryCollectorTest, MetricsHaveBatteryIdTag) {
223 for (
const auto& m : metrics) {
224 auto it = m.tags.find(
"battery_id");
226 if (m.name.find(
"battery_") == 0) {
227 EXPECT_NE(it, m.tags.end()) <<
"Missing battery_id tag for: " << m.name;
233TEST(BatteryInfoCollectorTest, ReadAllBatteriesWhenPresent) {
234 battery_info_collector collector;
236 if (collector.is_battery_available()) {
237 auto readings = collector.read_all_batteries();
238 EXPECT_FALSE(readings.empty());
240 for (
const auto& reading : readings) {
241 EXPECT_TRUE(reading.battery_present);
242 EXPECT_TRUE(reading.metrics_available);
244 EXPECT_GE(reading.level_percent, 0.0);
245 EXPECT_LE(reading.level_percent, 100.0);
251TEST_F(BatteryCollectorTest, BatteryLevelInValidRange) {
252 auto readings =
collector_->get_last_readings();
256 for (
const auto& reading : readings) {
257 if (reading.metrics_available) {
258 EXPECT_GE(reading.level_percent, 0.0);
259 EXPECT_LE(reading.level_percent, 100.0);
265TEST_F(BatteryCollectorTest, HealthPercentageIsValid) {
267 auto readings =
collector_->get_last_readings();
269 for (
const auto& reading : readings) {
270 if (reading.metrics_available && reading.health_percent > 0.0) {
272 EXPECT_GE(reading.health_percent, 0.0);
273 EXPECT_LE(reading.health_percent, 150.0);
279TEST_F(BatteryCollectorTest, VoltageIsPositive) {
281 auto readings =
collector_->get_last_readings();
283 for (
const auto& reading : readings) {
284 if (reading.metrics_available && reading.voltage_volts > 0.0) {
286 EXPECT_GT(reading.voltage_volts, 0.0);
287 EXPECT_LT(reading.voltage_volts, 50.0);
293TEST_F(BatteryCollectorTest, StatusConsistency) {
295 auto readings =
collector_->get_last_readings();
297 for (
const auto& reading : readings) {
298 if (reading.metrics_available) {
300 if (reading.is_charging) {
305 EXPECT_GE(reading.level_percent, 90.0);
312TEST_F(BatteryCollectorTest, TimeEstimatesAreReasonable) {
314 auto readings =
collector_->get_last_readings();
316 for (
const auto& reading : readings) {
317 if (reading.metrics_available) {
319 if (reading.time_to_empty_seconds > 0) {
320 EXPECT_LT(reading.time_to_empty_seconds, 72 * 3600);
323 if (reading.time_to_full_seconds > 0) {
324 EXPECT_LT(reading.time_to_full_seconds, 24 * 3600);
331TEST_F(BatteryCollectorTest, CycleCountIsNonNegative) {
333 auto readings =
collector_->get_last_readings();
335 for (
const auto& reading : readings) {
336 if (reading.metrics_available && reading.cycle_count >= 0) {
338 EXPECT_LT(reading.cycle_count, 10000);
344TEST_F(BatteryCollectorTest, TemperatureIsReasonable) {
346 auto readings =
collector_->get_last_readings();
348 for (
const auto& reading : readings) {
349 if (reading.metrics_available && reading.temperature_available) {
351 EXPECT_GT(reading.temperature_celsius, -40.0);
352 EXPECT_LT(reading.temperature_celsius, 100.0);
Battery status monitoring collector.
@ charging
Battery is charging.
@ not_charging
Battery is not charging (plugged in but not charging)
@ discharging
Battery is discharging.
@ full
Battery is fully charged.
@ info
Informational, no action required.
std::string battery_status_to_string(battery_status status)
Convert battery_status to string representation.
TEST(AdapterFunctionalityTest, WorksWithoutLogger)
Test Scenario 1: Adapter with NULL logger.
TEST_F(AdaptiveMonitoringTest, AdaptiveConfigDefaults)
std::unique_ptr< battery_collector > collector_