Files
kustomize/kyaml/yaml/compatibility_test.go
2020-07-22 09:23:47 -07:00

138 lines
3.5 KiB
Go

// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package yaml_test
import (
"testing"
"github.com/stretchr/testify/assert"
"sigs.k8s.io/kustomize/kyaml/openapi"
"sigs.k8s.io/kustomize/kyaml/yaml"
)
func TestIsYaml1_1NonString(t *testing.T) {
type testCase struct {
val string
expected bool
}
testCases := []testCase{
{val: "hello world", expected: false},
{val: "2.0", expected: true},
{val: "2", expected: true},
{val: "true", expected: true},
{val: "1.0\nhello", expected: false}, // multiline strings should always be false
{val: "", expected: false}, // empty string should be considered a string
}
for k := range valueToTagMap {
testCases = append(testCases, testCase{val: k, expected: true})
}
for _, test := range testCases {
assert.Equal(t, test.expected,
yaml.IsYaml1_1NonString(&yaml.Node{Kind: yaml.ScalarNode, Value: test.val}), test.val)
}
}
func TestFormatNonStringStyle(t *testing.T) {
n := yaml.MustParse(`apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo
args:
- bar
- on
image: nginx:1.7.9
ports:
- name: http
containerPort: "80"
`)
s := openapi.SchemaForResourceType(
yaml.TypeMeta{APIVersion: "apps/v1", Kind: "Deployment"})
args, err := n.Pipe(yaml.Lookup(
"spec", "template", "spec", "containers", "[name=foo]", "args"))
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.NotNil(t, args) {
t.FailNow()
}
on := args.YNode().Content[1]
onS := s.Lookup(
"spec", "template", "spec", "containers", openapi.Elements, "args", openapi.Elements)
yaml.FormatNonStringStyle(on, *onS.Schema)
containerPort, err := n.Pipe(yaml.Lookup(
"spec", "template", "spec", "containers", "[name=foo]", "ports",
"[name=http]", "containerPort"))
if !assert.NoError(t, err) {
t.FailNow()
}
if !assert.NotNil(t, containerPort) {
t.FailNow()
}
cpS := s.Lookup("spec", "template", "spec", "containers", openapi.Elements,
"ports", openapi.Elements, "containerPort")
if !assert.NotNil(t, cpS) {
t.FailNow()
}
yaml.FormatNonStringStyle(containerPort.YNode(), *cpS.Schema)
actual := n.MustString()
expected := `apiVersion: apps/v1
kind: Deployment
spec:
template:
spec:
containers:
- name: foo
args:
- bar
- "on"
image: nginx:1.7.9
ports:
- name: http
containerPort: 80
`
assert.Equal(t, expected, actual)
}
// valueToTagMap is a map of values interpreted as non-strings in yaml 1.1 when left
// unquoted.
// To keep compatibility with the yaml parser used by Kubernetes (yaml 1.1) make sure the values
// which are treated as non-string values are kept as non-string values.
// https://github.com/go-yaml/yaml/blob/v2/resolve.go
var valueToTagMap = func() map[string]string {
val := map[string]string{}
// https://yaml.org/type/null.html
values := []string{"~", "null", "Null", "NULL"}
for i := range values {
val[values[i]] = yaml.NodeTagNull
}
// https://yaml.org/type/bool.html
values = []string{
"y", "Y", "yes", "Yes", "YES", "true", "True", "TRUE", "on", "On", "ON", "n", "N", "no",
"No", "NO", "false", "False", "FALSE", "off", "Off", "OFF"}
for i := range values {
val[values[i]] = yaml.NodeTagBool
}
// https://yaml.org/type/float.html
values = []string{
".nan", ".NaN", ".NAN", ".inf", ".Inf", ".INF",
"+.inf", "+.Inf", "+.INF", "-.inf", "-.Inf", "-.INF"}
for i := range values {
val[values[i]] = yaml.NodeTagFloat
}
return val
}()