Monitoring System 0.1.0
System resource monitoring with pluggable collectors and alerting
Loading...
Searching...
No Matches
test_buffering_strategies.cpp File Reference
#include <gtest/gtest.h>
#include "utils/buffering_strategy.h"
#include "utils/buffer_manager.h"
#include "utils/metric_storage.h"
#include <chrono>
#include <thread>
#include <vector>
#include <random>
#include <functional>
Include dependency graph for test_buffering_strategies.cpp:

Go to the source code of this file.

Classes

class  BufferingStrategiesTest
 Test suite for Phase 3 P3: Configurable buffering strategies. More...
 

Functions

 TEST_F (BufferingStrategiesTest, BufferingConfigValidation)
 
 TEST_F (BufferingStrategiesTest, ImmediateStrategy)
 
 TEST_F (BufferingStrategiesTest, FixedSizeStrategy)
 
 TEST_F (BufferingStrategiesTest, FixedSizeStrategyDropNewest)
 
 TEST_F (BufferingStrategiesTest, TimeBasedStrategy)
 
 TEST_F (BufferingStrategiesTest, TimeBasedStrategyBufferFull)
 
 TEST_F (BufferingStrategiesTest, PriorityBasedStrategy)
 
 TEST_F (BufferingStrategiesTest, PriorityBasedStrategyOverflow)
 
 TEST_F (BufferingStrategiesTest, AdaptiveStrategy)
 
 TEST_F (BufferingStrategiesTest, StrategyFactory)
 
 TEST_F (BufferingStrategiesTest, DefaultConfigurations)
 
 TEST_F (BufferingStrategiesTest, BufferManagerBasic)
 
 TEST_F (BufferingStrategiesTest, BufferManagerMultipleMetrics)
 
 TEST_F (BufferingStrategiesTest, BufferManagerCustomStrategy)
 
 TEST_F (BufferingStrategiesTest, BufferManagerBackgroundProcessing)
 
 TEST_F (BufferingStrategiesTest, ThreadSafety)
 

Function Documentation

◆ TEST_F() [1/16]

TEST_F ( BufferingStrategiesTest ,
AdaptiveStrategy  )

Definition at line 300 of file test_buffering_strategies.cpp.

300 {
301 buffering_config config;
302 config.strategy = buffering_strategy_type::adaptive;
303 config.max_buffer_size = 100;
304 config.load_factor_threshold = 0.7;
305 config.adaptive_check_interval = std::chrono::milliseconds(50);
306
307 adaptive_strategy strategy(config);
308
309 // Add some metrics
310 for (int i = 0; i < 20; ++i) {
311 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
312 strategy.add_metric(std::move(metric));
313 }
314
315 EXPECT_EQ(strategy.size(), 20);
316
317 // Add more metrics to increase load
318 for (int i = 20; i < 80; ++i) {
319 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
320 strategy.add_metric(std::move(metric));
321 }
322
323 // Should adapt to high load
324 EXPECT_TRUE(strategy.should_flush());
325}
Basic metric structure for interface compatibility.

◆ TEST_F() [2/16]

TEST_F ( BufferingStrategiesTest ,
BufferingConfigValidation  )

Definition at line 59 of file test_buffering_strategies.cpp.

59 {
60 // Test invalid configuration
61 buffering_config invalid_config;
62 invalid_config.max_buffer_size = 0; // Invalid
63
64 auto validation = invalid_config.validate();
65 EXPECT_FALSE(validation);
66
67 // Test valid configuration
68 buffering_config valid_config;
69 valid_config.max_buffer_size = 1024;
70 valid_config.flush_threshold_size = 512;
71 valid_config.flush_interval = std::chrono::milliseconds(1000);
72
73 validation = valid_config.validate();
74 EXPECT_TRUE(validation);
75
76 // Test invalid threshold
77 buffering_config invalid_threshold;
78 invalid_threshold.max_buffer_size = 100;
79 invalid_threshold.flush_threshold_size = 200; // Exceeds max size
80
81 validation = invalid_threshold.validate();
82 EXPECT_FALSE(validation);
83}

◆ TEST_F() [3/16]

TEST_F ( BufferingStrategiesTest ,
BufferManagerBackgroundProcessing  )

Definition at line 465 of file test_buffering_strategies.cpp.

