214 lines
5.9 KiB
Go
214 lines
5.9 KiB
Go
package sdk
|
|
|
|
import (
|
|
"fmt"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/portainer/portainer/api/filesystem"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"helm.sh/helm/v4/pkg/action"
|
|
v2chart "helm.sh/helm/v4/pkg/chart/v2"
|
|
chartutil "helm.sh/helm/v4/pkg/chart/v2/util"
|
|
repo "helm.sh/helm/v4/pkg/repo/v1"
|
|
)
|
|
|
|
func TestAppendChartReferenceAnnotations(t *testing.T) {
|
|
t.Parallel()
|
|
tests := []struct {
|
|
name string
|
|
chartPath string
|
|
repoURL string
|
|
registryID int
|
|
stackID int
|
|
existing map[string]string
|
|
want map[string]string
|
|
}{
|
|
{
|
|
name: "with registry ID",
|
|
chartPath: "charts/nginx",
|
|
registryID: 5,
|
|
stackID: 123,
|
|
want: map[string]string{
|
|
ChartPathAnnotation: "charts/nginx",
|
|
RegistryIDAnnotation: "5",
|
|
StackIDAnnotation: "123",
|
|
// repoURL is NOT added when registryID != 0
|
|
},
|
|
},
|
|
{
|
|
name: "with repo URL (no registry)",
|
|
chartPath: "charts/nginx",
|
|
repoURL: "https://charts.example.com",
|
|
stackID: 123,
|
|
want: map[string]string{
|
|
ChartPathAnnotation: "charts/nginx",
|
|
RepoURLAnnotation: "https://charts.example.com",
|
|
StackIDAnnotation: "123",
|
|
},
|
|
},
|
|
{
|
|
name: "preserves custom annotations",
|
|
chartPath: "my-chart",
|
|
existing: map[string]string{"custom": "value"},
|
|
want: map[string]string{
|
|
ChartPathAnnotation: "my-chart",
|
|
"custom": "value",
|
|
},
|
|
},
|
|
{
|
|
name: "replaces old chart annotations",
|
|
chartPath: "new-chart",
|
|
repoURL: "https://new.com",
|
|
existing: map[string]string{
|
|
ChartPathAnnotation: "old-chart",
|
|
RepoURLAnnotation: "https://old.com",
|
|
},
|
|
want: map[string]string{
|
|
ChartPathAnnotation: "new-chart",
|
|
RepoURLAnnotation: "https://new.com",
|
|
},
|
|
},
|
|
{
|
|
name: "omits zero values",
|
|
chartPath: "chart",
|
|
want: map[string]string{
|
|
ChartPathAnnotation: "chart",
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
result := appendChartReferenceAnnotations(
|
|
tt.chartPath, tt.repoURL, tt.registryID, tt.stackID,
|
|
nil, tt.existing,
|
|
)
|
|
|
|
assert.Equal(t, tt.want, result)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestAppendChartReferenceAnnotations_RepoURLLogic(t *testing.T) {
|
|
t.Parallel()
|
|
t.Run("repoURL only added when registryID is zero", func(t *testing.T) {
|
|
// With registry ID - no repoURL
|
|
result := appendChartReferenceAnnotations("chart", "url", 5, 0, nil, nil)
|
|
_, hasRepoURL := result[RepoURLAnnotation]
|
|
assert.False(t, hasRepoURL)
|
|
|
|
// Without registry ID - includes repoURL
|
|
result = appendChartReferenceAnnotations("chart", "url", 0, 0, nil, nil)
|
|
assert.Equal(t, "url", result[RepoURLAnnotation])
|
|
})
|
|
|
|
t.Run("does not mutate existing map", func(t *testing.T) {
|
|
existing := map[string]string{"key": "value"}
|
|
appendChartReferenceAnnotations("chart", "", 0, 0, nil, existing)
|
|
assert.Equal(t, map[string]string{"key": "value"}, existing)
|
|
})
|
|
}
|
|
|
|
func TestLoadAndValidateChartWithPathOptions(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
depTgzPath := saveMinimalDepChart(t, "dep-chart", "0.1.0")
|
|
depTgzName := filepath.Base(depTgzPath)
|
|
|
|
server := newHelmHTTPRepoServer(t, depTgzPath)
|
|
parentDir := writeParentChart(t, "parent-chart", "dep-chart", "0.1.0", server.URL)
|
|
|
|
hspm := newIsolatedHelmSDKPackageManager(t)
|
|
|
|
ch, err := hspm.loadAndValidateChartWithPathOptions(
|
|
new(action.Configuration),
|
|
&action.ChartPathOptions{},
|
|
parentDir, "", "", true, "test",
|
|
)
|
|
|
|
require.NoError(t, err)
|
|
require.NotNil(t, ch)
|
|
assert.Equal(t, "parent-chart", ch.Metadata.Name)
|
|
assert.FileExists(t, filesystem.JoinPaths(parentDir, "charts", depTgzName),
|
|
"dependency tarball should have been downloaded into charts/ — proves ContentCache was threaded into downloader.Manager")
|
|
}
|
|
|
|
// saveMinimalDepChart produces a valid dependency chart tarball on disk and returns its path.
|
|
func saveMinimalDepChart(t *testing.T, name, version string) string {
|
|
t.Helper()
|
|
tgzPath, err := chartutil.Save(&v2chart.Chart{
|
|
Metadata: &v2chart.Metadata{
|
|
Name: name,
|
|
Version: version,
|
|
APIVersion: "v2",
|
|
},
|
|
}, t.TempDir())
|
|
require.NoError(t, err)
|
|
return tgzPath
|
|
}
|
|
|
|
func newHelmHTTPRepoServer(t *testing.T, tgzPath string) *httptest.Server {
|
|
t.Helper()
|
|
tgzName := filepath.Base(tgzPath)
|
|
|
|
mux := http.NewServeMux()
|
|
server := httptest.NewServer(mux)
|
|
t.Cleanup(server.Close)
|
|
|
|
mux.HandleFunc("/"+tgzName, func(w http.ResponseWriter, r *http.Request) {
|
|
http.ServeFile(w, r, tgzPath)
|
|
})
|
|
index := fmt.Sprintf(`apiVersion: v1
|
|
entries:
|
|
dep-chart:
|
|
- name: dep-chart
|
|
version: 0.1.0
|
|
apiVersion: v2
|
|
urls:
|
|
- %s/%s
|
|
`, server.URL, tgzName)
|
|
mux.HandleFunc("/index.yaml", func(w http.ResponseWriter, r *http.Request) {
|
|
w.Header().Set("Content-Type", "text/yaml")
|
|
_, _ = w.Write([]byte(index))
|
|
})
|
|
return server
|
|
}
|
|
|
|
// writeParentChart writes a Chart.yaml declaring a single HTTP dependency and returns the chart dir.
|
|
func writeParentChart(t *testing.T, parentName, depName, depVersion, repoURL string) string {
|
|
t.Helper()
|
|
dir := t.TempDir()
|
|
chartYAML := fmt.Sprintf(`apiVersion: v2
|
|
name: %s
|
|
version: 0.1.0
|
|
dependencies:
|
|
- name: %s
|
|
version: %q
|
|
repository: %q
|
|
`, parentName, depName, depVersion, repoURL)
|
|
require.NoError(t, os.WriteFile(filesystem.JoinPaths(dir, "Chart.yaml"), []byte(chartYAML), 0o644))
|
|
return dir
|
|
}
|
|
|
|
func newIsolatedHelmSDKPackageManager(t *testing.T) *HelmSDKPackageManager {
|
|
t.Helper()
|
|
tmp := t.TempDir()
|
|
hspm := NewHelmSDKPackageManager()
|
|
hspm.settings.RepositoryConfig = filesystem.JoinPaths(tmp, "repositories.yaml")
|
|
hspm.settings.RepositoryCache = filesystem.JoinPaths(tmp, "repository")
|
|
hspm.settings.ContentCache = filesystem.JoinPaths(tmp, "content")
|
|
|
|
require.NoError(t, os.MkdirAll(hspm.settings.RepositoryCache, 0o700))
|
|
require.NoError(t, os.MkdirAll(hspm.settings.ContentCache, 0o700))
|
|
|
|
f := repo.NewFile()
|
|
require.NoError(t, f.WriteFile(hspm.settings.RepositoryConfig, 0o644))
|
|
|
|
return hspm
|
|
}
|