github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/state_push_test.go (about) 1 package command 2 3 import ( 4 "bytes" 5 "strings" 6 "testing" 7 8 "github.com/hashicorp/terraform/internal/backend" 9 "github.com/hashicorp/terraform/internal/backend/remote-state/inmem" 10 "github.com/hashicorp/terraform/internal/states" 11 "github.com/mitchellh/cli" 12 ) 13 14 func TestStatePush_empty(t *testing.T) { 15 // Create a temporary working directory that is empty 16 td := t.TempDir() 17 testCopyDir(t, testFixturePath("state-push-good"), td) 18 defer testChdir(t, td)() 19 20 expected := testStateRead(t, "replace.tfstate") 21 22 p := testProvider() 23 ui := new(cli.MockUi) 24 view, _ := testView(t) 25 c := &StatePushCommand{ 26 Meta: Meta{ 27 testingOverrides: metaOverridesForProvider(p), 28 Ui: ui, 29 View: view, 30 }, 31 } 32 33 args := []string{"replace.tfstate"} 34 if code := c.Run(args); code != 0 { 35 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 36 } 37 38 actual := testStateRead(t, "local-state.tfstate") 39 if !actual.Equal(expected) { 40 t.Fatalf("bad: %#v", actual) 41 } 42 } 43 44 func TestStatePush_lockedState(t *testing.T) { 45 // Create a temporary working directory that is empty 46 td := t.TempDir() 47 testCopyDir(t, testFixturePath("state-push-good"), td) 48 defer testChdir(t, td)() 49 50 p := testProvider() 51 ui := new(cli.MockUi) 52 view, _ := testView(t) 53 c := &StatePushCommand{ 54 Meta: Meta{ 55 testingOverrides: metaOverridesForProvider(p), 56 Ui: ui, 57 View: view, 58 }, 59 } 60 61 unlock, err := testLockState(t, testDataDir, "local-state.tfstate") 62 if err != nil { 63 t.Fatal(err) 64 } 65 defer unlock() 66 67 args := []string{"replace.tfstate"} 68 if code := c.Run(args); code != 1 { 69 t.Fatalf("bad: %d", code) 70 } 71 if !strings.Contains(ui.ErrorWriter.String(), "Error acquiring the state lock") { 72 t.Fatalf("expected a lock error, got: %s", ui.ErrorWriter.String()) 73 } 74 } 75 76 func TestStatePush_replaceMatch(t *testing.T) { 77 // Create a temporary working directory that is empty 78 td := t.TempDir() 79 testCopyDir(t, testFixturePath("state-push-replace-match"), td) 80 defer testChdir(t, td)() 81 82 expected := testStateRead(t, "replace.tfstate") 83 84 p := testProvider() 85 ui := new(cli.MockUi) 86 view, _ := testView(t) 87 c := &StatePushCommand{ 88 Meta: Meta{ 89 testingOverrides: metaOverridesForProvider(p), 90 Ui: ui, 91 View: view, 92 }, 93 } 94 95 args := []string{"replace.tfstate"} 96 if code := c.Run(args); code != 0 { 97 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 98 } 99 100 actual := testStateRead(t, "local-state.tfstate") 101 if !actual.Equal(expected) { 102 t.Fatalf("bad: %#v", actual) 103 } 104 } 105 106 func TestStatePush_replaceMatchStdin(t *testing.T) { 107 // Create a temporary working directory that is empty 108 td := t.TempDir() 109 testCopyDir(t, testFixturePath("state-push-replace-match"), td) 110 defer testChdir(t, td)() 111 112 expected := testStateRead(t, "replace.tfstate") 113 114 // Set up the replacement to come from stdin 115 var buf bytes.Buffer 116 if err := writeStateForTesting(expected, &buf); err != nil { 117 t.Fatalf("err: %s", err) 118 } 119 defer testStdinPipe(t, &buf)() 120 121 p := testProvider() 122 ui := new(cli.MockUi) 123 view, _ := testView(t) 124 c := &StatePushCommand{ 125 Meta: Meta{ 126 testingOverrides: metaOverridesForProvider(p), 127 Ui: ui, 128 View: view, 129 }, 130 } 131 132 args := []string{"-force", "-"} 133 if code := c.Run(args); code != 0 { 134 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 135 } 136 137 actual := testStateRead(t, "local-state.tfstate") 138 if !actual.Equal(expected) { 139 t.Fatalf("bad: %#v", actual) 140 } 141 } 142 143 func TestStatePush_lineageMismatch(t *testing.T) { 144 // Create a temporary working directory that is empty 145 td := t.TempDir() 146 testCopyDir(t, testFixturePath("state-push-bad-lineage"), td) 147 defer testChdir(t, td)() 148 149 expected := testStateRead(t, "local-state.tfstate") 150 151 p := testProvider() 152 ui := cli.NewMockUi() 153 view, _ := testView(t) 154 c := &StatePushCommand{ 155 Meta: Meta{ 156 testingOverrides: metaOverridesForProvider(p), 157 Ui: ui, 158 View: view, 159 }, 160 } 161 162 args := []string{"replace.tfstate"} 163 if code := c.Run(args); code != 1 { 164 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 165 } 166 167 actual := testStateRead(t, "local-state.tfstate") 168 if !actual.Equal(expected) { 169 t.Fatalf("bad: %#v", actual) 170 } 171 } 172 173 func TestStatePush_serialNewer(t *testing.T) { 174 // Create a temporary working directory that is empty 175 td := t.TempDir() 176 testCopyDir(t, testFixturePath("state-push-serial-newer"), td) 177 defer testChdir(t, td)() 178 179 expected := testStateRead(t, "local-state.tfstate") 180 181 p := testProvider() 182 ui := new(cli.MockUi) 183 view, _ := testView(t) 184 c := &StatePushCommand{ 185 Meta: Meta{ 186 testingOverrides: metaOverridesForProvider(p), 187 Ui: ui, 188 View: view, 189 }, 190 } 191 192 args := []string{"replace.tfstate"} 193 if code := c.Run(args); code != 1 { 194 t.Fatalf("bad: %d", code) 195 } 196 197 actual := testStateRead(t, "local-state.tfstate") 198 if !actual.Equal(expected) { 199 t.Fatalf("bad: %#v", actual) 200 } 201 } 202 203 func TestStatePush_serialOlder(t *testing.T) { 204 // Create a temporary working directory that is empty 205 td := t.TempDir() 206 testCopyDir(t, testFixturePath("state-push-serial-older"), td) 207 defer testChdir(t, td)() 208 209 expected := testStateRead(t, "replace.tfstate") 210 211 p := testProvider() 212 ui := new(cli.MockUi) 213 view, _ := testView(t) 214 c := &StatePushCommand{ 215 Meta: Meta{ 216 testingOverrides: metaOverridesForProvider(p), 217 Ui: ui, 218 View: view, 219 }, 220 } 221 222 args := []string{"replace.tfstate"} 223 if code := c.Run(args); code != 0 { 224 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 225 } 226 227 actual := testStateRead(t, "local-state.tfstate") 228 if !actual.Equal(expected) { 229 t.Fatalf("bad: %#v", actual) 230 } 231 } 232 233 func TestStatePush_forceRemoteState(t *testing.T) { 234 td := t.TempDir() 235 testCopyDir(t, testFixturePath("inmem-backend"), td) 236 defer testChdir(t, td)() 237 defer inmem.Reset() 238 239 s := states.NewState() 240 statePath := testStateFile(t, s) 241 242 // init the backend 243 ui := new(cli.MockUi) 244 view, _ := testView(t) 245 initCmd := &InitCommand{ 246 Meta: Meta{Ui: ui, View: view}, 247 } 248 if code := initCmd.Run([]string{}); code != 0 { 249 t.Fatalf("bad: \n%s", ui.ErrorWriter.String()) 250 } 251 252 // create a new workspace 253 ui = new(cli.MockUi) 254 newCmd := &WorkspaceNewCommand{ 255 Meta: Meta{Ui: ui, View: view}, 256 } 257 if code := newCmd.Run([]string{"test"}); code != 0 { 258 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter) 259 } 260 261 // put a dummy state in place, so we have something to force 262 b := backend.TestBackendConfig(t, inmem.New(), nil) 263 sMgr, err := b.StateMgr("test") 264 if err != nil { 265 t.Fatal(err) 266 } 267 if err := sMgr.WriteState(states.NewState()); err != nil { 268 t.Fatal(err) 269 } 270 if err := sMgr.PersistState(nil); err != nil { 271 t.Fatal(err) 272 } 273 274 // push our local state to that new workspace 275 ui = new(cli.MockUi) 276 c := &StatePushCommand{ 277 Meta: Meta{Ui: ui, View: view}, 278 } 279 280 args := []string{"-force", statePath} 281 if code := c.Run(args); code != 0 { 282 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 283 } 284 } 285 286 func TestStatePush_checkRequiredVersion(t *testing.T) { 287 // Create a temporary working directory that is empty 288 td := t.TempDir() 289 testCopyDir(t, testFixturePath("command-check-required-version"), td) 290 defer testChdir(t, td)() 291 292 p := testProvider() 293 ui := cli.NewMockUi() 294 view, _ := testView(t) 295 c := &StatePushCommand{ 296 Meta: Meta{ 297 testingOverrides: metaOverridesForProvider(p), 298 Ui: ui, 299 View: view, 300 }, 301 } 302 303 args := []string{"replace.tfstate"} 304 if code := c.Run(args); code != 1 { 305 t.Fatalf("got exit status %d; want 1\nstderr:\n%s\n\nstdout:\n%s", code, ui.ErrorWriter.String(), ui.OutputWriter.String()) 306 } 307 308 // Required version diags are correct 309 errStr := ui.ErrorWriter.String() 310 if !strings.Contains(errStr, `required_version = "~> 0.9.0"`) { 311 t.Fatalf("output should point to unmet version constraint, but is:\n\n%s", errStr) 312 } 313 if strings.Contains(errStr, `required_version = ">= 0.13.0"`) { 314 t.Fatalf("output should not point to met version constraint, but is:\n\n%s", errStr) 315 } 316 }