From 9f0022af8ccd0ff14d6ee3977f34d9fc06f8dd51 Mon Sep 17 00:00:00 2001 From: "devsy-app[bot]" <277138668+devsy-app[bot]@users.noreply.github.com> Date: Wed, 12 Aug 2026 11:06:02 +0000 Subject: [PATCH 1/2] test(docker): cover failedBootSentinel branches add direct unit tests; no behavioral change --- pkg/docker/boot_state_test.go | 66 +++++++++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) create mode 100644 pkg/docker/boot_state_test.go diff --git a/pkg/docker/boot_state_test.go b/pkg/docker/boot_state_test.go new file mode 100644 index 000000000..93129d95e --- /dev/null +++ b/pkg/docker/boot_state_test.go @@ -0,0 +1,66 @@ +package docker + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestFailedBootSentinel(t *testing.T) { + tests := []struct { + name string + status string + graceElapsed bool + wantSentinel error + wantNil bool + }{ + {"dead is terminal regardless of grace", "dead", false, ErrContainerTerminal, false}, + {"dead is terminal even after grace", "dead", true, ErrContainerTerminal, false}, + { + "removing is terminal regardless of grace", + "removing", + false, + ErrContainerTerminal, + false, + }, + {"removing is terminal even after grace", "removing", true, ErrContainerTerminal, false}, + {"exited before grace is still booting", "exited", false, nil, true}, + {"exited after grace failed", "exited", true, ErrContainerExited, false}, + {"created before grace is still booting", "created", false, nil, true}, + {"created after grace failed", "created", true, ErrContainerExited, false}, + {"paused is not a terminal boot state", "paused", true, nil, true}, + {"restarting is not a terminal boot state", "restarting", false, nil, true}, + {"empty status is not a terminal boot state", "", true, nil, true}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := failedBootSentinel(tt.status, tt.graceElapsed) + if tt.wantNil { + assert.Nil(t, got, "expected nil sentinel for status %q", tt.status) + return + } + assert.ErrorIs( + t, + got, + tt.wantSentinel, + "status %q (grace=%v) should map to %v", + tt.status, + tt.graceElapsed, + tt.wantSentinel, + ) + }) + } +} + +func TestFailedBootSentinel_TerminalNotConfusedWithExited(t *testing.T) { + terminal := failedBootSentinel("removing", false) + exited := failedBootSentinel("exited", true) + + assert.ErrorIs(t, terminal, ErrContainerTerminal) + assert.NotErrorIs(t, terminal, ErrContainerExited, + "terminal states must not be reported as exited") + assert.ErrorIs(t, exited, ErrContainerExited) + assert.NotErrorIs(t, exited, ErrContainerTerminal, + "exited-after-grace must not be reported as terminal") +} From 857242d18d00dc59fa48cff8a5e22ddacf953e3b Mon Sep 17 00:00:00 2001 From: "devsy-app[bot]" <277138668+devsy-app[bot]@users.noreply.github.com> Date: Thu, 13 Aug 2026 16:39:54 +0000 Subject: [PATCH 2/2] style(docker): extract boot status test consts Lift the repeated container status string literals (dead, removing, exited, created, paused, restarting) into constants so goconst stops flagging them. Lint fix only; no behavior change. This commit was created by an AI agent (OpenHands) on behalf of the user. --- pkg/docker/boot_state_test.go | 39 ++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/pkg/docker/boot_state_test.go b/pkg/docker/boot_state_test.go index 93129d95e..587f6377d 100644 --- a/pkg/docker/boot_state_test.go +++ b/pkg/docker/boot_state_test.go @@ -6,6 +6,15 @@ import ( "github.com/stretchr/testify/assert" ) +const ( + statusDead = "dead" + statusRemoving = "removing" + statusExited = "exited" + statusCreated = "created" + statusPaused = "paused" + statusRestarting = "restarting" +) + func TestFailedBootSentinel(t *testing.T) { tests := []struct { name string @@ -14,22 +23,28 @@ func TestFailedBootSentinel(t *testing.T) { wantSentinel error wantNil bool }{ - {"dead is terminal regardless of grace", "dead", false, ErrContainerTerminal, false}, - {"dead is terminal even after grace", "dead", true, ErrContainerTerminal, false}, + {"dead is terminal regardless of grace", statusDead, false, ErrContainerTerminal, false}, + {"dead is terminal even after grace", statusDead, true, ErrContainerTerminal, false}, { "removing is terminal regardless of grace", - "removing", + statusRemoving, + false, + ErrContainerTerminal, false, + }, + { + "removing is terminal even after grace", + statusRemoving, + true, ErrContainerTerminal, false, }, - {"removing is terminal even after grace", "removing", true, ErrContainerTerminal, false}, - {"exited before grace is still booting", "exited", false, nil, true}, - {"exited after grace failed", "exited", true, ErrContainerExited, false}, - {"created before grace is still booting", "created", false, nil, true}, - {"created after grace failed", "created", true, ErrContainerExited, false}, - {"paused is not a terminal boot state", "paused", true, nil, true}, - {"restarting is not a terminal boot state", "restarting", false, nil, true}, + {"exited before grace is still booting", statusExited, false, nil, true}, + {"exited after grace failed", statusExited, true, ErrContainerExited, false}, + {"created before grace is still booting", statusCreated, false, nil, true}, + {"created after grace failed", statusCreated, true, ErrContainerExited, false}, + {"paused is not a terminal boot state", statusPaused, true, nil, true}, + {"restarting is not a terminal boot state", statusRestarting, false, nil, true}, {"empty status is not a terminal boot state", "", true, nil, true}, } @@ -54,8 +69,8 @@ func TestFailedBootSentinel(t *testing.T) { } func TestFailedBootSentinel_TerminalNotConfusedWithExited(t *testing.T) { - terminal := failedBootSentinel("removing", false) - exited := failedBootSentinel("exited", true) + terminal := failedBootSentinel(statusRemoving, false) + exited := failedBootSentinel(statusExited, true) assert.ErrorIs(t, terminal, ErrContainerTerminal) assert.NotErrorIs(t, terminal, ErrContainerExited,