Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

result formatting #37

Merged
merged 1 commit into from
Sep 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "netkraken"
version = "0.1.6"
version = "0.1.7"
edition = "2021"

[[bin]]
Expand Down
8 changes: 4 additions & 4 deletions src/core/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ impl Tabled for ClientResult {
std::borrow::Cow::Borrowed("Sent"),
std::borrow::Cow::Borrowed("Received"),
std::borrow::Cow::Borrowed("Lost"),
std::borrow::Cow::Borrowed("Loss %"),
std::borrow::Cow::Borrowed("Min"),
std::borrow::Cow::Borrowed("Max"),
std::borrow::Cow::Borrowed("Avg"),
std::borrow::Cow::Borrowed("Loss (%)"),
std::borrow::Cow::Borrowed("Min (ms)"),
std::borrow::Cow::Borrowed("Max (ms)"),
std::borrow::Cow::Borrowed("Avg (ms)"),
]
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/tcp/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ use crate::core::konst::{BIND_ADDR, BIND_PORT, BUFFER_SIZE};
use crate::util::dns::resolve_host;
use crate::util::handler::{io_error_switch_handler, loop_handler, output_handler2};
use crate::util::message::{
client_result_msg, client_summary_msg, client_summary_table_msg, ping_header_msg,
resolved_ips_msg,
client_result_msg, client_summary_table_msg, ping_header_msg, resolved_ips_msg,
};
use crate::util::parser::parse_ipaddr;
use crate::util::result::get_results_map;
use crate::util::result::{client_summary_result, get_results_map};
use crate::util::time::{calc_connect_ms, time_now_us};

#[derive(Debug)]
Expand Down Expand Up @@ -143,7 +142,7 @@ impl TcpClient {
send_count,
latencies,
};
let summary_msg = client_summary_msg(&addr, ConnectMethod::TCP, client_summary);
let summary_msg = client_summary_result(&addr, ConnectMethod::TCP, client_summary);
// println!("{}", summary_msg);
client_results.push(summary_msg)
}
Expand Down
10 changes: 5 additions & 5 deletions src/udp/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,10 @@ use crate::core::konst::{BIND_ADDR, BIND_PORT, BUFFER_SIZE, MAX_PACKET_SIZE, PIN
use crate::util::dns::resolve_host;
use crate::util::handler::{io_error_switch_handler, loop_handler, output_handler2};
use crate::util::message::{
client_result_msg, client_summary_msg, client_summary_table_msg, ping_header_msg,
resolved_ips_msg,
client_result_msg, client_summary_table_msg, ping_header_msg, resolved_ips_msg,
};
use crate::util::parser::parse_ipaddr;
use crate::util::result::get_results_map;
use crate::util::result::{client_summary_result, get_results_map};
use crate::util::time::{calc_connect_ms, time_now_us};

pub struct UdpClient {
Expand Down Expand Up @@ -134,8 +133,9 @@ impl UdpClient {
send_count,
latencies,
};
let summary_msg = client_summary_msg(&addr, ConnectMethod::UDP, client_summary);
client_results.push(summary_msg)
let client_summary =
client_summary_result(&addr, ConnectMethod::UDP, client_summary);
client_results.push(client_summary)
}
}

Expand Down
91 changes: 22 additions & 69 deletions src/util/message.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use std::net::SocketAddr;

use tabled::settings::Panel;
use tabled::settings::{object::Rows, Alignment, Margin, Modify, Span, Style};
use tabled::Table;

use crate::core::common::{
ClientResult, ClientSummary, ConnectMethod, ConnectRecord, ConnectResult, HostRecord,
};
use crate::core::common::{ClientResult, ConnectMethod, ConnectRecord, ConnectResult, HostRecord};

/// Return the CLI header message
pub fn cli_header_msg() -> String {
Expand Down Expand Up @@ -85,62 +84,29 @@ pub fn client_result_msg(record: &ConnectRecord) -> String {
}
}

/// Returns a client connection summary message
pub fn client_summary_msg(
destination: &String,
protocol: ConnectMethod,
client_summary: ClientSummary,
) -> ClientResult {
let mut min: f64 = 0.0;
let mut max: f64 = 0.0;
let mut avg: f64 = 0.0;
let mut latencies = client_summary.latencies;

// Filetr our any f64::NAN
latencies.retain(|f| !f.is_nan());
latencies.retain(|f| f > &0.0);

// Sort lowest to highest
// TODO: Fix this unwrap
latencies.sort_by(|a, b| a.partial_cmp(b).unwrap());

if !latencies.is_empty() {
min = *latencies.first().unwrap_or(&0.0);
max = *latencies.last().unwrap_or(&0.0);
let sum: f64 = latencies.iter().sum();
avg = sum / latencies.len() as f64;
}

let received_count = latencies.len() as u16;

ClientResult {
destination: destination.to_owned(),
protocol,
sent: client_summary.send_count,
received: received_count,
lost: client_summary.send_count - received_count,
loss_percent: calc_loss_percent(client_summary.send_count, received_count),
min,
max,
avg,
}
}

