diff --git a/pkg/lint2/helm_integration_test.go b/pkg/lint2/helm_integration_test.go new file mode 100644 index 000000000..6dfec312f --- /dev/null +++ b/pkg/lint2/helm_integration_test.go @@ -0,0 +1,76 @@ +//go:build integration +// +build integration + +package lint2 + +import ( + "context" + "testing" + + "github.com/replicatedhq/replicated/pkg/tools" +) + +// TestLintChart_Integration tests the full helm chart linting flow +// with actual helm binary execution. This test requires the helm +// tool to be downloadable and should be run with: go test -tags=integration +func TestLintChart_Integration(t *testing.T) { + ctx := context.Background() + + t.Run("valid helm chart", func(t *testing.T) { + result, err := LintChart(ctx, "testdata/charts/valid-chart", tools.DefaultHelmVersion) + if err != nil { + t.Fatalf("LintChart() error = %v, want nil", err) + } + + if !result.Success { + t.Errorf("Expected success=true for valid chart, got false") + } + + // Valid chart may have INFO or WARNING messages + // but should not have errors + for _, msg := range result.Messages { + if msg.Severity == "ERROR" { + t.Errorf("Unexpected ERROR in valid chart: %s", msg.Message) + } + } + }) + + t.Run("invalid yaml helm chart", func(t *testing.T) { + result, err := LintChart(ctx, "testdata/charts/invalid-yaml", tools.DefaultHelmVersion) + if err != nil { + t.Fatalf("LintChart() error = %v, want nil", err) + } + + if result.Success { + t.Errorf("Expected success=false for invalid YAML chart, got true") + } + + // Should have at least one error message + hasError := false + for _, msg := range result.Messages { + if msg.Severity == "ERROR" { + hasError = true + // Verify error message is not empty + if msg.Message == "" { + t.Errorf("Error message should not be empty") + } + } + } + + if !hasError { + t.Errorf("Expected at least one ERROR message for invalid YAML chart") + } + }) + + t.Run("non-existent chart path", func(t *testing.T) { + _, err := LintChart(ctx, "testdata/charts/does-not-exist", tools.DefaultHelmVersion) + if err == nil { + t.Errorf("Expected error for non-existent chart path, got nil") + } + + // Error should mention the path doesn't exist + if err != nil && !contains(err.Error(), "does not exist") { + t.Errorf("Error should mention path doesn't exist, got: %v", err) + } + }) +} diff --git a/pkg/lint2/preflight_integration_test.go b/pkg/lint2/preflight_integration_test.go index 7413de623..ecdd899a2 100644 --- a/pkg/lint2/preflight_integration_test.go +++ b/pkg/lint2/preflight_integration_test.go @@ -14,10 +14,6 @@ import ( // with actual preflight binary execution. This test requires the preflight // tool to be downloadable and should be run with: go test -tags=integration func TestLintPreflight_Integration(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test in short mode") - } - ctx := context.Background() t.Run("valid preflight spec", func(t *testing.T) { diff --git a/pkg/lint2/testdata/charts/invalid-yaml/Chart.yaml b/pkg/lint2/testdata/charts/invalid-yaml/Chart.yaml new file mode 100644 index 000000000..93c9b9cdc --- /dev/null +++ b/pkg/lint2/testdata/charts/invalid-yaml/Chart.yaml @@ -0,0 +1,7 @@ +apiVersion: v2 +name: invalid-yaml-chart +description: A chart with YAML syntax errors for testing +type: application +version: 1.0.0 +appVersion: "1.0.0 +# Missing closing quote above - this is a syntax error diff --git a/pkg/lint2/testdata/charts/valid-chart/Chart.yaml b/pkg/lint2/testdata/charts/valid-chart/Chart.yaml new file mode 100644 index 000000000..a414ff965 --- /dev/null +++ b/pkg/lint2/testdata/charts/valid-chart/Chart.yaml @@ -0,0 +1,6 @@ +apiVersion: v2 +name: valid-chart +description: A valid Helm chart for testing +type: application +version: 1.0.0 +appVersion: "1.0.0" diff --git a/pkg/lint2/testdata/charts/valid-chart/templates/_helpers.tpl b/pkg/lint2/testdata/charts/valid-chart/templates/_helpers.tpl new file mode 100644 index 000000000..3ad1d79d7 --- /dev/null +++ b/pkg/lint2/testdata/charts/valid-chart/templates/_helpers.tpl @@ -0,0 +1,19 @@ +{{/* vim: set filetype=mustache: */}} +{{/* +Expand the name of the chart. +*/}} +{{- define "valid-chart.name" -}} +{{- default .Chart.Name .Values.nameOverride | trunc 63 | trimSuffix "-" -}} +{{- end -}} + +{{/* +Create a default fully qualified app name. +*/}} +{{- define "valid-chart.fullname" -}} +{{- if .Values.fullnameOverride -}} +{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" -}} +{{- else -}} +{{- $name := default .Chart.Name .Values.nameOverride -}} +{{- printf "%s-%s" .Release.Name $name | trunc 63 | trimSuffix "-" -}} +{{- end -}} +{{- end -}} diff --git a/pkg/lint2/testdata/charts/valid-chart/templates/deployment.yaml b/pkg/lint2/testdata/charts/valid-chart/templates/deployment.yaml new file mode 100644 index 000000000..b89b529dc --- /dev/null +++ b/pkg/lint2/testdata/charts/valid-chart/templates/deployment.yaml @@ -0,0 +1,22 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: {{ include "valid-chart.fullname" . }} + labels: + app: {{ include "valid-chart.name" . }} +spec: + replicas: {{ .Values.replicaCount }} + selector: + matchLabels: + app: {{ include "valid-chart.name" . }} + template: + metadata: + labels: + app: {{ include "valid-chart.name" . }} + spec: + containers: + - name: {{ .Chart.Name }} + image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + imagePullPolicy: {{ .Values.image.pullPolicy }} + ports: + - containerPort: 80 diff --git a/pkg/lint2/testdata/charts/valid-chart/values.yaml b/pkg/lint2/testdata/charts/valid-chart/values.yaml new file mode 100644 index 000000000..7bf9820ae --- /dev/null +++ b/pkg/lint2/testdata/charts/valid-chart/values.yaml @@ -0,0 +1,11 @@ +# Default values for valid-chart +replicaCount: 1 + +image: + repository: nginx + tag: stable + pullPolicy: IfNotPresent + +service: + type: ClusterIP + port: 80 diff --git a/pkg/tools/resolver_fallback_test.go b/pkg/tools/resolver_integration_test.go similarity index 91% rename from pkg/tools/resolver_fallback_test.go rename to pkg/tools/resolver_integration_test.go index 5298eaea2..be381d3db 100644 --- a/pkg/tools/resolver_fallback_test.go +++ b/pkg/tools/resolver_integration_test.go @@ -1,3 +1,6 @@ +//go:build integration +// +build integration + package tools import ( @@ -13,10 +16,6 @@ import ( // Currently FAILS due to bug: Download() discards the actual version used, // so Resolver looks for the tool at the wrong path. func TestResolverWithInvalidVersionFallback(t *testing.T) { - if testing.Short() { - t.Skip("skipping integration test that downloads from network") - } - ctx := context.Background() resolver := NewResolver()