/* * Copyright 2018 Intel Corporation, Inc * Copyright 2020,2021 Samsung Electronics, Modifications * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package helm import ( "crypto/sha256" "fmt" "io/ioutil" "path/filepath" "strings" "testing" ) func TestProcessValues(t *testing.T) { chartDir := "../../mock_files/mock_charts/testchart2" profileDir := "../../mock_files/mock_profiles/profile1" testCases := []struct { label string valueFiles []string values []string expectedHash string expectedError string }{ { label: "Process Values with Value Files Override", valueFiles: []string{ filepath.Join(chartDir, "values.yaml"), filepath.Join(profileDir, "override_values.yaml"), }, //Hash of a combined values.yaml file that is expected expectedHash: "c18a70f426933de3c051c996dc34fd537d0131b2d13a2112a2ecff674db6c2f9", expectedError: "", }, { label: "Process Values with Values Pair Override", valueFiles: []string{ filepath.Join(chartDir, "values.yaml"), }, //Use the same convention as specified in helm template --set values: []string{ "service.externalPort=82", }, //Hash of a combined values.yaml file that is expected expectedHash: "028a3521fc9f8777ea7e67a6de0c51f2c875b88ca91734999657f0ca924ddb7a", expectedError: "", }, { label: "Process Values with Both Overrides", valueFiles: []string{ filepath.Join(chartDir, "values.yaml"), filepath.Join(profileDir, "override_values.yaml"), }, //Use the same convention as specified in helm template --set //Key takes precedence over the value from override_values.yaml values: []string{ "service.externalPort=82", }, //Hash of a combined values.yaml file that is expected expectedHash: "516fab4ab7b76ba2ff35a97c2a79b74302543f532857b945f2fe25e717e755be", expectedError: "", }, { label: "Process complex Pair Override", values: []string{ "name={a,b,c}", "servers[0].port=80", }, expectedError: "", expectedHash: "50d9401b003f65c1ccfd1c5155106fff88c8201ab8b7d66bd6ffa4fe2883bead", }, } h := sha256.New() for _, testCase := range testCases { t.Run(testCase.label, func(t *testing.T) { tc := NewTemplateClient("1.12.3", "testnamespace", "testreleasename") out, err := tc.processValues(testCase.valueFiles, testCase.values) if err != nil { if testCase.expectedError == "" { t.Fatalf("Got an error %s", err) } if strings.Contains(err.Error(), testCase.expectedError) == false { t.Fatalf("Got unexpected error message %s", err) } } else { //Compute the hash of returned data and compare h.Write(out) gotHash := fmt.Sprintf("%x", h.Sum(nil)) h.Reset() if gotHash != testCase.expectedHash { t.Fatalf("Got unexpected hash '%s' of values.yaml:\n%s", gotHash, out) } } }) } } func TestGenerateKubernetesArtifacts(t *testing.T) { chartDir := "../../mock_files/mock_charts/testchart2" profileDir := "../../mock_files/mock_profiles/profile1" testCases := []struct { label string chartPath string valueFiles []string values []string expectedHashMap map[string]string expectedError string }{ { label: "Generate artifacts without any overrides", chartPath: chartDir, valueFiles: []string{}, values: []string{}, //sha256 hash of the evaluated templates in each chart expectedHashMap: map[string]string{ "testchart2/templates/service.yaml": "fdd6a2b6795486f0dd1d8c44379afb5ffe4072c09f9cf6594738e8ded4dd872d", "subcharta/templates/service.yaml": "570389588fffdb7193ab265888d781f3d751f3a40362533344f9aa7bb93a8bb0", "subchartb/templates/service.yaml": "5654e03d922e8ec49649b4bbda9dfc9e643b3b7c9c18b602cc7e26fd36a39c2a", }, expectedError: "", }, { label: "Generate artifacts with overrides", chartPath: chartDir, valueFiles: []string{ filepath.Join(profileDir, "override_values.yaml"), }, values: []string{ "service.externalPort=82", }, //sha256 hash of the evaluated templates in each chart expectedHashMap: map[string]string{ "testchart2/templates/service.yaml": "2bb96e791ecb6a3404bc5de3f6c4182aed881630269e2aa6766df38b0f852724", "subcharta/templates/service.yaml": "570389588fffdb7193ab265888d781f3d751f3a40362533344f9aa7bb93a8bb0", "subchartb/templates/service.yaml": "5654e03d922e8ec49649b4bbda9dfc9e643b3b7c9c18b602cc7e26fd36a39c2a", }, expectedError: "", }, { label: "Generate artifacts from multi-template and empty files v1", chartPath: "../../mock_files/mock_charts/testchart3", valueFiles: []string{}, values: []string{ "goingEmpty=false", }, expectedHashMap: map[string]string{ "testchart3/templates/multi.yaml-2": "e24cbbefac2c2f700880b8fd041838f2dd48bbc1e099e7c1d2485ae7feb3da0d", "testchart3/templates/multi.yaml-3": "592a8e5b2c35b8469aa45703a835bc00657bfe36b51eb08427a46e7d22fb1525", }, expectedError: "", }, { label: "Generate artifacts from multi-template and empty files v2", chartPath: "../../mock_files/mock_charts/testchart3", valueFiles: []string{}, values: []string{ "goingEmpty=true", }, expectedHashMap: map[string]string{ "testchart3/templates/multi.yaml-3": "e24cbbefac2c2f700880b8fd041838f2dd48bbc1e099e7c1d2485ae7feb3da0d", "testchart3/templates/multi.yaml-4": "0bea01e65148584609ede5000c024241ba1c35b440b32ec0a4f7013015715bfe", "testchart3/templates/multi.yaml-5": "6a5af22538c273b9d4a3156e3b6bb538c655041eae31e93db21a9e178f73ecf0", }, expectedError: "", }, { label: "Test simple v3 helm charts support", chartPath: "../../mock_files/mock_charts/mockv3", valueFiles: []string{}, values: []string{}, expectedError: "", expectedHashMap: map[string]string{ "mockv3/templates/deployment.yaml": "259a027a4957e7428eb1d2e774fa1afaa62449521853f8b2916887040bae2ca4", }, }, } h := sha256.New() for _, testCase := range testCases { t.Run(testCase.label, func(t *testing.T) { tc := NewTemplateClient("1.12.3", "testnamespace", "testreleasename") out, _, err := tc.GenerateKubernetesArtifacts(testCase.chartPath, testCase.valueFiles, testCase.values) if err != nil { if testCase.expectedError == "" { t.Fatalf("Got an error %s", err) } if strings.Contains(err.Error(), testCase.expectedError) == false { t.Fatalf("Got unexpected error message %s", err) } } else { //Compute the hash of returned data and compare for _, v := range out { f := v.FilePath data, err := ioutil.ReadFile(f) if err != nil { t.Errorf("Unable to read file %s", v) } h.Write(data) gotHash := fmt.Sprintf("%x", h.Sum(nil)) h.Reset() //Find the right hash from expectedHashMap expectedHash := "" for k1, v1 := range testCase.expectedHashMap { if strings.Contains(f, k1) == true { expectedHash = v1 break } } if gotHash != expectedHash { t.Fatalf("Got unexpected hash for %s: '%s'; expected: '%s'", f, gotHash, expectedHash) } } } }) } }