// Copyright 2019 The Kubernetes Authors. // SPDX-License-Identifier: Apache-2.0 package kioutil_test import ( "bytes" "math/rand" "strings" "testing" "time" "github.com/stretchr/testify/assert" "sigs.k8s.io/kustomize/kyaml/kio" "sigs.k8s.io/kustomize/kyaml/kio/kioutil" "sigs.k8s.io/kustomize/kyaml/yaml" ) func TestSortNodes_moreThan10(t *testing.T) { input := ` a: b --- c: d --- e: f --- g: h --- i: j --- k: l --- m: n --- o: p --- q: r --- s: t --- u: v --- w: x --- y: z ` actual := &bytes.Buffer{} rw := kio.ByteReadWriter{Reader: bytes.NewBufferString(input), Writer: actual} nodes, err := rw.Read() if !assert.NoError(t, err) { t.Fail() } // randomize the list rand.Seed(time.Now().UnixNano()) rand.Shuffle(len(nodes), func(i, j int) { nodes[i], nodes[j] = nodes[j], nodes[i] }) // sort them back into their original order if !assert.NoError(t, kioutil.SortNodes(nodes)) { t.Fail() } // check the sorted values expected := strings.Split(input, "---") for i := range nodes { a := strings.TrimSpace(nodes[i].MustString()) b := strings.TrimSpace(expected[i]) if !assert.Contains(t, a, b) { t.Fail() } } if !assert.NoError(t, rw.Write(nodes)) { t.Fail() } assert.Equal(t, strings.TrimSpace(input), strings.TrimSpace(actual.String())) } func TestDefaultPathAnnotation(t *testing.T) { var tests = []struct { dir string input string // input expected string // expected result name string }{ { `foo`, `apiVersion: v1 kind: Bar metadata: name: a namespace: b `, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'foo/b/bar_a.yaml' `, `with namespace`}, { `foo`, `apiVersion: v1 kind: Bar metadata: name: a `, `apiVersion: v1 kind: Bar metadata: name: a annotations: config.kubernetes.io/path: 'foo/bar_a.yaml' `, `without namespace`}, { ``, `apiVersion: v1 kind: Bar metadata: name: a namespace: b `, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'b/bar_a.yaml' `, `without dir`}, { ``, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'a/b.yaml' `, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'a/b.yaml' `, `skip`}, } for _, s := range tests { n := yaml.MustParse(s.input) err := kioutil.DefaultPathAnnotation(s.dir, []*yaml.RNode{n}) if !assert.NoError(t, err, s.name) { t.FailNow() } if !assert.Equal(t, s.expected, n.MustString(), s.name) { t.FailNow() } } } func TestDefaultPathAndIndexAnnotation(t *testing.T) { var tests = []struct { dir string input string // input expected string // expected result name string }{ { `foo`, `apiVersion: v1 kind: Bar metadata: name: a namespace: b `, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'foo/b/bar_a.yaml' config.kubernetes.io/index: '0' `, `with namespace`}, { `foo`, `apiVersion: v1 kind: Bar metadata: name: a `, `apiVersion: v1 kind: Bar metadata: name: a annotations: config.kubernetes.io/path: 'foo/bar_a.yaml' config.kubernetes.io/index: '0' `, `without namespace`}, { ``, `apiVersion: v1 kind: Bar metadata: name: a namespace: b `, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'b/bar_a.yaml' config.kubernetes.io/index: '0' `, `without dir`}, { ``, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'a/b.yaml' config.kubernetes.io/index: '5' `, `apiVersion: v1 kind: Bar metadata: name: a namespace: b annotations: config.kubernetes.io/path: 'a/b.yaml' config.kubernetes.io/index: '5' `, `skip`}, } for _, s := range tests { out := &bytes.Buffer{} r := kio.ByteReadWriter{ Reader: bytes.NewBufferString(s.input), Writer: out, KeepReaderAnnotations: true, OmitReaderAnnotations: true, } n, err := r.Read() if !assert.NoError(t, err, s.name) { t.FailNow() } if !assert.NoError(t, kioutil.DefaultPathAndIndexAnnotation(s.dir, n), s.name) { t.FailNow() } if !assert.NoError(t, r.Write(n), s.name) { t.FailNow() } if !assert.Equal(t, s.expected, out.String(), s.name) { t.FailNow() } } } func TestCreatePathAnnotationValue(t *testing.T) { var tests = []struct { dir string meta yaml.ResourceMeta // input expected string // expected result name string }{ { `dir`, yaml.ResourceMeta{ TypeMeta: yaml.TypeMeta{ APIVersion: "apps/v1", Kind: "foo", }, ObjectMeta: yaml.ObjectMeta{ NameMeta: yaml.NameMeta{ Name: "bar", Namespace: "baz", }, }, }, `dir/baz/foo_bar.yaml`, `with namespace`, }, { ``, yaml.ResourceMeta{ TypeMeta: yaml.TypeMeta{ APIVersion: "apps/v1", Kind: "foo", }, ObjectMeta: yaml.ObjectMeta{ NameMeta: yaml.NameMeta{ Name: "bar", Namespace: "baz", }, }, }, `baz/foo_bar.yaml`, `without dir`, }, { `dir`, yaml.ResourceMeta{ TypeMeta: yaml.TypeMeta{ APIVersion: "apps/v1", Kind: "foo", }, ObjectMeta: yaml.ObjectMeta{ NameMeta: yaml.NameMeta{Name: "bar"}, }, }, `dir/foo_bar.yaml`, `without namespace`, }, { ``, yaml.ResourceMeta{ TypeMeta: yaml.TypeMeta{ APIVersion: "apps/v1", Kind: "foo", }, ObjectMeta: yaml.ObjectMeta{ NameMeta: yaml.NameMeta{Name: "bar"}, }, }, `foo_bar.yaml`, `without namespace or dir`, }, { ``, yaml.ResourceMeta{ TypeMeta: yaml.TypeMeta{ APIVersion: "apps/v1", Kind: "foo", }, ObjectMeta: yaml.ObjectMeta{}, }, `foo_.yaml`, `without namespace, dir or name`, }, { ``, yaml.ResourceMeta{ TypeMeta: yaml.TypeMeta{ APIVersion: "apps/v1", }, ObjectMeta: yaml.ObjectMeta{}, }, `_.yaml`, `without any`, }, } for _, s := range tests { p := kioutil.CreatePathAnnotationValue(s.dir, s.meta) if !assert.Equal(t, s.expected, p, s.name) { t.FailNow() } } }