Commit 54b352ae authored by k8s-merge-robot's avatar k8s-merge-robot

Merge pull request #26907 from smarterclayton/tolerate_quantity

Automatic merge from submit-queue Resource quantity must support leading and trailing whitespace in JSON for back-compat For backwards compatibility reasons, we must continue to support leading or trailing whitespace on Quantity values when deserialized from JSON. We must also support numbers serialized into yaml (`cpu: 1`) and JSON (`"cpu": 1`) Fixes #26898
parents 85b67f2f 653ddbb0
...@@ -260,7 +260,6 @@ Suffix: ...@@ -260,7 +260,6 @@ Suffix:
switch str[i] { switch str[i] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9': case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
default: default:
pos = i
break Suffix break Suffix
} }
} }
...@@ -620,6 +619,7 @@ func (q Quantity) MarshalJSON() ([]byte, error) { ...@@ -620,6 +619,7 @@ func (q Quantity) MarshalJSON() ([]byte, error) {
} }
// UnmarshalJSON implements the json.Unmarshaller interface. // UnmarshalJSON implements the json.Unmarshaller interface.
// TODO: Remove support for leading/trailing whitespace
func (q *Quantity) UnmarshalJSON(value []byte) error { func (q *Quantity) UnmarshalJSON(value []byte) error {
l := len(value) l := len(value)
if l == 4 && bytes.Equal(value, []byte("null")) { if l == 4 && bytes.Equal(value, []byte("null")) {
...@@ -627,14 +627,11 @@ func (q *Quantity) UnmarshalJSON(value []byte) error { ...@@ -627,14 +627,11 @@ func (q *Quantity) UnmarshalJSON(value []byte) error {
q.i = int64Amount{} q.i = int64Amount{}
return nil return nil
} }
if l < 2 { if l >= 2 && value[0] == '"' && value[l-1] == '"' {
return ErrFormatWrong
}
if value[0] == '"' && value[l-1] == '"' {
value = value[1 : l-1] value = value[1 : l-1]
} }
parsed, err := ParseQuantity(string(value)) parsed, err := ParseQuantity(strings.TrimSpace(string(value)))
if err != nil { if err != nil {
return err return err
} }
......
...@@ -19,7 +19,9 @@ package resource ...@@ -19,7 +19,9 @@ package resource
import ( import (
"encoding/json" "encoding/json"
"math/rand" "math/rand"
"strings"
"testing" "testing"
"unicode"
fuzz "github.com/google/gofuzz" fuzz "github.com/google/gofuzz"
"github.com/spf13/pflag" "github.com/spf13/pflag"
...@@ -231,6 +233,9 @@ func TestQuantityParse(t *testing.T) { ...@@ -231,6 +233,9 @@ func TestQuantityParse(t *testing.T) {
{"0Ti", decQuantity(0, 0, BinarySI)}, {"0Ti", decQuantity(0, 0, BinarySI)},
{"0T", decQuantity(0, 0, DecimalSI)}, {"0T", decQuantity(0, 0, DecimalSI)},
// Quantity less numbers are allowed
{"1", decQuantity(1, 0, DecimalSI)},
// Binary suffixes // Binary suffixes
{"1Ki", decQuantity(1024, 0, BinarySI)}, {"1Ki", decQuantity(1024, 0, BinarySI)},
{"8Ki", decQuantity(8*1024, 0, BinarySI)}, {"8Ki", decQuantity(8*1024, 0, BinarySI)},
...@@ -422,7 +427,7 @@ func TestQuantityParse(t *testing.T) { ...@@ -422,7 +427,7 @@ func TestQuantityParse(t *testing.T) {
desired := &inf.Dec{} desired := &inf.Dec{}
expect := Quantity{d: infDecAmount{Dec: desired}} expect := Quantity{d: infDecAmount{Dec: desired}}
for _, item := range table { for _, item := range table {
got, err := ParseQuantity("-" + item.input) got, err := ParseQuantity("-" + strings.TrimLeftFunc(item.input, unicode.IsSpace))
if err != nil { if err != nil {
t.Errorf("-%v: unexpected error: %v", item.input, err) t.Errorf("-%v: unexpected error: %v", item.input, err)
continue continue
...@@ -444,7 +449,7 @@ func TestQuantityParse(t *testing.T) { ...@@ -444,7 +449,7 @@ func TestQuantityParse(t *testing.T) {
// Try everything with an explicit + // Try everything with an explicit +
for _, item := range table { for _, item := range table {
got, err := ParseQuantity("+" + item.input) got, err := ParseQuantity("+" + strings.TrimLeftFunc(item.input, unicode.IsSpace))
if err != nil { if err != nil {
t.Errorf("-%v: unexpected error: %v", item.input, err) t.Errorf("-%v: unexpected error: %v", item.input, err)
continue continue
...@@ -472,6 +477,10 @@ func TestQuantityParse(t *testing.T) { ...@@ -472,6 +477,10 @@ func TestQuantityParse(t *testing.T) {
"1i", "1i",
"-3.01i", "-3.01i",
"-3.01e-", "-3.01e-",
// trailing whitespace is forbidden
" 1",
"1 ",
} }
for _, item := range invalid { for _, item := range invalid {
_, err := ParseQuantity(item) _, err := ParseQuantity(item)
...@@ -815,6 +824,31 @@ func TestJSON(t *testing.T) { ...@@ -815,6 +824,31 @@ func TestJSON(t *testing.T) {
} }
} }
func TestJSONWhitespace(t *testing.T) {
q := Quantity{}
testCases := []struct {
in string
expect string
}{
{`" 1"`, "1"},
{`"1 "`, "1"},
{`1`, "1"},
{` 1`, "1"},
{`1 `, "1"},
{`10`, "10"},
{`-1`, "-1"},
{` -1`, "-1"},
}
for _, test := range testCases {
if err := json.Unmarshal([]byte(test.in), &q); err != nil {
t.Errorf("%q: %v", test.in, err)
}
if q.String() != test.expect {
t.Errorf("unexpected string: %q", q.String())
}
}
}
func TestMilliNewSet(t *testing.T) { func TestMilliNewSet(t *testing.T) {
table := []struct { table := []struct {
value int64 value int64
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment