@@ -2,6 +2,7 @@ use crate::measurements::format_bytes;
22use  crate :: measurements:: log_measurements; 
33use  crate :: measurements:: Measurement ; 
44use  crate :: progress:: print_progress; 
5+ use  log; 
56use  regex:: Regex ; 
67use  reqwest:: { 
78    blocking:: { Client ,  RequestBuilder } , 
@@ -12,19 +13,57 @@ use std::{
1213    fmt:: Display , 
1314    time:: { Duration ,  Instant } , 
1415} ; 
15- 
1616const  BASE_URL :  & str  = "http://speed.cloudflare.com" ; 
1717const  DOWNLOAD_URL :  & str  = "__down?bytes=" ; 
1818const  UPLOAD_URL :  & str  = "__up" ; 
19- // pub const PAYLOAD_SIZES: [usize; 1] = [10_000]; 
20- pub  const  PAYLOAD_SIZES :  [ usize ;  4 ]  = [ 100_000 ,  1_000_000 ,  10_000_000 ,  25_000_000 ] ; 
2119
2220#[ derive( Clone ,  Copy ,  Debug ,  Hash ,  Eq ,  PartialEq ) ]  
2321pub ( crate )  enum  TestType  { 
2422    Download , 
2523    Upload , 
2624} 
2725
26+ #[ derive( Clone ,  Debug ) ]  
27+ pub ( crate )  enum  PayloadSize  { 
28+     K100  = 100_000 , 
29+     M1  = 1_000_000 , 
30+     M10  = 10_000_000 , 
31+     M25  = 25_000_000 , 
32+     M100  = 100_000_000 , 
33+ } 
34+ 
35+ impl  Display  for  PayloadSize  { 
36+     fn  fmt ( & self ,  f :  & mut  std:: fmt:: Formatter < ' _ > )  -> std:: fmt:: Result  { 
37+         write ! ( f,  "{}" ,  format_bytes( self . clone( )  as  usize ) ) 
38+     } 
39+ } 
40+ 
41+ impl  PayloadSize  { 
42+     pub  fn  from ( payload_string :  String )  -> Result < Self ,  String >  { 
43+         match  payload_string. to_lowercase ( ) . as_str ( )  { 
44+             "100_000"  | "100000"  | "100k"  | "100kb"  => Ok ( Self :: K100 ) , 
45+             "1_000_000"  | "1000000"  | "1m"  | "1mb"  => Ok ( Self :: M1 ) , 
46+             "10_000_000"  | "10000000"  | "10m"  | "10mb"  => Ok ( Self :: M10 ) , 
47+             "25_000_000"  | "25000000"  | "25m"  | "25mb"  => Ok ( Self :: M25 ) , 
48+             "100_000_000"  | "100000000"  | "100m"  | "100mb"  => Ok ( Self :: M100 ) , 
49+             _ => Err ( "Value needs to be one of 100k, 1m, 10m, 25m or 100m" . to_string ( ) ) , 
50+         } 
51+     } 
52+ 
53+     fn  sizes_from_max ( max_payload_size :  PayloadSize )  -> Vec < usize >  { 
54+         log:: debug!( "getting payload iterations for max_payload_size {max_payload_size:?}" ) ; 
55+         let  payload_bytes:  Vec < usize >  =
56+             vec ! [ 100_000 ,  1_000_000 ,  10_000_000 ,  25_000_000 ,  100_000_000 ] ; 
57+         match  max_payload_size { 
58+             PayloadSize :: K100  => payload_bytes[ 0 ..1 ] . to_vec ( ) , 
59+             PayloadSize :: M1  => payload_bytes[ 0 ..2 ] . to_vec ( ) , 
60+             PayloadSize :: M10  => payload_bytes[ 0 ..3 ] . to_vec ( ) , 
61+             PayloadSize :: M25  => payload_bytes[ 0 ..4 ] . to_vec ( ) , 
62+             PayloadSize :: M100  => payload_bytes[ 0 ..5 ] . to_vec ( ) , 
63+         } 
64+     } 
65+ } 
66+ 
2867struct  Metadata  { 
2968    city :  String , 
3069    country :  String , 
@@ -43,18 +82,31 @@ impl Display for Metadata {
4382    } 
4483} 
4584
46- pub ( crate )  fn  speed_test ( client :  Client ,  nr_tests :  u32 ,  nr_latency_tests :  u32 )  { 
85+ pub ( crate )  fn  speed_test ( 
86+     client :  Client , 
87+     max_payload_size :  PayloadSize , 
88+     nr_tests :  u32 , 
89+     nr_latency_tests :  u32 , 
90+ )  { 
4791    let  metadata = fetch_metadata ( & client) ; 
4892    println ! ( "{metadata}" ) ; 
4993    run_latency_test ( & client,  nr_latency_tests) ; 
50-     let  mut  measurements = run_tests ( & client,  test_download,  TestType :: Download ,  nr_tests) ; 
94+     let  payload_sizes = PayloadSize :: sizes_from_max ( max_payload_size) ; 
95+     let  mut  measurements = run_tests ( 
96+         & client, 
97+         test_download, 
98+         TestType :: Download , 
99+         payload_sizes. clone ( ) , 
100+         nr_tests, 
101+     ) ; 
51102    measurements. append ( & mut  run_tests ( 
52103        & client, 
53104        test_upload, 
54105        TestType :: Upload , 
106+         payload_sizes. clone ( ) , 
55107        nr_tests, 
56108    ) ) ; 
57-     log_measurements ( & measurements) ; 
109+     log_measurements ( & measurements,  payload_sizes ) ; 
58110} 
59111
60112fn  run_latency_test ( client :  & Client ,  nr_latency_tests :  u32 )  -> ( Vec < f64 > ,  f64 )  { 
@@ -103,15 +155,16 @@ fn test_latency(client: &Client) -> f64 {
103155    } 
104156    req_latency
105157} 
106- 
107158fn  run_tests ( 
108159    client :  & Client , 
109160    test_fn :  fn ( & Client ,  usize )  -> f64 , 
110161    test_type :  TestType , 
162+     payload_sizes :  Vec < usize > , 
111163    nr_tests :  u32 , 
112164)  -> Vec < Measurement >  { 
113165    let  mut  measurements:  Vec < Measurement >  = Vec :: new ( ) ; 
114-     for  payload_size in  PAYLOAD_SIZES  { 
166+     for  payload_size in  payload_sizes { 
167+         log:: debug!( "running tests for payload_size {payload_size}" ) ; 
115168        for  i in  0 ..nr_tests { 
116169            print_progress ( 
117170                & format ! ( "{:?} {:<5}" ,  test_type,  format_bytes( payload_size) ) , 
0 commit comments