github.com/kanishk98/terraform@v1.3.0-dev.0.20220917174235-661ca8088a6a/internal/cloud/backend_runTasks_test.go (about)

     1  package cloud
     2  
     3  import (
     4  	"context"
     5  	"strings"
     6  	"testing"
     7  
     8  	"github.com/hashicorp/go-tfe"
     9  )
    10  
    11  type testIntegrationOutput struct {
    12  	ctx    *IntegrationContext
    13  	output *strings.Builder
    14  	t      *testing.T
    15  }
    16  
    17  var _ IntegrationOutputWriter = (*testIntegrationOutput)(nil) // Compile time check
    18  
    19  func (s *testIntegrationOutput) End() {
    20  	s.output.WriteString("END\n")
    21  }
    22  
    23  func (s *testIntegrationOutput) SubOutput(str string) {
    24  	s.output.WriteString(s.ctx.B.Colorize().Color("[reset]│ "+str) + "\n")
    25  }
    26  
    27  func (s *testIntegrationOutput) Output(str string) {
    28  	s.output.WriteString(s.ctx.B.Colorize().Color("[reset]│ ") + str + "\n")
    29  }
    30  
    31  func (s *testIntegrationOutput) OutputElapsed(message string, maxMessage int) {
    32  	s.output.WriteString("PENDING MESSAGE: " + message)
    33  }
    34  
    35  func newMockIntegrationContext(b *Cloud, t *testing.T) (*IntegrationContext, *testIntegrationOutput) {
    36  	ctx := context.Background()
    37  
    38  	// Retrieve the workspace used to run this operation in.
    39  	w, err := b.client.Workspaces.Read(ctx, b.organization, b.WorkspaceMapping.Name)
    40  	if err != nil {
    41  		t.Fatalf("error retrieving workspace: %v", err)
    42  	}
    43  
    44  	// Create a new configuration version.
    45  	c, err := b.client.ConfigurationVersions.Create(ctx, w.ID, tfe.ConfigurationVersionCreateOptions{})
    46  	if err != nil {
    47  		t.Fatalf("error creating configuration version: %v", err)
    48  	}
    49  
    50  	// Create a pending run to block this run.
    51  	r, err := b.client.Runs.Create(ctx, tfe.RunCreateOptions{
    52  		ConfigurationVersion: c,
    53  		Workspace:            w,
    54  	})
    55  	if err != nil {
    56  		t.Fatalf("error creating pending run: %v", err)
    57  	}
    58  
    59  	op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
    60  	defer configCleanup()
    61  	defer done(t)
    62  
    63  	integrationContext := &IntegrationContext{
    64  		B:             b,
    65  		StopContext:   ctx,
    66  		CancelContext: ctx,
    67  		Op:            op,
    68  		Run:           r,
    69  	}
    70  
    71  	return integrationContext, &testIntegrationOutput{
    72  		ctx:    integrationContext,
    73  		output: &strings.Builder{},
    74  		t:      t,
    75  	}
    76  }
    77  
    78  func TestCloud_runTasksWithTaskResults(t *testing.T) {
    79  	b, bCleanup := testBackendWithName(t)
    80  	defer bCleanup()
    81  
    82  	integrationContext, writer := newMockIntegrationContext(b, t)
    83  
    84  	cases := map[string]struct {
    85  		taskResults     []*tfe.TaskResult
    86  		context         *IntegrationContext
    87  		writer          *testIntegrationOutput
    88  		expectedOutputs []string
    89  		isError         bool
    90  	}{
    91  		"all-succeeded": {
    92  			taskResults: []*tfe.TaskResult{
    93  				{ID: "1", TaskName: "Mandatory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "mandatory"},
    94  				{ID: "2", TaskName: "Advisory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "advisory"},
    95  			},
    96  			writer:          writer,
    97  			context:         integrationContext,
    98  			expectedOutputs: []string{"Overall Result: Passed\n"},
    99  			isError:         false,
   100  		},
   101  		"mandatory-failed": {
   102  			taskResults: []*tfe.TaskResult{
   103  				{ID: "1", TaskName: "Mandatory", Message: "500 Error", Status: "failed", WorkspaceTaskEnforcementLevel: "mandatory"},
   104  				{ID: "2", TaskName: "Advisory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "advisory"},
   105  			},
   106  			writer:          writer,
   107  			context:         integrationContext,
   108  			expectedOutputs: []string{"Passed\n", "A-OK\n", "Overall Result: Failed\n"},
   109  			isError:         true,
   110  		},
   111  		"advisory-failed": {
   112  			taskResults: []*tfe.TaskResult{
   113  				{ID: "1", TaskName: "Mandatory", Message: "A-OK", Status: "passed", WorkspaceTaskEnforcementLevel: "mandatory"},
   114  				{ID: "2", TaskName: "Advisory", Message: "500 Error", Status: "failed", WorkspaceTaskEnforcementLevel: "advisory"},
   115  			},
   116  			writer:          writer,
   117  			context:         integrationContext,
   118  			expectedOutputs: []string{"Failed (Advisory)", "Overall Result: Passed with advisory failure"},
   119  			isError:         false,
   120  		},
   121  		"unreachable": {
   122  			taskResults: []*tfe.TaskResult{
   123  				{ID: "1", TaskName: "Mandatory", Message: "", Status: "unreachable", WorkspaceTaskEnforcementLevel: "mandatory"},
   124  				{ID: "2", TaskName: "Advisory", Message: "", Status: "unreachable", WorkspaceTaskEnforcementLevel: "advisory"},
   125  			},
   126  			writer:          writer,
   127  			context:         integrationContext,
   128  			expectedOutputs: []string{"Skipping"},
   129  			isError:         false,
   130  		},
   131  	}
   132  
   133  	for caseName, c := range cases {
   134  		c.writer.output.Reset()
   135  		err := b.runTasksWithTaskResults(c.context, writer, func(b *Cloud, stopCtx context.Context) (*tfe.TaskStage, error) {
   136  			return &tfe.TaskStage{
   137  				TaskResults: c.taskResults,
   138  			}, nil
   139  		})
   140  
   141  		if c.isError && err == nil {
   142  			t.Fatalf("Expected %s to be error", caseName)
   143  		}
   144  
   145  		if !c.isError && err != nil {
   146  			t.Errorf("Expected %s to not be error but received %s", caseName, err)
   147  		}
   148  
   149  		output := c.writer.output.String()
   150  		for _, expected := range c.expectedOutputs {
   151  			if !strings.Contains(output, expected) {
   152  				t.Fatalf("Expected output to contain '%s' but it was:\n\n%s", expected, output)
   153  			}
   154  		}
   155  	}
   156  }