Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_monitorable_interface.cpp File Reference

Unit tests for monitorable interface and monitoring data. More...

#include <gtest/gtest.h>
#include <kcenon/monitoring/interfaces/monitorable_interface.h>
#include <thread>
#include <atomic>
Include dependency graph for test_monitorable_interface.cpp:

Go to the source code of this file.

Classes

class  test_monitorable_component
 
class  MonitorableInterfaceTest
 

Functions

 TEST_F (MonitorableInterfaceTest, MonitoringDataBasicOperations)
 
 TEST_F (MonitorableInterfaceTest, MonitoringDataMerge)
 
 TEST_F (MonitorableInterfaceTest, MonitoringDataClearAndEmpty)
 
 TEST_F (MonitorableInterfaceTest, MonitorableComponentBasic)
 
 TEST_F (MonitorableInterfaceTest, MonitoringEnableDisable)
 
 TEST_F (MonitorableInterfaceTest, MonitoringReset)
 
 TEST_F (MonitorableInterfaceTest, AggregatorBasicOperations)
 
 TEST_F (MonitorableInterfaceTest, AggregatorDataCollection)
 
 TEST_F (MonitorableInterfaceTest, AggregatorWithDisabledComponents)
 
 TEST_F (MonitorableInterfaceTest, AggregatorComponentRemoval)
 
 TEST_F (MonitorableInterfaceTest, MonitoringDataTimestamp)
 
 TEST_F (MonitorableInterfaceTest, ThreadSafetyMonitorableComponent)
 

Detailed Description

Unit tests for monitorable interface and monitoring data.

Definition in file test_monitorable_interface.cpp.

Function Documentation

◆ TEST_F() [1/12]

TEST_F ( MonitorableInterfaceTest ,
AggregatorBasicOperations  )

Test monitoring_aggregator basic operations

Definition at line 297 of file test_monitorable_interface.cpp.

297 {
298 monitoring_aggregator aggregator("main_aggregator");
299
300 // Create components
301 auto comp1 = std::make_shared<test_monitorable_component>("comp1");
302 auto comp2 = std::make_shared<test_monitorable_component>("comp2");
303 auto comp3 = std::make_shared<test_monitorable_component>("comp3");
304
305 // Set different metrics for each
306 comp1->set_cpu_usage(25.0);
307 comp1->set_memory_usage(1000.0);
308 comp1->perform_operation();
309
310 comp2->set_cpu_usage(50.0);
311 comp2->set_memory_usage(2000.0);
312 comp2->perform_operation();
313 comp2->perform_operation();
314
315 comp3->set_cpu_usage(75.0);
316 comp3->set_memory_usage(3000.0);
317 comp3->perform_operation();
318 comp3->perform_operation();
319 comp3->perform_operation();
320
321 // Add components to aggregator
322 aggregator.add_component(comp1);
323 aggregator.add_component(comp2);
324 aggregator.add_component(comp3);
325
326 EXPECT_EQ(aggregator.size(), 3);
327
328 // Get component IDs
329 auto ids = aggregator.get_component_ids();
330 EXPECT_EQ(ids.size(), 3);
331 EXPECT_TRUE(std::find(ids.begin(), ids.end(), "comp1") != ids.end());
332 EXPECT_TRUE(std::find(ids.begin(), ids.end(), "comp2") != ids.end());
333 EXPECT_TRUE(std::find(ids.begin(), ids.end(), "comp3") != ids.end());
334
335 // Get specific component
336 auto retrieved = aggregator.get_component("comp2");
337 ASSERT_NE(retrieved, nullptr);
338 EXPECT_EQ(retrieved->get_monitoring_id(), "comp2");
339}
Utility class to aggregate metrics from multiple monitorable components.

References kcenon::monitoring::monitoring_aggregator::add_component(), kcenon::monitoring::monitoring_aggregator::get_component(), kcenon::monitoring::monitoring_aggregator::get_component_ids(), and kcenon::monitoring::monitoring_aggregator::size().

Here is the call graph for this function:

◆ TEST_F() [2/12]

TEST_F ( MonitorableInterfaceTest ,
AggregatorComponentRemoval  )

Test aggregator component removal

Definition at line 421 of file test_monitorable_interface.cpp.

