#trace #emulation #model #networking #utility

netem-trace

A library for for generating network emulation trace

8 releases

0.3.4 Jun 30, 2024
0.3.3 Jun 25, 2024
0.3.2 Mar 22, 2024
0.3.0 Nov 29, 2023
0.1.0 Feb 12, 2023

#238 in Network programming

Apache-2.0

115KB
1.5K SLoC

netem-trace

github-repo crates.io docs.rs LICENSE Apache-2.0

A library for generating network emulation trace. Now only supported mahimahi.

Attention: This library is still under development. The API is not stable.

MSRV: 1.60

Examples

Use bandwidth model directly (model or bw-model feature should be enabled):

use netem_trace::model::{StaticBwConfig, NormalizedBwConfig};
use netem_trace::{Bandwidth, Duration, BwTrace};
let mut static_bw = StaticBwConfig::new()
    .bw(Bandwidth::from_mbps(24))
    .duration(Duration::from_secs(1))
    .build();
assert_eq!(
    static_bw.next_bw(),
    Some((Bandwidth::from_mbps(24), Duration::from_secs(1)))
);
let mut normal_bw = NormalizedBwConfig::new()
    .mean(Bandwidth::from_mbps(12))
    .std_dev(Bandwidth::from_mbps(1))
    .duration(Duration::from_secs(1))
    .step(Duration::from_millis(100))
    .seed(42)
    .build();
assert_eq!(
    normal_bw.next_bw(),
    Some((Bandwidth::from_bps(12069427), Duration::from_millis(100)))
);
assert_eq!(
    normal_bw.next_bw(),
    Some((Bandwidth::from_bps(12132938), Duration::from_millis(100)))
);
let mut normal_bw = NormalizedBwConfig::new()
    .mean(Bandwidth::from_mbps(12))
    .std_dev(Bandwidth::from_mbps(1))
    .duration(Duration::from_secs(1))
    .step(Duration::from_millis(100))
    .seed(42)
    .upper_bound(Bandwidth::from_kbps(12100))
    .lower_bound(Bandwidth::from_kbps(11900))
    .build();
assert_eq!(
    normal_bw.next_bw(),
    Some((Bandwidth::from_bps(12069427), Duration::from_millis(100)))
);
assert_eq!(
    normal_bw.next_bw(),
    Some((Bandwidth::from_bps(12100000), Duration::from_millis(100)))
);

Produce traces in mahimahi format (mahimahi feature should also be enabled):

use netem_trace::model::{StaticBwConfig};
use netem_trace::{Bandwidth, Duration};
use netem_trace::{Mahimahi, MahimahiExt};
let mut static_bw = StaticBwConfig::new()
    .bw(Bandwidth::from_mbps(24))
    .duration(Duration::from_secs(1))
    .build();
assert_eq!(
    static_bw.mahimahi(&Duration::from_millis(5)),
    [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]
);
let mut static_bw = StaticBwConfig::new()
    .bw(Bandwidth::from_mbps(12))
    .duration(Duration::from_secs(1))
    .build();
assert_eq!(
    static_bw.mahimahi_to_string(&Duration::from_millis(5)),
    "1\n2\n3\n4\n5"
);
let a = vec![
    Box::new(
        StaticBwConfig::new()
            .bw(Bandwidth::from_mbps(12))
            .duration(Duration::from_secs(1)),
    ) as Box<dyn BwTraceConfig>,
    Box::new(
        StaticBwConfig::new()
            .bw(Bandwidth::from_mbps(24))
            .duration(Duration::from_secs(1)),
    ) as Box<dyn BwTraceConfig>,
];
let mut c = Box::new(RepeatedBwPatternConfig::new().pattern(a).count(2)).into_model();
assert_eq!(c.mahimahi(&Duration::from_millis(5)), [1, 2, 3, 4, 5]);

Load traces in mahimahi format (mahimahi feature should also be enabled):

use netem_trace::load_mahimahi_trace;
use netem_trace::{Bandwidth, BwTrace, Duration};
let trace = vec![1, 1, 5, 6];
let mut bw = load_mahimahi_trace(trace, None).unwrap().build();
// first cycle
assert_eq!(
    bw.next_bw(),
    Some((Bandwidth::from_mbps(24), Duration::from_millis(1)))
);
assert_eq!(
    bw.next_bw(),
    Some((Bandwidth::from_mbps(0), Duration::from_millis(3)))
);
assert_eq!(
    bw.next_bw(),
    Some((Bandwidth::from_mbps(12), Duration::from_millis(2)))
);
// second cycle
assert_eq!(
    bw.next_bw(),
    Some((Bandwidth::from_mbps(24), Duration::from_millis(1)))
);

Work with configuration files (serde feature should also be enabled):

use netem_trace::model::{StaticBwConfig, BwTraceConfig, RepeatedBwPatternConfig};
use netem_trace::{Bandwidth, Duration, BwTrace};

let a = vec![
    Box::new(
        StaticBwConfig::new()
            .bw(Bandwidth::from_mbps(12))
            .duration(Duration::from_secs(1)),
    ) as Box<dyn BwTraceConfig>,
    Box::new(
        StaticBwConfig::new()
            .bw(Bandwidth::from_mbps(24))
            .duration(Duration::from_secs(1)),
    ) as Box<dyn BwTraceConfig>,
];
let ser =
    Box::new(RepeatedBwPatternConfig::new().pattern(a).count(2)) as Box<dyn BwTraceConfig>;
let ser_str = serde_json::to_string(&ser).unwrap();
let des_str = "{\"RepeatedBwPatternConfig\":{\"pattern\":[{\"StaticBwConfig\":{\"bw\":{\"gbps\":0,\"bps\":12000000},\"duration\":{\"secs\":1,\"nanos\":0}}},{\"StaticBwConfig\":{\"bw\":{\"gbps\":0,\"bps\":24000000},\"duration\":{\"secs\":1,\"nanos\":0}}}],\"count\":2}}";
// The content would be "{\"RepeatedBwPatternConfig\":{\"pattern\":[{\"StaticBwConfig\":{\"bw\":\"12Mbps\",\"duration\":\"1s\"}},{\"StaticBwConfig\":{\"bw\":\"24Mbps\",\"duration\":\"1s\"}}],\"count\":2}}"
// if the `human` feature is also enabled.
assert_eq!(ser_str, des_str);
let des: Box<dyn BwTraceConfig> = serde_json::from_str(des_str).unwrap();
let mut model = des.into_model();
assert_eq!(
    model.next_bw(),
    Some((Bandwidth::from_mbps(12), Duration::from_secs(1)))
);

Maintainer

@BobAnkh

How to contribute

You should follow our Code of Conduct.

See CONTRIBUTING GUIDELINES for contributing conventions.

Make sure to pass all the tests before submitting your code.

Contributors

Yixin
Yixin Shen
Haixuan
Haixuan Tong
Yixuan
Yixuan Gao

LICENSE

Apache-2.0

Dependencies

~55–640KB
~12K SLoC