mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 18:43:34 +00:00
405
vendor/k8s.io/apimachinery/pkg/util/yaml/decoder_test.go
generated
vendored
405
vendor/k8s.io/apimachinery/pkg/util/yaml/decoder_test.go
generated
vendored
@ -1,405 +0,0 @@
|
||||
/*
|
||||
Copyright 2014 The Kubernetes Authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package yaml
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestYAMLDecoderReadBytesLength(t *testing.T) {
|
||||
d := `---
|
||||
stuff: 1
|
||||
test-foo: 1
|
||||
`
|
||||
testCases := []struct {
|
||||
bufLen int
|
||||
expectLen int
|
||||
expectErr error
|
||||
}{
|
||||
{len(d), len(d), nil},
|
||||
{len(d) + 10, len(d), nil},
|
||||
{len(d) - 10, len(d) - 10, io.ErrShortBuffer},
|
||||
}
|
||||
|
||||
for i, testCase := range testCases {
|
||||
r := NewDocumentDecoder(ioutil.NopCloser(bytes.NewReader([]byte(d))))
|
||||
b := make([]byte, testCase.bufLen)
|
||||
n, err := r.Read(b)
|
||||
if err != testCase.expectErr || n != testCase.expectLen {
|
||||
t.Fatalf("%d: unexpected body: %d / %v", i, n, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestYAMLDecoderCallsAfterErrShortBufferRestOfFrame(t *testing.T) {
|
||||
d := `---
|
||||
stuff: 1
|
||||
test-foo: 1`
|
||||
r := NewDocumentDecoder(ioutil.NopCloser(bytes.NewReader([]byte(d))))
|
||||
b := make([]byte, 12)
|
||||
n, err := r.Read(b)
|
||||
if err != io.ErrShortBuffer || n != 12 {
|
||||
t.Fatalf("expected ErrShortBuffer: %d / %v", n, err)
|
||||
}
|
||||
expected := "---\nstuff: 1"
|
||||
if string(b) != expected {
|
||||
t.Fatalf("expected bytes read to be: %s got: %s", expected, string(b))
|
||||
}
|
||||
b = make([]byte, 13)
|
||||
n, err = r.Read(b)
|
||||
if err != nil || n != 13 {
|
||||
t.Fatalf("expected nil: %d / %v", n, err)
|
||||
}
|
||||
expected = "\n\ttest-foo: 1"
|
||||
if string(b) != expected {
|
||||
t.Fatalf("expected bytes read to be: '%s' got: '%s'", expected, string(b))
|
||||
}
|
||||
b = make([]byte, 15)
|
||||
n, err = r.Read(b)
|
||||
if err != io.EOF || n != 0 {
|
||||
t.Fatalf("expected EOF: %d / %v", n, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSplitYAMLDocument(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
atEOF bool
|
||||
expect string
|
||||
adv int
|
||||
}{
|
||||
{"foo", true, "foo", 3},
|
||||
{"fo", false, "", 0},
|
||||
|
||||
{"---", true, "---", 3},
|
||||
{"---\n", true, "---\n", 4},
|
||||
{"---\n", false, "", 0},
|
||||
|
||||
{"\n---\n", false, "", 5},
|
||||
{"\n---\n", true, "", 5},
|
||||
|
||||
{"abc\n---\ndef", true, "abc", 8},
|
||||
{"def", true, "def", 3},
|
||||
{"", true, "", 0},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
adv, token, err := splitYAMLDocument([]byte(testCase.input), testCase.atEOF)
|
||||
if err != nil {
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
}
|
||||
if adv != testCase.adv {
|
||||
t.Errorf("%d: advance did not match: %d %d", i, testCase.adv, adv)
|
||||
}
|
||||
if testCase.expect != string(token) {
|
||||
t.Errorf("%d: token did not match: %q %q", i, testCase.expect, string(token))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestGuessJSON(t *testing.T) {
|
||||
if r, _, isJSON := GuessJSONStream(bytes.NewReader([]byte(" \n{}")), 100); !isJSON {
|
||||
t.Fatalf("expected stream to be JSON")
|
||||
} else {
|
||||
b := make([]byte, 30)
|
||||
n, err := r.Read(b)
|
||||
if err != nil || n != 4 {
|
||||
t.Fatalf("unexpected body: %d / %v", n, err)
|
||||
}
|
||||
if string(b[:n]) != " \n{}" {
|
||||
t.Fatalf("unexpected body: %q", string(b[:n]))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestScanYAML(t *testing.T) {
|
||||
s := bufio.NewScanner(bytes.NewReader([]byte(`---
|
||||
stuff: 1
|
||||
|
||||
---
|
||||
`)))
|
||||
s.Split(splitYAMLDocument)
|
||||
if !s.Scan() {
|
||||
t.Fatalf("should have been able to scan")
|
||||
}
|
||||
t.Logf("scan: %s", s.Text())
|
||||
if !s.Scan() {
|
||||
t.Fatalf("should have been able to scan")
|
||||
}
|
||||
t.Logf("scan: %s", s.Text())
|
||||
if s.Scan() {
|
||||
t.Fatalf("scan should have been done")
|
||||
}
|
||||
if s.Err() != nil {
|
||||
t.Fatalf("err should have been nil: %v", s.Err())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeYAML(t *testing.T) {
|
||||
s := NewYAMLToJSONDecoder(bytes.NewReader([]byte(`---
|
||||
stuff: 1
|
||||
|
||||
---
|
||||
`)))
|
||||
obj := generic{}
|
||||
if err := s.Decode(&obj); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if fmt.Sprintf("%#v", obj) != `yaml.generic{"stuff":1}` {
|
||||
t.Errorf("unexpected object: %#v", obj)
|
||||
}
|
||||
obj = generic{}
|
||||
if err := s.Decode(&obj); err != nil {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
if len(obj) != 0 {
|
||||
t.Fatalf("unexpected object: %#v", obj)
|
||||
}
|
||||
obj = generic{}
|
||||
if err := s.Decode(&obj); err != io.EOF {
|
||||
t.Fatalf("unexpected error: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeBrokenYAML(t *testing.T) {
|
||||
s := NewYAMLOrJSONDecoder(bytes.NewReader([]byte(`---
|
||||
stuff: 1
|
||||
test-foo: 1
|
||||
|
||||
---
|
||||
`)), 100)
|
||||
obj := generic{}
|
||||
err := s.Decode(&obj)
|
||||
if err == nil {
|
||||
t.Fatal("expected error with yaml: violate, got no error")
|
||||
}
|
||||
fmt.Printf("err: %s\n", err.Error())
|
||||
if !strings.Contains(err.Error(), "yaml: line 3:") {
|
||||
t.Fatalf("expected %q to have 'yaml: line 3:' found a tab character", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestDecodeBrokenJSON(t *testing.T) {
|
||||
s := NewYAMLOrJSONDecoder(bytes.NewReader([]byte(`{
|
||||
"foo": {
|
||||
"stuff": 1
|
||||
"otherStuff": 2
|
||||
}
|
||||
}
|
||||
`)), 100)
|
||||
obj := generic{}
|
||||
err := s.Decode(&obj)
|
||||
if err == nil {
|
||||
t.Fatal("expected error with json: prefix, got no error")
|
||||
}
|
||||
if !strings.HasPrefix(err.Error(), "json: line 3:") {
|
||||
t.Fatalf("expected %q to have 'json: line 3:' prefix", err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
type generic map[string]interface{}
|
||||
|
||||
func TestYAMLOrJSONDecoder(t *testing.T) {
|
||||
testCases := []struct {
|
||||
input string
|
||||
buffer int
|
||||
isJSON bool
|
||||
err bool
|
||||
out []generic
|
||||
}{
|
||||
{` {"1":2}{"3":4}`, 2, true, false, []generic{
|
||||
{"1": 2},
|
||||
{"3": 4},
|
||||
}},
|
||||
{" \n{}", 3, true, false, []generic{
|
||||
{},
|
||||
}},
|
||||
{" \na: b", 2, false, false, []generic{
|
||||
{"a": "b"},
|
||||
}},
|
||||
{" \n{\"a\": \"b\"}", 2, false, true, []generic{
|
||||
{"a": "b"},
|
||||
}},
|
||||
{" \n{\"a\": \"b\"}", 3, true, false, []generic{
|
||||
{"a": "b"},
|
||||
}},
|
||||
{` {"a":"b"}`, 100, true, false, []generic{
|
||||
{"a": "b"},
|
||||
}},
|
||||
{"", 1, false, false, []generic{}},
|
||||
{"foo: bar\n---\nbaz: biz", 100, false, false, []generic{
|
||||
{"foo": "bar"},
|
||||
{"baz": "biz"},
|
||||
}},
|
||||
{"foo: bar\n---\n", 100, false, false, []generic{
|
||||
{"foo": "bar"},
|
||||
}},
|
||||
{"foo: bar\n---", 100, false, false, []generic{
|
||||
{"foo": "bar"},
|
||||
}},
|
||||
{"foo: bar\n--", 100, false, true, []generic{
|
||||
{"foo": "bar"},
|
||||
}},
|
||||
{"foo: bar\n-", 100, false, true, []generic{
|
||||
{"foo": "bar"},
|
||||
}},
|
||||
{"foo: bar\n", 100, false, false, []generic{
|
||||
{"foo": "bar"},
|
||||
}},
|
||||
}
|
||||
for i, testCase := range testCases {
|
||||
decoder := NewYAMLOrJSONDecoder(bytes.NewReader([]byte(testCase.input)), testCase.buffer)
|
||||
objs := []generic{}
|
||||
|
||||
var err error
|
||||
for {
|
||||
out := make(generic)
|
||||
err = decoder.Decode(&out)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
objs = append(objs, out)
|
||||
}
|
||||
if err != io.EOF {
|
||||
switch {
|
||||
case testCase.err && err == nil:
|
||||
t.Errorf("%d: unexpected non-error", i)
|
||||
continue
|
||||
case !testCase.err && err != nil:
|
||||
t.Errorf("%d: unexpected error: %v", i, err)
|
||||
continue
|
||||
case err != nil:
|
||||
continue
|
||||
}
|
||||
}
|
||||
switch decoder.decoder.(type) {
|
||||
case *YAMLToJSONDecoder:
|
||||
if testCase.isJSON {
|
||||
t.Errorf("%d: expected JSON decoder, got YAML", i)
|
||||
}
|
||||
case *json.Decoder:
|
||||
if !testCase.isJSON {
|
||||
t.Errorf("%d: expected YAML decoder, got JSON", i)
|
||||
}
|
||||
}
|
||||
if fmt.Sprintf("%#v", testCase.out) != fmt.Sprintf("%#v", objs) {
|
||||
t.Errorf("%d: objects were not equal: \n%#v\n%#v", i, testCase.out, objs)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestReadSingleLongLine(t *testing.T) {
|
||||
testReadLines(t, []int{128 * 1024})
|
||||
}
|
||||
|
||||
func TestReadRandomLineLengths(t *testing.T) {
|
||||
minLength := 100
|
||||
maxLength := 96 * 1024
|
||||
maxLines := 100
|
||||
|
||||
lineLengths := make([]int, maxLines)
|
||||
for i := 0; i < maxLines; i++ {
|
||||
lineLengths[i] = rand.Intn(maxLength-minLength) + minLength
|
||||
}
|
||||
|
||||
testReadLines(t, lineLengths)
|
||||
}
|
||||
|
||||
func testReadLines(t *testing.T, lineLengths []int) {
|
||||
var (
|
||||
lines [][]byte
|
||||
inputStream []byte
|
||||
)
|
||||
for _, lineLength := range lineLengths {
|
||||
inputLine := make([]byte, lineLength+1)
|
||||
for i := 0; i < lineLength; i++ {
|
||||
char := rand.Intn('z'-'A') + 'A'
|
||||
inputLine[i] = byte(char)
|
||||
}
|
||||
inputLine[len(inputLine)-1] = '\n'
|
||||
lines = append(lines, inputLine)
|
||||
}
|
||||
for _, line := range lines {
|
||||
inputStream = append(inputStream, line...)
|
||||
}
|
||||
|
||||
// init Reader
|
||||
reader := bufio.NewReader(bytes.NewReader(inputStream))
|
||||
lineReader := &LineReader{reader: reader}
|
||||
|
||||
// read lines
|
||||
var readLines [][]byte
|
||||
for range lines {
|
||||
bytes, err := lineReader.Read()
|
||||
if err != nil && err != io.EOF {
|
||||
t.Fatalf("failed to read lines: %v", err)
|
||||
}
|
||||
readLines = append(readLines, bytes)
|
||||
}
|
||||
|
||||
// validate
|
||||
for i := range lines {
|
||||
if len(lines[i]) != len(readLines[i]) {
|
||||
t.Fatalf("expected line length: %d, but got %d", len(lines[i]), len(readLines[i]))
|
||||
}
|
||||
if !reflect.DeepEqual(lines[i], readLines[i]) {
|
||||
t.Fatalf("expected line: %v, but got %v", lines[i], readLines[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestTypedJSONOrYamlErrors(t *testing.T) {
|
||||
s := NewYAMLOrJSONDecoder(bytes.NewReader([]byte(`{
|
||||
"foo": {
|
||||
"stuff": 1
|
||||
"otherStuff": 2
|
||||
}
|
||||
}
|
||||
`)), 100)
|
||||
obj := generic{}
|
||||
err := s.Decode(&obj)
|
||||
if err == nil {
|
||||
t.Fatal("expected error with json: prefix, got no error")
|
||||
}
|
||||
if _, ok := err.(JSONSyntaxError); !ok {
|
||||
t.Fatalf("expected %q to be of type JSONSyntaxError", err.Error())
|
||||
}
|
||||
|
||||
s = NewYAMLOrJSONDecoder(bytes.NewReader([]byte(`---
|
||||
stuff: 1
|
||||
test-foo: 1
|
||||
|
||||
---
|
||||
`)), 100)
|
||||
obj = generic{}
|
||||
err = s.Decode(&obj)
|
||||
if err == nil {
|
||||
t.Fatal("expected error with yaml: prefix, got no error")
|
||||
}
|
||||
if _, ok := err.(YAMLSyntaxError); !ok {
|
||||
t.Fatalf("expected %q to be of type YAMLSyntaxError", err.Error())
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user