mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-04 01:40:07 +00:00
Implement cbor.Marshaler and cbor.Unmarshaler for resource.Quantity.
This commit is contained in:
parent
14367eee5a
commit
d2dfce59ff
@ -25,6 +25,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
|
||||||
|
|
||||||
inf "gopkg.in/inf.v0"
|
inf "gopkg.in/inf.v0"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -683,6 +685,12 @@ func (q Quantity) MarshalJSON() ([]byte, error) {
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q Quantity) MarshalCBOR() ([]byte, error) {
|
||||||
|
// The call to String() should never return the string "<nil>" because the receiver's
|
||||||
|
// address will never be nil.
|
||||||
|
return cbor.Marshal(q.String())
|
||||||
|
}
|
||||||
|
|
||||||
// ToUnstructured implements the value.UnstructuredConverter interface.
|
// ToUnstructured implements the value.UnstructuredConverter interface.
|
||||||
func (q Quantity) ToUnstructured() interface{} {
|
func (q Quantity) ToUnstructured() interface{} {
|
||||||
return q.String()
|
return q.String()
|
||||||
@ -711,6 +719,27 @@ func (q *Quantity) UnmarshalJSON(value []byte) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (q *Quantity) UnmarshalCBOR(value []byte) error {
|
||||||
|
var s *string
|
||||||
|
if err := cbor.Unmarshal(value, &s); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if s == nil {
|
||||||
|
q.d.Dec = nil
|
||||||
|
q.i = int64Amount{}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
parsed, err := ParseQuantity(strings.TrimSpace(*s))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
*q = parsed
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// NewDecimalQuantity returns a new Quantity representing the given
|
// NewDecimalQuantity returns a new Quantity representing the given
|
||||||
// value in the given format.
|
// value in the given format.
|
||||||
func NewDecimalQuantity(b inf.Dec, format Format) *Quantity {
|
func NewDecimalQuantity(b inf.Dec, format Format) *Quantity {
|
||||||
|
@ -27,10 +27,12 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
fuzz "github.com/google/gofuzz"
|
fuzz "github.com/google/gofuzz"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
inf "gopkg.in/inf.v0"
|
inf "gopkg.in/inf.v0"
|
||||||
|
|
||||||
|
cbor "k8s.io/apimachinery/pkg/runtime/serializer/cbor/direct"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
@ -1615,3 +1617,88 @@ func ExampleQuantityValue() {
|
|||||||
// Output:
|
// Output:
|
||||||
// --mem quantity sets amount of memory (default 1Mi)
|
// --mem quantity sets amount of memory (default 1Mi)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestQuantityUnmarshalCBOR(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
in []byte
|
||||||
|
want Quantity
|
||||||
|
errMessage string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "null",
|
||||||
|
in: []byte{0xf6}, // null
|
||||||
|
want: Quantity{},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "text string input",
|
||||||
|
in: []byte("\x621M"), // "1M"
|
||||||
|
want: Quantity{i: int64Amount{value: 1, scale: 6}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "byte string input",
|
||||||
|
in: []byte("\x421M"), // '1M'
|
||||||
|
want: Quantity{i: int64Amount{value: 1, scale: 6}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "whitespace",
|
||||||
|
in: []byte("\x4a \t\n\r1M \t\n\r"), // h'20090a0d314d20090a0d'
|
||||||
|
want: Quantity{i: int64Amount{value: 1, scale: 6}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty byte string",
|
||||||
|
in: []byte{0x40},
|
||||||
|
errMessage: ErrFormatWrong.Error(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty text string",
|
||||||
|
in: []byte{0x60},
|
||||||
|
errMessage: ErrFormatWrong.Error(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "unsupported input type",
|
||||||
|
in: []byte{0x07}, // 7
|
||||||
|
errMessage: "cbor: cannot unmarshal positive integer into Go value of type string",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
var got Quantity
|
||||||
|
if err := got.UnmarshalCBOR(tc.in); err != nil {
|
||||||
|
if tc.errMessage == "" {
|
||||||
|
t.Fatalf("want nil error, got: %v", err)
|
||||||
|
} else if gotMessage := err.Error(); tc.errMessage != gotMessage {
|
||||||
|
t.Fatalf("want error: %q, got: %q", tc.errMessage, gotMessage)
|
||||||
|
}
|
||||||
|
} else if tc.errMessage != "" {
|
||||||
|
t.Fatalf("got nil error, want: %s", tc.errMessage)
|
||||||
|
}
|
||||||
|
|
||||||
|
if diff := cmp.Diff(tc.want, got); diff != "" {
|
||||||
|
t.Errorf("unexpected diff:\n%s", diff)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestQuantityRoundtripCBOR(t *testing.T) {
|
||||||
|
for i := 0; i < 500; i++ {
|
||||||
|
var initial, final Quantity
|
||||||
|
fuzzer.Fuzz(&initial)
|
||||||
|
b, err := cbor.Marshal(initial)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("error encoding %v: %v", initial, err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
err = cbor.Unmarshal(b, &final)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("%v: error decoding %v: %v", initial, string(b), err)
|
||||||
|
}
|
||||||
|
if final.Cmp(initial) != 0 {
|
||||||
|
diag, err := cbor.Diagnose(b)
|
||||||
|
if err != nil {
|
||||||
|
t.Logf("failed to produce diagnostic encoding of 0x%x: %v", b, err)
|
||||||
|
}
|
||||||
|
t.Errorf("Expected equal: %v, %v (cbor was '%s')", initial, final, diag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user