mirror of https://github.com/k3s-io/k3s
Merge pull request #13092 from wojtek-t/refactor_etcd_create_test
Refactoring of create etcd tests.pull/6/head
commit
d14654589a
|
@ -36,9 +36,10 @@ import (
|
|||
|
||||
type Tester struct {
|
||||
*testing.T
|
||||
storage rest.Storage
|
||||
storageError injectErrorFunc
|
||||
clusterScope bool
|
||||
storage rest.Storage
|
||||
storageError injectErrorFunc
|
||||
clusterScope bool
|
||||
generatesName bool
|
||||
}
|
||||
|
||||
type injectErrorFunc func(err error)
|
||||
|
@ -62,6 +63,11 @@ func (t *Tester) ClusterScope() *Tester {
|
|||
return t
|
||||
}
|
||||
|
||||
func (t *Tester) GeneratesName() *Tester {
|
||||
t.generatesName = true
|
||||
return t
|
||||
}
|
||||
|
||||
// TestNamespace returns the namespace that will be used when creating contexts.
|
||||
// Returns NamespaceNone for cluster-scoped objects.
|
||||
func (t *Tester) TestNamespace() string {
|
||||
|
@ -96,14 +102,20 @@ func copyOrDie(obj runtime.Object) runtime.Object {
|
|||
return out
|
||||
}
|
||||
|
||||
type AssignFunc func(objs []runtime.Object) []runtime.Object
|
||||
type SetRVFunc func(resourceVersion uint64)
|
||||
type AssignFunc func([]runtime.Object) []runtime.Object
|
||||
type GetFunc func(api.Context, runtime.Object) (runtime.Object, error)
|
||||
type SetFunc func(api.Context, runtime.Object) error
|
||||
type SetRVFunc func(uint64)
|
||||
|
||||
// Test creating an object.
|
||||
func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) {
|
||||
func (t *Tester) TestCreate(valid runtime.Object, setFn SetFunc, getFn GetFunc, invalid ...runtime.Object) {
|
||||
t.testCreateHasMetadata(copyOrDie(valid))
|
||||
t.testCreateGeneratesName(copyOrDie(valid))
|
||||
t.testCreateGeneratesNameReturnsServerTimeout(copyOrDie(valid))
|
||||
if !t.generatesName {
|
||||
t.testCreateGeneratesName(copyOrDie(valid))
|
||||
t.testCreateGeneratesNameReturnsServerTimeout(copyOrDie(valid))
|
||||
}
|
||||
t.testCreateEquals(copyOrDie(valid), getFn)
|
||||
t.testCreateAlreadyExisting(copyOrDie(valid), setFn)
|
||||
if t.clusterScope {
|
||||
t.testCreateDiscardsObjectNamespace(copyOrDie(valid))
|
||||
t.testCreateIgnoresContextNamespace(copyOrDie(valid))
|
||||
|
@ -161,6 +173,53 @@ func (t *Tester) TestList(obj runtime.Object, assignFn AssignFunc, setRVFn SetRV
|
|||
// =============================================================================
|
||||
// Creation tests.
|
||||
|
||||
func (t *Tester) testCreateAlreadyExisting(obj runtime.Object, setFn SetFunc) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
fooMeta := t.getObjectMetaOrFail(foo)
|
||||
fooMeta.Name = "foo1"
|
||||
fooMeta.Namespace = api.NamespaceValue(ctx)
|
||||
fooMeta.GenerateName = ""
|
||||
if err := setFn(ctx, foo); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
_, err := t.storage.(rest.Creater).Create(ctx, foo)
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
t.Errorf("expected already exists err, got %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) testCreateEquals(obj runtime.Object, getFn GetFunc) {
|
||||
ctx := t.TestContext()
|
||||
|
||||
foo := copyOrDie(obj)
|
||||
fooMeta := t.getObjectMetaOrFail(foo)
|
||||
fooMeta.Name = "foo2"
|
||||
fooMeta.Namespace = api.NamespaceValue(ctx)
|
||||
fooMeta.GenerateName = ""
|
||||
|
||||
created, err := t.storage.(rest.Creater).Create(ctx, foo)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
got, err := getFn(ctx, foo)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
// Set resource version which might be unset in created object.
|
||||
createdMeta := t.getObjectMetaOrFail(created)
|
||||
gotMeta := t.getObjectMetaOrFail(got)
|
||||
createdMeta.ResourceVersion = gotMeta.ResourceVersion
|
||||
|
||||
if e, a := created, got; !api.Semantic.DeepEqual(e, a) {
|
||||
t.Errorf("unexpected obj: %#v, expected %#v", e, a)
|
||||
}
|
||||
}
|
||||
|
||||
func (t *Tester) testCreateDiscardsObjectNamespace(valid runtime.Object) {
|
||||
objectMeta := t.getObjectMetaOrFail(valid)
|
||||
|
||||
|
|
|
@ -18,7 +18,6 @@ package etcd
|
|||
|
||||
import (
|
||||
"strconv"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -87,102 +86,33 @@ var validController = api.ReplicationController{
|
|||
Spec: validControllerSpec,
|
||||
}
|
||||
|
||||
func TestEtcdCreateController(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
_, err := storage.Create(ctx, &validController)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
key, _ := storage.KeyFunc(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
resp, err := fakeClient.Get(key, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
var ctrl api.ReplicationController
|
||||
err = testapi.Codec().DecodeInto([]byte(resp.Node.Value), &ctrl)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if ctrl.Name != "foo" {
|
||||
t.Errorf("Unexpected controller: %#v %s", ctrl, resp.Node.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, _ := storage.KeyFunc(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0)
|
||||
|
||||
_, err := storage.Create(ctx, &validController)
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
t.Errorf("expected already exists err, got %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateControllerValidates(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _ := newStorage(t)
|
||||
emptyName := validController
|
||||
emptyName.Name = ""
|
||||
failureCases := []api.ReplicationController{emptyName}
|
||||
for _, failureCase := range failureCases {
|
||||
c, err := storage.Create(ctx, &failureCase)
|
||||
if c != nil {
|
||||
t.Errorf("Expected nil channel")
|
||||
}
|
||||
if !errors.IsInvalid(err) {
|
||||
t.Errorf("Expected to get an invalid resource error, got %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateControllerWithGeneratedName(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
controller := &api.ReplicationController{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
GenerateName: "rc-",
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.ReplicationController{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
}
|
||||
|
||||
ctx := api.NewDefaultContext()
|
||||
_, err := storage.Create(ctx, controller)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if controller.Name == "rc-" || !strings.HasPrefix(controller.Name, "rc-") {
|
||||
t.Errorf("unexpected name: %#v", controller)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateControllerWithConflictingNamespace(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
controller := &api.ReplicationController{
|
||||
ObjectMeta: api.ObjectMeta{Name: "test", Namespace: "not-default"},
|
||||
}
|
||||
|
||||
ctx := api.NewDefaultContext()
|
||||
channel, err := storage.Create(ctx, controller)
|
||||
if channel != nil {
|
||||
t.Error("Expected a nil channel, but we got a value")
|
||||
}
|
||||
errSubString := "namespace"
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, but we didn't get one")
|
||||
} else if !errors.IsBadRequest(err) ||
|
||||
strings.Index(err.Error(), errSubString) == -1 {
|
||||
t.Errorf("Expected a Bad Request error with the sub string '%s', got %v", errSubString, err)
|
||||
}
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.ReplicationController{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestEtcdControllerValidatesUpdate(t *testing.T) {
|
||||
|
@ -553,29 +483,6 @@ func TestEtcdWatchControllersNotMatch(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.ReplicationController{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
// invalid
|
||||
&api.ReplicationController{
|
||||
Spec: api.ReplicationControllerSpec{
|
||||
Replicas: 2,
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
|
|
|
@ -17,7 +17,6 @@ limitations under the License.
|
|||
package etcd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -29,8 +28,8 @@ import (
|
|||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/storage"
|
||||
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
|
@ -41,18 +40,9 @@ const (
|
|||
FAIL
|
||||
)
|
||||
|
||||
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
|
||||
fakeEtcdClient := tools.NewFakeEtcdClient(t)
|
||||
fakeEtcdClient.TestIndex = true
|
||||
helper := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
|
||||
return fakeEtcdClient, helper
|
||||
}
|
||||
|
||||
// newStorage creates a REST storage backed by etcd helpers
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
fakeEtcdClient, h := newEtcdStorage(t)
|
||||
storage := NewREST(h)
|
||||
return storage, fakeEtcdClient
|
||||
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
|
||||
return NewREST(etcdStorage), fakeClient
|
||||
}
|
||||
|
||||
// createController is a helper function that returns a controller with the updated resource version.
|
||||
|
@ -95,6 +85,33 @@ var validController = api.Daemon{
|
|||
Spec: validControllerSpec,
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.Daemon{
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Daemon{
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
// makeControllerKey constructs etcd paths to controller items enforcing namespace rules.
|
||||
func makeControllerKey(ctx api.Context, id string) (string, error) {
|
||||
return etcdgeneric.NamespaceKeyFunc(ctx, daemonPrefix, id)
|
||||
|
@ -106,103 +123,6 @@ func makeControllerListKey(ctx api.Context) string {
|
|||
return etcdgeneric.NamespaceKeyRootFunc(ctx, daemonPrefix)
|
||||
}
|
||||
|
||||
func TestEtcdCreateController(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
_, err := storage.Create(ctx, &validController)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
key, _ := makeControllerKey(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
resp, err := fakeClient.Get(key, false, false)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error %v", err)
|
||||
}
|
||||
var ctrl api.Daemon
|
||||
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &ctrl)
|
||||
if err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
|
||||
if ctrl.Name != "foo" {
|
||||
t.Errorf("Unexpected controller: %#v %s", ctrl, resp.Node.Value)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
key, _ := makeControllerKey(ctx, validController.Name)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0)
|
||||
|
||||
_, err := storage.Create(ctx, &validController)
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
t.Errorf("expected already exists err, got %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateControllerValidates(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, _ := newStorage(t)
|
||||
emptyName := validController
|
||||
emptyName.Name = ""
|
||||
failureCases := []api.Daemon{emptyName}
|
||||
for _, failureCase := range failureCases {
|
||||
c, err := storage.Create(ctx, &failureCase)
|
||||
if c != nil {
|
||||
t.Errorf("Expected nil channel")
|
||||
}
|
||||
if !errors.IsInvalid(err) {
|
||||
t.Errorf("Expected to get an invalid resource error, got %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateControllerWithGeneratedName(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
controller := &api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Namespace: api.NamespaceDefault,
|
||||
GenerateName: "daemon-",
|
||||
},
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
}
|
||||
|
||||
ctx := api.NewDefaultContext()
|
||||
_, err := storage.Create(ctx, controller)
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if controller.Name == "daemon-" || !strings.HasPrefix(controller.Name, "daemon-") {
|
||||
t.Errorf("unexpected name: %#v", controller)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreateControllerWithConflictingNamespace(t *testing.T) {
|
||||
storage, _ := newStorage(t)
|
||||
controller := &api.Daemon{
|
||||
ObjectMeta: api.ObjectMeta{Name: "test", Namespace: "not-default"},
|
||||
}
|
||||
|
||||
ctx := api.NewDefaultContext()
|
||||
channel, err := storage.Create(ctx, controller)
|
||||
if channel != nil {
|
||||
t.Error("Expected a nil channel, but we got a value")
|
||||
}
|
||||
errSubString := "namespace"
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, but we didn't get one")
|
||||
} else if !errors.IsBadRequest(err) ||
|
||||
strings.Index(err.Error(), errSubString) == -1 {
|
||||
t.Errorf("Expected a Bad Request error with the sub string '%s', got %v", errSubString, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdGetController(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
|
@ -653,27 +573,6 @@ func TestEtcdWatchControllersNotMatch(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.Daemon{
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: map[string]string{"a": "b"},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
// invalid
|
||||
&api.Daemon{
|
||||
Spec: api.DaemonSpec{
|
||||
Selector: map[string]string{},
|
||||
Template: &validPodTemplate.Template,
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeClient := newStorage(t)
|
||||
|
|
|
@ -67,6 +67,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
endpoints,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Endpoints{
|
||||
ObjectMeta: api.ObjectMeta{Name: "_-a123-a_"},
|
||||
|
|
|
@ -64,6 +64,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
autoscaler,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&expapi.HorizontalPodAutoscaler{},
|
||||
)
|
||||
|
|
|
@ -17,21 +17,14 @@ limitations under the License.
|
|||
package etcd
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
|
@ -39,11 +32,11 @@ func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
|||
return NewREST(etcdStorage), fakeClient
|
||||
}
|
||||
|
||||
func TestLimitRangeCreate(t *testing.T) {
|
||||
limitRange := &api.LimitRange{
|
||||
func validNewLimitRange() *api.LimitRange {
|
||||
return &api.LimitRange{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: "default",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: api.LimitRangeSpec{
|
||||
Limits: []api.LimitRangeItem{
|
||||
|
@ -61,72 +54,25 @@ func TestLimitRangeCreate(t *testing.T) {
|
|||
},
|
||||
},
|
||||
}
|
||||
|
||||
nodeWithLimitRange := tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), limitRange),
|
||||
ModifiedIndex: 1,
|
||||
CreatedIndex: 1,
|
||||
},
|
||||
},
|
||||
E: nil,
|
||||
}
|
||||
|
||||
emptyNode := tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{},
|
||||
E: tools.EtcdErrorNotFound,
|
||||
}
|
||||
|
||||
ctx := api.NewDefaultContext()
|
||||
key := "foo"
|
||||
prefix := etcdtest.AddPrefix("limitranges")
|
||||
|
||||
path, err := etcdgeneric.NamespaceKeyFunc(ctx, prefix, key)
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error: %v", err)
|
||||
}
|
||||
|
||||
table := map[string]struct {
|
||||
existing tools.EtcdResponseWithError
|
||||
expect tools.EtcdResponseWithError
|
||||
toCreate runtime.Object
|
||||
errOK func(error) bool
|
||||
}{
|
||||
"normal": {
|
||||
existing: emptyNode,
|
||||
expect: nodeWithLimitRange,
|
||||
toCreate: limitRange,
|
||||
errOK: func(err error) bool { return err == nil },
|
||||
},
|
||||
"preExisting": {
|
||||
existing: nodeWithLimitRange,
|
||||
expect: nodeWithLimitRange,
|
||||
toCreate: limitRange,
|
||||
errOK: errors.IsAlreadyExists,
|
||||
},
|
||||
}
|
||||
|
||||
for name, item := range table {
|
||||
storage, fakeClient := newStorage(t)
|
||||
fakeClient.Data[path] = item.existing
|
||||
_, err := storage.Create(ctx, item.toCreate)
|
||||
if !item.errOK(err) {
|
||||
t.Errorf("%v: unexpected error: %v", name, err)
|
||||
}
|
||||
|
||||
received := fakeClient.Data[path]
|
||||
var limitRange api.LimitRange
|
||||
if err := testapi.Codec().DecodeInto([]byte(received.R.Node.Value), &limitRange); err != nil {
|
||||
t.Errorf("unexpected error: %v", err)
|
||||
}
|
||||
// Unset CreationTimestamp and UID which are set automatically by infrastructure.
|
||||
limitRange.ObjectMeta.CreationTimestamp = util.Time{}
|
||||
limitRange.ObjectMeta.UID = ""
|
||||
received.R.Node.Value = runtime.EncodeOrDie(testapi.Codec(), &limitRange)
|
||||
|
||||
if e, a := item.expect, received; !reflect.DeepEqual(e, a) {
|
||||
t.Errorf("%v:\n%s", name, util.ObjectDiff(e, a))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError).GeneratesName()
|
||||
validLimitRange := validNewLimitRange()
|
||||
validLimitRange.ObjectMeta = api.ObjectMeta{}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
validLimitRange,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.LimitRange{
|
||||
ObjectMeta: api.ObjectMeta{Name: "_-a123-a_"},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -82,6 +82,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
node,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Node{
|
||||
ObjectMeta: api.ObjectMeta{Name: "_-a123-a_"},
|
||||
|
|
|
@ -68,6 +68,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
namespace,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Namespace{
|
||||
ObjectMeta: api.ObjectMeta{Name: "bad value"},
|
||||
|
|
|
@ -76,6 +76,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
pv,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.PersistentVolume{
|
||||
ObjectMeta: api.ObjectMeta{Name: "*BadName!"},
|
||||
|
|
|
@ -73,6 +73,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
pv,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.PersistentVolumeClaim{
|
||||
ObjectMeta: api.ObjectMeta{Name: "*BadName!"},
|
||||
|
|
|
@ -101,6 +101,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
pod,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid (empty contains list)
|
||||
&api.Pod{
|
||||
Spec: api.PodSpec{
|
||||
|
@ -494,25 +500,6 @@ func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateAlreadyExisting(t *testing.T) {
|
||||
storage, _, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
key, _ := storage.KeyFunc(ctx, "foo")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}),
|
||||
},
|
||||
},
|
||||
E: nil,
|
||||
}
|
||||
_, err := storage.Create(ctx, validNewPod())
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
t.Errorf("Unexpected error returned: %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateWithContainersNotFound(t *testing.T) {
|
||||
storage, bindingStorage, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
)
|
||||
|
@ -66,6 +67,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
pod,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.PodTemplate{
|
||||
Template: api.PodTemplateSpec{},
|
||||
|
|
|
@ -21,6 +21,7 @@ import (
|
|||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/storage"
|
||||
|
@ -36,8 +37,42 @@ func NewEtcdStorage(t *testing.T) (storage.Interface, *tools.FakeEtcdClient) {
|
|||
return etcdStorage, fakeClient
|
||||
}
|
||||
|
||||
func SetResourceVersion(fakeClient *tools.FakeEtcdClient, resourceVersion uint64) {
|
||||
fakeClient.ChangeIndex = resourceVersion
|
||||
type keyFunc func(api.Context, string) (string, error)
|
||||
type newFunc func() runtime.Object
|
||||
|
||||
func GetObject(fakeClient *tools.FakeEtcdClient, keyFn keyFunc, newFn newFunc, ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
meta, err := api.ObjectMetaFor(obj)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key, err := keyFn(ctx, meta.Name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key = etcdtest.AddPrefix(key)
|
||||
resp, err := fakeClient.Get(key, false, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result := newFn()
|
||||
if err := testapi.Codec().DecodeInto([]byte(resp.Node.Value), result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func SetObject(fakeClient *tools.FakeEtcdClient, keyFn keyFunc, ctx api.Context, obj runtime.Object) error {
|
||||
meta, err := api.ObjectMetaFor(obj)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key, err := keyFn(ctx, meta.Name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
key = etcdtest.AddPrefix(key)
|
||||
_, err = fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), obj), 0)
|
||||
return err
|
||||
}
|
||||
|
||||
func SetObjectsForKey(fakeClient *tools.FakeEtcdClient, key string, objects []runtime.Object) []runtime.Object {
|
||||
|
@ -66,3 +101,7 @@ func SetObjectsForKey(fakeClient *tools.FakeEtcdClient, key string, objects []ru
|
|||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func SetResourceVersion(fakeClient *tools.FakeEtcdClient, resourceVersion uint64) {
|
||||
fakeClient.ChangeIndex = resourceVersion
|
||||
}
|
||||
|
|
|
@ -18,12 +18,10 @@ package etcd
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/resource"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/api/testapi"
|
||||
|
@ -86,6 +84,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
resourcequota,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.ResourceQuota{
|
||||
ObjectMeta: api.ObjectMeta{Name: "_-a123-a_"},
|
||||
|
@ -202,36 +206,6 @@ func TestEtcdList(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
|
||||
storage, _, _ := newStorage(t)
|
||||
resourcequota := validNewResourceQuota()
|
||||
resourcequota.Namespace = ""
|
||||
_, err := storage.Create(api.NewContext(), resourcequota)
|
||||
// Accept "namespace" or "Namespace".
|
||||
if err == nil || !strings.Contains(err.Error(), "amespace") {
|
||||
t.Fatalf("expected error that namespace was missing from context, got: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdCreateAlreadyExisting(t *testing.T) {
|
||||
storage, _, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
key, _ := storage.KeyFunc(ctx, "foo")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "foo"}}),
|
||||
},
|
||||
},
|
||||
E: nil,
|
||||
}
|
||||
_, err := storage.Create(ctx, validNewResourceQuota())
|
||||
if !errors.IsAlreadyExists(err) {
|
||||
t.Errorf("Unexpected error returned: %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestEtcdUpdateStatus(t *testing.T) {
|
||||
storage, status, fakeClient := newStorage(t)
|
||||
ctx := api.NewDefaultContext()
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
)
|
||||
|
@ -51,6 +52,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
secret,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Secret{},
|
||||
&api.Secret{
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
Copyright 2015 The Kubernetes Authors All rights reserved.
|
||||
|
||||
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 etcd
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
|
||||
return NewREST(etcdStorage), fakeClient
|
||||
}
|
||||
|
||||
func validService() *api.Service {
|
||||
return &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{
|
||||
Name: "foo",
|
||||
Namespace: api.NamespaceDefault,
|
||||
},
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
ClusterIP: "None",
|
||||
SessionAffinity: "None",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
Ports: []api.ServicePort{{
|
||||
Port: 6502,
|
||||
Protocol: api.ProtocolTCP,
|
||||
TargetPort: util.NewIntOrStringFromInt(6502),
|
||||
}},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
validService := validService()
|
||||
validService.ObjectMeta = api.ObjectMeta{}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
validService,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.Service{
|
||||
Spec: api.ServiceSpec{},
|
||||
},
|
||||
// invalid
|
||||
&api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
ClusterIP: "invalid",
|
||||
SessionAffinity: "None",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
Ports: []api.ServicePort{{
|
||||
Port: 6502,
|
||||
Protocol: api.ProtocolTCP,
|
||||
TargetPort: util.NewIntOrStringFromInt(6502),
|
||||
}},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
|
@ -24,7 +24,6 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/errors"
|
||||
"k8s.io/kubernetes/pkg/api/rest"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
|
@ -33,6 +32,10 @@ import (
|
|||
"k8s.io/kubernetes/pkg/util"
|
||||
)
|
||||
|
||||
// TODO(wojtek-t): Cleanup this file.
|
||||
// It is now testing mostly the same things as other resources but
|
||||
// in a completely different way. We should unify it.
|
||||
|
||||
func NewTestREST(t *testing.T, endpoints *api.EndpointsList) (*REST, *registrytest.ServiceRegistry) {
|
||||
registry := registrytest.NewServiceRegistry()
|
||||
endpointRegistry := ®istrytest.EndpointRegistry{
|
||||
|
@ -741,25 +744,6 @@ func TestServiceRegistryIPLoadBalancer(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
// TODO: remove, covered by TestCreate
|
||||
func TestCreateServiceWithConflictingNamespace(t *testing.T) {
|
||||
storage := REST{}
|
||||
service := &api.Service{
|
||||
ObjectMeta: api.ObjectMeta{Name: "test", Namespace: "not-default"},
|
||||
}
|
||||
|
||||
ctx := api.NewDefaultContext()
|
||||
obj, err := storage.Create(ctx, service)
|
||||
if obj != nil {
|
||||
t.Error("Expected a nil object, but we got a value")
|
||||
}
|
||||
if err == nil {
|
||||
t.Errorf("Expected an error, but we didn't get one")
|
||||
} else if strings.Contains(err.Error(), "Service.Namespace does not match the provided context") {
|
||||
t.Errorf("Expected 'Service.Namespace does not match the provided context' error, got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestUpdateServiceWithConflictingNamespace(t *testing.T) {
|
||||
storage := REST{}
|
||||
service := &api.Service{
|
||||
|
@ -777,43 +761,3 @@ func TestUpdateServiceWithConflictingNamespace(t *testing.T) {
|
|||
t.Errorf("Expected 'Service.Namespace does not match the provided context' error, got '%s'", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
rest, registry := NewTestREST(t, nil)
|
||||
|
||||
test := resttest.New(t, rest, registry.SetError)
|
||||
test.TestCreate(
|
||||
// valid
|
||||
&api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
ClusterIP: "None",
|
||||
SessionAffinity: "None",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
Ports: []api.ServicePort{{
|
||||
Port: 6502,
|
||||
Protocol: api.ProtocolTCP,
|
||||
TargetPort: util.NewIntOrStringFromInt(6502),
|
||||
}},
|
||||
},
|
||||
},
|
||||
// invalid
|
||||
&api.Service{
|
||||
Spec: api.ServiceSpec{},
|
||||
},
|
||||
// invalid
|
||||
&api.Service{
|
||||
Spec: api.ServiceSpec{
|
||||
Selector: map[string]string{"bar": "baz"},
|
||||
ClusterIP: "invalid",
|
||||
SessionAffinity: "None",
|
||||
Type: api.ServiceTypeClusterIP,
|
||||
Ports: []api.ServicePort{{
|
||||
Port: 6502,
|
||||
Protocol: api.ProtocolTCP,
|
||||
TargetPort: util.NewIntOrStringFromInt(6502),
|
||||
}},
|
||||
},
|
||||
},
|
||||
)
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"k8s.io/kubernetes/pkg/api"
|
||||
"k8s.io/kubernetes/pkg/api/rest/resttest"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
)
|
||||
|
@ -49,6 +50,12 @@ func TestCreate(t *testing.T) {
|
|||
test.TestCreate(
|
||||
// valid
|
||||
serviceAccount,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&api.ServiceAccount{},
|
||||
&api.ServiceAccount{
|
||||
|
|
|
@ -26,29 +26,22 @@ import (
|
|||
"k8s.io/kubernetes/pkg/expapi/v1"
|
||||
"k8s.io/kubernetes/pkg/fields"
|
||||
"k8s.io/kubernetes/pkg/labels"
|
||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||
"k8s.io/kubernetes/pkg/runtime"
|
||||
"k8s.io/kubernetes/pkg/storage"
|
||||
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
|
||||
"k8s.io/kubernetes/pkg/tools"
|
||||
"k8s.io/kubernetes/pkg/tools/etcdtest"
|
||||
|
||||
"github.com/coreos/go-etcd/etcd"
|
||||
)
|
||||
|
||||
var scheme *runtime.Scheme
|
||||
var codec runtime.Codec
|
||||
|
||||
func init() {
|
||||
// Ensure that expapi/v1 packege is used, so that it will get initialized and register HorizontalPodAutoscaler object.
|
||||
_ = v1.ThirdPartyResource{}
|
||||
}
|
||||
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, storage.Interface) {
|
||||
fakeEtcdClient := tools.NewFakeEtcdClient(t)
|
||||
fakeEtcdClient.TestIndex = true
|
||||
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
|
||||
storage := NewREST(etcdStorage)
|
||||
return storage, fakeEtcdClient, etcdStorage
|
||||
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
|
||||
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
|
||||
return NewREST(etcdStorage), fakeClient
|
||||
}
|
||||
|
||||
func validNewThirdPartyResource(name string) *expapi.ThirdPartyResource {
|
||||
|
@ -66,28 +59,34 @@ func validNewThirdPartyResource(name string) *expapi.ThirdPartyResource {
|
|||
}
|
||||
|
||||
func TestCreate(t *testing.T) {
|
||||
storage, fakeEtcdClient, _ := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeEtcdClient.SetError)
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
rsrc := validNewThirdPartyResource("foo")
|
||||
rsrc.ObjectMeta = api.ObjectMeta{}
|
||||
test.TestCreate(
|
||||
// valid
|
||||
rsrc,
|
||||
func(ctx api.Context, obj runtime.Object) error {
|
||||
return registrytest.SetObject(fakeClient, storage.KeyFunc, ctx, obj)
|
||||
},
|
||||
func(ctx api.Context, obj runtime.Object) (runtime.Object, error) {
|
||||
return registrytest.GetObject(fakeClient, storage.KeyFunc, storage.NewFunc, ctx, obj)
|
||||
},
|
||||
// invalid
|
||||
&expapi.ThirdPartyResource{},
|
||||
)
|
||||
}
|
||||
|
||||
func TestUpdate(t *testing.T) {
|
||||
storage, fakeEtcdClient, _ := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeEtcdClient.SetError)
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
key, err := storage.KeyFunc(test.TestContext(), "foo")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
key = etcdtest.AddPrefix(key)
|
||||
fakeEtcdClient.ExpectNotFoundGet(key)
|
||||
fakeEtcdClient.ChangeIndex = 2
|
||||
fakeClient.ExpectNotFoundGet(key)
|
||||
fakeClient.ChangeIndex = 2
|
||||
rsrc := validNewThirdPartyResource("foo")
|
||||
existing := validNewThirdPartyResource("exists")
|
||||
existing.Namespace = test.TestNamespace()
|
||||
|
@ -106,13 +105,13 @@ func TestUpdate(t *testing.T) {
|
|||
|
||||
func TestDelete(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
storage, fakeEtcdClient, _ := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeEtcdClient.SetError)
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
rsrc := validNewThirdPartyResource("foo2")
|
||||
key, _ := storage.KeyFunc(ctx, "foo2")
|
||||
key = etcdtest.AddPrefix(key)
|
||||
createFn := func() runtime.Object {
|
||||
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
|
||||
fakeClient.Data[key] = tools.EtcdResponseWithError{
|
||||
R: &etcd.Response{
|
||||
Node: &etcd.Node{
|
||||
Value: runtime.EncodeOrDie(testapi.Codec(), rsrc),
|
||||
|
@ -123,24 +122,24 @@ func TestDelete(t *testing.T) {
|
|||
return rsrc
|
||||
}
|
||||
gracefulSetFn := func() bool {
|
||||
if fakeEtcdClient.Data[key].R.Node == nil {
|
||||
if fakeClient.Data[key].R.Node == nil {
|
||||
return false
|
||||
}
|
||||
return fakeEtcdClient.Data[key].R.Node.TTL == 30
|
||||
return fakeClient.Data[key].R.Node.TTL == 30
|
||||
}
|
||||
test.TestDeleteNoGraceful(createFn, gracefulSetFn)
|
||||
}
|
||||
|
||||
func TestGet(t *testing.T) {
|
||||
storage, fakeEtcdClient, _ := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeEtcdClient.SetError)
|
||||
storage, fakeClient := newStorage(t)
|
||||
test := resttest.New(t, storage, fakeClient.SetError)
|
||||
rsrc := validNewThirdPartyResource("foo")
|
||||
test.TestGet(rsrc)
|
||||
}
|
||||
|
||||
func TestEmptyList(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
registry, fakeClient, _ := newStorage(t)
|
||||
registry, fakeClient := newStorage(t)
|
||||
fakeClient.ChangeIndex = 1
|
||||
key := registry.KeyRootFunc(ctx)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
@ -162,7 +161,7 @@ func TestEmptyList(t *testing.T) {
|
|||
|
||||
func TestList(t *testing.T) {
|
||||
ctx := api.NewDefaultContext()
|
||||
registry, fakeClient, _ := newStorage(t)
|
||||
registry, fakeClient := newStorage(t)
|
||||
fakeClient.ChangeIndex = 1
|
||||
key := registry.KeyRootFunc(ctx)
|
||||
key = etcdtest.AddPrefix(key)
|
||||
|
|
Loading…
Reference in New Issue