From 32995b8d9a9b58f4a8e7371896d6f7af58315638 Mon Sep 17 00:00:00 2001 From: Tiago de Bem Natel de Moura Date: Fri, 7 Jan 2022 12:50:03 +0000 Subject: [PATCH] refactor: make e2e tests use terramate binary (#145) --- Makefile | 4 +- cmd/terramate/cli/cli.go | 278 +++++++++++++--------- cmd/terramate/cli/cli_main_test.go | 102 ++++++++ cmd/terramate/cli/cli_order_test.go | 28 +-- cmd/terramate/cli/cli_run_test.go | 70 +++--- cmd/terramate/cli/cli_runner_test.go | 139 +++++++++++ cmd/terramate/cli/cli_stacks_init_test.go | 64 ++--- cmd/terramate/cli/cli_stacks_list_test.go | 22 +- cmd/terramate/cli/cli_test.go | 109 ++------- cmd/terramate/cli/stacks_globals_test.go | 8 +- cmd/terramate/main.go | 6 +- 11 files changed, 521 insertions(+), 309 deletions(-) create mode 100644 cmd/terramate/cli/cli_main_test.go create mode 100644 cmd/terramate/cli/cli_runner_test.go diff --git a/Makefile b/Makefile index 113a7f710..31eb17aa2 100644 --- a/Makefile +++ b/Makefile @@ -41,7 +41,7 @@ mod: ## generates coverage report .PHONY: coverage coverage: - go test -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... ./... + go test -count=1 -coverprofile=$(COVERAGE_REPORT) -coverpkg=./... ./... ## generates coverage report and shows it on the browser locally .PHONY: coverage/show @@ -51,7 +51,7 @@ coverage/show: coverage ## test code .PHONY: test test: - go test -race ./... + go test -count=1 -race ./... ## Build terramate into bin directory .PHONY: build diff --git a/cmd/terramate/cli/cli.go b/cmd/terramate/cli/cli.go index 970c5b7a4..154814332 100644 --- a/cmd/terramate/cli/cli.go +++ b/cmd/terramate/cli/cli.go @@ -100,33 +100,27 @@ type cliSpec struct { InstallCompletions kongplete.InstallCompletions `cmd:"" help:"install shell completions"` } -// Run will run terramate with the provided flags defined on args from the -// directory wd. +// Exec will execute terramate with the provided flags defined on args. // Only flags should be on the args slice. -// Results will be written on stdout, according to the -// command flags. Any partial/non-critical errors will be -// written on stderr. +// Results will be written on stdout, according to the command flags and +// errors/warnings written on stderr. Exec will abort the process with a status +// code different than zero in the case of fatal errors. // -// Sometimes sub commands may be executed, the provided stdin -// will be passed to then as the sub process stdin. +// Sometimes sub commands may be executed, the provided stdin will be passed to +// then as the sub process stdin. // -// Each Run call is completely isolated from each other (no shared state) -// as far as the parameters are not shared between the Run calls. -// -// If a critical error is found an non-nil error is returned. -func Run( +// Each Exec call is completely isolated from each other (no shared state) as +// far as the parameters are not shared between the run calls. +func Exec( args []string, inheritEnv bool, stdin io.Reader, stdout io.Writer, stderr io.Writer, -) error { - c, err := newCLI(args, inheritEnv, stdin, stdout, stderr) - if err != nil { - return err - } - return c.run() +) { + c := newCLI(args, inheritEnv, stdin, stdout, stderr) + c.run() } type project struct { @@ -154,12 +148,16 @@ func newCLI( stdin io.Reader, stdout io.Writer, stderr io.Writer, -) (*cli, error) { +) *cli { if len(args) == 0 { // WHY: avoid default kong error, print help args = []string{"--help"} } + logger := log.With(). + Str("action", "newCli()"). + Logger() + kongExit := false kongExitStatus := 0 @@ -180,7 +178,9 @@ func newCLI( ) if err != nil { - return nil, fmt.Errorf("failed to create cli parser: %v", err) + logger.Fatal(). + Err(err). + Msg("failed to create cli parser") } kongplete.Complete(parser, @@ -190,11 +190,13 @@ func newCLI( ctx, err := parser.Parse(args) if kongExit && kongExitStatus == 0 { - return &cli{exit: true}, nil + return &cli{exit: true} } if err != nil { - return nil, fmt.Errorf("failed to parse cli args %v: %v", args, err) + logger.Fatal(). + Err(err). + Msgf("failed to parse cli args: %v", args) } logLevel := parsedArgs.LogLevel @@ -202,63 +204,76 @@ func newCLI( configureLogging(logLevel, logFmt, stderr) - log.Trace(). - Str("action", "newCli()"). + logger.Trace(). Msg("Get working directory.") wd := parsedArgs.Chdir if wd == "" { wd, err = os.Getwd() if err != nil { - return nil, fmt.Errorf("failed to get working directory: %w", err) + logger.Fatal(). + Err(err). + Msg("failed to get working directory") } } - logger := log.With(). - Str("action", "newCli()"). - Str("stack", wd). - Logger() - logger.Trace(). - Msgf("Evaluate symbolic links for %q.", wd) - wd, err = filepath.EvalSymlinks(wd) + Str("wd", wd). + Msg("Get absolute filepath for working dir") + wd, err = filepath.Abs(wd) if err != nil { - return nil, fmt.Errorf("failed evaluating symlinks for %q: %w", wd, err) + logger.Fatal(). + Str("wd", wd). + Err(err). + Msg("getting absolute path") } logger.Trace(). - Msgf("Get absolute file path of %q.", wd) - wd, err = filepath.Abs(wd) + Msgf("Evaluate symbolic links for %q.", wd) + wd, err = filepath.EvalSymlinks(wd) if err != nil { - return nil, fmt.Errorf("getting absolute path of %q: %w", wd, err) + logger.Fatal(). + Str("wd", wd). + Err(err). + Msg("failed evaluating symlinks") } logger.Trace(). Msgf("Change working directory to %q.", wd) err = os.Chdir(wd) if err != nil { - return nil, fmt.Errorf("failed to change working directory to %q: %w", wd, err) + logger.Fatal(). + Str("wd", wd). + Err(err). + Msg("failed to change working directory") } logger.Trace(). Msgf("Look up project in %q.", wd) prj, foundRoot, err := lookupProject(wd) if err != nil { - return nil, fmt.Errorf("failed to lookup project root from %q: %w", wd, err) + logger.Fatal(). + Str("wd", wd). + Err(err). + Msg("failed to lookup project root") } if !foundRoot { - return nil, fmt.Errorf("project root not found") + logger.Fatal(). + Msg("project root not found") } logger.Trace(). Msg("Set defaults from parsed command line arguments.") err = prj.setDefaults(&parsedArgs) if err != nil { - return nil, fmt.Errorf("setting configuration: %w", err) + logger.Fatal(). + Err(err). + Msg("setting configuration") } if parsedArgs.Changed && !prj.isRepo { - return nil, fmt.Errorf("flag --changed provided but no git repository found") + logger.Fatal(). + Msg("flag --changed provided but no git repository found") } return &cli{ @@ -269,13 +284,13 @@ func newCLI( parsedArgs: &parsedArgs, ctx: ctx, prj: prj, - }, nil + } } -func (c *cli) run() error { +func (c *cli) run() { if c.exit { // WHY: parser called exit but with no error (like help) - return nil + return } logger := log.With(). @@ -291,19 +306,25 @@ func (c *cli) run() error { Msg("Create new git wrapper.") git, err := newGit(c.root(), c.inheritEnv, true) if err != nil { - return err + log.Fatal(). + Err(err). + Msg("creating git wrapper.") } logger.Trace(). Msg("Check git default remote.") if err := c.checkDefaultRemote(git); err != nil { - return err + log.Fatal(). + Err(err). + Msg("Checking git default remote.") } logger.Trace(). Msg("Check git default branch was updated.") if err := c.checkLocalDefaultIsUpdated(git); err != nil { - return err + log.Fatal(). + Err(err). + Msg("checking git default branch was updated.") } } @@ -319,68 +340,78 @@ func (c *cli) run() error { Str("actionContext", "cli()"). Str("stack", c.wd()). Msg("Handle `plan graph`.") - return c.generateGraph() + c.generateGraph() case "plan run-order": log.Trace(). Str("actionContext", "cli()"). Str("stack", c.wd()). Msg("Print run-order.") - return c.printRunOrder() + c.printRunOrder() case "stacks init": log.Trace(). Str("actionContext", "cli()"). Str("stack", c.wd()). Msg("Handle stacks init command.") - return c.initStack([]string{c.wd()}) + c.initStack([]string{c.wd()}) case "stacks list": log.Trace(). Str("actionContext", "cli()"). Str("stack", c.wd()). Msg("Print list of stacks.") - return c.printStacks() + c.printStacks() case "stacks init ": log.Trace(). Str("actionContext", "cli()"). Str("stack", c.wd()). Msg("Handle stacks init command.") - return c.initStack(c.parsedArgs.Stacks.Init.StackDirs) + c.initStack(c.parsedArgs.Stacks.Init.StackDirs) case "stacks globals": log.Trace(). Str("actionContext", "cli()"). Str("stack", c.wd()). Msg("Handle stacks global command.") - return c.printStacksGlobals() + c.printStacksGlobals() case "run": logger.Debug(). Msg("Handle `run` command.") if len(c.parsedArgs.Run.Command) == 0 { - return errors.New("no command specified") + log.Fatal(). + Msg("no command specified") } fallthrough case "run ": logger.Debug(). Msg("Handle `run ` command.") - return c.runOnStacks() + c.runOnStacks() case "generate": logger.Debug(). Msg("Handle `generate` command.") - return generate.Do(c.root()) + err := generate.Do(c.root()) + if err != nil { + log.Fatal(). + Err(err). + Msg("generating code.") + } case "metadata": logger.Debug(). Msg("Handle `metadata` command.") - return c.printMetadata() + c.printMetadata() case "install-completions": logger.Debug(). Msg("Handle `install-completions` command.") - return c.parsedArgs.InstallCompletions.Run(c.ctx) + err := c.parsedArgs.InstallCompletions.Run(c.ctx) + if err != nil { + log.Fatal(). + Err(err). + Msg("installing shell completions.") + } default: - return fmt.Errorf("unexpected command sequence: %s", c.ctx.Command()) + log.Fatal(). + Msgf("unexpected command sequence: %s", c.ctx.Command()) } - - return nil } -func (c *cli) initStack(dirs []string) error { +func (c *cli) initStack(dirs []string) { var errmsgs []string logger := log.With(). @@ -409,10 +440,10 @@ func (c *cli) initStack(dirs []string) error { } if len(errmsgs) > 0 { - return ErrInit + log.Fatal(). + Err(ErrInit). + Send() } - - return nil } func (c *cli) listStacks(mgr *terramate.Manager, isChanged bool) ([]terramate.Entry, error) { @@ -426,7 +457,7 @@ func (c *cli) listStacks(mgr *terramate.Manager, isChanged bool) ([]terramate.En return mgr.List() } -func (c *cli) printStacks() error { +func (c *cli) printStacks() { logger := log.With(). Str("action", "printStacks()"). Logger() @@ -441,7 +472,8 @@ func (c *cli) printStacks() error { Msg("Get stack list.") entries, err := c.listStacks(mgr, c.parsedArgs.Changed) if err != nil { - return err + logger.Fatal(). + Err(err) } logger.Trace(). @@ -464,10 +496,9 @@ func (c *cli) printStacks() error { c.log(stackRepr) } } - return nil } -func (c *cli) generateGraph() error { +func (c *cli) generateGraph() { var getLabel func(s stack.S) string logger := log.With(). @@ -487,11 +518,14 @@ func (c *cli) generateGraph() error { Msg("Set label stack directory.") getLabel = func(s stack.S) string { return s.Dir } default: - return fmt.Errorf("-label expects the values \"stack.name\" or \"stack.dir\"") + logger.Fatal(). + Msg("-label expects the values \"stack.name\" or \"stack.dir\"") } entries, err := terramate.ListStacks(c.root()) if err != nil { - return err + logger.Fatal(). + Err(err). + Msg("listing stacks.") } logger.Debug(). @@ -508,20 +542,21 @@ func (c *cli) generateGraph() error { err := terramate.BuildDAG(graph, c.root(), e.Stack, loader, visited) if err != nil { - return fmt.Errorf("failed to build order tree: %w", err) + log.Fatal(). + Err(err). + Msg("failed to build order tree") } } for _, id := range graph.IDs() { val, err := graph.Node(id) if err != nil { - return fmt.Errorf("generating graph: %w", err) + log.Fatal(). + Err(err). + Msg("generating graph") } - err = generateDot(dotGraph, graph, id, val.(stack.S), getLabel) - if err != nil { - return err - } + generateDot(dotGraph, graph, id, val.(stack.S), getLabel) } logger.Debug(). @@ -537,7 +572,10 @@ func (c *cli) generateGraph() error { Msg("Set output to file.") f, err := os.Create(outFile) if err != nil { - return fmt.Errorf("opening file %q: %w", outFile, err) + log.Fatal(). + Str("path", outFile). + Err(err). + Msg("opening file") } defer f.Close() @@ -549,10 +587,11 @@ func (c *cli) generateGraph() error { Msg("Write graph to output.") _, err = out.Write([]byte(dotGraph.String())) if err != nil { - return fmt.Errorf("writing output to %q: %w", outFile, err) + log.Fatal(). + Str("path", outFile). + Err(err). + Msg("writing output") } - - return nil } func generateDot( @@ -561,12 +600,18 @@ func generateDot( id dag.ID, stackval stack.S, getLabel func(s stack.S) string, -) error { +) { + logger := log.With(). + Str("action", "generateDot()"). + Logger() + parent := dotGraph.Node(getLabel(stackval)) for _, childid := range graph.ChildrenOf(id) { val, err := graph.Node(childid) if err != nil { - return fmt.Errorf("generating dot file: %w", err) + logger.Fatal(). + Err(err). + Msg("generating dot file") } s := val.(stack.S) n := dotGraph.Node(getLabel(s)) @@ -584,15 +629,11 @@ func generateDot( continue } - err = generateDot(dotGraph, graph, childid, s, getLabel) - if err != nil { - return err - } + generateDot(dotGraph, graph, childid, s, getLabel) } - return nil } -func (c *cli) printRunOrder() error { +func (c *cli) printRunOrder() { logger := log.With(). Str("action", "printRunOrder()"). Str("stack", c.wd()). @@ -606,7 +647,8 @@ func (c *cli) printRunOrder() error { Msg("Get list of stacks.") entries, err := c.listStacks(mgr, c.parsedArgs.Changed) if err != nil { - return err + logger.Fatal(). + Err(err) } logger.Trace(). @@ -625,33 +667,41 @@ func (c *cli) printRunOrder() error { order, reason, err := terramate.RunOrder(c.root(), stacks, c.parsedArgs.Changed) if err != nil { if errors.Is(err, dag.ErrCycleDetected) { - return fmt.Errorf("%w: reason is %s", err, reason) + log.Fatal(). + Err(err). + Str("reason", reason). + Msg("running on order") } else { - return fmt.Errorf("failed to plan execution: %w", err) + log.Fatal(). + Err(err). + Msg("failed to plan execution") } } for _, s := range order { c.log("%s", s) } - - return nil } -func (c *cli) printStacksGlobals() error { +func (c *cli) printStacksGlobals() { + log := log.With(). + Str("action", "printStacksGlobals()"). + Logger() + metadata, err := terramate.LoadMetadata(c.root()) if err != nil { - return fmt.Errorf("listing stacks globals: loading stacks metadata: %v", err) + log.Fatal(). + Err(err). + Msg("listing stacks globals: loading stacks metadata") } for _, stackMetadata := range metadata.Stacks { globals, err := terramate.LoadStackGlobals(c.root(), stackMetadata) if err != nil { - return fmt.Errorf( - "listing stacks globals: loading stack %q globals: %v", - stackMetadata.Path, - err, - ) + log.Fatal(). + Err(err). + Str("stack", stackMetadata.Path). + Msg("listing stacks globals: loading stack") } globalsStrRepr := globals.String() @@ -664,10 +714,9 @@ func (c *cli) printStacksGlobals() error { c.log("\t%s", line) } } - return nil } -func (c *cli) printMetadata() error { +func (c *cli) printMetadata() { logger := log.With(). Str("action", "printMetadata()"). Logger() @@ -677,7 +726,8 @@ func (c *cli) printMetadata() error { Msg("Load metadata.") metadata, err := terramate.LoadMetadata(c.root()) if err != nil { - return err + logger.Fatal(). + Err(err) } logger.Trace(). @@ -693,11 +743,9 @@ func (c *cli) printMetadata() error { c.log("\tterramate.name=%q", stack.Name) c.log("\tterramate.path=%q", stack.Path) } - - return nil } -func (c *cli) runOnStacks() error { +func (c *cli) runOnStacks() { logger := log.With(). Str("action", "runOnStacks()"). Str("stack", c.wd()). @@ -711,7 +759,8 @@ func (c *cli) runOnStacks() error { Msg("Get list of stacks.") entries, err := c.listStacks(mgr, c.parsedArgs.Changed) if err != nil { - return err + logger.Fatal(). + Err(err) } if c.parsedArgs.Changed { @@ -745,9 +794,14 @@ func (c *cli) runOnStacks() error { order, reason, err := terramate.RunOrder(c.root(), stacks, c.parsedArgs.Changed) if err != nil { if errors.Is(err, dag.ErrCycleDetected) { - return fmt.Errorf("%w: reason is %s", err, reason) + logger.Fatal(). + Str("reason", reason). + Err(err). + Msg("running in order") } else { - return fmt.Errorf("failed to plan execution: %w", err) + log.Fatal(). + Err(err). + Msg("failed to plan execution") } } @@ -765,7 +819,7 @@ func (c *cli) runOnStacks() error { c.log("No stacks will be executed.") } - return nil + return } logger.Debug(). @@ -774,8 +828,6 @@ func (c *cli) runOnStacks() error { if err != nil { c.logerr("warn: failed to execute command: %v", err) } - - return nil } func (c *cli) wd() string { return c.prj.wd } diff --git a/cmd/terramate/cli/cli_main_test.go b/cmd/terramate/cli/cli_main_test.go new file mode 100644 index 000000000..db91fc9fa --- /dev/null +++ b/cmd/terramate/cli/cli_main_test.go @@ -0,0 +1,102 @@ +// Copyright 2022 Mineiros GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli_test + +import ( + "fmt" + "log" + "os" + "os/exec" + "path/filepath" + "runtime" + "testing" +) + +var terramateTestBin string + +// The TestMain function creates a terramate binary for testing purposes and +// deletes it after the tests have been run. +func TestMain(m *testing.M) { + os.Exit(setupAndRunTests(m)) +} + +func setupAndRunTests(m *testing.M) (status int) { + binTmpdir, err := os.MkdirTemp("", "cmd-terramate-test-") + if err != nil { + log.Fatal(err) + } + + defer os.RemoveAll(binTmpdir) + + goBin, err := lookupGoBin() + if err != nil { + log.Printf("failed to setup e2e tests: %v", err) + return 1 + } + + packageDir, err := os.Getwd() + if err != nil { + log.Printf("failed to get test working directory: %v", err) + return 1 + } + + // this file is inside cmd/terramate/cli + // change code below if it's not the case anymore. + projectRoot := filepath.Join(packageDir, "../../..") + terramateTestBin, err = buildTerramate(goBin, projectRoot, binTmpdir) + if err != nil { + log.Printf("failed to setup e2e tests: %v", err) + return 1 + } + + return m.Run() +} + +func buildTerramate(goBin string, projectRoot string, binDir string) (string, error) { + outBinPath := filepath.Join(binDir, "terramate"+platExeSuffix()) + cmd := exec.Command( + goBin, + "build", + "-o", + outBinPath, + filepath.Join(projectRoot, "cmd/terramate"), + ) + + out, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("failed to build terramate: %v (output: %s)", err, string(out)) + } + return outBinPath, nil +} + +func lookupGoBin() (string, error) { + exeSuffix := platExeSuffix() + path := filepath.Join(runtime.GOROOT(), "bin", "go"+exeSuffix) + if _, err := os.Stat(path); err == nil { + return path, nil + } + goBin, err := exec.LookPath("go" + exeSuffix) + if err != nil { + return "", fmt.Errorf("cannot find go tool: %v", err.Error()) + } + return goBin, nil +} + +func platExeSuffix() string { + if runtime.GOOS == "windows" { + return ".exe" + } + return "" +} diff --git a/cmd/terramate/cli/cli_order_test.go b/cmd/terramate/cli/cli_order_test.go index f6ebb4922..0aadf4f65 100644 --- a/cmd/terramate/cli/cli_order_test.go +++ b/cmd/terramate/cli/cli_order_test.go @@ -25,7 +25,7 @@ func TestOrderGraphAfter(t *testing.T) { type testcase struct { name string layout []string - want runResult + want runExpected } for _, tc := range []testcase{ @@ -34,7 +34,7 @@ func TestOrderGraphAfter(t *testing.T) { layout: []string{ `s:stack`, }, - want: runResult{ + want: runExpected{ Stdout: `digraph {n1[label="stack"];}`, FlattenStdout: true, }, @@ -45,7 +45,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack1`, `s:stack2`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack1"]; @@ -60,7 +60,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack:after=["../anotherstack"]`, `s:anotherstack`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="anotherstack"]; @@ -77,7 +77,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-b`, `s:stack-c`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; @@ -96,7 +96,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-b:after=["../stack-c"]`, `s:stack-c`, }, - want: runResult{ + want: runExpected{ Stdout: `digraph { n1[label="stack-a"]; n2[label="stack-b"]; @@ -120,7 +120,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-g`, `s:stack-x`, }, - want: runResult{ + want: runExpected{ Stdout: `digraph { n1[label="stack-a"]; n2[label="stack-b"]; @@ -148,7 +148,7 @@ func TestOrderGraphAfter(t *testing.T) { layout: []string{ `s:stack-a:after=["../stack-a"]`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; @@ -163,7 +163,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-a:after=["../stack-b"]`, `s:stack-b:after=["../stack-a"]`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph {n1[label="stack-a"]; n2[label="stack-b"]; @@ -180,7 +180,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-b:after=["../stack-a"]`, `s:stack-c:after=["../stack-a"]`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; @@ -203,7 +203,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-c`, `s:stack-d`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; @@ -232,7 +232,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-g`, `s:stack-h`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; @@ -261,7 +261,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-c`, `s:stack-d`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; @@ -290,7 +290,7 @@ func TestOrderGraphAfter(t *testing.T) { `s:stack-x`, `s:stack-y`, }, - want: runResult{ + want: runExpected{ Stdout: ` digraph { n1[label="stack-a"]; diff --git a/cmd/terramate/cli/cli_run_test.go b/cmd/terramate/cli/cli_run_test.go index 1cf2f4060..c7193e996 100644 --- a/cmd/terramate/cli/cli_run_test.go +++ b/cmd/terramate/cli/cli_run_test.go @@ -30,7 +30,7 @@ func TestCLIRunOrder(t *testing.T) { name string layout []string changed bool - want runResult + want runExpected } for _, tc := range []testcase{ @@ -39,7 +39,7 @@ func TestCLIRunOrder(t *testing.T) { layout: []string{ "s:stack-a", }, - want: runResult{ + want: runExpected{ Stdout: `stack-a `, }, @@ -49,7 +49,7 @@ func TestCLIRunOrder(t *testing.T) { layout: []string{ "s:stack:after=[]", }, - want: runResult{ + want: runExpected{ Stdout: `stack `, }, @@ -64,7 +64,7 @@ func TestCLIRunOrder(t *testing.T) { "s:3", "s:boom", }, - want: runResult{ + want: runExpected{ Stdout: `1 2 3 @@ -80,7 +80,7 @@ frita "s:stack-a", `s:stack-b:after=["../stack-a"]`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-a stack-b `, @@ -93,7 +93,7 @@ stack-b `s:stack-b:after=["../stack-a"]`, `s:stack-c:after=["../stack-b"]`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-a stack-b stack-c @@ -107,7 +107,7 @@ stack-c `s:stack-b:after=["../stack-c"]`, `s:stack-a:after=["../stack-b"]`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-c stack-b stack-a @@ -120,7 +120,7 @@ stack-a `s:stack-a:after=["../stack-b"]`, `s:stack-b`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-b stack-a `, @@ -134,7 +134,7 @@ stack-a `s:stack-c`, `s:stack-d`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-b stack-c stack-d @@ -151,7 +151,7 @@ stack-a `s:stack-d:after=["../stack-z"]`, `s:stack-z`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-a stack-b stack-c @@ -168,7 +168,7 @@ stack-d `s:stack-a`, `s:stack-d:after=["../stack-b"]`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-a stack-b stack-c @@ -185,7 +185,7 @@ stack-d `s:stack-z:after=["../stack-d"]`, `s:stack-d:after=["../stack-b"]`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-a stack-b stack-c @@ -204,7 +204,7 @@ stack-z `s:stack-z:after=["../stack-d"]`, `s:stack-d:after=["../stack-b"]`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-a stack-b stack-c @@ -225,7 +225,7 @@ stack-z `s:stack-g`, `s:stack-h`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-d stack-f stack-b @@ -245,7 +245,7 @@ stack-a `s:stack-c`, `s:stack-d`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-b stack-c stack-a @@ -265,7 +265,7 @@ stack-z `s:stack-x`, `s:stack-y`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-x stack-y stack-a @@ -281,9 +281,9 @@ stack-z layout: []string{ `s:stack-a:after=["../stack-a"]`, }, - want: runResult{ - Error: dag.ErrCycleDetected, - IgnoreStderr: true, + want: runExpected{ + Status: defaultErrExitStatus, + StderrRegex: dag.ErrCycleDetected.Error(), }, }, { @@ -291,9 +291,9 @@ stack-z layout: []string{ `s:stack-a:after=["."]`, }, - want: runResult{ - Error: dag.ErrCycleDetected, - IgnoreStderr: true, + want: runExpected{ + Status: defaultErrExitStatus, + StderrRegex: dag.ErrCycleDetected.Error(), }, }, { @@ -303,9 +303,9 @@ stack-z `s:stack-b:after=["../stack-c"]`, `s:stack-c:after=["../stack-a"]`, }, - want: runResult{ - Error: dag.ErrCycleDetected, - IgnoreStderr: true, + want: runExpected{ + Status: defaultErrExitStatus, + StderrRegex: dag.ErrCycleDetected.Error(), }, }, { @@ -332,9 +332,9 @@ stack-z `s:19`, `s:20:after=["../10", "../1"]`, }, - want: runResult{ - Error: dag.ErrCycleDetected, - IgnoreStderr: true, + want: runExpected{ + Status: defaultErrExitStatus, + StderrRegex: dag.ErrCycleDetected.Error(), }, }, { @@ -348,7 +348,7 @@ stack-z `s:stack-c`, `s:stack-d`, }, - want: runResult{ + want: runExpected{ Stdout: `stack-b stack-c stack-a @@ -403,7 +403,7 @@ func TestRunOrderNotChangedStackIgnored(t *testing.T) { cli := newCLI(t, s.RootDir()) wantList := stack.RelPath() + "\n" - assertRunResult(t, cli.run("stacks", "list", "--changed"), runResult{Stdout: wantList}) + assertRunResult(t, cli.run("stacks", "list", "--changed"), runExpected{Stdout: wantList}) cat := test.LookPath(t, "cat") wantRun := fmt.Sprintf( @@ -419,7 +419,7 @@ func TestRunOrderNotChangedStackIgnored(t *testing.T) { "--changed", cat, mainTfFileName, - ), runResult{Stdout: wantRun}) + ), runExpected{Stdout: wantRun}) wantRun = fmt.Sprintf( "Running on changed stacks:\n[%s] running %s %s\n%s\n", @@ -435,7 +435,7 @@ func TestRunOrderNotChangedStackIgnored(t *testing.T) { "--changed", cat, mainTfFileName, - ), runResult{Stdout: wantRun}) + ), runExpected{Stdout: wantRun}) cli = newCLI(t, stack2.Path()) assertRunResult(t, cli.run( @@ -443,7 +443,7 @@ func TestRunOrderNotChangedStackIgnored(t *testing.T) { "--changed", cat, mainTfFileName, - ), runResult{Stdout: "Running on changed stacks:\n"}) + ), runExpected{Stdout: "Running on changed stacks:\n"}) } func TestRunOrderAllChangedStacksExecuted(t *testing.T) { @@ -479,7 +479,7 @@ func TestRunOrderAllChangedStacksExecuted(t *testing.T) { cli := newCLI(t, s.RootDir()) wantList := stack.RelPath() + "\n" + stack2.RelPath() + "\n" - assertRunResult(t, cli.run("stacks", "list", "--changed"), runResult{Stdout: wantList}) + assertRunResult(t, cli.run("stacks", "list", "--changed"), runExpected{Stdout: wantList}) cat := test.LookPath(t, "cat") wantRun := fmt.Sprintf( @@ -499,5 +499,5 @@ func TestRunOrderAllChangedStacksExecuted(t *testing.T) { "--changed", cat, mainTfFileName, - ), runResult{Stdout: wantRun}) + ), runExpected{Stdout: wantRun}) } diff --git a/cmd/terramate/cli/cli_runner_test.go b/cmd/terramate/cli/cli_runner_test.go new file mode 100644 index 000000000..3f2c73f03 --- /dev/null +++ b/cmd/terramate/cli/cli_runner_test.go @@ -0,0 +1,139 @@ +// Copyright 2022 Mineiros GmbH +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package cli_test + +import ( + "bytes" + "os/exec" + "regexp" + "strings" + "testing" + + "github.com/madlambda/spells/assert" +) + +const defaultErrExitStatus = 1 + +type tscli struct { + t *testing.T + chdir string +} + +type runResult struct { + Cmd string + Stdout string + Stderr string + Status int +} + +type runExpected struct { + Stdout string + Stderr string + StdoutRegex string + StderrRegex string + + IgnoreStdout bool + IgnoreStderr bool + + FlattenStdout bool + Status int +} + +func newCLI(t *testing.T, chdir string) tscli { + return tscli{ + t: t, + chdir: chdir, + } +} + +func (ts tscli) run(args ...string) runResult { + t := ts.t + t.Helper() + + stdin := &bytes.Buffer{} + stdout := &bytes.Buffer{} + stderr := &bytes.Buffer{} + + allargs := []string{} + if ts.chdir != "" { + allargs = append(allargs, "--chdir", ts.chdir) + } + + allargs = append(allargs, args...) + + cmd := exec.Command(terramateTestBin, allargs...) + cmd.Stdout = stdout + cmd.Stderr = stderr + cmd.Stdin = stdin + + _ = cmd.Run() + + return runResult{ + Cmd: strings.Join(args, " "), + Stdout: stdout.String(), + Stderr: stderr.String(), + Status: cmd.ProcessState.ExitCode(), + } +} + +func assertRun(t *testing.T, got runResult) { + t.Helper() + + assertRunResult(t, got, runExpected{IgnoreStdout: true, IgnoreStderr: true}) +} + +func assertRunResult(t *testing.T, got runResult, want runExpected) { + t.Helper() + + if !want.IgnoreStdout { + stdout := got.Stdout + wantStdout := want.Stdout + if want.FlattenStdout { + stdout = flatten(stdout) + wantStdout = flatten(wantStdout) + } + if want.StdoutRegex != "" { + matched, err := regexp.MatchString(want.StdoutRegex, stdout) + assert.NoError(t, err, "failed to compile regex %q", want.StdoutRegex) + + if !matched { + t.Errorf("%q stdout=\"%s\" does not match regex %q", got.Cmd, + stdout, + want.StdoutRegex, + ) + } + } else { + assert.EqualStrings(t, wantStdout, stdout, "stdout mismatch") + } + } + + if !want.IgnoreStderr { + if want.StderrRegex != "" { + matched, err := regexp.MatchString(want.StderrRegex, got.Stderr) + assert.NoError(t, err, "failed to compile regex %q", want.StderrRegex) + + if !matched { + t.Errorf("%q stderr=\"%s\" does not match regex %q", got.Cmd, + got.Stderr, + want.StderrRegex, + ) + } + } else { + assert.EqualStrings(t, want.Stderr, got.Stderr, "stderr mismatch") + } + } + + assert.EqualInts(t, want.Status, got.Status, "exit status mismatch") +} diff --git a/cmd/terramate/cli/cli_stacks_init_test.go b/cmd/terramate/cli/cli_stacks_init_test.go index 40d19ed84..660461a12 100644 --- a/cmd/terramate/cli/cli_stacks_init_test.go +++ b/cmd/terramate/cli/cli_stacks_init_test.go @@ -46,7 +46,7 @@ func TestStacksInit(t *testing.T) { layout []string input []string force bool - want runResult + want runExpected } for _, tc := range []testcase{ @@ -88,9 +88,9 @@ func TestStacksInit(t *testing.T) { }, input: []string{"other-version"}, force: false, - want: runResult{ - IgnoreStderr: true, - Error: cli.ErrInit, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, { @@ -110,9 +110,9 @@ func TestStacksInit(t *testing.T) { }, input: []string{"stack1", "stack2", "other-version"}, force: false, - want: runResult{ - IgnoreStderr: true, - Error: cli.ErrInit, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, { @@ -122,9 +122,9 @@ func TestStacksInit(t *testing.T) { }, input: []string{"other-version"}, force: false, - want: runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, { @@ -142,9 +142,9 @@ func TestStacksInit(t *testing.T) { }, input: []string{"other-version"}, force: false, - want: runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, { @@ -162,9 +162,9 @@ func TestStacksInit(t *testing.T) { }, input: []string{"other-version"}, force: false, - want: runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, { @@ -181,9 +181,9 @@ func TestStacksInit(t *testing.T) { "s:other-version:version=< 0.0.1", }, input: []string{"other-version"}, - want: runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, { @@ -192,9 +192,9 @@ func TestStacksInit(t *testing.T) { "s:other-version:version=> 999.0.0", }, input: []string{"other-version"}, - want: runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + want: runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }, }, } { @@ -212,7 +212,7 @@ func TestStacksInit(t *testing.T) { } assertRunResult(t, cli.run(args...), tc.want) - if tc.want.Error != nil { + if tc.want.Status != 0 { return } @@ -236,9 +236,9 @@ func TestStacksInit(t *testing.T) { func TestInitNonExistingDir(t *testing.T) { s := sandbox.New(t) c := newCLI(t, s.RootDir()) - assertRunResult(t, c.run("stacks", "init", test.NonExistingDir(t)), runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + assertRunResult(t, c.run("stacks", "init", test.NonExistingDir(t)), runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }) } @@ -248,9 +248,9 @@ func TestInitFailInitializeChildOfStack(t *testing.T) { parent := test.Mkdir(t, s.RootDir(), "parent-stack") child := test.Mkdir(t, parent, "child-stack") assertRun(t, c.run("stacks", "init", parent)) - assertRunResult(t, c.run("stacks", "init", child), runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + assertRunResult(t, c.run("stacks", "init", child), runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }) } @@ -260,9 +260,9 @@ func TestInitFailInitializeParentOfChildStack(t *testing.T) { parent := test.Mkdir(t, s.RootDir(), "parent-stack") child := test.Mkdir(t, parent, "child-stack") assertRun(t, c.run("stacks", "init", child)) - assertRunResult(t, c.run("stacks", "init", parent), runResult{ - Error: cli.ErrInit, - IgnoreStderr: true, + assertRunResult(t, c.run("stacks", "init", parent), runExpected{ + StderrRegex: cli.ErrInit.Error(), + Status: 1, }) } diff --git a/cmd/terramate/cli/cli_stacks_list_test.go b/cmd/terramate/cli/cli_stacks_list_test.go index 8e5eb51a4..abcaca187 100644 --- a/cmd/terramate/cli/cli_stacks_list_test.go +++ b/cmd/terramate/cli/cli_stacks_list_test.go @@ -15,7 +15,6 @@ package cli_test import ( - "os" "testing" "github.com/mineiros-io/terramate/config" @@ -28,7 +27,7 @@ func TestCLIList(t *testing.T) { type testcase struct { name string layout []string - want runResult + want runExpected } for _, tc := range []testcase{ @@ -46,7 +45,7 @@ func TestCLIList(t *testing.T) { { name: "single stack", layout: []string{"s:stack"}, - want: runResult{ + want: runExpected{ Stdout: "stack\n", }, }, @@ -63,7 +62,7 @@ func TestCLIList(t *testing.T) { "d:more", "d:waste/directories", }, - want: runResult{ + want: runExpected{ Stdout: "there/is/a/very/deep/hidden/stack/here\n", }, }, @@ -72,7 +71,7 @@ func TestCLIList(t *testing.T) { layout: []string{ "s:1", "s:2", "s:3", }, - want: runResult{ + want: runExpected{ Stdout: "1\n2\n3\n", }, }, @@ -87,7 +86,7 @@ func TestCLIList(t *testing.T) { "d:something/else/uninportant", "s:3/x/y/z", }, - want: runResult{ + want: runExpected{ Stdout: `1 2 3/x/y/z @@ -115,7 +114,7 @@ func TestListStackWithNoTerramateBlock(t *testing.T) { Stack: &hcl.Stack{}, }) cli := newCLI(t, s.RootDir()) - assertRunResult(t, cli.run("stacks", "list"), runResult{Stdout: "stack\n"}) + assertRunResult(t, cli.run("stacks", "list"), runExpected{Stdout: "stack\n"}) } func TestListNoSuchFile(t *testing.T) { @@ -123,8 +122,9 @@ func TestListNoSuchFile(t *testing.T) { cli := newCLI(t, notExists) // errors from the manager are not logged in stderr - assertRunResult(t, cli.run("stacks", "list"), runResult{ - Error: os.ErrNotExist, + assertRunResult(t, cli.run("stacks", "list"), runExpected{ + Status: 1, + StderrRegex: "no such file or directory", }) } @@ -148,7 +148,7 @@ func TestListDetectChangesInSubDirOfStack(t *testing.T) { git.Add(stack.Path()) git.Commit("stack changed") - want := runResult{ + want := runExpected{ Stdout: stack.RelPath() + "\n", } assertRunResult(t, cli.run("stacks", "list", "--changed"), want) @@ -181,7 +181,7 @@ terramate { git.Add(stack.Path()) git.Commit("stack changed") - want := runResult{ + want := runExpected{ Stdout: stack.RelPath() + "\n", } assertRunResult(t, cli.run("stacks", "list", "--changed"), want) diff --git a/cmd/terramate/cli/cli_test.go b/cmd/terramate/cli/cli_test.go index 155d738c2..a9ec83d42 100644 --- a/cmd/terramate/cli/cli_test.go +++ b/cmd/terramate/cli/cli_test.go @@ -15,10 +15,7 @@ package cli_test import ( - "bytes" - "errors" "fmt" - "strings" "testing" "github.com/mineiros-io/terramate/cmd/terramate/cli" @@ -69,7 +66,7 @@ source = "%s" cli := newCLI(t, s.RootDir()) want := stack1.RelPath() + "\n" - assertRunResult(t, cli.run("stacks", "list", "--changed"), runResult{Stdout: want}) + assertRunResult(t, cli.run("stacks", "list", "--changed"), runExpected{Stdout: want}) } func TestBugModuleMultipleFilesSameDir(t *testing.T) { @@ -128,7 +125,7 @@ module "mod1" { cli := newCLI(t, s.RootDir()) want := stack.RelPath() + "\n" - assertRunResult(t, cli.run("stacks", "list", "--changed"), runResult{Stdout: want}) + assertRunResult(t, cli.run("stacks", "list", "--changed"), runExpected{Stdout: want}) } func TestListAndRunChangedStack(t *testing.T) { @@ -154,7 +151,7 @@ func TestListAndRunChangedStack(t *testing.T) { git.CommitAll("stack changed") wantList := stack.RelPath() + "\n" - assertRunResult(t, cli.run("stacks", "list", "--changed"), runResult{Stdout: wantList}) + assertRunResult(t, cli.run("stacks", "list", "--changed"), runExpected{Stdout: wantList}) cat := test.LookPath(t, "cat") wantRun := fmt.Sprintf( @@ -170,7 +167,7 @@ func TestListAndRunChangedStack(t *testing.T) { "--changed", cat, mainTfFileName, - ), runResult{Stdout: wantRun}) + ), runExpected{Stdout: wantRun}) } func TestListAndRunChangedStackInAbsolutePath(t *testing.T) { @@ -197,7 +194,7 @@ func TestListAndRunChangedStackInAbsolutePath(t *testing.T) { git.CommitAll("stack changed") wantList := stack.Path() + "\n" - assertRunResult(t, cli.run("stacks", "list", "--changed"), runResult{Stdout: wantList}) + assertRunResult(t, cli.run("stacks", "list", "--changed"), runExpected{Stdout: wantList}) cat := test.LookPath(t, "cat") wantRun := fmt.Sprintf( @@ -213,7 +210,7 @@ func TestListAndRunChangedStackInAbsolutePath(t *testing.T) { "--changed", cat, mainTfFileName, - ), runResult{Stdout: wantRun}) + ), runExpected{Stdout: wantRun}) } func TestDefaultBaseRefInOtherThanMain(t *testing.T) { @@ -235,7 +232,7 @@ func TestDefaultBaseRefInOtherThanMain(t *testing.T) { git.Add(stack.Path()) git.Commit("stack changed") - want := runResult{ + want := runExpected{ Stdout: stack.RelPath() + "\n", } assertRunResult(t, cli.run("stacks", "list", "--changed"), want) @@ -256,7 +253,7 @@ func TestDefaultBaseRefInMain(t *testing.T) { git.Push("main") // main uses HEAD^1 as default baseRef. - want := runResult{ + want := runExpected{ Stdout: stack.RelPath() + "\n", IgnoreStderr: true, } @@ -279,7 +276,7 @@ func TestBaseRefFlagPrecedenceOverDefault(t *testing.T) { assertRunResult(t, cli.run("stacks", "list", "--changed", "--git-change-base", "origin/main"), - runResult{ + runExpected{ IgnoreStderr: true, }, ) @@ -298,9 +295,9 @@ func TestFailsOnChangeDetectionIfCurrentBranchIsMainAndItIsOutdated(t *testing.T git.Add(".") git.Commit("all") - wantRes := runResult{ - Error: cli.ErrOutdatedLocalRev, - IgnoreStderr: true, + wantRes := runExpected{ + Status: 1, + StderrRegex: cli.ErrOutdatedLocalRev.Error(), } assertRunResult(t, ts.run("stacks", "list", "--changed"), wantRes) @@ -320,9 +317,9 @@ func TestFailsOnChangeDetectionIfRepoDoesntHaveOriginMain(t *testing.T) { t.Helper() ts := newCLI(t, rootdir) - wantRes := runResult{ - Error: cli.ErrNoDefaultRemoteConfig, - IgnoreStderr: true, + wantRes := runExpected{ + Status: 1, + StderrRegex: cli.ErrNoDefaultRemoteConfig.Error(), } assertRunResult(t, ts.run("stacks", "list", "--changed"), wantRes) @@ -358,79 +355,5 @@ func TestNoArgsProvidesBasicHelp(t *testing.T) { cli := newCLI(t, "") cli.run("--help") help := cli.run("--help") - assertRunResult(t, cli.run(), runResult{Stdout: help.Stdout}) -} - -type runResult struct { - Cmd string - Stdout string - FlattenStdout bool - IgnoreStdout bool - Stderr string - IgnoreStderr bool - Error error -} - -type tscli struct { - t *testing.T - chdir string -} - -func newCLI(t *testing.T, chdir string) tscli { - return tscli{ - t: t, - chdir: chdir, - } -} - -func (ts tscli) run(args ...string) runResult { - ts.t.Helper() - - stdin := &bytes.Buffer{} - stdout := &bytes.Buffer{} - stderr := &bytes.Buffer{} - - allargs := []string{} - if ts.chdir != "" { - allargs = append(allargs, "--chdir", ts.chdir) - } - - allargs = append(allargs, args...) - err := cli.Run(allargs, false, stdin, stdout, stderr) - - return runResult{ - Cmd: strings.Join(args, " "), - Stdout: stdout.String(), - Stderr: stderr.String(), - Error: err, - } -} - -func assertRun(t *testing.T, got runResult) { - t.Helper() - - assertRunResult(t, got, runResult{IgnoreStdout: true, IgnoreStderr: true}) -} - -func assertRunResult(t *testing.T, got runResult, want runResult) { - t.Helper() - - stdout := got.Stdout - wantStdout := want.Stdout - if want.FlattenStdout { - stdout = flatten(stdout) - wantStdout = flatten(wantStdout) - } - - if !want.IgnoreStdout && stdout != wantStdout { - t.Errorf("%q stdout=\"%s\" != wanted=\"%s\"", got.Cmd, stdout, wantStdout) - } - - if !want.IgnoreStderr && got.Stderr != want.Stderr { - t.Errorf("%q stderr=\"%s\" != wanted=\"%s\"", got.Cmd, got.Stderr, want.Stderr) - } - - if !errors.Is(got.Error, want.Error) { - t.Errorf("%q got.Error=[%v] != want.Error=[%v]", got.Cmd, got.Error, want.Error) - } + assertRunResult(t, cli.run(), runExpected{Stdout: help.Stdout}) } diff --git a/cmd/terramate/cli/stacks_globals_test.go b/cmd/terramate/cli/stacks_globals_test.go index b664bbaf2..e2afbc56c 100644 --- a/cmd/terramate/cli/stacks_globals_test.go +++ b/cmd/terramate/cli/stacks_globals_test.go @@ -34,7 +34,7 @@ func TestStacksGlobals(t *testing.T) { name string layout []string globals []globalsBlock - want runResult + want runExpected } ) @@ -74,7 +74,7 @@ func TestStacksGlobals(t *testing.T) { ), }, }, - want: runResult{ + want: runExpected{ Stdout: ` stack "/stack": bool = true @@ -97,7 +97,7 @@ stack "/stack": ), }, }, - want: runResult{ + want: runExpected{ Stdout: ` stack "/stacks/stack-1": str = "string" @@ -118,7 +118,7 @@ stack "/stacks/stack-1": ), }, }, - want: runResult{ + want: runExpected{ Stdout: ` stack "/stacks/stack-1": str = "string" diff --git a/cmd/terramate/main.go b/cmd/terramate/main.go index 80e691a35..23463a86c 100644 --- a/cmd/terramate/main.go +++ b/cmd/terramate/main.go @@ -15,15 +15,11 @@ package main import ( - "log" "os" "github.com/mineiros-io/terramate/cmd/terramate/cli" ) func main() { - err := cli.Run(os.Args[1:], true, os.Stdin, os.Stdout, os.Stderr) - if err != nil { - log.Fatal(err) - } + cli.Exec(os.Args[1:], true, os.Stdin, os.Stdout, os.Stderr) }