Merge pull request #123536 from benluddy/cbor-roundtrip-unit-via-interface

KEP-4222: Make CBOR roundtrip tests pass through interface{}.
This commit is contained in:
Kubernetes Prow Robot 2024-03-01 15:59:31 -08:00 committed by GitHub
commit 55e4172a0d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 61 additions and 27 deletions

View File

@ -276,13 +276,13 @@ func TestDecode(t *testing.T) {
assertOnError: assertNilError, assertOnError: assertNilError,
}, },
} { } {
ms := tc.modes decModes := tc.modes
if len(ms) == 0 { if len(decModes) == 0 {
ms = allDecModes decModes = allDecModes
} }
for _, dm := range ms { for _, decMode := range decModes {
modeName, ok := decModeNames[dm] modeName, ok := decModeNames[decMode]
if !ok { if !ok {
t.Fatal("test case configured to run against unrecognized mode") t.Fatal("test case configured to run against unrecognized mode")
} }
@ -295,7 +295,7 @@ func TestDecode(t *testing.T) {
} else { } else {
dst = reflect.New(reflect.TypeOf(tc.into)) dst = reflect.New(reflect.TypeOf(tc.into))
} }
err := dm.Unmarshal(tc.in, dst.Interface()) err := decMode.Unmarshal(tc.in, dst.Interface())
tc.assertOnError(t, err) tc.assertOnError(t, err)
if tc.want != nil { if tc.want != nil {
if diff := cmp.Diff(tc.want, dst.Elem().Interface()); diff != "" { if diff := cmp.Diff(tc.want, dst.Elem().Interface()); diff != "" {

View File

@ -24,12 +24,14 @@ import (
"time" "time"
"github.com/fxamacker/cbor/v2" "github.com/fxamacker/cbor/v2"
"github.com/google/go-cmp/cmp"
) )
func nilPointerFor[T interface{}]() *T { func nilPointerFor[T interface{}]() *T {
return nil return nil
} }
// TestRoundtrip roundtrips object serialization to interface{} and back via CBOR.
func TestRoundtrip(t *testing.T) { func TestRoundtrip(t *testing.T) {
type modePair struct { type modePair struct {
enc cbor.EncMode enc cbor.EncMode
@ -101,10 +103,6 @@ func TestRoundtrip(t *testing.T) {
name: "int64 zero", name: "int64 zero",
obj: int64(math.MinInt64), obj: int64(math.MinInt64),
}, },
{
name: "uint64 max",
obj: uint64(math.MaxUint64),
},
{ {
name: "uint64 zero", name: "uint64 zero",
obj: uint64(0), obj: uint64(0),
@ -260,24 +258,24 @@ func TestRoundtrip(t *testing.T) {
}{}, }{},
}, },
} { } {
mps := tc.modePairs modePairs := tc.modePairs
if len(mps) == 0 { if len(modePairs) == 0 {
// Default is all modes to all modes. // Default is all modes to all modes.
mps = []modePair{} modePairs = []modePair{}
for _, em := range allEncModes { for _, encMode := range allEncModes {
for _, dm := range allDecModes { for _, decMode := range allDecModes {
mps = append(mps, modePair{enc: em, dec: dm}) modePairs = append(modePairs, modePair{enc: encMode, dec: decMode})
} }
} }
} }
for _, mp := range mps { for _, modePair := range modePairs {
encModeName, ok := encModeNames[mp.enc] encModeName, ok := encModeNames[modePair.enc]
if !ok { if !ok {
t.Fatal("test case configured to run against unrecognized encode mode") t.Fatal("test case configured to run against unrecognized encode mode")
} }
decModeName, ok := decModeNames[mp.dec] decModeName, ok := decModeNames[modePair.dec]
if !ok { if !ok {
t.Fatal("test case configured to run against unrecognized decode mode") t.Fatal("test case configured to run against unrecognized decode mode")
} }
@ -285,18 +283,54 @@ func TestRoundtrip(t *testing.T) {
t.Run(fmt.Sprintf("enc=%s/dec=%s/%s", encModeName, decModeName, tc.name), func(t *testing.T) { t.Run(fmt.Sprintf("enc=%s/dec=%s/%s", encModeName, decModeName, tc.name), func(t *testing.T) {
original := tc.obj original := tc.obj
b, err := mp.enc.Marshal(original) cborFromOriginal, err := modePair.enc.Marshal(original)
if err != nil { if err != nil {
t.Fatalf("unexpected error from Marshal: %v", err) t.Fatalf("unexpected error from Marshal of original: %v", err)
} }
final := reflect.New(reflect.TypeOf(original)) var iface interface{}
err = mp.dec.Unmarshal(b, final.Interface()) if err := modePair.dec.Unmarshal(cborFromOriginal, &iface); err != nil {
if err != nil { t.Fatalf("unexpected error from Unmarshal into %T: %v", &iface, err)
t.Fatalf("unexpected error from Unmarshal: %v", err)
} }
if !reflect.DeepEqual(original, final.Elem().Interface()) {
t.Errorf("roundtrip difference:\nwant: %#v\ngot: %#v", original, final) cborFromIface, err := modePair.enc.Marshal(iface)
if err != nil {
t.Fatalf("unexpected error from Marshal of iface: %v", err)
}
{
// interface{} to interface{}
var iface2 interface{}
if err := modePair.dec.Unmarshal(cborFromIface, &iface2); err != nil {
t.Fatalf("unexpected error from Unmarshal into %T: %v", &iface2, err)
}
if diff := cmp.Diff(iface, iface2); diff != "" {
t.Errorf("unexpected difference on roundtrip from interface{} to interface{}:\n%s", diff)
}
}
{
// original to original
final := reflect.New(reflect.TypeOf(original))
err = modePair.dec.Unmarshal(cborFromOriginal, final.Interface())
if err != nil {
t.Fatalf("unexpected error from Unmarshal into %T: %v", final.Interface(), err)
}
if diff := cmp.Diff(original, final.Elem().Interface()); diff != "" {
t.Errorf("unexpected difference on roundtrip from original to original:\n%s", diff)
}
}
{
// original to interface{} to original
finalViaIface := reflect.New(reflect.TypeOf(original))
err = modePair.dec.Unmarshal(cborFromIface, finalViaIface.Interface())
if err != nil {
t.Fatalf("unexpected error from Unmarshal into %T: %v", finalViaIface.Interface(), err)
}
if diff := cmp.Diff(original, finalViaIface.Elem().Interface()); diff != "" {
t.Errorf("unexpected difference on roundtrip from original to interface{} to original:\n%s", diff)
}
} }
}) })
} }