13 个版本
0.0.12 | 2023 年 6 月 5 日 |
---|---|
0.0.11 | 2023 年 6 月 4 日 |
0.0.10 | 2023 年 2 月 12 日 |
0.0.8 | 2023 年 1 月 17 日 |
#1113 in 并发
170KB
3.5K SLoC
纤维验证器
纤维验证器是一个用于模型检查 Fibril 系统的库。
用法
请参阅 fibril_verifier 的文档。
lib.rs
:
纤维验证器是一个用于模型检查 Fibril 系统的库。
示例
[dependencies]
fibril = { version = "0", features = ["fibers", "rt", "serde_json"] }
serde = { version = "1", features = ["derive"] }
[dev-dependencies]
fibril_verifier = "0"
use fibril::*;
#[derive(Clone, Debug, PartialEq, serde::Deserialize, serde::Serialize)]
enum Msg { Inc, Double, Value(u64) }
fn server(sdk: Sdk<Msg>) {
let mut val = 0;
loop {
let (src, msg) = sdk.recv();
match msg {
Msg::Inc => {
val += 1;
sdk.send(src, Msg::Value(val));
}
Msg::Double => {
val *= 2;
sdk.send(src, Msg::Value(val));
}
_ => sdk.exit(),
}
}
}
// In the binary, bind the server to a UDP socket.
fn run_server_over_udp() {
use std::net::Ipv4Addr;
let mut rt = UdpRuntime::new_with_serde_json()
.ipv4(Ipv4Addr::LOCALHOST)
.port_fn(|n| 3000 + n);
rt.spawn(|| Fiber::new(server));
rt.join().unwrap();
}
// In the tests, the model checker will attempt to find a "trace" (sequence of steps) that
// causes a panic.
#[cfg(test)]
#[test]
fn may_panic() {
use fibril_verifier::*;
let mut verifier = Verifier::new(|cfg| {
let server = cfg.spawn(Fiber::new(server));
cfg.spawn(Fiber::new(move |sdk| {
sdk.send(server, Msg::Inc);
let (_src, msg) = sdk.recv();
assert_eq!(msg, Msg::Value(1)); // truth depends on race winner
}));
cfg.spawn(Fiber::new(move |sdk| {
sdk.send(server, Msg::Double);
let (_src, msg) = sdk.recv();
assert_eq!(msg, Msg::Value(2)); // truth depends on race winner
}));
});
// TIP: alternatively use verifier.assert_no_panic() to fail the test.
let (msg, _minimal_trace) = verifier.assert_panic();
assert!(msg.contains("left == right"));
}
以下是一个使用 netcat 与服务器交互的示例。
# send STDOUT to disk for clarity as replies are not newline delimited
$ nc -u 127.0.0.1 3000 > /tmp/replies
"Inc"
"Inc"
"Double"
^C
$ cat /tmp/replies
{"Value":1}{"Value":2}{"Value":4}
依赖项
~4–14MB
~155K SLoC