test: add test for prepare charts with template args
Signed-off-by: Kerstin Albers <kerstinzuzej@gmail.com>
This commit is contained in:
		
							parent
							
								
									2e52967d68
								
							
						
					
					
						commit
						228aab70a9
					
				|  | @ -8,6 +8,7 @@ import ( | ||||||
| 	"strings" | 	"strings" | ||||||
| 
 | 
 | ||||||
| 	"github.com/fatih/color" | 	"github.com/fatih/color" | ||||||
|  | 	"github.com/helmfile/chartify" | ||||||
| 
 | 
 | ||||||
| 	"github.com/helmfile/helmfile/pkg/helmexec" | 	"github.com/helmfile/helmfile/pkg/helmexec" | ||||||
| 	"github.com/helmfile/helmfile/pkg/state" | 	"github.com/helmfile/helmfile/pkg/state" | ||||||
|  | @ -42,6 +43,14 @@ func (r *Run) askForConfirmation(msg string) bool { | ||||||
| 	return AskForConfirmation(msg) | 	return AskForConfirmation(msg) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | type Chartifier struct { | ||||||
|  | 	runner *chartify.Runner | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *Chartifier) Chartify(release, dirOrChart string, opts ...chartify.ChartifyOption) (string, error) { | ||||||
|  | 	return c.runner.Chartify(release, dirOrChart, opts...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func (r *Run) prepareChartsIfNeeded(helmfileCommand string, dir string, concurrency int, opts state.ChartPrepareOptions) (map[state.PrepareChartKey]string, error) { | func (r *Run) prepareChartsIfNeeded(helmfileCommand string, dir string, concurrency int, opts state.ChartPrepareOptions) (map[state.PrepareChartKey]string, error) { | ||||||
| 	// Skip chart preparation for certain commands
 | 	// Skip chart preparation for certain commands
 | ||||||
| 	skipCommands := []string{"write-values", "list"} | 	skipCommands := []string{"write-values", "list"} | ||||||
|  | @ -49,7 +58,15 @@ func (r *Run) prepareChartsIfNeeded(helmfileCommand string, dir string, concurre | ||||||
| 		return nil, nil | 		return nil, nil | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	releaseToChart, errs := r.state.PrepareCharts(r.helm, dir, concurrency, helmfileCommand, opts) | 	chartifier := &Chartifier{ | ||||||
|  | 		runner: chartify.New( | ||||||
|  | 			chartify.HelmBin(r.state.DefaultHelmBinary), | ||||||
|  | 			chartify.KustomizeBin(r.state.DefaultKustomizeBinary), | ||||||
|  | 			chartify.UseHelm3(true), | ||||||
|  | 			chartify.WithLogf(r.state.Logger().Debugf)), | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	releaseToChart, errs := r.state.PrepareCharts(r.helm, chartifier, dir, concurrency, helmfileCommand, opts) | ||||||
| 	if len(errs) > 0 { | 	if len(errs) > 0 { | ||||||
| 		return nil, fmt.Errorf("%v", errs) | 		return nil, fmt.Errorf("%v", errs) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -1209,6 +1209,16 @@ type PrepareChartKey struct { | ||||||
| 	Namespace, Name, KubeContext string | 	Namespace, Name, KubeContext string | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func (st *HelmState) Logger() *zap.SugaredLogger { | ||||||
|  | 	return st.logger | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type Chartifier interface { | ||||||
|  | 	// Chartify creates a temporary Helm chart from a directory or a remote chart, and applies various transformations.
 | ||||||
|  | 	// Returns the full path to the temporary directory containing the generated chart if succeeded.
 | ||||||
|  | 	Chartify(release, dirOrChart string, opts ...chartify.ChartifyOption) (string, error) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // PrepareCharts creates temporary directories of charts.
 | // PrepareCharts creates temporary directories of charts.
 | ||||||
| //
 | //
 | ||||||
| // Each resulting "chart" can be one of the followings:
 | // Each resulting "chart" can be one of the followings:
 | ||||||
|  | @ -1220,10 +1230,10 @@ type PrepareChartKey struct { | ||||||
| // When running `helmfile template` on helm v2, or `helmfile lint` on both helm v2 and v3,
 | // When running `helmfile template` on helm v2, or `helmfile lint` on both helm v2 and v3,
 | ||||||
| // PrepareCharts will download and untar charts for linting and templating.
 | // PrepareCharts will download and untar charts for linting and templating.
 | ||||||
| //
 | //
 | ||||||
| // Otheriwse, if a chart is not a helm chart, it will call "chartify" to turn it into a chart.
 | // Otherwise, if a chart is not a helm chart, it will call "chartify" to turn it into a chart.
 | ||||||
| //
 | //
 | ||||||
| // If exists, it will also patch resources by json patches, strategic-merge patches, and injectors.
 | // If exists, it will also patch resources by json patches, strategic-merge patches, and injectors.
 | ||||||
| func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurrency int, helmfileCommand string, opts ChartPrepareOptions) (map[PrepareChartKey]string, []error) { | func (st *HelmState) PrepareCharts(helm helmexec.Interface, chartifier Chartifier, dir string, concurrency int, helmfileCommand string, opts ChartPrepareOptions) (map[PrepareChartKey]string, []error) { | ||||||
| 	if !opts.SkipResolve { | 	if !opts.SkipResolve { | ||||||
| 		updated, err := st.ResolveDeps() | 		updated, err := st.ResolveDeps() | ||||||
| 		if err != nil { | 		if err != nil { | ||||||
|  | @ -1317,13 +1327,6 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre | ||||||
| 				skipDeps := (!isLocal && !chartFetchedByGoGetter) || skipDepsGlobal || skipDepsRelease || skipDepsDefault | 				skipDeps := (!isLocal && !chartFetchedByGoGetter) || skipDepsGlobal || skipDepsRelease || skipDepsDefault | ||||||
| 
 | 
 | ||||||
| 				if chartification != nil && helmfileCommand != "pull" { | 				if chartification != nil && helmfileCommand != "pull" { | ||||||
| 					c := chartify.New( |  | ||||||
| 						chartify.HelmBin(st.DefaultHelmBinary), |  | ||||||
| 						chartify.KustomizeBin(st.DefaultKustomizeBinary), |  | ||||||
| 						chartify.UseHelm3(true), |  | ||||||
| 						chartify.WithLogf(st.logger.Debugf), |  | ||||||
| 					) |  | ||||||
| 
 |  | ||||||
| 					chartifyOpts := chartification.Opts | 					chartifyOpts := chartification.Opts | ||||||
| 
 | 
 | ||||||
| 					if skipDeps { | 					if skipDeps { | ||||||
|  | @ -1357,7 +1360,7 @@ func (st *HelmState) PrepareCharts(helm helmexec.Interface, dir string, concurre | ||||||
| 					} | 					} | ||||||
| 					chartifyOpts.SetFlags = append(chartifyOpts.SetFlags, flags...) | 					chartifyOpts.SetFlags = append(chartifyOpts.SetFlags, flags...) | ||||||
| 
 | 
 | ||||||
| 					out, err := c.Chartify(release.Name, chartPath, chartify.WithChartifyOpts(chartifyOpts)) | 					out, err := chartifier.Chartify(release.Name, chartPath, chartify.WithChartifyOpts(chartifyOpts)) | ||||||
| 					if err != nil { | 					if err != nil { | ||||||
| 						results <- &chartPrepareResult{err: err} | 						results <- &chartPrepareResult{err: err} | ||||||
| 						return | 						return | ||||||
|  |  | ||||||
|  | @ -4,11 +4,13 @@ import ( | ||||||
| 	"fmt" | 	"fmt" | ||||||
| 	"io" | 	"io" | ||||||
| 	"os" | 	"os" | ||||||
|  | 	"path" | ||||||
| 	"path/filepath" | 	"path/filepath" | ||||||
| 	"reflect" | 	"reflect" | ||||||
| 	"testing" | 	"testing" | ||||||
| 
 | 
 | ||||||
| 	"github.com/Masterminds/semver/v3" | 	"github.com/Masterminds/semver/v3" | ||||||
|  | 	"github.com/helmfile/chartify" | ||||||
| 	"github.com/helmfile/vals" | 	"github.com/helmfile/vals" | ||||||
| 	"github.com/stretchr/testify/assert" | 	"github.com/stretchr/testify/assert" | ||||||
| 	"github.com/stretchr/testify/require" | 	"github.com/stretchr/testify/require" | ||||||
|  | @ -2974,6 +2976,107 @@ func TestDiffpareSyncReleases(t *testing.T) { | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // capturingChartifier implements state.Chartifier for tests.
 | ||||||
|  | type capturingChartifier struct { | ||||||
|  | 	mChartify    func(release string, dirOrChart string, opts ...chartify.ChartifyOption) (string, error) | ||||||
|  | 	capturedArgs []chartifyArgs | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | type chartifyArgs struct { | ||||||
|  | 	release    string | ||||||
|  | 	dirOrChart string | ||||||
|  | 	opts       []chartify.ChartifyOption | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func (c *capturingChartifier) Chartify(release string, dirOrChart string, opts ...chartify.ChartifyOption) (string, error) { | ||||||
|  | 	c.capturedArgs = append(c.capturedArgs, chartifyArgs{release: release, dirOrChart: dirOrChart, opts: opts}) | ||||||
|  | 	return c.mChartify(release, dirOrChart, opts...) | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | func TestPrepareCharts_invokesChartifierWithTemplateArgs(t *testing.T) { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name         string | ||||||
|  | 		chartifier   *capturingChartifier | ||||||
|  | 		dir          string | ||||||
|  | 		concurrency  int | ||||||
|  | 		command      string | ||||||
|  | 		opts         ChartPrepareOptions | ||||||
|  | 		expectedArgs []chartifyArgs | ||||||
|  | 		helmDefaults *HelmSpec | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			name: "template command", | ||||||
|  | 			chartifier: &capturingChartifier{ | ||||||
|  | 				mChartify: func(release string, dirOrChart string, opts ...chartify.ChartifyOption) (string, error) { | ||||||
|  | 					return "someTempDir", nil | ||||||
|  | 				}, | ||||||
|  | 			}, | ||||||
|  | 			dir:         "someChartPath", | ||||||
|  | 			concurrency: 1, | ||||||
|  | 			command:     "template", | ||||||
|  | 			opts: ChartPrepareOptions{ | ||||||
|  | 				SkipDeps:     true, | ||||||
|  | 				TemplateArgs: "someArgs", | ||||||
|  | 			}, | ||||||
|  | 			helmDefaults: &HelmSpec{}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tt := range tests { | ||||||
|  | 		t.Run(tt.name, func(t *testing.T) { | ||||||
|  | 			tmpDir, err := os.MkdirTemp("", "test-prepare-charts-*") | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("setup temp test dir: %v", err) | ||||||
|  | 			} | ||||||
|  | 			defer os.RemoveAll(tmpDir) | ||||||
|  | 
 | ||||||
|  | 			err = os.Mkdir(path.Join(tmpDir, tt.dir), 0755) | ||||||
|  | 			if err != nil { | ||||||
|  | 				t.Fatalf("setup chart dir: %v", err) | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			release := ReleaseSpec{ | ||||||
|  | 				Name: tt.name, | ||||||
|  | 			} | ||||||
|  | 			releases := []ReleaseSpec{ | ||||||
|  | 				release, | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			state := &HelmState{ | ||||||
|  | 				basePath: tmpDir, | ||||||
|  | 				ReleaseSetSpec: ReleaseSetSpec{ | ||||||
|  | 					Releases:     releases, | ||||||
|  | 					HelmDefaults: *tt.helmDefaults, | ||||||
|  | 				}, | ||||||
|  | 				logger:         logger, | ||||||
|  | 				valsRuntime:    valsRuntime, | ||||||
|  | 				fs:             filesystem.DefaultFileSystem(), | ||||||
|  | 				RenderedValues: map[string]any{}, | ||||||
|  | 			} | ||||||
|  | 			helm := &exectest.Helm{ | ||||||
|  | 				Lists: map[exectest.ListKey]string{}, | ||||||
|  | 				Helm3: true, | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			_, errs := state.PrepareCharts(helm, tt.chartifier, path.Join(tmpDir, tt.dir), tt.concurrency, tt.command, tt.opts) | ||||||
|  | 
 | ||||||
|  | 			require.Len(t, errs, 0) | ||||||
|  | 			require.Len(t, tt.chartifier.capturedArgs, 1) | ||||||
|  | 
 | ||||||
|  | 			appliedChartifyOpts := &chartify.ChartifyOpts{} | ||||||
|  | 
 | ||||||
|  | 			for _, o := range tt.chartifier.capturedArgs[0].opts { | ||||||
|  | 				err = o.SetChartifyOption(appliedChartifyOpts) | ||||||
|  | 				if err != nil { | ||||||
|  | 					t.Fatalf("set captured chartify options: %v", err) | ||||||
|  | 				} | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			require.Equal(t, tt.opts.TemplateArgs, appliedChartifyOpts.TemplateArgs) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestPrepareSyncReleases(t *testing.T) { | func TestPrepareSyncReleases(t *testing.T) { | ||||||
| 	tests := []struct { | 	tests := []struct { | ||||||
| 		name         string | 		name         string | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue