mirror of
https://github.com/kubernetes/kubernetes.git
synced 2026-06-09 08:55:55 -04:00
test: address VolumeAttachment DV feedback
This commit is contained in:
parent
0ed84c6b5d
commit
3274946d52
5 changed files with 49 additions and 81 deletions
|
|
@ -22,3 +22,48 @@
|
|||
errorType: '*'
|
||||
origin: '*'
|
||||
reason: Not served by kube-apiserver.
|
||||
|
||||
# Scale subresource: no dedicated Strategy in the new tree; tested separately
|
||||
# via VerifyVersionedValidationEquivalence (which doesn't populate the
|
||||
# in-process coverage accumulator). extensions/v1beta1/Scale is covered by
|
||||
# the group-level entry above.
|
||||
- apiVersion: autoscaling/v1
|
||||
kind: Scale
|
||||
path: '*'
|
||||
errorType: '*'
|
||||
origin: '*'
|
||||
reason: Scale subresource has no dedicated Strategy; tested separately.
|
||||
- apiVersion: apps/v1beta1
|
||||
kind: Scale
|
||||
path: '*'
|
||||
errorType: '*'
|
||||
origin: '*'
|
||||
reason: Scale subresource has no dedicated Strategy; tested separately.
|
||||
- apiVersion: apps/v1beta2
|
||||
kind: Scale
|
||||
path: '*'
|
||||
errorType: '*'
|
||||
origin: '*'
|
||||
reason: Scale subresource has no dedicated Strategy; tested separately.
|
||||
|
||||
# VolumeAttachment spec is immutable. Updating inlineVolumeSpec.volumeMode is
|
||||
# rejected at spec before the nested PersistentVolumeSpec rule can be observed
|
||||
# through the REST strategy.
|
||||
- apiVersion: storage.k8s.io/v1
|
||||
kind: VolumeAttachment
|
||||
path: spec.source.inlineVolumeSpec.volumeMode
|
||||
errorType: FieldValueInvalid
|
||||
origin: immutable
|
||||
reason: VolumeAttachment spec immutability short-circuits this nested update rule.
|
||||
- apiVersion: storage.k8s.io/v1alpha1
|
||||
kind: VolumeAttachment
|
||||
path: spec.source.inlineVolumeSpec.volumeMode
|
||||
errorType: FieldValueInvalid
|
||||
origin: immutable
|
||||
reason: VolumeAttachment spec immutability short-circuits this nested update rule.
|
||||
- apiVersion: storage.k8s.io/v1beta1
|
||||
kind: VolumeAttachment
|
||||
path: spec.source.inlineVolumeSpec.volumeMode
|
||||
errorType: FieldValueInvalid
|
||||
origin: immutable
|
||||
reason: VolumeAttachment spec immutability short-circuits this nested update rule.
|
||||
|
|
|
|||
|
|
@ -17,27 +17,15 @@ limitations under the License.
|
|||
package volumeattachment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
apistoragev1 "k8s.io/api/storage/v1"
|
||||
apistoragev1alpha1 "k8s.io/api/storage/v1alpha1"
|
||||
apistoragev1beta1 "k8s.io/api/storage/v1beta1"
|
||||
"k8s.io/apimachinery/pkg/api/operation"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"k8s.io/apimachinery/pkg/test/coverage"
|
||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||
genericapirequest "k8s.io/apiserver/pkg/endpoints/request"
|
||||
"k8s.io/apiserver/pkg/registry/rest"
|
||||
apitesting "k8s.io/kubernetes/pkg/api/testing"
|
||||
core "k8s.io/kubernetes/pkg/apis/core"
|
||||
storage "k8s.io/kubernetes/pkg/apis/storage"
|
||||
validationstoragev1 "k8s.io/kubernetes/pkg/apis/storage/v1"
|
||||
validationstoragev1alpha1 "k8s.io/kubernetes/pkg/apis/storage/v1alpha1"
|
||||
validationstoragev1beta1 "k8s.io/kubernetes/pkg/apis/storage/v1beta1"
|
||||
registry "k8s.io/kubernetes/pkg/registry/storage/volumeattachment"
|
||||
)
|
||||
|
||||
|
|
@ -118,10 +106,9 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) {
|
|||
})
|
||||
|
||||
testCases := map[string]struct {
|
||||
oldInput storage.VolumeAttachment
|
||||
newInput storage.VolumeAttachment
|
||||
expectedErrs field.ErrorList
|
||||
verifyAllRules func(t *testing.T, apiVersion string)
|
||||
oldInput storage.VolumeAttachment
|
||||
newInput storage.VolumeAttachment
|
||||
expectedErrs field.ErrorList
|
||||
}{
|
||||
"valid update": {
|
||||
oldInput: mkValidVolumeAttachment(),
|
||||
|
|
@ -140,18 +127,12 @@ func testDeclarativeValidateUpdate(t *testing.T, apiVersion string) {
|
|||
expectedErrs: field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec"), nil, "field is immutable").WithOrigin("immutable").MarkAlpha(),
|
||||
},
|
||||
// The object-level update path short-circuits on immutable spec, so
|
||||
// cover the nested inline PersistentVolumeSpec rule explicitly here.
|
||||
verifyAllRules: verifyInlineVolumeSpecVolumeMode,
|
||||
},
|
||||
}
|
||||
|
||||
for name, tc := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
apitesting.VerifyUpdateValidationEquivalence(t, ctx, &tc.newInput, &tc.oldInput, registry.Strategy, tc.expectedErrs)
|
||||
if tc.verifyAllRules != nil {
|
||||
tc.verifyAllRules(t, apiVersion)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -164,6 +145,7 @@ func TweakAttacher(attacher string) func(obj *storage.VolumeAttachment) {
|
|||
|
||||
func TweakInlineVolumeSpec(spec *core.PersistentVolumeSpec) func(obj *storage.VolumeAttachment) {
|
||||
return func(obj *storage.VolumeAttachment) {
|
||||
// VolumeAttachmentSource is a union; clear PersistentVolumeName so the inline spec is selected.
|
||||
obj.Spec.Source.PersistentVolumeName = nil
|
||||
obj.Spec.Source.InlineVolumeSpec = spec
|
||||
}
|
||||
|
|
@ -201,53 +183,3 @@ func mkInlineVolumeSpec(volumeMode *core.PersistentVolumeMode) *core.PersistentV
|
|||
VolumeMode: volumeMode,
|
||||
}
|
||||
}
|
||||
|
||||
func verifyInlineVolumeSpecVolumeMode(t *testing.T, apiVersion string) {
|
||||
t.Helper()
|
||||
blockMode := corev1.PersistentVolumeBlock
|
||||
filesystemMode := corev1.PersistentVolumeFilesystem
|
||||
ctx := rest.WithAllDeclarativeEnforcedForTest(context.Background())
|
||||
op := operation.Operation{Type: operation.Update}
|
||||
fldPath := field.NewPath("spec", "source")
|
||||
|
||||
var errs field.ErrorList
|
||||
switch apiVersion {
|
||||
case "v1":
|
||||
oldObj := &apistoragev1.VolumeAttachmentSource{InlineVolumeSpec: mkVersionedInlineVolumeSpec(&filesystemMode)}
|
||||
newObj := &apistoragev1.VolumeAttachmentSource{InlineVolumeSpec: mkVersionedInlineVolumeSpec(&blockMode)}
|
||||
errs = validationstoragev1.Validate_VolumeAttachmentSource(ctx, op, fldPath, newObj, oldObj)
|
||||
case "v1alpha1":
|
||||
oldObj := &apistoragev1alpha1.VolumeAttachmentSource{InlineVolumeSpec: mkVersionedInlineVolumeSpec(&filesystemMode)}
|
||||
newObj := &apistoragev1alpha1.VolumeAttachmentSource{InlineVolumeSpec: mkVersionedInlineVolumeSpec(&blockMode)}
|
||||
errs = validationstoragev1alpha1.Validate_VolumeAttachmentSource(ctx, op, fldPath, newObj, oldObj)
|
||||
case "v1beta1":
|
||||
oldObj := &apistoragev1beta1.VolumeAttachmentSource{InlineVolumeSpec: mkVersionedInlineVolumeSpec(&filesystemMode)}
|
||||
newObj := &apistoragev1beta1.VolumeAttachmentSource{InlineVolumeSpec: mkVersionedInlineVolumeSpec(&blockMode)}
|
||||
errs = validationstoragev1beta1.Validate_VolumeAttachmentSource(ctx, op, fldPath, newObj, oldObj)
|
||||
default:
|
||||
t.Fatalf("unexpected apiVersion %q", apiVersion)
|
||||
}
|
||||
|
||||
expectedErrs := field.ErrorList{
|
||||
field.Invalid(field.NewPath("spec", "source", "inlineVolumeSpec", "volumeMode"), nil, "").WithOrigin("immutable").MarkAlpha(),
|
||||
}
|
||||
field.ErrorMatcher{}.ByType().ByOrigin().ByField().ByValidationStabilityLevel().BySource().Test(t, expectedErrs, errs)
|
||||
coverage.RecordObservedRules(schema.GroupVersionKind{
|
||||
Group: "storage.k8s.io",
|
||||
Version: apiVersion,
|
||||
Kind: "VolumeAttachment",
|
||||
}, errs)
|
||||
}
|
||||
|
||||
func mkVersionedInlineVolumeSpec(volumeMode *corev1.PersistentVolumeMode) *corev1.PersistentVolumeSpec {
|
||||
return &corev1.PersistentVolumeSpec{
|
||||
AccessModes: []corev1.PersistentVolumeAccessMode{corev1.ReadWriteOnce},
|
||||
PersistentVolumeSource: corev1.PersistentVolumeSource{
|
||||
CSI: &corev1.CSIPersistentVolumeSource{
|
||||
Driver: "com.test.foo",
|
||||
VolumeHandle: "valid-volume",
|
||||
},
|
||||
},
|
||||
VolumeMode: volumeMode,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ func init() {
|
|||
{ErrorType: "FieldValueRequired"},
|
||||
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
|
||||
},
|
||||
"spec.source.inlineVolumeSpec.volumeMode": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "immutable"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ func init() {
|
|||
{ErrorType: "FieldValueRequired"},
|
||||
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
|
||||
},
|
||||
"spec.source.inlineVolumeSpec.volumeMode": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "immutable"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,9 +38,6 @@ func init() {
|
|||
{ErrorType: "FieldValueRequired"},
|
||||
{ErrorType: "FieldValueTooLong", Origin: "maxLength"},
|
||||
},
|
||||
"spec.source.inlineVolumeSpec.volumeMode": {
|
||||
{ErrorType: "FieldValueInvalid", Origin: "immutable"},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue