Skip to content

Commit 273ecea

Browse files
committed
Merge #642
642: Handle short reads in pty tests r=Susurrus Some pty tests would fail intermittently because read(2) occasionally returns less data than requested.
2 parents a8baf55 + 9511e5f commit 273ecea

File tree

1 file changed

+28
-20
lines changed

1 file changed

+28
-20
lines changed

test/test_pty.rs

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,16 @@ use nix::sys::stat;
77
use nix::sys::termios::*;
88
use nix::unistd::{read, write, close};
99

10+
/// Helper function analogous to std::io::Read::read_exact, but for `RawFD`s
11+
fn read_exact(f: RawFd, buf: &mut [u8]) {
12+
let mut len = 0;
13+
while len < buf.len() {
14+
// get_mut would be better than split_at_mut, but it requires nightly
15+
let (_, remaining) = buf.split_at_mut(len);
16+
len += read(f, remaining).unwrap();
17+
}
18+
}
19+
1020
/// Test equivalence of `ptsname` and `ptsname_r`
1121
#[test]
1222
#[cfg(any(target_os = "android", target_os = "linux"))]
@@ -22,6 +32,7 @@ fn test_ptsname_equivalence() {
2232
}
2333

2434
/// Test data copying of `ptsname`
35+
// TODO need to run in a subprocess, since ptsname is non-reentrant
2536
#[test]
2637
#[cfg(any(target_os = "android", target_os = "linux"))]
2738
fn test_ptsname_copy() {
@@ -102,26 +113,25 @@ fn test_openpty() {
102113

103114
// Writing to one should be readable on the other one
104115
let string = "foofoofoo\n";
105-
let mut buf = [0u8; 16];
116+
let mut buf = [0u8; 10];
106117
write(pty.master, string.as_bytes()).unwrap();
107-
let len = read(pty.slave, &mut buf).unwrap();
118+
read_exact(pty.slave, &mut buf);
108119

109-
assert_eq!(len, string.len());
110-
assert_eq!(&buf[0..len], string.as_bytes());
120+
assert_eq!(&buf, string.as_bytes());
111121

112122
// Read the echo as well
113123
let echoed_string = "foofoofoo\r\n";
114-
let len = read(pty.master, &mut buf).unwrap();
115-
assert_eq!(len, echoed_string.len());
116-
assert_eq!(&buf[0..len], echoed_string.as_bytes());
124+
let mut buf = [0u8; 11];
125+
read_exact(pty.master, &mut buf);
126+
assert_eq!(&buf, echoed_string.as_bytes());
117127

118128
let string2 = "barbarbarbar\n";
119129
let echoed_string2 = "barbarbarbar\r\n";
130+
let mut buf = [0u8; 14];
120131
write(pty.slave, string2.as_bytes()).unwrap();
121-
let len = read(pty.master, &mut buf).unwrap();
132+
read_exact(pty.master, &mut buf);
122133

123-
assert_eq!(len, echoed_string2.len());
124-
assert_eq!(&buf[0..len], echoed_string2.as_bytes());
134+
assert_eq!(&buf, echoed_string2.as_bytes());
125135

126136
close(pty.master).unwrap();
127137
close(pty.slave).unwrap();
@@ -148,26 +158,24 @@ fn test_openpty_with_termios() {
148158

149159
// Writing to one should be readable on the other one
150160
let string = "foofoofoo\n";
151-
let mut buf = [0u8; 16];
161+
let mut buf = [0u8; 10];
152162
write(pty.master, string.as_bytes()).unwrap();
153-
let len = read(pty.slave, &mut buf).unwrap();
163+
read_exact(pty.slave, &mut buf);
154164

155-
assert_eq!(len, string.len());
156-
assert_eq!(&buf[0..len], string.as_bytes());
165+
assert_eq!(&buf, string.as_bytes());
157166

158167
// read the echo as well
159168
let echoed_string = "foofoofoo\n";
160-
let len = read(pty.master, &mut buf).unwrap();
161-
assert_eq!(len, echoed_string.len());
162-
assert_eq!(&buf[0..len], echoed_string.as_bytes());
169+
read_exact(pty.master, &mut buf);
170+
assert_eq!(&buf, echoed_string.as_bytes());
163171

164172
let string2 = "barbarbarbar\n";
165173
let echoed_string2 = "barbarbarbar\n";
174+
let mut buf = [0u8; 13];
166175
write(pty.slave, string2.as_bytes()).unwrap();
167-
let len = read(pty.master, &mut buf).unwrap();
176+
read_exact(pty.master, &mut buf);
168177

169-
assert_eq!(len, echoed_string2.len());
170-
assert_eq!(&buf[0..len], echoed_string2.as_bytes());
178+
assert_eq!(&buf, echoed_string2.as_bytes());
171179

172180
close(pty.master).unwrap();
173181
close(pty.slave).unwrap();

0 commit comments

Comments
 (0)