mirror of
https://github.com/kubernetes-sigs/kustomize.git
synced 2026-05-17 18:25:26 +00:00
358 lines
7.9 KiB
Go
358 lines
7.9 KiB
Go
// Copyright 2019 The Kubernetes Authors.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
package hasher
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"sigs.k8s.io/kustomize/kyaml/yaml"
|
|
)
|
|
|
|
func TestSortArrayAndComputeHash(t *testing.T) {
|
|
array1 := []string{"a", "b", "c", "d"}
|
|
array2 := []string{"c", "b", "d", "a"}
|
|
h1, err := SortArrayAndComputeHash(array1)
|
|
if err != nil {
|
|
t.Errorf("unexpected error %v", err)
|
|
}
|
|
if h1 == "" {
|
|
t.Errorf("failed to hash %v", array1)
|
|
}
|
|
h2, err := SortArrayAndComputeHash(array2)
|
|
if err != nil {
|
|
t.Errorf("unexpected error %v", err)
|
|
}
|
|
if h2 == "" {
|
|
t.Errorf("failed to hash %v", array2)
|
|
}
|
|
if h1 != h2 {
|
|
t.Errorf("hash is not consistent with reordered list: %s %s", h1, h2)
|
|
}
|
|
}
|
|
|
|
func Test_hex256(t *testing.T) {
|
|
// hash the empty string to be sure that sha256 is being used
|
|
expect := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
|
|
sum := hex256("")
|
|
if expect != sum {
|
|
t.Errorf("expected hash %q but got %q", expect, sum)
|
|
}
|
|
}
|
|
|
|
func TestConfigMapHash(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
cmYaml string
|
|
hash string
|
|
err string
|
|
}{
|
|
// empty map
|
|
{"empty data", `
|
|
apiVersion: v1
|
|
kind: ConfigMap`, "6ct58987ht", ""},
|
|
// one key
|
|
{"one key", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
data:
|
|
one: ""`, "9g67k2htb6", ""},
|
|
// three keys (tests sorting order)
|
|
{"three keys", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
data:
|
|
two: 2
|
|
one: ""
|
|
three: 3`, "7757f9kkct", ""},
|
|
// empty binary data map
|
|
{"empty binary data", `
|
|
apiVersion: v1
|
|
kind: ConfigMap`, "6ct58987ht", ""},
|
|
// one key with binary data
|
|
{"one key with binary data", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
binaryData:
|
|
one: ""`, "6mtk2m274t", ""},
|
|
// three keys with binary data (tests sorting order)
|
|
{"three keys with binary data", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
binaryData:
|
|
two: 2
|
|
one: ""
|
|
three: 3`, "9th7kc28dg", ""},
|
|
// two keys, one with string and another with binary data
|
|
{"two keys with one each", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
data:
|
|
one: ""
|
|
binaryData:
|
|
two: ""`, "698h7c7t9m", ""},
|
|
}
|
|
h := &Hasher{}
|
|
for _, c := range cases {
|
|
node, err := yaml.Parse(c.cmYaml)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
hashed, err := h.Hash(node)
|
|
if SkipRest(t, c.desc, err, c.err) {
|
|
continue
|
|
}
|
|
if c.hash != hashed {
|
|
t.Errorf("case %q, expect hash %q but got %q", c.desc, c.hash, h)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSecretHash(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
secretYaml string
|
|
hash string
|
|
err string
|
|
}{
|
|
// empty map
|
|
{"empty data", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type`, "5gmgkf8578", ""},
|
|
// one key
|
|
{"one key", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
one: ""`, "74bd68bm66", ""},
|
|
// three keys (tests sorting order)
|
|
{"three keys", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
two: 2
|
|
one: ""
|
|
three: 3`, "4gf75c7476", ""},
|
|
// with stringdata
|
|
{"stringdata", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
one: ""
|
|
stringData:
|
|
two: 2`, "c4h4264gdb", ""},
|
|
// empty stringdata
|
|
{"empty stringdata", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
one: ""`, "74bd68bm66", ""},
|
|
}
|
|
h := &Hasher{}
|
|
for _, c := range cases {
|
|
node, err := yaml.Parse(c.secretYaml)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
hashed, err := h.Hash(node)
|
|
if SkipRest(t, c.desc, err, c.err) {
|
|
continue
|
|
}
|
|
if c.hash != hashed {
|
|
t.Errorf("case %q, expect hash %q but got %q", c.desc, c.hash, h)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestBasicHash(t *testing.T) {
|
|
cases := map[string]struct {
|
|
res string
|
|
hash string
|
|
err string
|
|
}{
|
|
"minimal": {`
|
|
apiVersion: test/v1
|
|
kind: TestResource
|
|
metadata:
|
|
name: my-resource`, "244782mkb7", ""},
|
|
"with spec": {`
|
|
apiVersion: test/v1
|
|
kind: TestResource
|
|
metadata:
|
|
name: my-resource
|
|
spec:
|
|
foo: 1
|
|
bar: abc`, "59m2mdccg4", ""},
|
|
}
|
|
h := &Hasher{}
|
|
for n := range cases {
|
|
c := cases[n]
|
|
t.Run(n, func(t *testing.T) {
|
|
node, err := yaml.Parse(c.res)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
hashed, err := h.Hash(node)
|
|
if SkipRest(t, n, err, c.err) {
|
|
return
|
|
}
|
|
if c.hash != hashed {
|
|
t.Errorf("case %q, expect hash %q but got %q", n, c.hash, h)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestEncodeConfigMap(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
cmYaml string
|
|
expect string
|
|
err string
|
|
}{
|
|
// empty map
|
|
{"empty data", `
|
|
apiVersion: v1
|
|
kind: ConfigMap`, `{"data":"","kind":"ConfigMap","name":""}`, ""},
|
|
// one key
|
|
{"one key", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
data:
|
|
one: ""`, `{"data":{"one":""},"kind":"ConfigMap","name":""}`, ""},
|
|
// three keys (tests sorting order)
|
|
{"three keys", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
data:
|
|
two: 2
|
|
one: ""
|
|
three: 3`, `{"data":{"one":"","three":3,"two":2},"kind":"ConfigMap","name":""}`, ""},
|
|
// empty binary map
|
|
{"empty data", `
|
|
apiVersion: v1
|
|
kind: ConfigMap`, `{"data":"","kind":"ConfigMap","name":""}`, ""},
|
|
// one key with binary data
|
|
{"one key", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
binaryData:
|
|
one: ""`, `{"binaryData":{"one":""},"data":"","kind":"ConfigMap","name":""}`, ""},
|
|
// three keys with binary data (tests sorting order)
|
|
{"three keys", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
binaryData:
|
|
two: 2
|
|
one: ""
|
|
three: 3`, `{"binaryData":{"one":"","three":3,"two":2},"data":"","kind":"ConfigMap","name":""}`, ""},
|
|
// two keys, one string and one binary values
|
|
{"two keys with one each", `
|
|
apiVersion: v1
|
|
kind: ConfigMap
|
|
data:
|
|
one: ""
|
|
binaryData:
|
|
two: ""`, `{"binaryData":{"two":""},"data":{"one":""},"kind":"ConfigMap","name":""}`, ""},
|
|
}
|
|
for _, c := range cases {
|
|
node, err := yaml.Parse(c.cmYaml)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s, err := encodeConfigMap(node)
|
|
if SkipRest(t, c.desc, err, c.err) {
|
|
continue
|
|
}
|
|
if s != c.expect {
|
|
t.Errorf("case %q, expect %q but got %q from encode %#v", c.desc, c.expect, s, c.cmYaml)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncodeSecret(t *testing.T) {
|
|
cases := []struct {
|
|
desc string
|
|
secretYaml string
|
|
expect string
|
|
err string
|
|
}{
|
|
// empty map
|
|
{"empty data", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type`, `{"data":"","kind":"Secret","name":"","type":"my-type"}`, ""},
|
|
// one key
|
|
{"one key", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
one: ""`, `{"data":{"one":""},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
|
// three keys (tests sorting order) - note json.Marshal base64 encodes the values because they come in as []byte
|
|
{"three keys", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
two: 2
|
|
one: ""
|
|
three: 3`, `{"data":{"one":"","three":3,"two":2},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
|
// with stringdata
|
|
{"stringdata", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
one: ""
|
|
stringData:
|
|
two: 2`, `{"data":{"one":""},"kind":"Secret","name":"","stringData":{"two":2},"type":"my-type"}`, ""},
|
|
// empty stringdata
|
|
{"empty stringdata", `
|
|
apiVersion: v1
|
|
kind: Secret
|
|
type: my-type
|
|
data:
|
|
one: ""`, `{"data":{"one":""},"kind":"Secret","name":"","type":"my-type"}`, ""},
|
|
}
|
|
for _, c := range cases {
|
|
node, err := yaml.Parse(c.secretYaml)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
s, err := encodeSecret(node)
|
|
if SkipRest(t, c.desc, err, c.err) {
|
|
continue
|
|
}
|
|
if s != c.expect {
|
|
t.Errorf("case %q, expect %q but got %q from encode %#v", c.desc, c.expect, s, c.secretYaml)
|
|
}
|
|
}
|
|
}
|
|
|
|
// SkipRest returns true if there was a non-nil error or if we expected an
|
|
// error that didn't happen, and logs the appropriate error on the test object.
|
|
// The return value indicates whether we should skip the rest of the test case
|
|
// due to the error result.
|
|
func SkipRest(t *testing.T, desc string, err error, contains string) bool {
|
|
t.Helper()
|
|
if err != nil {
|
|
if len(contains) == 0 {
|
|
t.Errorf("case %q, expect nil error but got %q", desc, err.Error())
|
|
} else if !strings.Contains(err.Error(), contains) {
|
|
t.Errorf("case %q, expect error to contain %q but got %q", desc, contains, err.Error())
|
|
}
|
|
return true
|
|
} else if len(contains) > 0 {
|
|
t.Errorf("case %q, expect error to contain %q but got nil error", desc, contains)
|
|
return true
|
|
}
|
|
return false
|
|
}
|