github.com/argoproj/argo-cd/v2@v2.10.9/util/helm/helm_test.go (about) 1 package helm 2 3 import ( 4 "path/filepath" 5 "testing" 6 7 "github.com/stretchr/testify/require" 8 9 "github.com/argoproj/argo-cd/v2/util/io/path" 10 11 "github.com/argoproj/gitops-engine/pkg/utils/kube" 12 "github.com/stretchr/testify/assert" 13 appsv1 "k8s.io/api/apps/v1" 14 apiv1 "k8s.io/api/core/v1" 15 "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" 16 "k8s.io/apimachinery/pkg/runtime" 17 ) 18 19 func template(h Helm, opts *TemplateOpts) ([]*unstructured.Unstructured, error) { 20 out, err := h.Template(opts) 21 if err != nil { 22 return nil, err 23 } 24 return kube.SplitYAML([]byte(out)) 25 } 26 27 func TestHelmTemplateParams(t *testing.T) { 28 h, err := NewHelmApp("./testdata/minio", []HelmRepository{}, false, "", "", false) 29 assert.NoError(t, err) 30 opts := TemplateOpts{ 31 Name: "test", 32 Set: map[string]string{ 33 "service.type": "LoadBalancer", 34 "service.port": "1234", 35 }, 36 SetString: map[string]string{ 37 "service.annotations.prometheus\\.io/scrape": "true", 38 }, 39 } 40 objs, err := template(h, &opts) 41 assert.Nil(t, err) 42 assert.Equal(t, 5, len(objs)) 43 44 for _, obj := range objs { 45 if obj.GetKind() == "Service" && obj.GetName() == "test-minio" { 46 var svc apiv1.Service 47 err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &svc) 48 assert.Nil(t, err) 49 assert.Equal(t, apiv1.ServiceTypeLoadBalancer, svc.Spec.Type) 50 assert.Equal(t, int32(1234), svc.Spec.Ports[0].TargetPort.IntVal) 51 assert.Equal(t, "true", svc.ObjectMeta.Annotations["prometheus.io/scrape"]) 52 } 53 } 54 } 55 56 func TestHelmTemplateValues(t *testing.T) { 57 repoRoot := "./testdata/redis" 58 repoRootAbs, err := filepath.Abs(repoRoot) 59 require.NoError(t, err) 60 h, err := NewHelmApp(repoRootAbs, []HelmRepository{}, false, "", "", false) 61 assert.NoError(t, err) 62 valuesPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-production.yaml", nil) 63 require.NoError(t, err) 64 opts := TemplateOpts{ 65 Name: "test", 66 Values: []path.ResolvedFilePath{valuesPath}, 67 } 68 objs, err := template(h, &opts) 69 assert.Nil(t, err) 70 assert.Equal(t, 8, len(objs)) 71 72 for _, obj := range objs { 73 if obj.GetKind() == "Deployment" && obj.GetName() == "test-redis-slave" { 74 var dep appsv1.Deployment 75 err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &dep) 76 assert.Nil(t, err) 77 assert.Equal(t, int32(3), *dep.Spec.Replicas) 78 } 79 } 80 } 81 82 func TestHelmGetParams(t *testing.T) { 83 repoRoot := "./testdata/redis" 84 repoRootAbs, err := filepath.Abs(repoRoot) 85 require.NoError(t, err) 86 h, err := NewHelmApp(repoRootAbs, nil, false, "", "", false) 87 assert.NoError(t, err) 88 params, err := h.GetParameters(nil, repoRootAbs, repoRootAbs) 89 assert.Nil(t, err) 90 91 slaveCountParam := params["cluster.slaveCount"] 92 assert.Equal(t, "1", slaveCountParam) 93 } 94 95 func TestHelmGetParamsValueFiles(t *testing.T) { 96 repoRoot := "./testdata/redis" 97 repoRootAbs, err := filepath.Abs(repoRoot) 98 require.NoError(t, err) 99 h, err := NewHelmApp(repoRootAbs, nil, false, "", "", false) 100 assert.NoError(t, err) 101 valuesPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-production.yaml", nil) 102 require.NoError(t, err) 103 params, err := h.GetParameters([]path.ResolvedFilePath{valuesPath}, repoRootAbs, repoRootAbs) 104 assert.Nil(t, err) 105 106 slaveCountParam := params["cluster.slaveCount"] 107 assert.Equal(t, "3", slaveCountParam) 108 } 109 110 func TestHelmGetParamsValueFilesThatExist(t *testing.T) { 111 repoRoot := "./testdata/redis" 112 repoRootAbs, err := filepath.Abs(repoRoot) 113 require.NoError(t, err) 114 h, err := NewHelmApp(repoRootAbs, nil, false, "", "", false) 115 assert.NoError(t, err) 116 valuesMissingPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-missing.yaml", nil) 117 require.NoError(t, err) 118 valuesProductionPath, _, err := path.ResolveValueFilePathOrUrl(repoRootAbs, repoRootAbs, "values-production.yaml", nil) 119 require.NoError(t, err) 120 params, err := h.GetParameters([]path.ResolvedFilePath{valuesMissingPath, valuesProductionPath}, repoRootAbs, repoRootAbs) 121 assert.Nil(t, err) 122 123 slaveCountParam := params["cluster.slaveCount"] 124 assert.Equal(t, "3", slaveCountParam) 125 } 126 127 func TestHelmTemplateReleaseNameOverwrite(t *testing.T) { 128 h, err := NewHelmApp("./testdata/redis", nil, false, "", "", false) 129 assert.NoError(t, err) 130 131 objs, err := template(h, &TemplateOpts{Name: "my-release"}) 132 assert.Nil(t, err) 133 assert.Equal(t, 5, len(objs)) 134 135 for _, obj := range objs { 136 if obj.GetKind() == "StatefulSet" { 137 var stateful appsv1.StatefulSet 138 err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &stateful) 139 assert.Nil(t, err) 140 assert.Equal(t, "my-release-redis-master", stateful.ObjectMeta.Name) 141 } 142 } 143 } 144 145 func TestHelmTemplateReleaseName(t *testing.T) { 146 h, err := NewHelmApp("./testdata/redis", nil, false, "", "", false) 147 assert.NoError(t, err) 148 objs, err := template(h, &TemplateOpts{Name: "test"}) 149 assert.Nil(t, err) 150 assert.Equal(t, 5, len(objs)) 151 152 for _, obj := range objs { 153 if obj.GetKind() == "StatefulSet" { 154 var stateful appsv1.StatefulSet 155 err := runtime.DefaultUnstructuredConverter.FromUnstructured(obj.Object, &stateful) 156 assert.Nil(t, err) 157 assert.Equal(t, "test-redis-master", stateful.ObjectMeta.Name) 158 } 159 } 160 } 161 162 func TestHelmArgCleaner(t *testing.T) { 163 for input, expected := range map[string]string{ 164 `val`: `val`, 165 `bar`: `bar`, 166 `not, clean`: `not\, clean`, 167 `a\,b,c`: `a\,b\,c`, 168 `{a,b,c}`: `{a,b,c}`, 169 } { 170 cleaned := cleanSetParameters(input) 171 assert.Equal(t, expected, cleaned) 172 } 173 } 174 175 func TestVersion(t *testing.T) { 176 ver, err := Version(false) 177 assert.NoError(t, err) 178 assert.NotEmpty(t, ver) 179 } 180 181 func Test_flatVals(t *testing.T) { 182 t.Run("Map", func(t *testing.T) { 183 output := map[string]string{} 184 185 flatVals(map[string]interface{}{"foo": map[string]interface{}{"bar": "baz"}}, output) 186 187 assert.Equal(t, map[string]string{"foo.bar": "baz"}, output) 188 }) 189 t.Run("Array", func(t *testing.T) { 190 output := map[string]string{} 191 192 flatVals(map[string]interface{}{"foo": []interface{}{"bar", "baz"}}, output) 193 194 assert.Equal(t, map[string]string{"foo[0]": "bar", "foo[1]": "baz"}, output) 195 }) 196 t.Run("Val", func(t *testing.T) { 197 output := map[string]string{} 198 199 flatVals(map[string]interface{}{"foo": 1}, output) 200 201 assert.Equal(t, map[string]string{"foo": "1"}, output) 202 }) 203 } 204 205 func TestAPIVersions(t *testing.T) { 206 h, err := NewHelmApp("./testdata/api-versions", nil, false, "", "", false) 207 if !assert.NoError(t, err) { 208 return 209 } 210 211 objs, err := template(h, &TemplateOpts{}) 212 if !assert.NoError(t, err) || !assert.Len(t, objs, 1) { 213 return 214 } 215 assert.Equal(t, objs[0].GetAPIVersion(), "sample/v1") 216 217 objs, err = template(h, &TemplateOpts{APIVersions: []string{"sample/v2"}}) 218 if !assert.NoError(t, err) || !assert.Len(t, objs, 1) { 219 return 220 } 221 assert.Equal(t, objs[0].GetAPIVersion(), "sample/v2") 222 } 223 224 func TestSkipCrds(t *testing.T) { 225 h, err := NewHelmApp("./testdata/crds", nil, false, "", "", false) 226 if !assert.NoError(t, err) { 227 return 228 } 229 230 objs, err := template(h, &TemplateOpts{SkipCrds: false}) 231 if !assert.NoError(t, err) || !assert.Len(t, objs, 1) { 232 return 233 } 234 235 objs, err = template(h, &TemplateOpts{}) 236 if !assert.NoError(t, err) || !assert.Len(t, objs, 1) { 237 return 238 } 239 240 objs, err = template(h, &TemplateOpts{SkipCrds: true}) 241 if !assert.NoError(t, err) || !assert.Len(t, objs, 0) { 242 return 243 } 244 }