registry: move generic registry tester into k8s.io/apiserver
Kubernetes-commit: 0b100cb69b9f99445aa523cf9c4abae8f62c751a
This commit is contained in:
		
							parent
							
								
									bd9bc99807
								
							
						
					
					
						commit
						29de1cdd6d
					
				|  | @ -39,6 +39,7 @@ filegroup( | |||
|         ":package-srcs", | ||||
|         "//staging/src/k8s.io/apiserver/pkg/registry/generic/registry:all-srcs", | ||||
|         "//staging/src/k8s.io/apiserver/pkg/registry/generic/rest:all-srcs", | ||||
|         "//staging/src/k8s.io/apiserver/pkg/registry/generic/testing:all-srcs", | ||||
|     ], | ||||
|     tags = ["automanaged"], | ||||
| ) | ||||
|  |  | |||
|  | @ -0,0 +1,35 @@ | |||
| load("@io_bazel_rules_go//go:def.bzl", "go_library") | ||||
| 
 | ||||
| go_library( | ||||
|     name = "go_default_library", | ||||
|     srcs = ["tester.go"], | ||||
|     importpath = "k8s.io/apiserver/pkg/registry/generic/testing", | ||||
|     visibility = ["//visibility:public"], | ||||
|     deps = [ | ||||
|         "//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library", | ||||
|         "//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library", | ||||
|         "//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", | ||||
|         "//vendor/k8s.io/apimachinery/pkg/fields:go_default_library", | ||||
|         "//vendor/k8s.io/apimachinery/pkg/labels:go_default_library", | ||||
|         "//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library", | ||||
|         "//vendor/k8s.io/apiserver/pkg/endpoints/request:go_default_library", | ||||
|         "//vendor/k8s.io/apiserver/pkg/registry/generic/registry:go_default_library", | ||||
|         "//vendor/k8s.io/apiserver/pkg/registry/rest/resttest:go_default_library", | ||||
|         "//vendor/k8s.io/apiserver/pkg/storage/etcd:go_default_library", | ||||
|         "//vendor/k8s.io/apiserver/pkg/storage/testing:go_default_library", | ||||
|     ], | ||||
| ) | ||||
| 
 | ||||
| filegroup( | ||||
|     name = "package-srcs", | ||||
|     srcs = glob(["**"]), | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:private"], | ||||
| ) | ||||
| 
 | ||||
| filegroup( | ||||
|     name = "all-srcs", | ||||
|     srcs = [":package-srcs"], | ||||
|     tags = ["automanaged"], | ||||
|     visibility = ["//visibility:public"], | ||||
| ) | ||||
|  | @ -0,0 +1,202 @@ | |||
| /* | ||||
| Copyright 2015 The Kubernetes Authors. | ||||
| 
 | ||||
| Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| you may not use this file except in compliance with the License. | ||||
| You may obtain a copy of the License at | ||||
| 
 | ||||
|     http://www.apache.org/licenses/LICENSE-2.0
 | ||||
| 
 | ||||
| Unless required by applicable law or agreed to in writing, software | ||||
| distributed under the License is distributed on an "AS IS" BASIS, | ||||
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| See the License for the specific language governing permissions and | ||||
| limitations under the License. | ||||
| */ | ||||
| 
 | ||||
| package tester | ||||
| 
 | ||||
| import ( | ||||
| 	"fmt" | ||||
| 	"testing" | ||||
| 
 | ||||
| 	"k8s.io/apimachinery/pkg/api/errors" | ||||
| 	"k8s.io/apimachinery/pkg/api/meta" | ||||
| 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||||
| 	"k8s.io/apimachinery/pkg/fields" | ||||
| 	"k8s.io/apimachinery/pkg/labels" | ||||
| 	"k8s.io/apimachinery/pkg/runtime" | ||||
| 	genericapirequest "k8s.io/apiserver/pkg/endpoints/request" | ||||
| 	genericregistry "k8s.io/apiserver/pkg/registry/generic/registry" | ||||
| 	"k8s.io/apiserver/pkg/registry/rest/resttest" | ||||
| 	etcdstorage "k8s.io/apiserver/pkg/storage/etcd" | ||||
| 	storagetesting "k8s.io/apiserver/pkg/storage/testing" | ||||
| ) | ||||
| 
 | ||||
| type Tester struct { | ||||
| 	tester  *resttest.Tester | ||||
| 	storage *genericregistry.Store | ||||
| } | ||||
| type UpdateFunc func(runtime.Object) runtime.Object | ||||
| 
 | ||||
