Make runtime less global for Codec

* Make Codec separate from Scheme
* Move EncodeOrDie off Scheme to take a Codec
* Make Copy work without a Codec
* Create a "latest" package that imports all versions and
  sets global defaults for "most recent encoding"
  * v1beta1 is the current "latest", v1beta2 exists
  * Kill DefaultCodec, replace it with "latest.Codec"
  * This updates the client and etcd to store the latest known version
* EmbeddedObject is per schema and per package now
* Move runtime.DefaultScheme to api.Scheme
* Split out WatchEvent since it's not an API object today, treat it
like a special object in api
* Kill DefaultResourceVersioner, instead place it on "latest" (as the
  package that understands all packages)
* Move objDiff to runtime.ObjectDiff
This commit is contained in:
Clayton Coleman
2014-09-11 13:02:53 -04:00
parent 154a91cd33
commit 61e3ce7ddc
58 changed files with 944 additions and 389 deletions

View File

@@ -43,14 +43,15 @@ func (*InternalSimple) IsAnAPIObject() {}
func (*ExternalSimple) IsAnAPIObject() {}
func TestScheme(t *testing.T) {
runtime.DefaultScheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
runtime.DefaultScheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
scheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
internalToExternalCalls := 0
externalToInternalCalls := 0
// Register functions to verify that scope.Meta() gets set correctly.
err := runtime.DefaultScheme.AddConversionFuncs(
err := scheme.AddConversionFuncs(
func(in *InternalSimple, out *ExternalSimple, scope conversion.Scope) error {
if e, a := "", scope.Meta().SrcVersion; e != a {
t.Errorf("Expected '%v', got '%v'", e, a)
@@ -85,10 +86,10 @@ func TestScheme(t *testing.T) {
// Test Encode, Decode, and DecodeInto
obj := runtime.Object(simple)
data, err := runtime.DefaultScheme.EncodeToVersion(obj, "externalVersion")
obj2, err2 := runtime.DefaultScheme.Decode(data)
data, err := scheme.EncodeToVersion(obj, "externalVersion")
obj2, err2 := scheme.Decode(data)
obj3 := &InternalSimple{}
err3 := runtime.DefaultScheme.DecodeInto(data, obj3)
err3 := scheme.DecodeInto(data, obj3)
if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v' '%v'", err, err2, err3)
}
@@ -104,7 +105,7 @@ func TestScheme(t *testing.T) {
// Test Convert
external := &ExternalSimple{}
err = runtime.DefaultScheme.Convert(simple, external)
err = scheme.Convert(simple, external)
if err != nil {
t.Errorf("Unexpected error: %v", err)
}
@@ -123,12 +124,13 @@ func TestScheme(t *testing.T) {
}
func TestBadJSONRejection(t *testing.T) {
scheme := runtime.NewScheme()
badJSONMissingKind := []byte(`{ }`)
if _, err := runtime.DefaultScheme.Decode(badJSONMissingKind); err == nil {
if _, err := scheme.Decode(badJSONMissingKind); err == nil {
t.Errorf("Did not reject despite lack of kind field: %s", badJSONMissingKind)
}
badJSONUnknownType := []byte(`{"kind": "bar"}`)
if _, err1 := runtime.DefaultScheme.Decode(badJSONUnknownType); err1 == nil {
if _, err1 := scheme.Decode(badJSONUnknownType); err1 == nil {
t.Errorf("Did not reject despite use of unknown type: %s", badJSONUnknownType)
}
/*badJSONKindMismatch := []byte(`{"kind": "Pod"}`)
@@ -163,12 +165,13 @@ func (*ExternalExtensionType) IsAnAPIObject() {}
func (*InternalExtensionType) IsAnAPIObject() {}
func TestExtensionMapping(t *testing.T) {
runtime.DefaultScheme.AddKnownTypeWithName("", "ExtensionType", &InternalExtensionType{})
runtime.DefaultScheme.AddKnownTypeWithName("", "A", &ExtensionA{})
runtime.DefaultScheme.AddKnownTypeWithName("", "B", &ExtensionB{})
runtime.DefaultScheme.AddKnownTypeWithName("testExternal", "ExtensionType", &ExternalExtensionType{})
runtime.DefaultScheme.AddKnownTypeWithName("testExternal", "A", &ExtensionA{})
runtime.DefaultScheme.AddKnownTypeWithName("testExternal", "B", &ExtensionB{})
scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName("", "ExtensionType", &InternalExtensionType{})
scheme.AddKnownTypeWithName("", "A", &ExtensionA{})
scheme.AddKnownTypeWithName("", "B", &ExtensionB{})
scheme.AddKnownTypeWithName("testExternal", "ExtensionType", &ExternalExtensionType{})
scheme.AddKnownTypeWithName("testExternal", "A", &ExtensionA{})
scheme.AddKnownTypeWithName("testExternal", "B", &ExtensionB{})
table := []struct {
obj runtime.Object
@@ -187,14 +190,14 @@ func TestExtensionMapping(t *testing.T) {
}
for _, item := range table {
gotEncoded, err := runtime.DefaultScheme.EncodeToVersion(item.obj, "testExternal")
gotEncoded, err := scheme.EncodeToVersion(item.obj, "testExternal")
if err != nil {
t.Errorf("unexpected error '%v' (%#v)", err, item.obj)
} else if e, a := item.encoded, string(gotEncoded); e != a {
t.Errorf("expected %v, got %v", e, a)
}
gotDecoded, err := runtime.DefaultScheme.Decode([]byte(item.encoded))
gotDecoded, err := scheme.Decode([]byte(item.encoded))
if err != nil {
t.Errorf("unexpected error '%v' (%v)", err, item.encoded)
} else if e, a := item.obj, gotDecoded; !reflect.DeepEqual(e, a) {
@@ -209,3 +212,25 @@ func TestExtensionMapping(t *testing.T) {
}
}
}
func TestEncode(t *testing.T) {
scheme := runtime.NewScheme()
scheme.AddKnownTypeWithName("", "Simple", &InternalSimple{})
scheme.AddKnownTypeWithName("externalVersion", "Simple", &ExternalSimple{})
codec := runtime.CodecFor(scheme, "externalVersion")
test := &InternalSimple{
TestString: "I'm the same",
}
obj := runtime.Object(test)
data, err := codec.Encode(obj)
obj2, err2 := codec.Decode(data)
if err != nil || err2 != nil {
t.Fatalf("Failure: '%v' '%v'", err, err2)
}
if _, ok := obj2.(*InternalSimple); !ok {
t.Fatalf("Got wrong type")
}
if !reflect.DeepEqual(obj2, test) {
t.Errorf("Expected:\n %#v,\n Got:\n %#v", &test, obj2)
}
}