Fix runtime tick outcome counting

This commit is contained in:
Michael Mikovsky
2026-05-09 12:51:03 -06:00
parent 0f54b53a79
commit 8bf660546a
+97
View File
@@ -150,6 +150,7 @@ where
/// Processes one nonblocking runtime step. /// Processes one nonblocking runtime step.
pub fn tick(&mut self, budget: TickBudget) -> Result<TickOutcome, NodeRuntimeError<T::Error>> { pub fn tick(&mut self, budget: TickBudget) -> Result<TickOutcome, NodeRuntimeError<T::Error>> {
let mut outcome = TickOutcome::default(); let mut outcome = TickOutcome::default();
let effects_start = self.effects.entries().len();
for _ in 0..budget.max_inbound_frames { for _ in 0..budget.max_inbound_frames {
let Some((connection, frame)) = self let Some((connection, frame)) = self
@@ -167,12 +168,14 @@ where
.effects .effects
.entries() .entries()
.iter() .iter()
.skip(effects_start)
.filter(|effect| matches!(effect, RuntimeEffect::Dropped)) .filter(|effect| matches!(effect, RuntimeEffect::Dropped))
.count(); .count();
outcome.local_events += self outcome.local_events += self
.effects .effects
.entries() .entries()
.iter() .iter()
.skip(effects_start)
.filter(|effect| matches!(effect, RuntimeEffect::Local(_))) .filter(|effect| matches!(effect, RuntimeEffect::Local(_)))
.count(); .count();
@@ -505,4 +508,98 @@ mod tests {
.expect("frame processes"); .expect("frame processes");
assert!(matches!(runtime.effects()[0], RuntimeEffect::Local(_))); assert!(matches!(runtime.effects()[0], RuntimeEffect::Local(_)));
} }
#[test]
fn tick_counts_only_new_local_events() {
let parent = ConnectionId::new(1);
let mut connections = Connections::new();
connections.push(Connection::registered(
parent,
ConnectionDirection::Parent,
vec![],
ConnectionGeneration::INITIAL,
));
let mut endpoint =
ProtocolEndpoint::new(vec![String::from("agent")], Some(vec![]), vec![], vec![]);
endpoint
.add_endpoint_procedure("org.example.v1.echo.invoke")
.expect("procedure registers");
let frame = encode_packet(
&PacketHeader {
packet_type: PacketType::Call,
src_path: vec![],
dst_path: vec![String::from("agent")],
dst_leaf: None,
hook_id: None,
},
&CallMessage {
procedure_id: String::from("org.example.v1.echo.invoke"),
data: vec![],
response_hook: None,
},
)
.expect("frame encodes");
let transport = RecordingTransport {
inbound: Some((parent, frame)),
sent: Vec::new(),
};
let mut runtime = NodeRuntime::new(EndpointState::new(endpoint), connections, transport);
let first = runtime.tick(TickBudget::default()).expect("tick succeeds");
assert_eq!(first.local_events, 1);
assert!(matches!(runtime.effects()[0], RuntimeEffect::Local(_)));
let second = runtime.tick(TickBudget::default()).expect("tick succeeds");
assert_eq!(second.local_events, 0);
assert!(matches!(runtime.effects()[0], RuntimeEffect::Local(_)));
}
#[test]
fn tick_counts_only_new_dropped_frames() {
let child = ConnectionId::new(1);
let mut connections = Connections::new();
connections.push(Connection::registered(
child,
ConnectionDirection::Child,
vec![String::from("agent"), String::from("kid")],
ConnectionGeneration::INITIAL,
));
let mut endpoint =
ProtocolEndpoint::new(vec![String::from("agent")], Some(vec![]), vec![], vec![]);
endpoint
.add_endpoint_procedure("org.example.v1.echo.invoke")
.expect("procedure registers");
let frame = encode_packet(
&PacketHeader {
packet_type: PacketType::Call,
src_path: vec![String::from("agent"), String::from("kid")],
dst_path: vec![String::from("agent")],
dst_leaf: None,
hook_id: None,
},
&CallMessage {
procedure_id: String::from("org.example.v1.echo.invoke"),
data: vec![],
response_hook: None,
},
)
.expect("frame encodes");
let transport = RecordingTransport {
inbound: Some((child, frame)),
sent: Vec::new(),
};
let mut runtime = NodeRuntime::new(EndpointState::new(endpoint), connections, transport);
let first = runtime.tick(TickBudget::default()).expect("tick succeeds");
assert_eq!(first.dropped_frames, 1);
assert!(matches!(runtime.effects()[0], RuntimeEffect::Dropped));
let second = runtime.tick(TickBudget::default()).expect("tick succeeds");
assert_eq!(second.dropped_frames, 0);
assert!(matches!(runtime.effects()[0], RuntimeEffect::Dropped));
}
} }