From 9aa1459defecafc1e8908c77011b0ab0de63b8d8 Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Tue, 13 Feb 2024 05:27:01 +0000 Subject: [PATCH] add more tests --- .github/workflows/build-tests.yml | 22 +++--- cmd/teachart/install.go | 2 +- cmd/teachart/lint.go | 2 +- cmd/teachart/repo_add.go | 6 +- cmd/teachart/repo_list.go | 8 +- cmd/teachart/repo_remove.go | 11 ++- cmd/teachart/template.go | 2 +- pkg/engine/engine.go | 7 +- pkg/engine/engine_test.go | 9 ++- pkg/engine/helm.go | 9 ++- pkg/repo/manager.go | 4 +- pkg/repo/repo_checkout.go | 12 ++- tests/chart/values.yaml | 0 tests/{ => data}/chart/Chart.yaml | 0 .../chart/templates/test_values.yaml | 6 ++ tests/data/chart/values.yaml | 2 + tests/data/values.yaml | 2 + tests/integration/integration_test.go | 75 +++++++++++++++++++ tests/values.yaml | 0 19 files changed, 143 insertions(+), 36 deletions(-) delete mode 100644 tests/chart/values.yaml rename tests/{ => data}/chart/Chart.yaml (100%) rename tests/{ => data}/chart/templates/test_values.yaml (71%) create mode 100644 tests/data/chart/values.yaml create mode 100644 tests/data/values.yaml create mode 100644 tests/integration/integration_test.go delete mode 100644 tests/values.yaml diff --git a/.github/workflows/build-tests.yml b/.github/workflows/build-tests.yml index 3389c1e..2df29a0 100644 --- a/.github/workflows/build-tests.yml +++ b/.github/workflows/build-tests.yml @@ -10,14 +10,14 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 - with: - go-version-file: go.mod - check-latest: true - - run: make deps - - run: make checks - - run: make lint - - run: make build - - run: make test - timeout-minutes: 30 + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version-file: go.mod + check-latest: true + - run: make deps + - run: make checks + - run: make lint + - run: make build + - run: make test + timeout-minutes: 30 diff --git a/cmd/teachart/install.go b/cmd/teachart/install.go index d54097e..698356c 100644 --- a/cmd/teachart/install.go +++ b/cmd/teachart/install.go @@ -139,7 +139,7 @@ func NewInstallCmd(ctx context.Context, globalOptions *options.GlobalOptions) *c if err != nil { return errors.Wrap(err, "Create compose client error") } - renderEngine, err := engine.NewRenderEngine(opts.GetChartDir(), opts.GetTeaChart()) + renderEngine, err := engine.NewRenderEngine(opts.GetChartDir(), opts.GetTeaChart(), nil) if err != nil { return errors.Wrap(err, "Create helm engine error") } diff --git a/cmd/teachart/lint.go b/cmd/teachart/lint.go index b2f3743..eb1fd12 100644 --- a/cmd/teachart/lint.go +++ b/cmd/teachart/lint.go @@ -88,7 +88,7 @@ func runLint(ctx context.Context, opts lintOptions) error { logrus.Debugf("Temp directory created:%s", tempDir) // render templates - renderEngine, err := engine.NewRenderEngine(chartDir, opts.GetTeaChart()) + renderEngine, err := engine.NewRenderEngine(chartDir, opts.GetTeaChart(), &engine.NewEngineOptions{Strict: true}) if err != nil { return nil, errors.Wrap(err, "Create helm engine error") } diff --git a/cmd/teachart/repo_add.go b/cmd/teachart/repo_add.go index 6da8b04..07c4046 100644 --- a/cmd/teachart/repo_add.go +++ b/cmd/teachart/repo_add.go @@ -5,6 +5,7 @@ package cmd import ( "context" "errors" + "fmt" "github.com/go-git/go-git/v5" "github.com/sirupsen/logrus" @@ -34,7 +35,7 @@ func NewRepoAddCmd(ctx context.Context, repoOpts *repoOptions) *cobra.Command { opts.Name = args[0] opts.URL = args[1] - return runRepoAdd(ctx, opts.manager, opts) + return runRepoAdd(ctx, cmd, opts.manager, opts) }, } @@ -44,7 +45,8 @@ func NewRepoAddCmd(ctx context.Context, repoOpts *repoOptions) *cobra.Command { return cmd } -func runRepoAdd(ctx context.Context, manager *repo.Manager, opts *repoAddOptions) error { +func runRepoAdd(ctx context.Context, cmd *cobra.Command, manager *repo.Manager, opts *repoAddOptions) error { + fmt.Fprintf(cmd.OutOrStdout(), "adding repo `%s` from %s\n", opts.Name, opts.URL) err := manager.Add(ctx, opts.Name, opts.URL, opts.force) if errors.Is(err, git.ErrRepositoryAlreadyExists) { logrus.Errorf("repo `%s` already exists. use --force/-f to overwrite the repo.", opts.Name) diff --git a/cmd/teachart/repo_list.go b/cmd/teachart/repo_list.go index 227b986..8f9db80 100644 --- a/cmd/teachart/repo_list.go +++ b/cmd/teachart/repo_list.go @@ -24,21 +24,21 @@ func NewRepoListCmd(ctx context.Context, repoOpts *repoOptions) *cobra.Command { Use: "list", Short: "List all chart repos.", RunE: func(cmd *cobra.Command, args []string) error { - return runRepoList(ctx, opts) + return runRepoList(ctx, cmd, opts) }, } return cmd } -func runRepoList(ctx context.Context, opts *repoListOptions) error { +func runRepoList(ctx context.Context, cmd *cobra.Command, opts *repoListOptions) error { reposMap, err := opts.manager.List() if err != nil { return err } if len(reposMap) == 0 { - fmt.Println("no repositories. use `repo add` to add repos") + fmt.Fprintln(cmd.OutOrStdout(), "no repositories. use `repo add` to add repos") return nil } @@ -51,6 +51,6 @@ func runRepoList(ctx context.Context, opts *repoListOptions) error { } table.AddRow(name, remote.Config().URLs[0]) } - fmt.Println(table.String()) + fmt.Fprintln(cmd.OutOrStdout(), table.String()) return nil } diff --git a/cmd/teachart/repo_remove.go b/cmd/teachart/repo_remove.go index a50085f..7fa92d3 100644 --- a/cmd/teachart/repo_remove.go +++ b/cmd/teachart/repo_remove.go @@ -4,6 +4,7 @@ package cmd import ( "context" + "fmt" "github.com/spf13/cobra" "github.com/yp05327/teachart/pkg/repo" @@ -27,13 +28,17 @@ func NewRepoRemoveCmd(ctx context.Context, repoOpts *repoOptions) *cobra.Command RunE: func(cmd *cobra.Command, args []string) error { opts.name = args[0] - return runRepoRemove(ctx, opts.manager, opts) + return runRepoRemove(ctx, cmd, opts.manager, opts) }, } return cmd } -func runRepoRemove(ctx context.Context, manager *repo.Manager, opts *repoRemoveOptions) error { - return manager.Remove(opts.name) +func runRepoRemove(ctx context.Context, cmd *cobra.Command, manager *repo.Manager, opts *repoRemoveOptions) error { + err := manager.Remove(opts.name) + if err == nil { + fmt.Fprintf(cmd.OutOrStdout(), "repo %s removed\n", opts.name) + } + return err } diff --git a/cmd/teachart/template.go b/cmd/teachart/template.go index 542bb5b..475d2ae 100644 --- a/cmd/teachart/template.go +++ b/cmd/teachart/template.go @@ -74,7 +74,7 @@ func NewTemplateCmd(ctx context.Context, globalOptions *options.GlobalOptions) * } func runTemplate(ctx context.Context, opts templateOptions) error { - renderEngine, err := engine.NewRenderEngine(opts.GetChartDir(), opts.GetTeaChart()) + renderEngine, err := engine.NewRenderEngine(opts.GetChartDir(), opts.GetTeaChart(), nil) if err != nil { return errors.Wrap(err, "Create helm engine error") } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index f6de33f..62b0d26 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -6,11 +6,14 @@ import ( "helm.sh/helm/v3/pkg/cli/values" ) +type NewEngineOptions struct { + Strict bool +} type RenderEngine interface { Render(valueOpts values.Options, save bool) (map[string]string, error) GetConfigPaths(files map[string]string) []string } -func NewRenderEngine(chartDir string, teachart *TeaChart) (RenderEngine, error) { - return newHelm(chartDir, teachart) +func NewRenderEngine(chartDir string, teachart *TeaChart, opts *NewEngineOptions) (RenderEngine, error) { + return newHelm(chartDir, teachart, opts) } diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 51b5acb..23c2f2d 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -8,7 +8,8 @@ import ( "helm.sh/helm/v3/pkg/cli/values" ) -const testChartDir = "../../tests/chart" +const testChartDir = "../../tests/data/chart" +const testValuesFile = "../../tests/data/values.yaml" var testTeaChart = TeaChart{ ProjectName: "test", @@ -17,9 +18,11 @@ var testTeaChart = TeaChart{ } func TestHelmRender(t *testing.T) { - e, err := NewRenderEngine(testChartDir, &testTeaChart) + e, err := NewRenderEngine(testChartDir, &testTeaChart, &NewEngineOptions{Strict: true}) assert.NoError(t, err) - _, err = e.Render(values.Options{}, false) + _, err = e.Render(values.Options{ + ValueFiles: []string{testValuesFile}, + }, false) assert.NoError(t, err) } diff --git a/pkg/engine/helm.go b/pkg/engine/helm.go index 3b82261..5941e9a 100644 --- a/pkg/engine/helm.go +++ b/pkg/engine/helm.go @@ -26,15 +26,20 @@ type Helm struct { teachart *TeaChart } -func newHelm(chartDir string, teachart *TeaChart) (*Helm, error) { +func newHelm(chartDir string, teachart *TeaChart, opts *NewEngineOptions) (*Helm, error) { chart, err := loader.Load(chartDir) if err != nil { return nil, err } // TODO support Dependencies + if opts == nil { + opts = &NewEngineOptions{} + } return &Helm{ - engine: &helm_engine.Engine{}, + engine: &helm_engine.Engine{ + Strict: opts.Strict, + }, chart: chart, teachart: teachart, }, nil diff --git a/pkg/repo/manager.go b/pkg/repo/manager.go index 4b85d6e..57c6237 100644 --- a/pkg/repo/manager.go +++ b/pkg/repo/manager.go @@ -44,8 +44,7 @@ func (m *Manager) getRepoPath(name string) string { func (m *Manager) Remove(name string) error { err := os.RemoveAll(m.getRepoPath(name)) if os.IsNotExist(err) { - logrus.Warnf("repo `%s` does not exist in %s", name, m.rootDir) - return nil + return fmt.Errorf("repo `%s` does not exist in %s", name, m.rootDir) } return err } @@ -91,7 +90,6 @@ func (m *Manager) Add(ctx context.Context, name, url string, force bool) error { } // load git repo - fmt.Printf("adding repo `%s` from %s\n", name, url) if err := repoClient.Init(ctx, url); err != nil { if !errors.Is(err, git.ErrRepositoryAlreadyExists) { // need rollback when init failed diff --git a/pkg/repo/repo_checkout.go b/pkg/repo/repo_checkout.go index 97745fb..e66b8d6 100644 --- a/pkg/repo/repo_checkout.go +++ b/pkg/repo/repo_checkout.go @@ -4,6 +4,7 @@ package repo import ( "context" + "errors" "fmt" "github.com/go-git/go-git/v5" @@ -31,11 +32,16 @@ func (c *Client) Checkout(ctx context.Context, authMethod transport.AuthMethod, gitOpts.Hash = plumbing.NewHash(opts.Commit) } else { tag, err := c.GetTagByVersion(opts.Version) - if err != nil { + if errors.Is(err, git.ErrTagNotFound) { + // try to get the main branch + fetchOpts.Ref = config.RefSpec("refs/heads/main:refs/heads/main") + gitOpts.Branch = "refs/heads/main" + } else if err != nil { return err + } else { + fetchOpts.Ref = config.RefSpec(fmt.Sprintf("refs/tags/%s:refs/tags/%s", tag, tag)) + gitOpts.Branch = plumbing.ReferenceName(tag) } - fetchOpts.Ref = config.RefSpec(fmt.Sprintf("refs/tags/%s:refs/tags/%s", tag, tag)) - gitOpts.Branch = plumbing.ReferenceName(tag) } if err := c.Fetch(ctx, authMethod, fetchOpts); err != nil { diff --git a/tests/chart/values.yaml b/tests/chart/values.yaml deleted file mode 100644 index e69de29..0000000 diff --git a/tests/chart/Chart.yaml b/tests/data/chart/Chart.yaml similarity index 100% rename from tests/chart/Chart.yaml rename to tests/data/chart/Chart.yaml diff --git a/tests/chart/templates/test_values.yaml b/tests/data/chart/templates/test_values.yaml similarity index 71% rename from tests/chart/templates/test_values.yaml rename to tests/data/chart/templates/test_values.yaml index 5633a47..604e926 100644 --- a/tests/chart/templates/test_values.yaml +++ b/tests/data/chart/templates/test_values.yaml @@ -8,3 +8,9 @@ {{ .Chart.Description }} {{ .Chart.Version }} {{ .Chart.AppVersion }} + +# default values +{{ .Values.default.string }} + +# user values from file +{{ .Values.file.string }} diff --git a/tests/data/chart/values.yaml b/tests/data/chart/values.yaml new file mode 100644 index 0000000..1a21eee --- /dev/null +++ b/tests/data/chart/values.yaml @@ -0,0 +1,2 @@ +default: + string: test \ No newline at end of file diff --git a/tests/data/values.yaml b/tests/data/values.yaml new file mode 100644 index 0000000..3657440 --- /dev/null +++ b/tests/data/values.yaml @@ -0,0 +1,2 @@ +file: + string: test \ No newline at end of file diff --git a/tests/integration/integration_test.go b/tests/integration/integration_test.go new file mode 100644 index 0000000..6ed4573 --- /dev/null +++ b/tests/integration/integration_test.go @@ -0,0 +1,75 @@ +package integration + +import ( + "bytes" + "context" + "strings" + "testing" + + "github.com/stretchr/testify/assert" + cmd "github.com/yp05327/teachart/cmd/teachart" + "github.com/yp05327/teachart/pkg/app" + "github.com/yp05327/teachart/pkg/options" +) + +func TestRepo(t *testing.T) { + ctx := context.Background() + + var out bytes.Buffer + c := cmd.NewRepoCmd(ctx, options.NewGlobalOptions(app.DefaultRepoDir)) + c.SetOut(&out) + + tests := []struct { + args string + expected string + }{ + { + // list without repos exist + args: "list", + expected: "no repositories. use `repo add` to add repos", + }, + { + // add a repo + args: "add test https://github.com/TeaChart/gitea", + expected: "adding repo `test` from https://github.com/TeaChart/gitea", + }, + { + // list repo + args: "list", + expected: "NAME\tURL \ntest\thttps://github.com/TeaChart/gitea", + }, { + // remove the repo + args: "remove test", + expected: "repo test removed", + }, + } + + for _, tt := range tests { + c.SetArgs(strings.Split(tt.args, " ")) + err := c.Execute() + assert.NoError(t, err) + length := len(out.String()) + assert.Less(t, 0, length) + assert.Equal(t, tt.expected, out.String()[:length-1]) + out.Reset() + } +} + +func TestInstallAndUninstall(t *testing.T) { + ctx := context.Background() + + c, err := cmd.NewRootCmd(ctx, options.NewGlobalOptions(app.DefaultRepoDir)) + assert.NoError(t, err) + + tests := []string{ + "repo add test https://github.com/TeaChart/gitea", + "install test", + "uninstall", + } + + for _, tt := range tests { + c.SetArgs(strings.Split(tt, " ")) + err := c.Execute() + assert.NoError(t, err) + } +} diff --git a/tests/values.yaml b/tests/values.yaml deleted file mode 100644 index e69de29..0000000