mirror of https://github.com/helm/helm
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
212 lines
7.6 KiB
212 lines
7.6 KiB
/*
|
|
Copyright The Helm Authors.
|
|
|
|
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 rules
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
chart "helm.sh/helm/v4/internal/chart/v3"
|
|
"helm.sh/helm/v4/internal/chart/v3/lint/support"
|
|
chartutil "helm.sh/helm/v4/internal/chart/v3/util"
|
|
)
|
|
|
|
const (
|
|
badChartNameDir = "testdata/badchartname"
|
|
badChartDir = "testdata/badchartfile"
|
|
anotherBadChartDir = "testdata/anotherbadchartfile"
|
|
)
|
|
|
|
var (
|
|
badChartNamePath = filepath.Join(badChartNameDir, "Chart.yaml")
|
|
badChartFilePath = filepath.Join(badChartDir, "Chart.yaml")
|
|
nonExistingChartFilePath = filepath.Join(os.TempDir(), "Chart.yaml")
|
|
)
|
|
|
|
var (
|
|
badChart, _ = chartutil.LoadChartfile(badChartFilePath)
|
|
badChartName, _ = chartutil.LoadChartfile(badChartNamePath)
|
|
)
|
|
|
|
// Validation functions Test
|
|
func TestValidateChartYamlNotDirectory(t *testing.T) {
|
|
_ = os.Mkdir(nonExistingChartFilePath, os.ModePerm)
|
|
defer os.Remove(nonExistingChartFilePath)
|
|
|
|
assert.Error(t, validateChartYamlNotDirectory(nonExistingChartFilePath), "validateChartYamlNotDirectory to return a linter error, got no error")
|
|
}
|
|
|
|
func TestValidateChartYamlFormat(t *testing.T) {
|
|
require.Error(t, validateChartYamlFormat(errors.New("Read error")), "validateChartYamlFormat to return a linter error, got no error")
|
|
|
|
assert.NoError(t, validateChartYamlFormat(nil), "validateChartYamlFormat to return no error, got a linter error")
|
|
}
|
|
|
|
func TestValidateChartName(t *testing.T) {
|
|
require.Error(t, validateChartName(badChart), "validateChartName to return a linter error, got no error")
|
|
|
|
assert.Error(t, validateChartName(badChartName), "expected validateChartName to return a linter error for an invalid name, got no error")
|
|
}
|
|
|
|
func TestValidateChartVersion(t *testing.T) {
|
|
failTest := []struct {
|
|
Version string
|
|
ErrorMsg string
|
|
}{
|
|
{"", "version is required"},
|
|
{"1.2.3.4", "version '1.2.3.4' is not a valid SemVerV2"},
|
|
{"waps", "'waps' is not a valid SemVerV2"},
|
|
{"-3", "'-3' is not a valid SemVerV2"},
|
|
{"1.1", "'1.1' is not a valid SemVerV2"},
|
|
{"1", "'1' is not a valid SemVerV2"},
|
|
}
|
|
|
|
successTest := []string{"0.0.1", "0.0.1+build", "0.0.1-beta"}
|
|
|
|
for i, test := range failTest {
|
|
t.Run(strconv.Itoa(i), func(t *testing.T) {
|
|
badChart.Version = test.Version
|
|
require.ErrorContains(t, validateChartVersion(badChart), test.ErrorMsg, "validateChartVersion(%s) to return \"%s\", got no error", test.Version, test.ErrorMsg)
|
|
})
|
|
}
|
|
|
|
for _, version := range successTest {
|
|
badChart.Version = version
|
|
assert.NoError(t, validateChartVersion(badChart), "validateChartVersion(%s) to return no error, got a linter error", version)
|
|
}
|
|
}
|
|
|
|
func TestValidateChartMaintainer(t *testing.T) {
|
|
failTest := []struct {
|
|
Name string
|
|
Email string
|
|
ErrorMsg string
|
|
}{
|
|
{"", "", "each maintainer requires a name"},
|
|
{"", "test@test.com", "each maintainer requires a name"},
|
|
{"John Snow", "wrongFormatEmail.com", "invalid email"},
|
|
}
|
|
|
|
successTest := []struct {
|
|
Name string
|
|
Email string
|
|
}{
|
|
{"John Snow", ""},
|
|
{"John Snow", "john@winterfell.com"},
|
|
}
|
|
|
|
for _, test := range failTest {
|
|
t.Run(fmt.Sprintf("%s, %s", test.Name, test.Email), func(t *testing.T) {
|
|
badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}}
|
|
require.ErrorContains(t, validateChartMaintainer(badChart), test.ErrorMsg, "validateChartMaintainer(%s, %s) to return \"%s\", got no error", test.Name, test.Email, test.ErrorMsg)
|
|
})
|
|
}
|
|
|
|
for _, test := range successTest {
|
|
t.Run(fmt.Sprintf("%s, %s", test.Name, test.Email), func(t *testing.T) {
|
|
badChart.Maintainers = []*chart.Maintainer{{Name: test.Name, Email: test.Email}}
|
|
require.NoError(t, validateChartMaintainer(badChart), "validateChartMaintainer(%s, %s) to return no error", test.Name, test.Email)
|
|
})
|
|
}
|
|
|
|
// Testing for an empty maintainer
|
|
badChart.Maintainers = []*chart.Maintainer{nil}
|
|
assert.EqualError(t, validateChartMaintainer(badChart), "a maintainer entry is empty")
|
|
}
|
|
|
|
func TestValidateChartSources(t *testing.T) {
|
|
failTest := []string{"", "RiverRun", "john@winterfell", "riverrun.io"}
|
|
successTest := []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish"}
|
|
for _, test := range failTest {
|
|
t.Run(test, func(t *testing.T) {
|
|
badChart.Sources = []string{test}
|
|
require.ErrorContains(t, validateChartSources(badChart), "invalid source URL", "validateChartSources(%s) to return \"invalid source URL\", got no error", test)
|
|
})
|
|
}
|
|
|
|
for _, test := range successTest {
|
|
badChart.Sources = []string{test}
|
|
assert.NoError(t, validateChartSources(badChart), "validateChartSources(%s) to return no error", test)
|
|
}
|
|
}
|
|
|
|
func TestValidateChartIconPresence(t *testing.T) {
|
|
t.Run("Icon absent", func(t *testing.T) {
|
|
testChart := &chart.Metadata{
|
|
Icon: "",
|
|
}
|
|
|
|
assert.ErrorContains(t, validateChartIconPresence(testChart), "icon is recommended", "expected %q", "icon is recommended")
|
|
})
|
|
t.Run("Icon present", func(t *testing.T) {
|
|
testChart := &chart.Metadata{
|
|
Icon: "http://example.org/icon.png",
|
|
}
|
|
assert.NoError(t, validateChartIconPresence(testChart))
|
|
})
|
|
}
|
|
|
|
func TestValidateChartIconURL(t *testing.T) {
|
|
failTest := []string{"RiverRun", "john@winterfell", "riverrun.io"}
|
|
successTest := []string{"http://riverrun.io", "https://riverrun.io", "https://riverrun.io/blackfish.png"}
|
|
for _, test := range failTest {
|
|
t.Run(test, func(t *testing.T) {
|
|
badChart.Icon = test
|
|
require.ErrorContains(t, validateChartIconURL(badChart), "invalid icon URL", "validateChartIconURL(%s) to return \"invalid icon URL\", got no error", test)
|
|
})
|
|
}
|
|
|
|
for _, test := range successTest {
|
|
badChart.Icon = test
|
|
assert.NoError(t, validateChartIconURL(badChart), "validateChartIconURL(%s) to return no error", test)
|
|
}
|
|
}
|
|
|
|
func TestV3Chartfile(t *testing.T) {
|
|
t.Run("Chart.yaml basic validity issues", func(t *testing.T) {
|
|
linter := support.Linter{ChartDir: badChartDir}
|
|
Chartfile(&linter)
|
|
msgs := linter.Messages
|
|
expectedNumberOfErrorMessages := 6
|
|
|
|
require.Lenf(t, msgs, expectedNumberOfErrorMessages, "Expected %d errors", expectedNumberOfErrorMessages)
|
|
require.ErrorContains(t, msgs[0].Err, "name is required", "Unexpected message 0")
|
|
require.ErrorContains(t, msgs[1].Err, "apiVersion is required. The value must be \"v3\"", "Unexpected message 1")
|
|
require.ErrorContains(t, msgs[2].Err, "version '0.0.0.0' is not a valid SemVer", "Unexpected message 2")
|
|
assert.ErrorContains(t, msgs[3].Err, "icon is recommended", "Unexpected message 3")
|
|
})
|
|
|
|
t.Run("Chart.yaml validity issues due to type mismatch", func(t *testing.T) {
|
|
linter := support.Linter{ChartDir: anotherBadChartDir}
|
|
Chartfile(&linter)
|
|
msgs := linter.Messages
|
|
expectedNumberOfErrorMessages := 3
|
|
|
|
require.Lenf(t, msgs, expectedNumberOfErrorMessages, "Expected %d errors", expectedNumberOfErrorMessages)
|
|
require.ErrorContains(t, msgs[0].Err, "version should be of type string", "Unexpected message 0")
|
|
require.ErrorContains(t, msgs[1].Err, "version '7.2445e+06' is not a valid SemVer", "Unexpected message 1")
|
|
assert.ErrorContains(t, msgs[2].Err, "appVersion should be of type string", "Unexpected message 2")
|
|
})
|
|
}
|