pull/31517/merge
Hamza Hathoute 2 days ago committed by GitHub
commit b4b59afdd4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -22,6 +22,7 @@ import (
"fmt"
"os"
"path/filepath"
"text/template"
)
// UpdateGolden writes out the golden files with the latest values, rather than failing the test.
@ -40,10 +41,10 @@ type HelperT interface {
}
// AssertGoldenString asserts that the given string matches the contents of the given file.
func AssertGoldenString(t TestingT, actual, filename string) {
func AssertGoldenString(t TestingT, actual, filename string, goldenArgs map[string]string) {
t.Helper()
if err := compare([]byte(actual), path(filename)); err != nil {
if err := compare([]byte(actual), path(filename), goldenArgs); err != nil {
t.Fatalf("%v\n", err)
}
}
@ -56,7 +57,7 @@ func AssertGoldenFile(t TestingT, actualFileName string, expectedFilename string
if err != nil {
t.Fatalf("%v", err)
}
AssertGoldenString(t, string(actual), expectedFilename)
AssertGoldenString(t, string(actual), expectedFilename, map[string]string{})
}
func path(filename string) string {
@ -66,7 +67,7 @@ func path(filename string) string {
return filepath.Join("testdata", filename)
}
func compare(actual []byte, filename string) error {
func compare(actual []byte, filename string, templates map[string]string) error {
actual = normalize(actual)
if err := update(filename, actual); err != nil {
return err
@ -77,12 +78,34 @@ func compare(actual []byte, filename string) error {
return fmt.Errorf("unable to read testdata %s: %w", filename, err)
}
expected = normalize(expected)
if templates != nil && len(templates) > 0 {
expected, err = templateString(expected, templates)
if err != nil {
return fmt.Errorf("unable to template testdata %s: %w", filename, err)
}
}
if !bytes.Equal(expected, actual) {
return fmt.Errorf("does not match golden file %s\n\nWANT:\n'%s'\n\nGOT:\n'%s'", filename, expected, actual)
}
return nil
}
func templateString(content []byte, data map[string]string) ([]byte, error) {
tmpl, err := template.New("content").Parse(string(content))
if err != nil {
return nil, err
}
var buf bytes.Buffer
if err := tmpl.Execute(&buf, data); err != nil {
return nil, err
}
return buf.Bytes(), nil
}
func update(filename string, in []byte) error {
if !*updateGolden {
return nil

@ -59,7 +59,7 @@ func TestList(t *testing.T) {
if err := NewDependency().List(tcase.chart, &buf); err != nil {
t.Fatal(err)
}
test.AssertGoldenString(t, buf.String(), tcase.golden)
test.AssertGoldenString(t, buf.String(), tcase.golden, map[string]string{})
}
}

@ -840,7 +840,7 @@ OUTER:
if err != nil {
return err
}
if dac.Name() == rac.Name() {
if dac.Name() == rac.Name() && dac.Version() == rac.Version() {
continue OUTER
}
}

@ -51,6 +51,10 @@ func (r *v2Accessor) Name() string {
return r.chrt.Metadata.Name
}
func (r *v2Accessor) Version() string {
return r.chrt.Metadata.Version
}
func (r *v2Accessor) IsRoot() bool {
return r.chrt.IsRoot()
}
@ -120,6 +124,10 @@ func (r *v3Accessor) Name() string {
return r.chrt.Metadata.Name
}
func (r *v3Accessor) Version() string {
return r.chrt.Metadata.Version
}
func (r *v3Accessor) IsRoot() bool {
return r.chrt.IsRoot()
}

@ -47,6 +47,10 @@ func (r *v2DependencyAccessor) Name() string {
return r.dep.Name
}
func (r *v2DependencyAccessor) Version() string {
return r.dep.Version
}
func (r *v2DependencyAccessor) Alias() string {
return r.dep.Alias
}
@ -59,6 +63,10 @@ func (r *v3DependencyAccessor) Name() string {
return r.dep.Name
}
func (r *v3DependencyAccessor) Version() string {
return r.dep.Version
}
func (r *v3DependencyAccessor) Alias() string {
return r.dep.Alias
}

@ -25,6 +25,7 @@ type Dependency any
type Accessor interface {
Name() string
Version() string
IsRoot() bool
MetadataAsMap() map[string]any
Files() []*common.File
@ -40,5 +41,6 @@ type Accessor interface {
type DependencyAccessor interface {
Name() string
Version() string
Alias() string
}

@ -69,7 +69,7 @@ func runTestCmd(t *testing.T, tests []cmdTestCase) {
t.Errorf("expected no error, got: '%v'", err)
}
if tt.golden != "" {
test.AssertGoldenString(t, out, tt.golden)
test.AssertGoldenString(t, out, tt.golden, tt.goldenArgs)
}
})
}
@ -129,10 +129,11 @@ func executeActionCommandStdinC(store *storage.Storage, in *os.File, cmd string)
// cmdTestCase describes a test case that works with releases.
type cmdTestCase struct {
name string
cmd string
golden string
wantError bool
name string
cmd string
golden string
goldenArgs map[string]string
wantError bool
// Rels are the available releases at the start of the test.
rels []*release.Release
// Number of repeats (in case a feature was previously flaky and the test checks

@ -153,6 +153,15 @@ func TestInstall(t *testing.T) {
cmd: "install --dependency-update updeps testdata/testcharts/chart-with-subchart-update",
golden: "output/chart-with-subchart-update.txt",
},
// Install chart with update-dependency
{
name: "install chart with outdated dependencies",
cmd: fmt.Sprintf("install --dependency-update --repository-cache %s --repository-config %s updeps testdata/testcharts/chart-with-outdated-dependency --username username --password password", srv.Root(), repoFile),
golden: "output/install-with-outdated-deps.txt",
goldenArgs: map[string]string{
"repoUrl": srv.URL(),
},
},
// Install, chart with bad dependencies in Chart.yaml in /charts
{
name: "install chart with bad dependencies in Chart.yaml",

@ -0,0 +1,12 @@
Hang tight while we grab the latest from your chart repositories...
...Successfully got an update from the "test" chart repository
Update Complete. ⎈Happy Helming!⎈
Saving 1 charts
Downloading oci-dependent-chart from repo {{ .repoUrl }}
Deleting outdated charts
NAME: updeps
LAST DEPLOYED: Fri Sep 2 22:04:05 1977
NAMESPACE: default
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete

@ -0,0 +1,21 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*~
# Various IDEs
.project
.idea/
*.tmproj

@ -0,0 +1,8 @@
apiVersion: v1
description: A Helm chart for Kubernetes
name: chart-with-outdated-dependency
version: 0.1.0
dependencies:
- name: oci-dependent-chart
version: 0.1.0
repository: "@test"

@ -0,0 +1,23 @@
# Patterns to ignore when building packages.
# This supports shell glob matching, relative path matching, and
# negation (prefixed with !). Only one pattern per line.
.DS_Store
# Common VCS dirs
.git/
.gitignore
.bzr/
.bzrignore
.hg/
.hgignore
.svn/
# Common backup files
*.swp
*.bak
*.tmp
*.orig
*~
# Various IDEs
.project
.idea/
*.tmproj
.vscode/

@ -0,0 +1,6 @@
apiVersion: v2
appVersion: 1.16.0
description: A Helm chart for Kubernetes
name: oci-dependent-chart
type: application
version: 0.0.1

@ -0,0 +1,22 @@
1. Get the application URL by running these commands:
{{- if .Values.ingress.enabled }}
{{- range $host := .Values.ingress.hosts }}
{{- range .paths }}
http{{ if $.Values.ingress.tls }}s{{ end }}://{{ $host.host }}{{ . }}
{{- end }}
{{- end }}
{{- else if contains "NodePort" .Values.service.type }}
export NODE_PORT=$(kubectl get --namespace {{ .Release.Namespace }} -o jsonpath="{.spec.ports[0].nodePort}" services {{ include "oci-dependent-chart.fullname" . }})
export NODE_IP=$(kubectl get nodes --namespace {{ .Release.Namespace }} -o jsonpath="{.items[0].status.addresses[0].address}")
echo http://$NODE_IP:$NODE_PORT
{{- else if contains "LoadBalancer" .Values.service.type }}
NOTE: It may take a few minutes for the LoadBalancer IP to be available.
You can watch the status of by running 'kubectl get --namespace {{ .Release.Namespace }} svc -w {{ include "oci-dependent-chart.fullname" . }}'
export SERVICE_IP=$(kubectl get svc --namespace {{ .Release.Namespace }} {{ include "oci-dependent-chart.fullname" . }} --template "{{"{{ range (index .status.loadBalancer.ingress 0) }}{{.}}{{ end }}"}}")
echo http://$SERVICE_IP:{{ .Values.service.port }}
{{- else if contains "ClusterIP" .Values.service.type }}
export POD_NAME=$(kubectl get pods --namespace {{ .Release.Namespace }} -l "app.kubernetes.io/name={{ include "oci-dependent-chart.name" . }},app.kubernetes.io/instance={{ .Release.Name }}" -o jsonpath="{.items[0].metadata.name}")
export CONTAINER_PORT=$(kubectl get pod --namespace {{ .Release.Namespace }} $POD_NAME -o jsonpath="{.spec.containers[0].ports[0].containerPort}")
echo "Visit http://127.0.0.1:8080 to use your application"
kubectl --namespace {{ .Release.Namespace }} port-forward $POD_NAME 8080:$CONTAINER_PORT
{{- end }}

@ -0,0 +1,15 @@
apiVersion: v1
kind: Pod
metadata:
name: "{{ include "oci-dependent-chart.fullname" . }}-test-connection"
labels:
{{- include "oci-dependent-chart.labels" . | nindent 4 }}
annotations:
"helm.sh/hook": test
spec:
containers:
- name: wget
image: busybox
command: ['wget']
args: ['{{ include "oci-dependent-chart.fullname" . }}:{{ .Values.service.port }}']
restartPolicy: Never

@ -0,0 +1,3 @@
# Default values for oci-dependent-chart.
# This is a YAML-formatted file.
# Declare variables to be passed into your templates.

@ -0,0 +1,4 @@
# Default values for reqtest.
# This is a YAML-formatted file.
# Declare name/value pairs to be passed into your templates.
# name: value
Loading…
Cancel
Save