include!("../../tests/wait_model.rs"); #[test] fn stale_wait_lookup_cannot_cancel_new_same_channel_generation() { let mut s = system(); let old = arm(&mut s, 0, 1, 0, None); let stale = wait::WaitToken { set: old.set, slot: old.slot, generation: old.generation, }; assert!(s.waits.cancel(&old).is_ok()); assert!(s.waits.retire(old).is_ok()); let next = arm(&mut s, 0, 1, 0, None); let before = s.waits.records(); assert_eq!(s.waits.cancel(&stale), Err(wait::Error::Stale)); assert_eq!(s.waits.records(), before); assert_eq!(s.ledger.pins.get(), 2); assert!(s.waits.cancel(&next).is_ok()); assert!(s.waits.retire(next).is_ok()); } #[test] fn same_desired_source_in_independent_sets_rejects_foreign_wait() { let mut a = system(); let mut b = system(); let token = arm(&mut a, 0, 1, 0, None); assert_ne!(a.waits.identity, b.waits.identity); assert_eq!(a.ingress[0].source(), b.ingress[0].source()); let before = b.waits.records(); assert_eq!(b.waits.cancel(&token), Err(wait::Error::Foreign)); assert_eq!(b.waits.records(), before); assert_eq!(b.ledger.pins.get(), 0); assert!(a.waits.cancel(&token).is_ok()); assert!(a.waits.retire(token).is_ok()); } #[test] fn generation_max_retires_slot_before_any_source_acquire() { let mut s = system(); s.waits.slots[0].record.generation = u64::MAX; let c = s .waits .with_backend_observation(|d| capture(&d.bank, s.handles[0], &s.hardware, 19, false)); let retains = s.ledger.retains.get(); let failure = s .waits .arm(&s.ingress[0], s.ids[0], s.ids[1], c, None) .err() .unwrap(); assert_eq!(failure.error, wait::Error::Exhausted); assert!(failure.retained.is_none()); assert_eq!(s.waits.records()[0].phase, wait::Phase::Retired); assert_eq!(s.ledger.retains.get(), retains); assert_eq!(s.ledger.pins.get(), 0); let token = arm(&mut s, 0, 1, 0, None); assert_eq!(token.slot(), 1); assert_eq!(token.generation(), 1); assert!(s.waits.cancel(&token).is_ok()); assert!(s.waits.retire(token).is_ok()); } #[test] fn loss_counter_overflow_retains_exact_events_and_producer_progression() { let mut s = system(); for sequence in 1..=2 { s.observations[0].borrow_mut().sequence = sequence; assert_eq!(s.ingress[0].poll(), Ok(true)); } s.ingress[0].lost = u64::MAX; s.observations[0].borrow_mut().sequence = 3; let sequence = s.ingress[0].sequence; let last = s.ingress[0].last_lost_sequence; let clock = s.ingress[0].clock; assert_eq!(s.ingress[0].poll(), Err(wait::Error::Exhausted)); assert_eq!(s.ingress[0].pending(), 2); assert_eq!(s.ingress[0].sequence, sequence); assert_eq!(s.ingress[0].last_lost_sequence, last); assert_eq!(s.ingress[0].clock, clock); } #[test] fn winner_counter_overflow_keeps_actual_staged_prepared_and_both_links() { let mut s = system(); let token = arm(&mut s, 0, 1, 0, Some(200)); s.waits.winners = u64::MAX; let before = s.waits.records(); let nonce = s.waits.slots[0] .owned .as_ref() .unwrap() .prepared .as_ref() .unwrap() .token .as_ref() .unwrap() .nonce(); assert_eq!(s.waits.cancel(&token), Err(wait::Error::Exhausted)); assert_eq!(s.waits.records(), before); assert_eq!(s.ledger.pins.get(), 2); assert_eq!( s.waits.slots[0] .owned .as_ref() .unwrap() .prepared .as_ref() .unwrap() .token .as_ref() .unwrap() .nonce(), nonce ); assert_eq!( s.waits.with_backend_observation(|d| d.state(s.ids[0])), ThreadState::Running ); }