61 buffering_config invalid_config;
62 invalid_config.max_buffer_size = 0;
64 auto validation = invalid_config.validate();
65 EXPECT_FALSE(validation);
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);
73 validation = valid_config.validate();
74 EXPECT_TRUE(validation);
77 buffering_config invalid_threshold;
78 invalid_threshold.max_buffer_size = 100;
79 invalid_threshold.flush_threshold_size = 200;
81 validation = invalid_threshold.validate();
82 EXPECT_FALSE(validation);
87 buffering_config config;
88 config.strategy = buffering_strategy_type::immediate;
90 immediate_strategy strategy(config);
93 EXPECT_EQ(strategy.size(), 0);
94 EXPECT_FALSE(strategy.should_flush());
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());
102 EXPECT_EQ(strategy.size(), 0);
105 auto flush_result = strategy.flush();
106 EXPECT_TRUE(flush_result);
107 EXPECT_TRUE(flush_result.value().empty());
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);
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;
124 fixed_size_strategy strategy(config);
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());
133 EXPECT_EQ(strategy.size(), 3);
134 EXPECT_TRUE(strategy.should_flush());
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());
143 EXPECT_EQ(strategy.size(), 5);
146 auto flush_result = strategy.flush();
147 EXPECT_TRUE(flush_result);
148 EXPECT_EQ(flush_result.value().size(), 5);
151 EXPECT_EQ(strategy.size(), 0);
152 EXPECT_FALSE(strategy.should_flush());
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);
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;
167 fixed_size_strategy strategy(config);
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));
175 EXPECT_EQ(strategy.size(), 3);
178 auto metric = create_test_metric(
"test_overflow", 999.0);
179 strategy.add_metric(std::move(
metric));
181 EXPECT_EQ(strategy.size(), 3);
183 const auto& stats = strategy.get_statistics();
184 EXPECT_GT(stats.items_dropped_overflow.load(), 0);
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);
194 time_based_strategy strategy(config);
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));
202 EXPECT_EQ(strategy.size(), 5);
203 EXPECT_FALSE(strategy.should_flush());
206 std::this_thread::sleep_for(std::chrono::milliseconds(150));
208 EXPECT_TRUE(strategy.should_flush());
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);
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);
223 time_based_strategy strategy(config);
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));
232 EXPECT_TRUE(strategy.should_flush());
237 buffering_config config;
238 config.strategy = buffering_strategy_type::priority_based;
239 config.max_buffer_size = 10;
240 config.flush_priority_threshold = 200;
242 priority_based_strategy strategy(config);
245 std::vector<uint8_t> priorities = {100, 150, 250, 50, 220};
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));
252 EXPECT_EQ(strategy.size(), 5);
253 EXPECT_TRUE(strategy.should_flush());
256 auto flush_result = strategy.flush();
257 EXPECT_TRUE(flush_result);
259 const auto& flushed_items = flush_result.value();
260 EXPECT_EQ(flushed_items.size(), 5);
263 for (
size_t i = 1; i < flushed_items.size(); ++i) {
264 EXPECT_GE(flushed_items[i-1].priority, flushed_items[i].priority);
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;
274 priority_based_strategy strategy(config);
277 std::vector<uint8_t> priorities = {100, 200, 150, 250, 50};
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));
284 EXPECT_EQ(strategy.size(), 3);
287 auto flush_result = strategy.flush();
288 EXPECT_TRUE(flush_result);
290 const auto& flushed_items = flush_result.value();
291 EXPECT_EQ(flushed_items.size(), 3);
294 for (
const auto& item : flushed_items) {
295 EXPECT_GT(item.priority, 100);
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);
307 adaptive_strategy strategy(config);
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));
315 EXPECT_EQ(strategy.size(), 20);
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));
324 EXPECT_TRUE(strategy.should_flush());
330 buffering_config immediate_config;
331 immediate_config.strategy = buffering_strategy_type::immediate;
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);
338 buffering_config fixed_config;
339 fixed_config.strategy = buffering_strategy_type::fixed_size;
340 fixed_config.max_buffer_size = 1024;
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);
347 buffering_config invalid_config;
348 invalid_config.max_buffer_size = 0;
350 EXPECT_THROW(create_buffering_strategy(invalid_config), std::invalid_argument);
355 auto configs = create_default_buffering_configs();
357 EXPECT_GT(configs.size(), 0);
360 for (
const auto& config : configs) {
361 auto validation = config.validate();
362 EXPECT_TRUE(validation) <<
"Default configuration validation failed";
365 EXPECT_NO_THROW(create_buffering_strategy(config));
371 auto storage = std::make_shared<metric_storage>();
373 buffer_manager_config config;
374 config.enable_automatic_flushing =
false;
376 buffer_manager manager(config,
storage);
379 for (
int i = 0; i < 5; ++i) {
383 auto result = manager.add_metric(
"cpu_usage", std::move(
metric));
384 EXPECT_TRUE(result.is_ok());
388 auto size_result = manager.get_buffer_size(
"cpu_usage");
389 EXPECT_TRUE(size_result);
390 EXPECT_EQ(size_result.value(), 5);
393 auto flush_result = manager.force_flush(
"cpu_usage");
394 EXPECT_TRUE(flush_result);
397 size_result = manager.get_buffer_size(
"cpu_usage");
398 EXPECT_TRUE(size_result);
399 EXPECT_EQ(size_result.value(), 0);
403 buffer_manager manager;
405 std::vector<std::string> metric_names = {
"cpu_usage",
"memory_usage",
"disk_io"};
408 for (
const auto& metric_name : metric_names) {
409 for (
int i = 0; i < 3; ++i) {
413 manager.add_metric(metric_name, std::move(
metric));
418 auto buffered_metrics = manager.get_buffered_metrics();
419 EXPECT_EQ(buffered_metrics.size(), 3);
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());
427 manager.force_flush_all();
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);
438 buffer_manager manager;
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;
446 auto result = manager.configure_metric_buffer(
"high_priority_metric", custom_config);
447 EXPECT_TRUE(result.is_ok());
450 std::vector<uint8_t> priorities = {100, 250, 150};
452 for (
size_t i = 0; i < priorities.size(); ++i) {
456 auto add_result = manager.add_metric(
"high_priority_metric", std::move(
metric), priorities[i]);
457 EXPECT_TRUE(add_result);
461 auto stats_result = manager.get_buffer_statistics(
"high_priority_metric");
462 EXPECT_TRUE(stats_result);
466 auto storage = std::make_shared<metric_storage>();
468 buffer_manager_config config;
469 config.background_check_interval = std::chrono::milliseconds(50);
470 config.enable_automatic_flushing =
true;
472 buffer_manager manager(config,
storage);
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;
480 manager.configure_metric_buffer(
"timed_metric", time_config);
483 auto start_result = manager.start_background_processing();
484 EXPECT_TRUE(start_result);
487 for (
int i = 0; i < 5; ++i) {
491 manager.add_metric(
"timed_metric", std::move(
metric));
495 std::this_thread::sleep_for(std::chrono::milliseconds(200));
498 auto size_result = manager.get_buffer_size(
"timed_metric");
499 EXPECT_TRUE(size_result);
500 EXPECT_EQ(size_result.value(), 0);
503 manager.stop_background_processing();
508 buffer_manager manager;
510 const int num_threads = 4;
511 const int metrics_per_thread = 100;
512 std::vector<std::thread> threads;
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";
519 for (
int i = 0; i < metrics_per_thread; ++i) {
523 manager.add_metric(metric_name, std::move(
metric));
526 std::this_thread::sleep_for(std::chrono::microseconds(1));
532 for (
auto& thread : threads) {
537 auto buffered_metrics = manager.get_buffered_metrics();
538 EXPECT_EQ(buffered_metrics.size(), num_threads);
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);