Fix self linking of objects returned in lists.

pull/6/head
Daniel Smith 2014-10-30 15:04:11 -07:00
parent b2b090c8f4
commit b28234fac6
4 changed files with 97 additions and 1 deletions

View File

@ -271,6 +271,63 @@ func runAPIVersionsTest(c *client.Client) {
glog.Infof("Version test passed")
}
func runSelfLinkTest(c *client.Client) {
var svc api.Service
err := c.Post().Path("services").Body(
&api.Service{
ObjectMeta: api.ObjectMeta{
Name: "selflinktest",
Labels: map[string]string{
"name": "selflinktest",
},
},
Port: 12345,
// This is here because validation requires it.
Selector: map[string]string{
"foo": "bar",
},
},
).Do().Into(&svc)
if err != nil {
glog.Fatalf("Failed creating selflinktest service: %v", err)
}
err = c.Get().AbsPath(svc.SelfLink).Do().Into(&svc)
if err != nil {
glog.Fatalf("Failed listing service with supplied self link '%v': %v", svc.SelfLink, err)
}
var svcList api.ServiceList
err = c.Get().Path("services").Do().Into(&svcList)
if err != nil {
glog.Fatalf("Failed listing services: %v", err)
}
err = c.Get().AbsPath(svcList.SelfLink).Do().Into(&svcList)
if err != nil {
glog.Fatalf("Failed listing services with supplied self link '%v': %v", svcList.SelfLink, err)
}
found := false
for i := range svcList.Items {
item := &svcList.Items[i]
if item.Name != "selflinktest" {
continue
}
found = true
err = c.Get().AbsPath(item.SelfLink).Do().Into(&svc)
if err != nil {
glog.Fatalf("Failed listing service with supplied self link '%v': %v", item.SelfLink, err)
}
break
}
if !found {
glog.Fatalf("never found selflinktest service")
}
glog.Infof("Self link test passed")
// TODO: Should test PUT at some point, too.
}
func runAtomicPutTest(c *client.Client) {
var svc api.Service
err := c.Post().Path("services").Body(
@ -509,6 +566,7 @@ func main() {
runServiceTest,
runAPIVersionsTest,
runMasterServiceTest,
runSelfLinkTest,
}
var wg sync.WaitGroup
wg.Add(len(testFuncs))

View File

@ -62,7 +62,25 @@ func (h *RESTHandler) setSelfLink(obj runtime.Object, req *http.Request) error {
newURL.Path = path.Join(h.canonicalPrefix, req.URL.Path)
newURL.RawQuery = ""
newURL.Fragment = ""
return h.selfLinker.SetSelfLink(obj, newURL.String())
err := h.selfLinker.SetSelfLink(obj, newURL.String())
if err != nil {
return err
}
if !runtime.IsListType(obj) {
return nil
}
// Set self-link of objects in the list.
items, err := runtime.ExtractList(obj)
if err != nil {
return err
}
for i := range items {
if err := h.setSelfLinkAddName(items[i], req); err != nil {
return err
}
}
return runtime.SetList(obj, items)
}
// Like setSelfLink, but appends the object's name.

View File

@ -23,6 +23,11 @@ import (
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)
func IsListType(obj Object) bool {
_, err := GetItemsPtr(obj)
return err == nil
}
// GetItemsPtr returns a pointer to the list object's Items member.
// If 'list' doesn't have an Items member, it's not really a list type
// and an error will be returned.

View File

@ -26,6 +26,21 @@ import (
"github.com/google/gofuzz"
)
func TestIsList(t *testing.T) {
tests := []struct {
obj runtime.Object
isList bool
}{
{&api.PodList{}, true},
{&api.Pod{}, false},
}
for _, item := range tests {
if e, a := item.isList, runtime.IsListType(item.obj); e != a {
t.Errorf("%v: Expected %v, got %v", reflect.TypeOf(item.obj), e, a)
}
}
}
func TestExtractList(t *testing.T) {
pl := &api.PodList{
Items: []api.Pod{