Skip to content

Commit 4867f17

Browse files
Fix flaky tests
1 parent 12886c0 commit 4867f17

File tree

1 file changed

+105
-38
lines changed

1 file changed

+105
-38
lines changed

text/tests/head/mod.rs

Lines changed: 105 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -11,49 +11,49 @@
1111
use plib::{run_test, TestPlan};
1212
use rand::{seq::SliceRandom, thread_rng};
1313

14-
fn generate_valid_arguments(n: Option<&str>, c: Option<&str>) -> Vec<Vec<String>> {
15-
let mut argument_forms = Vec::<Vec<(String, String)>>::new();
14+
/* #region Normal tests */
15+
fn head_test(n: Option<&str>, c: Option<&str>, test_data: &str, expected_output: &str) {
16+
fn generate_valid_arguments(n: Option<&str>, c: Option<&str>) -> Vec<Vec<String>> {
17+
let mut argument_forms = Vec::<Vec<(String, String)>>::new();
1618

17-
let mut args_outer = Vec::<(String, String)>::new();
19+
let mut args_outer = Vec::<(String, String)>::new();
1820

19-
for n_form in ["-n", "--lines"] {
20-
args_outer.clear();
21+
for n_form in ["-n", "--lines"] {
22+
args_outer.clear();
2123

22-
if let Some(n_str) = n {
23-
args_outer.push((n_form.to_owned(), n_str.to_owned()));
24-
};
24+
if let Some(n_str) = n {
25+
args_outer.push((n_form.to_owned(), n_str.to_owned()));
26+
};
2527

26-
for c_form in ["-c", "--bytes"] {
27-
let mut args_inner = args_outer.clone();
28+
for c_form in ["-c", "--bytes"] {
29+
let mut args_inner = args_outer.clone();
2830

29-
if let Some(c_str) = c {
30-
args_inner.push((c_form.to_owned(), c_str.to_owned()));
31-
};
31+
if let Some(c_str) = c {
32+
args_inner.push((c_form.to_owned(), c_str.to_owned()));
33+
};
3234

33-
argument_forms.push(args_inner);
35+
argument_forms.push(args_inner);
36+
}
3437
}
35-
}
3638

37-
argument_forms.shuffle(&mut thread_rng());
39+
argument_forms.shuffle(&mut thread_rng());
40+
41+
let mut flattened = Vec::<Vec<String>>::with_capacity(argument_forms.len());
3842

39-
let mut flattened = Vec::<Vec<String>>::with_capacity(argument_forms.len());
43+
for ve in argument_forms {
44+
let mut vec = Vec::<String>::new();
4045

41-
for ve in argument_forms {
42-
let mut vec = Vec::<String>::new();
46+
for (st, str) in ve {
47+
vec.push(st);
48+
vec.push(str);
49+
}
4350

44-
for (st, str) in ve {
45-
vec.push(st);
46-
vec.push(str);
51+
flattened.push(vec);
4752
}
4853

49-
flattened.push(vec);
54+
flattened
5055
}
5156

52-
flattened
53-
}
54-
55-
/* #region Normal tests */
56-
fn head_test(n: Option<&str>, c: Option<&str>, test_data: &str, expected_output: &str) {
5757
for ve in generate_valid_arguments(n, c) {
5858
run_test(TestPlan {
5959
cmd: "head".to_owned(),
@@ -123,6 +123,11 @@ fn test_head_c() {
123123
mod property_tests {
124124
use plib::run_test_base;
125125
use proptest::{prelude::TestCaseError, prop_assert, test_runner::TestRunner};
126+
use std::{
127+
sync::mpsc::{self, RecvTimeoutError},
128+
thread::{self},
129+
time::Duration,
130+
};
126131

127132
fn get_test_runner(cases: u32) -> TestRunner {
128133
TestRunner::new(proptest::test_runner::Config {
@@ -134,7 +139,7 @@ mod property_tests {
134139
}
135140

136141
fn run_head_and_verify_output(
137-
input: Vec<u8>,
142+
input: &[u8],
138143
true_if_lines_false_if_bytes: bool,
139144
count: usize,
140145
) -> Result<(), TestCaseError> {
@@ -144,11 +149,7 @@ mod property_tests {
144149
"-c"
145150
};
146151

147-
let output = run_test_base(
148-
"head",
149-
&vec![n_or_c.to_owned(), count.to_string()],
150-
input.as_slice(),
151-
);
152+
let output = run_test_base("head", &vec![n_or_c.to_owned(), count.to_string()], input);
152153

153154
let stdout = &output.stdout;
154155

@@ -167,8 +168,46 @@ mod property_tests {
167168
Ok(())
168169
}
169170

171+
fn run_head_and_verify_output_with_timeout(
172+
true_if_lines_false_if_bytes: bool,
173+
count: usize,
174+
input: Vec<u8>,
175+
) -> Result<(), TestCaseError> {
176+
let (sender, receiver) = mpsc::channel::<Result<(), TestCaseError>>();
177+
178+
let input_len = input.len();
179+
180+
thread::spawn(move || {
181+
sender.send(run_head_and_verify_output(
182+
input.as_slice(),
183+
true_if_lines_false_if_bytes,
184+
count,
185+
))
186+
});
187+
188+
match receiver.recv_timeout(Duration::from_secs(60_u64)) {
189+
Ok(result) => result,
190+
Err(RecvTimeoutError::Timeout) => {
191+
eprint!(
192+
"\
193+
head property test has been running for more than a minute. The spawned process will have to be killed manually.
194+
195+
true_if_lines_false_if_bytes: {true_if_lines_false_if_bytes}
196+
count: {count}
197+
input_len: {input_len}
198+
"
199+
);
200+
201+
Err(TestCaseError::fail("Spawned process did not terminate"))
202+
}
203+
Err(RecvTimeoutError::Disconnected) => {
204+
unreachable!();
205+
}
206+
}
207+
}
208+
170209
#[test]
171-
fn property_test_random() {
210+
fn test_head_property_test_small_or_large() {
172211
get_test_runner(16_u32)
173212
.run(
174213
&(
@@ -177,14 +216,18 @@ mod property_tests {
177216
proptest::collection::vec(proptest::num::u8::ANY, 0_usize..65_536_usize),
178217
),
179218
|(true_if_lines_false_if_bytes, count, input)| {
180-
run_head_and_verify_output(input, true_if_lines_false_if_bytes, count)
219+
run_head_and_verify_output_with_timeout(
220+
true_if_lines_false_if_bytes,
221+
count,
222+
input,
223+
)
181224
},
182225
)
183226
.unwrap();
184227
}
185228

186229
#[test]
187-
fn property_test_small() {
230+
fn test_head_property_test_small() {
188231
get_test_runner(128_u32)
189232
.run(
190233
&(
@@ -193,7 +236,31 @@ mod property_tests {
193236
proptest::collection::vec(proptest::num::u8::ANY, 0_usize..16_384_usize),
194237
),
195238
|(true_if_lines_false_if_bytes, count, input)| {
196-
run_head_and_verify_output(input, true_if_lines_false_if_bytes, count)
239+
run_head_and_verify_output_with_timeout(
240+
true_if_lines_false_if_bytes,
241+
count,
242+
input,
243+
)
244+
},
245+
)
246+
.unwrap();
247+
}
248+
249+
#[test]
250+
fn test_head_property_test_very_small() {
251+
get_test_runner(128_u32)
252+
.run(
253+
&(
254+
proptest::bool::ANY,
255+
(0_usize..512_usize),
256+
proptest::collection::vec(proptest::num::u8::ANY, 0_usize..512_usize),
257+
),
258+
|(true_if_lines_false_if_bytes, count, input)| {
259+
run_head_and_verify_output_with_timeout(
260+
true_if_lines_false_if_bytes,
261+
count,
262+
input,
263+
)
197264
},
198265
)
199266
.unwrap();

0 commit comments

Comments
 (0)