From 6fc16f4ed22ebdf53236bfa434678fa663149c6a Mon Sep 17 00:00:00 2001 From: yxxhero Date: Sat, 18 Apr 2026 08:48:34 +0800 Subject: [PATCH] test: add integration test for issue #2502 race condition with shared local chart Signed-off-by: yxxhero --- test/integration/run.sh | 1 + .../issue-2502-race-condition-local-chart.sh | 57 +++++++++++++++++++ .../input/helm/my-chart/Chart.yaml | 10 ++++ .../input/helm/my-chart/values.yaml | 8 +++ .../input/helmfile.yaml | 13 +++++ 5 files changed, 89 insertions(+) create mode 100644 test/integration/test-cases/issue-2502-race-condition-local-chart.sh create mode 100644 test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/Chart.yaml create mode 100644 test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/values.yaml create mode 100644 test/integration/test-cases/issue-2502-race-condition-local-chart/input/helmfile.yaml diff --git a/test/integration/run.sh b/test/integration/run.sh index a7116e8f..6b3cd92a 100755 --- a/test/integration/run.sh +++ b/test/integration/run.sh @@ -96,6 +96,7 @@ ${kubectl} create namespace ${test_ns} || fail "Could not create namespace ${tes # TEST CASES---------------------------------------------------------------------------------------------------------- +. ${dir}/test-cases/issue-2502-race-condition-local-chart.sh . ${dir}/test-cases/chart-deps-condition.sh . ${dir}/test-cases/fetch-forl-local-chart.sh . ${dir}/test-cases/suppress-output-line-regex.sh diff --git a/test/integration/test-cases/issue-2502-race-condition-local-chart.sh b/test/integration/test-cases/issue-2502-race-condition-local-chart.sh new file mode 100644 index 00000000..5f7722e9 --- /dev/null +++ b/test/integration/test-cases/issue-2502-race-condition-local-chart.sh @@ -0,0 +1,57 @@ +# Integration test for issue #2502: Race condition when multiple releases share a local chart +# https://github.com/helmfile/helmfile/issues/2502 +# +# When multiple releases reference the same local chart, concurrent goroutines +# race on rewriting Chart.yaml dependencies, causing: +# "Error: validation: chart.metadata.name is required" +# +# This test verifies the fix works WITHOUT --concurrency 1 workaround. + +issue_2502_input_dir="${cases_dir}/issue-2502-race-condition-local-chart/input" + +issue_2502_tmp=$(mktemp -d) +actual="${issue_2502_tmp}/actual.yaml" + +cleanup_issue_2502() { + if [ -n "${issue_2502_tmp}" ] && [ -d "${issue_2502_tmp}" ]; then + rm -rf "${issue_2502_tmp}" + fi +} +trap cleanup_issue_2502 EXIT + +test_start "issue #2502: race condition with shared local chart" + +info "Running helmfile template with 5 releases sharing the same local chart (default concurrency)" + +# Run WITHOUT --concurrency 1 to test the fix. +# Before the fix, this would intermittently fail with: +# "Error: validation: chart.metadata.name is required" +# Run multiple iterations to increase chance of catching a race. +pass=0 +iterations=5 +for i in $(seq 1 ${iterations}); do + if ${helmfile} -f ${issue_2502_input_dir}/helmfile.yaml -e test template --skip-deps > ${actual} 2>&1; then + pass=$((pass + 1)) + else + cat ${actual} + fail "helmfile template failed on iteration ${i}/${iterations} (race condition on shared local chart)" + fi +done + +if [ ${pass} -ne ${iterations} ]; then + fail "Expected ${iterations}/${iterations} passes but got ${pass}/${iterations}" +fi + +info "All ${iterations} iterations passed successfully" + +# Verify all 5 releases are present in output +for name in app app-2 app-3 app-4 app-5; do + if ! grep -q "name: ${name}" ${actual}; then + fail "Output should contain release '${name}'" + fi +done + +cleanup_issue_2502 +trap - EXIT + +test_pass "issue #2502: race condition with shared local chart" diff --git a/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/Chart.yaml b/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/Chart.yaml new file mode 100644 index 00000000..a03785c1 --- /dev/null +++ b/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/Chart.yaml @@ -0,0 +1,10 @@ +dependencies: + - name: raw + repository: file://../../../charts/raw + version: 0.0.1 +apiVersion: v2 +appVersion: "1.0.0" +description: A test chart for race condition reproduction +name: my-chart +type: application +version: 0.1.0 diff --git a/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/values.yaml b/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/values.yaml new file mode 100644 index 00000000..8f37b0b5 --- /dev/null +++ b/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helm/my-chart/values.yaml @@ -0,0 +1,8 @@ +templates: + - | + apiVersion: v1 + kind: ConfigMap + metadata: + name: {{ .Release.Name }}-config + data: + key: value diff --git a/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helmfile.yaml b/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helmfile.yaml new file mode 100644 index 00000000..8727d73e --- /dev/null +++ b/test/integration/test-cases/issue-2502-race-condition-local-chart/input/helmfile.yaml @@ -0,0 +1,13 @@ +environments: + test: {} +releases: + - name: app + chart: helm/my-chart + - name: app-2 + chart: helm/my-chart + - name: app-3 + chart: helm/my-chart + - name: app-4 + chart: helm/my-chart + - name: app-5 + chart: helm/my-chart