Skip to content

Commit f08116b

Browse files
committed
ci: fix a race in TestExecIn and TestExecInTTY
Fixes: #4437 We can use a chan to wait the output from init process. After we received the content, it means that the init process has started. Then we can exec into this container to use ps command to check the init process and the exec process are both exist. Signed-off-by: lifubang <[email protected]>
1 parent d82235c commit f08116b

File tree

2 files changed

+72
-15
lines changed

2 files changed

+72
-15
lines changed

libcontainer/integration/execin_test.go

+50-15
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,37 @@ func TestExecIn(t *testing.T) {
3030
// Execute a first process in the container
3131
stdinR, stdinW, err := os.Pipe()
3232
ok(t, err)
33+
defer func() {
34+
_ = stdinR.Close()
35+
_ = stdinW.Close()
36+
}()
37+
stdoutR, stdoutW, err := os.Pipe()
38+
ok(t, err)
39+
defer func() {
40+
_ = stdoutR.Close()
41+
_ = stdoutW.Close()
42+
}()
43+
44+
ch := waitStdOut(stdoutR)
3345
process := &libcontainer.Process{
34-
Cwd: "/",
35-
Args: []string{"cat"},
36-
Env: standardEnvironment,
37-
Stdin: stdinR,
38-
Init: true,
46+
Cwd: "/",
47+
Args: []string{"cat", "/proc/self/cmdline", "-"},
48+
Env: standardEnvironment,
49+
Stdin: stdinR,
50+
Stdout: stdoutW,
51+
Init: true,
3952
}
4053
err = container.Run(process)
41-
_ = stdinR.Close()
42-
defer stdinW.Close() //nolint: errcheck
54+
defer func() {
55+
_, _ = stdinW.Write([]byte("hello"))
56+
_ = stdinW.Close()
57+
if _, err := process.Wait(); err != nil {
58+
t.Log(err)
59+
}
60+
}()
61+
ok(t, err)
62+
63+
err = <-ch
4364
ok(t, err)
4465

4566
buffers := newStdBuffers()
@@ -55,8 +76,6 @@ func TestExecIn(t *testing.T) {
5576
err = container.Run(ps)
5677
ok(t, err)
5778
waitProcess(ps, t)
58-
_ = stdinW.Close()
59-
waitProcess(process, t)
6079

6180
out := buffers.Stdout.String()
6281
if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") {
@@ -242,23 +261,39 @@ func TestExecInTTY(t *testing.T) {
242261
// Execute a first process in the container
243262
stdinR, stdinW, err := os.Pipe()
244263
ok(t, err)
264+
defer func() {
265+
_ = stdinR.Close()
266+
_ = stdinW.Close()
267+
}()
268+
stdoutR, stdoutW, err := os.Pipe()
269+
ok(t, err)
270+
defer func() {
271+
_ = stdoutR.Close()
272+
_ = stdoutW.Close()
273+
}()
274+
275+
ch := waitStdOut(stdoutR)
245276
process := &libcontainer.Process{
246-
Cwd: "/",
247-
Args: []string{"cat"},
248-
Env: standardEnvironment,
249-
Stdin: stdinR,
250-
Init: true,
277+
Cwd: "/",
278+
Args: []string{"cat", "/proc/self/cmdline", "-"},
279+
Env: standardEnvironment,
280+
Stdin: stdinR,
281+
Stdout: stdoutW,
282+
Init: true,
251283
}
252284
err = container.Run(process)
253-
_ = stdinR.Close()
254285
defer func() {
286+
_, _ = stdinW.Write([]byte("hello"))
255287
_ = stdinW.Close()
256288
if _, err := process.Wait(); err != nil {
257289
t.Log(err)
258290
}
259291
}()
260292
ok(t, err)
261293

294+
err = <-ch
295+
ok(t, err)
296+
262297
ps := &libcontainer.Process{
263298
Cwd: "/",
264299
Args: []string{"ps"},

libcontainer/integration/utils_test.go

+22
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,25 @@ func runContainerOk(t *testing.T, config *configs.Config, args ...string) *stdBu
231231
func destroyContainer(container *libcontainer.Container) {
232232
_ = container.Destroy()
233233
}
234+
235+
func waitStdOut(stdout *os.File) chan error {
236+
ch := make(chan error, 1)
237+
buf := make([]byte, 1)
238+
go func() {
239+
defer close(ch)
240+
241+
for {
242+
n, err := stdout.Read(buf)
243+
if err != nil {
244+
ch <- err
245+
return
246+
}
247+
248+
if n >= 0 {
249+
ch <- nil
250+
return
251+
}
252+
}
253+
}()
254+
return ch
255+
}

0 commit comments

Comments
 (0)