github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/command/format/state_test.go (about)

     1  package format
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/internal/addrs"
     8  	"github.com/hashicorp/terraform/internal/configs/configschema"
     9  	"github.com/hashicorp/terraform/internal/providers"
    10  	"github.com/hashicorp/terraform/internal/states"
    11  	"github.com/hashicorp/terraform/internal/terraform"
    12  	"github.com/zclconf/go-cty/cty"
    13  )
    14  
    15  func TestState(t *testing.T) {
    16  	tests := []struct {
    17  		State *StateOpts
    18  		Want  string
    19  	}{
    20  		{
    21  			&StateOpts{
    22  				State:   &states.State{},
    23  				Color:   disabledColorize,
    24  				Schemas: &terraform.Schemas{},
    25  			},
    26  			"The state file is empty. No resources are represented.",
    27  		},
    28  		{
    29  			&StateOpts{
    30  				State:   basicState(t),
    31  				Color:   disabledColorize,
    32  				Schemas: testSchemas(),
    33  			},
    34  			basicStateOutput,
    35  		},
    36  		{
    37  			&StateOpts{
    38  				State:   nestedState(t),
    39  				Color:   disabledColorize,
    40  				Schemas: testSchemas(),
    41  			},
    42  			nestedStateOutput,
    43  		},
    44  		{
    45  			&StateOpts{
    46  				State:   deposedState(t),
    47  				Color:   disabledColorize,
    48  				Schemas: testSchemas(),
    49  			},
    50  			deposedNestedStateOutput,
    51  		},
    52  		{
    53  			&StateOpts{
    54  				State:   onlyDeposedState(t),
    55  				Color:   disabledColorize,
    56  				Schemas: testSchemas(),
    57  			},
    58  			onlyDeposedOutput,
    59  		},
    60  		{
    61  			&StateOpts{
    62  				State:   stateWithMoreOutputs(t),
    63  				Color:   disabledColorize,
    64  				Schemas: testSchemas(),
    65  			},
    66  			stateWithMoreOutputsOutput,
    67  		},
    68  	}
    69  
    70  	for i, tt := range tests {
    71  		t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
    72  			got := State(tt.State)
    73  			if got != tt.Want {
    74  				t.Errorf(
    75  					"wrong result\ninput: %v\ngot: \n%q\nwant: \n%q",
    76  					tt.State.State, got, tt.Want,
    77  				)
    78  			}
    79  		})
    80  	}
    81  }
    82  
    83  func testProvider() *terraform.MockProvider {
    84  	p := new(terraform.MockProvider)
    85  	p.ReadResourceFn = func(req providers.ReadResourceRequest) providers.ReadResourceResponse {
    86  		return providers.ReadResourceResponse{NewState: req.PriorState}
    87  	}
    88  
    89  	p.GetProviderSchemaResponse = testProviderSchema()
    90  
    91  	return p
    92  }
    93  
    94  func testProviderSchema() *providers.GetProviderSchemaResponse {
    95  	return &providers.GetProviderSchemaResponse{
    96  		Provider: providers.Schema{
    97  			Block: &configschema.Block{
    98  				Attributes: map[string]*configschema.Attribute{
    99  					"region": {Type: cty.String, Optional: true},
   100  				},
   101  			},
   102  		},
   103  		ResourceTypes: map[string]providers.Schema{
   104  			"test_resource": {
   105  				Block: &configschema.Block{
   106  					Attributes: map[string]*configschema.Attribute{
   107  						"id":      {Type: cty.String, Computed: true},
   108  						"foo":     {Type: cty.String, Optional: true},
   109  						"woozles": {Type: cty.String, Optional: true},
   110  					},
   111  					BlockTypes: map[string]*configschema.NestedBlock{
   112  						"nested": {
   113  							Nesting: configschema.NestingList,
   114  							Block: configschema.Block{
   115  								Attributes: map[string]*configschema.Attribute{
   116  									"compute": {Type: cty.String, Optional: true},
   117  									"value":   {Type: cty.String, Optional: true},
   118  								},
   119  							},
   120  						},
   121  					},
   122  				},
   123  			},
   124  		},
   125  		DataSources: map[string]providers.Schema{
   126  			"test_data_source": {
   127  				Block: &configschema.Block{
   128  					Attributes: map[string]*configschema.Attribute{
   129  						"compute": {Type: cty.String, Optional: true},
   130  						"value":   {Type: cty.String, Computed: true},
   131  					},
   132  				},
   133  			},
   134  		},
   135  	}
   136  }
   137  
   138  func testSchemas() *terraform.Schemas {
   139  	provider := testProvider()
   140  	return &terraform.Schemas{
   141  		Providers: map[addrs.Provider]*terraform.ProviderSchema{
   142  			addrs.NewDefaultProvider("test"): provider.ProviderSchema(),
   143  		},
   144  	}
   145  }
   146  
   147  const basicStateOutput = `# data.test_data_source.data:
   148  data "test_data_source" "data" {
   149      compute = "sure"
   150  }
   151  
   152  # test_resource.baz[0]:
   153  resource "test_resource" "baz" {
   154      woozles = "confuzles"
   155  }
   156  
   157  
   158  Outputs:
   159  
   160  bar = "bar value"`
   161  
   162  const nestedStateOutput = `# test_resource.baz[0]:
   163  resource "test_resource" "baz" {
   164      woozles = "confuzles"
   165  
   166      nested {
   167          value = "42"
   168      }
   169  }`
   170  
   171  const deposedNestedStateOutput = `# test_resource.baz[0]:
   172  resource "test_resource" "baz" {
   173      woozles = "confuzles"
   174  
   175      nested {
   176          value = "42"
   177      }
   178  }
   179  
   180  # test_resource.baz[0]: (deposed object 1234)
   181  resource "test_resource" "baz" {
   182      woozles = "confuzles"
   183  
   184      nested {
   185          value = "42"
   186      }
   187  }`
   188  
   189  const onlyDeposedOutput = `# test_resource.baz[0]:
   190  # test_resource.baz[0]: (deposed object 1234)
   191  resource "test_resource" "baz" {
   192      woozles = "confuzles"
   193  
   194      nested {
   195          value = "42"
   196      }
   197  }
   198  
   199  # test_resource.baz[0]: (deposed object 5678)
   200  resource "test_resource" "baz" {
   201      woozles = "confuzles"
   202  
   203      nested {
   204          value = "42"
   205      }
   206  }`
   207  
   208  const stateWithMoreOutputsOutput = `# test_resource.baz[0]:
   209  resource "test_resource" "baz" {
   210      woozles = "confuzles"
   211  }
   212  
   213  
   214  Outputs:
   215  
   216  bool_var = true
   217  int_var = 42
   218  map_var = {
   219      "first"  = "foo"
   220      "second" = "bar"
   221  }
   222  sensitive_var = (sensitive value)
   223  string_var = "string value"`
   224  
   225  func basicState(t *testing.T) *states.State {
   226  	state := states.NewState()
   227  
   228  	rootModule := state.RootModule()
   229  	if rootModule == nil {
   230  		t.Errorf("root module is nil; want valid object")
   231  	}
   232  
   233  	rootModule.SetLocalValue("foo", cty.StringVal("foo value"))
   234  	rootModule.SetOutputValue("bar", cty.StringVal("bar value"), false)
   235  	rootModule.SetResourceInstanceCurrent(
   236  		addrs.Resource{
   237  			Mode: addrs.ManagedResourceMode,
   238  			Type: "test_resource",
   239  			Name: "baz",
   240  		}.Instance(addrs.IntKey(0)),
   241  		&states.ResourceInstanceObjectSrc{
   242  			Status:        states.ObjectReady,
   243  			SchemaVersion: 1,
   244  			AttrsJSON:     []byte(`{"woozles":"confuzles"}`),
   245  		},
   246  		addrs.AbsProviderConfig{
   247  			Provider: addrs.NewDefaultProvider("test"),
   248  			Module:   addrs.RootModule,
   249  		},
   250  	)
   251  	rootModule.SetResourceInstanceCurrent(
   252  		addrs.Resource{
   253  			Mode: addrs.DataResourceMode,
   254  			Type: "test_data_source",
   255  			Name: "data",
   256  		}.Instance(addrs.NoKey),
   257  		&states.ResourceInstanceObjectSrc{
   258  			Status:        states.ObjectReady,
   259  			SchemaVersion: 1,
   260  			AttrsJSON:     []byte(`{"compute":"sure"}`),
   261  		},
   262  		addrs.AbsProviderConfig{
   263  			Provider: addrs.NewDefaultProvider("test"),
   264  			Module:   addrs.RootModule,
   265  		},
   266  	)
   267  	return state
   268  }
   269  
   270  func stateWithMoreOutputs(t *testing.T) *states.State {
   271  	state := states.NewState()
   272  
   273  	rootModule := state.RootModule()
   274  	if rootModule == nil {
   275  		t.Errorf("root module is nil; want valid object")
   276  	}
   277  
   278  	rootModule.SetOutputValue("string_var", cty.StringVal("string value"), false)
   279  	rootModule.SetOutputValue("int_var", cty.NumberIntVal(42), false)
   280  	rootModule.SetOutputValue("bool_var", cty.BoolVal(true), false)
   281  	rootModule.SetOutputValue("sensitive_var", cty.StringVal("secret!!!"), true)
   282  	rootModule.SetOutputValue("map_var", cty.MapVal(map[string]cty.Value{
   283  		"first":  cty.StringVal("foo"),
   284  		"second": cty.StringVal("bar"),
   285  	}), false)
   286  
   287  	rootModule.SetResourceInstanceCurrent(
   288  		addrs.Resource{
   289  			Mode: addrs.ManagedResourceMode,
   290  			Type: "test_resource",
   291  			Name: "baz",
   292  		}.Instance(addrs.IntKey(0)),
   293  		&states.ResourceInstanceObjectSrc{
   294  			Status:        states.ObjectReady,
   295  			SchemaVersion: 1,
   296  			AttrsJSON:     []byte(`{"woozles":"confuzles"}`),
   297  		},
   298  		addrs.AbsProviderConfig{
   299  			Provider: addrs.NewDefaultProvider("test"),
   300  			Module:   addrs.RootModule,
   301  		},
   302  	)
   303  	return state
   304  }
   305  
   306  func nestedState(t *testing.T) *states.State {
   307  	state := states.NewState()
   308  
   309  	rootModule := state.RootModule()
   310  	if rootModule == nil {
   311  		t.Errorf("root module is nil; want valid object")
   312  	}
   313  
   314  	rootModule.SetResourceInstanceCurrent(
   315  		addrs.Resource{
   316  			Mode: addrs.ManagedResourceMode,
   317  			Type: "test_resource",
   318  			Name: "baz",
   319  		}.Instance(addrs.IntKey(0)),
   320  		&states.ResourceInstanceObjectSrc{
   321  			Status:        states.ObjectReady,
   322  			SchemaVersion: 1,
   323  			AttrsJSON:     []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
   324  		},
   325  		addrs.AbsProviderConfig{
   326  			Provider: addrs.NewDefaultProvider("test"),
   327  			Module:   addrs.RootModule,
   328  		},
   329  	)
   330  	return state
   331  }
   332  
   333  func deposedState(t *testing.T) *states.State {
   334  	state := nestedState(t)
   335  	rootModule := state.RootModule()
   336  	rootModule.SetResourceInstanceDeposed(
   337  		addrs.Resource{
   338  			Mode: addrs.ManagedResourceMode,
   339  			Type: "test_resource",
   340  			Name: "baz",
   341  		}.Instance(addrs.IntKey(0)),
   342  		states.DeposedKey("1234"),
   343  		&states.ResourceInstanceObjectSrc{
   344  			Status:        states.ObjectReady,
   345  			SchemaVersion: 1,
   346  			AttrsJSON:     []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
   347  		},
   348  		addrs.AbsProviderConfig{
   349  			Provider: addrs.NewDefaultProvider("test"),
   350  			Module:   addrs.RootModule,
   351  		},
   352  	)
   353  	return state
   354  }
   355  
   356  // replicate a corrupt resource where only a deposed exists
   357  func onlyDeposedState(t *testing.T) *states.State {
   358  	state := states.NewState()
   359  
   360  	rootModule := state.RootModule()
   361  	if rootModule == nil {
   362  		t.Errorf("root module is nil; want valid object")
   363  	}
   364  
   365  	rootModule.SetResourceInstanceDeposed(
   366  		addrs.Resource{
   367  			Mode: addrs.ManagedResourceMode,
   368  			Type: "test_resource",
   369  			Name: "baz",
   370  		}.Instance(addrs.IntKey(0)),
   371  		states.DeposedKey("1234"),
   372  		&states.ResourceInstanceObjectSrc{
   373  			Status:        states.ObjectReady,
   374  			SchemaVersion: 1,
   375  			AttrsJSON:     []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
   376  		},
   377  		addrs.AbsProviderConfig{
   378  			Provider: addrs.NewDefaultProvider("test"),
   379  			Module:   addrs.RootModule,
   380  		},
   381  	)
   382  	rootModule.SetResourceInstanceDeposed(
   383  		addrs.Resource{
   384  			Mode: addrs.ManagedResourceMode,
   385  			Type: "test_resource",
   386  			Name: "baz",
   387  		}.Instance(addrs.IntKey(0)),
   388  		states.DeposedKey("5678"),
   389  		&states.ResourceInstanceObjectSrc{
   390  			Status:        states.ObjectReady,
   391  			SchemaVersion: 1,
   392  			AttrsJSON:     []byte(`{"woozles":"confuzles","nested": [{"value": "42"}]}`),
   393  		},
   394  		addrs.AbsProviderConfig{
   395  			Provider: addrs.NewDefaultProvider("test"),
   396  			Module:   addrs.RootModule,
   397  		},
   398  	)
   399  	return state
   400  }