1#[macro_export]
19macro_rules! maybe_fail {
20 ($tag:literal) => {
21 #[cfg(feature = "chaos")]
22 {
23 if $crate::__failpoint_internal::is_failpoint_enabled($tag) {
24 return Err($tag.into());
25 }
26 }
27 };
28 ($tag:literal, $err:expr) => {
29 #[cfg(feature = "chaos")]
30 {
31 if $crate::__failpoint_internal::is_failpoint_enabled($tag) {
32 return Err($err);
33 }
34 }
35 };
36}
37
38#[macro_export]
47macro_rules! maybe_panic {
48 ($tag:literal) => {
49 #[cfg(feature = "chaos")]
50 {
51 if $crate::__failpoint_internal::is_failpoint_enabled($tag) {
52 panic!($tag);
53 }
54 }
55 };
56}
57
58#[macro_export]
65macro_rules! maybe_sleep {
66 ($tag:literal, $millis:literal) => {
67 #[cfg(feature = "chaos")]
68 {
69 if $crate::__failpoint_internal::is_failpoint_enabled($tag) {
70 std::thread::sleep(std::time::Duration::from_millis($millis));
71 }
72 }
73 };
74}
75
76#[macro_export]
84macro_rules! maybe_sleep_async {
85 ($tag:literal, $millis:literal) => {
86 #[cfg(feature = "chaos")]
87 {
88 if $crate::__failpoint_internal::is_failpoint_enabled($tag) {
89 let duration = std::time::Duration::from_millis($millis);
90 $crate::__failpoint_internal::sleep_async_internal(duration).await;
91 }
92 }
93 };
94}
95
96#[macro_export]
130macro_rules! with_failpoint {
131 ($tag:literal, panic, $code:expr) => {{
132 #[cfg(feature = "chaos")]
133 {
134 $crate::__failpoint_internal::enable_failpoint($tag);
135 let result = std::panic::catch_unwind(|| $code);
136 $crate::__failpoint_internal::disable_failpoint($tag);
137 match result {
138 Ok(_) => panic!(
139 "Expected panic from failpoint '{}', but none occurred",
140 $tag
141 ),
142 Err(_) => {}
143 }
144 }
145 }};
146
147 ($tag:literal, error, $code:expr) => {{
148 #[cfg(feature = "chaos")]
149 {
150 $crate::__failpoint_internal::enable_failpoint($tag);
151 let result = $code;
152 $crate::__failpoint_internal::disable_failpoint($tag);
153
154 match result {
155 Err(_) => {}
156 Ok(_) => panic!(
157 "Expected error from failpoint '{}', but function returned Ok",
158 $tag
159 ),
160 }
161 }
162 }};
163
164 ($tag:literal, $min_ms:literal, $tolerance_ms:literal, $code:expr) => {{
165 #[cfg(feature = "chaos")]
166 {
167 $crate::__failpoint_internal::enable_failpoint($tag);
168 let start = std::time::Instant::now();
169 $code;
170 let elapsed = start.elapsed();
171 $crate::__failpoint_internal::disable_failpoint($tag);
172
173 let max = std::time::Duration::from_millis($min_ms + $tolerance_ms);
174 let min = std::time::Duration::from_millis($min_ms - $tolerance_ms);
175
176 assert!(
177 elapsed <= max && elapsed >= min,
178 "Expected sleep between {:?} and {:?} from failpoint '{}', got {:?}",
179 min,
180 max,
181 $tag,
182 elapsed
183 );
184 }
185 }};
186}
187#[macro_export]
188macro_rules! with_failpoint_async {
189 ($tag:literal, $min_ms:literal, $tolerance_ms:literal, $code:expr) => {{
190 #[cfg(feature = "chaos")]
191 {
192 $crate::__failpoint_internal::enable_failpoint($tag);
193 let start = std::time::Instant::now();
194 $code.await;
195 let elapsed = start.elapsed();
196 $crate::__failpoint_internal::disable_failpoint($tag);
197
198 let max = std::time::Duration::from_millis($min_ms + $tolerance_ms);
199 let min = std::time::Duration::from_millis($min_ms - $tolerance_ms);
200
201 assert!(
202 elapsed <= max && elapsed >= min,
203 "Expected sleep between {:?} and {:?} from failpoint '{}', got {:?}",
204 min,
205 max,
206 $tag,
207 elapsed
208 );
209 }
210 }};
211}