Unification refactoring to pkg/registry

This commit is contained in:
Wojciech Tyczynski
2015-08-20 11:17:04 +02:00
parent e5735fdc7c
commit 5931cc74cc
33 changed files with 501 additions and 649 deletions

View File

@@ -75,7 +75,7 @@ func (r *registryGetter) GetSecret(namespace, name string) (*api.Secret, error)
// uses the specified storage to retrieve service accounts and secrets. // uses the specified storage to retrieve service accounts and secrets.
func NewGetterFromStorageInterface(storage storage.Interface) ServiceAccountTokenGetter { func NewGetterFromStorageInterface(storage storage.Interface) ServiceAccountTokenGetter {
return NewGetterFromRegistries( return NewGetterFromRegistries(
serviceaccount.NewRegistry(serviceaccountetcd.NewStorage(storage)), serviceaccount.NewRegistry(serviceaccountetcd.NewREST(storage)),
secret.NewRegistry(secretetcd.NewStorage(storage)), secret.NewRegistry(secretetcd.NewREST(storage)),
) )
} }

View File

@@ -434,25 +434,25 @@ func (m *Master) init(c *Config) {
podTemplateStorage := podtemplateetcd.NewREST(c.DatabaseStorage) podTemplateStorage := podtemplateetcd.NewREST(c.DatabaseStorage)
eventStorage := eventetcd.NewStorage(c.DatabaseStorage, uint64(c.EventTTL.Seconds())) eventStorage := eventetcd.NewREST(c.DatabaseStorage, uint64(c.EventTTL.Seconds()))
limitRangeStorage := limitrangeetcd.NewStorage(c.DatabaseStorage) limitRangeStorage := limitrangeetcd.NewREST(c.DatabaseStorage)
resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewStorage(c.DatabaseStorage) resourceQuotaStorage, resourceQuotaStatusStorage := resourcequotaetcd.NewREST(c.DatabaseStorage)
secretStorage := secretetcd.NewStorage(c.DatabaseStorage) secretStorage := secretetcd.NewREST(c.DatabaseStorage)
serviceAccountStorage := serviceaccountetcd.NewStorage(c.DatabaseStorage) serviceAccountStorage := serviceaccountetcd.NewREST(c.DatabaseStorage)
persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewStorage(c.DatabaseStorage) persistentVolumeStorage, persistentVolumeStatusStorage := pvetcd.NewREST(c.DatabaseStorage)
persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewStorage(c.DatabaseStorage) persistentVolumeClaimStorage, persistentVolumeClaimStatusStorage := pvcetcd.NewREST(c.DatabaseStorage)
namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewStorage(c.DatabaseStorage) namespaceStorage, namespaceStatusStorage, namespaceFinalizeStorage := namespaceetcd.NewREST(c.DatabaseStorage)
m.namespaceRegistry = namespace.NewRegistry(namespaceStorage) m.namespaceRegistry = namespace.NewRegistry(namespaceStorage)
endpointsStorage := endpointsetcd.NewStorage(c.DatabaseStorage) endpointsStorage := endpointsetcd.NewREST(c.DatabaseStorage)
m.endpointRegistry = endpoint.NewRegistry(endpointsStorage) m.endpointRegistry = endpoint.NewRegistry(endpointsStorage)
nodeStorage, nodeStatusStorage := nodeetcd.NewStorage(c.DatabaseStorage, c.KubeletClient) nodeStorage, nodeStatusStorage := nodeetcd.NewREST(c.DatabaseStorage, c.KubeletClient)
m.nodeRegistry = minion.NewRegistry(nodeStorage) m.nodeRegistry = minion.NewRegistry(nodeStorage)
serviceStorage := serviceetcd.NewStorage(c.DatabaseStorage) serviceStorage := serviceetcd.NewREST(c.DatabaseStorage)
m.serviceRegistry = service.NewRegistry(serviceStorage) m.serviceRegistry = service.NewRegistry(serviceStorage)
var serviceClusterIPRegistry service.RangeRegistry var serviceClusterIPRegistry service.RangeRegistry

View File

@@ -27,17 +27,13 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for replication controllers against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// controllerPrefix is the location for controllers in etcd, only exposed
// for testing
var controllerPrefix = "/controllers"
// NewREST returns a RESTStorage object that will work against replication controllers. // NewREST returns a RESTStorage object that will work against replication controllers.
func NewREST(s storage.Interface) *REST { func NewREST(s storage.Interface) *REST {
prefix := "/controllers"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ReplicationController{} }, NewFunc: func() runtime.Object { return &api.ReplicationController{} },
@@ -46,12 +42,12 @@ func NewREST(s storage.Interface) *REST {
// Produces a path that etcd understands, to the root of the resource // Produces a path that etcd understands, to the root of the resource
// by combining the namespace in the context with the given prefix // by combining the namespace in the context with the given prefix
KeyRootFunc: func(ctx api.Context) string { KeyRootFunc: func(ctx api.Context) string {
return etcdgeneric.NamespaceKeyRootFunc(ctx, controllerPrefix) return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
}, },
// Produces a path that etcd understands, to the resource by combining // Produces a path that etcd understands, to the resource by combining
// the namespace in the context with the given prefix // the namespace in the context with the given prefix
KeyFunc: func(ctx api.Context, name string) (string, error) { KeyFunc: func(ctx api.Context, name string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, controllerPrefix, name) return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name)
}, },
// Retrieve the name field of a replication controller // Retrieve the name field of a replication controller
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
@@ -71,6 +67,5 @@ func NewREST(s storage.Interface) *REST {
Storage: s, Storage: s,
} }
return &REST{store} return &REST{store}
} }

View File

@@ -25,14 +25,13 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/rest/resttest" "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"
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
"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/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
@@ -43,18 +42,9 @@ const (
FAIL FAIL
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
// newStorage creates a REST storage backed by etcd helpers
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, s := newEtcdStorage(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
storage := NewREST(s) return NewREST(etcdStorage), fakeClient
return storage, fakeEtcdClient
} }
// createController is a helper function that returns a controller with the updated resource version. // createController is a helper function that returns a controller with the updated resource version.
@@ -97,11 +87,6 @@ var validController = api.ReplicationController{
Spec: validControllerSpec, Spec: validControllerSpec,
} }
// makeControllerKey constructs etcd paths to controller items enforcing namespace rules.
func makeControllerKey(ctx api.Context, id string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, controllerPrefix, id)
}
func TestEtcdCreateController(t *testing.T) { func TestEtcdCreateController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
@@ -109,14 +94,14 @@ func TestEtcdCreateController(t *testing.T) {
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
key, _ := makeControllerKey(ctx, validController.Name) key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
resp, err := fakeClient.Get(key, false, false) resp, err := fakeClient.Get(key, false, false)
if err != nil { if err != nil {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var ctrl api.ReplicationController var ctrl api.ReplicationController
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &ctrl) err = testapi.Codec().DecodeInto([]byte(resp.Node.Value), &ctrl)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -129,9 +114,9 @@ func TestEtcdCreateController(t *testing.T) {
func TestEtcdCreateControllerAlreadyExisting(t *testing.T) { func TestEtcdCreateControllerAlreadyExisting(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0)
_, err := storage.Create(ctx, &validController) _, err := storage.Create(ctx, &validController)
if !errors.IsAlreadyExists(err) { if !errors.IsAlreadyExists(err) {
@@ -332,11 +317,11 @@ func TestEtcdListControllers(t *testing.T) {
func TestEtcdUpdateController(t *testing.T) { func TestEtcdUpdateController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
// set a key, then retrieve the current resource version and try updating it // set a key, then retrieve the current resource version and try updating it
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0)
update := validController update := validController
update.ResourceVersion = strconv.FormatUint(resp.Node.ModifiedIndex, 10) update.ResourceVersion = strconv.FormatUint(resp.Node.ModifiedIndex, 10)
update.Spec.Replicas = validController.Spec.Replicas + 1 update.Spec.Replicas = validController.Spec.Replicas + 1
@@ -357,10 +342,10 @@ func TestEtcdUpdateController(t *testing.T) {
func TestEtcdDeleteController(t *testing.T) { func TestEtcdDeleteController(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &validController), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &validController), 0)
obj, err := storage.Delete(ctx, validController.Name, nil) obj, err := storage.Delete(ctx, validController.Name, nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@@ -430,7 +415,7 @@ func TestEtcdWatchControllersMatch(t *testing.T) {
Namespace: "default", Namespace: "default",
}, },
} }
controllerBytes, _ := latest.Codec.Encode(controller) controllerBytes, _ := testapi.Codec().Encode(controller)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{
@@ -483,7 +468,7 @@ func TestEtcdWatchControllersFields(t *testing.T) {
Replicas: 0, Replicas: 0,
}, },
} }
controllerBytes, _ := latest.Codec.Encode(controller) controllerBytes, _ := testapi.Codec().Encode(controller)
for expectedResult, fieldSet := range testFieldMap { for expectedResult, fieldSet := range testFieldMap {
for _, field := range fieldSet { for _, field := range fieldSet {
@@ -552,7 +537,7 @@ func TestEtcdWatchControllersNotMatch(t *testing.T) {
}, },
}, },
} }
controllerBytes, _ := latest.Codec.Encode(controller) controllerBytes, _ := testapi.Codec().Encode(controller)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{
@@ -595,7 +580,7 @@ func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, _ := makeControllerKey(ctx, validController.Name) key, _ := storage.KeyFunc(ctx, validController.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
@@ -604,7 +589,7 @@ func TestDelete(t *testing.T) {
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &rc), Value: runtime.EncodeOrDie(testapi.Codec(), &rc),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },

View File

@@ -27,36 +27,34 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for endpoints against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewStorage returns a RESTStorage object that will work against endpoints. // NewREST returns a RESTStorage object that will work against endpoints.
func NewStorage(s storage.Interface) *REST { func NewREST(s storage.Interface) *REST {
prefix := "/services/endpoints" prefix := "/services/endpoints"
return &REST{ store := &etcdgeneric.Etcd{
&etcdgeneric.Etcd{ NewFunc: func() runtime.Object { return &api.Endpoints{} },
NewFunc: func() runtime.Object { return &api.Endpoints{} }, NewListFunc: func() runtime.Object { return &api.EndpointsList{} },
NewListFunc: func() runtime.Object { return &api.EndpointsList{} }, KeyRootFunc: func(ctx api.Context) string {
KeyRootFunc: func(ctx api.Context) string { return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
},
KeyFunc: func(ctx api.Context, name string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Endpoints).Name, nil
},
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
return endpoint.MatchEndpoints(label, field)
},
EndpointName: "endpoints",
CreateStrategy: endpoint.Strategy,
UpdateStrategy: endpoint.Strategy,
Storage: s,
}, },
KeyFunc: func(ctx api.Context, name string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name)
},
ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.Endpoints).Name, nil
},
PredicateFunc: func(label labels.Selector, field fields.Selector) generic.Matcher {
return endpoint.MatchEndpoints(label, field)
},
EndpointName: "endpoints",
CreateStrategy: endpoint.Strategy,
UpdateStrategy: endpoint.Strategy,
Storage: s,
} }
return &REST{store}
} }

View File

