## Coverage Report

#### Created: 2026-01-25 15:05

next uncovered line (L), next uncovered region (R), next uncovered branch (B)

    /home/noah/src/trueno/src/brick/connection.rs

    Line
    Count
    Source
    1
    //! Connection Management
    2
    //!
    3
    //! AWP-06: Managed connections with TTL, idle timeout, and health tracking.
    4
    //! AWP-10: Keep-Alive normalization for HTTP connections.
    5
    //! AWP-12: Bitflags connection state for efficient state tracking.
    6
    7
    use std::time::{Duration, Instant};
    8
    9
    // ----------------------------------------------------------------------------
    10
    // AWP-06: Connection TTL + Health Check
    11
    // ----------------------------------------------------------------------------
    12
    13
    /// Connection with TTL and health tracking.
    14
    #[derive(Debug)]
    15
    pub struct ManagedConnection<T> {
    16
        /// The underlying connection
    17
        inner: T,
    18
        /// When the connection was created
    19
        created_at: Instant,
    20
        /// When the connection was last used
    21
        last_used: Instant,
    22
        /// Maximum lifetime (TTL)
    23
        max_lifetime: Duration,
    24
        /// Maximum idle time
    25
        max_idle: Duration,
    26
        /// Health check failures
    27
        health_failures: usize,
    28
    }
    29
    30
    impl<T> ManagedConnection<T> {
    31
        /// Create a new managed connection.
    32
    0
        pub fn new(inner: T, max_lifetime: Duration, max_idle: Duration) -> Self {
    33
    0
            let now = Instant::now();
    34
    0
            Self {
    35
    0
                inner,
    36
    0
                created_at: now,
    37
    0
                last_used: now,
    38
    0
                max_lifetime,
    39
    0
                max_idle,
    40
    0
                health_failures: 0,
    41
    0
            }
    42
    0
        }
    43
    44
        /// Check if the connection is still valid.
    45
        #[must_use]
    46
    0
        pub fn is_valid(&self) -> bool {
    47
    0
            let now = Instant::now();
    48
    0
            let not_expired = now.duration_since(self.created_at) < self.max_lifetime;
    49
    0
            let not_idle = now.duration_since(self.last_used) < self.max_idle;
    50
    0
            let healthy = self.health_failures < 3;
    51
    0
            not_expired && not_idle && healthy
    52
    0
        }
    53
    54
        /// Check if the connection has expired (TTL exceeded).
    55
        #[must_use]
    56
    0
        pub fn is_expired(&self) -> bool {
    57
    0
            self.created_at.elapsed() >= self.max_lifetime
    58
    0
        }
    59
    60
        /// Check if the connection is idle.
    61
        #[must_use]
    62
    0
        pub fn is_idle(&self) -> bool {
    63
    0
            self.last_used.elapsed() >= self.max_idle
    64
    0
        }
    65
    66
        /// Mark the connection as used.
    67
    0
        pub fn touch(&mut self) {
    68
    0
            self.last_used = Instant::now();
    69
    0
        }
    70
    71
        /// Record a health check failure.
    72
    0
        pub fn record_health_failure(&mut self) {
    73
    0
            self.health_failures += 1;
    74
    0
        }
    75
    76
        /// Reset health failure count.
    77
    0
        pub fn reset_health(&mut self) {
    78
    0
            self.health_failures = 0;
    79
    0
        }
    80
    81
        /// Get the underlying connection.
    82
    0
        pub fn inner(&self) -> &T {
    83
    0
            &self.inner
    84
    0
        }
    85
    86
        /// Get mutable access to the underlying connection.
    87
    0
        pub fn inner_mut(&mut self) -> &mut T {
    88
    0
            &mut self.inner
    89
    0
        }
    90
    91
        /// Consume and return the underlying connection.
    92
    0
        pub fn into_inner(self) -> T {
    93
    0
            self.inner
    94
    0
        }
    95
    96
        /// Get connection age.
    97
        #[must_use]
    98
    0
        pub fn age(&self) -> Duration {
    99
    0
            self.created_at.elapsed()
    100
    0
        }
    101
    102
        /// Get idle time.
    103
        #[must_use]
    104
    0
        pub fn idle_time(&self) -> Duration {
    105
    0
            self.last_used.elapsed()
    106
    0
        }
    107
    108
        /// Get health failure count (for testing/diagnostics).
    109
        #[must_use]
    110
    0
        pub fn health_failures(&self) -> usize {
    111
    0
            self.health_failures
    112
    0
        }
    113
    }
    114
    115
    // ----------------------------------------------------------------------------
    116
    // AWP-10: Keep-Alive Normalization
    117
    // ----------------------------------------------------------------------------
    118
    119
    /// Normalized keep-alive configuration.
    120
    ///
    121
    /// Canonicalizes various keep-alive settings into a standard form.
    122
    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
    123
    pub struct KeepAliveConfig {
    124
        /// Whether keep-alive is enabled
    125
        pub enabled: bool,
    126
        /// Timeout duration in seconds
    127
        pub timeout_secs: u32,
    128
        /// Maximum number of requests per connection
    129
        pub max_requests: u32,
    130
    }
    131
    132
    impl KeepAliveConfig {
    133
        /// Create with default values.
    134
    0
        pub fn new() -> Self {
    135
    0
            Self {
    136
    0
                enabled: true,
    137
    0
                timeout_secs: 60,
    138
    0
                max_requests: 100,
    139
    0
            }
    140
    0
        }
    141
    142
        /// Disabled keep-alive.
    143
    0
        pub fn disabled() -> Self {
    144
    0
            Self {
    145
    0
                enabled: false,
    146
    0
                timeout_secs: 0,
    147
    0
                max_requests: 0,
    148
    0
            }
    149
    0
        }
    150
    151
        /// Parse from HTTP header value (e.g., "timeout=5, max=100").
    152
    0
        pub fn from_header(header: &str) -> Self {
    153
    0
            let mut config = Self::new();
    154
    155
    0
            for part in header.split(',') {
    156
    0
                let part = part.trim();
    157
    0
                if let Some((key, val)) = part.split_once('=') {
    158
    0
                    let key = key.trim().to_lowercase();
    159
    0
                    let val = val.trim();
    160
    161
    0
                    match key.as_str() {
    162
    0
                        "timeout" => {
    163
    0
                            if let Ok(t) = val.parse() {
    164
    0
                                config.timeout_secs = t;
    165
    0
                            }
    166
                        }
    167
    0
                        "max" => {
    168
    0
                            if let Ok(m) = val.parse() {
    169
    0
                                config.max_requests = m;
    170
    0
                            }
    171
                        }
    172
    0
                        _ => {}
    173
                    }
    174
    0
                }
    175
            }
    176
    177
    0
            config
    178
    0
        }
    179
    180
        /// Check if connection should be kept alive after n requests.
    181
        #[must_use]
    182
    0
        pub fn should_keep_alive(&self, request_count: u32) -> bool {
    183
    0
            self.enabled && request_count < self.max_requests
    184
    0
        }
    185
    }
    186
    187
    impl Default for KeepAliveConfig {
    188
    0
        fn default() -> Self {
    189
    0
            Self::new()
    190
    0
        }
    191
    }
    192
    193
    // ----------------------------------------------------------------------------
    194
    // AWP-12: Bitflags Connection State
    195
    // ----------------------------------------------------------------------------
    196
    197
    /// Compact connection state using bitflags.
    198
    ///
    199
    /// Efficiently represents multiple boolean states in a single byte.
    200
    #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
    201
    pub struct ConnectionState(u8);
    202
    203
    impl ConnectionState {
    204
        /// Connection is open
    205
        pub const OPEN: u8 = 0b0000_0001;
    206
        /// Connection is readable
    207
        pub const READABLE: u8 = 0b0000_0010;
    208
        /// Connection is writable
    209
        pub const WRITABLE: u8 = 0b0000_0100;
    210
        /// Connection has pending data
    211
        pub const HAS_PENDING: u8 = 0b0000_1000;
    212
        /// Connection is in keep-alive mode
    213
        pub const KEEP_ALIVE: u8 = 0b0001_0000;
    214
        /// Connection upgrade requested (e.g., WebSocket)
    215
        pub const UPGRADE: u8 = 0b0010_0000;
    216
        /// Connection is closing
    217
        pub const CLOSING: u8 = 0b0100_0000;
    218
        /// Connection has error
    219
        pub const ERROR: u8 = 0b1000_0000;
    220
    221
        /// Create new state with no flags set.
    222
        #[must_use]
    223
    0
        pub fn new() -> Self {
    224
    0
            Self(0)
    225
    0
        }
    226
    227
        /// Create state with initial open + writable.
    228
        #[must_use]
    229
    0
        pub fn open_connection() -> Self {
    230
    0
            Self(Self::OPEN | Self::WRITABLE)
    231
    0
        }
    232
    233
        /// Set a flag.
    234
    0
        pub fn set(&mut self, flag: u8) {
    235
    0
            self.0 |= flag;
    236
    0
        }
    237
    238
        /// Clear a flag.
    239
    0
        pub fn clear(&mut self, flag: u8) {
    240
    0
            self.0 &= !flag;
    241
    0
        }
    242
    243
        /// Check if flag is set.
    244
        #[must_use]
    245
    0
        pub fn is_set(&self, flag: u8) -> bool {
    246
    0
            self.0 & flag != 0
    247
    0
        }
    248
    249
        /// Check if connection is open and healthy.
    250
        #[must_use]
    251
    0
        pub fn is_healthy(&self) -> bool {
    252
    0
            self.is_set(Self::OPEN) && !self.is_set(Self::ERROR) && !self.is_set(Self::CLOSING)
    253
    0
        }
    254
    255
        /// Check if connection can read.
    256
        #[must_use]
    257
    0
        pub fn can_read(&self) -> bool {
    258
    0
            self.is_set(Self::OPEN) && self.is_set(Self::READABLE)
    259
    0
        }
    260
    261
        /// Check if connection can write.
    262
        #[must_use]
    263
    0
        pub fn can_write(&self) -> bool {
    264
    0
            self.is_set(Self::OPEN) && self.is_set(Self::WRITABLE) && !self.is_set(Self::CLOSING)
    265
    0
        }
    266
    267
        /// Get raw bits.
    268
        #[must_use]
    269
    0
        pub fn bits(&self) -> u8 {
    270
    0
            self.0
    271
    0
        }
    272
    }
    273
    274
    #[cfg(test)]
    275
    mod tests {
    276
        use super::*;
    277
    278
        #[test]
    279
        fn test_managed_connection_new() {
    280
            let conn = ManagedConnection::new(
    281
                "test_connection",
    282
                Duration::from_secs(60),
    283
                Duration::from_secs(10),
    284
            );
    285
    286
            assert_eq!(conn.inner(), &"test_connection");
    287
            assert!(conn.is_valid());
    288
            assert!(!conn.is_expired());
    289
            assert!(!conn.is_idle());
    290
        }
    291
    292
        #[test]
    293
        fn test_managed_connection_inner_mut() {
    294
            let mut conn = ManagedConnection::new(
    295
                vec![1, 2, 3],
    296
                Duration::from_secs(60),
    297
                Duration::from_secs(10),
    298
            );
    299
    300
            conn.inner_mut().push(4);
    301
            assert_eq!(conn.inner(), &vec![1, 2, 3, 4]);
    302
        }
    303
    304
        #[test]
    305
        fn test_managed_connection_into_inner() {
    306
            let conn = ManagedConnection::new(42u32, Duration::from_secs(60), Duration::from_secs(10));
    307
    308
            let value = conn.into_inner();
    309
            assert_eq!(value, 42);
    310
        }
    311
    312
        #[test]
    313
        fn test_managed_connection_touch() {
    314
            let mut conn = ManagedConnection::new(
    315
                "test",
    316
                Duration::from_secs(60),
    317
                Duration::from_millis(10),
    318
            );
    319
    320
            std::thread::sleep(Duration::from_millis(5));
    321
            let idle_before = conn.idle_time();
    322
    323
            conn.touch();
    324
            let idle_after = conn.idle_time();
    325
    326
            assert!(idle_after < idle_before);
    327
        }
    328
    329
        #[test]
    330
        fn test_managed_connection_health_failures() {
    331
            let mut conn =
    332
                ManagedConnection::new("test", Duration::from_secs(60), Duration::from_secs(10));
    333
    334
            assert!(conn.is_valid());
    335
    336
            conn.record_health_failure();
    337
            conn.record_health_failure();
    338
            assert!(conn.is_valid()); // 2 failures, still valid
    339
    340
            conn.record_health_failure();
    341
            assert!(!conn.is_valid()); // 3 failures, now invalid
    342
    343
            conn.reset_health();
    344
            assert!(conn.is_valid()); // Reset, valid again
    345
        }
    346
    347
        #[test]
    348
        fn test_managed_connection_age() {
    349
            let conn =
    350
                ManagedConnection::new("test", Duration::from_secs(60), Duration::from_secs(10));
    351
    352
            let age = conn.age();
    353
            assert!(age < Duration::from_millis(100));
    354
        }
    355
    356
        #[test]
    357
        fn test_managed_connection_ttl_expiry() {
    358
            let conn =
    359
                ManagedConnection::new("test", Duration::from_millis(10), Duration::from_secs(60));
    360
    361
            assert!(!conn.is_expired());
    362
    363
            std::thread::sleep(Duration::from_millis(15));
    364
    365
            assert!(conn.is_expired());
    366
            assert!(!conn.is_valid());
    367
        }
    368
    369
        #[test]
    370
        fn test_managed_connection_idle_expiry() {
    371
            let conn =
    372
                ManagedConnection::new("test", Duration::from_secs(60), Duration::from_millis(10));
    373
    374
            assert!(!conn.is_idle());
    375
    376
            std::thread::sleep(Duration::from_millis(15));
    377
    378
            assert!(conn.is_idle());
    379
            assert!(!conn.is_valid());
    380
        }
    381
    382
        /// FALSIFICATION TEST: Verify all three conditions must pass for validity
    383
        ///
    384
        /// A connection is valid only if: not_expired AND not_idle AND healthy.
    385
        /// If any one fails, the connection should be invalid.
    386
        #[test]
    387
        fn test_falsify_validity_requires_all_conditions() {
    388
            // Test 1: Healthy and not idle, but expired
    389
            let expired = ManagedConnection::new(
    390
                "test",
    391
                Duration::from_millis(5),
    392
                Duration::from_secs(60),
    393
            );
    394
            std::thread::sleep(Duration::from_millis(10));
    395
            assert!(
    396
                !expired.is_valid(),
    397
                "FALSIFICATION FAILED: Expired connection should be invalid"
    398
            );
    399
    400
            // Test 2: Healthy and not expired, but idle
    401
            let idle = ManagedConnection::new(
    402
                "test",
    403
                Duration::from_secs(60),
    404
                Duration::from_millis(5),
    405
            );
    406
            std::thread::sleep(Duration::from_millis(10));
    407
            assert!(
    408
                !idle.is_valid(),
    409
                "FALSIFICATION FAILED: Idle connection should be invalid"
    410
            );
    411
    412
            // Test 3: Not expired and not idle, but unhealthy
    413
            let mut unhealthy =
    414
                ManagedConnection::new("test", Duration::from_secs(60), Duration::from_secs(60));
    415
            unhealthy.record_health_failure();
    416
            unhealthy.record_health_failure();
    417
            unhealthy.record_health_failure();
    418
            assert!(
    419
                !unhealthy.is_valid(),
    420
                "FALSIFICATION FAILED: Unhealthy connection should be invalid"
    421
            );
    422
    423
            // Test 4: All conditions pass
    424
            let valid =
    425
                ManagedConnection::new("test", Duration::from_secs(60), Duration::from_secs(60));
    426
            assert!(
    427
                valid.is_valid(),
    428
                "FALSIFICATION FAILED: Fresh connection should be valid"
    429
            );
    430
        }
    431
    432
        /// FALSIFICATION TEST: Touch must reset idle timer
    433
        ///
    434
        /// Uses 200ms timeout with 100ms sleeps to provide 100ms margin against timing jitter.
    435
        /// Previous 20ms/15ms (5ms margin) caused flaky failures on Mac.
    436
        #[test]
    437
        fn test_falsify_touch_resets_idle() {
    438
            let mut conn =
    439
                ManagedConnection::new("test", Duration::from_secs(60), Duration::from_millis(200));
    440
    441
            // Wait until almost idle (100ms of 200ms timeout = 50% margin)
    442
            std::thread::sleep(Duration::from_millis(100));
    443
            assert!(
    444
                !conn.is_idle(),
    445
                "Should not be idle yet at 100ms with 200ms timeout"
    446
            );
    447
    448
            // Touch to reset
    449
            conn.touch();
    450
    451
            // Wait another 100ms (would be 200ms total without touch, but only 100ms since touch)
    452
            std::thread::sleep(Duration::from_millis(100));
    453
            assert!(
    454
                !conn.is_idle(),
    455
                "FALSIFICATION FAILED: Touch should have reset idle timer"
    456
            );
    457
    458
            // Now wait until actually idle (another 150ms = 250ms since touch > 200ms timeout)
    459
            std::thread::sleep(Duration::from_millis(150));
    460
            assert!(conn.is_idle(), "Should be idle now (250ms since touch > 200ms timeout)");
    461
        }
    462
    463
        // =========================================================================
    464
        // KeepAliveConfig Tests
    465
        // =========================================================================
    466
    467
        #[test]
    468
        fn test_keep_alive_config_new() {
    469
            let config = KeepAliveConfig::new();
    470
            assert!(config.enabled);
    471
            assert_eq!(config.timeout_secs, 60);
    472
            assert_eq!(config.max_requests, 100);
    473
        }
    474
    475
        #[test]
    476
        fn test_keep_alive_config_disabled() {
    477
            let config = KeepAliveConfig::disabled();
    478
            assert!(!config.enabled);
    479
            assert_eq!(config.timeout_secs, 0);
    480
            assert_eq!(config.max_requests, 0);
    481
        }
    482
    483
        #[test]
    484
        fn test_keep_alive_config_from_header() {
    485
            let config = KeepAliveConfig::from_header("timeout=30, max=50");
    486
            assert!(config.enabled);
    487
            assert_eq!(config.timeout_secs, 30);
    488
            assert_eq!(config.max_requests, 50);
    489
        }
    490
    491
        #[test]
    492
        fn test_keep_alive_config_from_header_partial() {
    493
            // Only timeout specified
    494
            let config = KeepAliveConfig::from_header("timeout=15");
    495
            assert_eq!(config.timeout_secs, 15);
    496
            assert_eq!(config.max_requests, 100); // Default
    497
    498
            // Only max specified
    499
            let config = KeepAliveConfig::from_header("max=25");
    500
            assert_eq!(config.timeout_secs, 60); // Default
    501
            assert_eq!(config.max_requests, 25);
    502
        }
    503
    504
        #[test]
    505
        fn test_keep_alive_config_from_header_invalid() {
    506
            // Invalid values are ignored
    507
            let config = KeepAliveConfig::from_header("timeout=abc, max=xyz");
    508
            assert_eq!(config.timeout_secs, 60); // Default
    509
            assert_eq!(config.max_requests, 100); // Default
    510
        }
    511
    512
        #[test]
    513
        fn test_keep_alive_config_should_keep_alive() {
    514
            let config = KeepAliveConfig::new(); // max_requests = 100
    515
            assert!(config.should_keep_alive(0));
    516
            assert!(config.should_keep_alive(50));
    517
            assert!(config.should_keep_alive(99));
    518
            assert!(!config.should_keep_alive(100));
    519
            assert!(!config.should_keep_alive(200));
    520
        }
    521
    522
        #[test]
    523
        fn test_keep_alive_config_should_keep_alive_disabled() {
    524
            let config = KeepAliveConfig::disabled();
    525
            assert!(!config.should_keep_alive(0));
    526
        }
    527
    528
        #[test]
    529
        fn test_keep_alive_config_default() {
    530
            let config = KeepAliveConfig::default();
    531
            assert_eq!(config, KeepAliveConfig::new());
    532
        }
    533
    534
        // =========================================================================
    535
        // ConnectionState Tests
    536
        // =========================================================================
    537
    538
        #[test]
    539
        fn test_connection_state_new() {
    540
            let state = ConnectionState::new();
    541
            assert_eq!(state.bits(), 0);
    542
            assert!(!state.is_set(ConnectionState::OPEN));
    543
        }
    544
    545
        #[test]
    546
        fn test_connection_state_open_connection() {
    547
            let state = ConnectionState::open_connection();
    548
            assert!(state.is_set(ConnectionState::OPEN));
    549
            assert!(state.is_set(ConnectionState::WRITABLE));
    550
            assert!(!state.is_set(ConnectionState::READABLE));
    551
        }
    552
    553
        #[test]
    554
        fn test_connection_state_set_clear() {
    555
            let mut state = ConnectionState::new();
    556
    557
            state.set(ConnectionState::OPEN);
    558
            assert!(state.is_set(ConnectionState::OPEN));
    559
    560
            state.set(ConnectionState::READABLE);
    561
            assert!(state.is_set(ConnectionState::OPEN));
    562
            assert!(state.is_set(ConnectionState::READABLE));
    563
    564
            state.clear(ConnectionState::OPEN);
    565
            assert!(!state.is_set(ConnectionState::OPEN));
    566
            assert!(state.is_set(ConnectionState::READABLE));
    567
        }
    568
    569
        #[test]
    570
        fn test_connection_state_is_healthy() {
    571
            let mut state = ConnectionState::open_connection();
    572
            assert!(state.is_healthy());
    573
    574
            state.set(ConnectionState::ERROR);
    575
            assert!(!state.is_healthy());
    576
    577
            state.clear(ConnectionState::ERROR);
    578
            state.set(ConnectionState::CLOSING);
    579
            assert!(!state.is_healthy());
    580
        }
    581
    582
        #[test]
    583
        fn test_connection_state_can_read() {
    584
            let mut state = ConnectionState::open_connection();
    585
            assert!(!state.can_read()); // Not readable yet
    586
    587
            state.set(ConnectionState::READABLE);
    588
            assert!(state.can_read());
    589
    590
            state.clear(ConnectionState::OPEN);
    591
            assert!(!state.can_read()); // Not open
    592
        }
    593
    594
        #[test]
    595
        fn test_connection_state_can_write() {
    596
            let mut state = ConnectionState::open_connection();
    597
            assert!(state.can_write());
    598
    599
            state.set(ConnectionState::CLOSING);
    600
            assert!(!state.can_write()); // Can't write when closing
    601
    602
            state.clear(ConnectionState::CLOSING);
    603
            state.clear(ConnectionState::WRITABLE);
    604
            assert!(!state.can_write()); // Not writable
    605
        }
    606
    607
        #[test]
    608
        fn test_connection_state_bits() {
    609
            let mut state = ConnectionState::new();
    610
            state.set(ConnectionState::OPEN);
    611
            state.set(ConnectionState::WRITABLE);
    612
            assert_eq!(state.bits(), 0b0000_0101);
    613
        }
    614
    615
        #[test]
    616
        fn test_connection_state_default() {
    617
            let state = ConnectionState::default();
    618
            assert_eq!(state.bits(), 0);
    619
        }
    620
    621
        /// FALSIFICATION TEST: ConnectionState bitflags must be non-overlapping
    622
        #[test]
    623
        fn test_falsify_connection_state_flags_unique() {
    624
            let flags = [
    625
                ConnectionState::OPEN,
    626
                ConnectionState::READABLE,
    627
                ConnectionState::WRITABLE,
    628
                ConnectionState::HAS_PENDING,
    629
                ConnectionState::KEEP_ALIVE,
    630
                ConnectionState::UPGRADE,
    631
                ConnectionState::CLOSING,
    632
                ConnectionState::ERROR,
    633
            ];
    634
    635
            // Each flag must be a power of 2 (single bit set)
    636
            for flag in &flags {
    637
                assert!(
    638
                    flag.is_power_of_two(),
    639
                    "FALSIFICATION FAILED: Flag {:08b} is not a power of 2",
    640
                    flag
    641
                );
    642
            }
    643
    644
            // No two flags should overlap
    645
            for i in 0..flags.len() {
    646
                for j in (i + 1)..flags.len() {
    647
                    assert_eq!(
    648
                        flags[i] & flags[j],
    649
                        0,
    650
                        "FALSIFICATION FAILED: Flags {:08b} and {:08b} overlap",
    651
                        flags[i],
    652
                        flags[j]
    653
                    );
    654
                }
    655
            }
    656
        }
    657
    658
        /// FALSIFICATION TEST: KeepAliveConfig should_keep_alive boundary
    659
        #[test]
    660
        fn test_falsify_keep_alive_boundary() {
    661
            let config = KeepAliveConfig {
    662
                enabled: true,
    663
                timeout_secs: 60,
    664
                max_requests: 100,
    665
            };
    666
    667
            // At exactly max_requests, should NOT keep alive
    668
            assert!(
    669
                !config.should_keep_alive(100),
    670
                "FALSIFICATION FAILED: should_keep_alive should return false at max_requests"
    671
            );
    672
    673
            // One below max should still be true
    674
            assert!(
    675
                config.should_keep_alive(99),
    676
                "FALSIFICATION FAILED: should_keep_alive should return true below max_requests"
    677
            );
    678
        }
    679
    }