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

return suitable string when error occur #34 #39

Open
wants to merge 15 commits into
base: main
Choose a base branch
from
Open
10 changes: 9 additions & 1 deletion src/bin/latency.rs
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,15 @@ fn do_client(
}
}
});

let is_tx_ts_enabled = {
if sock.enable_tx_timestamp().is_err() {
eprintln!("Failed to enable TX timestamp");
false
} else {
eprintln!("Socket TX timestamp enabled");
true
}
};
let mut tx_perf_buff = vec![0u8; size - 14];
let mut tx_eth_buff = vec![0u8; size];

Expand Down
94 changes: 64 additions & 30 deletions src/cbs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,15 @@
let output = Command::new("ethtool").arg(ifname).output();
match output {
Ok(output) => {
let out = str::from_utf8(&output.stdout).unwrap();
let pattern = regex::Regex::new(r"Speed: (?P<speed>\d+(?:|k|M|G)b[p/]?s)").unwrap();
let matched = pattern.captures(out).unwrap();
Ok(matched.name("speed").unwrap().as_str().to_string())
let out = str::from_utf8(&output.stdout).expect("failed to parse cbs schedule");
let pattern = regex::Regex::new(r"Speed: (?P<speed>\d+(?:|k|M|G)b[p/]?s)")
.expect("failed to parse cbs schedule");
let matched = pattern.captures(out).expect("failed to parse cbs schedule");
Ok(matched
.name("speed")
.expect("failed to parse cbs schedule")
.as_str()
.to_string())
}
Err(e) => Err(e.to_string()),
}
Expand All @@ -42,12 +47,23 @@
if let Some(value) = input.as_str() {
let matched =
regex::Regex::new(r"^(?P<v>[\d_]+)\s*(?P<modifier>|k|M|G|ki|Mi|Gi)(?P<b>b|B)$")
.unwrap()
.expect("failed to parse cbs schedule")
.captures(value)
.unwrap();
let v = matched.name("v").unwrap().as_str().parse::<i64>().unwrap();
let modifier = matched.name("modifier").unwrap().as_str();
let b = matched.name("b").unwrap().as_str();
.expect("failed to parse cbs schedule");
let v = matched
.name("v")
.expect("failed to parse cbs schedule")
.as_str()
.parse::<i64>()
.expect("failed to parse cbs schedule");
let modifier = matched
.name("modifier")
.expect("failed to parse cbs schedule")
.as_str();
let b = matched
.name("b")
.expect("failed to parse cbs schedule")
.as_str();
let multiplier_bits = match b {
"b" => 1,
"B" => 8,
Expand All @@ -65,17 +81,25 @@
};
return Ok(v * multiplier_bits * multiplier_modifier);
}
Ok(input.as_i64().unwrap())
Ok(input.as_i64().expect("failed to parse cbs schedule"))
}

pub fn to_bps(input: &Value) -> Result<i64, String> {
if let Some(value) = input.as_str() {
let matched = regex::Regex::new(r"^(?P<v>[\d_]+)\s*(?P<modifier>|k|M|G)(?P<b>b|B)[p/]s$")
.unwrap()
.expect("failed to parse cbs schedule")
.captures(value)
.unwrap();
let v = matched.name("v").unwrap().as_str().parse::<i64>().unwrap();
let modifier = matched.name("modifier").unwrap().as_str();
.expect("failed to parse cbs schedule");
let v = matched
.name("v")
.expect("failed to parse cbs schedule")
.as_str()
.parse::<i64>()
.expect("failed to parse cbs schedule");
let modifier = matched
.name("modifier")
.expect("failed to parse cbs schedule")
.as_str();
return {
match modifier {
"" => Ok(v),
Expand All @@ -86,7 +110,7 @@
}
};
}
Ok(input.as_i64().unwrap())
Ok(input.as_i64().expect("failed to parse cbs schedule"))
}

