github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/builtin/providers/terraform/resource_data_test.go (about)

     1  package terraform
     2  
     3  import (
     4  	"strings"
     5  	"testing"
     6  
     7  	"github.com/hashicorp/terraform/internal/providers"
     8  	"github.com/zclconf/go-cty/cty"
     9  	ctyjson "github.com/zclconf/go-cty/cty/json"
    10  )
    11  
    12  func TestManagedDataValidate(t *testing.T) {
    13  	cfg := map[string]cty.Value{
    14  		"input":            cty.NullVal(cty.DynamicPseudoType),
    15  		"output":           cty.NullVal(cty.DynamicPseudoType),
    16  		"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
    17  		"id":               cty.NullVal(cty.String),
    18  	}
    19  
    20  	// empty
    21  	req := providers.ValidateResourceConfigRequest{
    22  		TypeName: "terraform_data",
    23  		Config:   cty.ObjectVal(cfg),
    24  	}
    25  
    26  	resp := validateDataStoreResourceConfig(req)
    27  	if resp.Diagnostics.HasErrors() {
    28  		t.Error("empty config error:", resp.Diagnostics.ErrWithWarnings())
    29  	}
    30  
    31  	// invalid computed values
    32  	cfg["output"] = cty.StringVal("oops")
    33  	req.Config = cty.ObjectVal(cfg)
    34  
    35  	resp = validateDataStoreResourceConfig(req)
    36  	if !resp.Diagnostics.HasErrors() {
    37  		t.Error("expected error")
    38  	}
    39  
    40  	msg := resp.Diagnostics.Err().Error()
    41  	if !strings.Contains(msg, "attribute is read-only") {
    42  		t.Error("unexpected error", msg)
    43  	}
    44  }
    45  
    46  func TestManagedDataUpgradeState(t *testing.T) {
    47  	schema := dataStoreResourceSchema()
    48  	ty := schema.Block.ImpliedType()
    49  
    50  	state := cty.ObjectVal(map[string]cty.Value{
    51  		"input":  cty.StringVal("input"),
    52  		"output": cty.StringVal("input"),
    53  		"triggers_replace": cty.ListVal([]cty.Value{
    54  			cty.StringVal("a"), cty.StringVal("b"),
    55  		}),
    56  		"id": cty.StringVal("not-quite-unique"),
    57  	})
    58  
    59  	jsState, err := ctyjson.Marshal(state, ty)
    60  	if err != nil {
    61  		t.Fatal(err)
    62  	}
    63  
    64  	// empty
    65  	req := providers.UpgradeResourceStateRequest{
    66  		TypeName:     "terraform_data",
    67  		RawStateJSON: jsState,
    68  	}
    69  
    70  	resp := upgradeDataStoreResourceState(req)
    71  	if resp.Diagnostics.HasErrors() {
    72  		t.Error("upgrade state error:", resp.Diagnostics.ErrWithWarnings())
    73  	}
    74  
    75  	if !resp.UpgradedState.RawEquals(state) {
    76  		t.Errorf("prior state was:\n%#v\nupgraded state is:\n%#v\n", state, resp.UpgradedState)
    77  	}
    78  }
    79  
    80  func TestManagedDataRead(t *testing.T) {
    81  	req := providers.ReadResourceRequest{
    82  		TypeName: "terraform_data",
    83  		PriorState: cty.ObjectVal(map[string]cty.Value{
    84  			"input":  cty.StringVal("input"),
    85  			"output": cty.StringVal("input"),
    86  			"triggers_replace": cty.ListVal([]cty.Value{
    87  				cty.StringVal("a"), cty.StringVal("b"),
    88  			}),
    89  			"id": cty.StringVal("not-quite-unique"),
    90  		}),
    91  	}
    92  
    93  	resp := readDataStoreResourceState(req)
    94  	if resp.Diagnostics.HasErrors() {
    95  		t.Fatal("unexpected error", resp.Diagnostics.ErrWithWarnings())
    96  	}
    97  
    98  	if !resp.NewState.RawEquals(req.PriorState) {
    99  		t.Errorf("prior state was:\n%#v\nnew state is:\n%#v\n", req.PriorState, resp.NewState)
   100  	}
   101  }
   102  
   103  func TestManagedDataPlan(t *testing.T) {
   104  	schema := dataStoreResourceSchema().Block
   105  	ty := schema.ImpliedType()
   106  
   107  	for name, tc := range map[string]struct {
   108  		prior    cty.Value
   109  		proposed cty.Value
   110  		planned  cty.Value
   111  	}{
   112  		"create": {
   113  			prior: cty.NullVal(ty),
   114  			proposed: cty.ObjectVal(map[string]cty.Value{
   115  				"input":            cty.NullVal(cty.DynamicPseudoType),
   116  				"output":           cty.NullVal(cty.DynamicPseudoType),
   117  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   118  				"id":               cty.NullVal(cty.String),
   119  			}),
   120  			planned: cty.ObjectVal(map[string]cty.Value{
   121  				"input":            cty.NullVal(cty.DynamicPseudoType),
   122  				"output":           cty.NullVal(cty.DynamicPseudoType),
   123  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   124  				"id":               cty.UnknownVal(cty.String),
   125  			}),
   126  		},
   127  
   128  		"create-typed-null-input": {
   129  			prior: cty.NullVal(ty),
   130  			proposed: cty.ObjectVal(map[string]cty.Value{
   131  				"input":            cty.NullVal(cty.String),
   132  				"output":           cty.NullVal(cty.DynamicPseudoType),
   133  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   134  				"id":               cty.NullVal(cty.String),
   135  			}),
   136  			planned: cty.ObjectVal(map[string]cty.Value{
   137  				"input":            cty.NullVal(cty.String),
   138  				"output":           cty.NullVal(cty.String),
   139  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   140  				"id":               cty.UnknownVal(cty.String),
   141  			}),
   142  		},
   143  
   144  		"create-output": {
   145  			prior: cty.NullVal(ty),
   146  			proposed: cty.ObjectVal(map[string]cty.Value{
   147  				"input":            cty.StringVal("input"),
   148  				"output":           cty.NullVal(cty.DynamicPseudoType),
   149  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   150  				"id":               cty.NullVal(cty.String),
   151  			}),
   152  			planned: cty.ObjectVal(map[string]cty.Value{
   153  				"input":            cty.StringVal("input"),
   154  				"output":           cty.UnknownVal(cty.String),
   155  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   156  				"id":               cty.UnknownVal(cty.String),
   157  			}),
   158  		},
   159  
   160  		"update-input": {
   161  			prior: cty.ObjectVal(map[string]cty.Value{
   162  				"input":            cty.StringVal("input"),
   163  				"output":           cty.StringVal("input"),
   164  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   165  				"id":               cty.StringVal("not-quite-unique"),
   166  			}),
   167  			proposed: cty.ObjectVal(map[string]cty.Value{
   168  				"input":            cty.UnknownVal(cty.List(cty.String)),
   169  				"output":           cty.StringVal("input"),
   170  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   171  				"id":               cty.StringVal("not-quite-unique"),
   172  			}),
   173  			planned: cty.ObjectVal(map[string]cty.Value{
   174  				"input":            cty.UnknownVal(cty.List(cty.String)),
   175  				"output":           cty.UnknownVal(cty.List(cty.String)),
   176  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   177  				"id":               cty.StringVal("not-quite-unique"),
   178  			}),
   179  		},
   180  
   181  		"update-trigger": {
   182  			prior: cty.ObjectVal(map[string]cty.Value{
   183  				"input":            cty.StringVal("input"),
   184  				"output":           cty.StringVal("input"),
   185  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   186  				"id":               cty.StringVal("not-quite-unique"),
   187  			}),
   188  			proposed: cty.ObjectVal(map[string]cty.Value{
   189  				"input":            cty.StringVal("input"),
   190  				"output":           cty.StringVal("input"),
   191  				"triggers_replace": cty.StringVal("new-value"),
   192  				"id":               cty.StringVal("not-quite-unique"),
   193  			}),
   194  			planned: cty.ObjectVal(map[string]cty.Value{
   195  				"input":            cty.StringVal("input"),
   196  				"output":           cty.UnknownVal(cty.String),
   197  				"triggers_replace": cty.StringVal("new-value"),
   198  				"id":               cty.UnknownVal(cty.String),
   199  			}),
   200  		},
   201  
   202  		"update-input-trigger": {
   203  			prior: cty.ObjectVal(map[string]cty.Value{
   204  				"input":  cty.StringVal("input"),
   205  				"output": cty.StringVal("input"),
   206  				"triggers_replace": cty.MapVal(map[string]cty.Value{
   207  					"key": cty.StringVal("value"),
   208  				}),
   209  				"id": cty.StringVal("not-quite-unique"),
   210  			}),
   211  			proposed: cty.ObjectVal(map[string]cty.Value{
   212  				"input":  cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   213  				"output": cty.StringVal("input"),
   214  				"triggers_replace": cty.MapVal(map[string]cty.Value{
   215  					"key": cty.StringVal("new value"),
   216  				}),
   217  				"id": cty.StringVal("not-quite-unique"),
   218  			}),
   219  			planned: cty.ObjectVal(map[string]cty.Value{
   220  				"input":  cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   221  				"output": cty.UnknownVal(cty.List(cty.String)),
   222  				"triggers_replace": cty.MapVal(map[string]cty.Value{
   223  					"key": cty.StringVal("new value"),
   224  				}),
   225  				"id": cty.UnknownVal(cty.String),
   226  			}),
   227  		},
   228  	} {
   229  		t.Run("plan-"+name, func(t *testing.T) {
   230  			req := providers.PlanResourceChangeRequest{
   231  				TypeName:         "terraform_data",
   232  				PriorState:       tc.prior,
   233  				ProposedNewState: tc.proposed,
   234  			}
   235  
   236  			resp := planDataStoreResourceChange(req)
   237  			if resp.Diagnostics.HasErrors() {
   238  				t.Fatal(resp.Diagnostics.ErrWithWarnings())
   239  			}
   240  
   241  			if !resp.PlannedState.RawEquals(tc.planned) {
   242  				t.Errorf("expected:\n%#v\ngot:\n%#v\n", tc.planned, resp.PlannedState)
   243  			}
   244  		})
   245  	}
   246  }
   247  
   248  func TestManagedDataApply(t *testing.T) {
   249  	testUUIDHook = func() string {
   250  		return "not-quite-unique"
   251  	}
   252  	defer func() {
   253  		testUUIDHook = nil
   254  	}()
   255  
   256  	schema := dataStoreResourceSchema().Block
   257  	ty := schema.ImpliedType()
   258  
   259  	for name, tc := range map[string]struct {
   260  		prior   cty.Value
   261  		planned cty.Value
   262  		state   cty.Value
   263  	}{
   264  		"create": {
   265  			prior: cty.NullVal(ty),
   266  			planned: cty.ObjectVal(map[string]cty.Value{
   267  				"input":            cty.NullVal(cty.DynamicPseudoType),
   268  				"output":           cty.NullVal(cty.DynamicPseudoType),
   269  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   270  				"id":               cty.UnknownVal(cty.String),
   271  			}),
   272  			state: cty.ObjectVal(map[string]cty.Value{
   273  				"input":            cty.NullVal(cty.DynamicPseudoType),
   274  				"output":           cty.NullVal(cty.DynamicPseudoType),
   275  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   276  				"id":               cty.StringVal("not-quite-unique"),
   277  			}),
   278  		},
   279  
   280  		"create-output": {
   281  			prior: cty.NullVal(ty),
   282  			planned: cty.ObjectVal(map[string]cty.Value{
   283  				"input":            cty.StringVal("input"),
   284  				"output":           cty.UnknownVal(cty.String),
   285  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   286  				"id":               cty.UnknownVal(cty.String),
   287  			}),
   288  			state: cty.ObjectVal(map[string]cty.Value{
   289  				"input":            cty.StringVal("input"),
   290  				"output":           cty.StringVal("input"),
   291  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   292  				"id":               cty.StringVal("not-quite-unique"),
   293  			}),
   294  		},
   295  
   296  		"update-input": {
   297  			prior: cty.ObjectVal(map[string]cty.Value{
   298  				"input":            cty.StringVal("input"),
   299  				"output":           cty.StringVal("input"),
   300  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   301  				"id":               cty.StringVal("not-quite-unique"),
   302  			}),
   303  			planned: cty.ObjectVal(map[string]cty.Value{
   304  				"input":            cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   305  				"output":           cty.UnknownVal(cty.List(cty.String)),
   306  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   307  				"id":               cty.StringVal("not-quite-unique"),
   308  			}),
   309  			state: cty.ObjectVal(map[string]cty.Value{
   310  				"input":            cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   311  				"output":           cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   312  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   313  				"id":               cty.StringVal("not-quite-unique"),
   314  			}),
   315  		},
   316  
   317  		"update-trigger": {
   318  			prior: cty.ObjectVal(map[string]cty.Value{
   319  				"input":            cty.StringVal("input"),
   320  				"output":           cty.StringVal("input"),
   321  				"triggers_replace": cty.NullVal(cty.DynamicPseudoType),
   322  				"id":               cty.StringVal("not-quite-unique"),
   323  			}),
   324  			planned: cty.ObjectVal(map[string]cty.Value{
   325  				"input":            cty.StringVal("input"),
   326  				"output":           cty.UnknownVal(cty.String),
   327  				"triggers_replace": cty.StringVal("new-value"),
   328  				"id":               cty.UnknownVal(cty.String),
   329  			}),
   330  			state: cty.ObjectVal(map[string]cty.Value{
   331  				"input":            cty.StringVal("input"),
   332  				"output":           cty.StringVal("input"),
   333  				"triggers_replace": cty.StringVal("new-value"),
   334  				"id":               cty.StringVal("not-quite-unique"),
   335  			}),
   336  		},
   337  
   338  		"update-input-trigger": {
   339  			prior: cty.ObjectVal(map[string]cty.Value{
   340  				"input":  cty.StringVal("input"),
   341  				"output": cty.StringVal("input"),
   342  				"triggers_replace": cty.MapVal(map[string]cty.Value{
   343  					"key": cty.StringVal("value"),
   344  				}),
   345  				"id": cty.StringVal("not-quite-unique"),
   346  			}),
   347  			planned: cty.ObjectVal(map[string]cty.Value{
   348  				"input":  cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   349  				"output": cty.UnknownVal(cty.List(cty.String)),
   350  				"triggers_replace": cty.MapVal(map[string]cty.Value{
   351  					"key": cty.StringVal("new value"),
   352  				}),
   353  				"id": cty.UnknownVal(cty.String),
   354  			}),
   355  			state: cty.ObjectVal(map[string]cty.Value{
   356  				"input":  cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   357  				"output": cty.ListVal([]cty.Value{cty.StringVal("new-input")}),
   358  				"triggers_replace": cty.MapVal(map[string]cty.Value{
   359  					"key": cty.StringVal("new value"),
   360  				}),
   361  				"id": cty.StringVal("not-quite-unique"),
   362  			}),
   363  		},
   364  	} {
   365  		t.Run("apply-"+name, func(t *testing.T) {
   366  			req := providers.ApplyResourceChangeRequest{
   367  				TypeName:     "terraform_data",
   368  				PriorState:   tc.prior,
   369  				PlannedState: tc.planned,
   370  			}
   371  
   372  			resp := applyDataStoreResourceChange(req)
   373  			if resp.Diagnostics.HasErrors() {
   374  				t.Fatal(resp.Diagnostics.ErrWithWarnings())
   375  			}
   376  
   377  			if !resp.NewState.RawEquals(tc.state) {
   378  				t.Errorf("expected:\n%#v\ngot:\n%#v\n", tc.state, resp.NewState)
   379  			}
   380  		})
   381  	}
   382  }