Commit 97b4a64e authored by Wojciech Tyczynski's avatar Wojciech Tyczynski

Refactor registry etcd delete tests

parent b6f2f396
...@@ -19,16 +19,12 @@ package etcd ...@@ -19,16 +19,12 @@ package etcd
import ( import (
"testing" "testing"
"github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -127,6 +123,12 @@ func TestUpdate(t *testing.T) { ...@@ -127,6 +123,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewController())
}
func TestGenerationNumber(t *testing.T) { func TestGenerationNumber(t *testing.T) {
storage, _ := newStorage(t) storage, _ := newStorage(t)
modifiedSno := *validNewController() modifiedSno := *validNewController()
...@@ -218,59 +220,3 @@ func TestWatch(t *testing.T) { ...@@ -218,59 +220,3 @@ func TestWatch(t *testing.T) {
}, },
) )
} }
func TestEtcdDeleteController(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)
obj, err := storage.Delete(ctx, validController.Name, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if status, ok := obj.(*api.Status); !ok {
t.Errorf("Expected status of delete, got %#v", status)
} else if status.Status != api.StatusSuccess {
t.Errorf("Expected success, got %#v", status.Status)
}
if len(fakeClient.DeletedKeys) != 1 {
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
}
if fakeClient.DeletedKeys[0] != key {
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
}
}
func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError)
key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
rc := *validNewController()
rc.ResourceVersion = "1"
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), &rc),
ModifiedIndex: 1,
},
},
}
return &rc
}
gracefulSetFn := func() bool {
// If the controller is still around after trying to delete either the delete
// failed, or we're deleting it gracefully.
if fakeClient.Data[key].R.Node != nil {
return true
}
return false
}
test.TestDelete(createFn, gracefulSetFn)
}
...@@ -19,17 +19,13 @@ package etcd ...@@ -19,17 +19,13 @@ package etcd
import ( import (
"testing" "testing"
"github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api" "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"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -121,6 +117,12 @@ func TestUpdate(t *testing.T) { ...@@ -121,6 +117,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewDaemon())
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -158,59 +160,3 @@ func TestWatch(t *testing.T) { ...@@ -158,59 +160,3 @@ func TestWatch(t *testing.T) {
}, },
) )
} }
func TestEtcdDeleteDaemon(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, err := storage.KeyFunc(ctx, validDaemon.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validDaemon), 0)
obj, err := storage.Delete(ctx, validDaemon.Name, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if status, ok := obj.(*api.Status); !ok {
t.Errorf("Expected status of delete, got %#v", status)
} else if status.Status != api.StatusSuccess {
t.Errorf("Expected success, got %#v", status.Status)
}
if len(fakeClient.DeletedKeys) != 1 {
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
}
if fakeClient.DeletedKeys[0] != key {
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
}
}
func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError)
key, _ := storage.KeyFunc(ctx, validDaemon.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
dc := validNewDaemon()
dc.ResourceVersion = "1"
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), dc),
ModifiedIndex: 1,
},
},
}
return dc
}
gracefulSetFn := func() bool {
// If the daemon is still around after trying to delete either the delete
// failed, or we're deleting it gracefully.
if fakeClient.Data[key].R.Node != nil {
return true
}
return false
}
test.TestDelete(createFn, gracefulSetFn)
}
...@@ -19,17 +19,13 @@ package etcd ...@@ -19,17 +19,13 @@ package etcd
import ( import (
"testing" "testing"
"github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api" "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"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -122,6 +118,12 @@ func TestUpdate(t *testing.T) { ...@@ -122,6 +118,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewDeployment())
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -157,58 +159,3 @@ func TestWatch(t *testing.T) { ...@@ -157,58 +159,3 @@ func TestWatch(t *testing.T) {
}, },
) )
} }
func TestEtcdDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
key, err := storage.KeyFunc(ctx, validDeployment.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewDeployment()), 0)
obj, err := storage.Delete(ctx, validDeployment.Name, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if status, ok := obj.(*api.Status); !ok {
t.Errorf("Expected status of delete, got %#v", status)
} else if status.Status != api.StatusSuccess {
t.Errorf("Expected success, got %#v", status.Status)
}
if len(fakeClient.DeletedKeys) != 1 {
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
}
if fakeClient.DeletedKeys[0] != key {
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
}
}
func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError)
key, _ := storage.KeyFunc(ctx, validDeployment.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
dc := validNewDeployment()
dc.ResourceVersion = "1"
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), dc),
ModifiedIndex: 1,
},
},
}
return dc
}
gracefulSetFn := func() bool {
// If the deployment is still around after trying to delete either the delete
// failed, or we're deleting it gracefully.
if fakeClient.Data[key].R.Node != nil {
return true
}
return false
}
test.TestDelete(createFn, gracefulSetFn)
}
...@@ -20,15 +20,11 @@ import ( ...@@ -20,15 +20,11 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "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) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -93,31 +89,9 @@ func TestUpdate(t *testing.T) { ...@@ -93,31 +89,9 @@ func TestUpdate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewEndpoints())
endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, endpoints.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), endpoints),
ModifiedIndex: 1,
},
},
}
return endpoints
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
return fakeClient.Data[key].R.Node.TTL == 30
}
test.TestDelete(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -132,43 +106,25 @@ func TestList(t *testing.T) { ...@@ -132,43 +106,25 @@ func TestList(t *testing.T) {
test.TestList(validNewEndpoints()) test.TestList(validNewEndpoints())
} }
func TestEndpointsDecode(t *testing.T) { func TestWatch(t *testing.T) {
storage, _ := newStorage(t)
expected := validNewEndpoints()
body, err := testapi.Codec().Encode(expected)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual := storage.New()
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, actual) {
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
}
}
func TestDeleteEndpoints(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
endpoints := validNewEndpoints() test := registrytest.New(t, fakeClient, storage.Etcd)
name := endpoints.Name test.TestWatch(
key, _ := storage.KeyFunc(ctx, name) validNewEndpoints(),
key = etcdtest.AddPrefix(key) // matching labels
fakeClient.ChangeIndex = 1 []labels.Set{},
fakeClient.Data[key] = tools.EtcdResponseWithError{ // not matching labels
R: &etcd.Response{ []labels.Set{
Node: &etcd.Node{ {"foo": "bar"},
Value: runtime.EncodeOrDie(testapi.Codec(), endpoints),
ModifiedIndex: 1,
CreatedIndex: 1,
},
}, },
} // matching fields
_, err := storage.Delete(ctx, name, nil) []fields.Set{
if err != nil { {"metadata.name": "foo"},
t.Fatalf("unexpected error: %v", err) },
} // not matching fields
[]fields.Set{
{"metadata.name": "bar"},
{"name": "foo"},
},
)
} }
...@@ -21,17 +21,14 @@ import ( ...@@ -21,17 +21,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/expapi" "k8s.io/kubernetes/pkg/expapi"
// Ensure that expapi/v1 package is initialized. // Ensure that expapi/v1 package is initialized.
_ "k8s.io/kubernetes/pkg/expapi/v1" _ "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/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -85,30 +82,9 @@ func TestUpdate(t *testing.T) { ...@@ -85,30 +82,9 @@ func TestUpdate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := registrytest.New(t, fakeClient, storage.Etcd)
autoscaler := validNewHorizontalPodAutoscaler("foo2") test.TestDelete(validNewHorizontalPodAutoscaler("foo"))
key, _ := storage.KeyFunc(ctx, "foo2")
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), autoscaler),
ModifiedIndex: 1,
},
},
}
return autoscaler
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
return fakeClient.Data[key].R.Node.TTL == 30
}
test.TestDelete(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -122,3 +98,24 @@ func TestList(t *testing.T) { ...@@ -122,3 +98,24 @@ func TestList(t *testing.T) {
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewHorizontalPodAutoscaler("foo")) test.TestList(validNewHorizontalPodAutoscaler("foo"))
} }
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewHorizontalPodAutoscaler("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"},
},
)
}
...@@ -74,13 +74,20 @@ func (autoscalerStrategy) AllowUnconditionalUpdate() bool { ...@@ -74,13 +74,20 @@ func (autoscalerStrategy) AllowUnconditionalUpdate() bool {
return true return true
} }
// MatchAutoscaler returns a generic matcher for a given label and field selector. func AutoscalerToSelectableFields(limitRange *expapi.HorizontalPodAutoscaler) fields.Set {
return fields.Set{}
}
func MatchAutoscaler(label labels.Selector, field fields.Selector) generic.Matcher { func MatchAutoscaler(label labels.Selector, field fields.Selector) generic.Matcher {
return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { return &generic.SelectionPredicate{
autoscaler, ok := obj.(*expapi.HorizontalPodAutoscaler) Label: label,
if !ok { Field: field,
return false, fmt.Errorf("not a horizontal pod autoscaler") GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
} hpa, ok := obj.(*expapi.HorizontalPodAutoscaler)
return label.Matches(labels.Set(autoscaler.Labels)), nil if !ok {
}) return nil, nil, fmt.Errorf("given object is not a horizontal pod autoscaler.")
}
return labels.Set(hpa.ObjectMeta.Labels), AutoscalerToSelectableFields(hpa), nil
},
}
} }
...@@ -21,6 +21,8 @@ import ( ...@@ -21,6 +21,8 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
...@@ -97,6 +99,12 @@ func TestUpdate(t *testing.T) { ...@@ -97,6 +99,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewLimitRange())
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -108,3 +116,24 @@ func TestList(t *testing.T) { ...@@ -108,3 +116,24 @@ func TestList(t *testing.T) {
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewLimitRange()) test.TestList(validNewLimitRange())
} }
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewLimitRange(),
// 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"},
},
)
}
...@@ -22,16 +22,11 @@ import ( ...@@ -22,16 +22,11 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
) )
type fakeConnectionInfoGetter struct { type fakeConnectionInfoGetter struct {
...@@ -67,12 +62,6 @@ func validNewNode() *api.Node { ...@@ -67,12 +62,6 @@ func validNewNode() *api.Node {
} }
} }
func validChangedNode() *api.Node {
node := validNewNode()
node.ResourceVersion = "1"
return node
}
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope() test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
...@@ -104,31 +93,9 @@ func TestUpdate(t *testing.T) { ...@@ -104,31 +93,9 @@ func TestUpdate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
test.TestDelete(validNewNode())
node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), node),
ModifiedIndex: 1,
},
},
}
return node
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
return fakeClient.Data[key].R.Node.TTL == 30
}
test.TestDelete(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -143,7 +110,7 @@ func TestList(t *testing.T) { ...@@ -143,7 +110,7 @@ func TestList(t *testing.T) {
test.TestList(validNewNode()) test.TestList(validNewNode())
} }
func TestWatchNodes(t *testing.T) { func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope() test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
test.TestWatch( test.TestWatch(
...@@ -167,23 +134,3 @@ func TestWatchNodes(t *testing.T) { ...@@ -167,23 +134,3 @@ func TestWatchNodes(t *testing.T) {
}, },
) )
} }
func TestEtcdDeleteNode(t *testing.T) {
ctx := api.NewContext()
storage, fakeClient := newStorage(t)
node := validNewNode()
key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), node), 0)
_, err := storage.Delete(ctx, node.Name, nil)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if len(fakeClient.DeletedKeys) != 1 {
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
}
if fakeClient.DeletedKeys[0] != key {
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
}
}
...@@ -21,6 +21,8 @@ import ( ...@@ -21,6 +21,8 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
...@@ -59,15 +61,6 @@ func TestCreate(t *testing.T) { ...@@ -59,15 +61,6 @@ func TestCreate(t *testing.T) {
) )
} }
func expectNamespace(t *testing.T, out runtime.Object) (*api.Namespace, bool) {
namespace, ok := out.(*api.Namespace)
if !ok || namespace == nil {
t.Errorf("Expected an api.Namespace object, was %#v", out)
return nil, false
}
return namespace, true
}
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
namespace := validNewNamespace() namespace := validNewNamespace()
...@@ -93,24 +86,10 @@ func TestCreateSetsFields(t *testing.T) { ...@@ -93,24 +86,10 @@ func TestCreateSetsFields(t *testing.T) {
} }
} }
func TestNamespaceDecode(t *testing.T) { func TestDelete(t *testing.T) {
storage, _ := newStorage(t) storage, fakeClient := newStorage(t)
expected := validNewNamespace() test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope().ReturnDeletedObject()
expected.Status.Phase = api.NamespaceActive test.TestDelete(validNewNamespace())
expected.Spec.Finalizers = []api.FinalizerName{api.FinalizerKubernetes}
body, err := testapi.Codec().Encode(expected)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual := storage.New()
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, actual) {
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
}
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -125,31 +104,27 @@ func TestList(t *testing.T) { ...@@ -125,31 +104,27 @@ func TestList(t *testing.T) {
test.TestList(validNewNamespace()) test.TestList(validNewNamespace())
} }
func TestDeleteNamespace(t *testing.T) { func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1 test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
ctx := api.NewContext() test.TestWatch(
key, err := storage.Etcd.KeyFunc(ctx, "foo") validNewNamespace(),
key = etcdtest.AddPrefix(key) // matching labels
fakeClient.Data[key] = tools.EtcdResponseWithError{ []labels.Set{},
R: &etcd.Response{ // not matching labels
Node: &etcd.Node{ []labels.Set{
Value: runtime.EncodeOrDie(testapi.Codec(), &api.Namespace{ {"foo": "bar"},
ObjectMeta: api.ObjectMeta{
Name: "foo",
},
Status: api.NamespaceStatus{Phase: api.NamespaceActive},
}),
ModifiedIndex: 1,
CreatedIndex: 1,
},
}, },
} // matching fields
_, err = storage.Delete(api.NewContext(), "foo", nil) []fields.Set{
{"metadata.name": "foo"},
if err != nil { {"name": "foo"},
t.Fatalf("unexpected error: %v", err) },
} // not matching fields
[]fields.Set{
{"metadata.name": "bar"},
},
)
} }
func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) { func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
......
...@@ -143,10 +143,11 @@ func MatchNamespace(label labels.Selector, field fields.Selector) generic.Matche ...@@ -143,10 +143,11 @@ func MatchNamespace(label labels.Selector, field fields.Selector) generic.Matche
} }
// NamespaceToSelectableFields returns a label set that represents the object // NamespaceToSelectableFields returns a label set that represents the object
// TODO: fields are not labels, and the validation rules for them do not apply.
func NamespaceToSelectableFields(namespace *api.Namespace) labels.Set { func NamespaceToSelectableFields(namespace *api.Namespace) labels.Set {
return labels.Set{ return labels.Set{
"name": namespace.Name, "metadata.name": namespace.Name,
"status.phase": string(namespace.Status.Phase), "status.phase": string(namespace.Status.Phase),
// This is a bug, but we need to support it for backward compatibility.
"name": namespace.Name,
} }
} }
...@@ -21,15 +21,14 @@ import ( ...@@ -21,15 +21,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
...@@ -101,31 +100,9 @@ func TestUpdate(t *testing.T) { ...@@ -101,31 +100,9 @@ func TestUpdate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope().ReturnDeletedObject()
test.TestDelete(validNewPersistentVolume("foo"))
pv := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), pv),
ModifiedIndex: 1,
},
},
}
return pv
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
return fakeClient.Data[key].R.Node.TTL == 30
}
test.TestDelete(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -140,48 +117,30 @@ func TestList(t *testing.T) { ...@@ -140,48 +117,30 @@ func TestList(t *testing.T) {
test.TestList(validNewPersistentVolume("foo")) test.TestList(validNewPersistentVolume("foo"))
} }
func TestPersistentVolumesDecode(t *testing.T) { func TestWatch(t *testing.T) {
storage, _, _ := newStorage(t)
expected := validNewPersistentVolume("foo")
body, err := testapi.Codec().Encode(expected)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual := storage.New()
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, actual) {
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
}
}
func TestDeletePersistentVolumes(t *testing.T) {
ctx := api.NewContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
persistentVolume := validNewPersistentVolume("foo") test := registrytest.New(t, fakeClient, storage.Etcd).ClusterScope()
name := persistentVolume.Name test.TestWatch(
key, _ := storage.KeyFunc(ctx, name) validNewPersistentVolume("foo"),
key = etcdtest.AddPrefix(key) // matching labels
fakeClient.ChangeIndex = 1 []labels.Set{},
fakeClient.Data[key] = tools.EtcdResponseWithError{ // not matching labels
R: &etcd.Response{ []labels.Set{
Node: &etcd.Node{ {"foo": "bar"},
Value: runtime.EncodeOrDie(testapi.Codec(), persistentVolume),
ModifiedIndex: 1,
CreatedIndex: 1,
},
}, },
} // matching fields
_, err := storage.Delete(ctx, name, nil) []fields.Set{
if err != nil { {"metadata.name": "foo"},
t.Fatalf("unexpected error: %v", err) {"name": "foo"},
} },
// not matching fields
[]fields.Set{
{"metadata.name": "bar"},
},
)
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient := newStorage(t) storage, statusStorage, fakeClient := newStorage(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
......
...@@ -103,9 +103,10 @@ func MatchPersistentVolumes(label labels.Selector, field fields.Selector) generi ...@@ -103,9 +103,10 @@ func MatchPersistentVolumes(label labels.Selector, field fields.Selector) generi
} }
// PersistentVolumeToSelectableFields returns a label set that represents the object // PersistentVolumeToSelectableFields returns a label set that represents the object
// TODO: fields are not labels, and the validation rules for them do not apply.
func PersistentVolumeToSelectableFields(persistentvolume *api.PersistentVolume) labels.Set { func PersistentVolumeToSelectableFields(persistentvolume *api.PersistentVolume) labels.Set {
return labels.Set{ return labels.Set{
"metadata.name": persistentvolume.Name,
// This is a bug, but we need to support it for backward compatibility.
"name": persistentvolume.Name, "name": persistentvolume.Name,
} }
} }
...@@ -21,15 +21,14 @@ import ( ...@@ -21,15 +21,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
...@@ -59,12 +58,6 @@ func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim { ...@@ -59,12 +58,6 @@ func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim {
return pv return pv
} }
func validChangedPersistentVolumeClaim() *api.PersistentVolumeClaim {
pv := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
pv.ResourceVersion = "1"
return pv
}
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -100,31 +93,9 @@ func TestUpdate(t *testing.T) { ...@@ -100,31 +93,9 @@ func TestUpdate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
test.TestDelete(validNewPersistentVolumeClaim("foo", api.NamespaceDefault))
pv := validChangedPersistentVolumeClaim()
key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), pv),
ModifiedIndex: 1,
},
},
}
return pv
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
return fakeClient.Data[key].R.Node.TTL == 30
}
test.TestDelete(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -139,78 +110,30 @@ func TestList(t *testing.T) { ...@@ -139,78 +110,30 @@ func TestList(t *testing.T) {
test.TestList(validNewPersistentVolumeClaim("foo", api.NamespaceDefault)) test.TestList(validNewPersistentVolumeClaim("foo", api.NamespaceDefault))
} }
func TestPersistentVolumeClaimsDecode(t *testing.T) { func TestWatch(t *testing.T) {
storage, _, _ := newStorage(t)
expected := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
body, err := testapi.Codec().Encode(expected)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual := storage.New()
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, actual) {
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
}
}
func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
ctx := api.NewDefaultContext()
storage, _, fakeClient := newStorage(t)
persistentVolume := validChangedPersistentVolumeClaim()
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 0)
_, _, err := storage.Update(ctx, persistentVolume)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
response, err := fakeClient.Get(key, false, false)
if err != nil {
t.Fatalf("Unexpected error %v", err)
}
var persistentVolumeOut api.PersistentVolumeClaim
err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &persistentVolumeOut)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
persistentVolume.ObjectMeta.ResourceVersion = persistentVolumeOut.ObjectMeta.ResourceVersion
if !api.Semantic.DeepEqual(persistentVolume, &persistentVolumeOut) {
t.Errorf("Unexpected persistentVolume: %#v, expected %#v", &persistentVolumeOut, persistentVolume)
}
}
func TestDeletePersistentVolumeClaims(t *testing.T) {
ctx := api.NewDefaultContext()
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) test := registrytest.New(t, fakeClient, storage.Etcd)
name := pvClaim.Name test.TestWatch(
key, _ := storage.KeyFunc(ctx, name) validNewPersistentVolumeClaim("foo", api.NamespaceDefault),
key = etcdtest.AddPrefix(key) // matching labels
fakeClient.ChangeIndex = 1 []labels.Set{},
fakeClient.Data[key] = tools.EtcdResponseWithError{ // not matching labels
R: &etcd.Response{ []labels.Set{
Node: &etcd.Node{ {"foo": "bar"},
Value: runtime.EncodeOrDie(testapi.Codec(), pvClaim),
ModifiedIndex: 1,
CreatedIndex: 1,
},
}, },
} // matching fields
_, err := storage.Delete(ctx, name, nil) []fields.Set{
if err != nil { {"metadata.name": "foo"},
t.Fatalf("unexpected error: %v", err) {"name": "foo"},
} },
// not matching fields
[]fields.Set{
{"metadata.name": "bar"},
},
)
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient := newStorage(t) storage, statusStorage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
......
...@@ -103,9 +103,10 @@ func MatchPersistentVolumeClaim(label labels.Selector, field fields.Selector) ge ...@@ -103,9 +103,10 @@ func MatchPersistentVolumeClaim(label labels.Selector, field fields.Selector) ge
} }
// PersistentVolumeClaimToSelectableFields returns a label set that represents the object // PersistentVolumeClaimToSelectableFields returns a label set that represents the object
// TODO: fields are not labels, and the validation rules for them do not apply.
func PersistentVolumeClaimToSelectableFields(persistentvolumeclaim *api.PersistentVolumeClaim) labels.Set { func PersistentVolumeClaimToSelectableFields(persistentvolumeclaim *api.PersistentVolumeClaim) labels.Set {
return labels.Set{ return labels.Set{
"metadata.name": persistentvolumeclaim.Name,
// This is a bug, but we need to support it for backward compatibility.
"name": persistentvolumeclaim.Name, "name": persistentvolumeclaim.Name,
} }
} }
...@@ -25,7 +25,6 @@ import ( ...@@ -25,7 +25,6 @@ import (
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
etcderrors "k8s.io/kubernetes/pkg/api/errors/etcd" etcderrors "k8s.io/kubernetes/pkg/api/errors/etcd"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/fields" "k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels" "k8s.io/kubernetes/pkg/labels"
...@@ -122,50 +121,12 @@ func TestUpdate(t *testing.T) { ...@@ -122,50 +121,12 @@ func TestUpdate(t *testing.T) {
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
storage, _, _, fakeClient := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") test.TestDelete(validNewPod())
key = etcdtest.AddPrefix(key)
test := resttest.New(t, storage, fakeClient.SetError)
expectedNode := "some-node"
createFn := func() runtime.Object {
pod := validChangedPod()
pod.Spec.NodeName = expectedNode
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), pod),
ModifiedIndex: 1,
},
},
}
return pod
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
obj, err := testapi.Codec().Decode([]byte(fakeClient.Data[key].R.Node.Value))
if err != nil {
return false
}
pod := obj.(*api.Pod)
t.Logf("found object %#v", pod.ObjectMeta)
return pod.DeletionTimestamp != nil && pod.DeletionGracePeriodSeconds != nil && *pod.DeletionGracePeriodSeconds != 0
}
test.TestDeleteGraceful(createFn, 30, gracefulSetFn)
expectedNode = ""
test.TestDelete(createFn, gracefulSetFn)
}
func expectPod(t *testing.T, out runtime.Object) (*api.Pod, bool) { scheduledPod := validNewPod()
pod, ok := out.(*api.Pod) scheduledPod.Spec.NodeName = "some-node"
if !ok || pod == nil { test.TestDeleteGraceful(scheduledPod, 30)
t.Errorf("Expected an api.Pod object, was %#v", out)
return nil, false
}
return pod, true
} }
func TestCreateRegistryError(t *testing.T) { func TestCreateRegistryError(t *testing.T) {
...@@ -200,24 +161,6 @@ func TestCreateSetsFields(t *testing.T) { ...@@ -200,24 +161,6 @@ func TestCreateSetsFields(t *testing.T) {
} }
} }
func TestPodDecode(t *testing.T) {
storage, _, _, _ := newStorage(t)
expected := validNewPod()
body, err := testapi.Codec().Encode(expected)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual := storage.New()
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, actual) {
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
}
}
func TestResourceLocation(t *testing.T) { func TestResourceLocation(t *testing.T) {
expectedIP := "1.2.3.4" expectedIP := "1.2.3.4"
testCases := []struct { testCases := []struct {
...@@ -854,49 +797,3 @@ func TestEtcdUpdateStatus(t *testing.T) { ...@@ -854,49 +797,3 @@ func TestEtcdUpdateStatus(t *testing.T) {
t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, podOut)) t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, podOut))
} }
} }
func TestEtcdDeletePod(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"},
}), 0)
_, err := storage.Delete(ctx, "foo", api.NewDeleteOptions(0))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if len(fakeClient.DeletedKeys) != 1 {
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
} else if fakeClient.DeletedKeys[0] != key {
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
}
}
func TestEtcdDeletePodMultipleContainers(t *testing.T) {
storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"},
}), 0)
_, err := storage.Delete(ctx, "foo", api.NewDeleteOptions(0))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if len(fakeClient.DeletedKeys) != 1 {
t.Errorf("Expected 1 delete, found %#v", fakeClient.DeletedKeys)
}
if fakeClient.DeletedKeys[0] != key {
t.Errorf("Unexpected key: %s, expected %s", fakeClient.DeletedKeys[0], key)
}
}
...@@ -20,6 +20,8 @@ import ( ...@@ -20,6 +20,8 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
...@@ -87,6 +89,12 @@ func TestUpdate(t *testing.T) { ...@@ -87,6 +89,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
test.TestDelete(validNewPodTemplate("foo"))
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -98,3 +106,24 @@ func TestList(t *testing.T) { ...@@ -98,3 +106,24 @@ func TestList(t *testing.T) {
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewPodTemplate("foo")) test.TestList(validNewPodTemplate("foo"))
} }
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewPodTemplate("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"},
},
)
}
...@@ -73,13 +73,20 @@ func (podTemplateStrategy) AllowUnconditionalUpdate() bool { ...@@ -73,13 +73,20 @@ func (podTemplateStrategy) AllowUnconditionalUpdate() bool {
return true return true
} }
// MatchPodTemplate returns a generic matcher for a given label and field selector. func PodTemplateToSelectableFields(podTemplate *api.PodTemplate) fields.Set {
return fields.Set{}
}
func MatchPodTemplate(label labels.Selector, field fields.Selector) generic.Matcher { func MatchPodTemplate(label labels.Selector, field fields.Selector) generic.Matcher {
return generic.MatcherFunc(func(obj runtime.Object) (bool, error) { return &generic.SelectionPredicate{
podObj, ok := obj.(*api.PodTemplate) Label: label,
if !ok { Field: field,
return false, fmt.Errorf("not a pod template") GetAttrs: func(obj runtime.Object) (labels.Set, fields.Set, error) {
} pt, ok := obj.(*api.PodTemplate)
return label.Matches(labels.Set(podObj.Labels)), nil if !ok {
}) return nil, nil, fmt.Errorf("given object is not a pod template.")
}
return labels.Set(pt.ObjectMeta.Labels), PodTemplateToSelectableFields(pt), nil
},
}
} }
...@@ -75,6 +75,11 @@ func (t *Tester) GeneratesName() *Tester { ...@@ -75,6 +75,11 @@ func (t *Tester) GeneratesName() *Tester {
return t return t
} }
func (t *Tester) ReturnDeletedObject() *Tester {
t.tester = t.tester.ReturnDeletedObject()
return t
}
func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) { func (t *Tester) TestCreate(valid runtime.Object, invalid ...runtime.Object) {
t.tester.TestCreate( t.tester.TestCreate(
valid, valid,
...@@ -99,6 +104,24 @@ func (t *Tester) TestUpdate(valid runtime.Object, validUpdateFunc UpdateFunc, in ...@@ -99,6 +104,24 @@ func (t *Tester) TestUpdate(valid runtime.Object, validUpdateFunc UpdateFunc, in
) )
} }
func (t *Tester) TestDelete(valid runtime.Object) {
t.tester.TestDelete(
valid,
t.setObject,
t.getObject,
isNotFoundEtcdError,
)
}
func (t *Tester) TestDeleteGraceful(valid runtime.Object, expectedGrace int64) {
t.tester.TestDeleteGraceful(
valid,
t.setObject,
t.getObject,
expectedGrace,
)
}
func (t *Tester) TestGet(valid runtime.Object) { func (t *Tester) TestGet(valid runtime.Object) {
t.tester.TestGet(valid) t.tester.TestGet(valid)
} }
...@@ -219,3 +242,11 @@ func (t *Tester) emitObject(obj runtime.Object, action string) error { ...@@ -219,3 +242,11 @@ func (t *Tester) emitObject(obj runtime.Object, action string) error {
} }
return nil return nil
} }
func isNotFoundEtcdError(err error) bool {
etcdError, ok := err.(*etcd.EtcdError)
if !ok {
return false
}
return etcdError.ErrorCode == tools.EtcdErrorCodeNotFound
}
...@@ -30,8 +30,6 @@ import ( ...@@ -30,8 +30,6 @@ import (
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
"github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
...@@ -74,15 +72,6 @@ func TestCreate(t *testing.T) { ...@@ -74,15 +72,6 @@ func TestCreate(t *testing.T) {
) )
} }
func expectResourceQuota(t *testing.T, out runtime.Object) (*api.ResourceQuota, bool) {
resourcequota, ok := out.(*api.ResourceQuota)
if !ok || resourcequota == nil {
t.Errorf("Expected an api.ResourceQuota object, was %#v", out)
return nil, false
}
return resourcequota, true
}
func TestCreateRegistryError(t *testing.T) { func TestCreateRegistryError(t *testing.T) {
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
fakeClient.Err = fmt.Errorf("test error") fakeClient.Err = fmt.Errorf("test error")
...@@ -116,49 +105,10 @@ func TestCreateSetsFields(t *testing.T) { ...@@ -116,49 +105,10 @@ func TestCreateSetsFields(t *testing.T) {
} }
} }
func TestResourceQuotaDecode(t *testing.T) { func TestDelete(t *testing.T) {
storage, _, _ := newStorage(t)
expected := validNewResourceQuota()
body, err := testapi.Codec().Encode(expected)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
actual := storage.New()
if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, actual) {
t.Errorf("mismatch: %s", util.ObjectDiff(expected, actual))
}
}
func TestDeleteResourceQuota(t *testing.T) {
storage, _, fakeClient := newStorage(t) storage, _, fakeClient := newStorage(t)
fakeClient.ChangeIndex = 1 test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
ctx := api.NewDefaultContext() test.TestDelete(validNewResourceQuota())
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.ResourceQuota{
ObjectMeta: api.ObjectMeta{
Name: "foo",
Namespace: api.NamespaceDefault,
},
Status: api.ResourceQuotaStatus{},
}),
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) { func TestGet(t *testing.T) {
...@@ -195,7 +145,7 @@ func TestWatch(t *testing.T) { ...@@ -195,7 +145,7 @@ func TestWatch(t *testing.T) {
) )
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestUpdateStatus(t *testing.T) {
storage, status, fakeClient := newStorage(t) storage, status, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
......
...@@ -20,6 +20,8 @@ import ( ...@@ -20,6 +20,8 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
...@@ -78,6 +80,12 @@ func TestUpdate(t *testing.T) { ...@@ -78,6 +80,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestDelete(validNewSecret("foo"))
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -89,3 +97,24 @@ func TestList(t *testing.T) { ...@@ -89,3 +97,24 @@ func TestList(t *testing.T) {
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewSecret("foo")) test.TestList(validNewSecret("foo"))
} }
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewSecret("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"},
},
)
}
...@@ -106,6 +106,12 @@ func TestUpdate(t *testing.T) { ...@@ -106,6 +106,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).AllowCreateOnUpdate()
test.TestDelete(validService())
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).AllowCreateOnUpdate() test := registrytest.New(t, fakeClient, storage.Etcd).AllowCreateOnUpdate()
......
...@@ -20,6 +20,8 @@ import ( ...@@ -20,6 +20,8 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/fields"
"k8s.io/kubernetes/pkg/labels"
"k8s.io/kubernetes/pkg/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
...@@ -71,6 +73,12 @@ func TestUpdate(t *testing.T) { ...@@ -71,6 +73,12 @@ func TestUpdate(t *testing.T) {
) )
} }
func TestDelete(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd).ReturnDeletedObject()
test.TestDelete(validNewServiceAccount("foo"))
}
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
...@@ -82,3 +90,26 @@ func TestList(t *testing.T) { ...@@ -82,3 +90,26 @@ func TestList(t *testing.T) {
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewServiceAccount("foo")) test.TestList(validNewServiceAccount("foo"))
} }
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewServiceAccount("foo"),
// matching labels
[]labels.Set{},
// not matching labels
[]labels.Set{
{"foo": "bar"},
},
// matching fields
[]fields.Set{
{"metadata.name": "foo"},
},
// not matching fields
[]fields.Set{
{"metadata.name": "bar"},
{"name": "foo"},
},
)
}
...@@ -20,17 +20,14 @@ import ( ...@@ -20,17 +20,14 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "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"
// Ensure that expapi/v1 package is initialized. // Ensure that expapi/v1 package is initialized.
_ "k8s.io/kubernetes/pkg/expapi/v1" _ "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/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
...@@ -81,30 +78,9 @@ func TestUpdate(t *testing.T) { ...@@ -81,30 +78,9 @@ func TestUpdate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := registrytest.New(t, fakeClient, storage.Etcd)
rsrc := validNewThirdPartyResource("foo2") test.TestDelete(validNewThirdPartyResource("foo"))
key, _ := storage.KeyFunc(ctx, "foo2")
key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object {
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{
Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), rsrc),
ModifiedIndex: 1,
},
},
}
return rsrc
}
gracefulSetFn := func() bool {
if fakeClient.Data[key].R.Node == nil {
return false
}
return fakeClient.Data[key].R.Node.TTL == 30
}
test.TestDeleteNoGraceful(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
...@@ -118,3 +94,24 @@ func TestList(t *testing.T) { ...@@ -118,3 +94,24 @@ func TestList(t *testing.T) {
test := registrytest.New(t, fakeClient, storage.Etcd) test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestList(validNewThirdPartyResource("foo")) test.TestList(validNewThirdPartyResource("foo"))
} }
func TestWatch(t *testing.T) {
storage, fakeClient := newStorage(t)
test := registrytest.New(t, fakeClient, storage.Etcd)
test.TestWatch(
validNewThirdPartyResource("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