From dbd1068cc5f66030f3354cfcb894a68addb250bc Mon Sep 17 00:00:00 2001 From: Gregory Ballantine Date: Fri, 5 Aug 2022 20:58:24 -0400 Subject: [PATCH] Consolidated the test programs into one 'bgbench' program --- .woodpecker.yml | 3 +- Cargo.toml | 12 ++--- src/main.rs | 81 ++++++++++++++++++++++++++++++++ src/nettest.rs | 80 ------------------------------- src/{hdtest.rs => tests/disk.rs} | 14 ++++-- src/tests/mod.rs | 2 + src/tests/network.rs | 42 +++++++++++++++++ 7 files changed, 139 insertions(+), 95 deletions(-) create mode 100644 src/main.rs delete mode 100644 src/nettest.rs rename src/{hdtest.rs => tests/disk.rs} (57%) create mode 100644 src/tests/mod.rs create mode 100644 src/tests/network.rs diff --git a/.woodpecker.yml b/.woodpecker.yml index 9b6b2ec..498f358 100644 --- a/.woodpecker.yml +++ b/.woodpecker.yml @@ -8,8 +8,7 @@ pipeline: image: rust:1.62 commands: - cargo build --release - - "mv target/release/nettest target/release/nettest-${CI_COMMIT_TAG}-linux-x86_64" - - "mv target/release/hdtest target/release/hdtest-${CI_COMMIT_TAG}-linux-x86_64" + - "mv target/release/bgbench target/release/bgbench-${CI_COMMIT_TAG}-linux-x86_64" when: event: tag diff --git a/Cargo.toml b/Cargo.toml index a146381..f17b10b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,15 +4,11 @@ version = "0.1.0" edition = "2021" [[bin]] -name = "hdtest" -path = "src/hdtest.rs" - -[[bin]] -name = "nettest" -path = "src/nettest.rs" +name = "bgbench" +path = "src/main.rs" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -chrono = "0.4.19" -clap = { version = "3.1.2", features = ["derive"] } +chrono = "0.4.20" +clap = { version = "3.2.16", features = ["derive"] } diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..ff62a55 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,81 @@ +mod tests; + +use clap::{Parser, Subcommand}; + +#[derive(Parser)] +#[clap(name = "Bit Goblin Benchmark", author, version, about = "Bit Goblin's hardware benchmarking tool.", long_about = None)] +#[clap(propagate_version = true)] +struct Cli { + #[clap(subcommand)] + command: Commands, +} + +#[derive(Subcommand)] +enum Commands { + // disk tests subcommand + #[clap(name = "disk", about = "Hard drive and SSD benchmarks.")] + Disk(Disk), + // network tests subcommand + #[clap(name = "network", about = "Test various aspects of your network.")] + Net(Net), +} + +#[derive(Parser)] +struct Disk { + #[structopt(subcommand)] + disk_commands: DiskCommands, +} + +#[derive(Subcommand)] +enum DiskCommands { + #[clap(name = "write-test", about = "Write a large file to determine sequential disk speeds.")] + WriteTest { + #[clap(short = 't', default_value_t = String::from("/tmp/disk-test.tmp"))] + tempfile: String, + #[clap(short = 's', default_value_t = 5)] + size: u8, + }, +} + +#[derive(Parser)] +struct Net { + #[structopt(subcommand)] + net_commands: NetCommands, +} + +#[derive(Subcommand)] +enum NetCommands { + // ping subcommand + #[clap(name = "ping", about = "Ping a host to determine network latency.")] + Ping { + #[clap(short = 't', default_value_t = String::from("8.8.8.8"))] + host: String, + #[clap(short = 'c', default_value_t = 30)] + count: u16, + }, + + // bandwidth test subcommand + #[clap(name = "bandwidth", about = "Downloads a remote file to determine network bandwidth.")] + Bandwidth { + #[clap(short = 'd', default_value_t = String::from("https://www.bitgoblin.tech/hardware-tests/export-01.mp4"))] + download: String, + #[clap(short = 'o', default_value_t = String::from("./tempfile"))] + output: String, + }, +} + +fn main() { + let cli = Cli::parse(); + + // map subcommands back to the main command + match &cli.command { + Commands::Disk(args) => match &args.disk_commands { + DiskCommands::WriteTest { tempfile, size } => tests::disk::disk_write_test(tempfile, size), + } + + Commands::Net(args) => match &args.net_commands { + NetCommands::Ping { host, count } => tests::network::ping_host(host, count), + NetCommands::Bandwidth { download, output } => tests::network::bandwidth_test(download, output), + }, + } +} diff --git a/src/nettest.rs b/src/nettest.rs deleted file mode 100644 index a75be85..0000000 --- a/src/nettest.rs +++ /dev/null @@ -1,80 +0,0 @@ -use chrono::prelude::*; -use clap::{Parser, Subcommand}; -use std::{fs,process}; - -#[derive(Parser)] -#[clap(name = "Bit Goblin Network Tester", author, version, about = "Network testing app.", long_about = None)] -#[clap(propagate_version = true)] -struct Cli { - #[clap(subcommand)] - command: Commands, -} - -#[derive(Subcommand)] -enum Commands { - // ping subcommand - Ping { - #[clap(short = 't', default_value_t = String::from("8.8.8.8"))] - host: String, - #[clap(short = 'c', default_value_t = 30)] - count: u16, - }, - - // bandwidth test subcommand - Bandwidth { - #[clap(short = 'd', default_value_t = String::from("https://www.bitgoblin.tech/hardware-tests/export-01.mp4"))] - download: String, - #[clap(short = 'o', default_value_t = String::from("./tempfile"))] - output: String, - }, -} - -fn main() { - let cli = Cli::parse(); - - // map subcommands back to the main command - match &cli.command { - Commands::Ping { host, count } => ping_host(host, count), - Commands::Bandwidth { download, output } => bandwidth_test(download, output) - } -} - -// ping a host -fn ping_host(host: &str, count: &u16) { - println!("Pinging host {}, {} times.", host, count); - - // run the ping command - let output = process::Command::new("ping") - .arg(host) - .arg(format!("-c {}", count)) - .output() - .expect("Failed to execute command"); - - // check that the command succeeded - assert!(output.status.success()); - - // print out the ping results from stdout - println!("{}", String::from_utf8_lossy(&output.stdout)); -} - -// timed file copy test to guage bandwidth speeds -fn bandwidth_test(download: &str, output: &str) { - println!("Testing network bandwidth by downloading {}.", download); - - // get start time so we can track how long it takes to complete - let start_time = Utc::now(); - - // do the download - - // get finish time - let finish_time = Utc::now(); - // compute time to complete - let comp_time = finish_time - start_time; - println!("{}", comp_time.num_milliseconds()); - - // clean up the test file - match fs::remove_file(output) { - Ok(()) => println!("Cleaning up..."), - Err(e) => println!("There was a problem during cleanup - {}", e), - } -} diff --git a/src/hdtest.rs b/src/tests/disk.rs similarity index 57% rename from src/hdtest.rs rename to src/tests/disk.rs index fb2a349..3521e8a 100644 --- a/src/hdtest.rs +++ b/src/tests/disk.rs @@ -1,13 +1,17 @@ use std::fs; use std::process::Command; -fn main() { - // run the dd command with a block size of 1 MB, 10K times (10GB file) +// test disk write speeds by continually writing zeroes to it +pub fn disk_write_test(tempfile: &str, size: &u8) { + // convert size in Gigabytes down to Megabytes + let size_gigs: u32 = (*size as u32 * 1024).into(); + + // run the dd command with a block size of 1 MB let output = Command::new("dd") .arg("bs=1M") - .arg("count=10240") + .arg(format!("count={}", size_gigs)) .arg("if=/dev/zero") - .arg("of=./speed-test") + .arg(format!("of={}", tempfile)) .output() .expect("Failed to execute command"); @@ -18,7 +22,7 @@ fn main() { println!("{}", String::from_utf8_lossy(&output.stderr)); // remove the test file - match fs::remove_file("./speed-test") { + match fs::remove_file(tempfile) { Ok(()) => println!("Cleaning up..."), Err(e) => println!("There was a problem during cleanup - {}", e), } diff --git a/src/tests/mod.rs b/src/tests/mod.rs new file mode 100644 index 0000000..1b223d9 --- /dev/null +++ b/src/tests/mod.rs @@ -0,0 +1,2 @@ +pub mod disk; +pub mod network; diff --git a/src/tests/network.rs b/src/tests/network.rs new file mode 100644 index 0000000..4aad26a --- /dev/null +++ b/src/tests/network.rs @@ -0,0 +1,42 @@ +use chrono::prelude::*; +use std::{fs,process}; + +// ping a host +pub fn ping_host(host: &str, count: &u16) { + println!("Pinging host {}, {} times.", host, count); + + // run the ping command + let output = process::Command::new("ping") + .arg(host) + .arg(format!("-c {}", count)) + .output() + .expect("Failed to execute command"); + + // check that the command succeeded + assert!(output.status.success()); + + // print out the ping results from stdout + println!("{}", String::from_utf8_lossy(&output.stdout)); +} + +// timed file copy test to guage bandwidth speeds +pub fn bandwidth_test(download: &str, output: &str) { + println!("Testing network bandwidth by downloading {}.", download); + + // get start time so we can track how long it takes to complete + let start_time = Utc::now(); + + // do the download + + // get finish time + let finish_time = Utc::now(); + // compute time to complete + let comp_time = finish_time - start_time; + println!("{}", comp_time.num_milliseconds()); + + // clean up the test file + match fs::remove_file(output) { + Ok(()) => println!("Cleaning up..."), + Err(e) => println!("There was a problem during cleanup - {}", e), + } +}