465 {
466 auto storage = std::make_shared<metric_storage>();
467
468 buffer_manager_config config;
469 config.background_check_interval = std::chrono::milliseconds(50);
470 config.enable_automatic_flushing = true;
471
472 buffer_manager manager(config, storage);
473
474 // Configure time-based strategy with short interval
475 buffering_config time_config;
476 time_config.strategy = buffering_strategy_type::time_based;
477 time_config.flush_interval = std::chrono::milliseconds(100);
478 time_config.max_buffer_size = 100;
479
480 manager.configure_metric_buffer("timed_metric", time_config);
481
482 // Start background processing
483 auto start_result = manager.start_background_processing();
484 EXPECT_TRUE(start_result);
485
486 // Add metrics
487 for (int i = 0; i < 5; ++i) {
488 auto metadata = create_metric_metadata("timed_metric", metric_type::gauge);
489 compact_metric_value metric(metadata, static_cast<double>(i));
490
491 manager.add_metric("timed_metric", std::move(metric));
492 }
493
494 // Wait for background flush
495 std::this_thread::sleep_for(std::chrono::milliseconds(200));
496
497 // Buffer should be flushed automatically
498 auto size_result = manager.get_buffer_size("timed_metric");
499 EXPECT_TRUE(size_result);
500 EXPECT_EQ(size_result.value(), 0);
501
502 // Stop background processing
503 manager.stop_background_processing();
504}
metric_metadata create_metric_metadata(const std::string &name, metric_type type, size_t tag_count=0)
Create metric metadata from name and type.
@ storage
Storage device sensor.
Memory-efficient metric value storage.

References kcenon::monitoring::create_metric_metadata(), and kcenon::monitoring::storage.

Here is the call graph for this function:

◆ TEST_F() [4/16]

TEST_F ( BufferingStrategiesTest ,
BufferManagerBasic  )

Definition at line 370 of file test_buffering_strategies.cpp.

370 {
371 auto storage = std::make_shared<metric_storage>();
372
373 buffer_manager_config config;
374 config.enable_automatic_flushing = false; // Manual control for testing
375
376 buffer_manager manager(config, storage);
377
378 // Add metrics for different metric names
379 for (int i = 0; i < 5; ++i) {
380 auto metadata = create_metric_metadata("cpu_usage", metric_type::gauge);
381 compact_metric_value metric(metadata, 50.0 + i);
382
383 auto result = manager.add_metric("cpu_usage", std::move(metric));
384 EXPECT_TRUE(result.is_ok());
385 }
386
387 // Check buffer size
388 auto size_result = manager.get_buffer_size("cpu_usage");
389 EXPECT_TRUE(size_result);
390 EXPECT_EQ(size_result.value(), 5);
391
392 // Force flush
393 auto flush_result = manager.force_flush("cpu_usage");
394 EXPECT_TRUE(flush_result);
395
396 // Buffer should be empty after flush
397 size_result = manager.get_buffer_size("cpu_usage");
398 EXPECT_TRUE(size_result);
399 EXPECT_EQ(size_result.value(), 0);
400}

References kcenon::monitoring::create_metric_metadata(), and kcenon::monitoring::storage.

Here is the call graph for this function:

◆ TEST_F() [5/16]

TEST_F ( BufferingStrategiesTest ,
BufferManagerCustomStrategy  )

Definition at line 437 of file test_buffering_strategies.cpp.

437 {
438 buffer_manager manager;
439
440 // Configure custom buffering strategy
441 buffering_config custom_config;
442 custom_config.strategy = buffering_strategy_type::priority_based;
443 custom_config.max_buffer_size = 10;
444 custom_config.flush_priority_threshold = 200;
445
446 auto result = manager.configure_metric_buffer("high_priority_metric", custom_config);
447 EXPECT_TRUE(result.is_ok());
448
449 // Add metrics with different priorities
450 std::vector<uint8_t> priorities = {100, 250, 150};
451
452 for (size_t i = 0; i < priorities.size(); ++i) {
453 auto metadata = create_metric_metadata("high_priority_metric", metric_type::counter);
454 compact_metric_value metric(metadata, static_cast<double>(i));
455
456 auto add_result = manager.add_metric("high_priority_metric", std::move(metric), priorities[i]);
457 EXPECT_TRUE(add_result);
458 }
459
460 // Get buffer statistics
461 auto stats_result = manager.get_buffer_statistics("high_priority_metric");
462 EXPECT_TRUE(stats_result);
463}

References kcenon::monitoring::create_metric_metadata().

Here is the call graph for this function:

◆ TEST_F() [6/16]

TEST_F ( BufferingStrategiesTest ,
BufferManagerMultipleMetrics  )

Definition at line 402 of file test_buffering_strategies.cpp.

