From e4cc8f8e9d5263b520820c2a105b780ae4acc04b Mon Sep 17 00:00:00 2001 From: Yongrui Lin Date: Tue, 9 Jun 2026 20:56:55 +0000 Subject: [PATCH] testing: skip unserved extensions/v1beta1 in validation equivalence sweep Add WithSkipGroupVersions and apply it to the NetworkPolicy and Scale tests, whose internal types also register under the now-unvalidated extensions/v1beta1. --- pkg/api/testing/validation.go | 24 +++++++++++++++++++ .../apps/scale/declarative_validation_test.go | 2 +- .../scale/declarative_validation_test.go | 2 +- .../declarative_validation_test.go | 6 +++++ 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/pkg/api/testing/validation.go b/pkg/api/testing/validation.go index 39525d3dda0..3229b235539 100644 --- a/pkg/api/testing/validation.go +++ b/pkg/api/testing/validation.go @@ -29,6 +29,7 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" runtimetest "k8s.io/apimachinery/pkg/runtime/testing" "k8s.io/apimachinery/pkg/test/coverage" + "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/validation/field" genericapirequest "k8s.io/apiserver/pkg/endpoints/request" "k8s.io/apiserver/pkg/features" @@ -55,6 +56,12 @@ func VerifyVersionedValidationEquivalence(t *testing.T, obj, old runtime.Object, // Accumulate errors from all versioned validation, per version. all := map[string]field.ErrorList{} accumulate := func(t *testing.T, gv string, errs field.ErrorList) { + // Skip versions explicitly excluded from the equivalence sweep (e.g. a + // deprecated, unserved group whose types are intentionally not validated + // declaratively). + if opts.SkipGroupVersions.Has(gv) { + return + } // If normalization rules are provided, apply them to the field paths of generated errors. // This allows comparing errors between API versions that have structural differences // (e.g. flattened vs nested fields). @@ -222,6 +229,13 @@ type validationOption struct { // Fuzzer is the fuzzer to use for generating test objects. Fuzzer *randfill.Filler + + // SkipGroupVersions lists "group/version" strings to exclude from the + // versioned validation equivalence sweep. This is for kinds whose internal + // type is registered under a deprecated, unserved group (e.g. a workload + // type that also exists in extensions/v1beta1) for which declarative + // validation is intentionally not generated. + SkipGroupVersions sets.Set[string] } func WithSubResources(subResources ...string) ValidationTestConfig { @@ -248,6 +262,16 @@ func WithFuzzer(fuzzer *randfill.Filler) ValidationTestConfig { } } +// WithSkipGroupVersions excludes the given "group/version" strings from the +// versioned validation equivalence sweep. Use it for kinds whose internal type +// is also registered under a deprecated, unserved group (e.g. extensions/v1beta1) +// for which declarative validation is intentionally not generated. +func WithSkipGroupVersions(groupVersions ...string) ValidationTestConfig { + return func(o *validationOption) { + o.SkipGroupVersions = sets.New(groupVersions...) + } +} + // VerifyValidationEquivalence provides a helper for testing the migration from // hand-written imperative validation to declarative validation. It ensures that // the validation logic remains consistent across enforcement modes. diff --git a/test/declarative_validation/apps/scale/declarative_validation_test.go b/test/declarative_validation/apps/scale/declarative_validation_test.go index 841e4ae59dd..e905e226bff 100644 --- a/test/declarative_validation/apps/scale/declarative_validation_test.go +++ b/test/declarative_validation/apps/scale/declarative_validation_test.go @@ -61,7 +61,7 @@ func TestDeclarativeValidateUpdate(t *testing.T) { t.Run(k, func(t *testing.T) { tc.old.ResourceVersion = "1" tc.update.ResourceVersion = "1" - apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale")) + apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale"), apitesting.WithSkipGroupVersions("extensions/v1beta1")) }) } }) diff --git a/test/declarative_validation/autoscaling/scale/declarative_validation_test.go b/test/declarative_validation/autoscaling/scale/declarative_validation_test.go index 58d6fd8b0fc..9c51bfb2f97 100644 --- a/test/declarative_validation/autoscaling/scale/declarative_validation_test.go +++ b/test/declarative_validation/autoscaling/scale/declarative_validation_test.go @@ -61,7 +61,7 @@ func TestDeclarativeValidateUpdate(t *testing.T) { t.Run(k, func(t *testing.T) { tc.old.ResourceVersion = "1" tc.update.ResourceVersion = "1" - apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale")) + apitesting.VerifyUpdateValidationEquivalenceFunc(t, ctx, &tc.update, &tc.old, validateScale, tc.expectedErrs, apitesting.WithSubResources("scale"), apitesting.WithSkipGroupVersions("extensions/v1beta1")) }) } }) diff --git a/test/declarative_validation/networking/networkpolicy/declarative_validation_test.go b/test/declarative_validation/networking/networkpolicy/declarative_validation_test.go index 91aeb9e8b20..be5b0890ab0 100644 --- a/test/declarative_validation/networking/networkpolicy/declarative_validation_test.go +++ b/test/declarative_validation/networking/networkpolicy/declarative_validation_test.go @@ -80,6 +80,9 @@ func TestDeclarativeValidateIPBlockCIDR(t *testing.T) { &tc.input, registry.Strategy, tc.expectedErrs, + // extensions/v1beta1 is unserved and no longer carries + // declarative validation; skip it in the version sweep. + apitesting.WithSkipGroupVersions("extensions/v1beta1"), ) }) } @@ -148,6 +151,9 @@ func TestDeclarativeValidateIPBlockCIDRUpdate(t *testing.T) { &tc.oldObj, registry.Strategy, tc.expectedErrs, + // extensions/v1beta1 is unserved and no longer carries + // declarative validation; skip it in the version sweep. + apitesting.WithSkipGroupVersions("extensions/v1beta1"), ) }) }