fix(cmd): report implicit watcher waits

Signed-off-by: Karthik Chowdary <21139050+Karthik-Chowdary@users.noreply.github.com>
pull/32549/head
Karthik Chowdary 2 weeks ago
parent f590c59930
commit 1c632eee59

@ -158,7 +158,7 @@ func newInstallCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
}
client.DryRunStrategy = dryRunStrategy
printWaitMessage(out, outfmt, client.WaitStrategy, client.DryRunStrategy, client.Timeout)
printWaitMessage(out, outfmt, client.WaitStrategy, client.RollbackOnFailure, client.DryRunStrategy, client.Timeout)
rel, err := runInstall(args, client, valueOpts, out)
if err != nil {
@ -373,7 +373,12 @@ func checkIfInstallable(ch chart.Accessor) error {
return fmt.Errorf("%s charts are not installable", meta["Type"])
}
func printWaitMessage(out io.Writer, outfmt output.Format, strategy kube.WaitStrategy, dryRun action.DryRunStrategy, timeout time.Duration) {
func printWaitMessage(out io.Writer, outfmt output.Format, strategy kube.WaitStrategy, rollbackOnFailure bool, dryRun action.DryRunStrategy, timeout time.Duration) {
// Rollback-on-failure implicitly enables watcher waits in the action layer.
// Account for that here, before the action mutates its WaitStrategy.
if strategy == kube.HookOnlyStrategy && rollbackOnFailure {
strategy = kube.StatusWatcherStrategy
}
if outfmt != output.Table || strategy == kube.HookOnlyStrategy || dryRun != action.DryRunNone {
return
}

@ -17,14 +17,19 @@ limitations under the License.
package cmd
import (
"bytes"
"fmt"
"net/http"
"net/http/httptest"
"path/filepath"
"testing"
"time"
"github.com/stretchr/testify/require"
"helm.sh/helm/v4/pkg/action"
"helm.sh/helm/v4/pkg/cli/output"
"helm.sh/helm/v4/pkg/kube"
"helm.sh/helm/v4/pkg/repo/v1/repotest"
)
@ -323,3 +328,56 @@ func TestInstallFileCompletion(t *testing.T) {
checkFileCompletion(t, "install myname", true)
checkFileCompletion(t, "install myname mychart", false)
}
func TestPrintWaitMessage(t *testing.T) {
const message = "Waiting for resources to become ready (timeout: 42s)\n"
tests := []struct {
name string
format output.Format
strategy kube.WaitStrategy
rollbackOnFailure bool
dryRun action.DryRunStrategy
want string
}{
{name: "explicit watcher wait", format: output.Table, strategy: kube.StatusWatcherStrategy, dryRun: action.DryRunNone, want: message},
{name: "implicit watcher wait", format: output.Table, strategy: kube.HookOnlyStrategy, rollbackOnFailure: true, dryRun: action.DryRunNone, want: message},
{name: "hook-only wait", format: output.Table, strategy: kube.HookOnlyStrategy, dryRun: action.DryRunNone},
{name: "structured output", format: output.JSON, strategy: kube.StatusWatcherStrategy, dryRun: action.DryRunNone},
{name: "client dry run", format: output.Table, strategy: kube.StatusWatcherStrategy, dryRun: action.DryRunClient},
{name: "server dry run", format: output.Table, strategy: kube.StatusWatcherStrategy, dryRun: action.DryRunServer},
{name: "implicit wait client dry run", format: output.Table, strategy: kube.HookOnlyStrategy, rollbackOnFailure: true, dryRun: action.DryRunClient},
{name: "implicit wait server dry run", format: output.Table, strategy: kube.HookOnlyStrategy, rollbackOnFailure: true, dryRun: action.DryRunServer},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var out bytes.Buffer
printWaitMessage(&out, tt.format, tt.strategy, tt.rollbackOnFailure, tt.dryRun, 42*time.Second)
require.Equal(t, tt.want, out.String())
})
}
}
func TestInstallImplicitWaitProgress(t *testing.T) {
for _, flag := range []string{"--rollback-on-failure", "--atomic"} {
t.Run(flag, func(t *testing.T) {
defer resetEnv()()
_, out, err := executeActionCommand("install implicit-wait testdata/testcharts/empty " + flag)
require.NoError(t, err)
require.Contains(t, out, "Waiting for resources to become ready (timeout: 5m0s)\n")
})
}
}
func TestInstallDryRunSuppressesWaitProgress(t *testing.T) {
for _, dryRun := range []string{"client", "server"} {
t.Run(dryRun, func(t *testing.T) {
defer resetEnv()()
_, out, err := executeActionCommand("install dry-run-wait testdata/testcharts/empty --rollback-on-failure --dry-run=" + dryRun)
require.NoError(t, err)
require.NotContains(t, out, "Waiting for resources to become ready")
})
}
}

@ -163,7 +163,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
instClient.Replace = true
}
printWaitMessage(out, outfmt, instClient.WaitStrategy, instClient.DryRunStrategy, instClient.Timeout)
printWaitMessage(out, outfmt, instClient.WaitStrategy, instClient.RollbackOnFailure, instClient.DryRunStrategy, instClient.Timeout)
rel, err := runInstall(args, instClient, valueOpts, out)
if err != nil {
@ -259,7 +259,7 @@ func newUpgradeCmd(cfg *action.Configuration, out io.Writer) *cobra.Command {
cancel()
}()
printWaitMessage(out, outfmt, client.WaitStrategy, client.DryRunStrategy, client.Timeout)
printWaitMessage(out, outfmt, client.WaitStrategy, client.RollbackOnFailure, client.DryRunStrategy, client.Timeout)
rel, err := client.RunWithContext(ctx, args[0], ch, vals)
if err != nil {

@ -587,3 +587,34 @@ func TestUpgradeInstallServerSideApply(t *testing.T) {
})
}
}
func TestUpgradeImplicitWaitProgress(t *testing.T) {
tests := []struct {
name string
install bool
}{
{name: "upgrade"},
{name: "upgrade install", install: true},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
defer resetEnv()()
releaseName := "implicit-wait"
relMock, ch, chartPath := prepareMockRelease(t, releaseName)
store := storageFixture()
installFlag := ""
if tt.install {
installFlag = "--install"
} else {
require.NoError(t, store.Create(relMock(releaseName, 1, ch)))
}
cmd := fmt.Sprintf("upgrade %s %s --rollback-on-failure '%s'", releaseName, installFlag, chartPath)
_, out, err := executeActionCommandC(store, cmd)
require.NoError(t, err)
assert.Contains(t, out, "Waiting for resources to become ready (timeout: 5m0s)\n")
})
}
}

Loading…
Cancel
Save