chart のテストは https://helm.sh/docs/topics/chart_tests/#helm にあるように、実際に helm install
する必要があります。
そうではなくて、単純に吐き出される manifests が期待したものかどうかをテストしたいというケースもあると思います(僕はあった)。
helm template --execute
(v3 だと --show-only
) を使って出力されたファイルを使ってテストをする方法もありますが、あまりスマートとは言えない感じがします。
そこで terratest を使ってテストを書く方法についてメモがてら残します。
とりあえず適当に chart を作ります。
❯ helm create sample-chart
Createing sample-chart
今回は次のような単純な Pod を例にします。
❯ tree
.
├── Chart.yaml
├── charts
├── templates
│ ├── _helpers.tpl
│ └── pod.yaml
└── values.yaml
❯ cat values.yaml
image:
repository: nginx
tag: latest
❯ cat templates/pod.yaml
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- image: {{ $.Values.image.repository }}:{{ $.Values.image.tag }}
name: nginx
ports:
- containerPort: 80
name: http
tests
ディレクトリを用意し、 go mod init <repository>
を実行します。
❯ mkdir tests
❯ cd tests
❯ go mod init github.com/mrtc0/sample-charts
そして次のようなテストを書きます。
package test
import (
"testing"
"github.com/gruntwork-io/terratest/modules/helm"
corev1 "k8s.io/api/core/v1"
)
func TestOssecConfig(t *testing.T) {
helmChartPath := "../"
options := &helm.Options{
SetFiles: map[string]string{"test": "../values.yaml"},
}
output := helm.RenderTemplate(
t, options, helmChartPath, "sample-chart",
[]string{"templates/pod.yaml"},
)
var pod corev1.Pod
helm.UnmarshalK8SYaml(t, output, &pod)
expectImage := "nginx"
actualImage := pod.Spec.Containers[0].Image
if actualImage == "nginx" {
t.Errorf("expected : %s, but got %s", expectImage, actualImage)
}
}
go test
すると内部で helm template --set-file test=../values.yaml --show-only templates/pod.yaml sample-chart ../
相当のコマンドが実行されます。
helm.UnmarshalK8SYaml()
で生成された manifests を対応したリソースの構造体に Unmarshal してあげることで、リソースのテストができます。
❯ go test
TestOssecConfig 2020-03-19T20:03:45+09:00 command.go:87: Running command helm with args [template --set-file test=/private/tmp/c/sample-chart/values.yaml --show-only templates/pod.yaml sample-chart ../]
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: ---
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: # Source: sample-chart/templates/pod.yaml
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: apiVersion: v1
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: kind: Pod
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: metadata:
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: name: nginx
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: spec:
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: containers:
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: - image: nginx:latest
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: name: nginx
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: ports:
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: - containerPort: 80
TestOssecConfig 2020-03-19T20:03:46+09:00 command.go:158: name: http
PASS
ok github.com/mrtc0/sample-chart 1.043s
注意点
- helm v3 以上しか対応していない
- https://github.com/gruntwork-io/terratest/pull/467
- v2 までは
--show-only
が-x
もしくは--execute
であるが、バージョンによって分岐をしていない - PR のコメントを見る感じ v2 の対応はしない雰囲気…
- なので、 helmenv などで対応