mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-18 08:09:58 +00:00
Merge pull request #124324 from benluddy/cbor-decode-tests-grouped-by-cbor-type
KEP-4222: Group CBOR decode tests by the kind of their inputs.
This commit is contained in:
commit
77f7d1b89d
@ -37,14 +37,99 @@ func TestDecode(t *testing.T) {
|
||||
return b
|
||||
}
|
||||
|
||||
for _, tc := range []struct {
|
||||
type test struct {
|
||||
name string
|
||||
modes []cbor.DecMode
|
||||
modes []cbor.DecMode // most tests should run for all modes
|
||||
in []byte
|
||||
into interface{} // prototype for concrete destination type. if nil, decode into empty interface value.
|
||||
want interface{}
|
||||
assertOnError func(t *testing.T, e error)
|
||||
}{
|
||||
}
|
||||
|
||||
// Test cases are grouped by the kind of the CBOR data item being decoded, as enumerated in
|
||||
// https://www.rfc-editor.org/rfc/rfc8949.html#section-2.
|
||||
group := func(t *testing.T, name string, tests []test) {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
decModes := test.modes
|
||||
if len(decModes) == 0 {
|
||||
decModes = allDecModes
|
||||
}
|
||||
|
||||
for _, decMode := range decModes {
|
||||
modeName, ok := decModeNames[decMode]
|
||||
if !ok {
|
||||
t.Fatal("test case configured to run against unrecognized mode")
|
||||
}
|
||||
|
||||
t.Run(fmt.Sprintf("%s/mode=%s", test.name, modeName), func(t *testing.T) {
|
||||
var dst reflect.Value
|
||||
if test.into == nil {
|
||||
var i interface{}
|
||||
dst = reflect.ValueOf(&i)
|
||||
} else {
|
||||
dst = reflect.New(reflect.TypeOf(test.into))
|
||||
}
|
||||
err := decMode.Unmarshal(test.in, dst.Interface())
|
||||
test.assertOnError(t, err)
|
||||
if test.want != nil {
|
||||
if diff := cmp.Diff(test.want, dst.Elem().Interface()); diff != "" {
|
||||
t.Errorf("unexpected output:\n%s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
group(t, "unsigned integer", []test{
|
||||
{
|
||||
name: "unsigned integer decodes to interface{} as int64",
|
||||
in: hex("0a"), // 10
|
||||
want: int64(10),
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
})
|
||||
|
||||
group(t, "negative integer", []test{})
|
||||
|
||||
group(t, "byte string", []test{})
|
||||
|
||||
group(t, "text string", []test{
|
||||
{
|
||||
name: "reject text string containing invalid utf-8 sequence",
|
||||
in: hex("6180"), // text string beginning with continuation byte 0x80
|
||||
assertOnError: assertOnConcreteError(func(t *testing.T, e *cbor.SemanticError) {
|
||||
const expected = "cbor: invalid UTF-8 string"
|
||||
if msg := e.Error(); msg != expected {
|
||||
t.Errorf("expected %v, got %v", expected, msg)
|
||||
}
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "indefinite-length text string",
|
||||
in: hex("7f616161626163ff"), // (_ "a", "b", "c")
|
||||
want: "abc",
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
})
|
||||
|
||||
group(t, "array", []test{
|
||||
{
|
||||
name: "nested indefinite-length array",
|
||||
in: hex("9f9f8080ff9f8080ffff"), // [_ [_ [] []] [_ [][]]]
|
||||
want: []interface{}{
|
||||
[]interface{}{[]interface{}{}, []interface{}{}},
|
||||
[]interface{}{[]interface{}{}, []interface{}{}},
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
})
|
||||
|
||||
group(t, "map", []test{
|
||||
{
|
||||
name: "reject duplicate negative int keys into struct",
|
||||
modes: []cbor.DecMode{modes.DecodeLax},
|
||||
@ -216,22 +301,6 @@ func TestDecode(t *testing.T) {
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "reject text string containing invalid utf-8 sequence",
|
||||
in: hex("6180"), // text string beginning with continuation byte 0x80
|
||||
assertOnError: assertOnConcreteError(func(t *testing.T, e *cbor.SemanticError) {
|
||||
const expected = "cbor: invalid UTF-8 string"
|
||||
if msg := e.Error(); msg != expected {
|
||||
t.Errorf("expected %v, got %v", expected, msg)
|
||||
}
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: "unsigned integer decodes to interface{} as int64",
|
||||
in: hex("0a"), // 10
|
||||
want: int64(10),
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "unknown field error",
|
||||
modes: []cbor.DecMode{modes.Decode},
|
||||
@ -251,21 +320,6 @@ func TestDecode(t *testing.T) {
|
||||
want: struct{}{},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "indefinite-length text string",
|
||||
in: hex("7f616161626163ff"), // (_ "a", "b", "c")
|
||||
want: "abc",
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "nested indefinite-length array",
|
||||
in: hex("9f9f8080ff9f8080ffff"), // [_ [_ [] []] [_ [][]]]
|
||||
want: []interface{}{
|
||||
[]interface{}{[]interface{}{}, []interface{}{}},
|
||||
[]interface{}{[]interface{}{}, []interface{}{}},
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
{
|
||||
name: "nested indefinite-length map",
|
||||
in: hex("bf6141bf616101616202ff6142bf616901616a02ffff"), // {_ "A": {_ "a": 1, "b": 2}, "B": {_ "i": 1, "j": 2}}
|
||||
@ -275,34 +329,21 @@ func TestDecode(t *testing.T) {
|
||||
},
|
||||
assertOnError: assertNilError,
|
||||
},
|
||||
} {
|
||||
decModes := tc.modes
|
||||
if len(decModes) == 0 {
|
||||
decModes = allDecModes
|
||||
}
|
||||
|
||||
for _, decMode := range decModes {
|
||||
modeName, ok := decModeNames[decMode]
|
||||
if !ok {
|
||||
t.Fatal("test case configured to run against unrecognized mode")
|
||||
}
|
||||
|
||||
t.Run(fmt.Sprintf("mode=%s/%s", modeName, tc.name), func(t *testing.T) {
|
||||
var dst reflect.Value
|
||||
if tc.into == nil {
|
||||
var i interface{}
|
||||
dst = reflect.ValueOf(&i)
|
||||
} else {
|
||||
dst = reflect.New(reflect.TypeOf(tc.into))
|
||||
}
|
||||
err := decMode.Unmarshal(tc.in, dst.Interface())
|
||||
tc.assertOnError(t, err)
|
||||
if tc.want != nil {
|
||||
if diff := cmp.Diff(tc.want, dst.Elem().Interface()); diff != "" {
|
||||
t.Errorf("unexpected output:\n%s", diff)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
group(t, "floating-point number", []test{})
|
||||
|
||||
group(t, "simple value", []test{})
|
||||
|
||||
t.Run("tag", func(t *testing.T) {
|
||||
group(t, "rfc3339 time", []test{})
|
||||
|
||||
group(t, "epoch time", []test{})
|
||||
|
||||
group(t, "unsigned bignum", []test{})
|
||||
|
||||
group(t, "negative bignum", []test{})
|
||||
|
||||
group(t, "unrecognized", []test{})
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user