| // Copyright (c) HashiCorp, Inc. |
| // SPDX-License-Identifier: BUSL-1.1 |
| |
| package views |
| |
| import ( |
| "fmt" |
| "strings" |
| "testing" |
| |
| "github.com/google/go-cmp/cmp" |
| "github.com/hashicorp/hcl/v2" |
| "github.com/hashicorp/terraform/internal/command/arguments" |
| "github.com/hashicorp/terraform/internal/terminal" |
| "github.com/hashicorp/terraform/internal/tfdiags" |
| tfversion "github.com/hashicorp/terraform/version" |
| ) |
| |
| func TestNewInit_jsonViewDiagnostics(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitJSON); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| diags := getTestDiags(t) |
| newInit.Diagnostics(diags) |
| |
| version := tfversion.String() |
| want := []map[string]interface{}{ |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("Terraform %s", version), |
| "@module": "terraform.ui", |
| "terraform": version, |
| "type": "version", |
| "ui": JSON_UI_VERSION, |
| }, |
| { |
| "@level": "error", |
| "@message": "Error: Error selecting workspace", |
| "@module": "terraform.ui", |
| "diagnostic": map[string]interface{}{ |
| "severity": "error", |
| "summary": "Error selecting workspace", |
| "detail": "Workspace random_pet does not exist", |
| }, |
| "type": "diagnostic", |
| }, |
| { |
| "@level": "error", |
| "@message": "Error: Unsupported backend type", |
| "@module": "terraform.ui", |
| "diagnostic": map[string]interface{}{ |
| "severity": "error", |
| "summary": "Unsupported backend type", |
| "detail": "There is no explicit backend type named fake backend.", |
| }, |
| "type": "diagnostic", |
| }, |
| } |
| |
| actual := done(t).Stdout() |
| testJSONViewOutputEqualsFull(t, actual, want) |
| } |
| |
| func TestNewInit_humanViewDiagnostics(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitHuman); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| diags := getTestDiags(t) |
| newInit.Diagnostics(diags) |
| |
| actual := done(t).All() |
| expected := "\nError: Error selecting workspace\n\nWorkspace random_pet does not exist\n\nError: Unsupported backend type\n\nThere is no explicit backend type named fake backend.\n" |
| if !strings.Contains(actual, expected) { |
| t.Fatalf("expected output to contain: %s, but got %s", expected, actual) |
| } |
| } |
| |
| func TestNewInit_unsupportedViewDiagnostics(t *testing.T) { |
| defer func() { |
| r := recover() |
| if r == nil { |
| t.Fatalf("should panic with unsupported view type raw") |
| } else if r != "unknown view type raw" { |
| t.Fatalf("unexpected panic message: %v", r) |
| } |
| }() |
| |
| streams, done := terminal.StreamsForTesting(t) |
| defer done(t) |
| |
| NewInit(arguments.ViewRaw, NewView(streams).SetRunningInAutomation(true)) |
| } |
| |
| func getTestDiags(t *testing.T) tfdiags.Diagnostics { |
| t.Helper() |
| |
| var diags tfdiags.Diagnostics |
| diags = diags.Append( |
| tfdiags.Sourceless( |
| tfdiags.Error, |
| "Error selecting workspace", |
| "Workspace random_pet does not exist", |
| ), |
| &hcl.Diagnostic{ |
| Severity: hcl.DiagError, |
| Summary: "Unsupported backend type", |
| Detail: "There is no explicit backend type named fake backend.", |
| Subject: nil, |
| }, |
| ) |
| |
| return diags |
| } |
| |
| func TestNewInit_jsonViewOutput(t *testing.T) { |
| t.Run("no param", func(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitJSON); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| newInit.Output(InitializingProviderPluginMessage) |
| |
| version := tfversion.String() |
| want := []map[string]interface{}{ |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("Terraform %s", version), |
| "@module": "terraform.ui", |
| "terraform": version, |
| "type": "version", |
| "ui": JSON_UI_VERSION, |
| }, |
| { |
| "@level": "info", |
| "@message": "Initializing provider plugins...", |
| "message_code": "initializing_provider_plugin_message", |
| "@module": "terraform.ui", |
| "type": "init_output", |
| }, |
| } |
| |
| actual := done(t).Stdout() |
| testJSONViewOutputEqualsFull(t, actual, want) |
| }) |
| |
| t.Run("single param", func(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitJSON); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| packageName := "hashicorp/aws" |
| newInit.Output(FindingLatestVersionMessage, packageName) |
| |
| version := tfversion.String() |
| want := []map[string]interface{}{ |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("Terraform %s", version), |
| "@module": "terraform.ui", |
| "terraform": version, |
| "type": "version", |
| "ui": JSON_UI_VERSION, |
| }, |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("%s: Finding latest version...", packageName), |
| "@module": "terraform.ui", |
| "message_code": "finding_latest_version_message", |
| "type": "init_output", |
| }, |
| } |
| |
| actual := done(t).Stdout() |
| testJSONViewOutputEqualsFull(t, actual, want) |
| }) |
| |
| t.Run("variable length params", func(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitJSON); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| var packageName, packageVersion = "hashicorp/aws", "3.0.0" |
| newInit.Output(ProviderAlreadyInstalledMessage, packageName, packageVersion) |
| |
| version := tfversion.String() |
| want := []map[string]interface{}{ |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("Terraform %s", version), |
| "@module": "terraform.ui", |
| "terraform": version, |
| "type": "version", |
| "ui": JSON_UI_VERSION, |
| }, |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("%s v%s: Using previously-installed provider version", packageName, packageVersion), |
| "@module": "terraform.ui", |
| "message_code": "provider_already_installed_message", |
| "type": "init_output", |
| }, |
| } |
| |
| actual := done(t).Stdout() |
| testJSONViewOutputEqualsFull(t, actual, want) |
| }) |
| } |
| |
| func TestNewInit_jsonViewLog(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitJSON); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| newInit.LogInitMessage(InitializingProviderPluginMessage) |
| |
| version := tfversion.String() |
| want := []map[string]interface{}{ |
| { |
| "@level": "info", |
| "@message": fmt.Sprintf("Terraform %s", version), |
| "@module": "terraform.ui", |
| "terraform": version, |
| "type": "version", |
| "ui": JSON_UI_VERSION, |
| }, |
| { |
| "@level": "info", |
| "@message": "Initializing provider plugins...", |
| "@module": "terraform.ui", |
| "type": "log", |
| }, |
| } |
| |
| actual := done(t).Stdout() |
| testJSONViewOutputEqualsFull(t, actual, want) |
| } |
| |
| func TestNewInit_jsonViewPrepareMessage(t *testing.T) { |
| t.Run("existing message code", func(t *testing.T) { |
| streams, _ := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewJSON, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitJSON); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| want := "Initializing modules..." |
| |
| actual := newInit.PrepareMessage(InitializingModulesMessage) |
| if !cmp.Equal(want, actual) { |
| t.Errorf("unexpected output: %s", cmp.Diff(want, actual)) |
| } |
| }) |
| } |
| |
| func TestNewInit_humanViewOutput(t *testing.T) { |
| t.Run("no param", func(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitHuman); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| newInit.Output(InitializingProviderPluginMessage) |
| |
| actual := done(t).All() |
| expected := "Initializing provider plugins..." |
| if !strings.Contains(actual, expected) { |
| t.Fatalf("expected output to contain: %s, but got %s", expected, actual) |
| } |
| }) |
| |
| t.Run("single param", func(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitHuman); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| packageName := "hashicorp/aws" |
| newInit.Output(FindingLatestVersionMessage, packageName) |
| |
| actual := done(t).All() |
| expected := "Finding latest version of hashicorp/aws" |
| if !strings.Contains(actual, expected) { |
| t.Fatalf("expected output to contain: %s, but got %s", expected, actual) |
| } |
| }) |
| |
| t.Run("variable length params", func(t *testing.T) { |
| streams, done := terminal.StreamsForTesting(t) |
| |
| newInit := NewInit(arguments.ViewHuman, NewView(streams).SetRunningInAutomation(true)) |
| if _, ok := newInit.(*InitHuman); !ok { |
| t.Fatalf("unexpected return type %t", newInit) |
| } |
| |
| var packageName, packageVersion = "hashicorp/aws", "3.0.0" |
| newInit.Output(ProviderAlreadyInstalledMessage, packageName, packageVersion) |
| |
| actual := done(t).All() |
| expected := "- Using previously-installed hashicorp/aws v3.0.0" |
| if !strings.Contains(actual, expected) { |
| t.Fatalf("expected output to contain: %s, but got %s", expected, actual) |
| } |
| }) |
| } |