v2 / vlib / builtin / builtin_print_write_error_test.v
63 lines · 60 sloc · 1.43 KB · 5be2b1d9cd1f93efc8a776455991080648a51fb9
Raw
1import os
2import time
3
4const broken_stdout_child_source = r'
5import os
6
7fn main() {
8 mut broken := os.pipe() or { panic(err) }
9 saved_stdout := os.fd_dup(1)
10 defer {
11 os.fd_dup2(saved_stdout, 1)
12 os.fd_close(saved_stdout)
13 broken.close()
14 }
15 assert os.fd_dup2(broken.read_fd, 1) != -1
16 os.fd_close(broken.read_fd)
17 broken.read_fd = -1
18 println("broken stdout should not hang")
19}
20'
21
22fn test_println_does_not_hang_on_failed_stdout_write() {
23 $if windows {
24 return
25 }
26 child_source_path := os.join_path(os.vtmp_dir(),
27 'broken_stdout_child_${time.now().unix_milli()}.v')
28 os.write_file(child_source_path, broken_stdout_child_source)!
29 defer {
30 os.rm(child_source_path) or {}
31 }
32 mut p := os.new_process(@VEXE)
33 p.set_args(['run', child_source_path])
34 p.set_redirect_stdio()
35 p.run()
36 defer {
37 if p.is_alive() {
38 p.signal_kill()
39 p.wait()
40 }
41 p.close()
42 }
43 max_wait_iterations := $if s390x || rv64 { 1200 } $else { 300 }
44 for _ in 0 .. max_wait_iterations {
45 if !p.is_alive() {
46 break
47 }
48 time.sleep(50 * time.millisecond)
49 }
50 if p.is_alive() {
51 p.signal_kill()
52 p.wait()
53 stdout := p.stdout_slurp()
54 stderr := p.stderr_slurp()
55 assert false, 'println hung on a failed stdout write\nstdout:\n${stdout}\nstderr:\n${stderr}'
56 }
57 p.wait()
58 stdout := p.stdout_slurp()
59 stderr := p.stderr_slurp()
60 assert p.code == 0, 'child exited with ${p.code}\nstdout:\n${stdout}\nstderr:\n${stderr}'
61 assert stdout == '', stdout
62 assert stderr == '', stderr
63}
64