Merge pull request #31717 from AustinAbro321/use-logger-with-waiter

fix: use kube logger with status waiter
pull/31763/head
Scott Rigby 8 months ago committed by GitHub
commit f928025cdb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -166,7 +166,7 @@ func (c *Client) newStatusWatcher(opts ...WaitOption) (*statusWaiter, error) {
if waitContext == nil { if waitContext == nil {
waitContext = c.WaitContext waitContext = c.WaitContext
} }
return &statusWaiter{ sw := &statusWaiter{
restMapper: restMapper, restMapper: restMapper,
client: dynamicClient, client: dynamicClient,
ctx: waitContext, ctx: waitContext,
@ -175,7 +175,9 @@ func (c *Client) newStatusWatcher(opts ...WaitOption) (*statusWaiter, error) {
waitWithJobsCtx: o.waitWithJobsCtx, waitWithJobsCtx: o.waitWithJobsCtx,
waitForDeleteCtx: o.waitForDeleteCtx, waitForDeleteCtx: o.waitForDeleteCtx,
readers: o.statusReaders, readers: o.statusReaders,
}, nil }
sw.SetLogger(c.Logger().Handler())
return sw, nil
} }
func (c *Client) GetWaiter(ws WaitStrategy) (Waiter, error) { func (c *Client) GetWaiter(ws WaitStrategy) (Waiter, error) {

@ -38,6 +38,7 @@ import (
"k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic"
watchtools "k8s.io/client-go/tools/watch" watchtools "k8s.io/client-go/tools/watch"
"helm.sh/helm/v4/internal/logging"
helmStatusReaders "helm.sh/helm/v4/internal/statusreaders" helmStatusReaders "helm.sh/helm/v4/internal/statusreaders"
) )
@ -50,6 +51,7 @@ type statusWaiter struct {
waitWithJobsCtx context.Context waitWithJobsCtx context.Context
waitForDeleteCtx context.Context waitForDeleteCtx context.Context
readers []engine.StatusReader readers []engine.StatusReader
logging.LogHolder
} }
// DefaultStatusWatcherTimeout is the timeout used by the status waiter when a // DefaultStatusWatcherTimeout is the timeout used by the status waiter when a
@ -72,7 +74,7 @@ func (w *statusWaiter) WatchUntilReady(resourceList ResourceList, timeout time.D
} }
ctx, cancel := w.contextWithTimeout(w.watchUntilReadyCtx, timeout) ctx, cancel := w.contextWithTimeout(w.watchUntilReadyCtx, timeout)
defer cancel() defer cancel()
slog.Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout)
sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper)
jobSR := helmStatusReaders.NewCustomJobStatusReader(w.restMapper) jobSR := helmStatusReaders.NewCustomJobStatusReader(w.restMapper)
podSR := helmStatusReaders.NewCustomPodStatusReader(w.restMapper) podSR := helmStatusReaders.NewCustomPodStatusReader(w.restMapper)
@ -94,7 +96,7 @@ func (w *statusWaiter) Wait(resourceList ResourceList, timeout time.Duration) er
} }
ctx, cancel := w.contextWithTimeout(w.waitCtx, timeout) ctx, cancel := w.contextWithTimeout(w.waitCtx, timeout)
defer cancel() defer cancel()
slog.Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout)
sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper)
sw.StatusReader = statusreaders.NewStatusReader(w.restMapper, w.readers...) sw.StatusReader = statusreaders.NewStatusReader(w.restMapper, w.readers...)
return w.wait(ctx, resourceList, sw) return w.wait(ctx, resourceList, sw)
@ -106,7 +108,7 @@ func (w *statusWaiter) WaitWithJobs(resourceList ResourceList, timeout time.Dura
} }
ctx, cancel := w.contextWithTimeout(w.waitWithJobsCtx, timeout) ctx, cancel := w.contextWithTimeout(w.waitWithJobsCtx, timeout)
defer cancel() defer cancel()
slog.Debug("waiting for resources", "count", len(resourceList), "timeout", timeout) w.Logger().Debug("waiting for resources", "count", len(resourceList), "timeout", timeout)
sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper)
newCustomJobStatusReader := helmStatusReaders.NewCustomJobStatusReader(w.restMapper) newCustomJobStatusReader := helmStatusReaders.NewCustomJobStatusReader(w.restMapper)
readers := append([]engine.StatusReader(nil), w.readers...) readers := append([]engine.StatusReader(nil), w.readers...)
@ -122,7 +124,7 @@ func (w *statusWaiter) WaitForDelete(resourceList ResourceList, timeout time.Dur
} }
ctx, cancel := w.contextWithTimeout(w.waitForDeleteCtx, timeout) ctx, cancel := w.contextWithTimeout(w.waitForDeleteCtx, timeout)
defer cancel() defer cancel()
slog.Debug("waiting for resources to be deleted", "count", len(resourceList), "timeout", timeout) w.Logger().Debug("waiting for resources to be deleted", "count", len(resourceList), "timeout", timeout)
sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper) sw := watcher.NewDefaultStatusWatcher(w.client, w.restMapper)
return w.waitForDelete(ctx, resourceList, sw) return w.waitForDelete(ctx, resourceList, sw)
} }
@ -142,7 +144,7 @@ func (w *statusWaiter) waitForDelete(ctx context.Context, resourceList ResourceL
RESTScopeStrategy: watcher.RESTScopeNamespace, RESTScopeStrategy: watcher.RESTScopeNamespace,
}) })
statusCollector := collector.NewResourceStatusCollector(resources) statusCollector := collector.NewResourceStatusCollector(resources)
done := statusCollector.ListenWithObserver(eventCh, statusObserver(cancel, status.NotFoundStatus)) done := statusCollector.ListenWithObserver(eventCh, statusObserver(cancel, status.NotFoundStatus, w.Logger()))
<-done <-done
if statusCollector.Error != nil { if statusCollector.Error != nil {
@ -189,7 +191,7 @@ func (w *statusWaiter) wait(ctx context.Context, resourceList ResourceList, sw w
RESTScopeStrategy: watcher.RESTScopeNamespace, RESTScopeStrategy: watcher.RESTScopeNamespace,
}) })
statusCollector := collector.NewResourceStatusCollector(resources) statusCollector := collector.NewResourceStatusCollector(resources)
done := statusCollector.ListenWithObserver(eventCh, statusObserver(cancel, status.CurrentStatus)) done := statusCollector.ListenWithObserver(eventCh, statusObserver(cancel, status.CurrentStatus, w.Logger()))
<-done <-done
if statusCollector.Error != nil { if statusCollector.Error != nil {
@ -228,7 +230,7 @@ func contextWithTimeout(ctx context.Context, timeout time.Duration) (context.Con
return watchtools.ContextWithOptionalTimeout(ctx, timeout) return watchtools.ContextWithOptionalTimeout(ctx, timeout)
} }
func statusObserver(cancel context.CancelFunc, desired status.Status) collector.ObserverFunc { func statusObserver(cancel context.CancelFunc, desired status.Status, logger *slog.Logger) collector.ObserverFunc {
return func(statusCollector *collector.ResourceStatusCollector, _ event.Event) { return func(statusCollector *collector.ResourceStatusCollector, _ event.Event) {
var rss []*event.ResourceStatus var rss []*event.ResourceStatus
var nonDesiredResources []*event.ResourceStatus var nonDesiredResources []*event.ResourceStatus
@ -253,7 +255,7 @@ func statusObserver(cancel context.CancelFunc, desired status.Status) collector.
} }
if aggregator.AggregateStatus(rss, desired) == desired { if aggregator.AggregateStatus(rss, desired) == desired {
slog.Debug("all resources achieved desired status", "desiredStatus", desired, "resourceCount", len(rss)) logger.Debug("all resources achieved desired status", "desiredStatus", desired, "resourceCount", len(rss))
cancel() cancel()
return return
} }
@ -264,7 +266,7 @@ func statusObserver(cancel context.CancelFunc, desired status.Status) collector.
return nonDesiredResources[i].Identifier.Name < nonDesiredResources[j].Identifier.Name return nonDesiredResources[i].Identifier.Name < nonDesiredResources[j].Identifier.Name
}) })
first := nonDesiredResources[0] first := nonDesiredResources[0]
slog.Debug("waiting for resource", "namespace", first.Identifier.Namespace, "name", first.Identifier.Name, "kind", first.Identifier.GroupKind.Kind, "expectedStatus", desired, "actualStatus", first.Status) logger.Debug("waiting for resource", "namespace", first.Identifier.Namespace, "name", first.Identifier.Name, "kind", first.Identifier.GroupKind.Kind, "expectedStatus", desired, "actualStatus", first.Status)
} }
} }
} }

