Merge pull request #1860 from monopole/improveExampleVisibility

Start making examples more visible.
This commit is contained in:
Jeff Regan
2019-11-28 08:17:07 -08:00
committed by GitHub
4 changed files with 202 additions and 48 deletions

View File

@@ -1,19 +1,18 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package target_test
package krusty_test
import (
"strings"
"testing"
"sigs.k8s.io/kustomize/api/konfig"
"sigs.k8s.io/kustomize/api/loader"
kusttest_test "sigs.k8s.io/kustomize/api/testutils/kusttest"
. "sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/types"
)
func TestOrderPreserved(t *testing.T) {
th := kusttest_test.NewKustTestHarness(t, "/app/prod")
th := makeTestHarness(t)
th.WriteK("/app/base", `
namePrefix: b-
resources:
@@ -65,11 +64,7 @@ kind: Namespace
metadata:
name: myNs2
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
m := th.Run("/app/prod", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Namespace
@@ -104,7 +99,7 @@ metadata:
}
func TestBaseInResourceList(t *testing.T) {
th := kusttest_test.NewKustTestHarness(t, "/app/prod")
th := makeTestHarness(t)
th.WriteK("/app/prod", `
namePrefix: b-
resources:
@@ -124,10 +119,7 @@ spec:
selector:
backend: bungie
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
m := th.Run("/app/prod", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: v1
kind: Service
@@ -139,7 +131,7 @@ spec:
`)
}
func writeSmallBase(th *kusttest_test.KustTestHarness) {
func writeSmallBase(th testingHarness) {
th.WriteK("/app/base", `
namePrefix: a-
commonLabels:
@@ -177,12 +169,9 @@ spec:
}
func TestSmallBase(t *testing.T) {
th := kusttest_test.NewKustTestHarness(t, "/app/base")
th := makeTestHarness(t)
writeSmallBase(th)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
m := th.Run("/app/base", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
@@ -220,7 +209,7 @@ spec:
}
func TestSmallOverlay(t *testing.T) {
th := kusttest_test.NewKustTestHarness(t, "/app/overlay")
th := makeTestHarness(t)
writeSmallBase(th)
th.WriteK("/app/overlay", `
namePrefix: b-
@@ -251,10 +240,7 @@ metadata:
spec:
replicas: 1000
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
m := th.Run("/app/overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
@@ -298,9 +284,7 @@ spec:
}
func TestSharedPatchDisAllowed(t *testing.T) {
th := kusttest_test.NewKustTestHarnessFull(
t, "/app/overlay",
loader.RestrictionRootOnly, konfig.DisabledPluginConfig())
th := makeTestHarness(t)
writeSmallBase(th)
th.WriteK("/app/overlay", `
commonLabels:
@@ -318,10 +302,11 @@ metadata:
spec:
replicas: 1000
`)
_, err := th.MakeKustTarget().MakeCustomizedResMap()
if err == nil {
t.Fatalf("expected error")
}
err := th.RunWithErr("/app/overlay", func() Options {
o := th.MakeDefaultOptions()
o.LoadRestrictions = types.LoadRestrictionsRootOnly
return o
}())
if !strings.Contains(
err.Error(),
"security; file '/app/shared/deployment-patch.yaml' is not in or below '/app/overlay'") {
@@ -330,9 +315,7 @@ spec:
}
func TestSharedPatchAllowed(t *testing.T) {
th := kusttest_test.NewKustTestHarnessFull(
t, "/app/overlay",
loader.RestrictionNone, konfig.DisabledPluginConfig())
th := makeTestHarness(t)
writeSmallBase(th)
th.WriteK("/app/overlay", `
commonLabels:
@@ -350,10 +333,11 @@ metadata:
spec:
replicas: 1000
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
m := th.Run("/app/overlay", func() Options {
o := th.MakeDefaultOptions()
o.LoadRestrictions = types.LoadRestrictionsNone
return o
}())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment
@@ -397,7 +381,7 @@ spec:
}
func TestSmallOverlayJSONPatch(t *testing.T) {
th := kusttest_test.NewKustTestHarness(t, "/app/overlay")
th := makeTestHarness(t)
writeSmallBase(th)
th.WriteK("/app/overlay", `
resources:
@@ -415,10 +399,7 @@ patchesJson6902:
path: /spec/selector/backend
value: beagle
`)
m, err := th.MakeKustTarget().MakeCustomizedResMap()
if err != nil {
t.Fatalf("Err: %v", err)
}
m := th.Run("/app/overlay", th.MakeDefaultOptions())
th.AssertActualEqualsExpected(m, `
apiVersion: apps/v1
kind: Deployment

View File

@@ -1,6 +1,11 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
// Package krusty holds a very high level API to kustomize.
// The functions here should be similar to the CLI api.
// Package krusty is intended as the entry point package
// for those seeking to add kustomize ability to other
// programs.
//
// To use, follow the example of the kustomize CLI's 'build'
// command. Also, see the high level tests in this package,
// which serve a dual purpose as examples.
package krusty

View File

@@ -22,7 +22,7 @@ import (
// performing an exec to a kustomize CLI subprocess.
// To use, load a filesystem with kustomization files (any
// number of overlays and bases), then make a Kustomizer
// injected with the given fileystem, then call Build.
// injected with the given fileystem, then call Run.
type Kustomizer struct {
fSys filesys.FileSystem
options *Options

View File

@@ -0,0 +1,168 @@
// Copyright 2019 The Kubernetes Authors.
// SPDX-License-Identifier: Apache-2.0
package krusty_test
import (
"fmt"
"path/filepath"
"strings"
"testing"
"sigs.k8s.io/kustomize/api/filesys"
"sigs.k8s.io/kustomize/api/konfig"
. "sigs.k8s.io/kustomize/api/krusty"
"sigs.k8s.io/kustomize/api/resmap"
"sigs.k8s.io/kustomize/api/types"
)
type testingHarness struct {
t *testing.T
fSys filesys.FileSystem
}
func makeTestHarness(t *testing.T) testingHarness {
return testingHarness{
t: t,
fSys: filesys.MakeFsInMemory(),
}
}
func (th testingHarness) WriteK(path string, content string) {
th.fSys.WriteFile(
filepath.Join(
path,
konfig.DefaultKustomizationFileName()), []byte(`
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
`+content))
}
func (th testingHarness) WriteF(path string, content string) {
th.fSys.WriteFile(path, []byte(content))
}
func (th testingHarness) MakeDefaultOptions() Options {
return Options{
LoadRestrictions: types.LoadRestrictionsRootOnly,
PluginConfig: konfig.DisabledPluginConfig(),
}
}
func (th testingHarness) MakeEnabledPluginConfig() *types.PluginConfig {
// TODO: this doesn't work yet - need to set an env var.
// TODO: steal from kusttest_test.NewPluginTestEnv
c, err := konfig.EnabledPluginConfig()
if err != nil {
th.t.Fatal(err)
}
return c
}
// Run, failing on error.
func (th testingHarness) Run(path string, o Options) resmap.ResMap {
m, err := MakeKustomizer(th.fSys, &o).Run(path)
if err != nil {
th.t.Fatal(err)
}
return m
}
// Run, failing if there is no error.
func (th testingHarness) RunWithErr(path string, o Options) error {
_, err := MakeKustomizer(th.fSys, &o).Run(path)
if err == nil {
th.t.Fatalf("expected error")
}
return err
}
func (th testingHarness) AssertActualEqualsExpected(
m resmap.ResMap, expected string) {
th.AssertActualEqualsExpectedWithTweak(m, nil, expected)
}
func (th testingHarness) AssertActualEqualsExpectedWithTweak(
m resmap.ResMap, tweaker func([]byte) []byte, expected string) {
if m == nil {
th.t.Fatalf("Map should not be nil.")
}
// Ignore leading linefeed in expected value
// to ease readability of tests.
if len(expected) > 0 && expected[0] == 10 {
expected = expected[1:]
}
actual, err := m.AsYaml()
if err != nil {
th.t.Fatalf("Unexpected err: %v", err)
}
if tweaker != nil {
actual = tweaker(actual)
}
if string(actual) != expected {
th.reportDiffAndFail(actual, expected)
}
}
// Pretty printing of file differences.
func (th testingHarness) reportDiffAndFail(actual []byte, expected string) {
sE, maxLen := convertToArray(expected)
sA, _ := convertToArray(string(actual))
fmt.Println("===== ACTUAL BEGIN ========================================")
fmt.Print(string(actual))
fmt.Println("===== ACTUAL END ==========================================")
format := fmt.Sprintf("%%s %%-%ds %%s\n", maxLen+4)
limit := 0
if len(sE) < len(sA) {
limit = len(sE)
} else {
limit = len(sA)
}
fmt.Printf(format, " ", "EXPECTED", "ACTUAL")
fmt.Printf(format, " ", "--------", "------")
for i := 0; i < limit; i++ {
fmt.Printf(format, hint(sE[i], sA[i]), sE[i], sA[i])
}
if len(sE) < len(sA) {
for i := len(sE); i < len(sA); i++ {
fmt.Printf(format, "X", "", sA[i])
}
} else {
for i := len(sA); i < len(sE); i++ {
fmt.Printf(format, "X", sE[i], "")
}
}
th.t.Fatalf("Expected not equal to actual")
}
func convertToArray(x string) ([]string, int) {
a := strings.Split(strings.TrimSuffix(x, "\n"), "\n")
maxLen := 0
for i, v := range a {
z := tabToSpace(v)
if len(z) > maxLen {
maxLen = len(z)
}
a[i] = z
}
return a, maxLen
}
func hint(a, b string) string {
if a == b {
return " "
}
return "X"
}
func tabToSpace(input string) string {
var result []string
for _, i := range input {
if i == 9 {
result = append(result, " ")
} else {
result = append(result, string(i))
}
}
return strings.Join(result, "")
}