test(e2e): batch snapshot inspect with per-container fallback, explic… · docker/compose@a16c676 · GitHub
Skip to content

Commit a16c676

Browse files
committed
test(e2e): batch snapshot inspect with per-container fallback, explicit suite timeout
The per-container inspect of the previous fix doubled the suite's wall-clock on the containerd CI job — one docker CLI process per container per snapshot — pushing it past go test's default 10m and killing the run mid-flight. Snapshots go back to one batch inspect, falling back to individual inspects only when the batch fails because a helper container vanished. The e2e make targets also pass an explicit -timeout 20m so a slow job fails on its own results, not on the default timeout. TestUpStopWithLogsMixed becomes deterministic: with a bounded ping the service could exit on its own before the abort reached it and the pre_stop hook never ran; it now pings forever so the abort always interrupts it. Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
1 parent 0b378bb commit a16c676

3 files changed

Lines changed: 57 additions & 39 deletions

File tree

‎Makefile‎

Lines changed: 2 additions & 2 deletions

‎pkg/e2e/scenario.go‎

Lines changed: 49 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -324,47 +324,27 @@ func (s *Scenario) command(action Action) icmd.Cmd {
324324
}
325325

326326
// snapshot captures the current state of the project's containers.
327-
// Containers are inspected one by one: helper containers (e.g. the ones
328-
// running lifecycle hooks) carry the project label but can vanish between the
329-
// listing and the inspect, and one gone container must not blank the whole
327+
// The containers are inspected in one batch; if that fails — helper
328+
// containers (e.g. the ones running lifecycle hooks) carry the project label
329+
// but can vanish between the listing and the inspect — each container is
330+
// retried individually so one gone container does not blank the whole
330331
// snapshot. Helpers are also excluded from the snapshot itself: a container
331332
// belongs to a service if it is numbered as a replica or marked one-off.
332333
func (s *Scenario) snapshot() snapshot {
333334
s.t.Helper()
334335
snap := snapshot{}
335-
for _, id := range s.projectContainerIDs() {
336-
res := icmd.RunCmd(s.cli.NewDockerCmd(s.t, "inspect", id))
337-
if res.ExitCode != 0 {
338-
continue
339-
}
340-
var containers []struct {
341-
ID string `json:"Id"`
342-
Name string `json:"Name"`
343-
State struct {
344-
Status string `json:"Status"`
345-
StartedAt string `json:"StartedAt"`
346-
} `json:"State"`
347-
Config struct {
348-
Labels map[string]string `json:"Labels"`
349-
} `json:"Config"`
350-
}
351-
if err := json.Unmarshal([]byte(res.Stdout()), &containers); err != nil {
352-
continue
353-
}
354-
for _, c := range containers {
355-
oneOff := c.Config.Labels["com.docker.compose.oneoff"] == "True"
356-
if !oneOff && c.Config.Labels["com.docker.compose.container-number"] == "" {
357-
continue
336+
ids := s.projectContainerIDs()
337+
if len(ids) == 0 {
338+
return snap
339+
}
340+
res := icmd.RunCmd(s.cli.NewDockerCmd(s.t, append([]string{"inspect"}, ids...)...))
341+
if res.ExitCode == 0 {
342+
s.collect(snap, res.Stdout())
343+
} else {
344+
for _, id := range ids {
345+
if res := icmd.RunCmd(s.cli.NewDockerCmd(s.t, "inspect", id)); res.ExitCode == 0 {
346+
s.collect(snap, res.Stdout())
358347
}
359-
service := c.Config.Labels["com.docker.compose.service"]
360-
snap[service] = append(snap[service], containerState{
361-
ID: c.ID,
362-
Name: strings.TrimPrefix(c.Name, "/"),
363-
State: c.State.Status,
364-
StartedAt: c.State.StartedAt,
365-
OneOff: oneOff,
366-
Labels: c.Config.Labels,
367-
})
368348
}
369349
}
370350
for service := range snap {
@@ -373,6 +353,40 @@ func (s *Scenario) snapshot() snapshot {
373353
return snap
374354
}
375355

356+
// collect parses a docker inspect output into the snapshot, skipping helper
357+
// containers (neither numbered as a replica nor one-off).
358+
func (s *Scenario) collect(snap snapshot, inspectOutput string) {
359+
var containers []struct {
360+
ID string `json:"Id"`
361+
Name string `json:"Name"`
362+
State struct {
363+
Status string `json:"Status"`
364+
StartedAt string `json:"StartedAt"`
365+
} `json:"State"`
366+
Config struct {
367+
Labels map[string]string `json:"Labels"`
368+
} `json:"Config"`
369+
}
370+
if err := json.Unmarshal([]byte(inspectOutput), &containers); err != nil {
371+
return
372+
}
373+
for _, c := range containers {
374+
oneOff := c.Config.Labels["com.docker.compose.oneoff"] == "True"
375+
if !oneOff && c.Config.Labels["com.docker.compose.container-number"] == "" {
376+
continue
377+
}
378+
service := c.Config.Labels["com.docker.compose.service"]
379+
snap[service] = append(snap[service], containerState{
380+
ID: c.ID,
381+
Name: strings.TrimPrefix(c.Name, "/"),
382+
State: c.State.Status,
383+
StartedAt: c.State.StartedAt,
384+
OneOff: oneOff,
385+
Labels: c.Config.Labels,
386+
})
387+
}
388+
}
389+
376390
func (s *Scenario) projectContainerIDs() []string {
377391
res := icmd.RunCmd(s.cli.NewDockerCmd(s.t, "ps", "-a", "--no-trunc",
378392
"--filter", "label=com.docker.compose.project="+s.project, "--format", "{{.ID}}"))

‎pkg/e2e/up_test.go‎

Lines changed: 6 additions & 2 deletions

0 commit comments

Comments
 (0)