421 {
422 monitoring_aggregator aggregator("test_aggregator");
423
424 auto comp1 = std::make_shared<test_monitorable_component>("comp1");
425 auto comp2 = std::make_shared<test_monitorable_component>("comp2");
426 auto comp3 = std::make_shared<test_monitorable_component>("comp3");
427
428 aggregator.add_component(comp1);
429 aggregator.add_component(comp2);
430 aggregator.add_component(comp3);
431
432 EXPECT_EQ(aggregator.size(), 3);
433
434 // Remove comp2
435 bool removed = aggregator.remove_component("comp2");
436 EXPECT_TRUE(removed);
437 EXPECT_EQ(aggregator.size(), 2);
438
439 // Try to remove non-existent component
440 removed = aggregator.remove_component("nonexistent");
441 EXPECT_FALSE(removed);
442 EXPECT_EQ(aggregator.size(), 2);
443
444 // Verify comp2 is gone
445 auto ids = aggregator.get_component_ids();
446 EXPECT_TRUE(std::find(ids.begin(), ids.end(), "comp1") != ids.end());
447 EXPECT_FALSE(std::find(ids.begin(), ids.end(), "comp2") != ids.end());
448 EXPECT_TRUE(std::find(ids.begin(), ids.end(), "comp3") != ids.end());
449
450 // Clear all
451 aggregator.clear();
452 EXPECT_EQ(aggregator.size(), 0);
453}

References kcenon::monitoring::monitoring_aggregator::add_component(), kcenon::monitoring::monitoring_aggregator::clear(), kcenon::monitoring::monitoring_aggregator::get_component_ids(), kcenon::monitoring::monitoring_aggregator::remove_component(), and kcenon::monitoring::monitoring_aggregator::size().

Here is the call graph for this function:

◆ TEST_F() [3/12]

TEST_F ( MonitorableInterfaceTest ,
AggregatorDataCollection  )

Test monitoring_aggregator data collection

Definition at line 344 of file test_monitorable_interface.cpp.

344 {
345 monitoring_aggregator aggregator("test_aggregator");
346
347 // Create and configure components
348 auto comp1 = std::make_shared<test_monitorable_component>("comp1");
349 comp1->set_cpu_usage(30.0);
350 comp1->set_memory_usage(1500.0);
351
352 auto comp2 = std::make_shared<test_monitorable_component>("comp2");
353 comp2->set_cpu_usage(60.0);
354 comp2->set_memory_usage(2500.0);
355
356 aggregator.add_component(comp1);
357 aggregator.add_component(comp2);
358
359 // Collect all data
360 auto result = aggregator.collect_all();
361 ASSERT_TRUE(result.is_ok());
362
363 auto aggregated = result.value();
364 EXPECT_EQ(aggregated.get_component_name(), "test_aggregator");
365
366 // Check that metrics are prefixed
367 auto comp1_cpu = aggregated.get_metric("comp1.cpu_usage");
368 ASSERT_TRUE(comp1_cpu.has_value());
369 EXPECT_DOUBLE_EQ(comp1_cpu.value(), 30.0);
370
371 auto comp2_cpu = aggregated.get_metric("comp2.cpu_usage");
372 ASSERT_TRUE(comp2_cpu.has_value());
373 EXPECT_DOUBLE_EQ(comp2_cpu.value(), 60.0);
374
375 // Check aggregator metadata
376 auto component_count = aggregated.get_metric("aggregator.component_count");
377 ASSERT_TRUE(component_count.has_value());
378 EXPECT_DOUBLE_EQ(component_count.value(), 2.0);
379}

References kcenon::monitoring::monitoring_aggregator::add_component(), and kcenon::monitoring::monitoring_aggregator::collect_all().

Here is the call graph for this function:

◆ TEST_F() [4/12]

TEST_F ( MonitorableInterfaceTest ,
AggregatorWithDisabledComponents  )

Test aggregator with disabled components

Definition at line 384 of file test_monitorable_interface.cpp.

384 {
385 monitoring_aggregator aggregator("test_aggregator");
386
387 auto comp1 = std::make_shared<test_monitorable_component>("comp1");
388 auto comp2 = std::make_shared<test_monitorable_component>("comp2");
389
390 comp1->set_cpu_usage(40.0);
391 comp2->set_cpu_usage(80.0);
392
393 // Disable comp2
394 comp2->set_monitoring_enabled(false);
395
396 aggregator.add_component(comp1);
397 aggregator.add_component(comp2);
398
399 // Collect data
400 auto result = aggregator.collect_all();
401 ASSERT_TRUE(result.is_ok());
402
403 auto aggregated = result.value();
404
405 // comp1 data should be present
406 auto comp1_cpu = aggregated.get_metric("comp1.cpu_usage");
407 ASSERT_TRUE(comp1_cpu.has_value());
408
409 // comp2 data should not be present (it's disabled)
410 auto comp2_cpu = aggregated.get_metric("comp2.cpu_usage");
411 EXPECT_FALSE(comp2_cpu.has_value());
412
413 // comp2 is disabled, so it's skipped (no error tag needed)
414 auto comp2_error = aggregated.get_tag("comp2.error");
415 EXPECT_FALSE(comp2_error.has_value());
416}

