blob: 59237df0157d528924fb23f0eaf847dec6643983 [file] [edit]
// Copyright IBM Corp. 2014, 2026
// SPDX-License-Identifier: BUSL-1.1
package arguments
import (
"os"
"path/filepath"
"testing"
"github.com/google/go-cmp/cmp"
"github.com/hashicorp/terraform/internal/tfdiags"
)
func TestStateMigrateArgs_valid(t *testing.T) {
t.Parallel()
// Create lock files to use in test, as validation will check for the existence of the
// file if a path is supplied via CLI flags.
td := t.TempDir()
userLockFilePath := filepath.Join(td, ".terraform.lock.hcl")
if err := os.WriteFile(userLockFilePath, []byte(""), 0644); err != nil {
t.Fatalf("failed to create test lock file: %s", err)
}
invalidLockFilePath := filepath.Join(td, "invalid.lock.hcl")
if err := os.WriteFile(invalidLockFilePath, []byte(""), 0644); err != nil {
t.Fatalf("failed to create test lock file: %s", err)
}
testCases := []struct {
rawArgs []string
expectedArgs *StateMigrate
}{
{
rawArgs: []string{""},
expectedArgs: &StateMigrate{
SourceLockFilePath: "",
DestinationLockFilePath: "",
Upgrade: false,
InputEnabled: true,
ViewType: ViewHuman,
},
},
{ // set or override all flags
rawArgs: []string{
"-source-provider-lock-file", userLockFilePath,
"-destination-provider-lock-file", userLockFilePath,
"-upgrade",
"-json",
"-input=false",
},
expectedArgs: &StateMigrate{
SourceLockFilePath: userLockFilePath,
DestinationLockFilePath: userLockFilePath,
Upgrade: true,
InputEnabled: false,
ViewType: ViewJSON,
},
},
}
for i, tc := range testCases {
args, diags := ParseStateMigrate(tc.rawArgs)
if diags.HasErrors() {
t.Fatalf("unexpected diagnostics: %v", diags)
}
if diff := cmp.Diff(tc.expectedArgs, args); diff != "" {
t.Fatalf("%d: supplied: %q, got unexpected arguments:\n%s", i, tc.rawArgs, diff)
}
}
}
func TestStateMigrateArgs_invalid(t *testing.T) {
t.Parallel()
// Create lock files to use in test, as validation will check for the existence of the
// file if a path is supplied via CLI flags.
td := t.TempDir()
userLockFilePath := filepath.Join(td, ".terraform.lock.hcl")
if err := os.WriteFile(userLockFilePath, []byte(""), 0644); err != nil {
t.Fatalf("failed to create test lock file: %s", err)
}
invalidLockFilePath := filepath.Join(td, "invalid.lock.hcl")
if err := os.WriteFile(invalidLockFilePath, []byte(""), 0644); err != nil {
t.Fatalf("failed to create test lock file: %s", err)
}
testCases := []struct {
rawArgs []string
expectedArgs *StateMigrate
expectedDiags tfdiags.Diagnostics
}{
{
rawArgs: []string{"-input=false", "-source-provider-lock-file", invalidLockFilePath},
expectedArgs: &StateMigrate{
SourceLockFilePath: invalidLockFilePath,
DestinationLockFilePath: "",
Upgrade: false,
InputEnabled: false,
ViewType: ViewHuman,
},
expectedDiags: tfdiags.Diagnostics{
tfdiags.Sourceless(
tfdiags.Error,
"Invalid source-provider-lock-file",
"Expected lock file name to be .terraform.lock.hcl, got: invalid.lock.hcl",
),
},
},
{
rawArgs: []string{"-input=false", "-destination-provider-lock-file", invalidLockFilePath},
expectedArgs: &StateMigrate{
SourceLockFilePath: "",
DestinationLockFilePath: invalidLockFilePath,
Upgrade: false,
InputEnabled: false,
ViewType: ViewHuman,
},
expectedDiags: tfdiags.Diagnostics{
tfdiags.Sourceless(
tfdiags.Error,
"Invalid destination-provider-lock-file",
"Expected lock file name to be .terraform.lock.hcl, got: invalid.lock.hcl",
),
},
},
{ // set lock file paths outside of automation
rawArgs: []string{
"-source-provider-lock-file", userLockFilePath,
"-destination-provider-lock-file", invalidLockFilePath,
},
expectedArgs: &StateMigrate{
SourceLockFilePath: userLockFilePath,
DestinationLockFilePath: invalidLockFilePath,
Upgrade: false,
InputEnabled: true,
ViewType: ViewHuman,
},
expectedDiags: tfdiags.Diagnostics{
tfdiags.Sourceless(
tfdiags.Error,
"Conflicting command-line flags provided",
"-source-provider-lock-file cannot be used outside of automation (with -input=true)",
),
tfdiags.Sourceless(
tfdiags.Error,
"Conflicting command-line flags provided",
"-destination-provider-lock-file cannot be used outside of automation (with -input=true)",
),
// Diagnostic about invalid lock file regardless of this flag not being allow
tfdiags.Sourceless(
tfdiags.Error,
"Invalid destination-provider-lock-file",
"Expected lock file name to be .terraform.lock.hcl, got: invalid.lock.hcl",
),
},
},
{ // JSON output outside of automation
rawArgs: []string{
"-json",
},
expectedArgs: &StateMigrate{
SourceLockFilePath: "",
DestinationLockFilePath: "",
Upgrade: false,
InputEnabled: true,
ViewType: ViewJSON,
},
expectedDiags: tfdiags.Diagnostics{
tfdiags.Sourceless(
tfdiags.Error,
"Conflicting command-line flags provided",
"-json cannot be used outside of automation (with -input=true)",
),
},
},
}
for i, tc := range testCases {
args, diags := ParseStateMigrate(tc.rawArgs)
if !diags.HasErrors() {
t.Fatalf("expected diagnostics, but got none")
}
tfdiags.AssertDiagnosticsMatch(t, diags, tc.expectedDiags)
if diff := cmp.Diff(tc.expectedArgs, args); diff != "" {
t.Fatalf("%d: supplied: %q, got unexpected arguments:\n%s", i, tc.rawArgs, diff)
}
}
}