| func New(t *testing.T, storage *genericregistry.Store, scheme *runtime.Scheme) *Tester { | ||||
| 	return &Tester{ | ||||
| 		tester:  resttest.New(t, storage, scheme), | ||||
| 		storage: storage, | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestNamespace() string { | ||||
| 	return t.tester.TestNamespace() | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) ClusterScope() *Tester { | ||||
| 	t.tester = t.tester.ClusterScope() | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) Namer(namer func(int) string) *Tester { | ||||
| 	t.tester = t.tester.Namer(namer) | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) AllowCreateOnUpdate() *Tester { | ||||
| 	t.tester = t.tester.AllowCreateOnUpdate() | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) GeneratesName() *Tester { | ||||
| 	t.tester = t.tester.GeneratesName() | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) ReturnDeletedObject() *Tester { | ||||
| 	t.tester = t.tester.ReturnDeletedObject() | ||||
| 	return t | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) { | ||||
| 	t.tester.TestCreate( | ||||
| 		valid, | ||||
| 		t.createObject, | ||||
| 		t.getObject, | ||||
| 		invalid..., | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestUpdate(valid runtime.Object, validUpdateFunc UpdateFunc, invalidUpdateFunc ...UpdateFunc) { | ||||
| 	var invalidFuncs []resttest.UpdateFunc | ||||
| 	for _, f := range invalidUpdateFunc { | ||||
| 		invalidFuncs = append(invalidFuncs, resttest.UpdateFunc(f)) | ||||
| 	} | ||||
| 	t.tester.TestUpdate( | ||||
| 		valid, | ||||
| 		t.createObject, | ||||
| 		t.getObject, | ||||
| 		resttest.UpdateFunc(validUpdateFunc), | ||||
| 		invalidFuncs..., | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestDelete(valid runtime.Object) { | ||||
| 	t.tester.TestDelete( | ||||
| 		valid, | ||||
| 		t.createObject, | ||||
| 		t.getObject, | ||||
| 		errors.IsNotFound, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestDeleteGraceful(valid runtime.Object, expectedGrace int64) { | ||||
| 	t.tester.TestDeleteGraceful( | ||||
| 		valid, | ||||
| 		t.createObject, | ||||
| 		t.getObject, | ||||
| 		expectedGrace, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestGet(valid runtime.Object) { | ||||
| 	t.tester.TestGet(valid) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestList(valid runtime.Object) { | ||||
| 	t.tester.TestList( | ||||
| 		valid, | ||||
| 		t.setObjectsForList, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) TestWatch(valid runtime.Object, labelsPass, labelsFail []labels.Set, fieldsPass, fieldsFail []fields.Set) { | ||||
| 	t.tester.TestWatch( | ||||
| 		valid, | ||||
| 		t.emitObject, | ||||
| 		labelsPass, | ||||
| 		labelsFail, | ||||
| 		fieldsPass, | ||||
| 		fieldsFail, | ||||
| 		// TODO: This should be filtered, the registry should not be aware of this level of detail
 | ||||
| 		[]string{etcdstorage.EtcdCreate, etcdstorage.EtcdDelete}, | ||||
| 	) | ||||
| } | ||||
| 
 | ||||
| // Helper functions
 | ||||
| 
 | ||||
| func (t *Tester) getObject(ctx genericapirequest.Context, obj runtime.Object) (runtime.Object, error) { | ||||
| 	accessor, err := meta.Accessor(obj) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 
 | ||||
| 	result, err := t.storage.Get(ctx, accessor.GetName(), &metav1.GetOptions{}) | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| 	} | ||||
| 	return result, nil | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) createObject(ctx genericapirequest.Context, obj runtime.Object) error { | ||||
| 	accessor, err := meta.Accessor(obj) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	key, err := t.storage.KeyFunc(ctx, accessor.GetName()) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return t.storage.Storage.Create(ctx, key, obj, nil, 0) | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) setObjectsForList(objects []runtime.Object) []runtime.Object { | ||||
| 	key := t.storage.KeyRootFunc(t.tester.TestContext()) | ||||
| 	if _, err := t.storage.DeleteCollection(t.tester.TestContext(), nil, nil); err != nil { | ||||
| 		t.tester.Errorf("unable to clear collection: %v", err) | ||||
| 		return nil | ||||
| 	} | ||||
| 	if err := storagetesting.CreateObjList(key, t.storage.Storage, objects); err != nil { | ||||
| 		t.tester.Errorf("unexpected error: %v", err) | ||||
| 		return nil | ||||
| 	} | ||||
| 	return objects | ||||
| } | ||||
| 
 | ||||
| func (t *Tester) emitObject(obj runtime.Object, action string) error { | ||||
| 	ctx := t.tester.TestContext() | ||||
| 	var err error | ||||
| 
 | ||||
| 	switch action { | ||||
| 	case etcdstorage.EtcdCreate: | ||||
| 		err = t.createObject(ctx, obj) | ||||
| 	case etcdstorage.EtcdDelete: | ||||
| 		var accessor metav1.Object | ||||
| 		accessor, err = meta.Accessor(obj) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 		_, _, err = t.storage.Delete(ctx, accessor.GetName(), nil) | ||||
| 	default: | ||||
| 		err = fmt.Errorf("unexpected action: %v", action) | ||||
| 	} | ||||
| 
 | ||||
| 	return err | ||||
| } | ||||
		Loading…
	
		Reference in New Issue