mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 01:06:27 +00:00
k8s.io/apiserver/storage: add a new TestCreate case.
Add a test case of create with rv set. Signed-off-by: Siyuan Zhang <sizhang@google.com>
This commit is contained in:
parent
0d63366bdf
commit
2f923e356e
@ -17,13 +17,16 @@ limitations under the License.
|
|||||||
package storage
|
package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"k8s.io/apimachinery/pkg/api/errors"
|
apierrors "k8s.io/apimachinery/pkg/api/errors"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/util/validation/field"
|
"k8s.io/apimachinery/pkg/util/validation/field"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var ErrResourceVersionSetOnCreate = errors.New("resourceVersion should not be set on objects to be created")
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ErrCodeKeyNotFound int = iota + 1
|
ErrCodeKeyNotFound int = iota + 1
|
||||||
ErrCodeKeyExists
|
ErrCodeKeyExists
|
||||||
@ -176,7 +179,7 @@ var tooLargeResourceVersionCauseMsg = "Too large resource version"
|
|||||||
// NewTooLargeResourceVersionError returns a timeout error with the given retrySeconds for a request for
|
// NewTooLargeResourceVersionError returns a timeout error with the given retrySeconds for a request for
|
||||||
// a minimum resource version that is larger than the largest currently available resource version for a requested resource.
|
// a minimum resource version that is larger than the largest currently available resource version for a requested resource.
|
||||||
func NewTooLargeResourceVersionError(minimumResourceVersion, currentRevision uint64, retrySeconds int) error {
|
func NewTooLargeResourceVersionError(minimumResourceVersion, currentRevision uint64, retrySeconds int) error {
|
||||||
err := errors.NewTimeoutError(fmt.Sprintf("Too large resource version: %d, current: %d", minimumResourceVersion, currentRevision), retrySeconds)
|
err := apierrors.NewTimeoutError(fmt.Sprintf("Too large resource version: %d, current: %d", minimumResourceVersion, currentRevision), retrySeconds)
|
||||||
err.ErrStatus.Details.Causes = []metav1.StatusCause{
|
err.ErrStatus.Details.Causes = []metav1.StatusCause{
|
||||||
{
|
{
|
||||||
Type: metav1.CauseTypeResourceVersionTooLarge,
|
Type: metav1.CauseTypeResourceVersionTooLarge,
|
||||||
@ -188,8 +191,8 @@ func NewTooLargeResourceVersionError(minimumResourceVersion, currentRevision uin
|
|||||||
|
|
||||||
// IsTooLargeResourceVersion returns true if the error is a TooLargeResourceVersion error.
|
// IsTooLargeResourceVersion returns true if the error is a TooLargeResourceVersion error.
|
||||||
func IsTooLargeResourceVersion(err error) bool {
|
func IsTooLargeResourceVersion(err error) bool {
|
||||||
if !errors.IsTimeout(err) {
|
if !apierrors.IsTimeout(err) {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return errors.HasStatusCause(err, metav1.CauseTypeResourceVersionTooLarge)
|
return apierrors.HasStatusCause(err, metav1.CauseTypeResourceVersionTooLarge)
|
||||||
}
|
}
|
||||||
|
@ -199,7 +199,7 @@ func (s *store) Create(ctx context.Context, key string, obj, out runtime.Object,
|
|||||||
)
|
)
|
||||||
defer span.End(500 * time.Millisecond)
|
defer span.End(500 * time.Millisecond)
|
||||||
if version, err := s.versioner.ObjectResourceVersion(obj); err == nil && version != 0 {
|
if version, err := s.versioner.ObjectResourceVersion(obj); err == nil && version != 0 {
|
||||||
return errors.New("resourceVersion should not be set on objects to be created")
|
return storage.ErrResourceVersionSetOnCreate
|
||||||
}
|
}
|
||||||
if err := s.versioner.PrepareObjectForStorage(obj); err != nil {
|
if err := s.versioner.PrepareObjectForStorage(obj); err != nil {
|
||||||
return fmt.Errorf("PrepareObjectForStorage failed: %v", err)
|
return fmt.Errorf("PrepareObjectForStorage failed: %v", err)
|
||||||
|
@ -44,30 +44,45 @@ import (
|
|||||||
type KeyValidation func(ctx context.Context, t *testing.T, key string)
|
type KeyValidation func(ctx context.Context, t *testing.T, key string)
|
||||||
|
|
||||||
func RunTestCreate(ctx context.Context, t *testing.T, store storage.Interface, validation KeyValidation) {
|
func RunTestCreate(ctx context.Context, t *testing.T, store storage.Interface, validation KeyValidation) {
|
||||||
out := &example.Pod{}
|
tests := []struct {
|
||||||
obj := &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test-ns", SelfLink: "testlink"}}
|
name string
|
||||||
|
inputObj *example.Pod
|
||||||
|
expectedError error
|
||||||
|
}{{
|
||||||
|
name: "successful create",
|
||||||
|
inputObj: &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "foo", Namespace: "test-ns"}},
|
||||||
|
}, {
|
||||||
|
name: "create with ResourceVersion set",
|
||||||
|
inputObj: &example.Pod{ObjectMeta: metav1.ObjectMeta{Name: "bar", Namespace: "test-ns", ResourceVersion: "1"}},
|
||||||
|
expectedError: storage.ErrResourceVersionSetOnCreate,
|
||||||
|
}}
|
||||||
|
|
||||||
// verify that kv pair is empty before set
|
for _, tt := range tests {
|
||||||
key := computePodKey(obj)
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
if err := store.Get(ctx, key, storage.GetOptions{}, out); !storage.IsNotFound(err) {
|
out := &example.Pod{} // reset
|
||||||
t.Fatalf("expecting empty result on key %s, got %v", key, err)
|
// verify that kv pair is empty before set
|
||||||
}
|
key := computePodKey(tt.inputObj)
|
||||||
|
if err := store.Get(ctx, key, storage.GetOptions{}, out); !storage.IsNotFound(err) {
|
||||||
|
t.Fatalf("expecting empty result on key %s, got %v", key, err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := store.Create(ctx, key, obj, out, 0); err != nil {
|
err := store.Create(ctx, key, tt.inputObj, out, 0)
|
||||||
t.Fatalf("Set failed: %v", err)
|
if !errors.Is(err, tt.expectedError) {
|
||||||
|
t.Errorf("expecting error %v, but get: %v", tt.expectedError, err)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// basic tests of the output
|
||||||
|
if tt.inputObj.ObjectMeta.Name != out.ObjectMeta.Name {
|
||||||
|
t.Errorf("pod name want=%s, get=%s", tt.inputObj.ObjectMeta.Name, out.ObjectMeta.Name)
|
||||||
|
}
|
||||||
|
if out.ResourceVersion == "" {
|
||||||
|
t.Errorf("output should have non-empty resource version")
|
||||||
|
}
|
||||||
|
validation(ctx, t, key)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
// basic tests of the output
|
|
||||||
if obj.ObjectMeta.Name != out.ObjectMeta.Name {
|
|
||||||
t.Errorf("pod name want=%s, get=%s", obj.ObjectMeta.Name, out.ObjectMeta.Name)
|
|
||||||
}
|
|
||||||
if out.ResourceVersion == "" {
|
|
||||||
t.Errorf("output should have non-empty resource version")
|
|
||||||
}
|
|
||||||
if out.SelfLink != "" {
|
|
||||||
t.Errorf("output should have empty selfLink")
|
|
||||||
}
|
|
||||||
|
|
||||||
validation(ctx, t, key)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func RunTestCreateWithTTL(ctx context.Context, t *testing.T, store storage.Interface) {
|
func RunTestCreateWithTTL(ctx context.Context, t *testing.T, store storage.Interface) {
|
||||||
|
Loading…
Reference in New Issue
Block a user