402 {
403 buffer_manager manager;
404
405 std::vector<std::string> metric_names = {"cpu_usage", "memory_usage", "disk_io"};
406
407 // Add metrics for different metric names
408 for (const auto& metric_name : metric_names) {
409 for (int i = 0; i < 3; ++i) {
410 auto metadata = create_metric_metadata(metric_name, metric_type::gauge);
411 compact_metric_value metric(metadata, static_cast<double>(i));
412
413 manager.add_metric(metric_name, std::move(metric));
414 }
415 }
416
417 // Check that all metrics have buffers
418 auto buffered_metrics = manager.get_buffered_metrics();
419 EXPECT_EQ(buffered_metrics.size(), 3);
420
421 for (const auto& metric_name : metric_names) {
422 EXPECT_NE(std::find(buffered_metrics.begin(), buffered_metrics.end(), metric_name),
423 buffered_metrics.end());
424 }
425
426 // Force flush all
427 manager.force_flush_all();
428
429 // All buffers should be empty
430 for (const auto& metric_name : metric_names) {
431 auto size_result = manager.get_buffer_size(metric_name);
432 EXPECT_TRUE(size_result);
433 EXPECT_EQ(size_result.value(), 0);
434 }
435}

References kcenon::monitoring::create_metric_metadata().

Here is the call graph for this function:

◆ TEST_F() [7/16]

TEST_F ( BufferingStrategiesTest ,
DefaultConfigurations  )

Definition at line 354 of file test_buffering_strategies.cpp.

354 {
355 auto configs = create_default_buffering_configs();
356
357 EXPECT_GT(configs.size(), 0);
358
359 // Validate all default configurations
360 for (const auto& config : configs) {
361 auto validation = config.validate();
362 EXPECT_TRUE(validation) << "Default configuration validation failed";
363
364 // Test that we can create strategies with these configurations
365 EXPECT_NO_THROW(create_buffering_strategy(config));
366 }
367}

◆ TEST_F() [8/16]

TEST_F ( BufferingStrategiesTest ,
FixedSizeStrategy  )

Definition at line 117 of file test_buffering_strategies.cpp.

117 {
118 buffering_config config;
119 config.strategy = buffering_strategy_type::fixed_size;
120 config.max_buffer_size = 5;
121 config.flush_threshold_size = 3;
122 config.overflow_policy = buffer_overflow_policy::drop_oldest;
123
124 fixed_size_strategy strategy(config);
125
126 // Add metrics up to threshold
127 for (int i = 0; i < 3; ++i) {
128 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
129 auto result = strategy.add_metric(std::move(metric));
130 EXPECT_TRUE(result.is_ok());
131 }
132
133 EXPECT_EQ(strategy.size(), 3);
134 EXPECT_TRUE(strategy.should_flush()); // Should flush at threshold
135
136 // Add more metrics to test overflow
137 for (int i = 3; i < 8; ++i) {
138 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
139 auto result = strategy.add_metric(std::move(metric));
140 EXPECT_TRUE(result.is_ok());
141 }
142
143 EXPECT_EQ(strategy.size(), 5); // Should not exceed max size
144
145 // Flush buffer
146 auto flush_result = strategy.flush();
147 EXPECT_TRUE(flush_result);
148 EXPECT_EQ(flush_result.value().size(), 5);
149
150 // Buffer should be empty after flush
151 EXPECT_EQ(strategy.size(), 0);
152 EXPECT_FALSE(strategy.should_flush());
153
154 // Check statistics
155 const auto& stats = strategy.get_statistics();
156 EXPECT_EQ(stats.total_items_buffered.load(), 8);
157 EXPECT_EQ(stats.total_items_flushed.load(), 5);
158 EXPECT_EQ(stats.items_dropped_overflow.load(), 3);
159}

◆ TEST_F() [9/16]

TEST_F ( BufferingStrategiesTest ,
FixedSizeStrategyDropNewest  )

Definition at line 161 of file test_buffering_strategies.cpp.

161 {
162 buffering_config config;
163 config.strategy = buffering_strategy_type::fixed_size;
164 config.max_buffer_size = 3;
165 config.overflow_policy = buffer_overflow_policy::drop_newest;
166
167 fixed_size_strategy strategy(config);
168
169 // Fill buffer
170 for (int i = 0; i < 3; ++i) {
171 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
172 strategy.add_metric(std::move(metric));
173 }
174
175 EXPECT_EQ(strategy.size(), 3);
176
177 // Try to add one more (should be dropped)
178 auto metric = create_test_metric("test_overflow", 999.0);
179 strategy.add_metric(std::move(metric));
180
181 EXPECT_EQ(strategy.size(), 3); // Size unchanged
182
183 const auto& stats = strategy.get_statistics();
184 EXPECT_GT(stats.items_dropped_overflow.load(), 0);
185}

◆ TEST_F() [10/16]

TEST_F ( BufferingStrategiesTest ,
ImmediateStrategy  )

Definition at line 86 of file test_buffering_strategies.cpp.

86 {
87 buffering_config config;
88 config.strategy = buffering_strategy_type::immediate;
89
90 immediate_strategy strategy(config);
91
92 // Test basic properties
93 EXPECT_EQ(strategy.size(), 0);
94 EXPECT_FALSE(strategy.should_flush());
95
96 // Add metric (should be processed immediately)
97 auto metric = create_test_metric("test_metric", 42.0);
98 auto result = strategy.add_metric(std::move(metric));
99 EXPECT_TRUE(result.is_ok());
100
101 // Size should still be 0 (no buffering)
102 EXPECT_EQ(strategy.size(), 0);
103
104 // Flush should return empty vector
105 auto flush_result = strategy.flush();
106 EXPECT_TRUE(flush_result);
107 EXPECT_TRUE(flush_result.value().empty());
108
109 // Check statistics
110 const auto& stats = strategy.get_statistics();
111 EXPECT_EQ(stats.total_items_buffered.load(), 1);
112 EXPECT_EQ(stats.total_items_flushed.load(), 1);
113 EXPECT_EQ(stats.total_flushes.load(), 1);
114}

◆ TEST_F() [11/16]

TEST_F ( BufferingStrategiesTest ,
PriorityBasedStrategy  )

Definition at line 236 of file test_buffering_strategies.cpp.

236 {
237 buffering_config config;
238 config.strategy = buffering_strategy_type::priority_based;
239 config.max_buffer_size = 10;
240 config.flush_priority_threshold = 200;
241
242 priority_based_strategy strategy(config);
243
244 // Add metrics with different priorities
245 std::vector<uint8_t> priorities = {100, 150, 250, 50, 220};
246
247 for (size_t i = 0; i < priorities.size(); ++i) {
248 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i), priorities[i]);
249 strategy.add_metric(std::move(metric));
250 }
251
252 EXPECT_EQ(strategy.size(), 5);
253 EXPECT_TRUE(strategy.should_flush()); // Should flush due to high priority items
254
255 // Flush and check order (should be sorted by priority)
256 auto flush_result = strategy.flush();
257 EXPECT_TRUE(flush_result);
258
259 const auto& flushed_items = flush_result.value();
260 EXPECT_EQ(flushed_items.size(), 5);
261
262 // Check that items are sorted by priority (highest first)
263 for (size_t i = 1; i < flushed_items.size(); ++i) {
264 EXPECT_GE(flushed_items[i-1].priority, flushed_items[i].priority);
265 }
266}

◆ TEST_F() [12/16]

TEST_F ( BufferingStrategiesTest ,
PriorityBasedStrategyOverflow  )

Definition at line 268 of file test_buffering_strategies.cpp.

268 {
269 buffering_config config;
270 config.strategy = buffering_strategy_type::priority_based;
271 config.max_buffer_size = 3;
272 config.overflow_policy = buffer_overflow_policy::drop_lowest_priority;
273
274 priority_based_strategy strategy(config);
275
276 // Add metrics with different priorities
277 std::vector<uint8_t> priorities = {100, 200, 150, 250, 50};
278
279 for (size_t i = 0; i < priorities.size(); ++i) {
280 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i), priorities[i]);
281 strategy.add_metric(std::move(metric));
282 }
283
284 EXPECT_EQ(strategy.size(), 3); // Should maintain max size
285
286 // Flush and verify highest priorities are kept
287 auto flush_result = strategy.flush();
288 EXPECT_TRUE(flush_result);
289
290 const auto& flushed_items = flush_result.value();
291 EXPECT_EQ(flushed_items.size(), 3);
292
293 // Check that lowest priority items were dropped
294 for (const auto& item : flushed_items) {
295 EXPECT_GT(item.priority, 100); // Priority 50 and 100 should be dropped
296 }
297}

◆ TEST_F() [13/16]

TEST_F ( BufferingStrategiesTest ,
StrategyFactory  )

Definition at line 328 of file test_buffering_strategies.cpp.

