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 <ptikhomirov@virtuozzo.com>
This commit is contained in:
Pavel Tikhomirov 2021-03-16 14:27:52 +03:00
parent 4735a0c84f
commit 0c3be53107

View file

@ -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())