File
Blob: firmware/vendor/str0m/tests/bwe/probes.rs
| 1 | //! Core probe control mechanics tests. |
| 2 | |
| 3 | use std::sync::Arc; |
| 4 | use std::time::Duration; |
| 5 | |
| 6 | use netem::{DataSize, NetemConfig}; |
| 7 | use str0m::RtcError; |
| 8 | use str0m::bwe::Bitrate; |
| 9 | |
| 10 | use crate::common::{BweTestContext, Step, connect_with_bwe, init_crypto_default, init_log}; |
| 11 | |
| 12 | #[test] |
| 13 | fn initial_exponential_probes_3x_and_6x() -> Result<(), RtcError> { |
| 14 | init_log(); |
| 15 | init_crypto_default(); |
| 16 | |
| 17 | let plan = vec![ |
| 18 | Step::Conditions { |
| 19 | description: "High bandwidth network", |
| 20 | config: NetemConfig::new() |
| 21 | .link(Bitrate::mbps(10), DataSize::kbytes(200)) |
| 22 | .seed(42), |
| 23 | }, |
| 24 | Step::Media { |
| 25 | description: "Start at 1 Mbps", |
| 26 | desired_bitrate: Bitrate::mbps(10), |
| 27 | media_send_rate: Bitrate::mbps(1), |
| 28 | }, |
| 29 | Step::Run { |
| 30 | description: "Allow initial probing", |
| 31 | duration: Duration::from_millis(100), |
| 32 | }, |
| 33 | // Verify initial exponential probes at 3x and 6x start rate |
| 34 | Step::CheckProbe { |
| 35 | description: "First exponential probe at 3x (3 Mbps)", |
| 36 | check: Arc::new(|_index, probe| { |
| 37 | let expected = Bitrate::mbps(3); |
| 38 | let tolerance = 0.05; |
| 39 | probe.target_bitrate() >= expected * (1.0 - tolerance) |
| 40 | && probe.target_bitrate() <= expected * (1.0 + tolerance) |
| 41 | && !probe.is_alr_probe() |
| 42 | }), |
| 43 | }, |
| 44 | Step::CheckProbe { |
| 45 | description: "Second exponential probe at 6x (6 Mbps)", |
| 46 | check: Arc::new(|_index, probe| { |
| 47 | let expected = Bitrate::mbps(6); |
| 48 | let tolerance = 0.05; |
| 49 | probe.target_bitrate() >= expected * (1.0 - tolerance) |
| 50 | && probe.target_bitrate() <= expected * (1.0 + tolerance) |
| 51 | && !probe.is_alr_probe() |
| 52 | }), |
| 53 | }, |
| 54 | ]; |
| 55 | |
| 56 | let (mut l, mut r) = connect_with_bwe(Bitrate::mbps(1), Bitrate::mbps(10)); |
| 57 | let mut ctx = BweTestContext::new(&mut l, &mut r); |
| 58 | ctx.run_plan(&mut l, &mut r, &plan)?; |
| 59 | |
| 60 | Ok(()) |
| 61 | } |
| 62 | |
| 63 | #[test] |
| 64 | fn further_exponential_probes_at_2x() -> Result<(), RtcError> { |
| 65 | init_log(); |
| 66 | init_crypto_default(); |
| 67 | |
| 68 | let plan = vec![ |
| 69 | Step::Conditions { |
| 70 | description: "High bandwidth network", |
| 71 | config: NetemConfig::new() |
| 72 | .link(Bitrate::mbps(20), DataSize::kbytes(400)) |
| 73 | .seed(42), |
| 74 | }, |
| 75 | Step::Media { |
| 76 | description: "Start at 1 Mbps, high max", |
| 77 | desired_bitrate: Bitrate::mbps(20), |
| 78 | media_send_rate: Bitrate::mbps(1), |
| 79 | }, |
| 80 | Step::Run { |
| 81 | description: "Let probing discover capacity", |
| 82 | duration: Duration::from_secs(1), |
| 83 | }, |
| 84 | // After initial 3x and 6x probes, should see further probes at 2x estimate |
| 85 | // When estimate grows past 0.7x last probe (0.7 * 6 = 4.2 Mbps), |
| 86 | // further probe fires at 2x estimate |
| 87 | Step::CheckProbe { |
| 88 | description: "Further probe beyond 6x (should be ~2x estimate)", |
| 89 | check: Arc::new(|_index, probe| { |
| 90 | // Accept any probe > 6 Mbps (beyond initial 6x) |
| 91 | // This proves further exponential probing is working |
| 92 | probe.target_bitrate() > Bitrate::mbps(6) && !probe.is_alr_probe() |
| 93 | }), |
| 94 | }, |
| 95 | ]; |
| 96 | |
| 97 | let (mut l, mut r) = connect_with_bwe(Bitrate::mbps(1), Bitrate::mbps(20)); |
| 98 | let mut ctx = BweTestContext::new(&mut l, &mut r); |
| 99 | ctx.run_plan(&mut l, &mut r, &plan)?; |
| 100 | |
| 101 | Ok(()) |
| 102 | } |
| 103 | |
| 104 | #[test] |
| 105 | fn probes_respect_max_bitrate_cap() -> Result<(), RtcError> { |
| 106 | init_log(); |
| 107 | init_crypto_default(); |
| 108 | |
| 109 | let plan = vec![ |
| 110 | Step::Conditions { |
| 111 | description: "Very high bandwidth network", |
| 112 | config: NetemConfig::new() |
| 113 | .link(Bitrate::mbps(50), DataSize::kbytes(1000)) |
| 114 | .seed(42), |
| 115 | }, |
| 116 | Step::Media { |
| 117 | description: "Start at 2 Mbps, cap at 10 Mbps", |
| 118 | desired_bitrate: Bitrate::mbps(10), // This is the max |
| 119 | media_send_rate: Bitrate::mbps(2), |
| 120 | }, |
| 121 | Step::Run { |
| 122 | description: "Let probing happen", |
| 123 | duration: Duration::from_secs(2), |
| 124 | }, |
| 125 | // Every probe should be capped at 2x max_bitrate = 20 Mbps |
| 126 | // This checks that the probing respects the application's desired rate |
| 127 | Step::CheckProbe { |
| 128 | description: "No probe exceeds 2x max_bitrate (20 Mbps)", |
| 129 | check: Arc::new(|_index, probe| { |
| 130 | // Every non-ALR probe should be under the 2x max_bitrate cap |
| 131 | !probe.is_alr_probe() && probe.target_bitrate() <= Bitrate::mbps(20) |
| 132 | }), |
| 133 | }, |
| 134 | ]; |
| 135 | |
| 136 | let (mut l, mut r) = connect_with_bwe(Bitrate::mbps(2), Bitrate::mbps(10)); |
| 137 | let mut ctx = BweTestContext::new(&mut l, &mut r); |
| 138 | ctx.run_plan(&mut l, &mut r, &plan)?; |
| 139 | |
| 140 | Ok(()) |
| 141 | } |