@@ -20,12 +20,10 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"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/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -33,17 +31,9 @@ import (
"github.com/coreos/go-etcd/etcd" "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, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, s := newEtcdStorage(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
storage := NewStorage(s) return NewREST(etcdStorage), fakeClient
return storage, fakeEtcdClient
} }
func validNewEndpoints() *api.Endpoints { func validNewEndpoints() *api.Endpoints {
@@ -70,8 +60,8 @@ func validChangedEndpoints() *api.Endpoints {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, fakeEtcdClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
endpoints := validNewEndpoints() endpoints := validNewEndpoints()
endpoints.ObjectMeta = api.ObjectMeta{} endpoints.ObjectMeta = api.ObjectMeta{}
test.TestCreate( test.TestCreate(
@@ -86,17 +76,17 @@ func TestCreate(t *testing.T) {
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeEtcdClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
endpoints := validChangedEndpoints() endpoints := validChangedEndpoints()
key, _ := storage.KeyFunc(ctx, endpoints.Name) key, _ := storage.KeyFunc(ctx, endpoints.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, endpoints), Value: runtime.EncodeOrDie(testapi.Codec(), endpoints),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -104,10 +94,10 @@ func TestDelete(t *testing.T) {
return endpoints return endpoints
} }
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL == 30 return fakeClient.Data[key].R.Node.TTL == 30
} }
test.TestDelete(createFn, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
@@ -137,13 +127,13 @@ func TestEtcdListEndpoints(t *testing.T) {
func TestEndpointsDecode(t *testing.T) { func TestEndpointsDecode(t *testing.T) {
storage, _ := newStorage(t) storage, _ := newStorage(t)
expected := validNewEndpoints() expected := validNewEndpoints()
body, err := latest.Codec.Encode(expected) body, err := testapi.Codec().Encode(expected)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := storage.New() actual := storage.New()
if err := latest.Codec.DecodeInto(body, actual); err != nil { if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -159,7 +149,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewEndpoints()), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewEndpoints()), 0)
_, _, err := storage.Update(ctx, endpoints) _, _, err := storage.Update(ctx, endpoints)
if err != nil { if err != nil {
@@ -171,7 +161,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var endpointsOut api.Endpoints var endpointsOut api.Endpoints
err = latest.Codec.DecodeInto([]byte(response.Node.Value), &endpointsOut) err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &endpointsOut)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -193,7 +183,7 @@ func TestDeleteEndpoints(t *testing.T) {
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, endpoints), Value: runtime.EncodeOrDie(testapi.Codec(), endpoints),
ModifiedIndex: 1, ModifiedIndex: 1,
CreatedIndex: 1, CreatedIndex: 1,
}, },

View File

@@ -31,7 +31,8 @@ type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
func NewStorage(s storage.Interface, ttl uint64) *REST { // NewREST returns a RESTStorage object that will work against events.
func NewREST(s storage.Interface, ttl uint64) *REST {
prefix := "/events" prefix := "/events"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Event{} }, NewFunc: func() runtime.Object { return &api.Event{} },

View File

@@ -24,8 +24,8 @@ import (
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
"k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -35,12 +35,9 @@ import (
var testTTL uint64 = 60 var testTTL uint64 = 60
func NewTestEventStorage(t *testing.T) (*tools.FakeEtcdClient, *REST) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
f := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
f.TestIndex = true return NewREST(etcdStorage, testTTL), fakeClient
s := etcdstorage.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewStorage(s, testTTL)
} }
func TestEventCreate(t *testing.T) { func TestEventCreate(t *testing.T) {
@@ -101,7 +98,7 @@ func TestEventCreate(t *testing.T) {
} }
for name, item := range table { for name, item := range table {
fakeClient, storage := NewTestEventStorage(t) storage, fakeClient := newStorage(t)
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
_, err := storage.Create(ctx, item.toCreate) _, err := storage.Create(ctx, item.toCreate)
if !item.errOK(err) { if !item.errOK(err) {
@@ -217,7 +214,7 @@ func TestEventUpdate(t *testing.T) {
} }
for name, item := range table { for name, item := range table {
fakeClient, storage := NewTestEventStorage(t) storage, fakeClient := newStorage(t)
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
_, _, err := storage.Update(ctx, item.toUpdate) _, _, err := storage.Update(ctx, item.toUpdate)
if !item.errOK(err) { if !item.errOK(err) {

View File

@@ -20,7 +20,7 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd" etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
@@ -36,7 +36,7 @@ import (
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage return fakeEtcdClient, etcdStorage
} }
@@ -98,7 +98,7 @@ func TestGet(t *testing.T) {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &validController), Value: runtime.EncodeOrDie(testapi.Codec(), &validController),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -123,7 +123,7 @@ func TestUpdate(t *testing.T) {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &validController), Value: runtime.EncodeOrDie(testapi.Codec(), &validController),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -146,7 +146,7 @@ func TestUpdate(t *testing.T) {
} }
var controller api.ReplicationController var controller api.ReplicationController
latest.Codec.DecodeInto([]byte(response.Node.Value), &controller) testapi.Codec().DecodeInto([]byte(response.Node.Value), &controller)
if controller.Spec.Replicas != replicas { if controller.Spec.Replicas != replicas {
t.Errorf("wrong replicas count expected: %d got: %d", replicas, controller.Spec.Replicas) t.Errorf("wrong replicas count expected: %d got: %d", replicas, controller.Spec.Replicas)
} }

View File

@@ -28,14 +28,13 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for horizontal pod autoscalers against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewREST returns a RESTStorage object that will work against horizontal pod autoscalers. // NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
func NewREST(s storage.Interface) *REST { func NewREST(s storage.Interface) *REST {
var prefix = "/horizontalpodautoscalers" prefix := "/horizontalpodautoscalers"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &expapi.HorizontalPodAutoscaler{} }, NewFunc: func() runtime.Object { return &expapi.HorizontalPodAutoscaler{} },
// NewListFunc returns an object capable of storing results of an etcd list. // NewListFunc returns an object capable of storing results of an etcd list.
@@ -68,6 +67,5 @@ func NewREST(s storage.Interface) *REST {
Storage: s, Storage: s,
} }
return &REST{store} return &REST{store}
} }

View File

@@ -24,32 +24,19 @@ import (
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/expapi" "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/registry/registrytest" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "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"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
var scheme *runtime.Scheme func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
var codec runtime.Codec etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
return NewREST(etcdStorage), fakeClient
func init() {
// Ensure that expapi/v1 packege is used, so that it will get initialized and register HorizontalPodAutoscaler object.
dummy := v1.HorizontalPodAutoscaler{}
dummy.Spec = v1.HorizontalPodAutoscalerSpec{}
}
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 validNewHorizontalPodAutoscaler(name string) *expapi.HorizontalPodAutoscaler { func validNewHorizontalPodAutoscaler(name string) *expapi.HorizontalPodAutoscaler {
@@ -70,8 +57,8 @@ func validNewHorizontalPodAutoscaler(name string) *expapi.HorizontalPodAutoscale
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
autoscaler := validNewHorizontalPodAutoscaler("foo") autoscaler := validNewHorizontalPodAutoscaler("foo")
autoscaler.ObjectMeta = api.ObjectMeta{} autoscaler.ObjectMeta = api.ObjectMeta{}
test.TestCreate( test.TestCreate(
@@ -83,15 +70,15 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2 fakeClient.ChangeIndex = 2
autoscaler := validNewHorizontalPodAutoscaler("foo") autoscaler := validNewHorizontalPodAutoscaler("foo")
existing := validNewHorizontalPodAutoscaler("exists") existing := validNewHorizontalPodAutoscaler("exists")
existing.Namespace = test.TestNamespace() existing.Namespace = test.TestNamespace()
@@ -110,13 +97,13 @@ func TestUpdate(t *testing.T) {
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
autoscaler := validNewHorizontalPodAutoscaler("foo2") autoscaler := validNewHorizontalPodAutoscaler("foo2")
key, _ := storage.KeyFunc(ctx, "foo2") key, _ := storage.KeyFunc(ctx, "foo2")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(testapi.Codec(), autoscaler), Value: runtime.EncodeOrDie(testapi.Codec(), autoscaler),
@@ -127,32 +114,32 @@ func TestDelete(t *testing.T) {
return autoscaler return autoscaler
} }
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL == 30 return fakeClient.Data[key].R.Node.TTL == 30
} }
test.TestDelete(createFn, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
autoscaler := validNewHorizontalPodAutoscaler("foo") autoscaler := validNewHorizontalPodAutoscaler("foo")
test.TestGet(autoscaler) test.TestGet(autoscaler)
} }
func TestList(t *testing.T) { func TestList(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
autoscaler := validNewHorizontalPodAutoscaler("foo") autoscaler := validNewHorizontalPodAutoscaler("foo")
test.TestList( test.TestList(
autoscaler, autoscaler,
func(objects []runtime.Object) []runtime.Object { func(objects []runtime.Object) []runtime.Object {
return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) return registrytest.SetObjectsForKey(fakeClient, key, objects)
}, },
func(resourceVersion uint64) { func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) registrytest.SetResourceVersion(fakeClient, resourceVersion)
}) })
} }

View File

@@ -31,7 +31,8 @@ type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
func NewStorage(s storage.Interface) *REST { // NewREST returns a RESTStorage object that will work against horizontal pod autoscalers.
func NewREST(s storage.Interface) *REST {
prefix := "/limitranges" prefix := "/limitranges"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.LimitRange{} }, NewFunc: func() runtime.Object { return &api.LimitRange{} },

View File

@@ -25,8 +25,8 @@ import (
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/api/testapi"
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
"k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/runtime"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -34,11 +34,9 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func NewTestLimitRangeStorage(t *testing.T) (*tools.FakeEtcdClient, *REST) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
f := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
f.TestIndex = true return NewREST(etcdStorage), fakeClient
s := etcdstorage.NewEtcdStorage(f, testapi.Codec(), etcdtest.PathPrefix())
return f, NewStorage(s)
} }
func TestLimitRangeCreate(t *testing.T) { func TestLimitRangeCreate(t *testing.T) {
@@ -110,7 +108,7 @@ func TestLimitRangeCreate(t *testing.T) {
} }
for name, item := range table { for name, item := range table {
fakeClient, storage := NewTestLimitRangeStorage(t) storage, fakeClient := newStorage(t)
fakeClient.Data[path] = item.existing fakeClient.Data[path] = item.existing
_, err := storage.Create(ctx, item.toCreate) _, err := storage.Create(ctx, item.toCreate)
if !item.errOK(err) { if !item.errOK(err) {

View File

@@ -49,7 +49,7 @@ func (r *StatusREST) Update(ctx api.Context, obj runtime.Object) (runtime.Object
} }
// NewStorage returns a RESTStorage object that will work against nodes. // NewStorage returns a RESTStorage object that will work against nodes.
func NewStorage(s storage.Interface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) { func NewREST(s storage.Interface, connection client.ConnectionInfoGetter) (*REST, *StatusREST) {
prefix := "/minions" prefix := "/minions"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Node{} }, NewFunc: func() runtime.Object { return &api.Node{} },

View File

@@ -22,26 +22,19 @@ import (
"time" "time"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest" "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/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
const (
PASS = iota
FAIL
)
type fakeConnectionInfoGetter struct { type fakeConnectionInfoGetter struct {
} }
@@ -49,17 +42,10 @@ func (fakeConnectionInfoGetter) GetConnectionInfo(host string) (string, uint, ht
return "http", 12345, nil, nil return "http", 12345, nil, nil
} }
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient := tools.NewFakeEtcdClient(t)
fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient, s := newEtcdStorage(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
storage, _ := NewStorage(s, fakeConnectionInfoGetter{}) storage, _ := NewREST(etcdStorage, fakeConnectionInfoGetter{})
return storage, fakeEtcdClient return storage, fakeClient
} }
func validNewNode() *api.Node { func validNewNode() *api.Node {
@@ -89,8 +75,8 @@ func validChangedNode() *api.Node {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, fakeEtcdClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
node := validNewNode() node := validNewNode()
node.ObjectMeta = api.ObjectMeta{GenerateName: "foo"} node.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
test.TestCreate( test.TestCreate(
@@ -105,17 +91,17 @@ func TestCreate(t *testing.T) {
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, fakeEtcdClient := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
node := validChangedNode() node := validChangedNode()
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, node), Value: runtime.EncodeOrDie(testapi.Codec(), node),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -123,10 +109,10 @@ func TestDelete(t *testing.T) {
return node return node
} }
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL == 30 return fakeClient.Data[key].R.Node.TTL == 30
} }
test.TestDelete(createFn, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
@@ -160,7 +146,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewNode()), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewNode()), 0)
_, _, err := storage.Update(ctx, node) _, _, err := storage.Update(ctx, node)
if err != nil { if err != nil {
@@ -172,7 +158,7 @@ func TestEtcdUpdateEndpoints(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var nodeOut api.Node var nodeOut api.Node
err = latest.Codec.DecodeInto([]byte(response.Node.Value), &nodeOut) err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &nodeOut)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -189,7 +175,7 @@ func TestEtcdDeleteNode(t *testing.T) {
node := validNewNode() node := validNewNode()
key, _ := storage.KeyFunc(ctx, node.Name) key, _ := storage.KeyFunc(ctx, node.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, node), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), node), 0)
_, err := storage.Delete(ctx, node.Name, nil) _, err := storage.Delete(ctx, node.Name, nil)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@@ -245,7 +231,7 @@ func TestEtcdWatchNodesMatch(t *testing.T) {
} }
fakeClient.WaitForWatchCompletion() fakeClient.WaitForWatchCompletion()
nodeBytes, _ := latest.Codec.Encode(node) nodeBytes, _ := testapi.Codec().Encode(node)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{
@@ -278,7 +264,7 @@ func TestEtcdWatchNodesNotMatch(t *testing.T) {
} }
fakeClient.WaitForWatchCompletion() fakeClient.WaitForWatchCompletion()
nodeBytes, _ := latest.Codec.Encode(node) nodeBytes, _ := testapi.Codec().Encode(node)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{

View File

@@ -48,8 +48,8 @@ type FinalizeREST struct {
store *etcdgeneric.Etcd store *etcdgeneric.Etcd
} }
// NewStorage returns a RESTStorage object that will work against namespaces // NewREST returns a RESTStorage object that will work against namespaces.
func NewStorage(s storage.Interface) (*REST, *StatusREST, *FinalizeREST) { func NewREST(s storage.Interface) (*REST, *StatusREST, *FinalizeREST) {
prefix := "/namespaces" prefix := "/namespaces"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Namespace{} }, NewFunc: func() runtime.Object { return &api.Namespace{} },
@@ -67,11 +67,13 @@ func NewStorage(s storage.Interface) (*REST, *StatusREST, *FinalizeREST) {
return namespace.MatchNamespace(label, field) return namespace.MatchNamespace(label, field)
}, },
EndpointName: "namespaces", EndpointName: "namespaces",
Storage: s,
CreateStrategy: namespace.Strategy,
UpdateStrategy: namespace.Strategy,
ReturnDeletedObject: true,
Storage: s,
} }
store.CreateStrategy = namespace.Strategy
store.UpdateStrategy = namespace.Strategy
store.ReturnDeletedObject = true
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = namespace.StatusStrategy statusStore.UpdateStrategy = namespace.StatusStrategy

View File

@@ -20,13 +20,11 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/registry/namespace" "k8s.io/kubernetes/pkg/registry/namespace"
"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/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -34,17 +32,10 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true storage, _, _ := NewREST(etcdStorage)
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return storage, fakeClient
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient, s := newEtcdStorage(t)
storage, _, _ := NewStorage(s)
return storage, fakeEtcdClient, s
} }
func validNewNamespace() *api.Namespace { func validNewNamespace() *api.Namespace {
@@ -65,14 +56,13 @@ func validChangedNamespace() *api.Namespace {
} }
func TestStorage(t *testing.T) { func TestStorage(t *testing.T) {
storage, _, _ := newStorage(t) storage, _ := newStorage(t)
namespace.NewRegistry(storage) namespace.NewRegistry(storage)
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage, _, _ := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope()
namespace := validNewNamespace() namespace := validNewNamespace()
namespace.ObjectMeta = api.ObjectMeta{GenerateName: "foo"} namespace.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
test.TestCreate( test.TestCreate(
@@ -95,23 +85,19 @@ func expectNamespace(t *testing.T, out runtime.Object) (*api.Namespace, bool) {
} }
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage, _, _ := NewStorage(etcdStorage)
namespace := validNewNamespace() namespace := validNewNamespace()
_, err := storage.Create(api.NewContext(), namespace) ctx := api.NewContext()
if err != fakeEtcdClient.Err { _, err := storage.Create(ctx, namespace)
if err != fakeClient.Err {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := &api.Namespace{} object, err := storage.Get(ctx, "foo")
ctx := api.NewContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo")
if err != nil { if err != nil {
t.Fatalf("unexpected key error: %v", err) t.Errorf("unexpected error: %v", err)
}
if err := etcdStorage.Get(key, actual, false); err != nil {
t.Fatalf("unexpected extraction error: %v", err)
} }
actual := object.(*api.Namespace)
if actual.Name != namespace.Name { if actual.Name != namespace.Name {
t.Errorf("unexpected namespace: %#v", actual) t.Errorf("unexpected namespace: %#v", actual)
} }
@@ -124,18 +110,17 @@ func TestCreateSetsFields(t *testing.T) {
} }
func TestNamespaceDecode(t *testing.T) { func TestNamespaceDecode(t *testing.T) {
_, etcdStorage := newEtcdStorage(t) storage, _ := newStorage(t)
storage, _, _ := NewStorage(etcdStorage)
expected := validNewNamespace() expected := validNewNamespace()
expected.Status.Phase = api.NamespaceActive expected.Status.Phase = api.NamespaceActive
expected.Spec.Finalizers = []api.FinalizerName{api.FinalizerKubernetes} expected.Spec.Finalizers = []api.FinalizerName{api.FinalizerKubernetes}
body, err := latest.Codec.Encode(expected) body, err := testapi.Codec().Encode(expected)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := storage.New() actual := storage.New()
if err := latest.Codec.DecodeInto(body, actual); err != nil { if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -145,38 +130,37 @@ func TestNamespaceDecode(t *testing.T) {
} }
func TestGet(t *testing.T) { func TestGet(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
namespace := validNewNamespace() namespace := validNewNamespace()
test.TestGet(namespace) test.TestGet(namespace)
} }
func TestList(t *testing.T) { func TestList(t *testing.T) {
storage, fakeEtcdClient, _ := newStorage(t) storage, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
namespace := validNewNamespace() namespace := validNewNamespace()
test.TestList( test.TestList(
namespace, namespace,
func(objects []runtime.Object) []runtime.Object { func(objects []runtime.Object) []runtime.Object {
return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) return registrytest.SetObjectsForKey(fakeClient, key, objects)
}, },
func(resourceVersion uint64) { func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) registrytest.SetResourceVersion(fakeClient, resourceVersion)
}) })
} }
func TestDeleteNamespace(t *testing.T) { func TestDeleteNamespace(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
storage, _, _ := NewStorage(etcdStorage)
ctx := api.NewContext() ctx := api.NewContext()
key, err := storage.Etcd.KeyFunc(ctx, "foo") key, err := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ Value: runtime.EncodeOrDie(testapi.Codec(), &api.Namespace{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
}, },
@@ -195,14 +179,14 @@ func TestDeleteNamespace(t *testing.T) {
} }
func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) { func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
now := util.Now() storage, fakeClient := newStorage(t)
fakeEtcdClient, etcdStorage := newEtcdStorage(t) fakeClient.ChangeIndex = 1
fakeEtcdClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces/foo") key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ now := util.Now()
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ Value: runtime.EncodeOrDie(testapi.Codec(), &api.Namespace{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
DeletionTimestamp: &now, DeletionTimestamp: &now,
@@ -217,7 +201,6 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(etcdStorage)
_, err := storage.Delete(api.NewContext(), "foo", nil) _, err := storage.Delete(api.NewContext(), "foo", nil)
if err == nil { if err == nil {
t.Fatalf("expected error: %v", err) t.Fatalf("expected error: %v", err)
@@ -225,14 +208,14 @@ func TestDeleteNamespaceWithIncompleteFinalizers(t *testing.T) {
} }
func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) { func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
now := util.Now() storage, fakeClient := newStorage(t)
fakeEtcdClient, etcdStorage := newEtcdStorage(t) fakeClient.ChangeIndex = 1
fakeEtcdClient.ChangeIndex = 1
key := etcdtest.AddPrefix("/namespaces/foo") key := etcdtest.AddPrefix("/namespaces/foo")
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ now := util.Now()
fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Namespace{ Value: runtime.EncodeOrDie(testapi.Codec(), &api.Namespace{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
DeletionTimestamp: &now, DeletionTimestamp: &now,
@@ -247,7 +230,6 @@ func TestDeleteNamespaceWithCompleteFinalizers(t *testing.T) {
}, },
}, },
} }
storage, _, _ := NewStorage(etcdStorage)
_, err := storage.Delete(api.NewContext(), "foo", nil) _, err := storage.Delete(api.NewContext(), "foo", nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)

View File

@@ -29,13 +29,12 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for persistentvolumes against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewREST returns a RESTStorage object that will work against PersistentVolume objects. // NewREST returns a RESTStorage object that will work against persistent volumes.
func NewStorage(s storage.Interface) (*REST, *StatusREST) { func NewREST(s storage.Interface) (*REST, *StatusREST) {
prefix := "/persistentvolumes" prefix := "/persistentvolumes"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolume{} }, NewFunc: func() runtime.Object { return &api.PersistentVolume{} },
@@ -54,13 +53,13 @@ func NewStorage(s storage.Interface) (*REST, *StatusREST) {
}, },
EndpointName: "persistentvolume", EndpointName: "persistentvolume",
CreateStrategy: persistentvolume.Strategy,
UpdateStrategy: persistentvolume.Strategy,
ReturnDeletedObject: true,
Storage: s, Storage: s,
} }
store.CreateStrategy = persistentvolume.Strategy
store.UpdateStrategy = persistentvolume.Strategy
store.ReturnDeletedObject = true
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = persistentvolume.StatusStrategy statusStore.UpdateStrategy = persistentvolume.StatusStrategy

View File

@@ -20,13 +20,11 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"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/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -34,12 +32,10 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true storage, statusStorage := NewREST(etcdStorage)
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return storage, statusStorage, fakeClient
storage, statusStorage := NewStorage(etcdStorage)
return storage, statusStorage, fakeEtcdClient, etcdStorage
} }
func validNewPersistentVolume(name string) *api.PersistentVolume { func validNewPersistentVolume(name string) *api.PersistentVolume {
@@ -73,8 +69,8 @@ func validChangedPersistentVolume() *api.PersistentVolume {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, _, fakeEtcdClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
pv := validNewPersistentVolume("foo") pv := validNewPersistentVolume("foo")
pv.ObjectMeta = api.ObjectMeta{GenerateName: "foo"} pv.ObjectMeta = api.ObjectMeta{GenerateName: "foo"}
test.TestCreate( test.TestCreate(
@@ -89,17 +85,17 @@ func TestCreate(t *testing.T) {
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, _, fakeEtcdClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
pv := validChangedPersistentVolume() pv := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, pv.Name) key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, pv), Value: runtime.EncodeOrDie(testapi.Codec(), pv),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -107,23 +103,23 @@ func TestDelete(t *testing.T) {
return pv return pv
} }
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL == 30 return fakeClient.Data[key].R.Node.TTL == 30
} }
test.TestDelete(createFn, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
func TestEtcdGetPersistentVolumes(t *testing.T) { func TestEtcdGetPersistentVolumes(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
persistentVolume := validNewPersistentVolume("foo") persistentVolume := validNewPersistentVolume("foo")
test.TestGet(persistentVolume) test.TestGet(persistentVolume)
} }
func TestEtcdListPersistentVolumes(t *testing.T) { func TestEtcdListPersistentVolumes(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError).ClusterScope() test := resttest.New(t, storage, fakeClient.SetError).ClusterScope()
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
persistentVolume := validNewPersistentVolume("foo") persistentVolume := validNewPersistentVolume("foo")
@@ -138,15 +134,15 @@ func TestEtcdListPersistentVolumes(t *testing.T) {
} }
func TestPersistentVolumesDecode(t *testing.T) { func TestPersistentVolumesDecode(t *testing.T) {
storage, _, _, _ := newStorage(t) storage, _, _ := newStorage(t)
expected := validNewPersistentVolume("foo") expected := validNewPersistentVolume("foo")
body, err := latest.Codec.Encode(expected) body, err := testapi.Codec().Encode(expected)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := storage.New() actual := storage.New()
if err := latest.Codec.DecodeInto(body, actual); err != nil { if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -157,12 +153,12 @@ func TestPersistentVolumesDecode(t *testing.T) {
func TestEtcdUpdatePersistentVolumes(t *testing.T) { func TestEtcdUpdatePersistentVolumes(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
persistentVolume := validChangedPersistentVolume() persistentVolume := validChangedPersistentVolume()
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolume("foo")), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewPersistentVolume("foo")), 0)
_, _, err := storage.Update(ctx, persistentVolume) _, _, err := storage.Update(ctx, persistentVolume)
if err != nil { if err != nil {
@@ -174,7 +170,7 @@ func TestEtcdUpdatePersistentVolumes(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var persistentVolumeOut api.PersistentVolume var persistentVolumeOut api.PersistentVolume
err = latest.Codec.DecodeInto([]byte(response.Node.Value), &persistentVolumeOut) err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &persistentVolumeOut)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -187,7 +183,7 @@ func TestEtcdUpdatePersistentVolumes(t *testing.T) {
func TestDeletePersistentVolumes(t *testing.T) { func TestDeletePersistentVolumes(t *testing.T) {
ctx := api.NewContext() ctx := api.NewContext()
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
persistentVolume := validNewPersistentVolume("foo") persistentVolume := validNewPersistentVolume("foo")
name := persistentVolume.Name name := persistentVolume.Name
key, _ := storage.KeyFunc(ctx, name) key, _ := storage.KeyFunc(ctx, name)
@@ -196,7 +192,7 @@ func TestDeletePersistentVolumes(t *testing.T) {
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, persistentVolume), Value: runtime.EncodeOrDie(testapi.Codec(), persistentVolume),
ModifiedIndex: 1, ModifiedIndex: 1,
CreatedIndex: 1, CreatedIndex: 1,
}, },
@@ -209,14 +205,14 @@ func TestDeletePersistentVolumes(t *testing.T) {
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient, etcdStorage := newStorage(t) storage, statusStorage, fakeClient := newStorage(t)
ctx := api.NewContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
ctx := api.NewContext()
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
pvStart := validNewPersistentVolume("foo") pvStart := validNewPersistentVolume("foo")
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), pvStart), 1)
pvIn := &api.PersistentVolume{ pvIn := &api.PersistentVolume{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@@ -237,12 +233,11 @@ func TestEtcdUpdateStatus(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var pvOut api.PersistentVolume pvOut, err := storage.Get(ctx, "foo")
key, _ = storage.KeyFunc(ctx, "foo") if err != nil {
if err := etcdStorage.Get(key, &pvOut, false); err != nil { t.Errorf("unexpected error: %v", err)
t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, pvOut) { if !api.Semantic.DeepEqual(&expected, pvOut) {
t.Errorf("unexpected object: %s", util.ObjectDiff(expected, pvOut)) t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, pvOut))
} }
} }

View File

@@ -27,13 +27,12 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for persistentvolumeclaims against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewREST returns a RESTStorage object that will work against PersistentVolumeClaim objects. // NewREST returns a RESTStorage object that will work against persistent volume claims.
func NewStorage(s storage.Interface) (*REST, *StatusREST) { func NewREST(s storage.Interface) (*REST, *StatusREST) {
prefix := "/persistentvolumeclaims" prefix := "/persistentvolumeclaims"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} }, NewFunc: func() runtime.Object { return &api.PersistentVolumeClaim{} },
@@ -52,13 +51,13 @@ func NewStorage(s storage.Interface) (*REST, *StatusREST) {
}, },
EndpointName: "persistentvolumeclaims", EndpointName: "persistentvolumeclaims",
CreateStrategy: persistentvolumeclaim.Strategy,
UpdateStrategy: persistentvolumeclaim.Strategy,
ReturnDeletedObject: true,
Storage: s, Storage: s,
} }
store.CreateStrategy = persistentvolumeclaim.Strategy
store.UpdateStrategy = persistentvolumeclaim.Strategy
store.ReturnDeletedObject = true
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = persistentvolumeclaim.StatusStrategy statusStore.UpdateStrategy = persistentvolumeclaim.StatusStrategy

View File

@@ -20,13 +20,11 @@ import (
"testing" "testing"
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi"
"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/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -34,12 +32,10 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true storage, statusStorage := NewREST(etcdStorage)
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return storage, statusStorage, fakeClient
storage, statusStorage := NewStorage(etcdStorage)
return storage, statusStorage, fakeEtcdClient, etcdStorage
} }
func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim { func validNewPersistentVolumeClaim(name, ns string) *api.PersistentVolumeClaim {
@@ -70,9 +66,8 @@ func validChangedPersistentVolumeClaim() *api.PersistentVolumeClaim {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
storage, _, fakeClient := newStorage(t)
registry, _, fakeEtcdClient, _ := newStorage(t) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, registry, fakeEtcdClient.SetError)
pv := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) pv := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
pv.ObjectMeta = api.ObjectMeta{} pv.ObjectMeta = api.ObjectMeta{}
test.TestCreate( test.TestCreate(
@@ -87,17 +82,17 @@ func TestCreate(t *testing.T) {
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
storage, _, fakeEtcdClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
pv := validChangedPersistentVolumeClaim() pv := validChangedPersistentVolumeClaim()
key, _ := storage.KeyFunc(ctx, pv.Name) key, _ := storage.KeyFunc(ctx, pv.Name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
createFn := func() runtime.Object { createFn := func() runtime.Object {
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, pv), Value: runtime.EncodeOrDie(testapi.Codec(), pv),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -105,23 +100,23 @@ func TestDelete(t *testing.T) {
return pv return pv
} }
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL == 30 return fakeClient.Data[key].R.Node.TTL == 30
} }
test.TestDelete(createFn, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
func TestEtcdGetPersistentVolumeClaims(t *testing.T) { func TestEtcdGetPersistentVolumeClaims(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
claim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) claim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
test.TestGet(claim) test.TestGet(claim)
} }
func TestEtcdListPersistentVolumeClaims(t *testing.T) { func TestEtcdListPersistentVolumeClaims(t *testing.T) {
storage, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
test := resttest.New(t, storage, fakeClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.KeyRootFunc(test.TestContext()))
claim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) claim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
@@ -136,15 +131,15 @@ func TestEtcdListPersistentVolumeClaims(t *testing.T) {
} }
func TestPersistentVolumeClaimsDecode(t *testing.T) { func TestPersistentVolumeClaimsDecode(t *testing.T) {
registry, _, _, _ := newStorage(t) storage, _, _ := newStorage(t)
expected := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) expected := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
body, err := latest.Codec.Encode(expected) body, err := testapi.Codec().Encode(expected)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := registry.New() actual := storage.New()
if err := latest.Codec.DecodeInto(body, actual); err != nil { if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -155,14 +150,14 @@ func TestPersistentVolumeClaimsDecode(t *testing.T) {
func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) { func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
registry, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
persistentVolume := validChangedPersistentVolumeClaim() persistentVolume := validChangedPersistentVolumeClaim()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewPersistentVolumeClaim("foo", api.NamespaceDefault)), 0)
_, _, err := registry.Update(ctx, persistentVolume) _, _, err := storage.Update(ctx, persistentVolume)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -172,7 +167,7 @@ func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var persistentVolumeOut api.PersistentVolumeClaim var persistentVolumeOut api.PersistentVolumeClaim
err = latest.Codec.DecodeInto([]byte(response.Node.Value), &persistentVolumeOut) err = testapi.Codec().DecodeInto([]byte(response.Node.Value), &persistentVolumeOut)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -185,36 +180,36 @@ func TestEtcdUpdatePersistentVolumeClaims(t *testing.T) {
func TestDeletePersistentVolumeClaims(t *testing.T) { func TestDeletePersistentVolumeClaims(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
registry, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) pvClaim := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
name := pvClaim.Name name := pvClaim.Name
key, _ := registry.KeyFunc(ctx, name) key, _ := storage.KeyFunc(ctx, name)
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, pvClaim), Value: runtime.EncodeOrDie(testapi.Codec(), pvClaim),
ModifiedIndex: 1, ModifiedIndex: 1,
CreatedIndex: 1, CreatedIndex: 1,
}, },
}, },
} }
_, err := registry.Delete(ctx, name, nil) _, err := storage.Delete(ctx, name, nil)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
storage, statusStorage, fakeClient, etcdStorage := newStorage(t) storage, statusStorage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := storage.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault) pvcStart := validNewPersistentVolumeClaim("foo", api.NamespaceDefault)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, pvcStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), pvcStart), 1)
pvc := &api.PersistentVolumeClaim{ pvc := &api.PersistentVolumeClaim{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@@ -244,12 +239,11 @@ func TestEtcdUpdateStatus(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var pvcOut api.PersistentVolumeClaim pvcOut, err := storage.Get(ctx, "foo")
key, _ = storage.KeyFunc(ctx, "foo") if err != nil {
if err := etcdStorage.Get(key, &pvcOut, false); err != nil { t.Errorf("unexpected error: %v", err)
t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, pvcOut) { if !api.Semantic.DeepEqual(&expected, pvcOut) {
t.Errorf("unexpected object: %s", util.ObjectDiff(expected, pvcOut)) t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, pvcOut))
} }
} }

View File

@@ -25,17 +25,15 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"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/latest"
"k8s.io/kubernetes/pkg/api/rest" "k8s.io/kubernetes/pkg/api/rest"
"k8s.io/kubernetes/pkg/api/rest/resttest" "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/pod" "k8s.io/kubernetes/pkg/registry/pod"
"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/securitycontext" "k8s.io/kubernetes/pkg/securitycontext"
"k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"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"
@@ -43,17 +41,10 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *BindingREST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t)
storage := NewStorage(etcdStorage, nil) storage := NewStorage(etcdStorage, nil)
return storage.Pod, storage.Binding, storage.Status, fakeEtcdClient, etcdStorage return storage.Pod, storage.Binding, storage.Status, fakeClient
} }
func validNewPod() *api.Pod { func validNewPod() *api.Pod {
@@ -89,14 +80,13 @@ func validChangedPod() *api.Pod {
} }
func TestStorage(t *testing.T) { func TestStorage(t *testing.T) {
storage, _, _, _, _ := newStorage(t) storage, _, _, _ := newStorage(t)
pod.NewRegistry(storage) pod.NewRegistry(storage)
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
pod := validNewPod() pod := validNewPod()
pod.ObjectMeta = api.ObjectMeta{} pod.ObjectMeta = api.ObjectMeta{}
// Make an invalid pod with an an incorrect label. // Make an invalid pod with an an incorrect label.
@@ -120,19 +110,18 @@ func TestCreate(t *testing.T) {
} }
func TestDelete(t *testing.T) { func TestDelete(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
test := resttest.New(t, storage, fakeEtcdClient.SetError) test := resttest.New(t, storage, fakeClient.SetError)
createFn := func() runtime.Object { createFn := func() runtime.Object {
pod := validChangedPod() pod := validChangedPod()
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, pod), Value: runtime.EncodeOrDie(testapi.Codec(), pod),
ModifiedIndex: 1, ModifiedIndex: 1,
}, },
}, },
@@ -140,10 +129,10 @@ func TestDelete(t *testing.T) {
return pod return pod
} }
gracefulSetFn := func() bool { gracefulSetFn := func() bool {
if fakeEtcdClient.Data[key].R.Node == nil { if fakeClient.Data[key].R.Node == nil {
return false return false
} }
return fakeEtcdClient.Data[key].R.Node.TTL == 30 return fakeClient.Data[key].R.Node.TTL == 30
} }
test.TestDelete(createFn, gracefulSetFn) test.TestDelete(createFn, gracefulSetFn)
} }
@@ -158,31 +147,29 @@ func expectPod(t *testing.T, out runtime.Object) (*api.Pod, bool) {
} }
func TestCreateRegistryError(t *testing.T) { func TestCreateRegistryError(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeClient.Err = fmt.Errorf("test error")
storage := NewStorage(etcdStorage, nil).Pod
pod := validNewPod() pod := validNewPod()
_, err := storage.Create(api.NewDefaultContext(), pod) _, err := storage.Create(api.NewDefaultContext(), pod)
if err != fakeEtcdClient.Err { if err != fakeClient.Err {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} }
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod
pod := validNewPod() pod := validNewPod()
_, err := storage.Create(api.NewDefaultContext(), pod) _, err := storage.Create(api.NewDefaultContext(), pod)
if err != fakeEtcdClient.Err { if err != fakeClient.Err {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") object, err := storage.Get(ctx, "foo")
actual := &api.Pod{} if err != nil {
if err := etcdStorage.Get(key, actual, false); err != nil { t.Errorf("unexpected error: %v", err)
t.Fatalf("unexpected extraction error: %v", err)
} }
actual := object.(*api.Pod)
if actual.Name != pod.Name { if actual.Name != pod.Name {
t.Errorf("unexpected pod: %#v", actual) t.Errorf("unexpected pod: %#v", actual)
} }
@@ -192,16 +179,15 @@ func TestCreateSetsFields(t *testing.T) {
} }
func TestPodDecode(t *testing.T) { func TestPodDecode(t *testing.T) {
_, etcdStorage := newEtcdStorage(t) storage, _, _, _ := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod
expected := validNewPod() expected := validNewPod()
body, err := latest.Codec.Encode(expected) body, err := testapi.Codec().Encode(expected)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := storage.New() actual := storage.New()
if err := latest.Codec.DecodeInto(body, actual); err != nil { if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -211,15 +197,14 @@ func TestPodDecode(t *testing.T) {
} }
func TestUpdateWithConflictingNamespace(t *testing.T) { func TestUpdateWithConflictingNamespace(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ Value: runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"}, ObjectMeta: api.ObjectMeta{Name: "foo", Namespace: "default"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: api.PodSpec{NodeName: "machine"},
}), }),
@@ -336,14 +321,13 @@ func TestResourceLocation(t *testing.T) {
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
for _, tc := range testCases { for _, tc := range testCases {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &tc.pod), Value: runtime.EncodeOrDie(testapi.Codec(), &tc.pod),
}, },
}, },
} }
@@ -367,16 +351,15 @@ func TestResourceLocation(t *testing.T) {
} }
func TestDeletePod(t *testing.T) { func TestDeletePod(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
storage := NewStorage(etcdStorage, nil).Pod
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ Value: runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
@@ -395,34 +378,32 @@ func TestDeletePod(t *testing.T) {
} }
func TestEtcdGet(t *testing.T) { func TestEtcdGet(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
pod := validNewPod() pod := validNewPod()
test.TestGet(pod) test.TestGet(pod)
} }
func TestEtcdList(t *testing.T) { func TestEtcdList(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, _, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage, nil).Pod test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key := etcdtest.AddPrefix(storage.Etcd.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.Etcd.KeyRootFunc(test.TestContext()))
pod := validNewPod() pod := validNewPod()
test.TestList( test.TestList(
pod, pod,
func(objects []runtime.Object) []runtime.Object { func(objects []runtime.Object) []runtime.Object {
return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) return registrytest.SetObjectsForKey(fakeClient, key, objects)
}, },
func(resourceVersion uint64) { func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) registrytest.SetResourceVersion(fakeClient, resourceVersion)
}) })
} }
func TestEtcdCreate(t *testing.T) { func TestEtcdCreate(t *testing.T) {
registry, bindingRegistry, _, fakeClient, _ := newStorage(t) storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@@ -430,13 +411,13 @@ func TestEtcdCreate(t *testing.T) {
}, },
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
_, err := registry.Create(ctx, validNewPod()) _, err := storage.Create(ctx, validNewPod())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
// Suddenly, a wild scheduler appears: // Suddenly, a wild scheduler appears:
_, err = bindingRegistry.Create(ctx, &api.Binding{ _, err = bindingStorage.Create(ctx, &api.Binding{
ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"}, ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"},
Target: api.ObjectReference{Name: "machine"}, Target: api.ObjectReference{Name: "machine"},
}) })
@@ -449,7 +430,7 @@ func TestEtcdCreate(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var pod api.Pod var pod api.Pod
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &pod) err = testapi.Codec().DecodeInto([]byte(resp.Node.Value), &pod)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -457,17 +438,16 @@ func TestEtcdCreate(t *testing.T) {
if pod.Name != "foo" { if pod.Name != "foo" {
t.Errorf("Unexpected pod: %#v %s", pod, resp.Node.Value) t.Errorf("Unexpected pod: %#v %s", pod, resp.Node.Value)
} }
} }
// Ensure that when scheduler creates a binding for a pod that has already been deleted // Ensure that when scheduler creates a binding for a pod that has already been deleted
// by the API server, API server returns not-found error. // by the API server, API server returns not-found error.
func TestEtcdCreateBindingNoPod(t *testing.T) { func TestEtcdCreateBindingNoPod(t *testing.T) {
registry, bindingRegistry, _, fakeClient, _ := newStorage(t) storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@@ -479,7 +459,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) {
// - Create (apiserver) // - Create (apiserver)
// - Schedule (scheduler) // - Schedule (scheduler)
// - Delete (apiserver) // - Delete (apiserver)
_, err := bindingRegistry.Create(ctx, &api.Binding{ _, err := bindingStorage.Create(ctx, &api.Binding{
ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"}, ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"},
Target: api.ObjectReference{Name: "machine"}, Target: api.ObjectReference{Name: "machine"},
}) })
@@ -490,7 +470,7 @@ func TestEtcdCreateBindingNoPod(t *testing.T) {
t.Fatalf("Unexpected error returned: %#v", err) t.Fatalf("Unexpected error returned: %#v", err)
} }
_, err = registry.Get(ctx, "foo") _, err = storage.Get(ctx, "foo")
if err == nil { if err == nil {
t.Fatalf("Expected not-found-error but got nothing") t.Fatalf("Expected not-found-error but got nothing")
} }
@@ -500,11 +480,11 @@ func TestEtcdCreateBindingNoPod(t *testing.T) {
} }
func TestEtcdCreateFailsWithoutNamespace(t *testing.T) { func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
fakeClient.TestIndex = true fakeClient.TestIndex = true
pod := validNewPod() pod := validNewPod()
pod.Namespace = "" pod.Namespace = ""
_, err := registry.Create(api.NewContext(), pod) _, err := storage.Create(api.NewContext(), pod)
// Accept "namespace" or "Namespace". // Accept "namespace" or "Namespace".
if err == nil || !strings.Contains(err.Error(), "amespace") { if err == nil || !strings.Contains(err.Error(), "amespace") {
t.Fatalf("expected error that namespace was missing from context, got: %v", err) t.Fatalf("expected error that namespace was missing from context, got: %v", err)
@@ -512,29 +492,29 @@ func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
} }
func TestEtcdCreateAlreadyExisting(t *testing.T) { func TestEtcdCreateAlreadyExisting(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}), Value: runtime.EncodeOrDie(testapi.Codec(), &api.Pod{ObjectMeta: api.ObjectMeta{Name: "foo"}}),
}, },
}, },
E: nil, E: nil,
} }
_, err := registry.Create(ctx, validNewPod()) _, err := storage.Create(ctx, validNewPod())
if !errors.IsAlreadyExists(err) { if !errors.IsAlreadyExists(err) {
t.Errorf("Unexpected error returned: %#v", err) t.Errorf("Unexpected error returned: %#v", err)
} }
} }
func TestEtcdCreateWithContainersNotFound(t *testing.T) { func TestEtcdCreateWithContainersNotFound(t *testing.T) {
registry, bindingRegistry, _, fakeClient, _ := newStorage(t) storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@@ -542,13 +522,13 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
}, },
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
_, err := registry.Create(ctx, validNewPod()) _, err := storage.Create(ctx, validNewPod())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
// Suddenly, a wild scheduler appears: // Suddenly, a wild scheduler appears:
_, err = bindingRegistry.Create(ctx, &api.Binding{ _, err = bindingStorage.Create(ctx, &api.Binding{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
Name: "foo", Name: "foo",
@@ -565,7 +545,7 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var pod api.Pod var pod api.Pod
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &pod) err = testapi.Codec().DecodeInto([]byte(resp.Node.Value), &pod)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -579,10 +559,10 @@ func TestEtcdCreateWithContainersNotFound(t *testing.T) {
} }
func TestEtcdCreateWithConflict(t *testing.T) { func TestEtcdCreateWithConflict(t *testing.T) {
registry, bindingRegistry, _, fakeClient, _ := newStorage(t) storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: nil, Node: nil,
@@ -590,7 +570,7 @@ func TestEtcdCreateWithConflict(t *testing.T) {
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
_, err := registry.Create(ctx, validNewPod()) _, err := storage.Create(ctx, validNewPod())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -604,22 +584,22 @@ func TestEtcdCreateWithConflict(t *testing.T) {
}, },
Target: api.ObjectReference{Name: "machine"}, Target: api.ObjectReference{Name: "machine"},
} }
_, err = bindingRegistry.Create(ctx, &binding) _, err = bindingStorage.Create(ctx, &binding)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
_, err = bindingRegistry.Create(ctx, &binding) _, err = bindingStorage.Create(ctx, &binding)
if err == nil || !errors.IsConflict(err) { if err == nil || !errors.IsConflict(err) {
t.Fatalf("expected resource conflict error, not: %v", err) t.Fatalf("expected resource conflict error, not: %v", err)
} }
} }
func TestEtcdCreateWithExistingContainers(t *testing.T) { func TestEtcdCreateWithExistingContainers(t *testing.T) {
registry, bindingRegistry, _, fakeClient, _ := newStorage(t) storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@@ -627,13 +607,13 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
}, },
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
_, err := registry.Create(ctx, validNewPod()) _, err := storage.Create(ctx, validNewPod())
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
// Suddenly, a wild scheduler appears: // Suddenly, a wild scheduler appears:
_, err = bindingRegistry.Create(ctx, &api.Binding{ _, err = bindingStorage.Create(ctx, &api.Binding{
ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"}, ObjectMeta: api.ObjectMeta{Namespace: api.NamespaceDefault, Name: "foo"},
Target: api.ObjectReference{Name: "machine"}, Target: api.ObjectReference{Name: "machine"},
}) })
@@ -646,7 +626,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
t.Fatalf("Unexpected error %v", err) t.Fatalf("Unexpected error %v", err)
} }
var pod api.Pod var pod api.Pod
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &pod) err = testapi.Codec().DecodeInto([]byte(resp.Node.Value), &pod)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -657,7 +637,7 @@ func TestEtcdCreateWithExistingContainers(t *testing.T) {
} }
func TestEtcdCreateBinding(t *testing.T) { func TestEtcdCreateBinding(t *testing.T) {
registry, bindingRegistry, _, fakeClient, _ := newStorage(t) storage, bindingStorage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
@@ -702,7 +682,7 @@ func TestEtcdCreateBinding(t *testing.T) {
}, },
} }
for k, test := range testCases { for k, test := range testCases {
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
@@ -710,14 +690,14 @@ func TestEtcdCreateBinding(t *testing.T) {
}, },
E: tools.EtcdErrorNotFound, E: tools.EtcdErrorNotFound,
} }
if _, err := registry.Create(ctx, validNewPod()); err != nil { if _, err := storage.Create(ctx, validNewPod()); err != nil {
t.Fatalf("%s: unexpected error: %v", k, err) t.Fatalf("%s: unexpected error: %v", k, err)
} }
if _, err := bindingRegistry.Create(ctx, &test.binding); !test.errOK(err) { if _, err := bindingStorage.Create(ctx, &test.binding); !test.errOK(err) {
t.Errorf("%s: unexpected error: %v", k, err) t.Errorf("%s: unexpected error: %v", k, err)
} else if err == nil { } else if err == nil {
// If bind succeeded, verify Host field in pod's Spec. // If bind succeeded, verify Host field in pod's Spec.
pod, err := registry.Get(ctx, validNewPod().ObjectMeta.Name) pod, err := storage.Get(ctx, validNewPod().ObjectMeta.Name)
if err != nil { if err != nil {
t.Errorf("%s: unexpected error: %v", k, err) t.Errorf("%s: unexpected error: %v", k, err)
} else if pod.(*api.Pod).Spec.NodeName != test.binding.Target.Name { } else if pod.(*api.Pod).Spec.NodeName != test.binding.Target.Name {
@@ -728,11 +708,11 @@ func TestEtcdCreateBinding(t *testing.T) {
} }
func TestEtcdUpdateNotFound(t *testing.T) { func TestEtcdUpdateNotFound(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{}, R: &etcd.Response{},
@@ -748,23 +728,23 @@ func TestEtcdUpdateNotFound(t *testing.T) {
}, },
}, },
} }
_, _, err := registry.Update(ctx, &podIn) _, _, err := storage.Update(ctx, &podIn)
if err == nil { if err == nil {
t.Errorf("unexpected non-error") t.Errorf("unexpected non-error")
} }
} }
func TestEtcdUpdateNotScheduled(t *testing.T) { func TestEtcdUpdateNotScheduled(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, validNewPod()), 1) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), validNewPod()), 1)
podIn := validChangedPod() podIn := validChangedPod()
_, _, err := registry.Update(ctx, podIn) _, _, err := storage.Update(ctx, podIn)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -773,20 +753,20 @@ func TestEtcdUpdateNotScheduled(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
podOut := &api.Pod{} podOut := &api.Pod{}
latest.Codec.DecodeInto([]byte(response.Node.Value), podOut) testapi.Codec().DecodeInto([]byte(response.Node.Value), podOut)
if !api.Semantic.DeepEqual(podOut, podIn) { if !api.Semantic.DeepEqual(podOut, podIn) {
t.Errorf("objects differ: %v", util.ObjectDiff(podOut, podIn)) t.Errorf("objects differ: %v", util.ObjectDiff(podOut, podIn))
} }
} }
func TestEtcdUpdateScheduled(t *testing.T) { func TestEtcdUpdateScheduled(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
@@ -826,7 +806,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
DNSPolicy: api.DNSClusterFirst, DNSPolicy: api.DNSClusterFirst,
}, },
} }
_, _, err := registry.Update(ctx, &podIn) _, _, err := storage.Update(ctx, &podIn)
if err != nil { if err != nil {
t.Errorf("Unexpected error: %v", err) t.Errorf("Unexpected error: %v", err)
} }
@@ -835,7 +815,7 @@ func TestEtcdUpdateScheduled(t *testing.T) {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var podOut api.Pod var podOut api.Pod
latest.Codec.DecodeInto([]byte(response.Node.Value), &podOut) testapi.Codec().DecodeInto([]byte(response.Node.Value), &podOut)
if !api.Semantic.DeepEqual(podOut, podIn) { if !api.Semantic.DeepEqual(podOut, podIn) {
t.Errorf("expected: %#v, got: %#v", podOut, podIn) t.Errorf("expected: %#v, got: %#v", podOut, podIn)
} }
@@ -843,11 +823,11 @@ func TestEtcdUpdateScheduled(t *testing.T) {
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
registry, _, status, fakeClient, etcdStorage := newStorage(t) storage, _, statusStorage, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
podStart := api.Pod{ podStart := api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@@ -864,7 +844,7 @@ func TestEtcdUpdateStatus(t *testing.T) {
}, },
}, },
} }
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &podStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &podStart), 1)
podIn := api.Pod{ podIn := api.Pod{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@@ -900,32 +880,31 @@ func TestEtcdUpdateStatus(t *testing.T) {
expected.Labels = podIn.Labels expected.Labels = podIn.Labels
expected.Status = podIn.Status expected.Status = podIn.Status
_, _, err := status.Update(ctx, &podIn) _, _, err := statusStorage.Update(ctx, &podIn)
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var podOut api.Pod podOut, err := storage.Get(ctx, "foo")
key, _ = registry.KeyFunc(ctx, "foo") if err != nil {
if err := etcdStorage.Get(key, &podOut, false); err != nil { t.Errorf("unexpected error: %v", err)
t.Fatalf("Unexpected error: %v", err)
} }
if !api.Semantic.DeepEqual(expected, podOut) { if !api.Semantic.DeepEqual(&expected, podOut) {
t.Errorf("unexpected object: %s", util.ObjectDiff(expected, podOut)) t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, podOut))
} }
} }
func TestEtcdDeletePod(t *testing.T) { func TestEtcdDeletePod(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: api.PodSpec{NodeName: "machine"},
}), 0) }), 0)
_, err := registry.Delete(ctx, "foo", api.NewDeleteOptions(0)) _, err := storage.Delete(ctx, "foo", api.NewDeleteOptions(0))
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -938,16 +917,16 @@ func TestEtcdDeletePod(t *testing.T) {
} }
func TestEtcdDeletePodMultipleContainers(t *testing.T) { func TestEtcdDeletePodMultipleContainers(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, &api.Pod{ fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), &api.Pod{
ObjectMeta: api.ObjectMeta{Name: "foo"}, ObjectMeta: api.ObjectMeta{Name: "foo"},
Spec: api.PodSpec{NodeName: "machine"}, Spec: api.PodSpec{NodeName: "machine"},
}), 0) }), 0)
_, err := registry.Delete(ctx, "foo", api.NewDeleteOptions(0)) _, err := storage.Delete(ctx, "foo", api.NewDeleteOptions(0))
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -961,9 +940,9 @@ func TestEtcdDeletePodMultipleContainers(t *testing.T) {
} }
func TestEtcdWatchPods(t *testing.T) { func TestEtcdWatchPods(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := storage.Watch(ctx,
labels.Everything(), labels.Everything(),
fields.Everything(), fields.Everything(),
"1", "1",
@@ -988,9 +967,9 @@ func TestEtcdWatchPods(t *testing.T) {
} }
func TestEtcdWatchPodsMatch(t *testing.T) { func TestEtcdWatchPodsMatch(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := storage.Watch(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
fields.Everything(), fields.Everything(),
"1", "1",
@@ -1008,7 +987,7 @@ func TestEtcdWatchPodsMatch(t *testing.T) {
}, },
}, },
} }
podBytes, _ := latest.Codec.Encode(pod) podBytes, _ := testapi.Codec().Encode(pod)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{
@@ -1027,9 +1006,9 @@ func TestEtcdWatchPodsMatch(t *testing.T) {
} }
func TestEtcdWatchPodsNotMatch(t *testing.T) { func TestEtcdWatchPodsNotMatch(t *testing.T) {
registry, _, _, fakeClient, _ := newStorage(t) storage, _, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := storage.Watch(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
fields.Everything(), fields.Everything(),
"1", "1",
@@ -1047,7 +1026,7 @@ func TestEtcdWatchPodsNotMatch(t *testing.T) {
}, },
}, },
} }
podBytes, _ := latest.Codec.Encode(pod) podBytes, _ := testapi.Codec().Encode(pod)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{

View File

@@ -27,7 +27,6 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for pod templates against etcd
type REST struct { type REST struct {
etcdgeneric.Etcd etcdgeneric.Etcd
} }
@@ -58,6 +57,5 @@ func NewREST(s storage.Interface) *REST {
Storage: s, Storage: s,
} }
return &REST{store} return &REST{store}
} }