328 {
329 // Test immediate strategy creation
330 buffering_config immediate_config;
331 immediate_config.strategy = buffering_strategy_type::immediate;
332
333 auto immediate_strategy = create_buffering_strategy(immediate_config);
334 EXPECT_NE(immediate_strategy, nullptr);
335 EXPECT_EQ(immediate_strategy->get_config().strategy, buffering_strategy_type::immediate);
336
337 // Test fixed size strategy creation
338 buffering_config fixed_config;
339 fixed_config.strategy = buffering_strategy_type::fixed_size;
340 fixed_config.max_buffer_size = 1024;
341
342 auto fixed_strategy = create_buffering_strategy(fixed_config);
343 EXPECT_NE(fixed_strategy, nullptr);
344 EXPECT_EQ(fixed_strategy->get_config().strategy, buffering_strategy_type::fixed_size);
345
346 // Test invalid configuration
347 buffering_config invalid_config;
348 invalid_config.max_buffer_size = 0; // Invalid
349
350 EXPECT_THROW(create_buffering_strategy(invalid_config), std::invalid_argument);
351}

◆ TEST_F() [14/16]

TEST_F ( BufferingStrategiesTest ,
ThreadSafety  )

Definition at line 507 of file test_buffering_strategies.cpp.

507 {
508 buffer_manager manager;
509
510 const int num_threads = 4;
511 const int metrics_per_thread = 100;
512 std::vector<std::thread> threads;
513
514 // Launch multiple threads adding metrics
515 for (int t = 0; t < num_threads; ++t) {
516 threads.emplace_back([&manager, t, metrics_per_thread]() {
517 std::string metric_name = "thread_" + std::to_string(t) + "_metric";
518
519 for (int i = 0; i < metrics_per_thread; ++i) {
520 auto metadata = create_metric_metadata(metric_name, metric_type::counter);
521 compact_metric_value metric(metadata, static_cast<double>(i));
522
523 manager.add_metric(metric_name, std::move(metric));
524
525 // Small delay to increase chance of contention
526 std::this_thread::sleep_for(std::chrono::microseconds(1));
527 }
528 });
529 }
530
531 // Wait for all threads to complete
532 for (auto& thread : threads) {
533 thread.join();
534 }
535
536 // Verify metrics were added
537 auto buffered_metrics = manager.get_buffered_metrics();
538 EXPECT_EQ(buffered_metrics.size(), num_threads);
539
540 // Check each metric buffer
541 for (int t = 0; t < num_threads; ++t) {
542 std::string metric_name = "thread_" + std::to_string(t) + "_metric";
543 auto size_result = manager.get_buffer_size(metric_name);
544 EXPECT_TRUE(size_result);
545 EXPECT_EQ(size_result.value(), metrics_per_thread);
546 }
547}

References kcenon::monitoring::create_metric_metadata().

Here is the call graph for this function:

◆ TEST_F() [15/16]

TEST_F ( BufferingStrategiesTest ,
TimeBasedStrategy  )

Definition at line 188 of file test_buffering_strategies.cpp.

188 {
189 buffering_config config;
190 config.strategy = buffering_strategy_type::time_based;
191 config.max_buffer_size = 100;
192 config.flush_interval = std::chrono::milliseconds(100);
193
194 time_based_strategy strategy(config);
195
196 // Add some metrics
197 for (int i = 0; i < 5; ++i) {
198 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
199 strategy.add_metric(std::move(metric));
200 }
201
202 EXPECT_EQ(strategy.size(), 5);
203 EXPECT_FALSE(strategy.should_flush()); // Too soon to flush
204
205 // Wait for flush interval
206 std::this_thread::sleep_for(std::chrono::milliseconds(150));
207
208 EXPECT_TRUE(strategy.should_flush()); // Should flush after interval
209
210 // Flush and verify
211 auto flush_result = strategy.flush();
212 EXPECT_TRUE(flush_result);
213 EXPECT_EQ(flush_result.value().size(), 5);
214 EXPECT_EQ(strategy.size(), 0);
215}

◆ TEST_F() [16/16]

TEST_F ( BufferingStrategiesTest ,
TimeBasedStrategyBufferFull  )

Definition at line 217 of file test_buffering_strategies.cpp.

217 {
218 buffering_config config;
219 config.strategy = buffering_strategy_type::time_based;
220 config.max_buffer_size = 3;
221 config.flush_interval = std::chrono::seconds(10); // Long interval
222
223 time_based_strategy strategy(config);
224
225 // Fill buffer beyond capacity
226 for (int i = 0; i < 5; ++i) {
227 auto metric = create_test_metric("test_" + std::to_string(i), static_cast<double>(i));
228 strategy.add_metric(std::move(metric));
229 }
230
231 // Should trigger flush due to buffer full condition
232 EXPECT_TRUE(strategy.should_flush());
233}