Adjust testing for server-side validation as default

This commit is contained in:
Kevin Delgado 2022-03-26 03:44:16 +00:00
parent a3a24e1c7b
commit f234cb142a
3 changed files with 38 additions and 25 deletions

View File

@ -251,8 +251,8 @@
works for CRD preserving unknown fields at the schema root [Conformance]'
description: Register a custom resource definition with x-preserve-unknown-fields
in the schema root. Attempt to create and apply a change a custom resource, via
kubectl; client-side validation MUST accept unknown properties. Attempt kubectl
explain; the output MUST show the custom resource KIND.
kubectl; kubectl validation MUST accept unknown properties. Attempt kubectl explain;
the output MUST show the custom resource KIND.
release: v1.16
file: test/e2e/apimachinery/crd_publish_openapi.go
- testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in embedded
@ -261,7 +261,7 @@
works for CRD preserving unknown fields in an embedded object [Conformance]'
description: Register a custom resource definition with x-preserve-unknown-fields
in an embedded object. Attempt to create and apply a change a custom resource,
via kubectl; client-side validation MUST accept unknown properties. Attempt kubectl
via kubectl; kubectl validation MUST accept unknown properties. Attempt kubectl
explain; the output MUST show that x-preserve-unknown-properties is used on the
nested field.
release: v1.16
@ -271,12 +271,12 @@
works for CRD with validation schema [Conformance]'
description: Register a custom resource definition with a validating schema consisting
of objects, arrays and primitives. Attempt to create and apply a change a custom
resource using valid properties, via kubectl; client-side validation MUST pass.
Attempt both operations with unknown properties and without required properties;
client-side validation MUST reject the operations. Attempt kubectl explain; the
output MUST explain the custom resource properties. Attempt kubectl explain on
custom resource properties; the output MUST explain the nested custom resource
properties.
resource using valid properties, via kubectl; kubectl validation MUST pass. Attempt
both operations with unknown properties and without required properties; kubectl
validation MUST reject the operations. Attempt kubectl explain; the output MUST
explain the custom resource properties. Attempt kubectl explain on custom resource
properties; the output MUST explain the nested custom resource properties. All
validation should be the same.
release: v1.16
file: test/e2e/apimachinery/crd_publish_openapi.go
- testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in object
@ -284,7 +284,7 @@
works for CRD without validation schema [Conformance]'
description: Register a custom resource definition with x-preserve-unknown-fields
in the top level object. Attempt to create and apply a change a custom resource,
via kubectl; client-side validation MUST accept unknown properties. Attempt kubectl
via kubectl; kubectl validation MUST accept unknown properties. Attempt kubectl
explain; the output MUST contain a valid DESCRIPTION stanza.
release: v1.16
file: test/e2e/apimachinery/crd_publish_openapi.go

View File

@ -58,10 +58,11 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
Testname: Custom Resource OpenAPI Publish, with validation schema
Description: Register a custom resource definition with a validating schema consisting of objects, arrays and
primitives. Attempt to create and apply a change a custom resource using valid properties, via kubectl;
client-side validation MUST pass. Attempt both operations with unknown properties and without required
properties; client-side validation MUST reject the operations. Attempt kubectl explain; the output MUST
kubectl validation MUST pass. Attempt both operations with unknown properties and without required
properties; kubectl validation MUST reject the operations. Attempt kubectl explain; the output MUST
explain the custom resource properties. Attempt kubectl explain on custom resource properties; the output MUST
explain the nested custom resource properties.
All validation should be the same.
*/
framework.ConformanceIt("works for CRD with validation schema", func() {
crd, err := setupCRD(f, schemaFoo, "foo", "v1")
@ -72,7 +73,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-foo")
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
ginkgo.By("client-side validation (kubectl create and apply) allows request with known and required properties")
ginkgo.By("kubectl validation (kubectl create and apply) allows request with known and required properties")
validCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, validCR, ns, "create", "-f", "-"); err != nil {
framework.Failf("failed to create valid CR %s: %v", validCR, err)
@ -87,13 +88,15 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
framework.Failf("failed to delete valid CR: %v", err)
}
ginkgo.By("client-side validation (kubectl create and apply) rejects request with value outside defined enum values")
ginkgo.By("kubectl validation (kubectl create and apply) rejects request with value outside defined enum values")
badEnumValueCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar", "feeling":"NonExistentValue"}]}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, badEnumValueCR, ns, "create", "-f", "-"); err == nil || !strings.Contains(err.Error(), `Unsupported value: "NonExistentValue"`) {
framework.Failf("unexpected no error when creating CR with unknown enum value: %v", err)
}
ginkgo.By("client-side validation (kubectl create and apply) rejects request with unknown properties when disallowed by the schema")
// TODO: server-side validation and client-side validation produce slightly different error messages.
// Because server-side is default in beta but not GA yet, we will produce different behaviors in the default vs GA only conformance tests. We have made the error generic enough to pass both, but should go back and make the error more specific once server-side validation goes GA.
ginkgo.By("kubectl validation (kubectl create and apply) rejects request with unknown properties when disallowed by the schema")
unknownCR := fmt.Sprintf(`{%s,"spec":{"foo":true}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, unknownCR, ns, "create", "-f", "-"); err == nil || (!strings.Contains(err.Error(), `unknown field "foo"`) && !strings.Contains(err.Error(), `unknown field "spec.foo"`)) {
framework.Failf("unexpected no error when creating CR with unknown field: %v", err)
@ -102,7 +105,8 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
framework.Failf("unexpected no error when applying CR with unknown field: %v", err)
}
ginkgo.By("client-side validation (kubectl create and apply) rejects request without required properties")
// TODO: see above note, we should check the value of the error once server-side validation is GA.
ginkgo.By("kubectl validation (kubectl create and apply) rejects request without required properties")
noRequireCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"age":"10"}]}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, noRequireCR, ns, "create", "-f", "-"); err == nil || (!strings.Contains(err.Error(), `missing required field "name"`) && !strings.Contains(err.Error(), `spec.bars[0].name: Required value`)) {
framework.Failf("unexpected no error when creating CR without required field: %v", err)
@ -141,7 +145,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
Release: v1.16
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in object
Description: Register a custom resource definition with x-preserve-unknown-fields in the top level object.
Attempt to create and apply a change a custom resource, via kubectl; client-side validation MUST accept unknown
Attempt to create and apply a change a custom resource, via kubectl; kubectl validation MUST accept unknown
properties. Attempt kubectl explain; the output MUST contain a valid DESCRIPTION stanza.
*/
framework.ConformanceIt("works for CRD without validation schema", func() {
@ -153,7 +157,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties")
ginkgo.By("kubectl validation (kubectl create and apply) allows request with any unknown properties")
randomCR := fmt.Sprintf(`{%s,"a":{"b":[{"c":"d"}]}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
framework.Failf("failed to create random CR %s for CRD without schema: %v", randomCR, err)
@ -182,7 +186,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
Release: v1.16
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields at root
Description: Register a custom resource definition with x-preserve-unknown-fields in the schema root.
Attempt to create and apply a change a custom resource, via kubectl; client-side validation MUST accept unknown
Attempt to create and apply a change a custom resource, via kubectl; kubectl validation MUST accept unknown
properties. Attempt kubectl explain; the output MUST show the custom resource KIND.
*/
framework.ConformanceIt("works for CRD preserving unknown fields at the schema root", func() {
@ -194,7 +198,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties")
ginkgo.By("kubectl validation (kubectl create and apply) allows request with any unknown properties")
randomCR := fmt.Sprintf(`{%s,"a":{"b":[{"c":"d"}]}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
framework.Failf("failed to create random CR %s for CRD that allows unknown properties at the root: %v", randomCR, err)
@ -223,7 +227,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
Release: v1.16
Testname: Custom Resource OpenAPI Publish, with x-preserve-unknown-fields in embedded object
Description: Register a custom resource definition with x-preserve-unknown-fields in an embedded object.
Attempt to create and apply a change a custom resource, via kubectl; client-side validation MUST accept unknown
Attempt to create and apply a change a custom resource, via kubectl; kubectl validation MUST accept unknown
properties. Attempt kubectl explain; the output MUST show that x-preserve-unknown-properties is used on the
nested field.
*/
@ -236,7 +240,7 @@ var _ = SIGDescribe("CustomResourcePublishOpenAPI [Privileged:ClusterAdmin]", fu
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
ns := fmt.Sprintf("--namespace=%v", f.Namespace.Name)
ginkgo.By("client-side validation (kubectl create and apply) allows request with any unknown properties")
ginkgo.By("kubectl validation (kubectl create and apply) allows request with any unknown properties")
randomCR := fmt.Sprintf(`{%s,"spec":{"a":null,"b":[{"c":"d"}]}}`, meta)
if _, err := framework.RunKubectlInput(f.Namespace.Name, randomCR, ns, "create", "-f", "-"); err != nil {
framework.Failf("failed to create random CR %s for CRD that allows unknown properties in a nested object: %v", randomCR, err)

View File

@ -1001,7 +1001,7 @@ metadata:
return nil
}
ginkgo.Describe("Kubectl client-side validation", func() {
ginkgo.Describe("Kubectl validation", func() {
ginkgo.It("should create/apply a CR with unknown fields for CRD with no validation schema", func() {
ginkgo.By("create CRD with no validation schema")
crd, err := crd.CreateTestCRD(f)
@ -1046,7 +1046,7 @@ metadata:
}
})
ginkgo.It("should create/apply a valid CR with arbitrary-extra properties for CRD with partially-specified validation schema", func() {
ginkgo.It("should create/apply an invalid/valid CR with arbitrary-extra properties for CRD with partially-specified validation schema", func() {
ginkgo.By("prepare CRD with partially-specified validation schema")
crd, err := crd.CreateTestCRD(f, func(crd *apiextensionsv1.CustomResourceDefinition) {
props := &apiextensionsv1.JSONSchemaProps{}
@ -1072,6 +1072,15 @@ metadata:
meta := fmt.Sprintf(metaPattern, crd.Crd.Spec.Names.Kind, crd.Crd.Spec.Group, crd.Crd.Spec.Versions[0].Name, "test-cr")
// XPreserveUnknownFields is defined on the root of the schema so unknown fields within the spec
// are still considered invalid
invalidArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}],"extraProperty":"arbitrary-value"}}`, meta)
err = createApplyCustomResource(invalidArbitraryCR, f.Namespace.Name, "test-cr", crd)
framework.ExpectError(err, "creating custom resource")
if !strings.Contains(err.Error(), `unknown field "spec.extraProperty"`) {
framework.Failf("incorrect error from createApplyCustomResource: %v", err)
}
// unknown fields on the root are considered valid
validArbitraryCR := fmt.Sprintf(`{%s,"spec":{"bars":[{"name":"test-bar"}]},"extraProperty":"arbitrary-value"}`, meta)
err = createApplyCustomResource(validArbitraryCR, f.Namespace.Name, "test-cr", crd)
@ -2151,7 +2160,7 @@ func startLocalProxy() (srv *httptest.Server, logs *bytes.Buffer) {
}
// createApplyCustomResource asserts that given CustomResource be created and applied
// without being rejected by client-side validation
// without being rejected by kubectl validation
func createApplyCustomResource(resource, namespace, name string, crd *crd.TestCrd) error {
ginkgo.By("successfully create CR")
if _, err := framework.RunKubectlInput(namespace, resource, "create", "--validate=true", "-f", "-"); err != nil {