From 5b6d3ff071627751f7cb61a24f038da93a9f80c1 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Dec 2025 07:52:17 +0000 Subject: [PATCH 1/2] fix: add range validation for nr-latency-tests parameter Prevents division by zero bug in run_latency_test function when nr_latency_tests is set to 0. Added range validation (1..1000) consistent with nr_tests parameter. Without this fix, setting --nr-latency-tests 0 would result in NaN when calculating average latency due to division by zero. --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 531df14..0860fd1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -45,7 +45,7 @@ pub struct SpeedTestCLIOptions { pub nr_tests: u32, /// Number of latency tests to run - #[arg(long, default_value_t = 25)] + #[arg(value_parser = clap::value_parser!(u32).range(1..1000), long, default_value_t = 25)] pub nr_latency_tests: u32, /// The max payload size in bytes to use [100k, 1m, 10m, 25m or 100m] From 4323262489acf73f476595745c1b6cdc3e901f41 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 30 Dec 2025 08:43:30 +0000 Subject: [PATCH 2/2] test: add unit tests for parameter range validation Added comprehensive unit tests for nr_tests and nr_latency_tests parameter validation to ensure: - Zero values are rejected - Minimum valid value (1) is accepted - Maximum valid value (999) is accepted - Out of range values (1000+) are rejected This ensures the division by zero bug fix is properly tested. --- src/lib.rs | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) diff --git a/src/lib.rs b/src/lib.rs index 0860fd1..2d18dfd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -231,4 +231,58 @@ mod tests { assert!(!options.should_upload()); assert!(options.should_download()); } + + #[test] + fn test_nr_tests_range_validation() { + // Test that nr_tests rejects 0 + let result = SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-tests", "0"]); + assert!(result.is_err()); + let err = result.unwrap_err(); + assert!(err.to_string().contains("0 is not in 1..1000")); + + // Test that nr_tests accepts 1 (minimum valid value) + let result = SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-tests", "1"]); + assert!(result.is_ok()); + assert_eq!(result.unwrap().nr_tests, 1); + + // Test that nr_tests accepts 999 (maximum valid value) + let result = SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-tests", "999"]); + assert!(result.is_ok()); + assert_eq!(result.unwrap().nr_tests, 999); + + // Test that nr_tests rejects 1000 + let result = SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-tests", "1000"]); + assert!(result.is_err()); + let err = result.unwrap_err(); + assert!(err.to_string().contains("1000 is not in 1..1000")); + } + + #[test] + fn test_nr_latency_tests_range_validation() { + // Test that nr_latency_tests rejects 0 + let result = + SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-latency-tests", "0"]); + assert!(result.is_err()); + let err = result.unwrap_err(); + assert!(err.to_string().contains("0 is not in 1..1000")); + + // Test that nr_latency_tests accepts 1 (minimum valid value) + let result = + SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-latency-tests", "1"]); + assert!(result.is_ok()); + assert_eq!(result.unwrap().nr_latency_tests, 1); + + // Test that nr_latency_tests accepts 999 (maximum valid value) + let result = + SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-latency-tests", "999"]); + assert!(result.is_ok()); + assert_eq!(result.unwrap().nr_latency_tests, 999); + + // Test that nr_latency_tests rejects 1000 + let result = + SpeedTestCLIOptions::try_parse_from(vec!["cfspeedtest", "--nr-latency-tests", "1000"]); + assert!(result.is_err()); + let err = result.unwrap_err(); + assert!(err.to_string().contains("1000 is not in 1..1000")); + } }