References kcenon::monitoring::monitoring_aggregator::add_component(), and kcenon::monitoring::monitoring_aggregator::collect_all().

Here is the call graph for this function:

◆ TEST_F() [5/12]

TEST_F ( MonitorableInterfaceTest ,
MonitorableComponentBasic  )

Test monitorable_component implementation

Definition at line 198 of file test_monitorable_interface.cpp.

198 {
199 test_monitorable_component component("test_comp_1");
200
201 // Test initial state
202 EXPECT_EQ(component.get_monitoring_id(), "test_comp_1");
203 EXPECT_TRUE(component.is_monitoring_enabled());
204
205 // Perform operations
206 component.perform_operation();
207 component.perform_operation();
208 component.set_cpu_usage(45.5);
209 component.set_memory_usage(2048.0);
210
211 // Get monitoring data
212 auto result = component.get_monitoring_data();
213 ASSERT_TRUE(result.is_ok());
214
215 auto data = result.value();
216 EXPECT_EQ(data.get_component_name(), "test_comp_1");
217
218 // Verify metrics
219 auto op_count = data.get_metric("operation_count");
220 ASSERT_TRUE(op_count.has_value());
221 EXPECT_DOUBLE_EQ(op_count.value(), 2.0);
222
223 auto cpu = data.get_metric("cpu_usage");
224 ASSERT_TRUE(cpu.has_value());
225 EXPECT_DOUBLE_EQ(cpu.value(), 45.5);
226
227 auto memory = data.get_metric("memory_usage");
228 ASSERT_TRUE(memory.has_value());
229 EXPECT_DOUBLE_EQ(memory.value(), 2048.0);
230
231 // Verify tags
232 auto type = data.get_tag("component_type");
233 ASSERT_TRUE(type.has_value());
234 EXPECT_EQ(type.value(), "test");
235
236 auto version = data.get_tag("version");
237 ASSERT_TRUE(version.has_value());
238 EXPECT_EQ(version.value(), "1.0.0");
239}
@ memory
Memory/DRAM power domain (RAPL)
@ cpu
CPU power domain (RAPL)

References kcenon::monitoring::cpu, test_monitorable_component::get_monitoring_data(), kcenon::monitoring::monitorable_component::get_monitoring_id(), kcenon::monitoring::monitorable_component::is_monitoring_enabled(), kcenon::monitoring::memory, test_monitorable_component::perform_operation(), test_monitorable_component::set_cpu_usage(), and test_monitorable_component::set_memory_usage().

Here is the call graph for this function:

◆ TEST_F() [6/12]

TEST_F ( MonitorableInterfaceTest ,
MonitoringDataBasicOperations  )

Test monitoring_data basic operations

Definition at line 89 of file test_monitorable_interface.cpp.

89 {
90 monitoring_data data("test_component");
91
92 // Test adding metrics
93 data.add_metric("cpu", 75.5);
94 data.add_metric("memory", 1024.0);
95
96 // Test adding tags
97 data.add_tag("host", "localhost");
98 data.add_tag("region", "us-east");
99
100 // Verify metrics
101 auto cpu = data.get_metric("cpu");
102 ASSERT_TRUE(cpu.has_value());
103 EXPECT_DOUBLE_EQ(cpu.value(), 75.5);
104
105 auto memory = data.get_metric("memory");
106 ASSERT_TRUE(memory.has_value());
107 EXPECT_DOUBLE_EQ(memory.value(), 1024.0);
108
109 auto missing = data.get_metric("nonexistent");
110 EXPECT_FALSE(missing.has_value());
111
112 // Verify tags
113 auto host = data.get_tag("host");
114 ASSERT_TRUE(host.has_value());
115 EXPECT_EQ(host.value(), "localhost");
116
117 auto region = data.get_tag("region");
118 ASSERT_TRUE(region.has_value());
119 EXPECT_EQ(region.value(), "us-east");
120
121 // Verify counts
122 EXPECT_EQ(data.metric_count(), 2);
123 EXPECT_EQ(data.tag_count(), 2);
124 EXPECT_FALSE(data.empty());
125
126 // Test component name
127 EXPECT_EQ(data.get_component_name(), "test_component");
128}
Container for monitoring metrics from a component.

