@@ -576,7 +576,10 @@ mod tests {
576576 use super :: * ;
577577 use crate :: test_helpers:: * ;
578578
579- use std:: time:: Duration ;
579+ use std:: {
580+ time:: { Duration , Instant } ,
581+ sync:: { Arc , atomic:: { AtomicU64 , Ordering } } ,
582+ } ;
580583
581584 #[ test]
582585 fn traits ( ) {
@@ -630,18 +633,64 @@ mod tests {
630633 }
631634
632635 #[ test]
633- fn test_create_timer_without_clock_source ( ) -> Result < ( ) , RclrsError > {
636+ fn test_create_timer ( ) -> Result < ( ) , RclrsError > {
634637 let context = Context :: new ( [ ] ) ?;
635638 let node = NodeBuilder :: new ( & context, "node_with_timer" )
636639 . namespace ( "test_create_timer" )
637640 . build ( ) ?;
638641
639- let _timer = node. create_timer_repeating ( Duration :: from_millis ( 1 ) , || { } ) ?;
642+ let repeat_counter = Arc :: new ( AtomicU64 :: new ( 0 ) ) ;
643+ let repeat_counter_check = Arc :: clone ( & repeat_counter) ;
644+ let _repeating_timer = node. create_timer_repeating (
645+ Duration :: from_millis ( 1 ) ,
646+ move || { repeat_counter. fetch_add ( 1 , Ordering :: AcqRel ) ; } ,
647+ ) ?;
640648 assert_eq ! ( node. live_timers( ) . len( ) , 1 ) ;
641649
650+ let oneshot_counter = Arc :: new ( AtomicU64 :: new ( 0 ) ) ;
651+ let oneshot_counter_check = Arc :: clone ( & oneshot_counter) ;
652+ let _oneshot_timer = node. create_timer_oneshot (
653+ Duration :: from_millis ( 1 )
654+ . node_time ( ) ,
655+ move || { oneshot_counter. fetch_add ( 1 , Ordering :: AcqRel ) ; } ,
656+ ) ?;
657+
658+ let oneshot_resetting_counter = Arc :: new ( AtomicU64 :: new ( 0 ) ) ;
659+ let oneshot_resetting_counter_check = Arc :: clone ( & oneshot_resetting_counter) ;
660+ let _oneshot_resetting_timer = node. create_timer_oneshot (
661+ Duration :: from_millis ( 1 ) ,
662+ move |timer : & Timer | {
663+ recursive_oneshot ( timer, oneshot_resetting_counter) ;
664+ } ,
665+ ) ;
666+
667+ let start = Instant :: now ( ) ;
668+ while start. elapsed ( ) < Duration :: from_millis ( 10 ) {
669+ crate :: spin_once ( Arc :: clone ( & node) , Some ( Duration :: from_millis ( 10 ) ) ) ?;
670+ }
671+
672+ // We give a little leeway to the exact count since timers won't always
673+ // be triggered perfectly. The important thing is that it was
674+ // successfully called repeatedly.
675+ assert ! ( repeat_counter_check. load( Ordering :: Acquire ) > 5 ) ;
676+ assert ! ( oneshot_resetting_counter_check. load( Ordering :: Acquire ) > 5 ) ;
677+
678+ // This should only have been triggered exactly once
679+ assert_eq ! ( oneshot_counter_check. load( Ordering :: Acquire ) , 1 ) ;
680+
642681 Ok ( ( ) )
643682 }
644683
684+ fn recursive_oneshot (
685+ timer : & Timer ,
686+ counter : Arc < AtomicU64 > ,
687+ ) {
688+ counter. fetch_add ( 1 , Ordering :: AcqRel ) ;
689+ timer. set_oneshot ( move |timer : & Timer | {
690+ recursive_oneshot ( timer, counter) ;
691+ } ) ;
692+ }
693+
645694 #[ test]
646695 fn test_logger_name ( ) -> Result < ( ) , RclrsError > {
647696 // Use helper to create 2 nodes for us
0 commit comments