Open feyleth opened 1 month ago
My guess is that if the scheduling of the async task differs between loom::future::block_on
and shuttle::future::block_on
, it could produce different results.
the block on might no have impact with that case
if we change loom::future::block_on
by one runtime create manually ex :
loom
#[test]
#[cfg(loom)]
fn test() {
use loom::thread;
let runtime = tokio::runtime::Builder::new_multi_thread().build().unwrap();
loom::model(move || {
let node = Node::new();
let clone_node = node.clone();
let subcribe_thread = thread::spawn(move || clone_node.subcribe());
thread::spawn(move || {
node.change_name("change".to_owned());
})
.join()
.unwrap();
let (new_node, mut events) = subcribe_thread.join().unwrap();
if new_node.name == "start" {
assert_eq!(
new_node,
NodeValue {
name: "start".to_owned(),
}
);
runtime.block_on(async move {
assert_eq!(events.recv().await, Ok(Event::Name("change".to_owned())));
});
} else {
assert_eq!(
new_node,
NodeValue {
name: "change".to_owned(),
}
);
}
});
}
shuttle:
#[test]
#[cfg(feature = "shuttle")]
fn test() {
use shuttle::thread;
let runtime = tokio::runtime::Builder::new_multi_thread().build().unwrap();
shuttle::check_random(
move || {
let node = Node::new();
let clone_node = node.clone();
let subcribe_thread = thread::spawn(move || clone_node.subcribe());
thread::spawn(move || {
node.change_name("change".to_owned());
})
.join()
.unwrap();
let (new_node, mut events) = subcribe_thread.join().unwrap();
if new_node.name == "start" {
assert_eq!(
new_node,
NodeValue {
name: "start".to_owned(),
}
);
runtime.block_on(async move {
assert_eq!(events.recv().await, Ok(Event::Name("change".to_owned())));
});
} else {
assert_eq!(
new_node,
NodeValue {
name: "change".to_owned(),
}
);
}
},
100,
);
}
still get same result
loom doesn't run this case:
pub fn subcribe(&self) -> (NodeValue, broadcast::Receiver<Event>) {
let node = self.value.lock().expect("Faile to get mutex").clone();
// run the thread that change_name at this moment
let subscribe = self.broadcast.subscribe();
((node), subscribe)
}
that does the receiver is create after the message was send so receiver doesn't have that message (normal but doesn't run this loom)
in this case not all branch was pass
but if we run same test with shuttle it will failed as expected