pub fn calc_credits(
Expand All @@ -95,7 +119,7 @@
) -> (CbsCredit, CbsCredit) {
let mut idle_slope_a = 0;
let mut max_frame_a = 0;
for stream in streams.get(&'a').unwrap() {
for stream in streams.get(&'a').expect("failed to parse cbs schedule") {
idle_slope_a += stream.bandwidth;
max_frame_a += stream.max_frame;
}
Expand All @@ -111,7 +135,7 @@

let mut idle_slope_b = 0;
let mut max_frame_b = 0;
for stream in streams.get(&'b').unwrap() {
for stream in streams.get(&'b').expect("failed to parse cbs schedule") {
idle_slope_b += stream.bandwidth;
max_frame_b += stream.max_frame;
}
Expand Down Expand Up @@ -144,40 +168,50 @@
Ok(speed) => to_bps(&Value::String(speed))?,
Err(_) => 1_000_000_000, // 1000Mbps
};
for (prio, priomap) in config.as_mapping().unwrap() {
if !tc_map.contains_key(&prio.as_i64().unwrap()) {
tc_map.insert(prio.as_i64().unwrap(), tc_map.len() as i64);
for (prio, priomap) in config.as_mapping().expect("failed to parse cbs schedule") {
if !tc_map.contains_key(&prio.as_i64().expect("failed to parse cbs schedule")) {

Check failure on line 172 in src/cbs.rs

View workflow job for this annotation

GitHub Actions / clippy

[clippy] src/cbs.rs#L172

error: usage of `contains_key` followed by `insert` on a `HashMap` --> src/cbs.rs:172:9 | 172 | / if !tc_map.contains_key(&prio.as_i64().expect("failed to parse cbs schedule")) { 173 | | tc_map.insert( 174 | | prio.as_i64().expect("failed to parse cbs schedule"), 175 | | tc_map.len() as i64, 176 | | ); 177 | | } | |_________^ help: try this: `tc_map.entry(prio.as_i64().expect("failed to parse cbs schedule")).or_insert_with(|| tc_map.len() as i64);` | = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry = note: `-D clippy::map-entry` implied by `-D warnings`
Raw output
src/cbs.rs:172:9:e:error: usage of `contains_key` followed by `insert` on a `HashMap`
   --> src/cbs.rs:172:9
    |
172 | /         if !tc_map.contains_key(&prio.as_i64().expect("failed to parse cbs schedule")) {
173 | |             tc_map.insert(
174 | |                 prio.as_i64().expect("failed to parse cbs schedule"),
175 | |                 tc_map.len() as i64,
176 | |             );
177 | |         }
    | |_________^ help: try this: `tc_map.entry(prio.as_i64().expect("failed to parse cbs schedule")).or_insert_with(|| tc_map.len() as i64);`
    |
    = help: for further information visit https://rust-lang.github.io/rust-clippy/master/index.html#map_entry
    = note: `-D clippy::map-entry` implied by `-D warnings`


__END__
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Failed to parse 'prio' as integer" is more precise error message

tc_map.insert(
prio.as_i64().expect("failed to parse cbs schedule"),
tc_map.len() as i64,
);
}
let child = CbsChild {
prio: prio.as_i64().unwrap(),
prio: prio.as_i64().expect("failed to parse cbs schedule"),
max_frame: to_bits(
priomap
.get(&Value::String("max_frame".to_string()))
.unwrap(),
.expect("failed to parse cbs schedule"),
)?,
bandwidth: to_bps(
priomap
.get(&Value::String("bandwidth".to_string()))
.unwrap(),
.expect("failed to parse cbs schedule"),
)?,
};
let index = priomap
.get(Value::String("class".to_string()).as_str().unwrap())
.unwrap()
.get(
Value::String("class".to_string())
.as_str()
.expect("failed to parse cbs schedule"),
)
.expect("failed to parse cbs schedule")
.as_str()
.unwrap()
.expect("failed to parse cbs schedule")
.chars()
.next()
.unwrap();
streams.get_mut(&index).unwrap().push(child);
.expect("failed to parse cbs schedule");
streams
.get_mut(&index)
.expect("failed to parse cbs schedule")
.push(child);
}
tc_map.insert(-1, tc_map.len() as i64);
let num_tc = tc_map.len() as i64;
for i in 0..16 {
if tc_map.contains_key(&i) {
ret_map.insert(i, *tc_map.get(&i).unwrap());
ret_map.insert(i, *tc_map.get(&i).expect("failed to parse cbs schedule"));
} else {
ret_map.insert(i, *tc_map.get(&-1).unwrap());
ret_map.insert(i, *tc_map.get(&-1).expect("failed to parse cbs schedule"));
}
}
let (credits_a, credits_b) = calc_credits(&streams, linkspeed);
Expand Down
41 changes: 23 additions & 18 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::tas::{normalise_tas, TasConfig};
use serde_yaml::{self, Value};
use std::collections::HashMap;
use std::fs::File;
use std::io::BufReader;
use std::io::{BufReader, Error};
use std::str;

#[derive(Clone)]
Expand All @@ -25,46 +25,52 @@ impl Config {

pub fn normalise_vlan(input: &Value) -> HashMap<i64, HashMap<i64, i64>> {
let mut ret_map = HashMap::new();
for (valnid, prio) in input.as_mapping().unwrap() {
for (vlanid, prio) in input.as_mapping().expect("failed to parse vlan") {
let mut vlan_map = HashMap::new();
for (prio, pri) in prio.as_mapping().unwrap() {
vlan_map.insert(prio.as_i64().unwrap(), pri.as_i64().unwrap());
for (prio, pri) in prio.as_mapping().expect("failed to parse vlan") {
vlan_map.insert(
prio.as_i64().expect("failed to parse vlan"),
pri.as_i64().expect("failed to parse vlan"),
);
}
ret_map.insert(valnid.as_i64().unwrap(), vlan_map);
ret_map.insert(vlanid.as_i64().expect("failed to parse vlan"), vlan_map);
}
ret_map
}

pub fn read_config(config_path: &str) -> Result<HashMap<String, Config>, i64> {
let file = File::open(config_path).expect("failed to open config.yaml");
pub fn read_config(config_path: &str) -> Result<HashMap<String, Config>, String> {
let file = File::open(config_path)
.unwrap_or_else(|_| panic!("failed to open config.yaml: {}", Error::last_os_error()));
let reader = BufReader::new(file);
let config: Value = serde_yaml::from_reader(reader).expect("failed to parse YAML");
let config: Value = serde_yaml::from_reader(reader)
.unwrap_or_else(|_| panic!("failed to parse YAML: {}", Error::last_os_error()));
let config = config
.as_mapping()
.unwrap()
.expect("failed to parse config")
.get(&Value::String("nics".to_string()))
.unwrap()
.unwrap_or_else(|| panic!("failed to parse config: {}", Error::last_os_error()))
.as_mapping()
.unwrap();
.expect("failed to parse config");
let mut ifname;
let mut ret = HashMap::new();
for (key, value) in config {
let mut info = Config::new(HashMap::new());
let value = value.as_mapping().unwrap();
ifname = key.as_str().unwrap();
let value = value.as_mapping().expect("failed to parse config");
ifname = key.as_str().expect("failed to parse config");
if value.contains_key(&Value::String("egress-qos-map".to_string())) {
info.egress_qos_map = normalise_vlan(
value
.get(&Value::String("egress-qos-map".to_string()))
.unwrap(),
.expect("failed to parse config"),
);
} else {
return Err(format!("egress-qos-map is not defined for {}", ifname));
}
if value.contains_key(&Value::String("tas".to_string())) {
match normalise_tas(value.get(&Value::String("tas".to_string())).unwrap()) {
Ok(tas) => info.tas = Some(tas),
Err(e) => {
eprintln!("{}", e);
return Err(-1);
return Err(e);
}
}
}
Expand All @@ -75,8 +81,7 @@ pub fn read_config(config_path: &str) -> Result<HashMap<String, Config>, i64> {
) {
Ok(cbs) => info.cbs = Some(cbs),
Err(e) => {
eprintln!("{}", e);
return Err(-1);
return Err(e);
}
}
}
Expand Down
14 changes: 7 additions & 7 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ fn create_vlan(ifname: &str, vlanid: u16) -> Result<String, String> {
unlock_shmem(&shm_fd)?;
match result {
Ok(_) => Ok(name),
Err(_) => Err(format!("Create vlan fails {}", Error::last_os_error())),
Err(e) => Err(format!("Create vlan fails {}", e)),
}
}

Expand All @@ -108,7 +108,7 @@ fn delete_vlan(ifname: &str, vlanid: u16) -> Result<i32, String> {
}
match vlan::delete_vlan(ifname, vlanid) {
Ok(v) => Ok(v),
Err(_) => Err(format!("Delete vlan fails {}", Error::last_os_error())),
Err(e) => Err(format!("Delete vlan fails {}", e)),
}
} else {
Ok(0)
Expand All @@ -125,8 +125,8 @@ pub fn sock_open(
) -> Result<TsnSocket, String> {
let name = match create_vlan(ifname, vlanid) {
Ok(v) => v,
Err(_) => {
return Err(format!("Create vlan fails {}", Error::last_os_error()));
Err(e) => {
return Err(format!("Create vlan fails {}", e));
}
};
let sock;
Expand Down Expand Up @@ -188,10 +188,10 @@ pub fn sock_open(
pub fn sock_close(sock: &mut TsnSocket) -> Result<(), String> {
match delete_vlan(&sock.ifname, sock.vlanid) {
Ok(_) => {
close(sock.fd).unwrap();
close(sock.fd).expect("close sock");
Ok(())
}
Err(_) => Err(format!("Delete vlan fails: {}", Error::last_os_error())),
Err(e) => Err(format!("Delete vlan fails: {}", e)),
}
}

Expand Down Expand Up @@ -569,7 +569,7 @@ fn get_config(ifname: &str) -> Result<config::Config, String> {
let configs = config::read_config(&config_path);
let configs = match configs {
Ok(v) => v,
Err(_) => return Err(format!("Read config fails: {}", Error::last_os_error())),
Err(e) => return Err(format!("Read config fails: {}", e)),
};
let config = configs.get(ifname);
match config {
Expand Down
20 changes: 12 additions & 8 deletions src/tas.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,24 +43,28 @@ pub fn normalise_tas(config: &Value) -> Result<TasConfig, String> {
let mut ret_map = HashMap::new();
let schedules = config
.get(&Value::String("schedule".to_string()))
.unwrap()
.expect("failed to parse tas schedule")
.as_sequence()
.unwrap();
.expect("failed to parse tas schedule");
for schedule in schedules {
let mut v = Vec::new();

for prio in schedule
.get(&Value::String("prio".to_string()))
.unwrap()
.expect("failed to parse tas schedule")
.as_sequence()
.unwrap()
.expect("failed to parse tas schedule")
{
v.push(prio.as_i64().unwrap());
v.push(prio.as_i64().expect("priority must be an integer"));
if prio.as_i64().unwrap() > 0 && !tc_map.contains_key(&prio.as_i64().unwrap()) {
tc_map.insert(prio.as_i64().unwrap(), tc_map.len() as i64);
}
}
let time = to_ns(schedule.get(&Value::String("time".to_string())).unwrap())?;
let time = to_ns(
schedule
.get(&Value::String("time".to_string()))
.expect("failed to parse tas schedule"),
)
.expect("tas schedule time must be in ns");
tas_schedule.push(TasSchedule { time, prio: v });
}

Expand Down Expand Up @@ -91,7 +95,7 @@ pub fn normalise_tas(config: &Value) -> Result<TasConfig, String> {
let txtime_delay = to_ns(
config
.get(&Value::String("txtime_delay".to_string()))
.unwrap(),
.expect("failed to parse tas schedule"),
)?;
Ok(TasConfig {
txtime_delay,
Expand Down
Loading
Loading