Skip to content

Commit

Permalink
chore: add tests for kustomize's sortOptions configuration
Browse files Browse the repository at this point in the history
The Kustomize rendering engine embedded in the operator, does not
enforce any aprticular order, but relies on the order of the manifests
provided, however, Kustomize has options to change the strategy used
to sort resources at the end of the Kustomize build see:

- https://kubectl.docs.kubernetes.io/references/kustomize/kustomization/sortoptions

This commit adds some test to ensure the sortOrder configuration is
honoured by the operator's own Kustomize engine.
  • Loading branch information
lburgazzoli committed Feb 5, 2025
1 parent 8504ce5 commit 994ee77
Show file tree
Hide file tree
Showing 3 changed files with 174 additions and 0 deletions.
136 changes: 136 additions & 0 deletions pkg/manifests/kustomize/kustomize_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,139 @@ func TestEngine(t *testing.T) {
)),
))
}

const testEngineKustomizationOrderLegacy = `
apiVersion: kustomize.config.k8s.io/v1beta1
sortOptions:
order: legacy
resources:
- test-engine-cm.yaml
- test-engine-deployment.yaml
- test-engine-secrets.yaml
`
const testEngineKustomizationOrderLegacyCustom = `
apiVersion: kustomize.config.k8s.io/v1beta1
sortOptions:
order: legacy
legacySortOptions:
orderFirst:
- Secret
- Deployment
orderLast:
- ConfigMap
resources:
- test-engine-cm.yaml
- test-engine-deployment.yaml
- test-engine-secrets.yaml
`

const testEngineKustomizationOrderFifo = `
apiVersion: kustomize.config.k8s.io/v1beta1
sortOptions:
order: fifo
resources:
- test-engine-cm.yaml
- test-engine-deployment.yaml
- test-engine-secrets.yaml
`

const testEngineOrderConfigMap = `
apiVersion: v1
kind: ConfigMap
metadata:
name: test-cm
data:
foo: bar
`

//nolint:gosec
const testEngineOrderSecret = `
apiVersion: v1
kind: Secret
metadata:
name: test-secrets
stringData:
bar: baz
`

const testEngineOrderDeployment = `
apiVersion: apps/v1
kind: Deployment
metadata:
name: test-deployment
spec:
replicas: 3
template:
spec:
containers:
- name: nginx
image: nginx:1.14.2
volumeMounts:
- name: config-volume
mountPath: /etc/config
- name: secrets-volume
mountPath: /etc/secrets
volumes:
- name: config-volume
configMap:
name: test-cm
- name: secrets-volume
secret:
name: test-secrets
`

func TestEngineOrder(t *testing.T) {
root := xid.New().String()

fs := filesys.MakeFsInMemory()

kustomizations := map[string]string{
"legacy": testEngineKustomizationOrderLegacy,
"ordered": testEngineKustomizationOrderLegacyCustom,
"fifo": testEngineKustomizationOrderFifo,
}

for k, v := range kustomizations {
t.Run(k, func(t *testing.T) {
g := NewWithT(t)

e := kustomize.NewEngine(
kustomize.WithEngineFS(fs),
)

_ = fs.MkdirAll(path.Join(root, kustomize.DefaultKustomizationFilePath))
_ = fs.WriteFile(path.Join(root, kustomize.DefaultKustomizationFileName), []byte(v))
_ = fs.WriteFile(path.Join(root, "test-engine-cm.yaml"), []byte(testEngineOrderConfigMap))
_ = fs.WriteFile(path.Join(root, "test-engine-secrets.yaml"), []byte(testEngineOrderSecret))
_ = fs.WriteFile(path.Join(root, "test-engine-deployment.yaml"), []byte(testEngineOrderDeployment))

r, err := e.Render(root)

g.Expect(err).NotTo(HaveOccurred())

switch k {
case "legacy":
g.Expect(r).Should(And(
HaveLen(3),
jq.Match(`.[0] | .kind == "ConfigMap"`),
jq.Match(`.[1] | .kind == "Secret"`),
jq.Match(`.[2] | .kind == "Deployment"`),
))
case "ordered":
g.Expect(r).Should(And(
HaveLen(3),
jq.Match(`.[0] | .kind == "Secret"`),
jq.Match(`.[1] | .kind == "Deployment"`),
jq.Match(`.[2] | .kind == "ConfigMap"`),
))
case "fifo":
g.Expect(r).Should(And(
HaveLen(3),
jq.Match(`.[0] | .kind == "ConfigMap"`),
jq.Match(`.[1] | .kind == "Deployment"`),
jq.Match(`.[2] | .kind == "Secret"`),
))
}
})
}
}
20 changes: 20 additions & 0 deletions pkg/utils/test/matchers/jq/jq_matcher_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import (
"encoding/json"
"testing"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"

"github.com/opendatahub-io/opendatahub-operator/v2/pkg/utils/test/matchers/jq"

. "github.com/onsi/gomega"
Expand Down Expand Up @@ -87,3 +89,21 @@ func TestMatcherWithType(t *testing.T) {
WithTransform(json.Marshal, jq.Match(`.a == 1`)),
)
}

func TestUnstructuredSliceMatcher(t *testing.T) {
t.Parallel()

g := NewWithT(t)

u := []unstructured.Unstructured{{
Object: map[string]interface{}{
"a": 1,
}},
}

g.Expect(u).Should(
jq.Match(`.[0] | .a == 1`))

g.Expect(unstructured.UnstructuredList{Items: u}).Should(
jq.Match(`.[0] | .a == 1`))
}
18 changes: 18 additions & 0 deletions pkg/utils/test/matchers/jq/jq_support.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,26 @@ func toType(in any) (any, error) {
}

return d, nil
case unstructured.UnstructuredList:
res := make([]any, 0, len(v.Items))
for i := range v.Items {
res = append(res, v.Items[i].Object)
}
return res, nil
case []unstructured.Unstructured:
res := make([]any, 0, len(v))
for i := range v {
res = append(res, v[i].Object)
}
return res, nil
case unstructured.Unstructured:
return v.Object, nil
case []*unstructured.Unstructured:
res := make([]any, 0, len(v))
for i := range v {
res = append(res, v[i].Object)
}
return res, nil
case *unstructured.Unstructured:
return v.Object, nil
}
Expand Down

0 comments on commit 994ee77

Please sign in to comment.