View File

@@ -21,18 +21,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true return NewREST(etcdStorage), fakeClient
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
} }
func validNewPodTemplate(name string) *api.PodTemplate { func validNewPodTemplate(name string) *api.PodTemplate {
@@ -63,9 +59,8 @@ func validNewPodTemplate(name string) *api.PodTemplate {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage := NewREST(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
pod := validNewPodTemplate("foo") pod := validNewPodTemplate("foo")
pod.ObjectMeta = api.ObjectMeta{} pod.ObjectMeta = api.ObjectMeta{}
test.TestCreate( test.TestCreate(
@@ -79,17 +74,16 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage := NewREST(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2 fakeClient.ChangeIndex = 2
pod := validNewPodTemplate("foo") pod := validNewPodTemplate("foo")
existing := validNewPodTemplate("exists") existing := validNewPodTemplate("exists")
existing.Namespace = test.TestNamespace() existing.Namespace = test.TestNamespace()

View File

@@ -17,13 +17,25 @@ limitations under the License.
package registrytest package registrytest
import ( import (
"testing"
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
"k8s.io/kubernetes/pkg/api/latest" "k8s.io/kubernetes/pkg/api/testapi"
"k8s.io/kubernetes/pkg/runtime" "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"
"k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func NewEtcdStorage(t *testing.T) (storage.Interface, *tools.FakeEtcdClient) {
fakeClient := tools.NewFakeEtcdClient(t)
fakeClient.TestIndex = true
etcdStorage := etcdstorage.NewEtcdStorage(fakeClient, testapi.Codec(), etcdtest.PathPrefix())
return etcdStorage, fakeClient
}
func SetResourceVersion(fakeClient *tools.FakeEtcdClient, resourceVersion uint64) { func SetResourceVersion(fakeClient *tools.FakeEtcdClient, resourceVersion uint64) {
fakeClient.ChangeIndex = resourceVersion fakeClient.ChangeIndex = resourceVersion
} }
@@ -33,8 +45,8 @@ func SetObjectsForKey(fakeClient *tools.FakeEtcdClient, key string, objects []ru
if len(objects) > 0 { if len(objects) > 0 {
nodes := make([]*etcd.Node, len(objects)) nodes := make([]*etcd.Node, len(objects))
for i, obj := range objects { for i, obj := range objects {
encoded := runtime.EncodeOrDie(latest.Codec, obj) encoded := runtime.EncodeOrDie(testapi.Codec(), obj)
decoded, _ := latest.Codec.Decode([]byte(encoded)) decoded, _ := testapi.Codec().Decode([]byte(encoded))
nodes[i] = &etcd.Node{Value: encoded} nodes[i] = &etcd.Node{Value: encoded}
result[i] = decoded result[i] = decoded
} }

View File

@@ -27,13 +27,12 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// rest implements a RESTStorage for resourcequotas against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewStorage returns a RESTStorage object that will work against ResourceQuota objects. // NewREST returns a RESTStorage object that will work against resource quotas.
func NewStorage(s storage.Interface) (*REST, *StatusREST) { func NewREST(s storage.Interface) (*REST, *StatusREST) {
prefix := "/resourcequotas" prefix := "/resourcequotas"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ResourceQuota{} }, NewFunc: func() runtime.Object { return &api.ResourceQuota{} },
@@ -52,13 +51,13 @@ func NewStorage(s storage.Interface) (*REST, *StatusREST) {
}, },
EndpointName: "resourcequotas", EndpointName: "resourcequotas",
CreateStrategy: resourcequota.Strategy,
UpdateStrategy: resourcequota.Strategy,
ReturnDeletedObject: true,
Storage: s, Storage: s,
} }
store.CreateStrategy = resourcequota.Strategy
store.UpdateStrategy = resourcequota.Strategy
store.ReturnDeletedObject = true
statusStore := *store statusStore := *store
statusStore.UpdateStrategy = resourcequota.StatusStrategy statusStore.UpdateStrategy = resourcequota.StatusStrategy

View File

@@ -24,16 +24,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/latest"
"k8s.io/kubernetes/pkg/api/resource" "k8s.io/kubernetes/pkg/api/resource"
"k8s.io/kubernetes/pkg/api/rest/resttest" "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/registry/resourcequota" "k8s.io/kubernetes/pkg/registry/resourcequota"
"k8s.io/kubernetes/pkg/runtime" "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"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
"k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/pkg/util"
@@ -41,17 +39,10 @@ import (
"github.com/coreos/go-etcd/etcd" "github.com/coreos/go-etcd/etcd"
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true storage, statusStorage := NewREST(etcdStorage)
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, latest.Codec, etcdtest.PathPrefix()) return storage, statusStorage, fakeClient
return fakeEtcdClient, etcdStorage
}
func newStorage(t *testing.T) (*REST, *StatusREST, *tools.FakeEtcdClient, storage.Interface) {
fakeEtcdClient, h := newEtcdStorage(t)
storage, statusStorage := NewStorage(h)
return storage, statusStorage, fakeEtcdClient, h
} }
func validNewResourceQuota() *api.ResourceQuota { func validNewResourceQuota() *api.ResourceQuota {
@@ -83,14 +74,13 @@ func validChangedResourceQuota() *api.ResourceQuota {
} }
func TestStorage(t *testing.T) { func TestStorage(t *testing.T) {
storage, _, _, _ := newStorage(t) storage, _, _ := newStorage(t)
resourcequota.NewRegistry(storage) resourcequota.NewRegistry(storage)
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, fakeClient := newStorage(t)
storage, _ := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
resourcequota.ObjectMeta = api.ObjectMeta{} resourcequota.ObjectMeta = api.ObjectMeta{}
test.TestCreate( test.TestCreate(
@@ -113,32 +103,30 @@ func expectResourceQuota(t *testing.T, out runtime.Object) (*api.ResourceQuota,
} }
func TestCreateRegistryError(t *testing.T) { func TestCreateRegistryError(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, fakeClient := newStorage(t)
fakeEtcdClient.Err = fmt.Errorf("test error") fakeClient.Err = fmt.Errorf("test error")
storage, _ := NewStorage(etcdStorage)
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
_, err := storage.Create(api.NewDefaultContext(), resourcequota) _, err := storage.Create(api.NewDefaultContext(), resourcequota)
if err != fakeEtcdClient.Err { if err != fakeClient.Err {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
} }
func TestCreateSetsFields(t *testing.T) { func TestCreateSetsFields(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, fakeClient := newStorage(t)
storage, _ := NewStorage(etcdStorage)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
_, err := storage.Create(api.NewDefaultContext(), resourcequota) _, err := storage.Create(api.NewDefaultContext(), resourcequota)
if err != fakeEtcdClient.Err { if err != fakeClient.Err {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := &api.ResourceQuota{} object, err := storage.Get(ctx, "foo")
key, _ := storage.Etcd.KeyFunc(ctx, "foo") if err != nil {
if err := etcdStorage.Get(key, actual, false); err != nil { t.Errorf("unexpected error: %v", err)
t.Fatalf("unexpected extraction error: %v", err)
} }
actual := object.(*api.ResourceQuota)
if actual.Name != resourcequota.Name { if actual.Name != resourcequota.Name {
t.Errorf("unexpected resourcequota: %#v", actual) t.Errorf("unexpected resourcequota: %#v", actual)
} }
@@ -148,16 +136,15 @@ func TestCreateSetsFields(t *testing.T) {
} }
func TestResourceQuotaDecode(t *testing.T) { func TestResourceQuotaDecode(t *testing.T) {
_, etcdStorage := newEtcdStorage(t) storage, _, _ := newStorage(t)
storage, _ := NewStorage(etcdStorage)
expected := validNewResourceQuota() expected := validNewResourceQuota()
body, err := latest.Codec.Encode(expected) body, err := testapi.Codec().Encode(expected)
if err != nil { if err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
actual := storage.New() actual := storage.New()
if err := latest.Codec.DecodeInto(body, actual); err != nil { if err := testapi.Codec().DecodeInto(body, actual); err != nil {
t.Fatalf("unexpected error: %v", err) t.Fatalf("unexpected error: %v", err)
} }
@@ -167,16 +154,15 @@ func TestResourceQuotaDecode(t *testing.T) {
} }
func TestDeleteResourceQuota(t *testing.T) { func TestDeleteResourceQuota(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, fakeClient := newStorage(t)
fakeEtcdClient.ChangeIndex = 1 fakeClient.ChangeIndex = 1
storage, _ := NewStorage(etcdStorage)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := storage.Etcd.KeyFunc(ctx, "foo") key, _ := storage.Etcd.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ Value: runtime.EncodeOrDie(testapi.Codec(), &api.ResourceQuota{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "foo", Name: "foo",
Namespace: api.NamespaceDefault, Namespace: api.NamespaceDefault,
@@ -195,35 +181,32 @@ func TestDeleteResourceQuota(t *testing.T) {
} }
func TestEtcdGet(t *testing.T) { func TestEtcdGet(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, fakeClient := newStorage(t)
storage, _ := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
test.TestGet(resourcequota) test.TestGet(resourcequota)
} }
func TestEtcdList(t *testing.T) { func TestEtcdList(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, _, fakeClient := newStorage(t)
storage, _ := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key := etcdtest.AddPrefix(storage.Etcd.KeyRootFunc(test.TestContext())) key := etcdtest.AddPrefix(storage.Etcd.KeyRootFunc(test.TestContext()))
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
test.TestList( test.TestList(
resourcequota, resourcequota,
func(objects []runtime.Object) []runtime.Object { func(objects []runtime.Object) []runtime.Object {
return registrytest.SetObjectsForKey(fakeEtcdClient, key, objects) return registrytest.SetObjectsForKey(fakeClient, key, objects)
}, },
func(resourceVersion uint64) { func(resourceVersion uint64) {
registrytest.SetResourceVersion(fakeEtcdClient, resourceVersion) registrytest.SetResourceVersion(fakeClient, resourceVersion)
}) })
} }
func TestEtcdCreateFailsWithoutNamespace(t *testing.T) { func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) storage, _, _ := newStorage(t)
fakeClient.TestIndex = true
resourcequota := validNewResourceQuota() resourcequota := validNewResourceQuota()
resourcequota.Namespace = "" resourcequota.Namespace = ""
_, err := registry.Create(api.NewContext(), resourcequota) _, err := storage.Create(api.NewContext(), resourcequota)
// Accept "namespace" or "Namespace". // Accept "namespace" or "Namespace".
if err == nil || !strings.Contains(err.Error(), "amespace") { if err == nil || !strings.Contains(err.Error(), "amespace") {
t.Fatalf("expected error that namespace was missing from context, got: %v", err) t.Fatalf("expected error that namespace was missing from context, got: %v", err)
@@ -231,33 +214,32 @@ func TestEtcdCreateFailsWithoutNamespace(t *testing.T) {
} }
func TestEtcdCreateAlreadyExisting(t *testing.T) { func TestEtcdCreateAlreadyExisting(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Data[key] = tools.EtcdResponseWithError{ fakeClient.Data[key] = tools.EtcdResponseWithError{
R: &etcd.Response{ R: &etcd.Response{
Node: &etcd.Node{ Node: &etcd.Node{
Value: runtime.EncodeOrDie(latest.Codec, &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "foo"}}), Value: runtime.EncodeOrDie(testapi.Codec(), &api.ResourceQuota{ObjectMeta: api.ObjectMeta{Name: "foo"}}),
}, },
}, },
E: nil, E: nil,
} }
_, err := registry.Create(ctx, validNewResourceQuota()) _, err := storage.Create(ctx, validNewResourceQuota())
if !errors.IsAlreadyExists(err) { if !errors.IsAlreadyExists(err) {
t.Errorf("Unexpected error returned: %#v", err) t.Errorf("Unexpected error returned: %#v", err)
} }
} }
func TestEtcdUpdateStatus(t *testing.T) { func TestEtcdUpdateStatus(t *testing.T) {
registry, status, fakeClient, etcdStorage := newStorage(t) storage, status, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
fakeClient.TestIndex = true
key, _ := registry.KeyFunc(ctx, "foo") key, _ := storage.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
resourcequotaStart := validNewResourceQuota() resourcequotaStart := validNewResourceQuota()
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, resourcequotaStart), 1) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), resourcequotaStart), 1)
resourcequotaIn := &api.ResourceQuota{ resourcequotaIn := &api.ResourceQuota{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
@@ -294,20 +276,16 @@ func TestEtcdUpdateStatus(t *testing.T) {
if err != nil { if err != nil {
t.Fatalf("Unexpected error: %v", err) t.Fatalf("Unexpected error: %v", err)
} }
var resourcequotaOut api.ResourceQuota rqOut, err := storage.Get(ctx, "foo")
key, _ = registry.KeyFunc(ctx, "foo") if !api.Semantic.DeepEqual(&expected, rqOut) {
if err := etcdStorage.Get(key, &resourcequotaOut, false); err != nil { t.Errorf("unexpected object: %s", util.ObjectDiff(&expected, rqOut))
t.Fatalf("Unexpected error: %v", err)
}
if !api.Semantic.DeepEqual(expected, resourcequotaOut) {
t.Errorf("unexpected object: %s", util.ObjectDiff(expected, resourcequotaOut))
} }
} }
func TestEtcdWatchResourceQuotas(t *testing.T) { func TestEtcdWatchResourceQuotas(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := storage.Watch(ctx,
labels.Everything(), labels.Everything(),
fields.Everything(), fields.Everything(),
"1", "1",
@@ -332,9 +310,9 @@ func TestEtcdWatchResourceQuotas(t *testing.T) {
} }
func TestEtcdWatchResourceQuotasMatch(t *testing.T) { func TestEtcdWatchResourceQuotasMatch(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := storage.Watch(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
fields.Everything(), fields.Everything(),
"1", "1",
@@ -352,7 +330,7 @@ func TestEtcdWatchResourceQuotasMatch(t *testing.T) {
}, },
}, },
} }
resourcequotaBytes, _ := latest.Codec.Encode(resourcequota) resourcequotaBytes, _ := testapi.Codec().Encode(resourcequota)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{
@@ -371,9 +349,9 @@ func TestEtcdWatchResourceQuotasMatch(t *testing.T) {
} }
func TestEtcdWatchResourceQuotasNotMatch(t *testing.T) { func TestEtcdWatchResourceQuotasNotMatch(t *testing.T) {
registry, _, fakeClient, _ := newStorage(t) storage, _, fakeClient := newStorage(t)
ctx := api.NewDefaultContext() ctx := api.NewDefaultContext()
watching, err := registry.Watch(ctx, watching, err := storage.Watch(ctx,
labels.SelectorFromSet(labels.Set{"name": "foo"}), labels.SelectorFromSet(labels.Set{"name": "foo"}),
fields.Everything(), fields.Everything(),
"1", "1",
@@ -391,7 +369,7 @@ func TestEtcdWatchResourceQuotasNotMatch(t *testing.T) {
}, },
}, },
} }
resourcequotaBytes, _ := latest.Codec.Encode(resourcequota) resourcequotaBytes, _ := testapi.Codec().Encode(resourcequota)
fakeClient.WatchResponse <- &etcd.Response{ fakeClient.WatchResponse <- &etcd.Response{
Action: "create", Action: "create",
Node: &etcd.Node{ Node: &etcd.Node{

View File

@@ -27,13 +27,12 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// REST implements a RESTStorage for secrets against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
// NewStorage returns a registry which will store Secret in the given etcdStorage // NewREST returns a RESTStorage object that will work against secrets.
func NewStorage(s storage.Interface) *REST { func NewREST(s storage.Interface) *REST {
prefix := "/secrets" prefix := "/secrets"
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
@@ -53,11 +52,10 @@ func NewStorage(s storage.Interface) *REST {
}, },
EndpointName: "secrets", EndpointName: "secrets",
CreateStrategy: secret.Strategy,
UpdateStrategy: secret.Strategy,
Storage: s, Storage: s,
} }
store.CreateStrategy = secret.Strategy
store.UpdateStrategy = secret.Strategy
return &REST{store} return &REST{store}
} }

View File

@@ -21,18 +21,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true return NewREST(etcdStorage), fakeClient
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
} }
func validNewSecret(name string) *api.Secret { func validNewSecret(name string) *api.Secret {
@@ -48,9 +44,8 @@ func validNewSecret(name string) *api.Secret {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
secret := validNewSecret("foo") secret := validNewSecret("foo")
secret.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"} secret.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
test.TestCreate( test.TestCreate(
@@ -70,17 +65,16 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2 fakeClient.ChangeIndex = 2
secret := validNewSecret("foo") secret := validNewSecret("foo")
existing := validNewSecret("exists") existing := validNewSecret("exists")
existing.Namespace = test.TestNamespace() existing.Namespace = test.TestNamespace()

View File

@@ -33,7 +33,8 @@ type REST struct {
etcdgeneric.Etcd etcdgeneric.Etcd
} }
func NewStorage(s storage.Interface) *REST { // NewREST returns a RESTStorage object that will work against services.
func NewREST(s storage.Interface) *REST {
prefix := "/services/specs" prefix := "/services/specs"
store := etcdgeneric.Etcd{ store := etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.Service{} }, NewFunc: func() runtime.Object { return &api.Service{} },
@@ -60,6 +61,7 @@ func NewStorage(s storage.Interface) *REST {
return &REST{store} return &REST{store}
} }
// FIXME: Move it.
func MatchServices(label labels.Selector, field fields.Selector) generic.Matcher { func MatchServices(label labels.Selector, field fields.Selector) generic.Matcher {
return &generic.SelectionPredicate{Label: label, Field: field, GetAttrs: ServiceAttributes} return &generic.SelectionPredicate{Label: label, Field: field, GetAttrs: ServiceAttributes}
} }

View File

@@ -22,7 +22,7 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/errors" "k8s.io/kubernetes/pkg/api/errors"
"k8s.io/kubernetes/pkg/api/latest" "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"
etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd" etcdgeneric "k8s.io/kubernetes/pkg/registry/generic/etcd"
@@ -37,8 +37,8 @@ import (
) )
func NewTestEtcdRegistry(client tools.EtcdClient) (Registry, *etcdservice.REST) { func NewTestEtcdRegistry(client tools.EtcdClient) (Registry, *etcdservice.REST) {
storage := etcdstorage.NewEtcdStorage(client, latest.Codec, etcdtest.PathPrefix()) storage := etcdstorage.NewEtcdStorage(client, testapi.Codec(), etcdtest.PathPrefix())
rest := etcdservice.NewStorage(storage) rest := etcdservice.NewREST(storage)
registry := NewRegistry(rest) registry := NewRegistry(rest)
return registry, rest return registry, rest
} }
@@ -87,10 +87,10 @@ func TestEtcdListServices(t *testing.T) {
Node: &etcd.Node{ Node: &etcd.Node{
Nodes: []*etcd.Node{ Nodes: []*etcd.Node{
{ {
Value: runtime.EncodeOrDie(latest.Codec, makeTestService("foo")), Value: runtime.EncodeOrDie(testapi.Codec(), makeTestService("foo")),
}, },
{ {
Value: runtime.EncodeOrDie(latest.Codec, makeTestService("bar")), Value: runtime.EncodeOrDie(testapi.Codec(), makeTestService("bar")),
}, },
}, },
}, },
@@ -124,7 +124,7 @@ func TestEtcdCreateService(t *testing.T) {
} }
var service api.Service var service api.Service
err = latest.Codec.DecodeInto([]byte(resp.Node.Value), &service) err = testapi.Codec().DecodeInto([]byte(resp.Node.Value), &service)
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
} }
@@ -140,7 +140,7 @@ func TestEtcdCreateServiceAlreadyExisting(t *testing.T) {
registry, rest := NewTestEtcdRegistry(fakeClient) registry, rest := NewTestEtcdRegistry(fakeClient)
key, _ := rest.KeyFunc(ctx, "foo") key, _ := rest.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, makeTestService("foo")), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), makeTestService("foo")), 0)
_, err := registry.CreateService(ctx, makeTestService("foo")) _, err := registry.CreateService(ctx, makeTestService("foo"))
if !errors.IsAlreadyExists(err) { if !errors.IsAlreadyExists(err) {
t.Errorf("expected already exists err, got %#v", err) t.Errorf("expected already exists err, got %#v", err)
@@ -161,8 +161,8 @@ func TestEtcdGetServiceDifferentNamespace(t *testing.T) {
key1 = etcdtest.AddPrefix(key1) key1 = etcdtest.AddPrefix(key1)
key2 = etcdtest.AddPrefix(key2) key2 = etcdtest.AddPrefix(key2)
fakeClient.Set(key1, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0) fakeClient.Set(key1, runtime.EncodeOrDie(testapi.Codec(), &api.Service{ObjectMeta: api.ObjectMeta{Namespace: "default", Name: "foo"}}), 0)
fakeClient.Set(key2, runtime.EncodeOrDie(latest.Codec, &api.Service{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0) fakeClient.Set(key2, runtime.EncodeOrDie(testapi.Codec(), &api.Service{ObjectMeta: api.ObjectMeta{Namespace: "other", Name: "foo"}}), 0)
service1, err := registry.GetService(ctx1, "foo") service1, err := registry.GetService(ctx1, "foo")
if err != nil { if err != nil {
@@ -194,7 +194,7 @@ func TestEtcdGetService(t *testing.T) {
registry, rest := NewTestEtcdRegistry(fakeClient) registry, rest := NewTestEtcdRegistry(fakeClient)
key, _ := rest.KeyFunc(ctx, "foo") key, _ := rest.KeyFunc(ctx, "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, makeTestService("foo")), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), makeTestService("foo")), 0)
service, err := registry.GetService(ctx, "foo") service, err := registry.GetService(ctx, "foo")
if err != nil { if err != nil {
t.Errorf("unexpected error: %v", err) t.Errorf("unexpected error: %v", err)
@@ -229,10 +229,10 @@ func TestEtcdDeleteService(t *testing.T) {
registry, _ := NewTestEtcdRegistry(fakeClient) registry, _ := NewTestEtcdRegistry(fakeClient)
key, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/specs", "foo") key, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/specs", "foo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, makeTestService("foo")), 0) fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), makeTestService("foo")), 0)
path, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/endpoints", "foo") path, _ := etcdgeneric.NamespaceKeyFunc(ctx, "/services/endpoints", "foo")
endpointsKey := etcdtest.AddPrefix(path) endpointsKey := etcdtest.AddPrefix(path)
fakeClient.Set(endpointsKey, runtime.EncodeOrDie(latest.Codec, &api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0) fakeClient.Set(endpointsKey, runtime.EncodeOrDie(testapi.Codec(), &api.Endpoints{ObjectMeta: api.ObjectMeta{Name: "foo"}}), 0)
err := registry.DeleteService(ctx, "foo") err := registry.DeleteService(ctx, "foo")
if err != nil { if err != nil {
@@ -254,7 +254,7 @@ func TestEtcdUpdateService(t *testing.T) {
registry, rest := NewTestEtcdRegistry(fakeClient) registry, rest := NewTestEtcdRegistry(fakeClient)
key, _ := rest.KeyFunc(ctx, "uniquefoo") key, _ := rest.KeyFunc(ctx, "uniquefoo")
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(latest.Codec, makeTestService("uniquefoo")), 0) resp, _ := fakeClient.Set(key, runtime.EncodeOrDie(testapi.Codec(), makeTestService("uniquefoo")), 0)
testService := api.Service{ testService := api.Service{
ObjectMeta: api.ObjectMeta{ ObjectMeta: api.ObjectMeta{
Name: "uniquefoo", Name: "uniquefoo",

View File

@@ -27,23 +27,21 @@ import (
"k8s.io/kubernetes/pkg/storage" "k8s.io/kubernetes/pkg/storage"
) )
// REST implements a RESTStorage for service accounts against etcd
type REST struct { type REST struct {
*etcdgeneric.Etcd *etcdgeneric.Etcd
} }
const Prefix = "/serviceaccounts" // NewREST returns a RESTStorage object that will work against service accounts.
func NewREST(s storage.Interface) *REST {
// NewStorage returns a RESTStorage object that will work against service accounts objects. prefix := "/serviceaccounts"
func NewStorage(s storage.Interface) *REST {
store := &etcdgeneric.Etcd{ store := &etcdgeneric.Etcd{
NewFunc: func() runtime.Object { return &api.ServiceAccount{} }, NewFunc: func() runtime.Object { return &api.ServiceAccount{} },
NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} }, NewListFunc: func() runtime.Object { return &api.ServiceAccountList{} },
KeyRootFunc: func(ctx api.Context) string { KeyRootFunc: func(ctx api.Context) string {
return etcdgeneric.NamespaceKeyRootFunc(ctx, Prefix) return etcdgeneric.NamespaceKeyRootFunc(ctx, prefix)
}, },
KeyFunc: func(ctx api.Context, name string) (string, error) { KeyFunc: func(ctx api.Context, name string) (string, error) {
return etcdgeneric.NamespaceKeyFunc(ctx, Prefix, name) return etcdgeneric.NamespaceKeyFunc(ctx, prefix, name)
}, },
ObjectNameFunc: func(obj runtime.Object) (string, error) { ObjectNameFunc: func(obj runtime.Object) (string, error) {
return obj.(*api.ServiceAccount).Name, nil return obj.(*api.ServiceAccount).Name, nil
@@ -53,12 +51,11 @@ func NewStorage(s storage.Interface) *REST {
}, },
EndpointName: "serviceaccounts", EndpointName: "serviceaccounts",
CreateStrategy: serviceaccount.Strategy,
UpdateStrategy: serviceaccount.Strategy,
ReturnDeletedObject: true,
Storage: s, Storage: s,
} }
store.CreateStrategy = serviceaccount.Strategy
store.UpdateStrategy = serviceaccount.Strategy
store.ReturnDeletedObject = true
return &REST{store} return &REST{store}
} }

View File

@@ -21,18 +21,14 @@ import (
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/api/rest/resttest" "k8s.io/kubernetes/pkg/api/rest/resttest"
"k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/registry/registrytest"
"k8s.io/kubernetes/pkg/storage"
etcdstorage "k8s.io/kubernetes/pkg/storage/etcd"
"k8s.io/kubernetes/pkg/tools" "k8s.io/kubernetes/pkg/tools"
"k8s.io/kubernetes/pkg/tools/etcdtest" "k8s.io/kubernetes/pkg/tools/etcdtest"
) )
func newEtcdStorage(t *testing.T) (*tools.FakeEtcdClient, storage.Interface) { func newStorage(t *testing.T) (*REST, *tools.FakeEtcdClient) {
fakeEtcdClient := tools.NewFakeEtcdClient(t) etcdStorage, fakeClient := registrytest.NewEtcdStorage(t)
fakeEtcdClient.TestIndex = true return NewREST(etcdStorage), fakeClient
etcdStorage := etcdstorage.NewEtcdStorage(fakeEtcdClient, testapi.Codec(), etcdtest.PathPrefix())
return fakeEtcdClient, etcdStorage
} }
func validNewServiceAccount(name string) *api.ServiceAccount { func validNewServiceAccount(name string) *api.ServiceAccount {
@@ -46,9 +42,8 @@ func validNewServiceAccount(name string) *api.ServiceAccount {
} }
func TestCreate(t *testing.T) { func TestCreate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
serviceAccount := validNewServiceAccount("foo") serviceAccount := validNewServiceAccount("foo")
serviceAccount.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"} serviceAccount.ObjectMeta = api.ObjectMeta{GenerateName: "foo-"}
test.TestCreate( test.TestCreate(
@@ -63,17 +58,16 @@ func TestCreate(t *testing.T) {
} }
func TestUpdate(t *testing.T) { func TestUpdate(t *testing.T) {
fakeEtcdClient, etcdStorage := newEtcdStorage(t) storage, fakeClient := newStorage(t)
storage := NewStorage(etcdStorage) test := resttest.New(t, storage, fakeClient.SetError)
test := resttest.New(t, storage, fakeEtcdClient.SetError)
key, err := storage.KeyFunc(test.TestContext(), "foo") key, err := storage.KeyFunc(test.TestContext(), "foo")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
key = etcdtest.AddPrefix(key) key = etcdtest.AddPrefix(key)
fakeEtcdClient.ExpectNotFoundGet(key) fakeClient.ExpectNotFoundGet(key)
fakeEtcdClient.ChangeIndex = 2 fakeClient.ChangeIndex = 2
serviceAccount := validNewServiceAccount("foo") serviceAccount := validNewServiceAccount("foo")
existing := validNewServiceAccount("exists") existing := validNewServiceAccount("exists")
existing.Namespace = test.TestNamespace() existing.Namespace = test.TestNamespace()