pull/30826/merge
jamoflaw 2 weeks ago committed by GitHub
commit 9acb5555cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -49,6 +49,8 @@ func ContainsTag(tags []string, tag string) bool {
return slices.Contains(tags, tag)
}
// GetTagMatchingVersionOrConstraint gets the latest tag matching a given semver constraint.
// Expects tags to be a sorted slice of semver tags (highest version first)
func GetTagMatchingVersionOrConstraint(tags []string, versionString string) (string, error) {
var constraint *semver.Constraints
if versionString == "" {

@ -17,11 +17,13 @@ limitations under the License.
package registry // import "helm.sh/helm/v4/pkg/registry"
import (
"fmt"
"reflect"
"testing"
"time"
ocispec "github.com/opencontainers/image-spec/specs-go/v1"
"github.com/stretchr/testify/assert"
chart "helm.sh/helm/v4/pkg/chart/v2"
helmtime "helm.sh/helm/v4/pkg/time"
@ -273,3 +275,282 @@ func TestGenerateOCICreatedAnnotations(t *testing.T) {
}
}
func TestIsOCI(t *testing.T) {
tests := []struct {
name string
uri string
isValid bool
}{
{
name: "Valid URI",
uri: "oci://example.com/myregistry:1.2.3",
isValid: true,
},
{
name: "Invalid URI prefix (boundary test 1)",
uri: "noci://example.com/myregistry:1.2.3",
isValid: false,
},
{
name: "Invalid URI prefix (boundary test 2)",
uri: "ocin://example.com/myregistry:1.2.3",
isValid: false,
},
}
for _, tt := range tests {
assert.Equal(t, tt.isValid, IsOCI(tt.uri), tt.name)
}
}
func TestContainsTag(t *testing.T) {
tagList := []string{"1.0.0", "1.0.1", "2.0.0", "2.1.0"}
tests := []struct {
name string
tag string
present bool
}{
{
name: "tag present",
tag: "1.0.1",
present: true,
},
{
name: "tag not present",
tag: "1.0.2",
present: false,
},
}
for _, tt := range tests {
assert.Equal(t, tt.present, ContainsTag(tagList, tt.tag), tt.name)
}
}
func TestGetTagMatchingVersionOrConstraint(t *testing.T) {
// GetTagMatchingVersionOrConstraint expects the tag list to be sorted highest to lowest version
tagList := []string{
"10.0.1",
"9.0.1",
"3.1.0",
"3.0.0",
"2.0.11",
"2.0.9",
"2.0.0",
"1.10.0",
"1.9.1",
"1.9.0",
"1.0.0",
"0.3.0",
"0.2.2",
"0.2.1",
"0.2.0",
"0.1.0",
"0.0.3",
"0.0.2",
"0.0.1",
}
tests := []struct {
name string
versionConstraint string
expectErr bool
expectVersion string
}{
{
name: "Explicit version",
versionConstraint: "1.10.0",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "Implicit wildcard default from empty string",
versionConstraint: "",
expectErr: false,
expectVersion: "10.0.1",
},
{
name: "No versions within wildcard constraint",
versionConstraint: "50.*",
expectErr: true,
expectVersion: "",
},
{
name: "Invalid version constraint",
versionConstraint: "<>!=20",
expectErr: true,
expectVersion: "",
},
{
name: "Explicit wildcard",
versionConstraint: "*",
expectErr: false,
expectVersion: "10.0.1",
},
{
name: "Major version wildcard selection",
versionConstraint: "2.*",
expectErr: false,
expectVersion: "2.0.11",
},
{
name: "Minor version wildcard selection",
versionConstraint: "3.1.*",
expectErr: false,
expectVersion: "3.1.0",
},
{
name: "~ major version",
versionConstraint: "~1",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "~ major version plus x",
versionConstraint: "~1.x",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "~ specific version",
versionConstraint: "~1.9.0",
expectErr: false,
expectVersion: "1.9.1",
},
{
name: "~ minor version",
versionConstraint: "~1.9",
expectErr: false,
expectVersion: "1.9.1",
},
{
name: "~ minor version plus x",
versionConstraint: "~1.9.x",
expectErr: false,
expectVersion: "1.9.1",
},
{
name: "^ specific version",
versionConstraint: "^1.9.0",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "^ minor version version >=1",
versionConstraint: "^1.9",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "^ minor version plus x >=1",
versionConstraint: "^1.9.x",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "^ major version plus x >=1",
versionConstraint: "^1.x",
expectErr: false,
expectVersion: "1.10.0",
},
{
name: "^ full version <1",
versionConstraint: "^0.2.1",
expectErr: false,
expectVersion: "0.2.2",
},
{
name: "^ minor version <1",
versionConstraint: "^0.2",
expectErr: false,
expectVersion: "0.2.2",
},
{
name: "^ patch version < 0.1",
versionConstraint: "^0.0.2",
expectErr: false,
expectVersion: "0.0.2",
},
{
name: "^ with 0.0",
versionConstraint: "^0.0",
expectErr: false,
expectVersion: "0.0.3",
},
{
name: "^ with 0",
versionConstraint: "^0",
expectErr: false,
expectVersion: "0.3.0",
},
{
name: "= operator",
versionConstraint: "=1.9.0",
expectErr: false,
expectVersion: "1.9.0",
},
{
name: "!= operator",
versionConstraint: "!=1.9.0",
expectErr: false,
expectVersion: "10.0.1",
},
{
name: "> operator",
versionConstraint: ">1.9.0",
expectErr: false,
expectVersion: "10.0.1",
},
{
name: "< operator",
versionConstraint: "<1.9.0",
expectErr: false,
expectVersion: "1.0.0",
},
{
name: ">= operator",
versionConstraint: ">=1.9.0",
expectErr: false,
expectVersion: "10.0.1",
},
{
name: "<= operator",
versionConstraint: "<=1.9.0",
expectErr: false,
expectVersion: "1.9.0",
},
{
name: "gte and less than combination",
versionConstraint: ">=1.9.0, <1.10.0",
expectErr: false,
expectVersion: "1.9.1",
},
{
name: "gte and lte with a negation combination",
versionConstraint: ">=1.9.0, <=1.10.0, !=1.10.0",
expectErr: false,
expectVersion: "1.9.1",
},
{
name: "multiple ranges separated by ||",
versionConstraint: ">=1.1.0, <=1.10.0 || >=2.0.0, <3.0.0",
expectErr: false,
expectVersion: "2.0.11",
},
}
for _, tt := range tests {
version, err := GetTagMatchingVersionOrConstraint(tagList, tt.versionConstraint)
if tt.expectErr {
assert.Error(t, err, fmt.Sprintf("Should produce an error (%s)", tt.name))
} else {
assert.Nil(t, err, fmt.Sprintf("Error should be nil (%s)", tt.name))
}
assert.Equal(t, tt.expectVersion, version, fmt.Sprintf("The expected matching version is %s (%s)", tt.expectVersion, tt.name))
}
}

Loading…
Cancel
Save