Update go dependencies

This commit is contained in:
Manuel de Brito Fontes 2018-05-26 11:27:53 -04:00 committed by Manuel Alejandro de Brito Fontes
parent 15ffb51394
commit bb4d483837
No known key found for this signature in database
GPG key ID: 786136016A8BA02A
1621 changed files with 86368 additions and 284392 deletions

View file

@ -1,371 +0,0 @@
/*
Copyright 2015 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 jsonpath
import (
"bytes"
"encoding/json"
"fmt"
"reflect"
"sort"
"strings"
"testing"
)
type jsonpathTest struct {
name string
template string
input interface{}
expect string
expectError bool
}
func testJSONPath(tests []jsonpathTest, allowMissingKeys bool, t *testing.T) {
for _, test := range tests {
j := New(test.name)
j.AllowMissingKeys(allowMissingKeys)
err := j.Parse(test.template)
if err != nil {
t.Errorf("in %s, parse %s error %v", test.name, test.template, err)
}
buf := new(bytes.Buffer)
err = j.Execute(buf, test.input)
if test.expectError {
if test.expectError && err == nil {
t.Errorf("in %s, expected execute error", test.name)
}
continue
} else if err != nil {
t.Errorf("in %s, execute error %v", test.name, err)
}
out := buf.String()
if out != test.expect {
t.Errorf(`in %s, expect to get "%s", got "%s"`, test.name, test.expect, out)
}
}
}
// testJSONPathSortOutput test cases related to map, the results may print in random order
func testJSONPathSortOutput(tests []jsonpathTest, t *testing.T) {
for _, test := range tests {
j := New(test.name)
err := j.Parse(test.template)
if err != nil {
t.Errorf("in %s, parse %s error %v", test.name, test.template, err)
}
buf := new(bytes.Buffer)
err = j.Execute(buf, test.input)
if err != nil {
t.Errorf("in %s, execute error %v", test.name, err)
}
out := buf.String()
//since map is visited in random order, we need to sort the results.
sortedOut := strings.Fields(out)
sort.Strings(sortedOut)
sortedExpect := strings.Fields(test.expect)
sort.Strings(sortedExpect)
if !reflect.DeepEqual(sortedOut, sortedExpect) {
t.Errorf(`in %s, expect to get "%s", got "%s"`, test.name, test.expect, out)
}
}
}
func testFailJSONPath(tests []jsonpathTest, t *testing.T) {
for _, test := range tests {
j := New(test.name)
err := j.Parse(test.template)
if err != nil {
t.Errorf("in %s, parse %s error %v", test.name, test.template, err)
}
buf := new(bytes.Buffer)
err = j.Execute(buf, test.input)
var out string
if err == nil {
out = "nil"
} else {
out = err.Error()
}
if out != test.expect {
t.Errorf("in %s, expect to get error %q, got %q", test.name, test.expect, out)
}
}
}
type book struct {
Category string
Author string
Title string
Price float32
}
func (b book) String() string {
return fmt.Sprintf("{Category: %s, Author: %s, Title: %s, Price: %v}", b.Category, b.Author, b.Title, b.Price)
}
type bicycle struct {
Color string
Price float32
IsNew bool
}
type empName string
type job string
type store struct {
Book []book
Bicycle []bicycle
Name string
Labels map[string]int
Employees map[empName]job
}
func TestStructInput(t *testing.T) {
storeData := store{
Name: "jsonpath",
Book: []book{
{"reference", "Nigel Rees", "Sayings of the Centurey", 8.95},
{"fiction", "Evelyn Waugh", "Sword of Honour", 12.99},
{"fiction", "Herman Melville", "Moby Dick", 8.99},
},
Bicycle: []bicycle{
{"red", 19.95, true},
{"green", 20.01, false},
},
Labels: map[string]int{
"engieer": 10,
"web/html": 15,
"k8s-app": 20,
},
Employees: map[empName]job{
"jason": "manager",
"dan": "clerk",
},
}
storeTests := []jsonpathTest{
{"plain", "hello jsonpath", nil, "hello jsonpath", false},
{"recursive", "{..}", []int{1, 2, 3}, "[1 2 3]", false},
{"filter", "{[?(@<5)]}", []int{2, 6, 3, 7}, "2 3", false},
{"quote", `{"{"}`, nil, "{", false},
{"union", "{[1,3,4]}", []int{0, 1, 2, 3, 4}, "1 3 4", false},
{"array", "{[0:2]}", []string{"Monday", "Tudesday"}, "Monday Tudesday", false},
{"variable", "hello {.Name}", storeData, "hello jsonpath", false},
{"dict/", "{$.Labels.web/html}", storeData, "15", false},
{"dict/", "{$.Employees.jason}", storeData, "manager", false},
{"dict/", "{$.Employees.dan}", storeData, "clerk", false},
{"dict-", "{.Labels.k8s-app}", storeData, "20", false},
{"nest", "{.Bicycle[*].Color}", storeData, "red green", false},
{"allarray", "{.Book[*].Author}", storeData, "Nigel Rees Evelyn Waugh Herman Melville", false},
{"allfileds", "{.Bicycle.*}", storeData, "{red 19.95 true} {green 20.01 false}", false},
{"recurfileds", "{..Price}", storeData, "8.95 12.99 8.99 19.95 20.01", false},
{"lastarray", "{.Book[-1:]}", storeData,
"{Category: fiction, Author: Herman Melville, Title: Moby Dick, Price: 8.99}", false},
{"recurarray", "{..Book[2]}", storeData,
"{Category: fiction, Author: Herman Melville, Title: Moby Dick, Price: 8.99}", false},
{"bool", "{.Bicycle[?(@.IsNew==true)]}", storeData, "{red 19.95 true}", false},
}
testJSONPath(storeTests, false, t)
missingKeyTests := []jsonpathTest{
{"nonexistent field", "{.hello}", storeData, "", false},
}
testJSONPath(missingKeyTests, true, t)
failStoreTests := []jsonpathTest{
{"invalid identifier", "{hello}", storeData, "unrecognized identifier hello", false},
{"nonexistent field", "{.hello}", storeData, "hello is not found", false},
{"invalid array", "{.Labels[0]}", storeData, "map[string]int is not array or slice", false},
{"invalid filter operator", "{.Book[?(@.Price<>10)]}", storeData, "unrecognized filter operator <>", false},
{"redundant end", "{range .Labels.*}{@}{end}{end}", storeData, "not in range, nothing to end", false},
}
testFailJSONPath(failStoreTests, t)
}
func TestJSONInput(t *testing.T) {
var pointsJSON = []byte(`[
{"id": "i1", "x":4, "y":-5},
{"id": "i2", "x":-2, "y":-5, "z":1},
{"id": "i3", "x": 8, "y": 3 },
{"id": "i4", "x": -6, "y": -1 },
{"id": "i5", "x": 0, "y": 2, "z": 1 },
{"id": "i6", "x": 1, "y": 4 }
]`)
var pointsData interface{}
err := json.Unmarshal(pointsJSON, &pointsData)
if err != nil {
t.Error(err)
}
pointsTests := []jsonpathTest{
{"exists filter", "{[?(@.z)].id}", pointsData, "i2 i5", false},
{"bracket key", "{[0]['id']}", pointsData, "i1", false},
}
testJSONPath(pointsTests, false, t)
}
// TestKubernetes tests some use cases from kubernetes
func TestKubernetes(t *testing.T) {
var input = []byte(`{
"kind": "List",
"items":[
{
"kind":"None",
"metadata":{
"name":"127.0.0.1",
"labels":{
"kubernetes.io/hostname":"127.0.0.1"
}
},
"status":{
"capacity":{"cpu":"4"},
"ready": true,
"addresses":[{"type": "LegacyHostIP", "address":"127.0.0.1"}]
}
},
{
"kind":"None",
"metadata":{
"name":"127.0.0.2",
"labels":{
"kubernetes.io/hostname":"127.0.0.2"
}
},
"status":{
"capacity":{"cpu":"8"},
"ready": false,
"addresses":[
{"type": "LegacyHostIP", "address":"127.0.0.2"},
{"type": "another", "address":"127.0.0.3"}
]
}
}
],
"users":[
{
"name": "myself",
"user": {}
},
{
"name": "e2e",
"user": {"username": "admin", "password": "secret"}
}
]
}`)
var nodesData interface{}
err := json.Unmarshal(input, &nodesData)
if err != nil {
t.Error(err)
}
nodesTests := []jsonpathTest{
{"range item", `{range .items[*]}{.metadata.name}, {end}{.kind}`, nodesData, "127.0.0.1, 127.0.0.2, List", false},
{"range item with quote", `{range .items[*]}{.metadata.name}{"\t"}{end}`, nodesData, "127.0.0.1\t127.0.0.2\t", false},
{"range addresss", `{.items[*].status.addresses[*].address}`, nodesData,
"127.0.0.1 127.0.0.2 127.0.0.3", false},
{"double range", `{range .items[*]}{range .status.addresses[*]}{.address}, {end}{end}`, nodesData,
"127.0.0.1, 127.0.0.2, 127.0.0.3, ", false},
{"item name", `{.items[*].metadata.name}`, nodesData, "127.0.0.1 127.0.0.2", false},
{"union nodes capacity", `{.items[*]['metadata.name', 'status.capacity']}`, nodesData,
"127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]", false},
{"range nodes capacity", `{range .items[*]}[{.metadata.name}, {.status.capacity}] {end}`, nodesData,
"[127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] ", false},
{"user password", `{.users[?(@.name=="e2e")].user.password}`, &nodesData, "secret", false},
{"hostname", `{.items[0].metadata.labels.kubernetes\.io/hostname}`, &nodesData, "127.0.0.1", false},
{"hostname filter", `{.items[?(@.metadata.labels.kubernetes\.io/hostname=="127.0.0.1")].kind}`, &nodesData, "None", false},
{"bool item", `{.items[?(@..ready==true)].metadata.name}`, &nodesData, "127.0.0.1", false},
}
testJSONPath(nodesTests, false, t)
randomPrintOrderTests := []jsonpathTest{
{"recursive name", "{..name}", nodesData, `127.0.0.1 127.0.0.2 myself e2e`, false},
}
testJSONPathSortOutput(randomPrintOrderTests, t)
}
func TestFilterPartialMatchesSometimesMissingAnnotations(t *testing.T) {
// for https://issues.k8s.io/45546
var input = []byte(`{
"kind": "List",
"items": [
{
"kind": "Pod",
"metadata": {
"name": "pod1",
"annotations": {
"color": "blue"
}
}
},
{
"kind": "Pod",
"metadata": {
"name": "pod2"
}
},
{
"kind": "Pod",
"metadata": {
"name": "pod3",
"annotations": {
"color": "green"
}
}
},
{
"kind": "Pod",
"metadata": {
"name": "pod4",
"annotations": {
"color": "blue"
}
}
}
]
}`)
var data interface{}
err := json.Unmarshal(input, &data)
if err != nil {
t.Fatal(err)
}
testJSONPath(
[]jsonpathTest{
{
"filter, should only match a subset, some items don't have annotations, tolerate missing items",
`{.items[?(@.metadata.annotations.color=="blue")].metadata.name}`,
data,
"pod1 pod4",
false, // expect no error
},
},
true, // allow missing keys
t,
)
testJSONPath(
[]jsonpathTest{
{
"filter, should only match a subset, some items don't have annotations, error on missing items",
`{.items[?(@.metadata.annotations.color=="blue")].metadata.name}`,
data,
"",
true, // expect an error
},
},
false, // don't allow missing keys
t,
)
}

View file

@ -1,152 +0,0 @@
/*
Copyright 2015 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 jsonpath
import (
"testing"
)
type parserTest struct {
name string
text string
nodes []Node
shouldError bool
}
var parserTests = []parserTest{
{"plain", `hello jsonpath`, []Node{newText("hello jsonpath")}, false},
{"variable", `hello {.jsonpath}`,
[]Node{newText("hello "), newList(), newField("jsonpath")}, false},
{"arrayfiled", `hello {['jsonpath']}`,
[]Node{newText("hello "), newList(), newField("jsonpath")}, false},
{"quote", `{"{"}`, []Node{newList(), newText("{")}, false},
{"array", `{[1:3]}`, []Node{newList(),
newArray([3]ParamsEntry{{1, true}, {3, true}, {0, false}})}, false},
{"allarray", `{.book[*].author}`,
[]Node{newList(), newField("book"),
newArray([3]ParamsEntry{{0, false}, {0, false}, {0, false}}), newField("author")}, false},
{"wildcard", `{.bicycle.*}`,
[]Node{newList(), newField("bicycle"), newWildcard()}, false},
{"filter", `{[?(@.price<3)]}`,
[]Node{newList(), newFilter(newList(), newList(), "<"),
newList(), newField("price"), newList(), newInt(3)}, false},
{"recursive", `{..}`, []Node{newList(), newRecursive()}, false},
{"recurField", `{..price}`,
[]Node{newList(), newRecursive(), newField("price")}, false},
{"arraydict", `{['book.price']}`, []Node{newList(),
newField("book"), newField("price"),
}, false},
{"union", `{['bicycle.price', 3, 'book.price']}`, []Node{newList(), newUnion([]*ListNode{}),
newList(), newField("bicycle"), newField("price"),
newList(), newArray([3]ParamsEntry{{3, true}, {4, true}, {0, false}}),
newList(), newField("book"), newField("price"),
}, false},
{"range", `{range .items}{.name},{end}`, []Node{
newList(), newIdentifier("range"), newField("items"),
newList(), newField("name"), newText(","),
newList(), newIdentifier("end"),
}, false},
{"malformat input", `{\\\}`, []Node{}, true},
{"paired parentheses in quotes", `{[?(@.status.nodeInfo.osImage == "()")]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("()")}, false},
{"paired parentheses in double quotes and with double quotes escape", `{[?(@.status.nodeInfo.osImage == "(\"\")")]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("(\"\")")}, false},
{"unregular parentheses in double quotes", `{[?(@.test == "())(")]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("test"), newList(), newText("())(")}, false},
{"plain text in single quotes", `{[?(@.status.nodeInfo.osImage == 'Linux')]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("Linux")}, false},
{"test filter suffix", `{[?(@.status.nodeInfo.osImage == "{[()]}")]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("{[()]}")}, false},
{"double inside single", `{[?(@.status.nodeInfo.osImage == "''")]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("''")}, false},
{"single inside double", `{[?(@.status.nodeInfo.osImage == '""')]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("\"\"")}, false},
{"single containing escaped single", `{[?(@.status.nodeInfo.osImage == '\\\'')]}`,
[]Node{newList(), newFilter(newList(), newList(), "=="), newList(), newField("status"), newField("nodeInfo"), newField("osImage"), newList(), newText("\\'")}, false},
}
func collectNode(nodes []Node, cur Node) []Node {
nodes = append(nodes, cur)
switch cur.Type() {
case NodeList:
for _, node := range cur.(*ListNode).Nodes {
nodes = collectNode(nodes, node)
}
case NodeFilter:
nodes = collectNode(nodes, cur.(*FilterNode).Left)
nodes = collectNode(nodes, cur.(*FilterNode).Right)
case NodeUnion:
for _, node := range cur.(*UnionNode).Nodes {
nodes = collectNode(nodes, node)
}
}
return nodes
}
func TestParser(t *testing.T) {
for _, test := range parserTests {
parser, err := Parse(test.name, test.text)
if test.shouldError {
if err == nil {
t.Errorf("unexpected non-error when parsing %s", test.name)
}
continue
}
if err != nil {
t.Errorf("parse %s error %v", test.name, err)
}
result := collectNode([]Node{}, parser.Root)[1:]
if len(result) != len(test.nodes) {
t.Errorf("in %s, expect to get %d nodes, got %d nodes", test.name, len(test.nodes), len(result))
t.Error(result)
}
for i, expect := range test.nodes {
if result[i].String() != expect.String() {
t.Errorf("in %s, %dth node, expect %v, got %v", test.name, i, expect, result[i])
}
}
}
}
type failParserTest struct {
name string
text string
err string
}
func TestFailParser(t *testing.T) {
failParserTests := []failParserTest{
{"unclosed action", "{.hello", "unclosed action"},
{"unrecognized character", "{*}", "unrecognized character in action: U+002A '*'"},
{"invalid number", "{+12.3.0}", "cannot parse number +12.3.0"},
{"unterminated array", "{[1}", "unterminated array"},
{"invalid index", "{[::-1]}", "invalid array index ::-1"},
{"unterminated filter", "{[?(.price]}", "unterminated filter"},
}
for _, test := range failParserTests {
_, err := Parse(test.name, test.text)
var out string
if err == nil {
out = "nil"
} else {
out = err.Error()
}
if out != test.err {
t.Errorf("in %s, expect to get error %v, got %v", test.name, test.err, out)
}
}
}