kep-3926: fix 60s shutdown timeout in transformation tests

Cancel informer watch connections before tearing down the test
apiserver to avoid hitting the 60s http.Server.Shutdown drain timeout.
Each subtest was blocking on open watch connections, adding ~300s to
the total suite runtime.

Decouple the informer lifecycle from the apiserver by using a separate
cancellable context for factory.Start(). Go's defer LIFO ordering
ensures the informer stops before test.cleanUp() shuts down the
server.

Also reduce EncryptionConfigFileChangePollDuration to 1s in TestMain.
This commit is contained in:
Krzysztof Ostrowski
2026-03-04 20:03:17 +01:00
parent df9ee166f5
commit 80cc27ae50
4 changed files with 19 additions and 10 deletions

View File

@@ -171,7 +171,9 @@ func TestBitFlipCorruptObjectDeletion(t *testing.T) {
t.Fatalf("unexpected error from AddEventHandler: %v", err)
}
factory.Start(test.Done())
informerCtx, informerCancel := context.WithCancel(test)
defer informerCancel()
factory.Start(informerCtx.Done())
waitForSyncCtx, waitForSyncCancel := context.WithTimeout(context.Background(), wait.ForeverTestTimeout)
defer waitForSyncCancel()
if !cache.WaitForCacheSync(waitForSyncCtx.Done(), secretInformer.Informer().HasSynced) {

View File

@@ -236,7 +236,9 @@ func TestCRAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) {
}
lister := informer.Lister()
factory.Start(test.Done())
informerCtx, informerCancel := context.WithCancel(test)
defer informerCancel()
factory.Start(informerCtx.Done())
waitForSyncCtx, waitForSyncCancel := context.WithTimeout(context.Background(), wait.ForeverTestTimeout)
defer waitForSyncCancel()
if !cache.WaitForCacheSync(waitForSyncCtx.Done(), informer.Informer().HasSynced) {

View File

@@ -21,10 +21,14 @@ import (
"testing"
"time"
encryptionconfigcontroller "k8s.io/apiserver/pkg/server/options/encryptionconfig/controller"
"k8s.io/kubernetes/test/integration/framework"
)
func TestMain(m *testing.M) {
// Speed up encryption config reload from the default 1 minute to 1 second.
// This variable is exported specifically for integration tests.
encryptionconfigcontroller.EncryptionConfigFileChangePollDuration = time.Second
framework.EtcdMain(m.Run)
}

View File

@@ -97,7 +97,7 @@ resources:
// 2. Secrets are decrypted on read
// when EncryptionConfiguration is passed to KubeAPI server.
func TestSecretsShouldBeTransformed(t *testing.T) {
var testCases = []struct {
testCases := []struct {
transformerConfigContent string
transformerPrefix string
unSealFunc unSealSecret
@@ -267,7 +267,9 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) {
}
lister := informer.Lister()
factory.Start(test.Done())
informerCtx, informerCancel := context.WithCancel(test)
defer informerCancel()
factory.Start(informerCtx.Done())
waitForSyncCtx, waitForSyncCancel := context.WithTimeout(context.Background(), wait.ForeverTestTimeout)
defer waitForSyncCancel()
if !cache.WaitForCacheSync(waitForSyncCtx.Done(), informer.Informer().HasSynced) {
@@ -295,8 +297,7 @@ func TestAllowUnsafeMalformedObjectDeletionFeature(t *testing.T) {
// i) wait for the breaking changes to take effect
testCtx, cancel := context.WithCancel(context.Background())
defer cancel()
// TODO: dynamic encryption config reload takes about 1m, so can't use
// wait.ForeverTestTimeout just yet, investigate and reduce the reload time.
// dynamic encryption config reload takes about 1m, so can't use wait.ForeverTestTimeout
err = wait.PollUntilContextTimeout(testCtx, 1*time.Second, 2*time.Minute, true, func(ctx context.Context) (done bool, err error) {
_, err = test.restClient.CoreV1().Secrets(testNamespace).Get(ctx, secretCorrupt, metav1.GetOptions{})
var got apierrors.APIStatus
@@ -665,8 +666,8 @@ func runBenchmark(b *testing.B, transformerConfig string) {
}
func unSealWithGCMTransformer(ctx context.Context, cipherText []byte, dataCtx value.Context,
transformerConfig apiserverv1.ProviderConfiguration) ([]byte, error) {
transformerConfig apiserverv1.ProviderConfiguration,
) ([]byte, error) {
block, err := newAESCipher(transformerConfig.AESGCM.Keys[0].Secret)
if err != nil {
return nil, fmt.Errorf("failed to create block cipher: %v", err)
@@ -686,8 +687,8 @@ func unSealWithGCMTransformer(ctx context.Context, cipherText []byte, dataCtx va
}
func unSealWithCBCTransformer(ctx context.Context, cipherText []byte, dataCtx value.Context,
transformerConfig apiserverv1.ProviderConfiguration) ([]byte, error) {
transformerConfig apiserverv1.ProviderConfiguration,
) ([]byte, error) {
block, err := newAESCipher(transformerConfig.AESCBC.Keys[0].Secret)
if err != nil {
return nil, err