github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/command/views/hook_count_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package views
     5  
     6  import (
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/zclconf/go-cty/cty"
    11  
    12  	"github.com/terramate-io/tf/addrs"
    13  	"github.com/terramate-io/tf/plans"
    14  	"github.com/terramate-io/tf/states"
    15  	"github.com/terramate-io/tf/terraform"
    16  
    17  	legacy "github.com/terramate-io/tf/legacy/terraform"
    18  )
    19  
    20  func TestCountHook_impl(t *testing.T) {
    21  	var _ terraform.Hook = new(countHook)
    22  }
    23  
    24  func TestCountHookPostDiff_DestroyDeposed(t *testing.T) {
    25  	h := new(countHook)
    26  
    27  	resources := map[string]*legacy.InstanceDiff{
    28  		"lorem": &legacy.InstanceDiff{DestroyDeposed: true},
    29  	}
    30  
    31  	for k := range resources {
    32  		addr := addrs.Resource{
    33  			Mode: addrs.ManagedResourceMode,
    34  			Type: "test_instance",
    35  			Name: k,
    36  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
    37  
    38  		h.PostDiff(addr, states.DeposedKey("deadbeef"), plans.Delete, cty.DynamicVal, cty.DynamicVal)
    39  	}
    40  
    41  	expected := new(countHook)
    42  	expected.ToAdd = 0
    43  	expected.ToChange = 0
    44  	expected.ToRemoveAndAdd = 0
    45  	expected.ToRemove = 1
    46  
    47  	if !reflect.DeepEqual(expected, h) {
    48  		t.Fatalf("Expected %#v, got %#v instead.", expected, h)
    49  	}
    50  }
    51  
    52  func TestCountHookPostDiff_DestroyOnly(t *testing.T) {
    53  	h := new(countHook)
    54  
    55  	resources := map[string]*legacy.InstanceDiff{
    56  		"foo":   &legacy.InstanceDiff{Destroy: true},
    57  		"bar":   &legacy.InstanceDiff{Destroy: true},
    58  		"lorem": &legacy.InstanceDiff{Destroy: true},
    59  		"ipsum": &legacy.InstanceDiff{Destroy: true},
    60  	}
    61  
    62  	for k := range resources {
    63  		addr := addrs.Resource{
    64  			Mode: addrs.ManagedResourceMode,
    65  			Type: "test_instance",
    66  			Name: k,
    67  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
    68  
    69  		h.PostDiff(addr, states.CurrentGen, plans.Delete, cty.DynamicVal, cty.DynamicVal)
    70  	}
    71  
    72  	expected := new(countHook)
    73  	expected.ToAdd = 0
    74  	expected.ToChange = 0
    75  	expected.ToRemoveAndAdd = 0
    76  	expected.ToRemove = 4
    77  
    78  	if !reflect.DeepEqual(expected, h) {
    79  		t.Fatalf("Expected %#v, got %#v instead.", expected, h)
    80  	}
    81  }
    82  
    83  func TestCountHookPostDiff_AddOnly(t *testing.T) {
    84  	h := new(countHook)
    85  
    86  	resources := map[string]*legacy.InstanceDiff{
    87  		"foo": &legacy.InstanceDiff{
    88  			Attributes: map[string]*legacy.ResourceAttrDiff{
    89  				"foo": &legacy.ResourceAttrDiff{RequiresNew: true},
    90  			},
    91  		},
    92  		"bar": &legacy.InstanceDiff{
    93  			Attributes: map[string]*legacy.ResourceAttrDiff{
    94  				"foo": &legacy.ResourceAttrDiff{RequiresNew: true},
    95  			},
    96  		},
    97  		"lorem": &legacy.InstanceDiff{
    98  			Attributes: map[string]*legacy.ResourceAttrDiff{
    99  				"foo": &legacy.ResourceAttrDiff{RequiresNew: true},
   100  			},
   101  		},
   102  	}
   103  
   104  	for k := range resources {
   105  		addr := addrs.Resource{
   106  			Mode: addrs.ManagedResourceMode,
   107  			Type: "test_instance",
   108  			Name: k,
   109  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   110  
   111  		h.PostDiff(addr, states.CurrentGen, plans.Create, cty.DynamicVal, cty.DynamicVal)
   112  	}
   113  
   114  	expected := new(countHook)
   115  	expected.ToAdd = 3
   116  	expected.ToChange = 0
   117  	expected.ToRemoveAndAdd = 0
   118  	expected.ToRemove = 0
   119  
   120  	if !reflect.DeepEqual(expected, h) {
   121  		t.Fatalf("Expected %#v, got %#v instead.", expected, h)
   122  	}
   123  }
   124  
   125  func TestCountHookPostDiff_ChangeOnly(t *testing.T) {
   126  	h := new(countHook)
   127  
   128  	resources := map[string]*legacy.InstanceDiff{
   129  		"foo": &legacy.InstanceDiff{
   130  			Destroy: false,
   131  			Attributes: map[string]*legacy.ResourceAttrDiff{
   132  				"foo": &legacy.ResourceAttrDiff{},
   133  			},
   134  		},
   135  		"bar": &legacy.InstanceDiff{
   136  			Destroy: false,
   137  			Attributes: map[string]*legacy.ResourceAttrDiff{
   138  				"foo": &legacy.ResourceAttrDiff{},
   139  			},
   140  		},
   141  		"lorem": &legacy.InstanceDiff{
   142  			Destroy: false,
   143  			Attributes: map[string]*legacy.ResourceAttrDiff{
   144  				"foo": &legacy.ResourceAttrDiff{},
   145  			},
   146  		},
   147  	}
   148  
   149  	for k := range resources {
   150  		addr := addrs.Resource{
   151  			Mode: addrs.ManagedResourceMode,
   152  			Type: "test_instance",
   153  			Name: k,
   154  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   155  
   156  		h.PostDiff(addr, states.CurrentGen, plans.Update, cty.DynamicVal, cty.DynamicVal)
   157  	}
   158  
   159  	expected := new(countHook)
   160  	expected.ToAdd = 0
   161  	expected.ToChange = 3
   162  	expected.ToRemoveAndAdd = 0
   163  	expected.ToRemove = 0
   164  
   165  	if !reflect.DeepEqual(expected, h) {
   166  		t.Fatalf("Expected %#v, got %#v instead.", expected, h)
   167  	}
   168  }
   169  
   170  func TestCountHookPostDiff_Mixed(t *testing.T) {
   171  	h := new(countHook)
   172  
   173  	resources := map[string]plans.Action{
   174  		"foo":   plans.Delete,
   175  		"bar":   plans.NoOp,
   176  		"lorem": plans.Update,
   177  		"ipsum": plans.Delete,
   178  	}
   179  
   180  	for k, a := range resources {
   181  		addr := addrs.Resource{
   182  			Mode: addrs.ManagedResourceMode,
   183  			Type: "test_instance",
   184  			Name: k,
   185  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   186  
   187  		h.PostDiff(addr, states.CurrentGen, a, cty.DynamicVal, cty.DynamicVal)
   188  	}
   189  
   190  	expected := new(countHook)
   191  	expected.ToAdd = 0
   192  	expected.ToChange = 1
   193  	expected.ToRemoveAndAdd = 0
   194  	expected.ToRemove = 2
   195  
   196  	if !reflect.DeepEqual(expected, h) {
   197  		t.Fatalf("Expected %#v, got %#v instead.",
   198  			expected, h)
   199  	}
   200  }
   201  
   202  func TestCountHookPostDiff_NoChange(t *testing.T) {
   203  	h := new(countHook)
   204  
   205  	resources := map[string]*legacy.InstanceDiff{
   206  		"foo":   &legacy.InstanceDiff{},
   207  		"bar":   &legacy.InstanceDiff{},
   208  		"lorem": &legacy.InstanceDiff{},
   209  		"ipsum": &legacy.InstanceDiff{},
   210  	}
   211  
   212  	for k := range resources {
   213  		addr := addrs.Resource{
   214  			Mode: addrs.ManagedResourceMode,
   215  			Type: "test_instance",
   216  			Name: k,
   217  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   218  
   219  		h.PostDiff(addr, states.CurrentGen, plans.NoOp, cty.DynamicVal, cty.DynamicVal)
   220  	}
   221  
   222  	expected := new(countHook)
   223  	expected.ToAdd = 0
   224  	expected.ToChange = 0
   225  	expected.ToRemoveAndAdd = 0
   226  	expected.ToRemove = 0
   227  
   228  	if !reflect.DeepEqual(expected, h) {
   229  		t.Fatalf("Expected %#v, got %#v instead.",
   230  			expected, h)
   231  	}
   232  }
   233  
   234  func TestCountHookPostDiff_DataSource(t *testing.T) {
   235  	h := new(countHook)
   236  
   237  	resources := map[string]plans.Action{
   238  		"foo":   plans.Delete,
   239  		"bar":   plans.NoOp,
   240  		"lorem": plans.Update,
   241  		"ipsum": plans.Delete,
   242  	}
   243  
   244  	for k, a := range resources {
   245  		addr := addrs.Resource{
   246  			Mode: addrs.DataResourceMode,
   247  			Type: "test_instance",
   248  			Name: k,
   249  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   250  
   251  		h.PostDiff(addr, states.CurrentGen, a, cty.DynamicVal, cty.DynamicVal)
   252  	}
   253  
   254  	expected := new(countHook)
   255  	expected.ToAdd = 0
   256  	expected.ToChange = 0
   257  	expected.ToRemoveAndAdd = 0
   258  	expected.ToRemove = 0
   259  
   260  	if !reflect.DeepEqual(expected, h) {
   261  		t.Fatalf("Expected %#v, got %#v instead.",
   262  			expected, h)
   263  	}
   264  }
   265  
   266  func TestCountHookApply_ChangeOnly(t *testing.T) {
   267  	h := new(countHook)
   268  
   269  	resources := map[string]*legacy.InstanceDiff{
   270  		"foo": &legacy.InstanceDiff{
   271  			Destroy: false,
   272  			Attributes: map[string]*legacy.ResourceAttrDiff{
   273  				"foo": &legacy.ResourceAttrDiff{},
   274  			},
   275  		},
   276  		"bar": &legacy.InstanceDiff{
   277  			Destroy: false,
   278  			Attributes: map[string]*legacy.ResourceAttrDiff{
   279  				"foo": &legacy.ResourceAttrDiff{},
   280  			},
   281  		},
   282  		"lorem": &legacy.InstanceDiff{
   283  			Destroy: false,
   284  			Attributes: map[string]*legacy.ResourceAttrDiff{
   285  				"foo": &legacy.ResourceAttrDiff{},
   286  			},
   287  		},
   288  	}
   289  
   290  	for k := range resources {
   291  		addr := addrs.Resource{
   292  			Mode: addrs.ManagedResourceMode,
   293  			Type: "test_instance",
   294  			Name: k,
   295  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   296  
   297  		h.PreApply(addr, states.CurrentGen, plans.Update, cty.DynamicVal, cty.DynamicVal)
   298  		h.PostApply(addr, states.CurrentGen, cty.DynamicVal, nil)
   299  	}
   300  
   301  	expected := &countHook{pending: make(map[string]plans.Action)}
   302  	expected.Added = 0
   303  	expected.Changed = 3
   304  	expected.Removed = 0
   305  
   306  	if !reflect.DeepEqual(expected, h) {
   307  		t.Fatalf("Expected:\n%#v\nGot:\n%#v\n", expected, h)
   308  	}
   309  }
   310  
   311  func TestCountHookApply_DestroyOnly(t *testing.T) {
   312  	h := new(countHook)
   313  
   314  	resources := map[string]*legacy.InstanceDiff{
   315  		"foo":   &legacy.InstanceDiff{Destroy: true},
   316  		"bar":   &legacy.InstanceDiff{Destroy: true},
   317  		"lorem": &legacy.InstanceDiff{Destroy: true},
   318  		"ipsum": &legacy.InstanceDiff{Destroy: true},
   319  	}
   320  
   321  	for k := range resources {
   322  		addr := addrs.Resource{
   323  			Mode: addrs.ManagedResourceMode,
   324  			Type: "test_instance",
   325  			Name: k,
   326  		}.Instance(addrs.NoKey).Absolute(addrs.RootModuleInstance)
   327  
   328  		h.PreApply(addr, states.CurrentGen, plans.Delete, cty.DynamicVal, cty.DynamicVal)
   329  		h.PostApply(addr, states.CurrentGen, cty.DynamicVal, nil)
   330  	}
   331  
   332  	expected := &countHook{pending: make(map[string]plans.Action)}
   333  	expected.Added = 0
   334  	expected.Changed = 0
   335  	expected.Removed = 4
   336  
   337  	if !reflect.DeepEqual(expected, h) {
   338  		t.Fatalf("Expected:\n%#v\nGot:\n%#v\n", expected, h)
   339  	}
   340  }