github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/state_list_test.go (about) 1 // Copyright (c) HashiCorp, Inc. 2 // SPDX-License-Identifier: MPL-2.0 3 4 package command 5 6 import ( 7 "strings" 8 "testing" 9 10 "github.com/mitchellh/cli" 11 ) 12 13 func TestStateList(t *testing.T) { 14 state := testState() 15 statePath := testStateFile(t, state) 16 17 p := testProvider() 18 ui := cli.NewMockUi() 19 c := &StateListCommand{ 20 Meta: Meta{ 21 testingOverrides: metaOverridesForProvider(p), 22 Ui: ui, 23 }, 24 } 25 26 args := []string{ 27 "-state", statePath, 28 } 29 if code := c.Run(args); code != 0 { 30 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 31 } 32 33 // Test that outputs were displayed 34 expected := strings.TrimSpace(testStateListOutput) + "\n" 35 actual := ui.OutputWriter.String() 36 if actual != expected { 37 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 38 } 39 } 40 41 func TestStateListWithID(t *testing.T) { 42 state := testState() 43 statePath := testStateFile(t, state) 44 45 p := testProvider() 46 ui := cli.NewMockUi() 47 c := &StateListCommand{ 48 Meta: Meta{ 49 testingOverrides: metaOverridesForProvider(p), 50 Ui: ui, 51 }, 52 } 53 54 args := []string{ 55 "-state", statePath, 56 "-id", "bar", 57 } 58 if code := c.Run(args); code != 0 { 59 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 60 } 61 62 // Test that outputs were displayed 63 expected := strings.TrimSpace(testStateListOutput) + "\n" 64 actual := ui.OutputWriter.String() 65 if actual != expected { 66 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 67 } 68 } 69 70 func TestStateListWithNonExistentID(t *testing.T) { 71 state := testState() 72 statePath := testStateFile(t, state) 73 74 p := testProvider() 75 ui := cli.NewMockUi() 76 c := &StateListCommand{ 77 Meta: Meta{ 78 testingOverrides: metaOverridesForProvider(p), 79 Ui: ui, 80 }, 81 } 82 83 args := []string{ 84 "-state", statePath, 85 "-id", "baz", 86 } 87 if code := c.Run(args); code != 0 { 88 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 89 } 90 91 // Test that output is empty 92 if ui.OutputWriter != nil { 93 actual := ui.OutputWriter.String() 94 if actual != "" { 95 t.Fatalf("Expected an empty output but got: %q", actual) 96 } 97 } 98 } 99 100 func TestStateList_backendDefaultState(t *testing.T) { 101 // Create a temporary working directory that is empty 102 td := t.TempDir() 103 testCopyDir(t, testFixturePath("state-list-backend-default"), td) 104 defer testChdir(t, td)() 105 106 p := testProvider() 107 ui := cli.NewMockUi() 108 c := &StateListCommand{ 109 Meta: Meta{ 110 testingOverrides: metaOverridesForProvider(p), 111 Ui: ui, 112 }, 113 } 114 115 args := []string{} 116 if code := c.Run(args); code != 0 { 117 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 118 } 119 120 // Test that outputs were displayed 121 expected := "null_resource.a\n" 122 actual := ui.OutputWriter.String() 123 if actual != expected { 124 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 125 } 126 } 127 128 func TestStateList_backendCustomState(t *testing.T) { 129 // Create a temporary working directory that is empty 130 td := t.TempDir() 131 testCopyDir(t, testFixturePath("state-list-backend-custom"), td) 132 defer testChdir(t, td)() 133 134 p := testProvider() 135 ui := cli.NewMockUi() 136 c := &StateListCommand{ 137 Meta: Meta{ 138 testingOverrides: metaOverridesForProvider(p), 139 Ui: ui, 140 }, 141 } 142 143 args := []string{} 144 if code := c.Run(args); code != 0 { 145 t.Fatalf("bad: %d\n\n%s", code, ui.ErrorWriter.String()) 146 } 147 148 // Test that outputs were displayed 149 expected := "null_resource.a\n" 150 actual := ui.OutputWriter.String() 151 if actual != expected { 152 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 153 } 154 } 155 156 func TestStateList_backendOverrideState(t *testing.T) { 157 // Create a temporary working directory that is empty 158 td := t.TempDir() 159 testCopyDir(t, testFixturePath("state-list-backend-custom"), td) 160 defer testChdir(t, td)() 161 162 p := testProvider() 163 ui := cli.NewMockUi() 164 c := &StateListCommand{ 165 Meta: Meta{ 166 testingOverrides: metaOverridesForProvider(p), 167 Ui: ui, 168 }, 169 } 170 171 // This test is configured to use a local backend that has 172 // a custom path defined. So we test if we can still pass 173 // is a user defined state file that will then override the 174 // one configured in the backend. As this file does not exist 175 // it should exit with a no state found error. 176 args := []string{"-state=" + DefaultStateFilename} 177 if code := c.Run(args); code != 1 { 178 t.Fatalf("bad: %d", code) 179 } 180 if !strings.Contains(ui.ErrorWriter.String(), "No state file was found!") { 181 t.Fatalf("expected a no state file error, got: %s", ui.ErrorWriter.String()) 182 } 183 } 184 185 func TestStateList_noState(t *testing.T) { 186 testCwd(t) 187 188 p := testProvider() 189 ui := cli.NewMockUi() 190 c := &StateListCommand{ 191 Meta: Meta{ 192 testingOverrides: metaOverridesForProvider(p), 193 Ui: ui, 194 }, 195 } 196 197 args := []string{} 198 if code := c.Run(args); code != 1 { 199 t.Fatalf("bad: %d", code) 200 } 201 } 202 203 func TestStateList_modules(t *testing.T) { 204 // Create a temporary working directory that is empty 205 td := t.TempDir() 206 testCopyDir(t, testFixturePath("state-list-nested-modules"), td) 207 defer testChdir(t, td)() 208 209 p := testProvider() 210 ui := cli.NewMockUi() 211 c := &StateListCommand{ 212 Meta: Meta{ 213 testingOverrides: metaOverridesForProvider(p), 214 Ui: ui, 215 }, 216 } 217 218 t.Run("list resources in module and submodules", func(t *testing.T) { 219 args := []string{"module.nest"} 220 if code := c.Run(args); code != 0 { 221 t.Fatalf("bad: %d", code) 222 } 223 224 // resources in the module and any submodules should be included in the outputs 225 expected := "module.nest.test_instance.nest\nmodule.nest.module.subnest.test_instance.subnest\n" 226 actual := ui.OutputWriter.String() 227 if actual != expected { 228 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 229 } 230 }) 231 232 t.Run("submodule has resources only", func(t *testing.T) { 233 // now get the state for a module that has no resources, only another nested module 234 ui.OutputWriter.Reset() 235 args := []string{"module.nonexist"} 236 if code := c.Run(args); code != 0 { 237 t.Fatalf("bad: %d", code) 238 } 239 expected := "module.nonexist.module.child.test_instance.child\n" 240 actual := ui.OutputWriter.String() 241 if actual != expected { 242 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 243 } 244 }) 245 246 t.Run("expanded module", func(t *testing.T) { 247 // finally get the state for a module with an index 248 ui.OutputWriter.Reset() 249 args := []string{"module.count"} 250 if code := c.Run(args); code != 0 { 251 t.Fatalf("bad: %d", code) 252 } 253 expected := "module.count[0].test_instance.count\nmodule.count[1].test_instance.count\n" 254 actual := ui.OutputWriter.String() 255 if actual != expected { 256 t.Fatalf("Expected:\n%q\n\nTo equal: %q", actual, expected) 257 } 258 }) 259 260 t.Run("completely nonexistent module", func(t *testing.T) { 261 // finally get the state for a module with an index 262 ui.OutputWriter.Reset() 263 args := []string{"module.notevenalittlebit"} 264 if code := c.Run(args); code != 1 { 265 t.Fatalf("bad: %d", code) 266 } 267 }) 268 269 } 270 271 const testStateListOutput = ` 272 test_instance.foo 273 `