/
githubmirror
/
terraform
Обзор
Документация
Войти
/
githubmirror
/
terraform
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
internal/command/init_policy_test.go
764 строки
25 KB
Sarah French
refactor: Replace remaining use of `cli.NewMockUi()` or `new(cli.MockUi)` in tests in the command package
16 июл 2026, 00:45
16 июл 2026, 00:45
91f04bd
Код
Авторство
О чём код?
// 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") } }