pub fn client_summary_table_msg(
dst_host: &String,
dst_port: u16,
connect_method: ConnectMethod,
client_results: &Vec<ClientResult>,
) -> String {
let header = format!(
"Statistics for {} connection to {}:{}",
"--- Statistics for {} connection to {}:{} ---",
connect_method.to_string().to_uppercase(),
dst_host,
dst_port,
);
let mut table = Table::new(client_results);
table.with(Panel::header(header));
table.to_string()
Table::new(client_results)
// table
.with(Style::ascii())
.with(Margin::new(0, 0, 1, 1))
.with(Panel::header(header))
.with(
Modify::new(Rows::first())
.with(Span::column(9))
.with(Alignment::center()),
)
.to_string()
}

/// Returns a server connection summary message
Expand Down Expand Up @@ -174,13 +140,6 @@ pub fn server_conn_success_msg(
}
}

/// Calculate the percentage of loss between the
/// amount of pings sent and the amount received
pub fn calc_loss_percent(sent: u16, received: u16) -> f64 {
let percent = (sent as f64 - received as f64) / sent as f64;
percent * 100.0
}

#[cfg(test)]
mod tests {
use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
Expand Down Expand Up @@ -259,13 +218,6 @@ mod tests {
assert_eq!(msg, "Connecting to 198.51.100.1:443 via TCP");
}

#[test]
fn calc_loss_percent_is_expected() {
let loss = calc_loss_percent(100, 99);

assert_eq!(loss, 1.0);
}

#[test]
fn cli_header_msg_is_expected() {
let msg = cli_header_msg();
Expand Down Expand Up @@ -307,13 +259,14 @@ mod tests {
&vec![client_results],
);

let expected = "+--------------+----------+------+----------+------+--------+---------+---------+---------+\n\
| Statistics for TCP connection to stuff.things:443 |\n\
+--------------+----------+------+----------+------+--------+---------+---------+---------+\n\
| Destination | Protocol | Sent | Received | Lost | Loss % | Min | Max | Avg |\n\
+--------------+----------+------+----------+------+--------+---------+---------+---------+\n\
| 198.51.100.1 | TCP | 4 | 4 | 0 | 0.00 | 234.000 | 254.000 | 243.000 |\n\
+--------------+----------+------+----------+------+--------+---------+---------+---------+";
let expected = " \n\
+--------------+----------+------+----------+------+----------+----------+----------+----------+\n\
| --- Statistics for TCP connection to stuff.things:443 --- |\n\
+--------------+----------+------+----------+------+----------+----------+----------+----------+\n\
| Destination | Protocol | Sent | Received | Lost | Loss (%) | Min (ms) | Max (ms) | Avg (ms) |\n\
+--------------+----------+------+----------+------+----------+----------+----------+----------+\n\
| 198.51.100.1 | TCP | 4 | 4 | 0 | 0.00 | 234.000 | 254.000 | 243.000 |\n\
+--------------+----------+------+----------+------+----------+----------+----------+----------+\n ";

assert_eq!(summary_table, expected);
}
Expand Down
57 changes: 56 additions & 1 deletion src/util/result.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::collections::HashMap;

use crate::core::common::HostRecord;
use crate::core::common::{ClientResult, ClientSummary, ConnectMethod, HostRecord};

/// Return a results_map hash from a Vec of HostRecords
pub fn get_results_map(host_records: &[HostRecord]) -> HashMap<String, HashMap<String, Vec<f64>>> {
Expand Down Expand Up @@ -28,6 +28,54 @@ pub fn get_results_map(host_records: &[HostRecord]) -> HashMap<String, HashMap<S
results_map
}

/// Returns a client summary result
pub fn client_summary_result(
destination: &String,
protocol: ConnectMethod,
client_summary: ClientSummary,
) -> ClientResult {
let mut min: f64 = 0.0;
let mut max: f64 = 0.0;
let mut avg: f64 = 0.0;
let mut latencies = client_summary.latencies;

// Filetr our any f64::NAN
latencies.retain(|f| !f.is_nan());
latencies.retain(|f| f > &0.0);

// Sort lowest to highest
// TODO: Fix this unwrap
latencies.sort_by(|a, b| a.partial_cmp(b).unwrap());

if !latencies.is_empty() {
min = *latencies.first().unwrap_or(&0.0);
max = *latencies.last().unwrap_or(&0.0);
let sum: f64 = latencies.iter().sum();
avg = sum / latencies.len() as f64;
}

let received_count = latencies.len() as u16;

ClientResult {
destination: destination.to_owned(),
protocol,
sent: client_summary.send_count,
received: received_count,
lost: client_summary.send_count - received_count,
loss_percent: calc_loss_percent(client_summary.send_count, received_count),
min,
max,
avg,
}
}

/// Calculate the percentage of loss between the
/// amount of pings sent and the amount received
pub fn calc_loss_percent(sent: u16, received: u16) -> f64 {
let percent = (sent as f64 - received as f64) / sent as f64;
percent * 100.0
}

#[cfg(test)]
mod tests {
use std::collections::HashMap;
Expand Down Expand Up @@ -85,4 +133,11 @@ mod tests {

assert_eq!(results_map, expected);
}

#[test]
fn calc_loss_percent_is_expected() {
let loss = calc_loss_percent(100, 99);

assert_eq!(loss, 1.0);
}
}
Loading