From 6e37dd26a1a9b16e6b523a94561fbfdb2a81e69c Mon Sep 17 00:00:00 2001 From: Daniel Fox Date: Wed, 5 Aug 2026 10:11:31 -0700 Subject: [PATCH] Add a test for version pushing normalization --- pkg/pusher/ocipusher_test.go | 72 ++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/pkg/pusher/ocipusher_test.go b/pkg/pusher/ocipusher_test.go index 972096605..18127f3d6 100644 --- a/pkg/pusher/ocipusher_test.go +++ b/pkg/pusher/ocipusher_test.go @@ -24,6 +24,8 @@ import ( "strings" "testing" + chart "helm.sh/helm/v4/pkg/chart/v2" + chartutil "helm.sh/helm/v4/pkg/chart/v2/util" "helm.sh/helm/v4/pkg/registry" ) @@ -586,6 +588,76 @@ func TestBuildOCIReference(t *testing.T) { } } +// TestOCIPusher_Push_NormalizeVersion checks that push() acts on the values +// returned by buildOCIReference: it must relax the registry client's strict mode +// whenever the normalized tag no longer matches the raw chart version. +// +// The registry client performs its strict mode check before contacting the +// registry, so an unreachable host is enough to observe the behaviour: if strict +// mode was left enabled the push fails with the strict mode error, otherwise it +// gets as far as the network and fails to connect. +func TestOCIPusher_Push_NormalizeVersion(t *testing.T) { + // Port 1 is not a registry, so a push that clears the strict mode check + // fails while connecting rather than being rejected locally. + const href = "oci://127.0.0.1:1/charts" + const strictModeError = "strict mode enabled" + + tests := []struct { + name string + version string + ociNormalizeVersion bool + }{ + { + name: "normalize disabled tags with the raw version", + version: "v1.2.3", + ociNormalizeVersion: false, + }, + { + name: "normalize canonicalizes the tag and relaxes strict mode", + version: "v1.2.3", + ociNormalizeVersion: true, + }, + { + name: "normalize completes a short version and relaxes strict mode", + version: "1.2", + ociNormalizeVersion: true, + }, + { + name: "normalize leaves a canonical version untouched", + version: "1.2.3", + ociNormalizeVersion: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + chartPath, err := chartutil.Save(&chart.Chart{ + Metadata: &chart.Metadata{ + APIVersion: chart.APIVersionV2, + Name: "normalizechart", + Version: tt.version, + }, + }, t.TempDir()) + if err != nil { + t.Fatal(err) + } + + pusher, err := NewOCIPusher(WithOCINormalizeVersion(tt.ociNormalizeVersion)) + if err != nil { + t.Fatal(err) + } + + err = pusher.Push(chartPath, href) + if err == nil { + t.Fatalf("Expected push to %s to fail", href) + } + if strings.Contains(err.Error(), strictModeError) { + t.Errorf("Expected push to clear the registry client's strict mode check, got %q", err.Error()) + } + }) + } +} + func TestOCIPusher_Push_MultipleOptions(t *testing.T) { chartPath := "../../pkg/cmd/testdata/testcharts/compressedchart-0.1.0.tgz"