@@ -695,12 +695,34 @@ rt_test! {
695
695
/// Tests that yielded tasks are not scheduled until **after** resource
696
696
/// drivers are polled.
697
697
///
698
- /// Note: we may have to delete this test as it is not necessarily reliable.
699
698
/// The OS does not guarantee when I/O events are delivered, so there may be
700
- /// more yields than anticipated.
699
+ /// more yields than anticipated. This makes the test slightly flaky. To
700
+ /// help avoid flakiness, we run the test 10 times and only fail it after
701
+ /// 10 failures in a row.
702
+ ///
703
+ /// Note that if the test fails by panicking rather than by returning false,
704
+ /// then we fail it immediately. That kind of failure should not happen
705
+ /// spuriously.
701
706
#[ test]
702
707
#[ cfg( not( target_os="wasi" ) ) ]
703
708
fn yield_defers_until_park( ) {
709
+ for _ in 0 ..10 {
710
+ if yield_defers_until_park_inner( ) {
711
+ // test passed
712
+ return ;
713
+ }
714
+
715
+ // Wait a bit and run the test again.
716
+ std:: thread:: sleep( std:: time:: Duration :: from_secs( 2 ) ) ;
717
+ }
718
+
719
+ panic!( "yield_defers_until_park is failing consistently" ) ;
720
+ }
721
+
722
+ /// Implementation of `yield_defers_until_park` test. Returns `true` if the
723
+ /// test passed.
724
+ #[ cfg( not( target_os="wasi" ) ) ]
725
+ fn yield_defers_until_park_inner( ) -> bool {
704
726
use std:: sync:: atomic:: { AtomicBool , Ordering :: SeqCst } ;
705
727
use std:: sync:: Barrier ;
706
728
@@ -727,14 +749,16 @@ rt_test! {
727
749
728
750
barrier. wait( ) ;
729
751
730
- tokio:: spawn( async move {
752
+ let ( fail_test, fail_test_recv) = oneshot:: channel:: <( ) >( ) ;
753
+
754
+ let jh = tokio:: spawn( async move {
731
755
// Create a TCP litener
732
756
let listener = TcpListener :: bind( "127.0.0.1:0" ) . await . unwrap( ) ;
733
757
let addr = listener. local_addr( ) . unwrap( ) ;
734
758
735
759
tokio:: join!(
736
760
async {
737
- // Done blocking intentionally
761
+ // Done in a blocking manner intentionally.
738
762
let _socket = std:: net:: TcpStream :: connect( addr) . unwrap( ) ;
739
763
740
764
// Yield until connected
@@ -744,7 +768,12 @@ rt_test! {
744
768
cnt += 1 ;
745
769
746
770
if cnt >= 10 {
747
- panic!( "yielded too many times; TODO: delete this test?" ) ;
771
+ // yielded too many times; report failure and
772
+ // sleep forever so that the `fail_test` branch
773
+ // of the `select!` below triggers.
774
+ let _ = fail_test. send( ( ) ) ;
775
+ futures:: future:: pending:: <( ) >( ) . await ;
776
+ break ;
748
777
}
749
778
}
750
779
} ,
@@ -753,8 +782,20 @@ rt_test! {
753
782
flag. store( true , SeqCst ) ;
754
783
}
755
784
) ;
756
- } ) . await . unwrap( ) ;
757
- } ) ;
785
+ } ) ;
786
+
787
+ // Wait until the spawned task completes or fails. If no message is
788
+ // sent on `fail_test`, then the test succeeds. Otherwise, it fails.
789
+ let success = fail_test_recv. await . is_err( ) ;
790
+
791
+ if success {
792
+ // Check for panics in spawned task.
793
+ jh. abort( ) ;
794
+ jh. await . unwrap( ) ;
795
+ }
796
+
797
+ success
798
+ } )
758
799
}
759
800
760
801
#[ cfg( not( target_os="wasi" ) ) ] // Wasi does not support threads
0 commit comments