Skip to content

Commit 42d3e97

Browse files
committed
Add E2E test for CBOR client compatibility with older apiservers.
Clients must be able to use CBOR without a guarantee that all apiservers support it. The apiserver aggregation layer avoids changing in any way that would require an aggregated apiservers to be updated. This end-to-end test verifies that a client's content negotiation behaviors continue to work over time when communicating with a 1.17 sample-apiserver.
1 parent a77f4c7 commit 42d3e97

File tree

2 files changed

+79
-2
lines changed

2 files changed

+79
-2
lines changed

test/e2e/apimachinery/protocol.go

Lines changed: 75 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,21 @@ import (
2626
v1 "k8s.io/api/core/v1"
2727
apierrors "k8s.io/apimachinery/pkg/api/errors"
2828
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
29+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2930
"k8s.io/apimachinery/pkg/fields"
31+
"k8s.io/apimachinery/pkg/runtime"
3032
"k8s.io/apimachinery/pkg/watch"
33+
"k8s.io/client-go/dynamic"
34+
clientfeatures "k8s.io/client-go/features"
35+
clientfeaturestesting "k8s.io/client-go/features/testing"
3136
"k8s.io/client-go/kubernetes"
32-
admissionapi "k8s.io/pod-security-admission/api"
33-
37+
aggregatorclientset "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset"
38+
"k8s.io/kubernetes/test/e2e/feature"
3439
"k8s.io/kubernetes/test/e2e/framework"
40+
imageutils "k8s.io/kubernetes/test/utils/image"
41+
admissionapi "k8s.io/pod-security-admission/api"
42+
samplev1alpha1 "k8s.io/sample-apiserver/pkg/apis/wardle/v1alpha1"
43+
samplev1alpha1client "k8s.io/sample-apiserver/pkg/generated/clientset/versioned/typed/wardle/v1alpha1"
3544
)
3645

3746
var _ = SIGDescribe("client-go should negotiate", func() {
@@ -96,3 +105,67 @@ var _ = SIGDescribe("client-go should negotiate", func() {
96105
})
97106
}
98107
})
108+
109+
var _ = SIGDescribe("CBOR", feature.CBOR, func() {
110+
f := framework.NewDefaultFramework("cbor")
111+
f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
112+
113+
// Must be serial to avoid conflict with other tests that set up a sample apiserver.
114+
f.It("clients remain compatible with the 1.17 sample-apiserver", f.WithSerial(), func(ctx context.Context) {
115+
clientfeaturestesting.SetFeatureDuringTest(g.GinkgoTB(), clientfeatures.ClientsAllowCBOR, true)
116+
clientfeaturestesting.SetFeatureDuringTest(g.GinkgoTB(), clientfeatures.ClientsPreferCBOR, true)
117+
118+
clientConfig, err := framework.LoadConfig()
119+
framework.ExpectNoError(err)
120+
121+
aggregatorClient, err := aggregatorclientset.NewForConfig(clientConfig)
122+
framework.ExpectNoError(err)
123+
124+
dynamicClient, err := dynamic.NewForConfig(clientConfig)
125+
framework.ExpectNoError(err)
126+
127+
objectNames := generateSampleAPIServerObjectNames(f.Namespace.Name)
128+
g.DeferCleanup(func(ctx context.Context) {
129+
cleanupSampleAPIServer(ctx, f.ClientSet, aggregatorClient, objectNames, samplev1alpha1.SchemeGroupVersion.Version+"."+samplev1alpha1.SchemeGroupVersion.Group)
130+
})
131+
SetUpSampleAPIServer(ctx, f, aggregatorClient, imageutils.GetE2EImage(imageutils.APIServer), objectNames, samplev1alpha1.SchemeGroupVersion.Group, samplev1alpha1.SchemeGroupVersion.Version)
132+
133+
flunder := samplev1alpha1.Flunder{
134+
ObjectMeta: metav1.ObjectMeta{
135+
Name: "test-flunder",
136+
},
137+
}
138+
139+
g.By("making requests with a generated client", func() {
140+
sampleClient, err := samplev1alpha1client.NewForConfig(clientConfig)
141+
framework.ExpectNoError(err)
142+
143+
_, err = sampleClient.Flunders(f.Namespace.Name).List(ctx, metav1.ListOptions{LabelSelector: "a,!a"})
144+
framework.ExpectNoError(err, "Failed to list with generated client")
145+
146+
_, err = sampleClient.Flunders(f.Namespace.Name).Create(ctx, &flunder, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}})
147+
o.Expect(err).To(o.MatchError(apierrors.IsUnsupportedMediaType, "Expected 415 (Unsupported Media Type) response on first write with generated client"))
148+
149+
_, err = sampleClient.Flunders(f.Namespace.Name).Create(ctx, &flunder, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}})
150+
framework.ExpectNoError(err, "Expected subsequent writes to succeed with generated client")
151+
})
152+
153+
g.By("making requests with a dynamic client", func() {
154+
unstructuredFlunderContent, err := runtime.DefaultUnstructuredConverter.ToUnstructured(&flunder)
155+
framework.ExpectNoError(err)
156+
unstructuredFlunder := &unstructured.Unstructured{Object: unstructuredFlunderContent}
157+
158+
flunderDynamicClient := dynamicClient.Resource(samplev1alpha1.SchemeGroupVersion.WithResource("flunders")).Namespace(f.Namespace.Name)
159+
160+
list, err := flunderDynamicClient.List(ctx, metav1.ListOptions{LabelSelector: "a,!a"})
161+
framework.ExpectNoError(err, "Failed to list with dynamic client")
162+
o.Expect(list.GetObjectKind().GroupVersionKind()).To(o.Equal(samplev1alpha1.SchemeGroupVersion.WithKind("FlunderList")))
163+
164+
_, err = flunderDynamicClient.Create(ctx, unstructuredFlunder, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}})
165+
o.Expect(err).To(o.MatchError(apierrors.IsUnsupportedMediaType, "Expected 415 (Unsupported Media Type) response on first write with dynamic client"))
166+
167+
_, err = flunderDynamicClient.Create(ctx, unstructuredFlunder, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}})
168+
framework.ExpectNoError(err, "Expected subsequent writes to succeed with dynamic client")
169+
})
170+
})
171+
})

test/e2e/feature/feature.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ var (
3434
// TODO: document the feature (owning SIG, when to use this feature for a test)
3535
BoundServiceAccountTokenVolume = framework.WithFeature(framework.ValidFeatures.Add("BoundServiceAccountTokenVolume"))
3636

37+
// Owner: sig-api-machinery
38+
// Marks tests that exercise the CBOR data format for serving or storage.
39+
CBOR = framework.WithFeature(framework.ValidFeatures.Add("CBOR"))
40+
3741
// TODO: document the feature (owning SIG, when to use this feature for a test)
3842
CloudProvider = framework.WithFeature(framework.ValidFeatures.Add("CloudProvider"))
3943

0 commit comments

Comments
 (0)