@@ -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( 800 ) ) . is_err( ) ) ;
39+ fail:: cfg ( "pause" , "pause" ) . unwrap ( ) ;
40+ rx. recv_timeout ( Duration :: from_millis ( 800 ) ) . unwrap ( ) ;
41+
42+ assert ! ( rx. recv_timeout( Duration :: from_millis( 800 ) ) . is_err( ) ) ;
43+ fail:: remove ( "pause" ) ;
44+ rx_before. recv ( ) . unwrap ( ) ;
45+ rx. recv_timeout ( Duration :: from_millis ( 800 ) ) . unwrap ( ) ;
46+ rx. recv_timeout ( Duration :: from_millis ( 800 ) ) . 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