@ -20,6 +20,7 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"log/slog"
"strings" "strings"
"sync/atomic" "sync/atomic"
"testing" "testing"
@ -326,6 +327,7 @@ func TestStatusWaitForDelete(t *testing.T) {
restMapper: fakeMapper, restMapper: fakeMapper,
client: fakeClient, client: fakeClient,
} }
statusWaiter.SetLogger(slog.Default().Handler())
objsToCreate := getRuntimeObjFromManifests(t, tt.manifestsToCreate) objsToCreate := getRuntimeObjFromManifests(t, tt.manifestsToCreate)
for _, objToCreate := range objsToCreate { for _, objToCreate := range objsToCreate {
u := objToCreate.(*unstructured.Unstructured) u := objToCreate.(*unstructured.Unstructured)
@ -369,6 +371,7 @@ func TestStatusWaitForDeleteNonExistentObject(t *testing.T) {
restMapper: fakeMapper, restMapper: fakeMapper,
client: fakeClient, client: fakeClient,
} }
statusWaiter.SetLogger(slog.Default().Handler())
// Don't create the object to test that the wait for delete works when the object doesn't exist // Don't create the object to test that the wait for delete works when the object doesn't exist
objManifest := getRuntimeObjFromManifests(t, []string{podCurrentManifest}) objManifest := getRuntimeObjFromManifests(t, []string{podCurrentManifest})
resourceList := getResourceListFromRuntimeObjs(t, c, objManifest) resourceList := getResourceListFromRuntimeObjs(t, c, objManifest)
@ -425,6 +428,7 @@ func TestStatusWait(t *testing.T) {
client: fakeClient, client: fakeClient,
restMapper: fakeMapper, restMapper: fakeMapper,
} }
statusWaiter.SetLogger(slog.Default().Handler())
objs := getRuntimeObjFromManifests(t, tt.objManifests) objs := getRuntimeObjFromManifests(t, tt.objManifests)
for _, obj := range objs { for _, obj := range objs {
u := obj.(*unstructured.Unstructured) u := obj.(*unstructured.Unstructured)
@ -481,6 +485,7 @@ func TestWaitForJobComplete(t *testing.T) {
client: fakeClient, client: fakeClient,
restMapper: fakeMapper, restMapper: fakeMapper,
} }
statusWaiter.SetLogger(slog.Default().Handler())
objs := getRuntimeObjFromManifests(t, tt.objManifests) objs := getRuntimeObjFromManifests(t, tt.objManifests)
for _, obj := range objs { for _, obj := range objs {
u := obj.(*unstructured.Unstructured) u := obj.(*unstructured.Unstructured)
@ -543,6 +548,7 @@ func TestWatchForReady(t *testing.T) {
client: fakeClient, client: fakeClient,
restMapper: fakeMapper, restMapper: fakeMapper,
} }
statusWaiter.SetLogger(slog.Default().Handler())
objs := getRuntimeObjFromManifests(t, tt.objManifests) objs := getRuntimeObjFromManifests(t, tt.objManifests)
for _, obj := range objs { for _, obj := range objs {
u := obj.(*unstructured.Unstructured) u := obj.(*unstructured.Unstructured)
@ -570,19 +576,19 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) {
name string name string
objManifests []string objManifests []string
expectErrStrs []string expectErrStrs []string
testFunc func(statusWaiter, ResourceList, time.Duration) error testFunc func(*statusWaiter, ResourceList, time.Duration) error
}{ }{
{ {
name: "pods in multiple namespaces", name: "pods in multiple namespaces",
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
{ {
name: "hooks in multiple namespaces", name: "hooks in multiple namespaces",
objManifests: []string{jobNamespace1CompleteManifest, podNamespace2SucceededManifest}, objManifests: []string{jobNamespace1CompleteManifest, podNamespace2SucceededManifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WatchUntilReady(rl, timeout) return sw.WatchUntilReady(rl, timeout)
}, },
}, },
@ -590,42 +596,42 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) {
name: "error when resource not ready in one namespace", name: "error when resource not ready in one namespace",
objManifests: []string{podNamespace1NoStatusManifest, podNamespace2Manifest}, objManifests: []string{podNamespace1NoStatusManifest, podNamespace2Manifest},
expectErrStrs: []string{"resource Pod/namespace-1/pod-ns1 not ready. status: InProgress", "context deadline exceeded"}, expectErrStrs: []string{"resource Pod/namespace-1/pod-ns1 not ready. status: InProgress", "context deadline exceeded"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
{ {
name: "delete resources in multiple namespaces", name: "delete resources in multiple namespaces",
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WaitForDelete(rl, timeout) return sw.WaitForDelete(rl, timeout)
}, },
}, },
{ {
name: "cluster-scoped resources work correctly with unrestricted permissions", name: "cluster-scoped resources work correctly with unrestricted permissions",
objManifests: []string{podNamespace1Manifest, clusterRoleManifest}, objManifests: []string{podNamespace1Manifest, clusterRoleManifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
{ {
name: "namespace-scoped and cluster-scoped resources work together", name: "namespace-scoped and cluster-scoped resources work together",
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest, clusterRoleManifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest, clusterRoleManifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
{ {
name: "delete cluster-scoped resources works correctly", name: "delete cluster-scoped resources works correctly",
objManifests: []string{podNamespace1Manifest, namespaceManifest}, objManifests: []string{podNamespace1Manifest, namespaceManifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WaitForDelete(rl, timeout) return sw.WaitForDelete(rl, timeout)
}, },
}, },
{ {
name: "watch cluster-scoped resources works correctly", name: "watch cluster-scoped resources works correctly",
objManifests: []string{clusterRoleManifest}, objManifests: []string{clusterRoleManifest},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WatchUntilReady(rl, timeout) return sw.WatchUntilReady(rl, timeout)
}, },
}, },
@ -646,6 +652,7 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) {
client: fakeClient, client: fakeClient,
restMapper: fakeMapper, restMapper: fakeMapper,
} }
sw.SetLogger(slog.Default().Handler())
objs := getRuntimeObjFromManifests(t, tt.objManifests) objs := getRuntimeObjFromManifests(t, tt.objManifests)
for _, obj := range objs { for _, obj := range objs {
u := obj.(*unstructured.Unstructured) u := obj.(*unstructured.Unstructured)
@ -668,7 +675,7 @@ func TestStatusWaitMultipleNamespaces(t *testing.T) {
} }
resourceList := getResourceListFromRuntimeObjs(t, c, objs) resourceList := getResourceListFromRuntimeObjs(t, c, objs)
err := tt.testFunc(sw, resourceList, time.Second*3) err := tt.testFunc(&sw, resourceList, time.Second*3)
if tt.expectErrStrs != nil { if tt.expectErrStrs != nil {
require.Error(t, err) require.Error(t, err)
for _, expectedErrStr := range tt.expectErrStrs { for _, expectedErrStr := range tt.expectErrStrs {
@ -756,13 +763,13 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
objManifests []string objManifests []string
allowedNamespaces []string allowedNamespaces []string
expectErrs []error expectErrs []error
testFunc func(statusWaiter, ResourceList, time.Duration) error testFunc func(*statusWaiter, ResourceList, time.Duration) error
}{ }{
{ {
name: "pods in multiple namespaces with namespace permissions", name: "pods in multiple namespaces with namespace permissions",
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
allowedNamespaces: []string{"namespace-1", "namespace-2"}, allowedNamespaces: []string{"namespace-1", "namespace-2"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -770,7 +777,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
name: "delete pods in multiple namespaces with namespace permissions", name: "delete pods in multiple namespaces with namespace permissions",
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
allowedNamespaces: []string{"namespace-1", "namespace-2"}, allowedNamespaces: []string{"namespace-1", "namespace-2"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WaitForDelete(rl, timeout) return sw.WaitForDelete(rl, timeout)
}, },
}, },
@ -778,7 +785,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
name: "hooks in multiple namespaces with namespace permissions", name: "hooks in multiple namespaces with namespace permissions",
objManifests: []string{jobNamespace1CompleteManifest, podNamespace2SucceededManifest}, objManifests: []string{jobNamespace1CompleteManifest, podNamespace2SucceededManifest},
allowedNamespaces: []string{"namespace-1", "namespace-2"}, allowedNamespaces: []string{"namespace-1", "namespace-2"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WatchUntilReady(rl, timeout) return sw.WatchUntilReady(rl, timeout)
}, },
}, },
@ -787,7 +794,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
objManifests: []string{podNamespace1Manifest, clusterRoleManifest}, objManifests: []string{podNamespace1Manifest, clusterRoleManifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")}, expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -796,7 +803,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
objManifests: []string{podNamespace1Manifest, namespaceManifest}, objManifests: []string{podNamespace1Manifest, namespaceManifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")}, expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WaitForDelete(rl, timeout) return sw.WaitForDelete(rl, timeout)
}, },
}, },
@ -805,7 +812,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have LIST permissions in namespace %q", "namespace-2")}, expectErrs: []error{fmt.Errorf("user does not have LIST permissions in namespace %q", "namespace-2")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -827,6 +834,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
client: baseFakeClient, client: baseFakeClient,
restMapper: fakeMapper, restMapper: fakeMapper,
} }
sw.SetLogger(slog.Default().Handler())
objs := getRuntimeObjFromManifests(t, tt.objManifests) objs := getRuntimeObjFromManifests(t, tt.objManifests)
for _, obj := range objs { for _, obj := range objs {
u := obj.(*unstructured.Unstructured) u := obj.(*unstructured.Unstructured)
@ -849,7 +857,7 @@ func TestStatusWaitRestrictedRBAC(t *testing.T) {
} }
resourceList := getResourceListFromRuntimeObjs(t, c, objs) resourceList := getResourceListFromRuntimeObjs(t, c, objs)
err := tt.testFunc(sw, resourceList, time.Second*3) err := tt.testFunc(&sw, resourceList, time.Second*3)
if tt.expectErrs != nil { if tt.expectErrs != nil {
require.Error(t, err) require.Error(t, err)
for _, expectedErr := range tt.expectErrs { for _, expectedErr := range tt.expectErrs {
@ -870,13 +878,13 @@ func TestStatusWaitMixedResources(t *testing.T) {
objManifests []string objManifests []string
allowedNamespaces []string allowedNamespaces []string
expectErrs []error expectErrs []error
testFunc func(statusWaiter, ResourceList, time.Duration) error testFunc func(*statusWaiter, ResourceList, time.Duration) error
}{ }{
{ {
name: "wait succeeds with namespace-scoped resources only", name: "wait succeeds with namespace-scoped resources only",
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
allowedNamespaces: []string{"namespace-1", "namespace-2"}, allowedNamespaces: []string{"namespace-1", "namespace-2"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -885,7 +893,7 @@ func TestStatusWaitMixedResources(t *testing.T) {
objManifests: []string{podNamespace1Manifest, clusterRoleManifest}, objManifests: []string{podNamespace1Manifest, clusterRoleManifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")}, expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -894,7 +902,7 @@ func TestStatusWaitMixedResources(t *testing.T) {
objManifests: []string{podNamespace1Manifest, clusterRoleManifest}, objManifests: []string{podNamespace1Manifest, clusterRoleManifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")}, expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WaitForDelete(rl, timeout) return sw.WaitForDelete(rl, timeout)
}, },
}, },
@ -903,7 +911,7 @@ func TestStatusWaitMixedResources(t *testing.T) {
objManifests: []string{podNamespace1Manifest, namespaceManifest}, objManifests: []string{podNamespace1Manifest, namespaceManifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")}, expectErrs: []error{fmt.Errorf("user does not have cluster-wide LIST permissions for cluster-scoped resources")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -912,7 +920,7 @@ func TestStatusWaitMixedResources(t *testing.T) {
objManifests: []string{podNamespace1Manifest, podNamespace2Manifest}, objManifests: []string{podNamespace1Manifest, podNamespace2Manifest},
allowedNamespaces: []string{"namespace-1"}, allowedNamespaces: []string{"namespace-1"},
expectErrs: []error{fmt.Errorf("user does not have LIST permissions in namespace %q", "namespace-2")}, expectErrs: []error{fmt.Errorf("user does not have LIST permissions in namespace %q", "namespace-2")},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -934,6 +942,7 @@ func TestStatusWaitMixedResources(t *testing.T) {
client: baseFakeClient, client: baseFakeClient,
restMapper: fakeMapper, restMapper: fakeMapper,
} }
sw.SetLogger(slog.Default().Handler())
objs := getRuntimeObjFromManifests(t, tt.objManifests) objs := getRuntimeObjFromManifests(t, tt.objManifests)
for _, obj := range objs { for _, obj := range objs {
u := obj.(*unstructured.Unstructured) u := obj.(*unstructured.Unstructured)
@ -956,7 +965,7 @@ func TestStatusWaitMixedResources(t *testing.T) {
} }
resourceList := getResourceListFromRuntimeObjs(t, c, objs) resourceList := getResourceListFromRuntimeObjs(t, c, objs)
err := tt.testFunc(sw, resourceList, time.Second*3) err := tt.testFunc(&sw, resourceList, time.Second*3)
if tt.expectErrs != nil { if tt.expectErrs != nil {
require.Error(t, err) require.Error(t, err)
for _, expectedErr := range tt.expectErrs { for _, expectedErr := range tt.expectErrs {
@ -1151,7 +1160,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) {
objManifests []string objManifests []string
customReader *mockStatusReader customReader *mockStatusReader
expectErrStrs []string expectErrStrs []string
testFunc func(statusWaiter, ResourceList, time.Duration) error testFunc func(*statusWaiter, ResourceList, time.Duration) error
}{ }{
{ {
name: "Wait returns error when resource has failed", name: "Wait returns error when resource has failed",
@ -1161,7 +1170,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) {
status: status.FailedStatus, status: status.FailedStatus,
}, },
expectErrStrs: []string{"resource Pod/ns/in-progress-pod not ready. status: Failed, message: mock status reader"}, expectErrStrs: []string{"resource Pod/ns/in-progress-pod not ready. status: Failed, message: mock status reader"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -1172,7 +1181,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) {
expectErrStrs: []string{ expectErrStrs: []string{
"resource Job/default/failed-job not ready. status: Failed", "resource Job/default/failed-job not ready. status: Failed",
}, },
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WaitWithJobs(rl, timeout) return sw.WaitWithJobs(rl, timeout)
}, },
}, },
@ -1188,7 +1197,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) {
"resource Pod/ns/in-progress-pod not ready. status: Failed, message: mock status reader", "resource Pod/ns/in-progress-pod not ready. status: Failed, message: mock status reader",
"resource Pod/ns/current-pod not ready. status: Failed, message: mock status reader", "resource Pod/ns/current-pod not ready. status: Failed, message: mock status reader",
}, },
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.Wait(rl, timeout) return sw.Wait(rl, timeout)
}, },
}, },
@ -1201,7 +1210,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) {
}, },
// WatchUntilReady also waits for CurrentStatus, so failed resources should return error // WatchUntilReady also waits for CurrentStatus, so failed resources should return error
expectErrStrs: []string{"resource Pod/ns/in-progress-pod not ready. status: Failed, message: mock status reader"}, expectErrStrs: []string{"resource Pod/ns/in-progress-pod not ready. status: Failed, message: mock status reader"},
testFunc: func(sw statusWaiter, rl ResourceList, timeout time.Duration) error { testFunc: func(sw *statusWaiter, rl ResourceList, timeout time.Duration) error {
return sw.WatchUntilReady(rl, timeout) return sw.WatchUntilReady(rl, timeout)
}, },
}, },
@ -1233,7 +1242,7 @@ func TestStatusWaitWithFailedResources(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
} }
resourceList := getResourceListFromRuntimeObjs(t, c, objs) resourceList := getResourceListFromRuntimeObjs(t, c, objs)
err := tt.testFunc(sw, resourceList, time.Second*3) err := tt.testFunc(&sw, resourceList, time.Second*3)
if tt.expectErrStrs != nil { if tt.expectErrStrs != nil {
require.Error(t, err) require.Error(t, err)
for _, expectedErrStr := range tt.expectErrStrs { for _, expectedErrStr := range tt.expectErrStrs {

Loading…
Cancel
Save