Browse code

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>

Pavel Tikhomirov authored on 2021/03/16 20:27:52
Showing 1 changed files
... ...
@@ -169,6 +169,8 @@ func (s *DockerSwarmSuite) TestServiceLogsFollow(c *testing.T) {
169 169
 	args := []string{"service", "logs", "-f", name}
170 170
 	cmd := exec.Command(dockerBinary, d.PrependHostArg(args)...)
171 171
 	r, w := io.Pipe()
172
+	defer r.Close()
173
+	defer w.Close()
172 174
 	cmd.Stdout = w
173 175
 	cmd.Stderr = w
174 176
 	assert.NilError(c, cmd.Start())