1mod diff;
7mod feature_flags;
8mod merge;
9mod network;
10mod rate_limit;
11mod retry;
12mod storage;
13mod timeout;
14
15pub use diff::{ConfigChange, ConfigDiff};
16pub use feature_flags::{FeatureFlags, FeatureFlagsBuilder};
17pub use merge::ConfigMerge;
18pub use network::{NetworkConfig, NetworkConfigBuilder};
19pub use rate_limit::{RateLimitConfig, RateLimitConfigBuilder};
20pub use retry::{RetryConfig, RetryConfigBuilder};
21pub use storage::{StorageConfig, StorageConfigBuilder};
22pub use timeout::{TimeoutConfig, TimeoutConfigBuilder};
23
24#[cfg(test)]
25mod tests {
26 use super::*;
27
28 #[test]
29 fn test_network_config_default() {
30 let config = NetworkConfig::default();
31 assert_eq!(config.max_connections, 100);
32 assert_eq!(config.connection_timeout_ms, 10_000);
33 assert!(config.enable_relay);
34 assert!(config.enable_dht);
35 }
36
37 #[test]
38 fn test_network_config_builder() {
39 let config = NetworkConfigBuilder::new()
40 .max_connections(50)
41 .connection_timeout_ms(5000)
42 .enable_relay(false)
43 .add_bootstrap_peer("/ip4/127.0.0.1/tcp/4001")
44 .build();
45
46 assert_eq!(config.max_connections, 50);
47 assert_eq!(config.connection_timeout_ms, 5000);
48 assert!(!config.enable_relay);
49 assert_eq!(config.bootstrap_peers.len(), 1);
50 }
51
52 #[test]
53 fn test_storage_config_default() {
54 let config = StorageConfig::default();
55 assert_eq!(config.data_dir, "./chie_data");
56 assert_eq!(config.max_cache_size_bytes, 10 * 1024 * 1024 * 1024);
57 assert!(config.enable_persistence);
58 assert!(config.enable_compression);
59 }
60
61 #[test]
62 fn test_storage_config_builder() {
63 let config = StorageConfigBuilder::new()
64 .data_dir("/var/lib/chie")
65 .max_cache_size_gb(20)
66 .enable_compression(false)
67 .sync_interval_secs(600)
68 .build();
69
70 assert_eq!(config.data_dir, "/var/lib/chie");
71 assert_eq!(config.max_cache_size_bytes, 20 * 1024 * 1024 * 1024);
72 assert!(!config.enable_compression);
73 assert_eq!(config.sync_interval_secs, 600);
74 }
75
76 #[test]
77 fn test_rate_limit_config_default() {
78 let config = RateLimitConfig::default();
79 assert_eq!(config.max_requests, 100);
80 assert_eq!(config.window_secs, 60);
81 assert_eq!(config.burst_size, 20);
82 assert!(config.enabled);
83 }
84
85 #[test]
86 fn test_rate_limit_config_builder() {
87 let config = RateLimitConfigBuilder::new()
88 .max_requests(200)
89 .window_secs(120)
90 .burst_size(50)
91 .enabled(false)
92 .build();
93
94 assert_eq!(config.max_requests, 200);
95 assert_eq!(config.window_secs, 120);
96 assert_eq!(config.burst_size, 50);
97 assert!(!config.enabled);
98 }
99
100 #[test]
101 fn test_retry_config_default() {
102 let config = RetryConfig::default();
103 assert_eq!(config.max_attempts, 3);
104 assert_eq!(config.initial_backoff_ms, 100);
105 assert_eq!(config.max_backoff_ms, 30_000);
106 assert_eq!(config.multiplier, 2.0);
107 assert!(config.enable_jitter);
108 }
109
110 #[test]
111 fn test_retry_config_builder() {
112 let config = RetryConfigBuilder::new()
113 .max_attempts(5)
114 .initial_backoff_ms(200)
115 .max_backoff_ms(60_000)
116 .multiplier(3.0)
117 .enable_jitter(false)
118 .build();
119
120 assert_eq!(config.max_attempts, 5);
121 assert_eq!(config.initial_backoff_ms, 200);
122 assert_eq!(config.max_backoff_ms, 60_000);
123 assert_eq!(config.multiplier, 3.0);
124 assert!(!config.enable_jitter);
125 }
126
127 #[test]
128 fn test_network_config_serde() {
129 let config = NetworkConfigBuilder::new().max_connections(75).build();
130
131 let json = serde_json::to_string(&config).unwrap();
132 let decoded: NetworkConfig = serde_json::from_str(&json).unwrap();
133
134 assert_eq!(decoded.max_connections, 75);
135 }
136
137 #[test]
138 fn test_storage_config_serde() {
139 let config = StorageConfigBuilder::new().data_dir("/custom/path").build();
140
141 let json = serde_json::to_string(&config).unwrap();
142 let decoded: StorageConfig = serde_json::from_str(&json).unwrap();
143
144 assert_eq!(decoded.data_dir, "/custom/path");
145 }
146
147 #[test]
148 fn test_builder_chaining() {
149 let config = NetworkConfigBuilder::new()
150 .max_connections(100)
151 .connection_timeout_ms(10_000)
152 .request_timeout_ms(30_000)
153 .enable_relay(true)
154 .enable_dht(true)
155 .add_bootstrap_peer("/ip4/1.2.3.4/tcp/4001")
156 .add_bootstrap_peer("/ip4/5.6.7.8/tcp/4001")
157 .add_listen_addr("/ip4/0.0.0.0/tcp/0")
158 .build();
159
160 assert_eq!(config.bootstrap_peers.len(), 2);
161 assert_eq!(config.listen_addrs.len(), 2); }
163
164 #[test]
165 fn test_retry_config_is_exhausted() {
166 let config = RetryConfig::default();
167 assert!(!config.is_exhausted(0));
168 assert!(!config.is_exhausted(1));
169 assert!(!config.is_exhausted(2));
170 assert!(config.is_exhausted(3));
171 assert!(config.is_exhausted(4));
172 }
173
174 #[test]
175 fn test_retry_config_next_backoff() {
176 let config = RetryConfigBuilder::new()
177 .initial_backoff_ms(100)
178 .max_backoff_ms(10_000)
179 .multiplier(2.0)
180 .enable_jitter(false)
181 .build();
182
183 assert_eq!(config.next_backoff_ms(0), 100);
184 assert_eq!(config.next_backoff_ms(1), 200);
185 assert_eq!(config.next_backoff_ms(2), 400);
186 assert_eq!(config.next_backoff_ms(3), 800);
187 assert_eq!(config.next_backoff_ms(10), 10_000); }
189
190 #[test]
191 fn test_retry_config_next_backoff_with_jitter() {
192 let config = RetryConfig::default();
193
194 let delay1 = config.next_backoff_ms(0);
196 let delay2 = config.next_backoff_ms(0);
197
198 assert!((75..=125).contains(&delay1));
200 assert!((75..=125).contains(&delay2));
201 }
202
203 #[test]
204 fn test_timeout_config_default() {
205 let config = TimeoutConfig::default();
206 assert_eq!(config.default_timeout_ms, 30_000);
207 assert_eq!(config.connection_timeout_ms, 10_000);
208 assert_eq!(config.read_timeout_ms, 60_000);
209 assert_eq!(config.write_timeout_ms, 60_000);
210 assert_eq!(config.idle_timeout_ms, 300_000);
211 assert_eq!(config.keepalive_interval_ms, 60_000);
212 assert!(config.keepalive_enabled());
213 assert!(config.idle_timeout_enabled());
214 }
215
216 #[test]
217 fn test_timeout_config_fast() {
218 let config = TimeoutConfig::fast();
219 assert_eq!(config.default_timeout_ms, 5_000);
220 assert_eq!(config.connection_timeout_ms, 3_000);
221 assert!(config.keepalive_enabled());
222 }
223
224 #[test]
225 fn test_timeout_config_slow() {
226 let config = TimeoutConfig::slow();
227 assert_eq!(config.default_timeout_ms, 120_000);
228 assert_eq!(config.connection_timeout_ms, 30_000);
229 assert!(config.keepalive_enabled());
230 }
231
232 #[test]
233 fn test_timeout_config_builder() {
234 let config = TimeoutConfigBuilder::new()
235 .default_timeout_ms(15_000)
236 .connection_timeout_ms(5_000)
237 .read_timeout_ms(30_000)
238 .write_timeout_ms(30_000)
239 .idle_timeout_ms(0) .keepalive_interval_ms(0) .build();
242
243 assert_eq!(config.default_timeout_ms, 15_000);
244 assert_eq!(config.connection_timeout_ms, 5_000);
245 assert!(!config.idle_timeout_enabled());
246 assert!(!config.keepalive_enabled());
247 }
248
249 #[test]
250 fn test_timeout_config_serde() {
251 let config = TimeoutConfigBuilder::new()
252 .default_timeout_ms(20_000)
253 .build();
254
255 let json = serde_json::to_string(&config).unwrap();
256 let decoded: TimeoutConfig = serde_json::from_str(&json).unwrap();
257
258 assert_eq!(decoded.default_timeout_ms, 20_000);
259 }
260
261 #[test]
263 fn test_network_config_validate_success() {
264 let config = NetworkConfig::default();
265 assert!(config.validate().is_ok());
266 }
267
268 #[test]
269 fn test_network_config_validate_zero_max_connections() {
270 let config = NetworkConfig {
271 max_connections: 0,
272 ..Default::default()
273 };
274 assert!(config.validate().is_err());
275 }
276
277 #[test]
278 fn test_network_config_validate_zero_connection_timeout() {
279 let config = NetworkConfig {
280 connection_timeout_ms: 0,
281 ..Default::default()
282 };
283 assert!(config.validate().is_err());
284 }
285
286 #[test]
287 fn test_network_config_validate_empty_listen_addrs() {
288 let mut config = NetworkConfig::default();
289 config.listen_addrs.clear();
290 assert!(config.validate().is_err());
291 }
292
293 #[test]
294 fn test_storage_config_validate_success() {
295 let config = StorageConfig::default();
296 assert!(config.validate().is_ok());
297 }
298
299 #[test]
300 fn test_storage_config_validate_empty_data_dir() {
301 let config = StorageConfig {
302 data_dir: String::new(),
303 ..Default::default()
304 };
305 assert!(config.validate().is_err());
306 }
307
308 #[test]
309 fn test_storage_config_validate_zero_cache_size() {
310 let config = StorageConfig {
311 max_cache_size_bytes: 0,
312 ..Default::default()
313 };
314 assert!(config.validate().is_err());
315 }
316
317 #[test]
318 fn test_rate_limit_config_validate_success() {
319 let config = RateLimitConfig::default();
320 assert!(config.validate().is_ok());
321 }
322
323 #[test]
324 fn test_rate_limit_config_validate_disabled() {
325 let config = RateLimitConfig {
326 enabled: false,
327 max_requests: 0, ..Default::default()
329 };
330 assert!(config.validate().is_ok());
331 }
332
333 #[test]
334 fn test_rate_limit_config_validate_zero_max_requests() {
335 let config = RateLimitConfig {
336 max_requests: 0,
337 ..Default::default()
338 };
339 assert!(config.validate().is_err());
340 }
341
342 #[test]
343 fn test_rate_limit_config_validate_zero_window() {
344 let config = RateLimitConfig {
345 window_secs: 0,
346 ..Default::default()
347 };
348 assert!(config.validate().is_err());
349 }
350
351 #[test]
352 fn test_rate_limit_config_validate_burst_exceeds_max() {
353 let config = RateLimitConfig {
354 max_requests: 100,
355 burst_size: 101,
356 ..Default::default()
357 };
358 assert!(config.validate().is_err());
359 }
360
361 #[test]
362 fn test_retry_config_validate_success() {
363 let config = RetryConfig::default();
364 assert!(config.validate().is_ok());
365 }
366
367 #[test]
368 fn test_retry_config_validate_zero_max_attempts() {
369 let config = RetryConfig {
370 max_attempts: 0,
371 ..Default::default()
372 };
373 assert!(config.validate().is_err());
374 }
375
376 #[test]
377 fn test_retry_config_validate_zero_initial_backoff() {
378 let config = RetryConfig {
379 initial_backoff_ms: 0,
380 ..Default::default()
381 };
382 assert!(config.validate().is_err());
383 }
384
385 #[test]
386 fn test_retry_config_validate_max_less_than_initial() {
387 let config = RetryConfig {
388 initial_backoff_ms: 1000,
389 max_backoff_ms: 500,
390 ..Default::default()
391 };
392 assert!(config.validate().is_err());
393 }
394
395 #[test]
396 fn test_retry_config_validate_zero_multiplier() {
397 let config = RetryConfig {
398 multiplier: 0.0,
399 ..Default::default()
400 };
401 assert!(config.validate().is_err());
402 }
403
404 #[test]
405 fn test_retry_config_validate_negative_multiplier() {
406 let config = RetryConfig {
407 multiplier: -1.0,
408 ..Default::default()
409 };
410 assert!(config.validate().is_err());
411 }
412
413 #[test]
414 fn test_timeout_config_validate_success() {
415 let config = TimeoutConfig::default();
416 assert!(config.validate().is_ok());
417 }
418
419 #[test]
420 fn test_timeout_config_validate_zero_default_timeout() {
421 let config = TimeoutConfig {
422 default_timeout_ms: 0,
423 ..Default::default()
424 };
425 assert!(config.validate().is_err());
426 }
427
428 #[test]
429 fn test_timeout_config_validate_zero_connection_timeout() {
430 let config = TimeoutConfig {
431 connection_timeout_ms: 0,
432 ..Default::default()
433 };
434 assert!(config.validate().is_err());
435 }
436
437 #[test]
438 fn test_timeout_config_validate_zero_read_timeout() {
439 let config = TimeoutConfig {
440 read_timeout_ms: 0,
441 ..Default::default()
442 };
443 assert!(config.validate().is_err());
444 }
445
446 #[test]
447 fn test_timeout_config_validate_zero_write_timeout() {
448 let config = TimeoutConfig {
449 write_timeout_ms: 0,
450 ..Default::default()
451 };
452 assert!(config.validate().is_err());
453 }
454
455 #[test]
456 fn test_timeout_config_validate_zero_idle_ok() {
457 let config = TimeoutConfig {
458 idle_timeout_ms: 0, ..Default::default()
460 };
461 assert!(config.validate().is_ok());
462 }
463
464 #[test]
465 fn test_timeout_config_validate_zero_keepalive_ok() {
466 let config = TimeoutConfig {
467 keepalive_interval_ms: 0, ..Default::default()
469 };
470 assert!(config.validate().is_ok());
471 }
472
473 #[test]
475 fn test_feature_flags_default() {
476 let flags = FeatureFlags::default();
477 assert!(!flags.experimental);
478 assert!(!flags.beta);
479 assert!(!flags.enhanced_telemetry);
480 assert!(!flags.performance_profiling);
481 assert!(!flags.debug_mode);
482 assert!(flags.compression_optimization);
483 assert!(flags.adaptive_retry);
484 }
485
486 #[test]
487 fn test_feature_flags_none() {
488 let flags = FeatureFlags::none();
489 assert!(!flags.experimental);
490 assert!(!flags.beta);
491 assert!(!flags.compression_optimization);
492 assert!(!flags.adaptive_retry);
493 }
494
495 #[test]
496 fn test_feature_flags_all() {
497 let flags = FeatureFlags::all();
498 assert!(flags.experimental);
499 assert!(flags.beta);
500 assert!(flags.enhanced_telemetry);
501 assert!(flags.performance_profiling);
502 assert!(flags.debug_mode);
503 assert!(flags.compression_optimization);
504 assert!(flags.adaptive_retry);
505 }
506
507 #[test]
508 fn test_feature_flags_has_unstable_features() {
509 let mut flags = FeatureFlags::default();
510 assert!(!flags.has_unstable_features());
511
512 flags.experimental = true;
513 assert!(flags.has_unstable_features());
514
515 flags.experimental = false;
516 flags.beta = true;
517 assert!(flags.has_unstable_features());
518 }
519
520 #[test]
521 fn test_feature_flags_has_diagnostic_features() {
522 let mut flags = FeatureFlags::default();
523 assert!(!flags.has_diagnostic_features());
524
525 flags.debug_mode = true;
526 assert!(flags.has_diagnostic_features());
527
528 flags.debug_mode = false;
529 flags.performance_profiling = true;
530 assert!(flags.has_diagnostic_features());
531
532 flags.performance_profiling = false;
533 flags.enhanced_telemetry = true;
534 assert!(flags.has_diagnostic_features());
535 }
536
537 #[test]
538 fn test_feature_flags_builder() {
539 let flags = FeatureFlagsBuilder::new()
540 .experimental(true)
541 .beta(true)
542 .debug_mode(true)
543 .build();
544
545 assert!(flags.experimental);
546 assert!(flags.beta);
547 assert!(flags.debug_mode);
548 assert!(!flags.performance_profiling);
549 }
550
551 #[test]
552 fn test_feature_flags_serde() {
553 let flags = FeatureFlagsBuilder::new()
554 .experimental(true)
555 .compression_optimization(false)
556 .build();
557
558 let json = serde_json::to_string(&flags).unwrap();
559 let decoded: FeatureFlags = serde_json::from_str(&json).unwrap();
560
561 assert!(decoded.experimental);
562 assert!(!decoded.compression_optimization);
563 }
564
565 #[test]
567 fn test_config_change_new() {
568 let change = ConfigChange::new("max_connections", &100, &200);
569 assert_eq!(change.field, "max_connections");
570 assert_eq!(change.old_value, "100");
571 assert_eq!(change.new_value, "200");
572 }
573
574 #[test]
575 fn test_config_change_serde() {
576 let change = ConfigChange::new("enable_relay", &true, &false);
577 let json = serde_json::to_string(&change).unwrap();
578 let decoded: ConfigChange = serde_json::from_str(&json).unwrap();
579
580 assert_eq!(decoded.field, "enable_relay");
581 assert_eq!(decoded.old_value, "true");
582 assert_eq!(decoded.new_value, "false");
583 }
584
585 #[test]
587 fn test_config_diff_network_no_changes() {
588 let config1 = NetworkConfig::default();
589 let config2 = NetworkConfig::default();
590
591 let changes = ConfigDiff::network_config(&config1, &config2);
592 assert!(changes.is_empty());
593 }
594
595 #[test]
596 fn test_config_diff_network_single_change() {
597 let config1 = NetworkConfig::default();
598 let config2 = NetworkConfig {
599 max_connections: 200,
600 ..Default::default()
601 };
602
603 let changes = ConfigDiff::network_config(&config1, &config2);
604 assert_eq!(changes.len(), 1);
605 assert_eq!(changes[0].field, "max_connections");
606 assert_eq!(changes[0].old_value, "100");
607 assert_eq!(changes[0].new_value, "200");
608 }
609
610 #[test]
611 fn test_config_diff_network_multiple_changes() {
612 let config1 = NetworkConfig::default();
613 let config2 = NetworkConfig {
614 max_connections: 200,
615 enable_relay: false,
616 connection_timeout_ms: 20_000,
617 ..Default::default()
618 };
619
620 let changes = ConfigDiff::network_config(&config1, &config2);
621 assert_eq!(changes.len(), 3);
622
623 let field_names: Vec<&str> = changes.iter().map(|c| c.field.as_str()).collect();
624 assert!(field_names.contains(&"max_connections"));
625 assert!(field_names.contains(&"enable_relay"));
626 assert!(field_names.contains(&"connection_timeout_ms"));
627 }
628
629 #[test]
630 fn test_config_diff_network_vec_changes() {
631 let config1 = NetworkConfig {
632 bootstrap_peers: vec!["peer1".to_string()],
633 ..Default::default()
634 };
635
636 let config2 = NetworkConfig {
637 bootstrap_peers: vec!["peer1".to_string(), "peer2".to_string()],
638 ..Default::default()
639 };
640
641 let changes = ConfigDiff::network_config(&config1, &config2);
642 assert_eq!(changes.len(), 1);
643 assert_eq!(changes[0].field, "bootstrap_peers");
644 }
645
646 #[test]
648 fn test_config_diff_retry_no_changes() {
649 let config1 = RetryConfig::default();
650 let config2 = RetryConfig::default();
651
652 let changes = ConfigDiff::retry_config(&config1, &config2);
653 assert!(changes.is_empty());
654 }
655
656 #[test]
657 fn test_config_diff_retry_single_change() {
658 let config1 = RetryConfig::default();
659 let config2 = RetryConfig {
660 max_attempts: 5,
661 ..Default::default()
662 };
663
664 let changes = ConfigDiff::retry_config(&config1, &config2);
665 assert_eq!(changes.len(), 1);
666 assert_eq!(changes[0].field, "max_attempts");
667 assert_eq!(changes[0].old_value, "3");
668 assert_eq!(changes[0].new_value, "5");
669 }
670
671 #[test]
672 fn test_config_diff_retry_multiple_changes() {
673 let config1 = RetryConfig::default();
674 let config2 = RetryConfig {
675 max_attempts: 5,
676 multiplier: 3.0,
677 enable_jitter: false,
678 ..Default::default()
679 };
680
681 let changes = ConfigDiff::retry_config(&config1, &config2);
682 assert_eq!(changes.len(), 3);
683
684 let field_names: Vec<&str> = changes.iter().map(|c| c.field.as_str()).collect();
685 assert!(field_names.contains(&"max_attempts"));
686 assert!(field_names.contains(&"multiplier"));
687 assert!(field_names.contains(&"enable_jitter"));
688 }
689
690 #[test]
692 fn test_config_diff_feature_flags_no_changes() {
693 let flags1 = FeatureFlags::default();
694 let flags2 = FeatureFlags::default();
695
696 let changes = ConfigDiff::feature_flags(&flags1, &flags2);
697 assert!(changes.is_empty());
698 }
699
700 #[test]
701 fn test_config_diff_feature_flags_single_change() {
702 let flags1 = FeatureFlags::default();
703 let flags2 = FeatureFlags {
704 experimental: true,
705 ..Default::default()
706 };
707
708 let changes = ConfigDiff::feature_flags(&flags1, &flags2);
709 assert_eq!(changes.len(), 1);
710 assert_eq!(changes[0].field, "experimental");
711 assert_eq!(changes[0].old_value, "false");
712 assert_eq!(changes[0].new_value, "true");
713 }
714
715 #[test]
716 fn test_config_diff_feature_flags_multiple_changes() {
717 let flags1 = FeatureFlags::default();
718 let flags2 = FeatureFlags {
719 experimental: true,
720 beta: true,
721 debug_mode: true,
722 ..Default::default()
723 };
724
725 let changes = ConfigDiff::feature_flags(&flags1, &flags2);
726 assert_eq!(changes.len(), 3);
727
728 let field_names: Vec<&str> = changes.iter().map(|c| c.field.as_str()).collect();
729 assert!(field_names.contains(&"experimental"));
730 assert!(field_names.contains(&"beta"));
731 assert!(field_names.contains(&"debug_mode"));
732 }
733
734 #[test]
736 fn test_config_merge_retry_complete_override() {
737 let base = RetryConfig::default();
738 let override_config = RetryConfig {
739 max_attempts: 10,
740 initial_backoff_ms: 500,
741 max_backoff_ms: 60_000,
742 multiplier: 3.0,
743 enable_jitter: false,
744 };
745
746 let merged = ConfigMerge::retry_config(&base, &override_config);
747
748 assert_eq!(merged.max_attempts, 10);
749 assert_eq!(merged.initial_backoff_ms, 500);
750 assert_eq!(merged.max_backoff_ms, 60_000);
751 assert!((merged.multiplier - 3.0).abs() < f64::EPSILON);
752 assert!(!merged.enable_jitter);
753 }
754
755 #[test]
756 fn test_config_merge_retry_partial_override() {
757 let base = RetryConfig {
758 max_attempts: 5,
759 initial_backoff_ms: 200,
760 max_backoff_ms: 40_000,
761 multiplier: 2.5,
762 enable_jitter: true,
763 };
764
765 let override_config = RetryConfig {
766 max_attempts: 10,
767 ..RetryConfig::default()
768 };
769
770 let merged = ConfigMerge::retry_config(&base, &override_config);
771
772 assert_eq!(merged.max_attempts, 10);
774 assert_eq!(
775 merged.initial_backoff_ms,
776 RetryConfig::default().initial_backoff_ms
777 );
778 }
779
780 #[test]
782 fn test_config_merge_feature_flags_override_all() {
783 let base = FeatureFlags::all();
784 let override_flags = FeatureFlags::none();
785
786 let merged = ConfigMerge::feature_flags(&base, &override_flags, true);
787
788 assert!(!merged.experimental);
790 assert!(!merged.beta);
791 assert!(!merged.enhanced_telemetry);
792 assert!(!merged.compression_optimization);
793 }
794
795 #[test]
796 fn test_config_merge_feature_flags_or_merge() {
797 let base = FeatureFlags {
798 experimental: true,
799 beta: false,
800 enhanced_telemetry: false,
801 performance_profiling: false,
802 debug_mode: false,
803 compression_optimization: true,
804 adaptive_retry: false,
805 };
806
807 let override_flags = FeatureFlags {
808 experimental: false,
809 beta: true,
810 enhanced_telemetry: false,
811 performance_profiling: true,
812 debug_mode: false,
813 compression_optimization: false,
814 adaptive_retry: true,
815 };
816
817 let merged = ConfigMerge::feature_flags(&base, &override_flags, false);
818
819 assert!(merged.experimental); assert!(merged.beta); assert!(!merged.enhanced_telemetry); assert!(merged.performance_profiling); assert!(!merged.debug_mode); assert!(merged.compression_optimization); assert!(merged.adaptive_retry); }
828
829 #[test]
830 fn test_config_merge_feature_flags_both_enabled() {
831 let base = FeatureFlags::all();
832 let override_flags = FeatureFlags {
833 experimental: true,
834 beta: true,
835 ..FeatureFlags::none()
836 };
837
838 let merged = ConfigMerge::feature_flags(&base, &override_flags, false);
839
840 assert!(merged.experimental);
842 assert!(merged.beta);
843 assert!(merged.enhanced_telemetry);
844 assert!(merged.performance_profiling);
845 assert!(merged.debug_mode);
846 assert!(merged.compression_optimization);
847 assert!(merged.adaptive_retry);
848 }
849}