From 0c3be531076617be52b641b6dbb60649f587b5f5 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Tue, 16 Mar 2021 14:27:52 +0300 Subject: [PATCH] integration-cli: Fix race in TestServiceLogsFollow test case Imagine that in test TestServiceLogsFollow the service TestServiceLogsFollow would print "log test" message to pipe exactly 3 times before cmd.Process.Kill() would kill the service in the end of test. This means that goroutine would hang "forever" in reader.Readline() because it can't read anything from pipe but pipe write end is still left open by the goroutine. This is standard behaviour of pipes, one should close the write end before reading from the read end, else reading would block forever. This problem does not fire frequently because the service normally prints "log test" message at least 4 times, but we saw this hang on our test runs in Virtuozzo. We can't close the write pipe end before reading in a goroutine because the goroutine is basicly a thread and closing a file descrptor would close it for all other threads and "log test" would not be printed at all. So I see another way to handle this race, we can just defer pipe close to the end of the main thread of the test case after killing the service. This way goroutine's reading would be interrupted and it would finish eventually. Signed-off-by: Pavel Tikhomirov --- integration-cli/docker_cli_service_logs_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/integration-cli/docker_cli_service_logs_test.go b/integration-cli/docker_cli_service_logs_test.go index 2680abf6c6..dd7baefc34 100644 --- a/integration-cli/docker_cli_service_logs_test.go +++ b/integration-cli/docker_cli_service_logs_test.go @@ -169,6 +169,8 @@ func (s *DockerSwarmSuite) TestServiceLogsFollow(c *testing.T) { args := []string{"service", "logs", "-f", name} cmd := exec.Command(dockerBinary, d.PrependHostArg(args)...) r, w := io.Pipe() + defer r.Close() + defer w.Close() cmd.Stdout = w cmd.Stderr = w assert.NilError(c, cmd.Start())