github.com/opentofu/opentofu@v1.7.1/internal/cloud/backend_taskStage_policyEvaluation_test.go (about)

     1  // Copyright (c) The OpenTofu Authors
     2  // SPDX-License-Identifier: MPL-2.0
     3  // Copyright (c) 2023 HashiCorp, Inc.
     4  // SPDX-License-Identifier: MPL-2.0
     5  
     6  package cloud
     7  
     8  import (
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/hashicorp/go-tfe"
    13  )
    14  
    15  func TestCloud_runTaskStageWithPolicyEvaluation(t *testing.T) {
    16  	b, bCleanup := testBackendWithName(t)
    17  	defer bCleanup()
    18  
    19  	integrationContext, writer := newMockIntegrationContext(b, t)
    20  
    21  	cases := map[string]struct {
    22  		taskStage       func() *tfe.TaskStage
    23  		context         *IntegrationContext
    24  		writer          *testIntegrationOutput
    25  		expectedOutputs []string
    26  		isError         bool
    27  	}{
    28  		"all-succeeded": {
    29  			taskStage: func() *tfe.TaskStage {
    30  				ts := &tfe.TaskStage{}
    31  				ts.PolicyEvaluations = []*tfe.PolicyEvaluation{
    32  					{ID: "pol-pass", ResultCount: &tfe.PolicyResultCount{Passed: 1}, Status: "passed"},
    33  				}
    34  				return ts
    35  			},
    36  			writer:          writer,
    37  			context:         integrationContext,
    38  			expectedOutputs: []string{"│ [bold]OPA Policy Evaluation\n\n│ [bold]→→ Overall Result: [green]PASSED\n│ [dim] This result means that all OPA policies passed and the protected behavior is allowed\n│ 1 policies evaluated\n\n│ → Policy set 1: [bold]policy-set-that-passes (1)\n│   ↳ Policy name: [bold]policy-pass\n│      | [green][bold]✓ Passed\n│      | [dim]This policy will pass\n"},
    39  			isError:         false,
    40  		},
    41  		"mandatory-failed": {
    42  			taskStage: func() *tfe.TaskStage {
    43  				ts := &tfe.TaskStage{}
    44  				ts.PolicyEvaluations = []*tfe.PolicyEvaluation{
    45  					{ID: "pol-fail", ResultCount: &tfe.PolicyResultCount{MandatoryFailed: 1}, Status: "failed"},
    46  				}
    47  				return ts
    48  			},
    49  			writer:          writer,
    50  			context:         integrationContext,
    51  			expectedOutputs: []string{"│ [bold]→→ Overall Result: [red]FAILED\n│ [dim] This result means that one or more OPA policies failed. More than likely, this was due to the discovery of violations by the main rule and other sub rules\n│ 1 policies evaluated\n\n│ → Policy set 1: [bold]policy-set-that-fails (1)\n│   ↳ Policy name: [bold]policy-fail\n│      | [red][bold]× Failed\n│      | [dim]This policy will fail"},
    52  			isError:         true,
    53  		},
    54  		"advisory-failed": {
    55  			taskStage: func() *tfe.TaskStage {
    56  				ts := &tfe.TaskStage{}
    57  				ts.PolicyEvaluations = []*tfe.PolicyEvaluation{
    58  					{ID: "adv-fail", ResultCount: &tfe.PolicyResultCount{AdvisoryFailed: 1}, Status: "failed"},
    59  				}
    60  				return ts
    61  			},
    62  			writer:          writer,
    63  			context:         integrationContext,
    64  			expectedOutputs: []string{"│ [bold]OPA Policy Evaluation\n\n│ [bold]→→ Overall Result: [red]FAILED\n│ [dim] This result means that one or more OPA policies failed. More than likely, this was due to the discovery of violations by the main rule and other sub rules\n│ 1 policies evaluated\n\n│ → Policy set 1: [bold]policy-set-that-fails (1)\n│   ↳ Policy name: [bold]policy-fail\n│      | [blue][bold]Ⓘ Advisory\n│      | [dim]This policy will fail"},
    65  			isError:         false,
    66  		},
    67  		"unreachable": {
    68  			taskStage: func() *tfe.TaskStage {
    69  				ts := &tfe.TaskStage{}
    70  				ts.PolicyEvaluations = []*tfe.PolicyEvaluation{
    71  					{ID: "adv-fail", ResultCount: &tfe.PolicyResultCount{Errored: 1}, Status: "unreachable"},
    72  				}
    73  				return ts
    74  			},
    75  			writer:          writer,
    76  			context:         integrationContext,
    77  			expectedOutputs: []string{"Skipping policy evaluation."},
    78  			isError:         false,
    79  		},
    80  	}
    81  
    82  	for _, c := range cases {
    83  		c.writer.output.Reset()
    84  		trs := policyEvaluationSummarizer{
    85  			cloud: b,
    86  		}
    87  		c.context.Poll(0, 0, func(i int) (bool, error) {
    88  			cont, _, _ := trs.Summarize(c.context, c.writer, c.taskStage())
    89  			if cont {
    90  				return true, nil
    91  			}
    92  
    93  			output := c.writer.output.String()
    94  			for _, expected := range c.expectedOutputs {
    95  				if !strings.Contains(output, expected) {
    96  					t.Fatalf("Expected output to contain '%s' but it was:\n\n%s", expected, output)
    97  				}
    98  			}
    99  			return false, nil
   100  		})
   101  	}
   102  }