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
This commit is contained in:
k8s-merge-robot
2016-06-08 16:16:41 -07:00
2 changed files with 39 additions and 8 deletions

View File

@@ -260,7 +260,6 @@ Suffix:
switch str[i] {
case '0', '1', '2', '3', '4', '5', '6', '7', '8', '9':
default:
pos = i
break Suffix
}
}
@@ -620,6 +619,7 @@ func (q Quantity) MarshalJSON() ([]byte, error) {
}
// UnmarshalJSON implements the json.Unmarshaller interface.
// TODO: Remove support for leading/trailing whitespace
func (q *Quantity) UnmarshalJSON(value []byte) error {
l := len(value)
if l == 4 && bytes.Equal(value, []byte("null")) {
@@ -627,14 +627,11 @@ func (q *Quantity) UnmarshalJSON(value []byte) error {
q.i = int64Amount{}
return nil
}
if l < 2 {
return ErrFormatWrong
}
if value[0] == '"' && value[l-1] == '"' {
if l >= 2 && value[0] == '"' && value[l-1] == '"' {
value = value[1 : l-1]
}
parsed, err := ParseQuantity(string(value))
parsed, err := ParseQuantity(strings.TrimSpace(string(value)))
if err != nil {
return err
}

View File

@@ -19,7 +19,9 @@ package resource
import (
"encoding/json"
"math/rand"
"strings"
"testing"
"unicode"
fuzz "github.com/google/gofuzz"
"github.com/spf13/pflag"
@@ -231,6 +233,9 @@ func TestQuantityParse(t *testing.T) {
{"0Ti", decQuantity(0, 0, BinarySI)},
{"0T", decQuantity(0, 0, DecimalSI)},
// Quantity less numbers are allowed
{"1", decQuantity(1, 0, DecimalSI)},
// Binary suffixes
{"1Ki", decQuantity(1024, 0, BinarySI)},
{"8Ki", decQuantity(8*1024, 0, BinarySI)},
@@ -422,7 +427,7 @@ func TestQuantityParse(t *testing.T) {
desired := &inf.Dec{}
expect := Quantity{d: infDecAmount{Dec: desired}}
for _, item := range table {
got, err := ParseQuantity("-" + item.input)
got, err := ParseQuantity("-" + strings.TrimLeftFunc(item.input, unicode.IsSpace))
if err != nil {
t.Errorf("-%v: unexpected error: %v", item.input, err)
continue
@@ -444,7 +449,7 @@ func TestQuantityParse(t *testing.T) {
// Try everything with an explicit +
for _, item := range table {
got, err := ParseQuantity("+" + item.input)
got, err := ParseQuantity("+" + strings.TrimLeftFunc(item.input, unicode.IsSpace))
if err != nil {
t.Errorf("-%v: unexpected error: %v", item.input, err)
continue
@@ -472,6 +477,10 @@ func TestQuantityParse(t *testing.T) {
"1i",
"-3.01i",
"-3.01e-",
// trailing whitespace is forbidden
" 1",
"1 ",
}
for _, item := range invalid {
_, err := ParseQuantity(item)
@@ -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) {
table := []struct {
value int64