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  `