References kcenon::monitoring::monitoring_data::add_metric(), kcenon::monitoring::monitoring_data::add_tag(), kcenon::monitoring::cpu, kcenon::monitoring::monitoring_data::empty(), kcenon::monitoring::monitoring_data::get_component_name(), kcenon::monitoring::monitoring_data::get_metric(), kcenon::monitoring::monitoring_data::get_tag(), kcenon::monitoring::host, kcenon::monitoring::memory, kcenon::monitoring::monitoring_data::metric_count(), and kcenon::monitoring::monitoring_data::tag_count().

Here is the call graph for this function:

◆ TEST_F() [7/12]

TEST_F ( MonitorableInterfaceTest ,
MonitoringDataClearAndEmpty  )

Test monitoring_data clear and empty

Definition at line 171 of file test_monitorable_interface.cpp.

171 {
172 monitoring_data data("test");
173
174 // Initially empty
175 EXPECT_TRUE(data.empty());
176 EXPECT_EQ(data.metric_count(), 0);
177 EXPECT_EQ(data.tag_count(), 0);
178
179 // Add data
180 data.add_metric("metric", 1.0);
181 data.add_tag("tag", "value");
182
183 EXPECT_FALSE(data.empty());
184 EXPECT_EQ(data.metric_count(), 1);
185 EXPECT_EQ(data.tag_count(), 1);
186
187 // Clear data
188 data.clear();
189
190 EXPECT_TRUE(data.empty());
191 EXPECT_EQ(data.metric_count(), 0);
192 EXPECT_EQ(data.tag_count(), 0);
193}

References kcenon::monitoring::monitoring_data::add_metric(), kcenon::monitoring::monitoring_data::add_tag(), kcenon::monitoring::monitoring_data::clear(), kcenon::monitoring::monitoring_data::empty(), kcenon::monitoring::monitoring_data::metric_count(), and kcenon::monitoring::monitoring_data::tag_count().

Here is the call graph for this function:

◆ TEST_F() [8/12]

TEST_F ( MonitorableInterfaceTest ,
MonitoringDataMerge  )

Test monitoring_data merge functionality

Definition at line 133 of file test_monitorable_interface.cpp.

133 {
134 monitoring_data data1("component1");
135 data1.add_metric("metric1", 10.0);
136 data1.add_tag("tag1", "value1");
137
138 monitoring_data data2("component2");
139 data2.add_metric("metric2", 20.0);
140 data2.add_tag("tag2", "value2");
141
142 // Merge without prefix
143 data1.merge(data2);
144
145 EXPECT_EQ(data1.metric_count(), 2);
146 EXPECT_EQ(data1.tag_count(), 2);
147
148 auto metric2 = data1.get_metric("metric2");
149 ASSERT_TRUE(metric2.has_value());
150 EXPECT_DOUBLE_EQ(metric2.value(), 20.0);
151
152 // Merge with prefix
153 monitoring_data data3("component3");
154 data3.add_metric("metric3", 30.0);
155 data3.add_tag("tag3", "value3");
156
157 data1.merge(data3, "prefix");
158
159 auto prefixed_metric = data1.get_metric("prefix.metric3");
160 ASSERT_TRUE(prefixed_metric.has_value());
161 EXPECT_DOUBLE_EQ(prefixed_metric.value(), 30.0);
162
163 auto prefixed_tag = data1.get_tag("prefix.tag3");
164 ASSERT_TRUE(prefixed_tag.has_value());
165 EXPECT_EQ(prefixed_tag.value(), "value3");
166}

References kcenon::monitoring::monitoring_data::add_metric(), kcenon::monitoring::monitoring_data::add_tag(), kcenon::monitoring::monitoring_data::get_metric(), kcenon::monitoring::monitoring_data::get_tag(), kcenon::monitoring::monitoring_data::merge(), kcenon::monitoring::monitoring_data::metric_count(), and kcenon::monitoring::monitoring_data::tag_count().

Here is the call graph for this function:

◆ TEST_F() [9/12]

TEST_F ( MonitorableInterfaceTest ,
MonitoringDataTimestamp  )

Test monitoring data timestamp

Definition at line 458 of file test_monitorable_interface.cpp.

458 {
459 auto start_time = std::chrono::system_clock::now();
460
461 monitoring_data data("test");
462
463 auto timestamp = data.get_timestamp();
464 auto end_time = std::chrono::system_clock::now();
465
466 // Timestamp should be between start and end
467 EXPECT_GE(timestamp, start_time);
468 EXPECT_LE(timestamp, end_time);
469}

