Skip to content

Commit 0847dc4

Browse files
add flag for verbose output
1 parent a69fecf commit 0847dc4

File tree

4 files changed

+33
-30
lines changed

4 files changed

+33
-30
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
## TODO
55
- [ ] Dynamic payload sizing depending on network speed
66
- [ ] Consider server processing time in measurements
7-
- [ ] CLI arguments (~~nr of tests~~, ~~payload sizes~~, verbosity)
7+
- [X] CLI arguments (~~nr of tests~~, ~~payload sizes~~, ~~verbosity~~)
88
- [ ] Clean up outputs
99
- [X] Boxplot for measurements
1010
- [ ] Asciinema recording in readme

src/main.rs

Lines changed: 11 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,36 +7,33 @@ use clap::Parser;
77
use speedtest::speed_test;
88
use speedtest::PayloadSize;
99

10-
// pub const PAYLOAD_SIZES: [usize; 4] = [100_000, 1_000_000, 10_000_000, 25_000_000];
11-
1210
/// Unofficial CLI for speed.cloudflare.com
1311
#[derive(Parser, Debug)]
1412
#[command(author, version, about, long_about = None)]
15-
struct Args {
16-
#[arg(value_parser = parse_payload_size, short, long, default_value_t = PayloadSize::M10)]
17-
/// The max payload size in bytes to use [100k, 1m, 10m, 25m or 100m]
18-
max_payload_size: PayloadSize,
19-
13+
pub(crate) struct SpeedTestOptions {
2014
/// Number of test runs per payload size. Needs to be at least 4
2115
#[arg(value_parser = clap::value_parser!(u32).range(4..1000), short, long, default_value_t = 10)]
2216
nr_tests: u32,
2317

2418
/// Number of latency tests to run
2519
#[arg(long, default_value_t = 25)]
2620
nr_latency_tests: u32,
21+
22+
/// The max payload size in bytes to use [100k, 1m, 10m, 25m or 100m]
23+
#[arg(value_parser = parse_payload_size, short, long, default_value_t = PayloadSize::M10)]
24+
max_payload_size: PayloadSize,
25+
26+
/// Enable verbose output i.e. print out boxplots of the measurements
27+
#[arg(short, long)]
28+
verbose: bool,
2729
}
2830

2931
fn main() {
3032
env_logger::init();
31-
let args = Args::parse();
33+
let options = SpeedTestOptions::parse();
3234
println!("Starting Cloudflare speed test");
3335
let client = reqwest::blocking::Client::new();
34-
speed_test(
35-
client,
36-
args.max_payload_size,
37-
args.nr_tests,
38-
args.nr_latency_tests,
39-
);
36+
speed_test(client, options);
4037
}
4138

4239
fn parse_payload_size(input_string: &str) -> Result<PayloadSize, String> {

src/measurements.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,26 @@ impl Display for Measurement {
2020
}
2121
}
2222

23-
pub(crate) fn log_measurements(measurements: &[Measurement], payload_sizes: Vec<usize>) {
23+
pub(crate) fn log_measurements(
24+
measurements: &[Measurement],
25+
payload_sizes: Vec<usize>,
26+
verbose: bool,
27+
) {
2428
println!("\n### STATS ###");
2529
measurements
2630
.iter()
2731
.map(|m| m.test_type)
2832
.collect::<HashSet<TestType>>()
2933
.iter()
30-
.for_each(|t| log_measurements_by_test_type(measurements, payload_sizes.clone(), *t));
34+
.for_each(|t| {
35+
log_measurements_by_test_type(measurements, payload_sizes.clone(), verbose, *t)
36+
});
3137
}
3238

3339
fn log_measurements_by_test_type(
3440
measurements: &[Measurement],
3541
payload_sizes: Vec<usize>,
42+
verbose: bool,
3643
test_type: TestType,
3744
) {
3845
for payload_size in payload_sizes {
@@ -46,8 +53,10 @@ fn log_measurements_by_test_type(
4653

4754
let formated_payload = format_bytes(payload_size);
4855
println!("{test_type:?} {formated_payload}: min {min:.2}, max {max:.2}, avg {avg:.2}");
49-
let plot = boxplot::render_plot(min, q1, median, q3, max);
50-
println!("{plot}\n");
56+
if verbose {
57+
let plot = boxplot::render_plot(min, q1, median, q3, max);
58+
println!("{plot}\n");
59+
}
5160
}
5261
}
5362

src/speedtest.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::measurements::format_bytes;
22
use crate::measurements::log_measurements;
33
use crate::measurements::Measurement;
44
use crate::progress::print_progress;
5+
use crate::SpeedTestOptions;
56
use log;
67
use regex::Regex;
78
use reqwest::{
@@ -13,6 +14,7 @@ use std::{
1314
fmt::Display,
1415
time::{Duration, Instant},
1516
};
17+
1618
const BASE_URL: &str = "http://speed.cloudflare.com";
1719
const DOWNLOAD_URL: &str = "__down?bytes=";
1820
const UPLOAD_URL: &str = "__up";
@@ -82,31 +84,26 @@ impl Display for Metadata {
8284
}
8385
}
8486

85-
pub(crate) fn speed_test(
86-
client: Client,
87-
max_payload_size: PayloadSize,
88-
nr_tests: u32,
89-
nr_latency_tests: u32,
90-
) {
87+
pub(crate) fn speed_test(client: Client, options: SpeedTestOptions) {
9188
let metadata = fetch_metadata(&client);
9289
println!("{metadata}");
93-
run_latency_test(&client, nr_latency_tests);
94-
let payload_sizes = PayloadSize::sizes_from_max(max_payload_size);
90+
run_latency_test(&client, options.nr_latency_tests);
91+
let payload_sizes = PayloadSize::sizes_from_max(options.max_payload_size);
9592
let mut measurements = run_tests(
9693
&client,
9794
test_download,
9895
TestType::Download,
9996
payload_sizes.clone(),
100-
nr_tests,
97+
options.nr_tests,
10198
);
10299
measurements.append(&mut run_tests(
103100
&client,
104101
test_upload,
105102
TestType::Upload,
106103
payload_sizes.clone(),
107-
nr_tests,
104+
options.nr_tests,
108105
));
109-
log_measurements(&measurements, payload_sizes);
106+
log_measurements(&measurements, payload_sizes, options.verbose);
110107
}
111108

112109
fn run_latency_test(client: &Client, nr_latency_tests: u32) -> (Vec<f64>, f64) {

0 commit comments

Comments
 (0)