mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-01 11:05:46 +00:00
test_infra: make measure_virtio_net_throughput & co measure PPS too
While measuring UDP PPS, we saturate the link, so there are packets lost. We only account for the packets that are not lost. Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
parent
d50a4cbb6b
commit
08e4d1f481
@ -105,7 +105,7 @@ pub fn performance_net_throughput(control: &PerformanceTestControl) -> f64 {
|
|||||||
|
|
||||||
let r = std::panic::catch_unwind(|| {
|
let r = std::panic::catch_unwind(|| {
|
||||||
guest.wait_vm_boot(None).unwrap();
|
guest.wait_vm_boot(None).unwrap();
|
||||||
measure_virtio_net_throughput(test_timeout, num_queues / 2, &guest, rx).unwrap()
|
measure_virtio_net_throughput(test_timeout, num_queues / 2, &guest, rx, true).unwrap()
|
||||||
});
|
});
|
||||||
|
|
||||||
let _ = child.kill();
|
let _ = child.kill();
|
||||||
@ -429,7 +429,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_iperf3_output(output.as_bytes(), true).unwrap(),
|
parse_iperf3_output(output.as_bytes(), true, true).unwrap(),
|
||||||
23957198874.604115
|
23957198874.604115
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -448,9 +448,31 @@ mod tests {
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
parse_iperf3_output(output.as_bytes(), false).unwrap(),
|
parse_iperf3_output(output.as_bytes(), false, true).unwrap(),
|
||||||
39520744482.79
|
39520744482.79
|
||||||
);
|
);
|
||||||
|
let output = r#"
|
||||||
|
{
|
||||||
|
"end": {
|
||||||
|
"sum": {
|
||||||
|
"start": 0,
|
||||||
|
"end": 5.000036,
|
||||||
|
"seconds": 5.000036,
|
||||||
|
"bytes": 29944971264,
|
||||||
|
"bits_per_second": 47911877363.396217,
|
||||||
|
"jitter_ms": 0.0038609822983198556,
|
||||||
|
"lost_packets": 16,
|
||||||
|
"packets": 913848,
|
||||||
|
"lost_percent": 0.0017508382137948542,
|
||||||
|
"sender": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
assert_eq!(
|
||||||
|
parse_iperf3_output(output.as_bytes(), true, false).unwrap(),
|
||||||
|
182765.08409139456
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1311,22 +1311,36 @@ pub fn clh_command(cmd: &str) -> String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_iperf3_output(output: &[u8], sender: bool) -> Result<f64, Error> {
|
pub fn parse_iperf3_output(output: &[u8], sender: bool, bandwidth: bool) -> Result<f64, Error> {
|
||||||
std::panic::catch_unwind(|| {
|
std::panic::catch_unwind(|| {
|
||||||
let s = String::from_utf8_lossy(output);
|
let s = String::from_utf8_lossy(output);
|
||||||
let v: Value = serde_json::from_str(&s).expect("'iperf3' parse error: invalid json output");
|
let v: Value = serde_json::from_str(&s).expect("'iperf3' parse error: invalid json output");
|
||||||
|
|
||||||
let bps: f64 = if sender {
|
if bandwidth {
|
||||||
|
if sender {
|
||||||
v["end"]["sum_sent"]["bits_per_second"]
|
v["end"]["sum_sent"]["bits_per_second"]
|
||||||
.as_f64()
|
.as_f64()
|
||||||
.expect("'iperf3' parse error: missing entry 'end.sum_sent.bits_per_second'")
|
.expect("'iperf3' parse error: missing entry 'end.sum_sent.bits_per_second'")
|
||||||
} else {
|
} else {
|
||||||
v["end"]["sum_received"]["bits_per_second"]
|
v["end"]["sum_received"]["bits_per_second"].as_f64().expect(
|
||||||
.as_f64()
|
"'iperf3' parse error: missing entry 'end.sum_received.bits_per_second'",
|
||||||
.expect("'iperf3' parse error: missing entry 'end.sum_received.bits_per_second'")
|
)
|
||||||
};
|
}
|
||||||
|
} else {
|
||||||
|
// iperf does not distinguish sent vs received in this case.
|
||||||
|
|
||||||
bps
|
let lost_packets = v["end"]["sum"]["lost_packets"]
|
||||||
|
.as_f64()
|
||||||
|
.expect("'iperf3' parse error: missing entry 'end.sum.lost_packets'");
|
||||||
|
let packets = v["end"]["sum"]["packets"]
|
||||||
|
.as_f64()
|
||||||
|
.expect("'iperf3' parse error: missing entry 'end.sum.packets'");
|
||||||
|
let seconds = v["end"]["sum"]["seconds"]
|
||||||
|
.as_f64()
|
||||||
|
.expect("'iperf3' parse error: missing entry 'end.sum.seconds'");
|
||||||
|
|
||||||
|
(packets - lost_packets) / seconds
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.map_err(|_| {
|
.map_err(|_| {
|
||||||
eprintln!(
|
eprintln!(
|
||||||
@ -1495,6 +1509,7 @@ pub fn measure_virtio_net_throughput(
|
|||||||
queue_pairs: u32,
|
queue_pairs: u32,
|
||||||
guest: &Guest,
|
guest: &Guest,
|
||||||
receive: bool,
|
receive: bool,
|
||||||
|
bandwidth: bool,
|
||||||
) -> Result<f64, Error> {
|
) -> Result<f64, Error> {
|
||||||
let default_port = 5201;
|
let default_port = 5201;
|
||||||
|
|
||||||
@ -1525,6 +1540,11 @@ pub fn measure_virtio_net_throughput(
|
|||||||
if !receive {
|
if !receive {
|
||||||
cmd.args(["-R"]);
|
cmd.args(["-R"]);
|
||||||
}
|
}
|
||||||
|
// Use UDP stream to measure packets per second. The bitrate is set to
|
||||||
|
// 1T to make sure it saturates the link.
|
||||||
|
if !bandwidth {
|
||||||
|
cmd.args(["-u", "-b", "1T"]);
|
||||||
|
}
|
||||||
let client = cmd
|
let client = cmd
|
||||||
.stderr(Stdio::piped())
|
.stderr(Stdio::piped())
|
||||||
.stdout(Stdio::piped())
|
.stdout(Stdio::piped())
|
||||||
@ -1535,7 +1555,7 @@ pub fn measure_virtio_net_throughput(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut err: Option<Error> = None;
|
let mut err: Option<Error> = None;
|
||||||
let mut bps = Vec::new();
|
let mut results = Vec::new();
|
||||||
let mut failed = false;
|
let mut failed = false;
|
||||||
for c in clients {
|
for c in clients {
|
||||||
let mut c = c;
|
let mut c = c;
|
||||||
@ -1547,7 +1567,7 @@ pub fn measure_virtio_net_throughput(
|
|||||||
if !failed {
|
if !failed {
|
||||||
// Safe to unwrap as we know the child has terminated succesffully
|
// Safe to unwrap as we know the child has terminated succesffully
|
||||||
let output = c.wait_with_output().unwrap();
|
let output = c.wait_with_output().unwrap();
|
||||||
bps.push(parse_iperf3_output(&output.stdout, receive)?);
|
results.push(parse_iperf3_output(&output.stdout, receive, bandwidth)?);
|
||||||
} else {
|
} else {
|
||||||
let _ = c.kill();
|
let _ = c.kill();
|
||||||
let output = c.wait_with_output().unwrap();
|
let output = c.wait_with_output().unwrap();
|
||||||
@ -1561,7 +1581,7 @@ pub fn measure_virtio_net_throughput(
|
|||||||
if let Some(e) = err {
|
if let Some(e) = err {
|
||||||
Err(e)
|
Err(e)
|
||||||
} else {
|
} else {
|
||||||
Ok(bps.iter().sum())
|
Ok(results.iter().sum())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9423,7 +9423,8 @@ mod rate_limiter {
|
|||||||
let r = std::panic::catch_unwind(|| {
|
let r = std::panic::catch_unwind(|| {
|
||||||
guest.wait_vm_boot(None).unwrap();
|
guest.wait_vm_boot(None).unwrap();
|
||||||
let measured_bps =
|
let measured_bps =
|
||||||
measure_virtio_net_throughput(test_timeout, num_queues / 2, &guest, rx).unwrap();
|
measure_virtio_net_throughput(test_timeout, num_queues / 2, &guest, rx, true)
|
||||||
|
.unwrap();
|
||||||
assert!(check_rate_limit(measured_bps, limit_bps, 0.1));
|
assert!(check_rate_limit(measured_bps, limit_bps, 0.1));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user