From 5f895270493d07c7782875e0a11e30af0c05491f Mon Sep 17 00:00:00 2001 From: Luke Kysow <1034429+lkysow@users.noreply.github.com> Date: Fri, 7 Dec 2018 10:15:42 -0600 Subject: [PATCH] Return plan output on error. If terraform plan returns an error, we still want to print the output to the pull request. --- server/events/runtime/plan_step_runner.go | 2 +- .../events/runtime/plan_step_runner_test.go | 61 ++++++++++++++++++- 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/server/events/runtime/plan_step_runner.go b/server/events/runtime/plan_step_runner.go index 3a393cdc5..b731544e0 100644 --- a/server/events/runtime/plan_step_runner.go +++ b/server/events/runtime/plan_step_runner.go @@ -39,7 +39,7 @@ func (p *PlanStepRunner) Run(ctx models.ProjectCommandContext, extraArgs []strin planCmd := p.buildPlanCmd(ctx, extraArgs, path) output, err := p.TerraformExecutor.RunCommandWithVersion(ctx.Log, filepath.Clean(path), planCmd, tfVersion, ctx.Workspace) if err != nil { - return "", err + return output, err } return p.fmtPlanOutput(output), nil } diff --git a/server/events/runtime/plan_step_runner_test.go b/server/events/runtime/plan_step_runner_test.go index d2f5c41bf..7e5556758 100644 --- a/server/events/runtime/plan_step_runner_test.go +++ b/server/events/runtime/plan_step_runner_test.go @@ -536,8 +536,19 @@ Terraform will perform the following actions: AnyStringSlice(), matchers2.AnyPtrToGoVersionVersion(), AnyString())). - ThenReturn(rawOutput, nil) - actOutput, err := s.Run(models.ProjectCommandContext{}, nil, "") + Then(func(params []Param) ReturnValues { + // This code allows us to return different values depending on the + // tf command being run while still using the wildcard matchers above. + tfArgs := params[2].([]string) + if stringSliceEquals(tfArgs, []string{"workspace", "show"}) { + return []ReturnValue{"default", nil} + } else if tfArgs[0] == "plan" { + return []ReturnValue{rawOutput, nil} + } else { + return []ReturnValue{"", errors.New("unexpected call to RunCommandWithVersion")} + } + }) + actOutput, err := s.Run(models.ProjectCommandContext{Workspace: "default"}, nil, "") Ok(t, err) Equals(t, ` An execution plan has been generated and is shown below. @@ -560,3 +571,49 @@ Terraform will perform the following actions: - aws_security_group_rule.allow_all `, actOutput) } + +// Test that even if there's an error, we get the returned output. +func TestRun_OutputOnErr(t *testing.T) { + RegisterMockTestingT(t) + terraform := mocks.NewMockClient() + tfVersion, _ := version.NewVersion("0.10.0") + s := runtime.PlanStepRunner{ + TerraformExecutor: terraform, + DefaultTFVersion: tfVersion, + } + expOutput := "expected output" + expErrMsg := "error!" + When(terraform.RunCommandWithVersion( + matchers.AnyPtrToLoggingSimpleLogger(), + AnyString(), + AnyStringSlice(), + matchers2.AnyPtrToGoVersionVersion(), + AnyString())). + Then(func(params []Param) ReturnValues { + // This code allows us to return different values depending on the + // tf command being run while still using the wildcard matchers above. + tfArgs := params[2].([]string) + if stringSliceEquals(tfArgs, []string{"workspace", "show"}) { + return []ReturnValue{"default\n", nil} + } else if tfArgs[0] == "plan" { + return []ReturnValue{expOutput, errors.New(expErrMsg)} + } else { + return []ReturnValue{"", errors.New("unexpected call to RunCommandWithVersion")} + } + }) + actOutput, actErr := s.Run(models.ProjectCommandContext{Workspace: "default"}, nil, "") + ErrEquals(t, expErrMsg, actErr) + Equals(t, expOutput, actOutput) +} + +func stringSliceEquals(a, b []string) bool { + if len(a) != len(b) { + return false + } + for i, v := range a { + if v != b[i] { + return false + } + } + return true +}