@ -487,6 +487,84 @@ func TestInit_backend(t *testing.T) {
}
}
// regression test for https://github.com/hashicorp/terraform/issues/38027
func TestInit_backend_migration_stateMgr_error ( t * testing . T ) {
// Create a temporary working directory that is empty
td := t . TempDir ( )
t . Chdir ( td )
{
// create some state in (implied) local backend
outputCfg := ` output "test" { value = "test" }
`
if err := os . WriteFile ( "output.tf" , [ ] byte ( outputCfg ) , 0644 ) ; err != nil {
t . Fatalf ( "err: %s" , err )
}
ui := new ( cli . MockUi )
applyView , done := testView ( t )
applyCmd := & ApplyCommand {
Meta : Meta {
Ui : ui ,
View : applyView ,
} ,
}
code := applyCmd . Run ( [ ] string { "-auto-approve" } )
testOut := done ( t )
if code != 0 {
t . Fatalf ( "bad: \n%s" , testOut . All ( ) )
}
if _ , err := os . Stat ( DefaultStateFilename ) ; err != nil {
t . Fatalf ( "err: %s" , err )
}
}
{
// attempt to migrate the state to a broken backend
testBackend := new ( httpBackend . TestHTTPBackend )
testBackend . SetMethodFunc ( "GET" , func ( w http . ResponseWriter , r * http . Request ) {
// simulate "broken backend" in the way described in #38027
// i.e. access denied
w . WriteHeader ( 403 )
} )
ts := httptest . NewServer ( http . HandlerFunc ( testBackend . Handle ) )
t . Cleanup ( ts . Close )
backendCfg := fmt . Sprintf ( ` terraform {
backend "http" {
address = % q
}
}
` , ts . URL )
if err := os . WriteFile ( "backend.tf" , [ ] byte ( backendCfg ) , 0644 ) ; err != nil {
t . Fatalf ( "err: %s" , err )
}
ui := new ( cli . MockUi )
initView , done := testView ( t )
initCmd := & InitCommand {
Meta : Meta {
Ui : ui ,
View : initView ,
} ,
}
code := initCmd . Run ( [ ] string { "-migrate-state" } )
out := done ( t )
if code == 0 {
t . Fatalf ( "expected migration to fail (gracefully): %s" , out . Stdout ( ) )
}
expectedErrMsg := "HTTP remote state endpoint invalid auth"
if ! strings . Contains ( out . Stderr ( ) , expectedErrMsg ) {
t . Fatalf ( "expected error %q, given: %s" , expectedErrMsg , out . Stderr ( ) )
}
getCalled := testBackend . CallCount ( "GET" )
if getCalled != 1 {
t . Fatalf ( "expected GET to be called exactly %d, called %d times" , 1 , getCalled )
}
}
}
func TestInit_backendUnset ( t * testing . T ) {
// Create a temporary working directory that is empty
td := t . TempDir ( )
@ -4344,8 +4422,6 @@ func TestInit_stateStore_to_backend(t *testing.T) {
testBackend := new ( httpBackend . TestHTTPBackend )
ts := httptest . NewServer ( http . HandlerFunc ( testBackend . Handle ) )
defer ts . Close ( )
t . Cleanup ( ts . Close )
// Override state store to backend
@ -4377,6 +4453,7 @@ func TestInit_stateStore_to_backend(t *testing.T) {
args := [ ] string {
"-enable-pluggable-state-storage-experiment=true" ,
"-migrate-state" ,
"-force-copy" ,
}
code := c . Run ( args )
@ -4414,13 +4491,13 @@ func TestInit_stateStore_to_backend(t *testing.T) {
t . Fatalf ( "unexpected data: %s" , diff )
}
expectedGetCalls := 4
if testBackend . GetCalled != expectedGetCalls {
t . Fatalf ( "expected %d GET calls, got %d" , expectedGetCalls , testBackend . GetCalled )
expectedGetCalls := 6
if testBackend . CallCount ( "GET" ) != expectedGetCalls {
t . Fatalf ( "expected %d GET calls, got %d" , expectedGetCalls , testBackend . CallCount ( "GET" ) )
}
expectedPostCalls := 1
if testBackend . PostCalled != expectedPostCalls {
t . Fatalf ( "expected %d POST calls, got %d" , expectedPostCalls , testBackend . PostCalled )
if testBackend . CallCount ( "POST" ) != expectedPostCalls {
t . Fatalf ( "expected %d POST calls, got %d" , expectedPostCalls , testBackend . CallCount ( "POST" ) )
}
}
}