Commit 2b2d6b67 authored by Wojciech Tyczynski's avatar Wojciech Tyczynski

Refactor registry tests to reduce dependency on go-etcd.

parent 57e35b79
......@@ -23,7 +23,6 @@ import (
"testing"
"time"
"github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/rest"
......@@ -544,7 +543,7 @@ func (t *Tester) testDeleteNoGraceful(obj runtime.Object, setFn SetFunc, getFn G
func (t *Tester) testDeleteNonExist(obj runtime.Object) {
objectMeta := t.getObjectMetaOrFail(obj)
t.withStorageError(&etcd.EtcdError{ErrorCode: tools.EtcdErrorCodeNotFound}, func() {
t.withStorageError(tools.EtcdErrorNotFound, func() {
_, err := t.storage.(rest.GracefulDeleter).Delete(t.TestContext(), objectMeta.Name, nil)
if err == nil || !errors.IsNotFound(err) {
t.Errorf("unexpected error: %v", err)
......
......@@ -17,20 +17,12 @@ 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/testapi"
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
"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"
)
var testTTL uint64 = 60
......@@ -41,199 +33,56 @@ func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
return NewREST(etcdStorage, testTTL), fakeClient
}
func TestEventCreate(t *testing.T) {
eventA := &api.Event{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
Reason: "forTesting",
InvolvedObject: api.ObjectReference{Name: "bar", Namespace: api.NamespaceDefault},
}
eventB := &api.Event{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
Reason: "forTesting",
InvolvedObject: api.ObjectReference{Name: "bar", Namespace: api.NamespaceDefault},
}
nodeWithEventA := tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), eventA),
ModifiedIndex: 1,
CreatedIndex: 1,
TTL: int64(testTTL),
},
func validNewEvent(namespace string) *api.Event {
return &api.Event{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Namespace: namespace,
},
E: nil,
}
emptyNode := tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
}
ctx := api.NewDefaultContext()
key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/events", key)
path = etcdtest.AddPrefix(path)
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: nodeWithEventA,
toCreate: eventA,
errOK: func(err error) bool { return err == nil },
Reason: "forTesting",
InvolvedObject: api.ObjectReference{
Name: "bar",
Namespace: namespace,
},
"preExisting": {
existing: nodeWithEventA,
expect: nodeWithEventA,
toCreate: eventB,
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)
}
// nullify fields set by infrastructure
received := fakeClient.Data[path]
var event api.Event
if err := testapi.Codec().DecodeInto([]byte(received.R.Node.Value), &event); err != nil {
t.Errorf("unexpected error: %v", err)
}
event.ObjectMeta.CreationTimestamp = util.Time{}
event.ObjectMeta.UID = ""
received.R.Node.Value = runtime.EncodeOrDie(testapi.Codec(), &event)
if e, a := item.expect, received; !reflect.DeepEqual(e, a) {
t.Errorf("%v:\n%s", name, util.ObjectDiff(e, a))
}
}
}
func TestEventUpdate(t *testing.T) {
eventA := &api.Event{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
Reason: "forTesting",
InvolvedObject: api.ObjectReference{Name: "foo", Namespace: api.NamespaceDefault},
}
eventB := &api.Event{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault},
Reason: "for testing again",
InvolvedObject: api.ObjectReference{Name: "foo", Namespace: api.NamespaceDefault},
}
eventC := &api.Event{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: api.NamespaceDefault, ResourceVersion: "1"},
Reason: "for testing again something else",
InvolvedObject: api.ObjectReference{Name: "foo", Namespace: api.NamespaceDefault},
}
nodeWithEventA := tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), eventA),
ModifiedIndex: 1,
CreatedIndex: 1,
TTL: int64(testTTL),
},
},
E: nil,
}
nodeWithEventB := tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), eventB),
ModifiedIndex: 1,
CreatedIndex: 1,
TTL: int64(testTTL),
},
},
E: nil,
}
nodeWithEventC := tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), eventC),
ModifiedIndex: 1,
CreatedIndex: 1,
TTL: int64(testTTL),
},
},
E: nil,
}
emptyNode := tools.EtcdResponseWithError{
R: &etcd.Response{},
E: tools.EtcdErrorNotFound,
}
ctx := api.NewDefaultContext()
key := "foo"
path, err := etcdgeneric.NamespaceKeyFunc(ctx, "/events", key)
path = etcdtest.AddPrefix(path)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
func TestCreate(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
event := validNewEvent(test.TestNamespace())
event.ObjectMeta = api.ObjectMeta{}
test.TestCreate(
// valid
event,
// invalid
&api.Event{},
)
}
table := map[string]struct {
existing tools.EtcdResponseWithError
expect tools.EtcdResponseWithError
toUpdate runtime.Object
errOK func(error) bool
}{
"doesNotExist": {
existing: emptyNode,
expect: nodeWithEventA,
toUpdate: eventA,
errOK: func(err error) bool { return err == nil },
func TestUpdate(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).AllowCreateOnUpdate()
test.TestUpdate(
// valid
validNewEvent(test.TestNamespace()),
// valid updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Event)
object.Reason = "forDifferentTesting"
return object
},
"doesNotExist2": {
existing: emptyNode,
expect: nodeWithEventB,
toUpdate: eventB,
errOK: func(err error) bool { return err == nil },
// invalid updateFunc
func(obj runtime.Object) runtime.Object {
object := obj.(*api.Event)
object.InvolvedObject.Namespace = "different-namespace"
return object
},
"replaceExisting": {
existing: nodeWithEventA,
expect: nodeWithEventC,
toUpdate: eventC,
errOK: func(err error) bool { return err == nil },
},
}
for name, item := range table {
storage, fakeClient := newStorage(t)
fakeClient.Data[path] = item.existing
_, _, err := storage.Update(ctx, item.toUpdate)
if !item.errOK(err) {
t.Errorf("%v: unexpected error: %v", name, err)
}
// nullify fields set by infrastructure
received := fakeClient.Data[path]
var event api.Event
if err := testapi.Codec().DecodeInto([]byte(received.R.Node.Value), &event); err != nil {
t.Errorf("unexpected error: %v", err)
}
event.ObjectMeta.CreationTimestamp = util.Time{}
event.ObjectMeta.UID = ""
received.R.Node.Value = runtime.EncodeOrDie(testapi.Codec(), &event)
)
}
if e, a := item.expect, received; !reflect.DeepEqual(e, a) {
t.Errorf("%v:\n%s", name, util.ObjectGoPrintDiff(e, a))
}
}
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewEvent(test.TestNamespace()))
}
......@@ -21,29 +21,17 @@ import (
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/expapi"
"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"
"k8s.io/kubernetes/pkg/util"
"k8s.io/kubernetes/pkg/expapi"
"github.com/coreos/go-etcd/etcd"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*RcREST, *ScaleREST, *tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(etcdStorage)
return storage.ReplicationController, storage.Scale, fakeEtcdClient, etcdStorage
func newStorage(t *testing.T) (*ScaleREST, *tools.FakeEtcdClient) {
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
return NewStorage(etcdStorage).Scale, fakeClient
}
var validPodTemplate = api.PodTemplate{
......@@ -90,43 +78,32 @@ var validScale = expapi.Scale{
}
func TestGet(t *testing.T) {
expect := &validScale
fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage, fakeClient := newStorage(t)
ctx := api.WithNamespace(api.NewContext(), "test")
key := etcdtest.AddPrefix("/controllers/test/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &validController),
ModifiedIndex: 1,
},
},
if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
storage := NewStorage(etcdStorage).Scale
obj, err := storage.Get(api.WithNamespace(api.NewContext(), "test"), "foo")
expect := &validScale
obj, err := storage.Get(ctx, "foo")
scale := obj.(*expapi.Scale)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if e, a := expect, scale; !api.Semantic.DeepEqual(e, a) {
t.Errorf("Unexpected scale: %s", util.ObjectDiff(e, a))
t.Errorf("unexpected scale: %s", util.ObjectDiff(e, a))
}
}
func TestUpdate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(etcdStorage).Scale
storage, fakeClient := newStorage(t)
ctx := api.WithNamespace(api.NewContext(), "test")
key := etcdtest.AddPrefix("/controllers/test/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &validController),
ModifiedIndex: 1,
},
},
if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
replicas := 12
update := expapi.Scale{
......@@ -136,13 +113,12 @@ func TestUpdate(t *testing.T) {
},
}
_, _, err := storage.Update(api.WithNamespace(api.NewContext(), "test"), &update)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
if _, _, err := storage.Update(ctx, &update); err != nil {
t.Fatalf("unexpected error: %v", err)
}
response, err := fakeEtcdClient.Get(key, false, false)
response, err := fakeClient.Get(key, false, false)
if err != nil {
t.Fatalf("Unexpected error: %v", err)
t.Fatalf("unexpected error: %v", err)
}
var controller api.ReplicationController
......
......@@ -28,8 +28,6 @@ import (
"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) {
......@@ -62,11 +60,11 @@ func TestCreate(t *testing.T) {
}
func TestCreateSetsFields(t *testing.T) {
storage, fakeClient := newStorage(t)
storage, _ := newStorage(t)
namespace := validNewNamespace()
ctx := api.NewContext()
_, err := storage.Create(ctx, namespace)
if err != fakeClient.Err {
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
......@@ -129,58 +127,46 @@ func TestWatch(t *testing.T) {
func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces/foo")
key := etcdtest.AddPrefix("namespaces/foo")
ctx := api.NewContext()
now := util.Now()
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &api.Namespace{
ObjectMeta: api.ObjectMeta{
Name: "foo",
DeletionTimestamp: &now,
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{api.FinalizerKubernetes},
},
Status: api.NamespaceStatus{Phase: api.NamespaceActive},
}),
ModifiedIndex: 1,
CreatedIndex: 1,
},
namespace := &api.Namespace{
ObjectMeta: api.ObjectMeta{
Name: "foo",
DeletionTimestamp: &now,
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{api.FinalizerKubernetes},
},
Status: api.NamespaceStatus{Phase: api.NamespaceActive},
}
_, err := storage.Delete(api.NewContext(), "foo", nil)
if err == nil {
t.Fatalf("expected error: %v", err)
if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), namespace), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, err := storage.Delete(ctx, "foo", nil); err == nil {
t.Errorf("unexpected error: %v", err)
}
}
func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces/foo")
key := etcdtest.AddPrefix("namespaces/foo")
ctx := api.NewContext()
now := util.Now()
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &api.Namespace{
ObjectMeta: api.ObjectMeta{
Name: "foo",
DeletionTimestamp: &now,
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{},
},
Status: api.NamespaceStatus{Phase: api.NamespaceActive},
}),
ModifiedIndex: 1,
CreatedIndex: 1,
},
namespace := &api.Namespace{
ObjectMeta: api.ObjectMeta{
Name: "foo",
DeletionTimestamp: &now,
},
Spec: api.NamespaceSpec{
Finalizers: []api.FinalizerName{},
},
Status: api.NamespaceStatus{Phase: api.NamespaceActive},
}
_, err := storage.Delete(api.NewContext(), "foo", nil)
if err != nil {
if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), namespace), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, err := storage.Delete(ctx, "foo", nil); err != nil {
t.Errorf("unexpected error: %v", err)
}
}
......@@ -34,8 +34,6 @@ import (
"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, *BindingREST, *StatusREST, *tools.FakeEtcdClient) {
......@@ -256,14 +254,10 @@ func TestResourceLocation(t *testing.T) {
ctx := api.NewDefaultContext()
for _, tc := range testCases {
storage, _, _, fakeClient := newStorage(t)
key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key, _ := storage.KeyFunc(ctx, tc.pod.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &tc.pod),
},
},
if _, err := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &tc.pod), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
redirector := rest.Redirector(storage)
......@@ -284,33 +278,6 @@ func TestResourceLocation(t *testing.T) {
}
}
func TestDeletePod(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1
ctx := api.NewDefaultContext()
key, _ := storage.Etcd.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",
Namespace: api.NamespaceDefault,
},
Spec: api.PodSpec{NodeName: "machine"},
}),
ModifiedIndex: 1,
CreatedIndex: 1,
},
},
}
_, err := storage.Delete(api.NewDefaultContext(), "foo", nil)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
}
func TestGet(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
......@@ -351,12 +318,7 @@ func TestEtcdCreate(t *testing.T) {
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
fakeClient.ExpectNotFoundGet(key)
_, err := storage.Create(ctx, validNewPod())
if err != nil {
t.Fatalf("unexpected error: %v", err)
......@@ -395,12 +357,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) {
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
fakeClient.ExpectNotFoundGet(key)
// Assume that a pod has undergone the following:
// - Create (apiserver)
// - Schedule (scheduler)
......@@ -443,12 +400,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
fakeClient.ExpectNotFoundGet(key)
_, err := storage.Create(ctx, validNewPod())
if err != nil {
t.Fatalf("unexpected error: %v", err)
......@@ -490,12 +442,7 @@ func TestEtcdCreateWithConflict(t *testing.T) {
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
fakeClient.ExpectNotFoundGet(key)
_, err := storage.Create(ctx, validNewPod())
if err != nil {
......@@ -528,12 +475,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
fakeClient.ExpectNotFoundGet(key)
_, err := storage.Create(ctx, validNewPod())
if err != nil {
t.Fatalf("unexpected error: %v", err)
......@@ -564,9 +506,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
}
func TestEtcdCreateBinding(t *testing.T) {
storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
testCases := map[string]struct {
binding api.Binding
......@@ -609,14 +549,11 @@ func TestEtcdCreateBinding(t *testing.T) {
},
}
for k, test := range testCases {
storage, bindingStorage, _, fakeClient := newStorage(t)
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: nil,
},
E: tools.EtcdErrorNotFound,
}
fakeClient.ExpectNotFoundGet(key)
if _, err := storage.Create(ctx, validNewPod()); err != nil {
t.Fatalf("%s: unexpected error: %v", k, err)
}
......
......@@ -20,32 +20,26 @@ import (
"strings"
"testing"
"github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/registry/service/allocator"
"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"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*Etcd, allocator.Interface, *tools.FakeEtcdClient) {
fakeEtcdClient, s := newEtcdStorage(t)
func newStorage(t *testing.T) (*Etcd, *tools.FakeEtcdClient, allocator.Interface) {
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
mem := allocator.NewAllocationMap(100, "rangeSpecValue")
etcd := NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", s)
etcd := NewEtcd(mem, "/ranges/serviceips", "serviceipallocation", etcdStorage)
return etcd, fakeClient, mem
}
return etcd, mem, fakeEtcdClient
func validNewRangeAllocation() *api.RangeAllocation {
return &api.RangeAllocation{
Range: "rangeSpecValue",
}
}
func key() string {
......@@ -54,31 +48,18 @@ func key() string {
}
func TestEmpty(t *testing.T) {
storage, _, ecli := newStorage(t)
ecli.ExpectNotFoundGet(key())
storage, fakeClient, _ := newStorage(t)
fakeClient.ExpectNotFoundGet(key())
if _, err := storage.Allocate(1); !strings.Contains(err.Error(), "cannot allocate resources of type serviceipallocation at this time") {
t.Fatal(err)
}
}
func initialObject(ecli *tools.FakeEtcdClient) {
ecli.Data[key()] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
CreatedIndex: 1,
ModifiedIndex: 2,
Value: runtime.EncodeOrDie(testapi.Codec(), &api.RangeAllocation{
Range: "rangeSpecValue",
}),
},
},
E: nil,
}
}
func TestStore(t *testing.T) {
storage, backing, ecli := newStorage(t)
initialObject(ecli)
storage, fakeClient, backing := newStorage(t)
if _, err := fakeClient.Set(key(), runtime.EncodeOrDie(testapi.Codec(), validNewRangeAllocation()), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if _, err := storage.Allocate(2); err != nil {
t.Fatal(err)
......@@ -94,7 +75,7 @@ func TestStore(t *testing.T) {
t.Fatal("Expected allocation to fail")
}
obj := ecli.Data[key()]
obj := fakeClient.Data[key()]
if obj.R == nil || obj.R.Node == nil {
t.Fatalf("%s is empty: %#v", key(), obj)
}
......@@ -106,7 +87,7 @@ func TestStore(t *testing.T) {
if err := storage.storage.Get(key(), allocation, false); err != nil {
t.Fatal(err)
}
if allocation.ResourceVersion != "1" {
if allocation.ResourceVersion != "2" {
t.Fatalf("%#v", allocation)
}
if allocation.Range != "rangeSpecValue" {
......
......@@ -21,29 +21,19 @@ import (
"strings"
"testing"
"github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/registry/service/allocator"
allocator_etcd "k8s.io/kubernetes/pkg/registry/service/allocator/etcd"
"k8s.io/kubernetes/pkg/registry/service/ipallocator"
"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"
)
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (ipallocator.Interface, allocator.Interface, *tools.FakeEtcdClient) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t)
func newStorage(t *testing.T) (*tools.FakeEtcdClient, ipallocator.Interface, allocator.Interface) {
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
_, cidr, err := net.ParseCIDR("192.168.1.0/24")
if err != nil {
t.Fatal(err)
......@@ -57,7 +47,14 @@ func newStorage(t *testing.T) (ipallocator.Interface, allocator.Interface, *tool
return etcd
})
return storage, backing, fakeEtcdClient
return fakeClient, storage, backing
}
func validNewRangeAllocation() *api.RangeAllocation {
_, cidr, _ := net.ParseCIDR("192.168.1.0/24")
return &api.RangeAllocation{
Range: cidr.String(),
}
}
func key() string {
......@@ -66,44 +63,30 @@ func key() string {
}
func TestEmpty(t *testing.T) {
storage, _, ecli := newStorage(t)
ecli.ExpectNotFoundGet(key())
fakeClient, storage, _ := newStorage(t)
fakeClient.ExpectNotFoundGet(key())
if err := storage.Allocate(net.ParseIP("192.168.1.2")); !strings.Contains(err.Error(), "cannot allocate resources of type serviceipallocation at this time") {
t.Fatal(err)
}
}
func TestErrors(t *testing.T) {
storage, _, _ := newStorage(t)
_, storage, _ := newStorage(t)
if err := storage.Allocate(net.ParseIP("192.168.0.0")); err != ipallocator.ErrNotInRange {
t.Fatal(err)
}
}
func initialObject(ecli *tools.FakeEtcdClient) {
_, cidr, _ := net.ParseCIDR("192.168.1.0/24")
ecli.Data[key()] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
CreatedIndex: 1,
ModifiedIndex: 2,
Value: runtime.EncodeOrDie(testapi.Codec(), &api.RangeAllocation{
Range: cidr.String(),
}),
},
},
E: nil,
}
}
func TestStore(t *testing.T) {
storage, r, ecli := newStorage(t)
initialObject(ecli)
fakeClient, storage, backing := newStorage(t)
if _, err := fakeClient.Set(key(), runtime.EncodeOrDie(testapi.Codec(), validNewRangeAllocation()), 0); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if err := storage.Allocate(net.ParseIP("192.168.1.2")); err != nil {
t.Fatal(err)
}
ok, err := r.Allocate(1)
ok, err := backing.Allocate(1)
if err != nil {
t.Fatal(err)
}
......@@ -114,7 +97,7 @@ func TestStore(t *testing.T) {
t.Fatal(err)
}
obj := ecli.Data[key()]
obj := fakeClient.Data[key()]
if obj.R == nil || obj.R.Node == nil {
t.Fatalf("%s is empty: %#v", key(), obj)
}
......
......@@ -20,36 +20,19 @@ import (
"testing"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/expapi"
"k8s.io/kubernetes/pkg/expapi/v1"
// Ensure that expapi/v1 package is initialized.
_ "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.ThirdPartyResourceData{}
}
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, "foo", "bar")
return storage, fakeEtcdClient, etcdStorage
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
return NewREST(etcdStorage, "foo", "bar"), fakeClient
}
func validNewThirdPartyResourceData(name string) *expapi.ThirdPartyResourceData {
......@@ -63,8 +46,8 @@ func validNewThirdPartyResourceData(name string) *expapi.ThirdPartyResourceData
}
func TestCreate(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t)
test := registrytest.New(t, fakeEtcdClient, storage.Etcd)
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
rsrc := validNewThirdPartyResourceData("foo")
rsrc.ObjectMeta = api.ObjectMeta{}
test.TestCreate(
......@@ -76,7 +59,7 @@ func TestCreate(t *testing.T) {
}
func TestUpdate(t *testing.T) {
storage, fakeClient, _ := newStorage(t)
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestUpdate(
// valid
......@@ -90,75 +73,41 @@ func TestUpdate(t *testing.T) {
)
}
func TestGet(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
rsrc := validNewThirdPartyResourceData("foo")
test.TestGet(rsrc)
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewThirdPartyResourceData("foo"))
}
func TestEmptyList(t *testing.T) {
ctx := api.NewDefaultContext()
registry, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{},
E: fakeClient.NewError(tools.EtcdErrorCodeNotFound),
}
rsrcList, err := registry.List(ctx, labels.Everything(), fields.Everything())
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(rsrcList.(*expapi.ThirdPartyResourceDataList).Items) != 0 {
t.Errorf("Unexpected non-zero autoscaler list: %#v", rsrcList)
}
if rsrcList.(*expapi.ThirdPartyResourceDataList).ResourceVersion != "1" {
t.Errorf("Unexpected resource version: %#v", rsrcList)
}
func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestGet(validNewThirdPartyResourceData("foo"))
}
func TestList(t *testing.T) {
ctx := api.NewDefaultContext()
registry, fakeClient, _ := newStorage(t)
fakeClient.ChangeIndex = 1
key := registry.KeyRootFunc(ctx)
key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Nodes: []*etcd.Node{
{
Value: runtime.EncodeOrDie(testapi.Codec(), &expapi.ThirdPartyResourceData{
ObjectMeta: api.ObjectMeta{Name: "foo"},
}),
},
{
Value: runtime.EncodeOrDie(testapi.Codec(), &expapi.ThirdPartyResourceData{
ObjectMeta: api.ObjectMeta{Name: "bar"},
}),
},
},
},
},
}
obj, err := registry.List(ctx, labels.Everything(), fields.Everything())
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
rsrcList := obj.(*expapi.ThirdPartyResourceDataList)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewThirdPartyResourceData("foo"))
}
if len(rsrcList.Items) != 2 {
t.Errorf("Unexpected ThirdPartyResourceData list: %#v", rsrcList)
}
if rsrcList.Items[0].Name != "foo" {
t.Errorf("Unexpected ThirdPartyResourceData: %#v", rsrcList.Items[0])
}
if rsrcList.Items[1].Name != "bar" {
t.Errorf("Unexpected ThirdPartyResourceData: %#v", rsrcList.Items[1])
}
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewThirdPartyResourceData("foo"),
// matching labels
[]labels.Set{},
// not matching labels
[]labels.Set{
{"foo": "bar"},
},
// matching fields
[]fields.Set{},
// not matching fields
[]fields.Set{
{"metadata.name": "bar"},
{"name": "foo"},
},
)
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment