Update AllAlpha integration tests to recognize CBOR.

Setting AllAlpha=true in integration tests changes the dynamic client request encoding and the
custom resource storage encoding to CBOR. The etcd storage path is updated to accept either JSON or
CBOR as storage encoding. The client feature gate controlling the dynamic client request encoding is
temporarily disabled until the serving codecs for builtin APIs are wired to the CBOR apiserver
feature gate.
This commit is contained in:
Ben Luddy 2024-11-05 08:54:16 -05:00
parent eafe7ed4a3
commit 88c9dd7534
No known key found for this signature in database
GPG Key ID: A6551E73A5974C30
2 changed files with 43 additions and 19 deletions

View File

@ -53,6 +53,8 @@ import (
mock "k8s.io/apiserver/pkg/storage/value/encrypt/envelope/testing/v1beta1"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
clientfeatures "k8s.io/client-go/features"
clientfeaturestesting "k8s.io/client-go/features/testing"
"k8s.io/client-go/rest"
featuregatetesting "k8s.io/component-base/featuregate/testing"
kmsapi "k8s.io/kms/apis/v1beta1"
@ -629,6 +631,9 @@ resources:
// Need to enable this explicitly as the feature is deprecated
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.KMSv1, true)
// TODO: Remove this override when the codecs used for serving all built-in APIs are wired to the apiserver feature gate.
clientfeaturestesting.SetFeatureDuringTest(t, clientfeatures.ClientsPreferCBOR, false)
test, err := newTransformTest(t, encryptionConfig, false, "", nil)
if err != nil {
t.Fatalf("failed to start KUBE API Server with encryptionConfig")

View File

@ -18,7 +18,6 @@ package etcd
import (
"context"
"encoding/json"
"fmt"
"path/filepath"
"reflect"
@ -33,10 +32,17 @@ import (
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer/cbor"
"k8s.io/apimachinery/pkg/runtime/serializer/json"
"k8s.io/apimachinery/pkg/runtime/serializer/recognizer"
utiljson "k8s.io/apimachinery/pkg/util/json"
"k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/dynamic"
clientfeatures "k8s.io/client-go/features"
clientfeaturestesting "k8s.io/client-go/features/testing"
featuregatetesting "k8s.io/component-base/featuregate/testing"
)
@ -77,6 +83,9 @@ func TestEtcdStoragePath(t *testing.T) {
featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllAlpha", true)
featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, "AllBeta", true)
// TODO: Remove this override when the codecs used for serving all built-in APIs are wired to the apiserver feature gate.
clientfeaturestesting.SetFeatureDuringTest(t, clientfeatures.ClientsPreferCBOR, false)
apiServer := StartRealAPIServerOrDie(t)
defer apiServer.Cleanup()
defer dumpEtcdKVOnFailure(t, apiServer.KV)
@ -124,7 +133,8 @@ func TestEtcdStoragePath(t *testing.T) {
err error
)
if shouldCreate {
if input, err = jsonToMetaObject([]byte(testData.Stub)); err != nil || input.isEmpty() {
input = new(metaObject)
if err = utiljson.Unmarshal([]byte(testData.Stub), input); err != nil || input.isEmpty() {
t.Fatalf("invalid test data for %s: %v", gvResource, err)
}
// unset type meta fields - we only set these in the CRD test data and it makes
@ -152,7 +162,20 @@ func TestEtcdStoragePath(t *testing.T) {
}
}
output, err := getFromEtcd(apiServer.KV, testData.ExpectedEtcdPath)
// Build a decoder that can decode JSON and CBOR from storage.
scheme := runtime.NewScheme()
if testData.ExpectedGVK != nil {
scheme.AddKnownTypeWithName(*testData.ExpectedGVK, &metaObject{})
} else {
scheme.AddKnownTypeWithName(gvk, &metaObject{})
}
decoder := recognizer.NewDecoder(
cbor.NewSerializer(scheme, scheme),
json.NewSerializerWithOptions(json.DefaultMetaFactory, scheme, scheme, json.SerializerOptions{}),
)
output, err := getFromEtcd(decoder, apiServer.KV, testData.ExpectedEtcdPath)
if err != nil {
t.Fatalf("failed to get from etcd for %s: %#v", gvResource, err)
}
@ -208,7 +231,7 @@ func TestEtcdStoragePath(t *testing.T) {
)
}
actualGVK := output.getGVK()
actualGVK := output.GroupVersionKind()
if actualGVK != expectedGVK {
t.Errorf("GVK for %s does not match, expected %s got %s", kind, expectedGVK, actualGVK)
}
@ -289,9 +312,7 @@ func getEtcdBucket(path string) string {
// stable fields to compare as a sanity check
type metaObject struct {
// all of type meta
Kind string `json:"kind,omitempty"`
APIVersion string `json:"apiVersion,omitempty"`
metav1.TypeMeta `json:",inline"`
// parts of object meta
Metadata struct {
@ -300,8 +321,10 @@ type metaObject struct {
} `json:"metadata,omitempty"`
}
func (obj *metaObject) getGVK() schema.GroupVersionKind {
return schema.FromAPIVersionAndKind(obj.APIVersion, obj.Kind)
var _ runtime.Object = &metaObject{}
func (*metaObject) DeepCopyObject() runtime.Object {
panic("unimplemented")
}
func (obj *metaObject) isEmpty() bool {
@ -315,14 +338,6 @@ type cleanupData struct {
resource schema.GroupVersionResource
}
func jsonToMetaObject(stub []byte) (*metaObject, error) {
obj := &metaObject{}
if err := json.Unmarshal(stub, obj); err != nil {
return nil, err
}
return obj, nil
}
func keyStringer(i interface{}) string {
base := "\n\t"
switch key := i.(type) {
@ -386,7 +401,7 @@ func (c *allClient) createPrerequisites(mapper meta.RESTMapper, ns string, prere
return nil
}
func getFromEtcd(keys clientv3.KV, path string) (*metaObject, error) {
func getFromEtcd(decoder runtime.Decoder, keys clientv3.KV, path string) (*metaObject, error) {
response, err := keys.Get(context.Background(), path)
if err != nil {
return nil, err
@ -394,7 +409,11 @@ func getFromEtcd(keys clientv3.KV, path string) (*metaObject, error) {
if response.More || response.Count != 1 || len(response.Kvs) != 1 {
return nil, fmt.Errorf("Invalid etcd response (not found == %v): %#v", response.Count == 0, response)
}
return jsonToMetaObject(response.Kvs[0].Value)
var obj metaObject
if err := runtime.DecodeInto(decoder, response.Kvs[0].Value, &obj); err != nil {
return nil, err
}
return &obj, nil
}
func diffMaps(a, b interface{}) ([]string, []string) {