blob: 14ff025720e73258c6b1c8be7dc90ddba36de624 [file] [log] [blame]
package cloud
import (
"context"
"strings"
"testing"
"github.com/hashicorp/go-tfe"
)
type testIntegrationOutput struct {
ctx *IntegrationContext
output *strings.Builder
t *testing.T
}
var _ IntegrationOutputWriter = (*testIntegrationOutput)(nil) // Compile time check
func (s *testIntegrationOutput) End() {
s.output.WriteString("END\n")
}
func (s *testIntegrationOutput) SubOutput(str string) {
s.output.WriteString(s.ctx.B.Colorize().Color("[reset]│ "+str) + "\n")
}
func (s *testIntegrationOutput) Output(str string) {
s.output.WriteString(s.ctx.B.Colorize().Color("[reset]│ ") + str + "\n")
}
func (s *testIntegrationOutput) OutputElapsed(message string, maxMessage int) {
s.output.WriteString("PENDING MESSAGE: " + message)
}
func newMockIntegrationContext(b *Cloud, t *testing.T) (*IntegrationContext, *testIntegrationOutput) {
ctx := context.Background()
// Retrieve the workspace used to run this operation in.
w, err := b.client.Workspaces.Read(ctx, b.organization, b.WorkspaceMapping.Name)
if err != nil {
t.Fatalf("error retrieving workspace: %v", err)
}
// Create a new configuration version.
c, err := b.client.ConfigurationVersions.Create(ctx, w.ID, tfe.ConfigurationVersionCreateOptions{})
if err != nil {
t.Fatalf("error creating configuration version: %v", err)
}
// Create a pending run to block this run.
r, err := b.client.Runs.Create(ctx, tfe.RunCreateOptions{
ConfigurationVersion: c,
Workspace: w,
})
if err != nil {
t.Fatalf("error creating pending run: %v", err)
}
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
defer configCleanup()
defer done(t)
integrationContext := &IntegrationContext{
B: b,
StopContext: ctx,
CancelContext: ctx,
Op: op,
Run: r,
}
return integrationContext, &testIntegrationOutput{
ctx: integrationContext,
output: &strings.Builder{},
t: t,
}
}
func TestCloud_runTasksWithTaskResults(t *testing.T) {
b, bCleanup := testBackendWithName(t)
defer bCleanup()
integrationContext, writer := newMockIntegrationContext(b, t)
cases := map[string]struct {
taskStage func() *tfe.TaskStage
context *IntegrationContext
writer *testIntegrationOutput
expectedOutputs []string
isError bool
}{
"all-succeeded": {
taskStage: func() *tfe.TaskStage {
ts := &tfe.TaskStage{}
ts.TaskResults = []*tfe.TaskResult{
{ID: "1", TaskName: "Mandatory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "mandatory"},
{ID: "2", TaskName: "Advisory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "advisory"},
}
return ts
},
writer: writer,
context: integrationContext,
expectedOutputs: []string{"Overall Result: Passed\n"},
isError: false,
},
"mandatory-failed": {
taskStage: func() *tfe.TaskStage {
ts := &tfe.TaskStage{}
ts.TaskResults = []*tfe.TaskResult{
{ID: "1", TaskName: "Mandatory", Message: "500 Error", Status: "failed", WorkspaceTaskEnforcementLevel: "mandatory"},
{ID: "2", TaskName: "Advisory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "advisory"},
}
return ts
},
writer: writer,
context: integrationContext,
expectedOutputs: []string{"Passed\n", "A-OK\n", "Overall Result: Failed\n"},
isError: true,
},
"advisory-failed": {
taskStage: func() *tfe.TaskStage {
ts := &tfe.TaskStage{}
ts.TaskResults = []*tfe.TaskResult{
{ID: "1", TaskName: "Mandatory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "mandatory"},
{ID: "2", TaskName: "Advisory", Message: "500 Error", Status: "failed", WorkspaceTaskEnforcementLevel: "advisory"},
}
return ts
},
writer: writer,
context: integrationContext,
expectedOutputs: []string{"Failed (Advisory)", "Overall Result: Passed with advisory failure"},
isError: false,
},
"unreachable": {
taskStage: func() *tfe.TaskStage {
ts := &tfe.TaskStage{}
ts.TaskResults = []*tfe.TaskResult{
{ID: "1", TaskName: "Mandatory", Message: "", Status: "unreachable", WorkspaceTaskEnforcementLevel: "mandatory"},
{ID: "2", TaskName: "Advisory", Message: "", Status: "unreachable", WorkspaceTaskEnforcementLevel: "advisory"},
}
return ts
},
writer: writer,
context: integrationContext,
expectedOutputs: []string{"Skipping"},
isError: false,
},
}
for _, c := range cases {
c.writer.output.Reset()
trs := taskResultSummarizer{
cloud: b,
}
c.context.Poll(0, 0, func(i int) (bool, error) {
cont, _, _ := trs.Summarize(c.context, c.writer, c.taskStage())
if cont {
return true, nil
}
output := c.writer.output.String()
for _, expected := range c.expectedOutputs {
if !strings.Contains(output, expected) {
t.Fatalf("Expected output to contain '%s' but it was:\n\n%s", expected, output)
}
}
return false, nil
})
}
}