Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions test/e2e/controller-manager/webhook_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,41 @@ limitations under the License.
package controller_manager

import (
"context"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
clientset "github.com/volcano-sh/kthena/client-go/clientset/versioned"
workload "github.com/volcano-sh/kthena/pkg/apis/workload/v1alpha1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// waitForWebhookReady waits until the webhook is ready to accept connections.
func waitForWebhookReady(t *testing.T, ctx context.Context, kthenaClient *clientset.Clientset, timeout time.Duration) {
t.Helper()
deadline := time.Now().Add(timeout)
probe := createValidModelBoosterForWebhookTest()
for time.Now().Before(deadline) {
_, err := kthenaClient.WorkloadV1alpha1().ModelBoosters(testNamespace).Create(ctx, probe, metav1.CreateOptions{DryRun: []string{"All"}})
if err == nil {
return
}
if !strings.Contains(err.Error(), "connect: connection refused") {
t.Fatalf("Webhook probe failed: %v", err)
}
t.Logf("Webhook not ready, retrying: %v", err)
time.Sleep(2 * time.Second)
}
t.Fatal("Webhook did not become ready within timeout")
}
Comment on lines +33 to +49
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

For better readability and to use idiomatic patterns from the Kubernetes ecosystem, consider refactoring this polling loop to use wait.PollUntilContextTimeout from the k8s.io/apimachinery/pkg/util/wait package. This function is designed for this exact purpose and makes the intent of the code clearer, while also handling timeout and cancellation more robustly.

You'll need to add "k8s.io/apimachinery/pkg/util/wait" to your imports.

Suggested change
func waitForWebhookReady(t *testing.T, ctx context.Context, kthenaClient *clientset.Clientset, timeout time.Duration) {
t.Helper()
deadline := time.Now().Add(timeout)
probe := createValidModelBoosterForWebhookTest()
for time.Now().Before(deadline) {
_, err := kthenaClient.WorkloadV1alpha1().ModelBoosters(testNamespace).Create(ctx, probe, metav1.CreateOptions{DryRun: []string{"All"}})
if err == nil {
return
}
if !strings.Contains(err.Error(), "connect: connection refused") {
t.Fatalf("Webhook probe failed: %v", err)
}
t.Logf("Webhook not ready, retrying: %v", err)
time.Sleep(2 * time.Second)
}
t.Fatal("Webhook did not become ready within timeout")
}
func waitForWebhookReady(t *testing.T, ctx context.Context, kthenaClient *clientset.Clientset, timeout time.Duration) {
t.Helper()
probe := createValidModelBoosterForWebhookTest()
err := wait.PollUntilContextTimeout(ctx, 2*time.Second, timeout, true, func(ctx context.Context) (bool, error) {
_, err := kthenaClient.WorkloadV1alpha1().ModelBoosters(testNamespace).Create(ctx, probe, metav1.CreateOptions{DryRun: []string{"All"}})
if err == nil {
return true, nil // Webhook is ready
}
if strings.Contains(err.Error(), "connect: connection refused") {
t.Logf("Webhook not ready, retrying: %v", err)
return false, nil // Continue polling
}
return false, err // Stop polling with an unexpected error
})
if err != nil {
t.Fatalf("Webhook did not become ready: %v", err)
}
}


// TestWebhook tests that the webhooks (validation and mutation) work as expected.
func TestWebhook(t *testing.T) {
ctx, kthenaClient, _ := setupControllerManagerE2ETest(t)
waitForWebhookReady(t, ctx, kthenaClient, 2*time.Minute) // avoid flaky "connection refused" after controller-manager restart

testCases := []struct {
name string
Expand Down
Loading