@@ -7,8 +7,50 @@ use std::*;
77
88use  fail:: fail_point; 
99
10+ #[ test]  
11+ #[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
12+ fn  test_pause ( )  { 
13+     let  local_registry = fail:: new_fail_group ( ) ; 
14+     local_registry. register_current ( ) ; 
15+     let  f = || { 
16+         fail_point ! ( "pause" ) ; 
17+     } ; 
18+     f ( ) ; 
19+ 
20+     fail:: cfg ( "pause" ,  "pause" ) . unwrap ( ) ; 
21+     let  ( tx,  rx)  = mpsc:: channel ( ) ; 
22+     // control `f()` is executed before next failpoint config 
23+     let  ( tx_before,  rx_before)  = mpsc:: channel ( ) ; 
24+     let  thread_registry = local_registry. clone ( ) ; 
25+     thread:: spawn ( move  || { 
26+         thread_registry. register_current ( ) ; 
27+         // pause 
28+         tx_before. send ( ( ) ) . unwrap ( ) ; 
29+         tx. send ( f ( ) ) . unwrap ( ) ; 
30+         // woken up by new order pause, and then pause again. 
31+         tx_before. send ( ( ) ) . unwrap ( ) ; 
32+         tx. send ( f ( ) ) . unwrap ( ) ; 
33+         // woken up by remove, and then quit immediately. 
34+         tx. send ( f ( ) ) . unwrap ( ) ; 
35+     } ) ; 
36+ 
37+     rx_before. recv ( ) . unwrap ( ) ; 
38+     assert ! ( rx. recv_timeout( Duration :: from_millis( 2000 ) ) . is_err( ) ) ; 
39+     fail:: cfg ( "pause" ,  "pause" ) . unwrap ( ) ; 
40+     rx. recv_timeout ( Duration :: from_millis ( 500 ) ) . unwrap ( ) ; 
41+ 
42+     assert ! ( rx. recv_timeout( Duration :: from_millis( 2000 ) ) . is_err( ) ) ; 
43+     fail:: remove ( "pause" ) ; 
44+     rx_before. recv ( ) . unwrap ( ) ; 
45+     rx. recv_timeout ( Duration :: from_millis ( 500 ) ) . unwrap ( ) ; 
46+     rx. recv_timeout ( Duration :: from_millis ( 500 ) ) . unwrap ( ) ; 
47+ } 
48+ 
1049#[ test]  
1150fn  test_off ( )  { 
51+     let  local_registry = fail:: new_fail_group ( ) ; 
52+     local_registry. register_current ( ) ; 
53+ 
1254    let  f = || { 
1355        fail_point ! ( "off" ,  |_| 2 ) ; 
1456        0 
@@ -22,6 +64,9 @@ fn test_off() {
2264#[ test]  
2365#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
2466fn  test_return ( )  { 
67+     let  local_registry = fail:: new_fail_group ( ) ; 
68+     local_registry. register_current ( ) ; 
69+ 
2570    let  f = || { 
2671        fail_point ! ( "return" ,  |s:  Option <String >| s
2772            . map_or( 2 ,  |s| s. parse( ) . unwrap( ) ) ) ; 
@@ -39,6 +84,9 @@ fn test_return() {
3984#[ test]  
4085#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
4186fn  test_sleep ( )  { 
87+     let  local_registry = fail:: new_fail_group ( ) ; 
88+     local_registry. register_current ( ) ; 
89+ 
4290    let  f = || { 
4391        fail_point ! ( "sleep" ) ; 
4492    } ; 
@@ -56,6 +104,9 @@ fn test_sleep() {
56104#[ should_panic]  
57105#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
58106fn  test_panic ( )  { 
107+     let  local_registry = fail:: new_fail_group ( ) ; 
108+     local_registry. register_current ( ) ; 
109+ 
59110    let  f = || { 
60111        fail_point ! ( "panic" ) ; 
61112    } ; 
@@ -66,6 +117,9 @@ fn test_panic() {
66117#[ test]  
67118#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
68119fn  test_print ( )  { 
120+     let  local_registry = fail:: new_fail_group ( ) ; 
121+     local_registry. register_current ( ) ; 
122+ 
69123    struct  LogCollector ( Arc < Mutex < Vec < String > > > ) ; 
70124    impl  log:: Log  for  LogCollector  { 
71125        fn  enabled ( & self ,  _:  & log:: Metadata )  -> bool  { 
@@ -97,38 +151,11 @@ fn test_print() {
97151    assert_eq ! ( msg,  "failpoint print executed." ) ; 
98152} 
99153
100- #[ test]  
101- #[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
102- fn  test_pause ( )  { 
103-     let  f = || { 
104-         fail_point ! ( "pause" ) ; 
105-     } ; 
106-     f ( ) ; 
107- 
108-     fail:: cfg ( "pause" ,  "pause" ) . unwrap ( ) ; 
109-     let  ( tx,  rx)  = mpsc:: channel ( ) ; 
110-     thread:: spawn ( move  || { 
111-         // pause 
112-         tx. send ( f ( ) ) . unwrap ( ) ; 
113-         // woken up by new order pause, and then pause again. 
114-         tx. send ( f ( ) ) . unwrap ( ) ; 
115-         // woken up by remove, and then quit immediately. 
116-         tx. send ( f ( ) ) . unwrap ( ) ; 
117-     } ) ; 
118- 
119-     assert ! ( rx. recv_timeout( Duration :: from_millis( 500 ) ) . is_err( ) ) ; 
120-     fail:: cfg ( "pause" ,  "pause" ) . unwrap ( ) ; 
121-     rx. recv_timeout ( Duration :: from_millis ( 500 ) ) . unwrap ( ) ; 
122- 
123-     assert ! ( rx. recv_timeout( Duration :: from_millis( 500 ) ) . is_err( ) ) ; 
124-     fail:: remove ( "pause" ) ; 
125-     rx. recv_timeout ( Duration :: from_millis ( 500 ) ) . unwrap ( ) ; 
126- 
127-     rx. recv_timeout ( Duration :: from_millis ( 500 ) ) . unwrap ( ) ; 
128- } 
129- 
130154#[ test]  
131155fn  test_yield ( )  { 
156+     let  local_registry = fail:: new_fail_group ( ) ; 
157+     local_registry. register_current ( ) ; 
158+ 
132159    let  f = || { 
133160        fail_point ! ( "yield" ) ; 
134161    } ; 
@@ -139,6 +166,9 @@ fn test_yield() {
139166#[ test]  
140167#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
141168fn  test_callback ( )  { 
169+     let  local_registry = fail:: new_fail_group ( ) ; 
170+     local_registry. register_current ( ) ; 
171+ 
142172    let  f1 = || { 
143173        fail_point ! ( "cb" ) ; 
144174    } ; 
@@ -160,6 +190,9 @@ fn test_callback() {
160190#[ test]  
161191#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
162192fn  test_delay ( )  { 
193+     let  local_registry = fail:: new_fail_group ( ) ; 
194+     local_registry. register_current ( ) ; 
195+ 
163196    let  f = || fail_point ! ( "delay" ) ; 
164197    let  timer = Instant :: now ( ) ; 
165198    fail:: cfg ( "delay" ,  "delay(1000)" ) . unwrap ( ) ; 
@@ -170,6 +203,9 @@ fn test_delay() {
170203#[ test]  
171204#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
172205fn  test_freq_and_count ( )  { 
206+     let  local_registry = fail:: new_fail_group ( ) ; 
207+     local_registry. register_current ( ) ; 
208+ 
173209    let  f = || { 
174210        fail_point ! ( "freq_and_count" ,  |s:  Option <String >| s
175211            . map_or( 2 ,  |s| s. parse( ) . unwrap( ) ) ) ; 
@@ -191,6 +227,9 @@ fn test_freq_and_count() {
191227#[ test]  
192228#[ cfg_attr( not( feature = "failpoints" ) ,  ignore) ]  
193229fn  test_condition ( )  { 
230+     let  local_registry = fail:: new_fail_group ( ) ; 
231+     local_registry. register_current ( ) ; 
232+ 
194233    let  f = |_enabled| { 
195234        fail_point ! ( "condition" ,  _enabled,  |_| 2 ) ; 
196235        0 
@@ -205,9 +244,61 @@ fn test_condition() {
205244
206245#[ test]  
207246fn  test_list ( )  { 
247+     let  local_registry = fail:: new_fail_group ( ) ; 
248+     local_registry. register_current ( ) ; 
249+ 
208250    assert ! ( !fail:: list( ) . contains( & ( "list" . to_string( ) ,  "off" . to_string( ) ) ) ) ; 
209251    fail:: cfg ( "list" ,  "off" ) . unwrap ( ) ; 
210252    assert ! ( fail:: list( ) . contains( & ( "list" . to_string( ) ,  "off" . to_string( ) ) ) ) ; 
211253    fail:: cfg ( "list" ,  "return" ) . unwrap ( ) ; 
212254    assert ! ( fail:: list( ) . contains( & ( "list" . to_string( ) ,  "return" . to_string( ) ) ) ) ; 
213255} 
256+ 
257+ #[ test]  
258+ fn  test_multiple_threads_cleanup ( )  { 
259+     let  local_registry = fail:: new_fail_group ( ) ; 
260+     local_registry. register_current ( ) ; 
261+ 
262+     let  ( tx,  rx)  = mpsc:: channel ( ) ; 
263+     thread:: spawn ( move  || { 
264+         local_registry. register_current ( ) ; 
265+         fail:: cfg ( "thread_point" ,  "sleep(10)" ) . unwrap ( ) ; 
266+         tx. send ( ( ) ) . unwrap ( ) ; 
267+     } ) ; 
268+     rx. recv ( ) . unwrap ( ) ; 
269+     let  l = fail:: list ( ) ; 
270+     assert ! ( 
271+         l. iter( ) 
272+             . find( |& x| x == & ( "thread_point" . to_owned( ) ,  "sleep(10)" . to_owned( ) ) ) 
273+             . is_some( ) 
274+             && l. len( )  == 1 
275+     ) ; 
276+ 
277+     let  ( tx,  rx)  = mpsc:: channel ( ) ; 
278+     let  t = thread:: spawn ( move  || { 
279+         let  local_registry = fail:: new_fail_group ( ) ; 
280+         local_registry. register_current ( ) ; 
281+         fail:: cfg ( "thread_point" ,  "panic" ) . unwrap ( ) ; 
282+         let  l = fail:: list ( ) ; 
283+         assert ! ( 
284+             l. iter( ) 
285+                 . find( |& x| x == & ( "thread_point" . to_owned( ) ,  "panic" . to_owned( ) ) ) 
286+                 . is_some( ) 
287+                 && l. len( )  == 1 
288+         ) ; 
289+         rx. recv ( ) . unwrap ( ) ; 
290+         local_registry. cleanup ( ) ; 
291+         let  l = fail:: list ( ) ; 
292+         assert ! ( l. is_empty( ) ) ; 
293+     } ) ; 
294+ 
295+     tx. send ( ( ) ) . unwrap ( ) ; 
296+     let  l = fail:: list ( ) ; 
297+     assert ! ( 
298+         l. iter( ) 
299+             . find( |& x| x == & ( "thread_point" . to_owned( ) ,  "sleep(10)" . to_owned( ) ) ) 
300+             . is_some( ) 
301+             && l. len( )  == 1 
302+     ) ; 
303+     t. join ( ) . unwrap ( ) ; 
304+ } 
0 commit comments