blob: 622159c81600966b825d5e21ebff9bfaddbf7177 [file] [edit]
// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package command
import (
"context"
"os"
"path/filepath"
"slices"
"strings"
"sync/atomic"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/zclconf/go-cty/cty"
"google.golang.org/protobuf/testing/protocmp"
"github.com/hashicorp/terraform/internal/policy"
"github.com/hashicorp/terraform/internal/policy/proto"
)
func TestInit_WithModulePolicy(t *testing.T) {
cases := []struct {
name string
policy *policy.EvaluationResponse
expected int
}{
{
name: "unknown module policy",
// This unknown evaluation should still lead to success of the init operation.
policy: &policy.EvaluationResponse{Overall: policy.UnknownResult},
expected: 0,
},
{
name: "advisory deny module policy",
// Advisory policies may return deny without error diagnostics and should
// not block init.
policy: &policy.EvaluationResponse{Overall: policy.DenyResult},
expected: 0,
},
{
name: "success module policy",
policy: &policy.EvaluationResponse{Overall: policy.AllowResult},
expected: 0,
},
{
name: "errored module policy",
policy: &policy.EvaluationResponse{
Overall: policy.DenyResult,
Diagnostics: policy.Diagnostics{
policy.NewErrorDiagnostic("test error", "test error detail", policy.DenyResult),
},
},
expected: 1,
},
}
for _, tc := range cases {
td := t.TempDir()
testCopyDir(t, testFixturePath("dynamic-module-sources/local-source-with-variable"), td)
t.Chdir(td)
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
t.Run(tc.name, func(t *testing.T) {
policyClient.EvaluateModuleResponse = tc.policy
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-var", "module_name=example"})
output := done(t)
if code != tc.expected {
t.Fatalf("got exit status %d; want %d\nstderr:\n%s\n\nstdout:\n%s", code, tc.expected, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateModuleCalled {
t.Fatal("expected EvaluateModule to be called")
}
if got, want := policyClient.EvaluateModuleRequest.Target, "./modules/example"; got != want {
t.Fatalf("wrong module policy target\ngot: %q\nwant: %q", got, want)
}
if !policyClient.EvaluateModuleCalled {
t.Fatal("expected EvaluateModule to be called")
}
if got, want := policyClient.EvaluateModuleRequest.Target, "./modules/example"; got != want {
t.Fatalf("wrong module policy target\ngot: %q\nwant: %q", got, want)
}
if policyClient.EvaluateModuleRequest.Meta == nil {
t.Fatal("expected module metadata to be set")
}
if got, want := policyClient.EvaluateModuleRequest.Meta.Address, "module.example"; got != want {
t.Fatalf("wrong module address\ngot: %q\nwant: %q", got, want)
}
if got, want := policyClient.EvaluateModuleRequest.Meta.Version, ""; got != want {
t.Fatalf("wrong module version\ngot: %q\nwant: %q", got, want)
}
})
}
}
func TestInit_WithPolicyClientStopAfterInit(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("dynamic-module-sources/local-source-with-variable"), td)
t.Chdir(td)
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
var stopCalled atomic.Bool
var policyEvaluated atomic.Bool
policyClient.StopFn = func() {
stopCalled.Store(true)
}
policyClient.EvaluateModuleFn = func(ctx context.Context, req policy.EvaluationRequest[*proto.PolicyEvaluateModuleRequest_ModuleMetadata]) policy.EvaluationResponse {
policyEvaluated.Store(true)
if stopCalled.Load() {
t.Fatal("policy client Stop was called before init finished")
}
return policy.EvaluationResponse{Overall: policy.AllowResult}
}
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-var", "module_name=example"})
output := done(t)
if code != 0 {
t.Fatalf("got exit status %d; want 0\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyEvaluated.Load() {
t.Fatal("expected module policy evaluation to be called during init")
}
if !stopCalled.Load() {
t.Fatal("expected policy client Stop to be called after init")
}
}
func TestInit_WithModulePolicy_AlreadyInstalled(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("dynamic-module-sources/add-version-constraint"), td)
t.Chdir(td)
if err := os.WriteFile(filepath.Join(td, ".terraform/modules/modules.json"), []byte(`{
"Modules": [
{
"Key": "",
"Source": "",
"Dir": ""
},
{
"Key": "child",
"Source": "registry.terraform.io/hashicorp/module-installer-acctest/aws",
"Version": "0.0.1",
"Dir": ".terraform/modules/child"
}
]
}`), 0644); err != nil {
t.Fatal(err)
}
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
policyClient.EvaluateModuleFn = func(ctx context.Context, req policy.EvaluationRequest[*proto.PolicyEvaluateModuleRequest_ModuleMetadata]) policy.EvaluationResponse {
if got, want := req.Meta.Version, "0.0.1"; got != want {
t.Fatalf("wrong module version\ngot: %q\nwant: %q", got, want)
}
return policy.EvaluationResponse{
Overall: policy.DenyResult,
Diagnostics: policy.Diagnostics{
policy.NewErrorDiagnostic(
"module policy denied",
"module policy blocked installation",
policy.DenyResult,
),
},
}
}
overs := overrides
overs.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overs,
Ui: ui,
View: view,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-no-color"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateModuleCalled {
t.Fatal("expected EvaluateModule to be called for already-installed module")
}
expected := `
Error: module policy denied
on add-version-constraint.tf line 7:
7: module "child" {
module policy blocked installation
Error: Policy evaluation failed
Module download blocked due to policy violations. Please review other
diagnostics for details.
`
if diff := cmp.Diff(expected, output.Stderr()); diff != "" {
t.Fatalf("unexpected stderr:\n%s", diff)
}
}
func TestInit_WithPolicySetupFailureJSON(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("init-nested-provider-requirements"), td)
t.Chdir(td)
providerSource := newMockProviderSource(t, map[string][]string{
"hashicorp/test": {"1.2.3", "1.2.4"},
"tf.example.com/awesomecorp/happycloud": {"1.0.0"},
"hashicorp/null": {"2.0.1"},
"hashicorp/grandchild": {"1.0.0"},
})
ui := testUiWrapped(t)
view, done := testView(t)
c := &InitCommand{
Meta: Meta{
Ui: ui,
View: view,
ProviderSource: providerSource,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-no-color", "-json"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
expected := `{"@level":"info","@message":"Terraform 1.15.0-dev","@module":"terraform.ui","terraform":"1.15.0-dev","type":"version","ui":"1.3"}
{"@level":"info","@message":"Initializing the backend...","@module":"terraform.ui","message_code":"initializing_backend_message","type":"init_output"}
{"@level":"error","@message":"Error: Failed to connect to policy engine","@module":"terraform.ui","@policy":"true","policy_diagnostic":{"severity":"error","summary":"Failed to connect to policy engine","detail":"Failed to connect to policy engine: failed to connect to plugin: exec: \"tfpolicy-plugin\": executable file not found in $PATH."},"policy_metadata":{},"result":"SetupErrorResult","type":"policy_diagnostic"}`
checkGoldenReferenceStr(t, output, expected)
}
func TestInit_WithModulePolicyDiagnostics(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("dynamic-module-sources/local-source-with-variable"), td)
t.Chdir(td)
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
policyClient.EvaluateModuleResponse = &policy.EvaluationResponse{
Overall: policy.DenyResult,
Diagnostics: policy.Diagnostics{
policy.DiagsFromProto([]*proto.Diagnostic{
{
Severity: proto.Severity_ERROR,
Summary: "module policy denied",
Result: &proto.DiagnosticResult{
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
},
},
}, &policy.Policy{
Address: "module_policy.example",
Filename: "policy_file.tfpolicy.hcl",
EnforcementLevel: "mandatory",
Result: policy.DenyResult,
})[0],
},
Policies: []*policy.Policy{
{
Address: "module_policy.example",
Filename: "policy_file.tfpolicy.hcl",
EnforcementLevel: "mandatory",
Result: policy.DenyResult,
},
},
}
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-var", "module_name=example", "-no-color"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateModuleCalled {
t.Fatal("expected EvaluateModule to be called")
}
stderr := output.Stderr()
expected := `
Error: module policy denied
on main.tf line 6:
6: module "example" {
Error: Policy evaluation failed
Module download blocked due to policy violations. Please review other
diagnostics for details.
`
if diff := cmp.Diff(expected, stderr); diff != "" {
t.Fatalf("unexpected stderr:\n%s", diff)
}
}
func TestInit_WithNestedModulePolicyDiagnostics(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("init-nested-provider-requirements"), td)
t.Chdir(td)
ui := testUiWrapped(t)
view, done := testView(t)
// assert modules are evaluated correctly
expected := map[string]policy.EvaluateResult{
"./grandchild": policy.DenyResult,
"./modules/child": policy.AllowResult,
}
actual := map[string]policy.EvaluateResult{}
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
policyClient.EvaluateModuleFn = func(ctx context.Context, req policy.EvaluationRequest[*proto.PolicyEvaluateModuleRequest_ModuleMetadata]) policy.EvaluationResponse {
if req.Target != "./grandchild" {
actual[req.Target] = policy.AllowResult
return policy.EvaluationResponse{Overall: policy.AllowResult}
}
actual[req.Target] = policy.DenyResult
return policy.EvaluationResponse{
Overall: policy.DenyResult,
Diagnostics: policy.Diagnostics{
policy.DiagsFromProto([]*proto.Diagnostic{
{
Severity: proto.Severity_ERROR,
Summary: "nested module policy denied",
Result: &proto.DiagnosticResult{
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
},
},
}, &policy.Policy{
Address: "module_policy.nested",
Filename: "policy_file.tfpolicy.hcl",
EnforcementLevel: "mandatory",
Result: policy.DenyResult,
})[0],
},
}
}
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-no-color"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateModuleCalled {
t.Fatal("expected EvaluateModule to be called")
}
if diff := cmp.Diff(expected, actual); diff != "" {
t.Fatalf("unexpected module policy evaluation results:\n%s", diff)
}
stderr := output.Stderr()
expectedStderr := `
Error: nested module policy denied
on modules/child/main.tf line 12:
12: module "nested" {
Error: Policy evaluation failed
Module download blocked due to policy violations. Please review other
diagnostics for details.
`
if diff := cmp.Diff(expectedStderr, stderr); diff != "" {
t.Fatalf("unexpected stderr:\n%s\nexpected:\n%s\n diff:\n%s", stderr, expectedStderr, diff)
}
}
func TestInit_WithModulePolicyJSON(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("dynamic-module-sources/local-source-with-variable"), td)
t.Chdir(td)
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
resp := policy.EvaluationFromProtoResponse(
proto.EvaluateResult_DENY_EVALUATE_RESULT,
[]*proto.PolicyEvaluationDetail{
{
Address: "module_policy.example",
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
File: "policy_file.tfpolicy.hcl",
PolicySetEnforcement: "mandatory",
Diagnostics: []*proto.Diagnostic{
{
Severity: proto.Severity_ERROR,
Summary: "module policy denied",
Result: &proto.DiagnosticResult{
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
},
},
},
DefRange: &proto.Range{
Filename: "policy_set.policy.hcl",
},
},
},
)
policyClient.EvaluateModuleResponse = &resp
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-var", "module_name=example", "-no-color", "-json"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 0\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateModuleCalled {
t.Fatal("expected EvaluateModule to be called")
}
expected := `{"@level":"info","@message":"Terraform 1.15.0-dev","@module":"terraform.ui","terraform":"1.15.0-dev","type":"version","ui":"1.3"}
{"@level":"info","@message":"Initializing the backend...","@module":"terraform.ui","message_code":"initializing_backend_message","type":"init_output"}
{"@level":"info","@message":"Initializing modules...","@module":"terraform.ui","message_code":"initializing_modules_message","type":"init_output"}
{"@level":"error","@message":"Error: module policy denied","@module":"terraform.ui","@policy":"true","policy_diagnostic":{"severity":"error","summary":"module policy denied","detail":"","range":{"filename":"main.tf","start":{"line":6,"column":1,"byte":60},"end":{"line":6,"column":17,"byte":76}},"snippet":{"context":null,"code":"module \"example\" {","start_line":6,"highlight_start_offset":0,"highlight_end_offset":16,"values":[]}},"policy_metadata":{"policy_set_path":"policy_file.tfpolicy.hcl","policy_name":"module_policy.example","file_name":"policy_set.policy.hcl","enforcement_level":"mandatory"},"result":"DenyResult","target_address":"module.example","type":"policy_diagnostic"}
{"@level":"info","@message":"Policy Result","@module":"terraform.ui","@policy":"true","target_address":"module.example","policy_address":"module_policy.example","policy_metadata":{"policy_set_path":"policy_file.tfpolicy.hcl","policy_name":"module_policy.example","file_name":"policy_set.policy.hcl","enforcement_level":"mandatory"},"result":"DenyResult","type":"policy_result"}
{"@level":"error","@message":"Error: Policy evaluation failed","@module":"terraform.ui","diagnostic":{"severity":"error","summary":"Policy evaluation failed","detail":"Module download blocked due to policy violations. Please review other diagnostics for details."},"type":"diagnostic"}`
checkGoldenReferenceStr(t, output, expected)
}
func TestInit_WithProviderPolicy(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("init-nested-provider-requirements"), td)
t.Chdir(td)
providerSource := newMockProviderSource(t, map[string][]string{
"hashicorp/test": {"1.2.3", "1.2.4"},
"tf.example.com/awesomecorp/happycloud": {"1.0.0"},
"hashicorp/null": {"2.0.1"},
"hashicorp/grandchild": {"1.0.0"},
})
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
actualTargets := []string{}
expectedTargets := []string{"test", "happycloud", "null", "grandchild"}
policyClient.EvaluateProviderFn = func(ctx context.Context, req policy.EvaluationRequest[*proto.PolicyEvaluateProviderRequest_ProviderMetadata]) policy.EvaluationResponse {
actualTargets = append(actualTargets, req.Target)
var expected *proto.PolicyEvaluateProviderRequest_ProviderMetadata
switch req.Target {
case "test":
expected = &proto.PolicyEvaluateProviderRequest_ProviderMetadata{
Name: "test",
Namespace: "hashicorp",
Source: "registry.terraform.io/hashicorp/test",
Version: "1.2.3",
}
case "happycloud":
expected = &proto.PolicyEvaluateProviderRequest_ProviderMetadata{
Name: "happycloud",
Namespace: "awesomecorp",
Source: "tf.example.com/awesomecorp/happycloud",
Version: "1.0.0",
}
case "null":
expected = &proto.PolicyEvaluateProviderRequest_ProviderMetadata{
Name: "null",
Namespace: "hashicorp",
Source: "registry.terraform.io/hashicorp/null",
Version: "2.0.1",
}
case "grandchild":
expected = &proto.PolicyEvaluateProviderRequest_ProviderMetadata{
Name: "grandchild",
Namespace: "hashicorp",
Source: "registry.terraform.io/hashicorp/grandchild",
Version: "1.0.0",
}
}
if diff := cmp.Diff(expected, req.Meta, protocmp.Transform(), cmp.Comparer(cty.Value.RawEquals)); diff != "" {
t.Fatalf("wrong provider metadata\ngot: %s\nwant: %v", diff, expected)
}
t.Cleanup(func() {
if !slices.Contains(expectedTargets, req.Target) {
t.Errorf("expected target %q to be in %v", req.Target, expectedTargets)
}
})
if req.Target == "test" {
// This unknown evaluation should still lead to success of the init operation.
return policy.EvaluationResponse{Overall: policy.UnknownResult}
}
if req.Target == "happycloud" {
// Advisory policies may return deny without error diagnostics and should
// not block init.
return policy.EvaluationResponse{Overall: policy.DenyResult}
}
return policy.EvaluationResponse{Overall: policy.AllowResult}
}
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
ProviderSource: providerSource,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td})
output := done(t)
if code != 0 {
t.Fatalf("got exit status %d; want 0\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateProviderCalled {
t.Fatal("expected EvaluateProvider to be called")
}
}
func TestInit_WithProviderPolicyDiagnostics(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("init-nested-provider-requirements"), td)
t.Chdir(td)
providerSource := newMockProviderSource(t, map[string][]string{
"hashicorp/test": {"1.2.3", "1.2.4"},
"tf.example.com/awesomecorp/happycloud": {"1.0.0"},
"hashicorp/null": {"2.0.1"},
"hashicorp/grandchild": {"1.0.0"},
})
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
expectedTargets := []string{"test", "happycloud", "null", "grandchild"}
actualTargets := []string{}
policyClient.EvaluateProviderFn = func(ctx context.Context, req policy.EvaluationRequest[*proto.PolicyEvaluateProviderRequest_ProviderMetadata]) policy.EvaluationResponse {
actualTargets = append(actualTargets, req.Target)
return policy.EvaluationFromProtoResponse(
proto.EvaluateResult_DENY_EVALUATE_RESULT,
[]*proto.PolicyEvaluationDetail{
{
Address: "provider_policy." + req.Target,
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
File: "policy_file.tfpolicy.hcl",
PolicySetEnforcement: "mandatory",
Diagnostics: []*proto.Diagnostic{
{
Severity: proto.Severity_ERROR,
Summary: req.Target + " provider policy denied",
Result: &proto.DiagnosticResult{
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
},
},
},
},
},
)
}
overs := overrides
overs.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overs,
Ui: ui,
View: view,
ProviderSource: providerSource,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-no-color"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateProviderCalled {
t.Fatal("expected EvaluateProvider to be called")
}
if got, want := len(actualTargets), len(expectedTargets); got != want {
t.Fatalf("wrong number of evaluated providers\ngot: %d (%v)\nwant: %d", got, actualTargets, want)
}
for _, target := range expectedTargets {
if !slices.Contains(actualTargets, target) {
t.Fatalf("missing provider evaluation for %q in %v", target, actualTargets)
}
}
stderr := output.Stderr()
for _, target := range expectedTargets {
if !strings.Contains(stderr, "Error: "+target+" provider policy denied") {
t.Fatalf("missing policy diagnostic for %q in stderr:\n%s", target, stderr)
}
}
if !strings.Contains(stderr, "Provider download blocked due to policy violations. Please review other diagnostics for details.") {
t.Fatalf("missing provider policy error in stderr:\n%s", stderr)
}
}
func TestInit_WithProviderPolicyJSON(t *testing.T) {
td := t.TempDir()
testCopyDir(t, testFixturePath("init-nested-provider-requirements"), td)
t.Chdir(td)
providerSource := newMockProviderSource(t, map[string][]string{
"hashicorp/test": {"1.2.3", "1.2.4"},
"awesomecorp/happycloud": {"1.0.0"},
"hashicorp/null": {"2.0.1"},
"hashicorp/grandchild": {"1.0.0"},
})
ui := testUiWrapped(t)
view, done := testView(t)
overrides := metaOverridesForProvider(testProvider())
policyClient := policy.NewTestMockClient(t)
resp := policy.EvaluationFromProtoResponse(
proto.EvaluateResult_DENY_EVALUATE_RESULT,
[]*proto.PolicyEvaluationDetail{
{
Address: "provider_policy.example",
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
File: "policy_file.tfpolicy.hcl",
PolicySetEnforcement: "mandatory",
Diagnostics: []*proto.Diagnostic{
{
Severity: proto.Severity_ERROR,
Summary: "provider policy denied",
Result: &proto.DiagnosticResult{
Result: proto.EvaluateResult_DENY_EVALUATE_RESULT,
},
},
},
},
},
)
policyClient.EvaluateProviderResponse = &resp
overrides.PolicyClient = policyClient
c := &InitCommand{
Meta: Meta{
testingOverrides: overrides,
Ui: ui,
View: view,
ProviderSource: providerSource,
AllowExperimentalFeatures: true,
},
}
code := c.Run([]string{"-policies", td, "-no-color", "-json"})
output := done(t)
if code != 1 {
t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, output.Stderr(), output.Stdout())
}
if !policyClient.EvaluateProviderCalled {
t.Fatal("expected EvaluateProvider to be called")
}
allOutput := strings.SplitSeq(output.Stdout(), "\n")
var foundPolicyDiagnostic bool
for line := range allOutput {
if strings.Contains(line, `"type":"policy_diagnostic"`) {
foundPolicyDiagnostic = strings.Contains(line, "provider policy denied")
}
}
if !foundPolicyDiagnostic {
t.Fatal("expected diagnostic output")
}
}