github.com/opentofu/opentofu@v1.7.1/internal/cloud/backend_refresh_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  	"context"
    10  	"strings"
    11  	"testing"
    12  	"time"
    13  
    14  	"github.com/mitchellh/cli"
    15  
    16  	"github.com/opentofu/opentofu/internal/backend"
    17  	"github.com/opentofu/opentofu/internal/command/arguments"
    18  	"github.com/opentofu/opentofu/internal/command/clistate"
    19  	"github.com/opentofu/opentofu/internal/command/views"
    20  	"github.com/opentofu/opentofu/internal/initwd"
    21  	"github.com/opentofu/opentofu/internal/plans"
    22  	"github.com/opentofu/opentofu/internal/states/statemgr"
    23  	"github.com/opentofu/opentofu/internal/terminal"
    24  )
    25  
    26  func testOperationRefresh(t *testing.T, configDir string) (*backend.Operation, func(), func(*testing.T) *terminal.TestOutput) {
    27  	t.Helper()
    28  
    29  	return testOperationRefreshWithTimeout(t, configDir, 0)
    30  }
    31  
    32  func testOperationRefreshWithTimeout(t *testing.T, configDir string, timeout time.Duration) (*backend.Operation, func(), func(*testing.T) *terminal.TestOutput) {
    33  	t.Helper()
    34  
    35  	_, configLoader, configCleanup := initwd.MustLoadConfigForTests(t, configDir, "tests")
    36  
    37  	streams, done := terminal.StreamsForTesting(t)
    38  	view := views.NewView(streams)
    39  	stateLockerView := views.NewStateLocker(arguments.ViewHuman, view)
    40  	operationView := views.NewOperation(arguments.ViewHuman, false, view)
    41  
    42  	return &backend.Operation{
    43  		ConfigDir:    configDir,
    44  		ConfigLoader: configLoader,
    45  		PlanRefresh:  true,
    46  		StateLocker:  clistate.NewLocker(timeout, stateLockerView),
    47  		Type:         backend.OperationTypeRefresh,
    48  		View:         operationView,
    49  	}, configCleanup, done
    50  }
    51  
    52  func TestCloud_refreshBasicActuallyRunsApplyRefresh(t *testing.T) {
    53  	b, bCleanup := testBackendWithName(t)
    54  	defer bCleanup()
    55  
    56  	op, configCleanup, done := testOperationRefresh(t, "./testdata/refresh")
    57  	defer configCleanup()
    58  	defer done(t)
    59  
    60  	op.UIOut = b.CLI
    61  	b.CLIColor = b.cliColorize()
    62  	op.PlanMode = plans.RefreshOnlyMode
    63  	op.Workspace = testBackendSingleWorkspaceName
    64  
    65  	run, err := b.Operation(context.Background(), op)
    66  	if err != nil {
    67  		t.Fatalf("error starting operation: %v", err)
    68  	}
    69  
    70  	<-run.Done()
    71  	if run.Result != backend.OperationSuccess {
    72  		t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
    73  	}
    74  
    75  	output := b.CLI.(*cli.MockUi).OutputWriter.String()
    76  	if !strings.Contains(output, "Proceeding with 'tofu apply -refresh-only -auto-approve'") {
    77  		t.Fatalf("expected TFC header in output: %s", output)
    78  	}
    79  
    80  	stateMgr, _ := b.StateMgr(testBackendSingleWorkspaceName)
    81  	// An error suggests that the state was not unlocked after apply
    82  	if _, err := stateMgr.Lock(statemgr.NewLockInfo()); err != nil {
    83  		t.Fatalf("unexpected error locking state after apply: %s", err.Error())
    84  	}
    85  }