Update the third party data codec to automatically include everything

in api.ObjectMeta.  Add more tests.
pull/6/head
Brendan Burns 2015-09-02 17:13:38 -07:00
parent c28b68d254
commit 61f272c8cd
3 changed files with 57 additions and 40 deletions

View File

@ -237,9 +237,10 @@ func testInstallThirdPartyAPIGetVersion(t *testing.T, version string) {
if err := decodeResponse(resp, &item); err != nil {
t.Errorf("unexpected error: %v", err)
}
// Fill in data that the apiserver injects
expectedObj.SelfLink = item.SelfLink
if !reflect.DeepEqual(item, expectedObj) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
t.Errorf("expected:\n%#v\nsaw:\n%#v\n", expectedObj, item)
}
}
@ -285,8 +286,14 @@ func testInstallThirdPartyAPIPostForVersion(t *testing.T, version string) {
t.Errorf("unexpected error: %v", err)
}
if !reflect.DeepEqual(item, inputObj) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", inputObj, item)
// fill in fields set by the apiserver
expectedObj := inputObj
expectedObj.SelfLink = item.SelfLink
expectedObj.Namespace = item.Namespace
expectedObj.UID = item.UID
expectedObj.CreationTimestamp = item.CreationTimestamp
if !reflect.DeepEqual(item, expectedObj) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
}
etcdResp, err := fakeClient.Get(etcdtest.PathPrefix()+"/ThirdPartyResourceData/company.com/foos/default/test", false, false)
@ -324,7 +331,8 @@ func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) {
expectedObj := Foo{
ObjectMeta: api.ObjectMeta{
Name: "test",
Name: "test",
Namespace: "default",
},
TypeMeta: api.TypeMeta{
Kind: "Foo",
@ -353,6 +361,9 @@ func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) {
t.Errorf("unexpected error: %v", err)
}
// Fill in fields set by the apiserver
expectedObj.SelfLink = item.SelfLink
expectedObj.Namespace = item.Namespace
if !reflect.DeepEqual(item, expectedObj) {
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
}

View File

@ -100,12 +100,12 @@ func (t *thirdPartyResourceDataCodec) populate(objIn *expapi.ThirdPartyResourceD
}
func (t *thirdPartyResourceDataCodec) populateFromObject(objIn *expapi.ThirdPartyResourceData, mapObj map[string]interface{}, data []byte) error {
kind, ok := mapObj["kind"].(string)
if !ok {
return fmt.Errorf("unexpected object for kind: %#v", mapObj["kind"])
typeMeta := api.TypeMeta{}
if err := json.Unmarshal(data, &typeMeta); err != nil {
return err
}
if kind != t.kind {
return fmt.Errorf("unexpected kind: %s, expected: %s", kind, t.kind)
if typeMeta.Kind != t.kind {
return fmt.Errorf("unexpected kind: %s, expected %s", typeMeta.Kind, t.kind)
}
metadata, ok := mapObj["metadata"].(map[string]interface{})
@ -113,38 +113,15 @@ func (t *thirdPartyResourceDataCodec) populateFromObject(objIn *expapi.ThirdPart
return fmt.Errorf("unexpected object for metadata: %#v", mapObj["metadata"])
}
if resourceVersion, ok := metadata["resourceVersion"]; ok {
resourceVersionStr, ok := resourceVersion.(string)
if !ok {
return fmt.Errorf("unexpected object for resourceVersion: %v", resourceVersion)
}
objIn.ResourceVersion = resourceVersionStr
metadataData, err := json.Marshal(metadata)
if err != nil {
return err
}
name, ok := metadata["name"].(string)
if !ok {
return fmt.Errorf("unexpected object for name: %#v", metadata)
if err := json.Unmarshal(metadataData, &objIn.ObjectMeta); err != nil {
return err
}
if labels, ok := metadata["labels"]; ok {
labelMap, ok := labels.(map[string]interface{})
if !ok {
return fmt.Errorf("unexpected object for labels: %v", labelMap)
}
for key, value := range labelMap {
valueStr, ok := value.(string)
if !ok {
return fmt.Errorf("unexpected label: %v", value)
}
if objIn.Labels == nil {
objIn.Labels = map[string]string{}
}
objIn.Labels[key] = valueStr
}
}
objIn.Name = name
objIn.Data = data
return nil
}
@ -230,16 +207,33 @@ const template = `{
"items": [ %s ]
}`
func encodeToJSON(obj *expapi.ThirdPartyResourceData) ([]byte, error) {
var objOut interface{}
if err := json.Unmarshal(obj.Data, &objOut); err != nil {
return nil, err
}
objMap, ok := objOut.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("unexpected type: %v", objOut)
}
objMap["metadata"] = obj.ObjectMeta
return json.Marshal(objMap)
}
func (t *thirdPartyResourceDataCodec) Encode(obj runtime.Object) (data []byte, err error) {
switch obj := obj.(type) {
case *expapi.ThirdPartyResourceData:
return obj.Data, nil
return encodeToJSON(obj)
case *expapi.ThirdPartyResourceDataList:
// TODO: There must be a better way to do this...
buff := &bytes.Buffer{}
dataStrings := make([]string, len(obj.Items))
for ix := range obj.Items {
dataStrings[ix] = string(obj.Items[ix].Data)
data, err := encodeToJSON(&obj.Items[ix])
if err != nil {
return nil, err
}
dataStrings[ix] = string(data)
}
fmt.Fprintf(buff, template, t.kind+"List", strings.Join(dataStrings, ","))
return buff.Bytes(), nil

View File

@ -20,9 +20,11 @@ import (
"encoding/json"
"reflect"
"testing"
"time"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/expapi"
"k8s.io/kubernetes/pkg/util"
)
type Foo struct {
@ -59,6 +61,16 @@ func TestCodec(t *testing.T) {
obj: &Foo{ObjectMeta: api.ObjectMeta{Name: "bar", ResourceVersion: "baz"}, TypeMeta: api.TypeMeta{Kind: "Foo"}},
name: "resource version",
},
{
obj: &Foo{
ObjectMeta: api.ObjectMeta{
Name: "bar",
CreationTimestamp: util.Time{time.Unix(100, 0)},
},
TypeMeta: api.TypeMeta{Kind: "Foo"},
},
name: "creation time",
},
{
obj: &Foo{
ObjectMeta: api.ObjectMeta{