github.com/opentofu/opentofu@v1.7.1/internal/states/statemgr/migrate_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 statemgr
     7  
     8  import (
     9  	"testing"
    10  
    11  	"github.com/zclconf/go-cty/cty"
    12  
    13  	"github.com/opentofu/opentofu/internal/addrs"
    14  	"github.com/opentofu/opentofu/internal/states"
    15  	"github.com/opentofu/opentofu/internal/states/statefile"
    16  )
    17  
    18  func TestCheckValidImport(t *testing.T) {
    19  	barState := states.BuildState(func(s *states.SyncState) {
    20  		s.SetOutputValue(
    21  			addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
    22  			cty.StringVal("bar"), false,
    23  		)
    24  	})
    25  	notBarState := states.BuildState(func(s *states.SyncState) {
    26  		s.SetOutputValue(
    27  			addrs.OutputValue{Name: "foo"}.Absolute(addrs.RootModuleInstance),
    28  			cty.StringVal("not bar"), false,
    29  		)
    30  	})
    31  	emptyState := states.NewState()
    32  
    33  	tests := map[string]struct {
    34  		New      *statefile.File
    35  		Existing *statefile.File
    36  		WantErr  string
    37  	}{
    38  		"exact match": {
    39  			New:      statefile.New(barState, "lineage", 1),
    40  			Existing: statefile.New(barState, "lineage", 1),
    41  			WantErr:  ``,
    42  		},
    43  		"overwrite unrelated empty state": {
    44  			New:      statefile.New(barState, "lineage1", 1),
    45  			Existing: statefile.New(emptyState, "lineage2", 1),
    46  			WantErr:  ``,
    47  		},
    48  		"different state with same serial": {
    49  			New:      statefile.New(barState, "lineage", 1),
    50  			Existing: statefile.New(notBarState, "lineage", 1),
    51  			WantErr:  `cannot overwrite existing state with serial 1 with a different state that has the same serial`,
    52  		},
    53  		"different state with newer serial": {
    54  			New:      statefile.New(barState, "lineage", 2),
    55  			Existing: statefile.New(notBarState, "lineage", 1),
    56  			WantErr:  ``,
    57  		},
    58  		"different state with older serial": {
    59  			New:      statefile.New(barState, "lineage", 1),
    60  			Existing: statefile.New(notBarState, "lineage", 2),
    61  			WantErr:  `cannot import state with serial 1 over newer state with serial 2`,
    62  		},
    63  		"different lineage with same serial": {
    64  			New:      statefile.New(barState, "lineage1", 2),
    65  			Existing: statefile.New(notBarState, "lineage2", 2),
    66  			WantErr:  `cannot import state with lineage "lineage1" over unrelated state with lineage "lineage2"`,
    67  		},
    68  		"different lineage with different serial": {
    69  			New:      statefile.New(barState, "lineage1", 3),
    70  			Existing: statefile.New(notBarState, "lineage2", 2),
    71  			WantErr:  `cannot import state with lineage "lineage1" over unrelated state with lineage "lineage2"`,
    72  		},
    73  		"new state is legacy": {
    74  			New:      statefile.New(barState, "", 2),
    75  			Existing: statefile.New(notBarState, "lineage", 2),
    76  			WantErr:  ``,
    77  		},
    78  		"old state is legacy": {
    79  			New:      statefile.New(barState, "lineage", 2),
    80  			Existing: statefile.New(notBarState, "", 2),
    81  			WantErr:  ``,
    82  		},
    83  		"both states are legacy": {
    84  			New:      statefile.New(barState, "", 2),
    85  			Existing: statefile.New(notBarState, "", 2),
    86  			WantErr:  ``,
    87  		},
    88  	}
    89  
    90  	for name, test := range tests {
    91  		t.Run(name, func(t *testing.T) {
    92  			gotErr := CheckValidImport(test.New, test.Existing)
    93  
    94  			if test.WantErr == "" {
    95  				if gotErr != nil {
    96  					t.Errorf("unexpected error: %s", gotErr)
    97  				}
    98  			} else {
    99  				if gotErr == nil {
   100  					t.Errorf("succeeded, but want error: %s", test.WantErr)
   101  				} else if got, want := gotErr.Error(), test.WantErr; got != want {
   102  					t.Errorf("wrong error\ngot:  %s\nwant: %s", got, want)
   103  				}
   104  			}
   105  		})
   106  	}
   107  }