From a6c839adf67883627170f04d8feecd803a7c5d97 Mon Sep 17 00:00:00 2001 From: lifubang Date: Mon, 14 Oct 2024 17:31:25 +0800 Subject: [PATCH] ci: fix a race in TestExecIn and TestExecInTTY Signed-off-by: lifubang --- libcontainer/integration/execin_test.go | 57 ++++++++++++++++++------- libcontainer/integration/utils_test.go | 22 ++++++++++ 2 files changed, 64 insertions(+), 15 deletions(-) diff --git a/libcontainer/integration/execin_test.go b/libcontainer/integration/execin_test.go index b9683b76442..3f2eb4a2596 100644 --- a/libcontainer/integration/execin_test.go +++ b/libcontainer/integration/execin_test.go @@ -30,16 +30,33 @@ func TestExecIn(t *testing.T) { // Execute a first process in the container stdinR, stdinW, err := os.Pipe() ok(t, err) + stdoutR, stdoutW, err := os.Pipe() + ok(t, err) + defer stdinR.Close() //nolint: errcheck + defer stdinW.Close() //nolint: errcheck + defer stdoutR.Close() //nolint: errcheck + defer stdoutW.Close() //nolint: errcheck + + ch := waitStdOut(stdoutR) process := &libcontainer.Process{ - Cwd: "/", - Args: []string{"cat"}, - Env: standardEnvironment, - Stdin: stdinR, - Init: true, + Cwd: "/", + Args: []string{"cat", "/proc/self/cmdline", "-"}, + Env: standardEnvironment, + Stdin: stdinR, + Stdout: stdoutW, + Init: true, } err = container.Run(process) - _ = stdinR.Close() - defer stdinW.Close() //nolint: errcheck + defer func() { + stdinW.Write([]byte("hello")) + _ = stdinW.Close() + if _, err := process.Wait(); err != nil { + t.Log(err) + } + }() + ok(t, err) + + err = <-ch ok(t, err) buffers := newStdBuffers() @@ -55,8 +72,6 @@ func TestExecIn(t *testing.T) { err = container.Run(ps) ok(t, err) waitProcess(ps, t) - _ = stdinW.Close() - waitProcess(process, t) out := buffers.Stdout.String() if !strings.Contains(out, "cat") || !strings.Contains(out, "ps") { @@ -242,16 +257,25 @@ func TestExecInTTY(t *testing.T) { // Execute a first process in the container stdinR, stdinW, err := os.Pipe() ok(t, err) + stdoutR, stdoutW, err := os.Pipe() + ok(t, err) + defer stdinR.Close() //nolint: errcheck + defer stdinW.Close() //nolint: errcheck + defer stdoutR.Close() //nolint: errcheck + defer stdoutW.Close() //nolint: errcheck + + ch := waitStdOut(stdoutR) process := &libcontainer.Process{ - Cwd: "/", - Args: []string{"cat"}, - Env: standardEnvironment, - Stdin: stdinR, - Init: true, + Cwd: "/", + Args: []string{"cat", "/proc/self/cmdline", "-"}, + Env: standardEnvironment, + Stdin: stdinR, + Stdout: stdoutW, + Init: true, } err = container.Run(process) - _ = stdinR.Close() defer func() { + stdinW.Write([]byte("hello")) _ = stdinW.Close() if _, err := process.Wait(); err != nil { t.Log(err) @@ -259,6 +283,9 @@ func TestExecInTTY(t *testing.T) { }() ok(t, err) + err = <-ch + ok(t, err) + ps := &libcontainer.Process{ Cwd: "/", Args: []string{"ps"}, diff --git a/libcontainer/integration/utils_test.go b/libcontainer/integration/utils_test.go index 780288ad02b..4bbec30c9cf 100644 --- a/libcontainer/integration/utils_test.go +++ b/libcontainer/integration/utils_test.go @@ -231,3 +231,25 @@ func runContainerOk(t *testing.T, config *configs.Config, args ...string) *stdBu func destroyContainer(container *libcontainer.Container) { _ = container.Destroy() } + +func waitStdOut(stdout *os.File) chan error { + ch := make(chan error, 1) + buf := make([]byte, 1) + go func() { + defer close(ch) + + for { + n, err := stdout.Read(buf) + if err != nil { + ch <- err + return + } + + if n >= 0 { + ch <- nil + return + } + } + }() + return ch +}