diff --git a/internal/troubleshoot/collect/config_dump.go b/internal/troubleshoot/collect/config_dump.go index e7e29152f9..f782e97963 100644 --- a/internal/troubleshoot/collect/config_dump.go +++ b/internal/troubleshoot/collect/config_dump.go @@ -10,6 +10,7 @@ import ( "context" "fmt" "path" + "time" adminv3 "github.com/envoyproxy/go-control-plane/envoy/admin/v3" troubleshootv1b2 "github.com/replicatedhq/troubleshoot/pkg/apis/troubleshoot/v1beta2" @@ -26,6 +27,8 @@ import ( const ( SecretsConfigDumpTypeURL = "type.googleapis.com/envoy.admin.v3.SecretsConfigDump" + // DefaultConfigDumpTimeout is the default timeout for config dump collection + DefaultConfigDumpTimeout = 30 * time.Second ) var _ tbcollect.Collector = &ConfigDump{} @@ -37,6 +40,8 @@ type ConfigDump struct { ClientConfig *rest.Config EnableSDS bool + // Timeout is the timeout for collecting config dumps. If not set, defaults to DefaultConfigDumpTimeout. + Timeout time.Duration } func (cd ConfigDump) Title() string { @@ -59,13 +64,24 @@ func (cd ConfigDump) CheckRBAC(_ context.Context, _ tbcollect.Collector, _ *trou return nil } +// getTimeout returns the configured timeout, or the default if not set +func (cd ConfigDump) getTimeout() time.Duration { + if cd.Timeout > 0 { + return cd.Timeout + } + return DefaultConfigDumpTimeout +} + func (cd ConfigDump) Collect(_ chan<- interface{}) (tbcollect.CollectorResult, error) { + ctx, cancel := context.WithTimeout(context.Background(), cd.getTimeout()) + defer cancel() + client, err := kubernetes.NewForConfig(cd.ClientConfig) if err != nil { return nil, err } - pods, err := listPods(context.TODO(), client, cd.Namespace, labels.SelectorFromSet(map[string]string{ + pods, err := listPods(ctx, client, cd.Namespace, labels.SelectorFromSet(map[string]string{ "app.kubernetes.io/component": "proxy", "app.kubernetes.io/managed-by": "envoy-gateway", "app.kubernetes.io/name": "envoy", diff --git a/internal/troubleshoot/collect/config_dump_test.go b/internal/troubleshoot/collect/config_dump_test.go new file mode 100644 index 0000000000..7774d8b2e7 --- /dev/null +++ b/internal/troubleshoot/collect/config_dump_test.go @@ -0,0 +1,71 @@ +// Copyright Envoy Gateway Authors +// SPDX-License-Identifier: Apache-2.0 +// The full text of the Apache license is available in the LICENSE file at +// the root of the repo. + +package collect + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func TestConfigDump_getTimeout(t *testing.T) { + tests := []struct { + name string + timeout time.Duration + expected time.Duration + }{ + { + name: "returns default when timeout is zero", + timeout: 0, + expected: DefaultConfigDumpTimeout, + }, + { + name: "returns default when timeout is negative", + timeout: -5 * time.Second, + expected: DefaultConfigDumpTimeout, + }, + { + name: "returns configured timeout when set", + timeout: 60 * time.Second, + expected: 60 * time.Second, + }, + { + name: "returns configured timeout when less than default", + timeout: 10 * time.Second, + expected: 10 * time.Second, + }, + { + name: "returns configured timeout when greater than default", + timeout: 120 * time.Second, + expected: 120 * time.Second, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + cd := ConfigDump{ + Timeout: tt.timeout, + } + got := cd.getTimeout() + assert.Equal(t, tt.expected, got, "getTimeout() should return expected duration") + }) + } +} + +func TestDefaultConfigDumpTimeout(t *testing.T) { + // Verify the default timeout constant is set to the expected value + expected := 30 * time.Second + assert.Equal(t, expected, DefaultConfigDumpTimeout, "DefaultConfigDumpTimeout should be 30 seconds") +} + +func TestConfigDump_TimeoutField(t *testing.T) { + // Test that the Timeout field can be set and retrieved + cd := ConfigDump{ + Timeout: 45 * time.Second, + } + assert.Equal(t, 45*time.Second, cd.Timeout, "Timeout field should be settable") +}