1
0
mirror of https://github.com/ko-build/ko.git synced 2025-03-17 20:47:51 +02:00
ko-build/pkg/resolve/selector_test.go

246 lines
4.8 KiB
Go

// Copyright 2018 Google LLC All Rights Reserved.
//
// 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 resolve
import (
"testing"
"github.com/google/go-cmp/cmp"
"gopkg.in/yaml.v3"
"k8s.io/apimachinery/pkg/labels"
)
var (
webSelector = selector(`app=web`)
notWebSelector = selector(`app!=web`)
nopSelector = selector(`foo!=bark`)
)
const (
webPod = `apiVersion: v1
kind: Pod
metadata:
labels:
# comments should be preserved
app: web
name: rss-site
`
dbPod = `apiVersion: v1
kind: Pod
metadata:
labels:
# comments should be preserved
app: db
name: rss-db
`
podList = `apiVersion: v1
kind: List
metadata:
resourceVersion: ""
selfLink: ""
items:
- apiVersion: v1
kind: Pod
metadata:
labels:
app: web
name: rss-site
- apiVersion: v1
kind: Pod
metadata:
labels:
app: db
name: rss-db
`
webPodList = `apiVersion: v1
kind: List
metadata:
resourceVersion: ""
selfLink: ""
items:
- apiVersion: v1
kind: Pod
metadata:
labels:
app: web
name: rss-site
`
dbPodList = `apiVersion: v1
kind: List
metadata:
resourceVersion: ""
selfLink: ""
items:
- apiVersion: v1
kind: Pod
metadata:
labels:
app: db
name: rss-db
`
)
func TestMatchesSelector(t *testing.T) {
tests := []struct {
desc string
input string
selector labels.Selector
output string
matches bool
}{{
desc: "single object with matching selector",
input: webPod,
selector: webSelector,
output: webPod,
matches: true,
}, {
desc: "single object with non-matching selector",
input: webPod,
selector: notWebSelector,
matches: false,
}, {
desc: "single object with noop selector",
input: dbPod,
selector: nopSelector,
output: dbPod,
matches: true,
}, {
desc: "selector matching elements of list object",
input: podList,
selector: webSelector,
output: webPodList,
matches: true,
}, {
desc: "selector matching other elements of list object",
input: podList,
selector: notWebSelector,
output: dbPodList,
matches: true,
}, {
desc: "selector matching all elements of list object",
input: podList,
selector: labels.Everything(),
output: podList,
matches: true,
}, {
desc: "selector matching no elements of list object",
input: podList,
selector: labels.Nothing(),
matches: false,
}, {
desc: "null node",
input: "!!null",
selector: labels.Everything(),
matches: false,
}}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
doc := strToYAML(t, test.input)
matches, err := MatchesSelector(doc, test.selector)
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if matches != test.matches {
t.Errorf("unexpected result: got %v - want %v", matches, test.matches)
}
// assert doc is mutated correctly
if test.output != "" {
// Normalize whitespace formatting
output := normalizeYAML(t, test.output)
if diff := cmp.Diff(output, yamlToStr(t, doc)); diff != "" {
t.Errorf("unexpected diff (-want, +got) %v", diff)
}
}
})
}
}
func TestSelectorFailure(t *testing.T) {
tests := []struct {
desc string
input string
}{
{
desc: "not an object",
input: "image: some.go/package",
},
{
desc: "not an object in a list",
input: `apiVersion: v1
kind: List
metadata:
resourceVersion: ""
selfLink: ""
items:
- blah: ha
`,
},
{
desc: "not a valid list",
input: `apiVersion: v1
kind: List
`,
},
}
for _, test := range tests {
t.Run(test.desc, func(t *testing.T) {
_, err := MatchesSelector(strToYAML(t, test.input), labels.Everything())
if err == nil {
t.Error("expected error")
}
})
}
}
func selector(s string) labels.Selector {
selector, err := labels.Parse(s)
if err != nil {
panic("unable to parse selector " + s)
}
return selector
}
func normalizeYAML(t *testing.T, yuml string) string {
t.Helper()
return yamlToStr(t, strToYAML(t, yuml))
}
func yamlToStr(t *testing.T, node *yaml.Node) string {
result, err := yaml.Marshal(node)
if err != nil {
t.Fatalf("error marshalling yaml: %v", err)
}
return string(result)
}
func strToYAML(t *testing.T, yuml string) *yaml.Node {
t.Helper()
var node yaml.Node
if err := yaml.Unmarshal([]byte(yuml), &node); err != nil {
t.Fatalf("error unmarshalling yaml: %v\n%v", err, yuml)
}
return &node
}