References kcenon::monitoring::monitoring_data::get_timestamp().

Here is the call graph for this function:

◆ TEST_F() [10/12]

TEST_F ( MonitorableInterfaceTest ,
MonitoringEnableDisable  )

Test monitoring enable/disable

Definition at line 244 of file test_monitorable_interface.cpp.

244 {
245 test_monitorable_component component("test_comp");
246
247 // Initially enabled
248 EXPECT_TRUE(component.is_monitoring_enabled());
249
250 auto result = component.get_monitoring_data();
251 EXPECT_TRUE(result.is_ok());
252
253 // Disable monitoring
254 auto disable_result = component.set_monitoring_enabled(false);
255 EXPECT_TRUE(disable_result.is_ok());
256 EXPECT_FALSE(component.is_monitoring_enabled());
257
258 // Should return error when disabled
259 result = component.get_monitoring_data();
260 EXPECT_TRUE(result.is_err());
261 EXPECT_EQ(static_cast<monitoring_error_code>(result.error().code), monitoring_error_code::monitoring_disabled);
262
263 // Re-enable monitoring
264 auto enable_result = component.set_monitoring_enabled(true);
265 EXPECT_TRUE(enable_result.is_ok());
266 EXPECT_TRUE(component.is_monitoring_enabled());
267
268 // Should work again
269 result = component.get_monitoring_data();
270 EXPECT_TRUE(result.is_ok());
271}
monitoring_error_code
Comprehensive error codes for monitoring system operations.
Definition error_codes.h:25

References test_monitorable_component::get_monitoring_data(), kcenon::monitoring::monitorable_component::is_monitoring_enabled(), and kcenon::monitoring::monitorable_component::set_monitoring_enabled().

Here is the call graph for this function:

◆ TEST_F() [11/12]

TEST_F ( MonitorableInterfaceTest ,
MonitoringReset  )

Test monitoring reset

Definition at line 276 of file test_monitorable_interface.cpp.

276 {
277 test_monitorable_component component("test_comp");
278
279 // Set some state
280 component.perform_operation();
281 component.perform_operation();
282 component.perform_operation();
283
284 EXPECT_EQ(component.get_operation_count(), 3);
285
286 // Reset monitoring (note: our test implementation doesn't reset internal counters)
287 auto reset_result = component.reset_monitoring();
288 EXPECT_TRUE(reset_result.is_ok());
289
290 // Internal state remains (as we didn't override reset_monitoring to clear it)
291 EXPECT_EQ(component.get_operation_count(), 3);
292}

References test_monitorable_component::get_operation_count(), test_monitorable_component::perform_operation(), and kcenon::monitoring::monitorable_component::reset_monitoring().

Here is the call graph for this function:

◆ TEST_F() [12/12]

TEST_F ( MonitorableInterfaceTest ,
ThreadSafetyMonitorableComponent  )

Test thread safety of monitorable component

Definition at line 474 of file test_monitorable_interface.cpp.

474 {
475 test_monitorable_component component("thread_test");
476
477 const int thread_count = 10;
478 const int operations_per_thread = 1000;
479 std::vector<std::thread> threads;
480
481 // Launch threads that perform operations
482 for (int i = 0; i < thread_count; ++i) {
483 threads.emplace_back([&component]() {
484 for (int j = 0; j < operations_per_thread; ++j) {
485 component.perform_operation();
486
487 // Also get monitoring data periodically
488 if (j % 100 == 0) {
489 auto result = component.get_monitoring_data();
490 EXPECT_TRUE(result.is_ok());
491 }
492 }
493 });
494 }
495
496 // Wait for all threads
497 for (auto& t : threads) {
498 t.join();
499 }
500
501 // Verify final count
502 EXPECT_EQ(component.get_operation_count(), thread_count * operations_per_thread);
503
504 // Get final monitoring data
505 auto result = component.get_monitoring_data();
506 ASSERT_TRUE(result.is_ok());
507
508 auto op_count = result.value().get_metric("operation_count");
509 ASSERT_TRUE(op_count.has_value());
510 EXPECT_DOUBLE_EQ(op_count.value(),
511 static_cast<double>(thread_count * operations_per_thread));
512}

References test_monitorable_component::get_monitoring_data(), test_monitorable_component::get_operation_count(), and test_monitorable_component::perform_operation().

Here is the call graph for this function: