use super::*;
fn run_actions(actions: &[(Kind, u8, u8, u8)]) {
let actions: Vec<_> = actions
.iter()
.map(|&(kind, slot, value, budget)| Action {
kind,
slot,
value,
budget,
})
.collect();
run(&actions);
}
#[test]
fn test_notifications() {
use Kind::*;
for budget in [0, 10, 255] {
for value in [0, 1, 2, 7] {
run_actions(&[
(Request, 0, 10, budget),
(Notify, 0, 0, 0),
(Notify, 0, 0, 0),
(Receive, 0, 20, 0),
(Reply, 0, 30, budget),
(Notify, 1, 0, 0),
(Outgoing, 0, 0, 0),
(Outgoing, 0, 0, 0),
(Written, 0, 2, 0),
(Answer, 0, value, 0),
(Written, 1, value, 0),
(Notify, 0, 0, 0),
(Notify, 1, 0, 0),
(Wait, 0, 0, 0),
(Wait, 1, 0, 0),
(Notify, 0, 0, 0),
]);
}
}
}
#[test]
fn test_notification_lifetimes() {
use Kind::*;
for ending in [Expire, Close, Drop, Open, CloseServer, DropSource] {
for observer in [Notify, Wait, DropPromise] {
run_actions(&[
(Request, 0, 10, 10),
(Request, 0, 11, 10),
(Receive, 0, 20, 0),
(Reply, 0, 30, 10),
(Notify, 0, 0, 0),
(Notify, 2, 0, 0),
(observer, 0, 0, 0),
(observer, 2, 0, 0),
(Advance, 0, 0, 10),
(ending, 0, 0, 0),
(Drop, 0, 0, 0),
(Notify, 1, 0, 0),
(Notify, 1, 0, 0),
]);
}
}
run_actions(&[
(Request, 0, 10, 100),
(Notify, 0, 0, 0),
(Outgoing, 0, 0, 0),
(Answer, 0, 0, 0),
(InboundLimits, 0, 0, 0),
(Wait, 0, 0, 0),
]);
}
#[test]
fn test_completion_orderings() {
use Kind::*;
for time in [9, 10, 11] {
for result in 0..3 {
let steps = [
(Request, 0, 10, 10),
(Request, 0, 20, 20),
(Outgoing, 0, 0, 0),
(Outgoing, 0, 0, 0),
(Receive, 0, 30, 1),
(Reply, 0, 40, 10),
(Outgoing, 0, 0, 0),
(Written, 1, 2, 0),
(Written, 1, 2, 0),
(Advance, 0, 0, time),
(Written, 2, 2, 0),
(Answer, 1, result, 0),
(Answer, 0, result, 0),
(Open, 0, 0, 1),
(Written, 2, 0, 0),
(Request, 1, 50, 20),
(Outgoing, 1, 0, 0),
(Close, 0, 1, 0),
(Answer, 3, result, 0),
(Drop, 0, 0, 0),
];
run_actions(&steps);
}
}
}
#[test]
fn test_model_scripts() {
use Kind::*;
for ending in [Open, Close, Drop, CloseServer, DropSource] {
for budget in [0, 1, 10, 255] {
run_actions(&[
(Request, 0, 10, budget),
(Request, 0, 20, budget),
(Outgoing, 0, 0, 0),
(Written, 0, 2, 0),
(Receive, 0, 30, 0),
(Reply, 0, 40, budget),
(Outgoing, 0, 0, 0),
(Advance, 0, 0, budget),
(Answer, 0, 0, 0),
(Expire, 0, 0, 0),
(ending, 0, 2, 0),
(Request, 0, 50, budget),
(Receive, 0, 60, 0),
(Abandon, 1, 0, 0),
(Outgoing, 0, 0, 0),
(DropPromise, 1, 0, 0),
(Drop, 0, 0, 0),
]);
}
}
run_actions(&[
(Receive, 0, 10, 0),
(AbandonmentTimeout, 0, 0, 10),
(Abandon, 0, 0, 0),
(Outgoing, 0, 0, 0),
(Written, 0, 0, 0),
(Open, 0, 0, 0),
(Close, 0, 0, 0),
(Request, 0, 20, 10),
(Drop, 0, 0, 0),
]);
}
#[test]
fn test_parked_waits() {
use Kind::*;
for budget in [0, 4, 200] {
for value in [0, 1, 2, 7] {
run_actions(&[
(Request, 0, 10, budget),
(Receive, 0, 20, 0),
(Reply, 0, 30, budget),
(Wait, 0, 0, 0),
(Wait, 1, 0, 0),
(Outgoing, 0, 0, 0),
(Outgoing, 0, 0, 0),
(Written, 0, value, 0),
(Written, 1, value, 0),
(Answer, 0, value, 0),
(Wait, 0, 0, 0),
(Wait, 1, 0, 0),
]);
}
}
}
#[test]
fn test_parked_wait_endings() {
use Kind::*;
for ending in [Expire, Close, Drop, Open, CloseServer, DropSource] {
for elapsed in [9, 10, 11] {
run_actions(&[
(Request, 0, 10, 10),
(Receive, 0, 20, 0),
(Reply, 0, 30, 10),
(Wait, 0, 0, 0),
(Wait, 1, 0, 0),
(Advance, 0, 0, elapsed),
(ending, 0, 2, 0),
(Wait, 0, 0, 0),
(Wait, 1, 0, 0),
]);
}
}
run_actions(&[
(Request, 0, 10, 20),
(Outgoing, 0, 0, 0),
(Wait, 0, 0, 0),
(Open, 0, 0, 0),
(Request, 1, 20, 20),
(Wait, 1, 0, 0),
(Outgoing, 1, 0, 0),
(Answer, 1, 0, 0),
(Wait, 1, 0, 0),
(Wait, 0, 0, 0),
]);
}
#[test]
fn test_raced_endings() {
use Kind::*;
for value in [0, 1, 2] {
run_actions(&[(Request, 0, 10, 30), (Close, 0, value, 0)]);
}
run_actions(&[(Receive, 0, 10, 0), (Reply, 0, 3, 30)]);
run_actions(&[(Request, 0, 10, 30), (Outgoing, 0, 0, 0), (Answer, 0, 7, 0)]);
run_actions(&[
(Receive, 0, 10, 0),
(Reply, 0, 20, 30),
(Outgoing, 0, 0, 0),
(Written, 0, 7, 0),
]);
for value in [0, 1, 2] {
run_actions(&[
(Receive, 0, 10, 0),
(Reply, 0, 20, 30),
(Outgoing, 0, 0, 0),
(Written, 0, value, 0),
(Written, 0, 7, 0),
]);
}
}
#[test]
fn test_server_endings() {
use Kind::*;
for value in [1, 2, 3] {
run_actions(&[
(Request, 0, 10, 30),
(Outgoing, 0, 0, 0),
(Close, 0, 2, 0),
(CloseServer, 0, value, 0),
(Open, 0, 0, 0),
(Request, 0, 20, 30),
]);
}
}
#[test]
fn test_parked_acceptance() {
use Kind::*;
for ending in [Open, CloseServer, DropSource] {
for value in [0, 2, 3] {
run_actions(&[
(Open, 0, 0, 2),
(Receive, 0, 10, 0),
(Request, 0, 20, 30),
(ending, 0, value, 0),
(Receive, 0, 30, 1),
(Request, 0, 40, 30),
(Reply, 0, 50, 30),
]);
}
}
run_actions(&[(Close, 0, 2, 0), (Open, 0, 0, 2), (CloseServer, 0, 2, 0)]);
}
#[test]
fn test_batched_abandonment() {
use Kind::*;
for timeout in [None, Some(0), Some(1), Some(60)] {
let mut actions = vec![
(Receive, 0, 10, 0),
(Receive, 0, 20, 0),
(Receive, 0, 30, 0),
];
if let Some(timeout) = timeout {
actions.push((AbandonmentTimeout, 0, 0, timeout));
}
actions.extend([
(Abandon, 2, 0, 0),
(Abandon, 0, 0, 0),
(Abandon, 1, 0, 0),
(Outgoing, 0, 1, 0),
(Outgoing, 0, 1, 0),
]);
run_actions(&actions);
}
}
#[test]
fn test_inbound_request_limits() {
use Kind::*;
for requests in [0, 1, 2, 4] {
for bytes in [0, 4, 5, 7, 14, 255] {
run_actions(&[
(InboundLimits, 0, requests, bytes),
(IncomingBatch, 0, 10, 1),
(Reply, 0, 20, 10),
(Abandon, 1, 0, 0),
(Outgoing, 0, 0, 0),
(Receive, 0, 30, 1),
(Advance, 0, 0, 10),
(Expire, 0, 0, 0),
(InboundLimits, 0, 0, 0),
(Open, 0, 0, 0),
(Receive, 1, 40, 0),
]);
}
}
}
#[test]
fn test_inbound_response_limits() {
use Kind::*;
for result in 0..3 {
let bytes = answer_size(match result {
0 => Ok(0),
1 => Err(Failure::Remote(257)),
_ => Err(Failure::WrongType),
}) as u8;
for observer in [Wait, DropPromise, Advance] {
run_actions(&[
(InboundLimits, 0, 4, bytes),
(Request, 0, 10, 20),
(Outgoing, 0, 0, 0),
(Answer, 0, result, 0),
(InboundLimits, 0, 0, bytes),
(observer, 0, 0, 0),
(Request, 0, 20, 20),
(Outgoing, 0, 0, 0),
(Answer, 1, result, 0),
(InboundLimits, 0, 4, bytes - 1),
(Open, 0, 0, 0),
(Drop, 0, 0, 0),
(Wait, 0, 0, 0),
(Wait, 1, 0, 0),
(Receive, 1, 30, 0),
]);
}
for observer in [Wait, DropPromise] {
run_actions(&[
(InboundLimits, 0, 0, bytes),
(Request, 0, 10, 20),
(Outgoing, 0, 0, 0),
(observer, 0, 0, 0),
(Answer, 0, result, 0),
(InboundLimits, 0, 1, 0),
(Request, 0, 20, 1),
(Outgoing, 0, 0, 0),
(Advance, 0, 0, 1),
(Answer, 1, result, 0),
(Wait, 1, 0, 0),
]);
}
}
}