github.com/replicatedhq/ship@v0.55.0/pkg/lifecycle/terraform/state_test.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "path" 6 "strings" 7 "testing" 8 9 "github.com/go-test/deep" 10 "github.com/golang/mock/gomock" 11 "github.com/hashicorp/terraform/terraform" 12 "github.com/replicatedhq/ship/pkg/state" 13 state2 "github.com/replicatedhq/ship/pkg/test-mocks/state" 14 "github.com/replicatedhq/ship/pkg/testing/logger" 15 "github.com/replicatedhq/ship/pkg/testing/matchers" 16 "github.com/spf13/afero" 17 "github.com/stretchr/testify/require" 18 ) 19 20 func TestPersistState(t *testing.T) { 21 tests := []struct { 22 name string 23 state string 24 instate state.State 25 outstate state.State 26 }{ 27 { 28 name: "post-delete state, mostly empty", 29 state: `{ 30 "version": 3, 31 "terraform_version": "0.11.9", 32 "serial": 3, 33 "lineage": "3218b0ca-45de-2227-e420-f0d948f91e86", 34 "modules": [ 35 { 36 "path": [ 37 "root" 38 ], 39 "outputs": {}, 40 "resources": {}, 41 "depends_on": [] 42 } 43 ] 44 } 45 `, 46 instate: state.State{ 47 V1: &state.V1{}, 48 }, 49 outstate: state.State{ 50 V1: &state.V1{ 51 Terraform: &state.Terraform{ 52 RawState: `{ 53 "version": 3, 54 "terraform_version": "0.11.9", 55 "serial": 3, 56 "lineage": "3218b0ca-45de-2227-e420-f0d948f91e86", 57 "modules": [ 58 { 59 "path": [ 60 "root" 61 ], 62 "outputs": {}, 63 "resources": {}, 64 "depends_on": [] 65 } 66 ] 67 } 68 `, 69 State: &terraform.State{ 70 Version: 3, 71 TFVersion: "0.11.9", 72 Serial: 3, 73 Lineage: "3218b0ca-45de-2227-e420-f0d948f91e86", 74 Modules: []*terraform.ModuleState{ 75 { 76 Path: []string{ 77 "root", 78 }, 79 Outputs: map[string]*terraform.OutputState{}, 80 Resources: map[string]*terraform.ResourceState{}, 81 Dependencies: []string{}, 82 }, 83 }, 84 }, 85 }, 86 }, 87 }, 88 }, 89 } 90 for _, test := range tests { 91 t.Run(test.name, func(t *testing.T) { 92 mc := gomock.NewController(t) 93 req := require.New(t) 94 debug := &logger.TestLogger{T: t} 95 mockFs := afero.Afero{Fs: afero.NewMemMapFs()} 96 statemanager := state2.NewMockManager(mc) 97 98 err := mockFs.WriteFile("installer/terraform.tfstate", []byte(test.state), 0644) 99 req.NoError(err) 100 101 statemanager.EXPECT().CachedState().Return(test.instate, nil) 102 statemanager.EXPECT().Save(&matchers.Is{ 103 Test: func(v interface{}) bool { 104 vstate := v.(state.State) 105 diff := deep.Equal(*vstate.V1.Terraform, *test.outstate.V1.Terraform) 106 t.Log(strings.Join(diff, "\n")) 107 return len(diff) == 0 108 }, 109 Describe: fmt.Sprintf("equal to %+v", *test.outstate.V1.Terraform), 110 }).Return(nil) 111 112 err = persistState(debug, mockFs, statemanager, "installer") 113 req.NoError(err) 114 115 mc.Finish() 116 117 }) 118 } 119 } 120 121 func TestRestoreState(t *testing.T) { 122 tests := []struct { 123 name string 124 instate state.State 125 expectFile string 126 }{ 127 { 128 name: "post-delete state, mostly empty", 129 expectFile: `{ 130 "version": 3, 131 "terraform_version": "0.11.9", 132 "serial": 3, 133 "lineage": "3218b0ca-45de-2227-e420-f0d948f91e86", 134 "modules": [ 135 { 136 "path": [ 137 "root" 138 ], 139 "outputs": {}, 140 "resources": {}, 141 "depends_on": [] 142 } 143 ] 144 } 145 `, 146 instate: state.State{ 147 V1: &state.V1{ 148 Terraform: &state.Terraform{ 149 RawState: `{ 150 "version": 3, 151 "terraform_version": "0.11.9", 152 "serial": 3, 153 "lineage": "3218b0ca-45de-2227-e420-f0d948f91e86", 154 "modules": [ 155 { 156 "path": [ 157 "root" 158 ], 159 "outputs": {}, 160 "resources": {}, 161 "depends_on": [] 162 } 163 ] 164 } 165 `, 166 State: &terraform.State{ 167 Version: 3, 168 TFVersion: "0.11.9", 169 Serial: 3, 170 Lineage: "3218b0ca-45de-2227-e420-f0d948f91e86", 171 Modules: []*terraform.ModuleState{ 172 { 173 Path: []string{ 174 "root", 175 }, 176 Outputs: map[string]*terraform.OutputState{}, 177 Resources: map[string]*terraform.ResourceState{}, 178 Dependencies: []string{}, 179 }, 180 }, 181 }, 182 }, 183 }, 184 }, 185 }, 186 } 187 for _, test := range tests { 188 t.Run(test.name, func(t *testing.T) { 189 mc := gomock.NewController(t) 190 req := require.New(t) 191 debug := &logger.TestLogger{T: t} 192 mockFs := afero.Afero{Fs: afero.NewMemMapFs()} 193 statemanager := state2.NewMockManager(mc) 194 195 statemanager.EXPECT().CachedState().Return(test.instate, nil) 196 197 err := restoreState(debug, mockFs, statemanager, "installer") 198 req.NoError(err) 199 200 contents, err := mockFs.ReadFile(path.Join("installer", "terraform.tfstate")) 201 req.NoError(err) 202 203 req.Equal(test.expectFile, string(contents)) 204 205 mc.Finish() 206 207 }) 208 } 209 }