...

Source file src/sigs.k8s.io/kustomize/kyaml/yaml/compatibility_test.go

Documentation: sigs.k8s.io/kustomize/kyaml/yaml

     1  // Copyright 2019 The Kubernetes Authors.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package yaml_test
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"sigs.k8s.io/kustomize/kyaml/openapi"
    11  	"sigs.k8s.io/kustomize/kyaml/yaml"
    12  )
    13  
    14  func TestIsYaml1_1NonString(t *testing.T) {
    15  	type testCase struct {
    16  		val      string
    17  		expected bool
    18  	}
    19  
    20  	testCases := []testCase{
    21  		{val: "hello world", expected: false},
    22  		{val: "2.0", expected: true},
    23  		{val: "2", expected: true},
    24  		{val: "true", expected: true},
    25  		{val: "1.0\nhello", expected: false}, // multiline strings should always be false
    26  		{val: "", expected: false},           // empty string should be considered a string
    27  	}
    28  
    29  	for k := range valueToTagMap {
    30  		testCases = append(testCases, testCase{val: k, expected: true})
    31  	}
    32  
    33  	for _, test := range testCases {
    34  		assert.Equal(t, test.expected,
    35  			yaml.IsYaml1_1NonString(&yaml.Node{Kind: yaml.ScalarNode, Value: test.val}), test.val)
    36  	}
    37  }
    38  
    39  func TestFormatNonStringStyle(t *testing.T) {
    40  	n := yaml.MustParse(`apiVersion: apps/v1
    41  kind: Deployment
    42  spec:
    43    template:
    44      spec:
    45        containers:
    46        - name: foo
    47          args:
    48          - bar
    49          - on
    50          image: nginx:1.7.9
    51          ports:
    52          - name: http
    53            containerPort: "80"
    54  `)
    55  	s := openapi.SchemaForResourceType(
    56  		yaml.TypeMeta{APIVersion: "apps/v1", Kind: "Deployment"})
    57  
    58  	args, err := n.Pipe(yaml.Lookup(
    59  		"spec", "template", "spec", "containers", "[name=foo]", "args"))
    60  	if !assert.NoError(t, err) {
    61  		t.FailNow()
    62  	}
    63  	if !assert.NotNil(t, args) {
    64  		t.FailNow()
    65  	}
    66  	on := args.YNode().Content[1]
    67  	onS := s.Lookup(
    68  		"spec", "template", "spec", "containers", openapi.Elements, "args", openapi.Elements)
    69  	yaml.FormatNonStringStyle(on, *onS.Schema)
    70  
    71  	containerPort, err := n.Pipe(yaml.Lookup(
    72  		"spec", "template", "spec", "containers", "[name=foo]", "ports",
    73  		"[name=http]", "containerPort"))
    74  	if !assert.NoError(t, err) {
    75  		t.FailNow()
    76  	}
    77  	if !assert.NotNil(t, containerPort) {
    78  		t.FailNow()
    79  	}
    80  	cpS := s.Lookup("spec", "template", "spec", "containers", openapi.Elements,
    81  		"ports", openapi.Elements, "containerPort")
    82  	if !assert.NotNil(t, cpS) {
    83  		t.FailNow()
    84  	}
    85  	yaml.FormatNonStringStyle(containerPort.YNode(), *cpS.Schema)
    86  
    87  	actual := n.MustString()
    88  	expected := `apiVersion: apps/v1
    89  kind: Deployment
    90  spec:
    91    template:
    92      spec:
    93        containers:
    94        - name: foo
    95          args:
    96          - bar
    97          - "on"
    98          image: nginx:1.7.9
    99          ports:
   100          - name: http
   101            containerPort: 80
   102  `
   103  	assert.Equal(t, expected, actual)
   104  }
   105  
   106  // valueToTagMap is a map of values interpreted as non-strings in yaml 1.1 when left
   107  // unquoted.
   108  // To keep compatibility with the yaml parser used by Kubernetes (yaml 1.1) make sure the values
   109  // which are treated as non-string values are kept as non-string values.
   110  // https://github.com/go-yaml/yaml/blob/v2/resolve.go
   111  var valueToTagMap = func() map[string]string {
   112  	val := map[string]string{}
   113  
   114  	// https://yaml.org/type/null.html
   115  	values := []string{"~", "null", "Null", "NULL"}
   116  	for i := range values {
   117  		val[values[i]] = yaml.NodeTagNull
   118  	}
   119  
   120  	// https://yaml.org/type/bool.html
   121  	values = []string{
   122  		"y", "Y", "yes", "Yes", "YES", "true", "True", "TRUE", "on", "On", "ON", "n", "N", "no",
   123  		"No", "NO", "false", "False", "FALSE", "off", "Off", "OFF"}
   124  	for i := range values {
   125  		val[values[i]] = yaml.NodeTagBool
   126  	}
   127  
   128  	// https://yaml.org/type/float.html
   129  	values = []string{
   130  		".nan", ".NaN", ".NAN", ".inf", ".Inf", ".INF",
   131  		"+.inf", "+.Inf", "+.INF", "-.inf", "-.Inf", "-.INF"}
   132  	for i := range values {
   133  		val[values[i]] = yaml.NodeTagFloat
   134  	}
   135  
   136  	return val
   137  }()
   138  

View as plain text