github.com/stefanmcshane/helm@v0.0.0-20221213002717-88a4a2c6e77d/pkg/lint/rules/chartfile_test.go (about) 1 /* 2 Copyright The Helm Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package rules 18 19 import ( 20 "os" 21 "path/filepath" 22 "strings" 23 "testing" 24 25 "github.com/pkg/errors" 26 27 "github.com/stefanmcshane/helm/pkg/chart" 28 "github.com/stefanmcshane/helm/pkg/chartutil" 29 "github.com/stefanmcshane/helm/pkg/lint/support" 30 ) 31 32 const ( 33 badChartDir = "testdata/badchartfile" 34 anotherBadChartDir = "testdata/anotherbadchartfile" 35 ) 36 37 var ( 38 badChartFilePath = filepath.Join(badChartDir, "Chart.yaml") 39 nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml") 40 ) 41 42 var badChart, _ = chartutil.LoadChartfile(badChartFilePath) 43 44 // Validation functions Test 45 func TestValidateChartYamlNotDirectory(t *testing.T) { 46 _ = os.Mkdir(nonExistingChartFilePath, os.ModePerm) 47 defer os.Remove(nonExistingChartFilePath) 48 49 err := validateChartYamlNotDirectory(nonExistingChartFilePath) 50 if err == nil { 51 t.Errorf("validateChartYamlNotDirectory to return a linter error, got no error") 52 } 53 } 54 55 func TestValidateChartYamlFormat(t *testing.T) { 56 err := validateChartYamlFormat(errors.New("Read error")) 57 if err == nil { 58 t.Errorf("validateChartYamlFormat to return a linter error, got no error") 59 } 60 61 err = validateChartYamlFormat(nil) 62 if err != nil { 63 t.Errorf("validateChartYamlFormat to return no error, got a linter error") 64 } 65 } 66 67 func TestValidateChartName(t *testing.T) { 68 err := validateChartName(badChart) 69 if err == nil { 70 t.Errorf("validateChartName to return a linter error, got no error") 71 } 72 } 73 74 func TestValidateChartVersion(t *testing.T) { 75 var failTest = []struct { 76 Version string 77 ErrorMsg string 78 }{ 79 {"", "version is required"}, 80 {"1.2.3.4", "version '1.2.3.4' is not a valid SemVer"}, 81 {"waps", "'waps' is not a valid SemVer"}, 82 {"-3", "'-3' is not a valid SemVer"}, 83 } 84 85 var successTest = []string{"0.0.1", "0.0.1+build", "0.0.1-beta"} 86 87 for _, test := range failTest { 88 badChart.Version = test.Version 89 err := validateChartVersion(badChart) 90 if err == nil || !strings.Contains(err.Error(), test.ErrorMsg) { 91 t.Errorf("validateChartVersion(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg) 92 } 93 } 94 95 for _, version := range successTest { 96 badChart.Version = version 97 err := validateChartVersion(badChart) 98 if err != nil { 99 t.Errorf("validateChartVersion(%s) to return no error, got a linter error", version) 100 } 101 } 102 } 103 104 func TestValidateChartMaintainer(t *testing.T) { 105 var failTest = []struct { 106 Name string 107 Email string 108 ErrorMsg string 109 }{ 110 {"", "", "each maintainer requires a name"}, 111 {"", "test@test.com", "each maintainer requires a name"}, 112 {"John Snow", "wrongFormatEmail.com", "invalid email"}, 113 } 114 115 var successTest = []struct { 116 Name string 117 Email string 118 }{ 119 {"John Snow", ""}, 120 {"John Snow", "john@winterfell.com"}, 121 } 122 123 for _, test := range failTest { 124 badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}} 125 err := validateChartMaintainer(badChart) 126 if err == nil || !strings.Contains(err.Error(), test.ErrorMsg) { 127 t.Errorf("validateChartMaintainer(%s, %s) to return \"%s\", got no error", test.Name, test.Email, test.ErrorMsg) 128 } 129 } 130 131 for _, test := range successTest { 132 badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}} 133 err := validateChartMaintainer(badChart) 134 if err != nil { 135 t.Errorf("validateChartMaintainer(%s, %s) to return no error, got %s", test.Name, test.Email, err.Error()) 136 } 137 } 138 } 139 140 func TestValidateChartSources(t *testing.T) { 141 var failTest = []string{"", "RiverRun", "john@winterfell", "riverrun.io"} 142 var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"} 143 for _, test := range failTest { 144 badChart.Sources = []string{test} 145 err := validateChartSources(badChart) 146 if err == nil || !strings.Contains(err.Error(), "invalid source URL") { 147 t.Errorf("validateChartSources(%s) to return \"invalid source URL\", got no error", test) 148 } 149 } 150 151 for _, test := range successTest { 152 badChart.Sources = []string{test} 153 err := validateChartSources(badChart) 154 if err != nil { 155 t.Errorf("validateChartSources(%s) to return no error, got %s", test, err.Error()) 156 } 157 } 158 } 159 160 func TestValidateChartIconPresence(t *testing.T) { 161 err := validateChartIconPresence(badChart) 162 if err == nil { 163 t.Errorf("validateChartIconPresence to return a linter error, got no error") 164 } 165 } 166 167 func TestValidateChartIconURL(t *testing.T) { 168 var failTest = []string{"RiverRun", "john@winterfell", "riverrun.io"} 169 var successTest = []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"} 170 for _, test := range failTest { 171 badChart.Icon = test 172 err := validateChartIconURL(badChart) 173 if err == nil || !strings.Contains(err.Error(), "invalid icon URL") { 174 t.Errorf("validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test) 175 } 176 } 177 178 for _, test := range successTest { 179 badChart.Icon = test 180 err := validateChartSources(badChart) 181 if err != nil { 182 t.Errorf("validateChartIconURL(%s) to return no error, got %s", test, err.Error()) 183 } 184 } 185 } 186 187 func TestChartfile(t *testing.T) { 188 t.Run("Chart.yaml basic validity issues", func(t *testing.T) { 189 linter := support.Linter{ChartDir: badChartDir} 190 Chartfile(&linter) 191 msgs := linter.Messages 192 expectedNumberOfErrorMessages := 6 193 194 if len(msgs) != expectedNumberOfErrorMessages { 195 t.Errorf("Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) 196 return 197 } 198 199 if !strings.Contains(msgs[0].Err.Error(), "name is required") { 200 t.Errorf("Unexpected message 0: %s", msgs[0].Err) 201 } 202 203 if !strings.Contains(msgs[1].Err.Error(), "apiVersion is required. The value must be either \"v1\" or \"v2\"") { 204 t.Errorf("Unexpected message 1: %s", msgs[1].Err) 205 } 206 207 if !strings.Contains(msgs[2].Err.Error(), "version '0.0.0.0' is not a valid SemVer") { 208 t.Errorf("Unexpected message 2: %s", msgs[2].Err) 209 } 210 211 if !strings.Contains(msgs[3].Err.Error(), "icon is recommended") { 212 t.Errorf("Unexpected message 3: %s", msgs[3].Err) 213 } 214 215 if !strings.Contains(msgs[4].Err.Error(), "chart type is not valid in apiVersion") { 216 t.Errorf("Unexpected message 4: %s", msgs[4].Err) 217 } 218 219 if !strings.Contains(msgs[5].Err.Error(), "dependencies are not valid in the Chart file with apiVersion") { 220 t.Errorf("Unexpected message 5: %s", msgs[5].Err) 221 } 222 }) 223 224 t.Run("Chart.yaml validity issues due to type mismatch", func(t *testing.T) { 225 linter := support.Linter{ChartDir: anotherBadChartDir} 226 Chartfile(&linter) 227 msgs := linter.Messages 228 expectedNumberOfErrorMessages := 3 229 230 if len(msgs) != expectedNumberOfErrorMessages { 231 t.Errorf("Expected %d errors, got %d", expectedNumberOfErrorMessages, len(msgs)) 232 return 233 } 234 235 if !strings.Contains(msgs[0].Err.Error(), "version should be of type string") { 236 t.Errorf("Unexpected message 0: %s", msgs[0].Err) 237 } 238 239 if !strings.Contains(msgs[1].Err.Error(), "version '7.2445e+06' is not a valid SemVer") { 240 t.Errorf("Unexpected message 1: %s", msgs[1].Err) 241 } 242 243 if !strings.Contains(msgs[2].Err.Error(), "appVersion should be of type string") { 244 t.Errorf("Unexpected message 2: %s", msgs[2].Err) 245 } 246 }) 247 }