Add more tests around JSON/YAML decoding from the CLI

Switch the ignore stream errors behavior to print a Warningf on
failure to parse, not v(2)
This commit is contained in:
Clayton Coleman 2015-01-14 12:38:36 -05:00
parent abc621759a
commit 31413c8727
4 changed files with 39 additions and 5 deletions

View File

@ -138,6 +138,19 @@ for version in "${kube_api_versions[@]}"; do
output_service=$(kubectl get service frontend -o json --output-version=v1beta3 "${kube_flags[@]}") output_service=$(kubectl get service frontend -o json --output-version=v1beta3 "${kube_flags[@]}")
kubectl delete service frontend "${kube_flags[@]}" kubectl delete service frontend "${kube_flags[@]}"
echo "${output_service}" | kubectl create -f - "${kube_flags[@]}" echo "${output_service}" | kubectl create -f - "${kube_flags[@]}"
kubectl create -f - "${kube_flags[@]}" << __EOF__
{
"kind": "Service",
"apiVersion": "v1beta1",
"id": "service-${version}-test",
"port": 80,
"protocol": "TCP",
"labels": {
"name": "${version}"
}
}
__EOF__
kubectl get services "something-${version}" "${kube_flags[@]}"
kubectl get services "${kube_flags[@]}" kubectl get services "${kube_flags[@]}"
kubectl delete service frontend "${kube_flags[@]}" kubectl delete service frontend "${kube_flags[@]}"

View File

@ -337,7 +337,10 @@ type StreamVisitor struct {
} }
// NewStreamVisitor creates a visitor that will return resources that were encoded into the provided // NewStreamVisitor creates a visitor that will return resources that were encoded into the provided
// stream. If ignoreErrors is set, unrecognized or invalid objects will be skipped and logged. // stream. If ignoreErrors is set, unrecognized or invalid objects will be skipped and logged. An
// empty stream is treated as an error for now.
// TODO: convert ignoreErrors into a func(data, error, count) bool that consumers can use to decide
// what to do with ignored errors.
func NewStreamVisitor(r io.Reader, mapper *Mapper, source string, ignoreErrors bool) Visitor { func NewStreamVisitor(r io.Reader, mapper *Mapper, source string, ignoreErrors bool) Visitor {
return &StreamVisitor{r, mapper, source, ignoreErrors} return &StreamVisitor{r, mapper, source, ignoreErrors}
} }
@ -356,7 +359,7 @@ func (v *StreamVisitor) Visit(fn VisitorFunc) error {
info, err := v.InfoForData(ext.RawJSON, v.Source) info, err := v.InfoForData(ext.RawJSON, v.Source)
if err != nil { if err != nil {
if v.IgnoreErrors { if v.IgnoreErrors {
glog.V(2).Infof("Unable to read item from stream %q: %v", err) glog.Warningf("Could not read an encoded object from %s: %v", v.Source, err)
glog.V(4).Infof("Unreadable: %s", string(ext.RawJSON)) glog.V(4).Infof("Unreadable: %s", string(ext.RawJSON))
continue continue
} }

View File

@ -149,6 +149,6 @@ func guessJSONStream(r io.Reader, size int) (io.Reader, bool) {
// Return true if the first non-whitespace bytes in buf is // Return true if the first non-whitespace bytes in buf is
// prefix // prefix
func hasPrefix(buf []byte, prefix []byte) bool { func hasPrefix(buf []byte, prefix []byte) bool {
buf = bytes.TrimLeftFunc(buf, unicode.IsSpace) trim := bytes.TrimLeftFunc(buf, unicode.IsSpace)
return bytes.HasPrefix(buf, prefix) return bytes.HasPrefix(trim, prefix)
} }

View File

@ -61,6 +61,21 @@ func TestSplitYAMLDocument(t *testing.T) {
} }
} }
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) { func TestScanYAML(t *testing.T) {
s := bufio.NewScanner(bytes.NewReader([]byte(`--- s := bufio.NewScanner(bytes.NewReader([]byte(`---
stuff: 1 stuff: 1
@ -130,7 +145,10 @@ func TestYAMLOrJSONDecoder(t *testing.T) {
{" \na: b", 2, false, false, []generic{ {" \na: b", 2, false, false, []generic{
{"a": "b"}, {"a": "b"},
}}, }},
{` \n{"a": "b"}`, 2, false, true, []generic{ {" \n{\"a\": \"b\"}", 2, false, true, []generic{
{"a": "b"},
}},
{" \n{\"a\": \"b\"}", 3, true, false, []generic{
{"a": "b"}, {"a": "b"},
}}, }},
{` {"a":"b"}`, 100, true, false, []generic{ {` {"a":"b"}`, 100, true, false, []generic{