Skip to content

Commit 3b34149

Browse files
authored
Wait until container is actually running, not just created. (cortexproject/cortex#3399)
Signed-off-by: Peter Štibraný <[email protected]>
1 parent e54fe94 commit 3b34149

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

service.go

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ func (s *ConcreteService) Start(networkName, sharedDir string) (err error) {
111111
s.usedNetworkName = networkName
112112

113113
// Wait until the container has been started.
114-
if err = s.WaitStarted(); err != nil {
114+
if err = s.WaitForRunning(); err != nil {
115115
return err
116116
}
117117

@@ -123,10 +123,10 @@ func (s *ConcreteService) Start(networkName, sharedDir string) (err error) {
123123
out, err = RunCommandAndGetOutput("docker", "port", s.containerName(), strconv.Itoa(containerPort))
124124
if err != nil {
125125
// Catch init errors.
126-
if werr := s.WaitStarted(); werr != nil {
126+
if werr := s.WaitForRunning(); werr != nil {
127127
return errors.Wrapf(werr, "failed to get mapping for port as container %s exited: %v", s.containerName(), err)
128128
}
129-
return errors.Wrapf(err, "unable to get mapping for port %d; service: %s", containerPort, s.name)
129+
return errors.Wrapf(err, "unable to get mapping for port %d; service: %s; output: %q", containerPort, s.name, out)
130130
}
131131

132132
stdout := strings.TrimSpace(string(out))
@@ -243,22 +243,36 @@ func (s *ConcreteService) containerName() string {
243243
return containerName(s.usedNetworkName, s.name)
244244
}
245245

246-
func (s *ConcreteService) WaitStarted() (err error) {
246+
func (s *ConcreteService) WaitForRunning() (err error) {
247247
if !s.isExpectedRunning() {
248248
return fmt.Errorf("service %s is stopped", s.Name())
249249
}
250250

251251
for s.retryBackoff.Reset(); s.retryBackoff.Ongoing(); {
252252
// Enforce a timeout on the command execution because we've seen some flaky tests
253253
// stuck here.
254-
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
255-
defer cancel()
256254

257-
err = exec.CommandContext(ctx, "docker", "inspect", s.containerName()).Run()
258-
if err == nil {
259-
return nil
255+
var out []byte
256+
out, err = RunCommandWithTimeoutAndGetOutput(5*time.Second, "docker", "inspect", "--format={{json .State.Running}}", s.containerName())
257+
if err != nil {
258+
s.retryBackoff.Wait()
259+
continue
260260
}
261-
s.retryBackoff.Wait()
261+
262+
if out == nil {
263+
err = fmt.Errorf("nil output")
264+
s.retryBackoff.Wait()
265+
continue
266+
}
267+
268+
str := strings.TrimSpace(string(out))
269+
if str != "true" {
270+
err = fmt.Errorf("unexpected output: %q", str)
271+
s.retryBackoff.Wait()
272+
continue
273+
}
274+
275+
return nil
262276
}
263277

264278
return fmt.Errorf("docker container %s failed to start: %v", s.name, err)

util.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package e2e
22

33
import (
4+
"context"
45
"io/ioutil"
56
"math"
67
"math/rand"
@@ -21,6 +22,14 @@ func RunCommandAndGetOutput(name string, args ...string) ([]byte, error) {
2122
return cmd.CombinedOutput()
2223
}
2324

25+
func RunCommandWithTimeoutAndGetOutput(timeout time.Duration, name string, args ...string) ([]byte, error) {
26+
ctx, cancel := context.WithTimeout(context.Background(), timeout)
27+
defer cancel()
28+
29+
cmd := exec.CommandContext(ctx, name, args...)
30+
return cmd.CombinedOutput()
31+
}
32+
2433
func EmptyFlags() map[string]string {
2534
return map[string]string{}
2635
}

0 commit comments

Comments
 (0)