} nodesTests := []jsonpathTest{ <del> {"range item", `{range .items[*]}{.metadata.name}, {end}{.kind}`, nodesData, "127.0.0.1, 127.0.0.2, List"}, {"range item with quote", `{range .items[*]}{.metadata.name}{"t"}{end}`, nodesData, "127.0.0.1t127.0.0.2t"}, </del> <ins> {"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.1t127.0.0.2t", false}, </ins> {"range addresss", `{.items[*].status.addresses[*].address}`, nodesData, <del> "127.0.0.1 127.0.0.2 127.0.0.3"}, </del> <ins> "127.0.0.1 127.0.0.2 127.0.0.3", false}, </ins> {"double range", `{range .items[*]}{range .status.addresses[*]}{.address}, {end}{end}`, nodesData, <del> "127.0.0.1, 127.0.0.2, 127.0.0.3, "}, {"item name", `{.items[*].metadata.name}`, nodesData, "127.0.0.1 127.0.0.2"}, </del> <ins> "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}, </ins> {"union nodes capacity", `{.items[*]['metadata.name', 'status.capacity']}`, nodesData, <del> "127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]"}, </del> <ins> "127.0.0.1 127.0.0.2 map[cpu:4] map[cpu:8]", false}, </ins> {"range nodes capacity", `{range .items[*]}[{.metadata.name}, {.status.capacity}] {end}`, nodesData, <del> "[127.0.0.1, map[cpu:4]] [127.0.0.2, map[cpu:8]] "}, {"user password", `{.users[?(@.name=="e2e")].user.password}`, &nodesData, "secret"}, {"hostname", `{.items[0].metadata.labels.kubernetes.io/hostname}`, &nodesData, "127.0.0.1"}, {"hostname filter", `{.items[?(@.metadata.labels.kubernetes.io/hostname=="127.0.0.1")].kind}`, &nodesData, "None"}, {"bool item", `{.items[?(@..ready==true)].metadata.name}`, &nodesData, "127.0.0.1"}, </del> <ins> "[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}, </ins> } testJSONPath(nodesTests, false, t) randomPrintOrderTests := []jsonpathTest{ <del> {"recursive name", "{..name}", nodesData, `127.0.0.1 127.0.0.2 myself e2e`}, </del> <ins> {"recursive name", "{..name}", nodesData, `127.0.0.1 127.0.0.2 myself e2e`, false}, </ins> } testJSONPathSortOutput(randomPrintOrderTests, t) } <ins> 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, ) } </ins>