github.com/terramate-io/tf@v0.0.0-20230830114523-fce866b4dfcd/depsfile/locks_test.go (about)

     1  // Copyright (c) HashiCorp, Inc.
     2  // SPDX-License-Identifier: MPL-2.0
     3  
     4  package depsfile
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/google/go-cmp/cmp"
    10  	"github.com/terramate-io/tf/addrs"
    11  	"github.com/terramate-io/tf/getproviders"
    12  )
    13  
    14  func TestLocksEqual(t *testing.T) {
    15  	boopProvider := addrs.NewDefaultProvider("boop")
    16  	v2 := getproviders.MustParseVersion("2.0.0")
    17  	v2LocalBuild := getproviders.MustParseVersion("2.0.0+awesomecorp.1")
    18  	v2GtConstraints := getproviders.MustParseVersionConstraints(">= 2.0.0")
    19  	v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
    20  	hash1 := getproviders.HashScheme("test").New("1")
    21  	hash2 := getproviders.HashScheme("test").New("2")
    22  	hash3 := getproviders.HashScheme("test").New("3")
    23  
    24  	equalBothWays := func(t *testing.T, a, b *Locks) {
    25  		t.Helper()
    26  		if !a.Equal(b) {
    27  			t.Errorf("a should be equal to b")
    28  		}
    29  		if !b.Equal(a) {
    30  			t.Errorf("b should be equal to a")
    31  		}
    32  	}
    33  	nonEqualBothWays := func(t *testing.T, a, b *Locks) {
    34  		t.Helper()
    35  		if a.Equal(b) {
    36  			t.Errorf("a should be equal to b")
    37  		}
    38  		if b.Equal(a) {
    39  			t.Errorf("b should be equal to a")
    40  		}
    41  	}
    42  
    43  	t.Run("both empty", func(t *testing.T) {
    44  		a := NewLocks()
    45  		b := NewLocks()
    46  		equalBothWays(t, a, b)
    47  	})
    48  	t.Run("an extra provider lock", func(t *testing.T) {
    49  		a := NewLocks()
    50  		b := NewLocks()
    51  		b.SetProvider(boopProvider, v2, v2GtConstraints, nil)
    52  		nonEqualBothWays(t, a, b)
    53  	})
    54  	t.Run("both have boop provider with same version", func(t *testing.T) {
    55  		a := NewLocks()
    56  		b := NewLocks()
    57  		// Note: the constraints are not part of the definition of "Equal", so they can differ
    58  		a.SetProvider(boopProvider, v2, v2GtConstraints, nil)
    59  		b.SetProvider(boopProvider, v2, v2EqConstraints, nil)
    60  		equalBothWays(t, a, b)
    61  	})
    62  	t.Run("both have boop provider with different versions", func(t *testing.T) {
    63  		a := NewLocks()
    64  		b := NewLocks()
    65  		a.SetProvider(boopProvider, v2, v2EqConstraints, nil)
    66  		b.SetProvider(boopProvider, v2LocalBuild, v2EqConstraints, nil)
    67  		nonEqualBothWays(t, a, b)
    68  	})
    69  	t.Run("both have boop provider with same version and same hashes", func(t *testing.T) {
    70  		a := NewLocks()
    71  		b := NewLocks()
    72  		hashes := []getproviders.Hash{hash1, hash2, hash3}
    73  		a.SetProvider(boopProvider, v2, v2EqConstraints, hashes)
    74  		b.SetProvider(boopProvider, v2, v2EqConstraints, hashes)
    75  		equalBothWays(t, a, b)
    76  	})
    77  	t.Run("both have boop provider with same version but different hashes", func(t *testing.T) {
    78  		a := NewLocks()
    79  		b := NewLocks()
    80  		hashesA := []getproviders.Hash{hash1, hash2}
    81  		hashesB := []getproviders.Hash{hash1, hash3}
    82  		a.SetProvider(boopProvider, v2, v2EqConstraints, hashesA)
    83  		b.SetProvider(boopProvider, v2, v2EqConstraints, hashesB)
    84  		nonEqualBothWays(t, a, b)
    85  	})
    86  }
    87  
    88  func TestLocksEqualProviderAddress(t *testing.T) {
    89  	boopProvider := addrs.NewDefaultProvider("boop")
    90  	v2 := getproviders.MustParseVersion("2.0.0")
    91  	v2LocalBuild := getproviders.MustParseVersion("2.0.0+awesomecorp.1")
    92  	v2GtConstraints := getproviders.MustParseVersionConstraints(">= 2.0.0")
    93  	v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
    94  	hash1 := getproviders.HashScheme("test").New("1")
    95  	hash2 := getproviders.HashScheme("test").New("2")
    96  	hash3 := getproviders.HashScheme("test").New("3")
    97  
    98  	equalProviderAddressBothWays := func(t *testing.T, a, b *Locks) {
    99  		t.Helper()
   100  		if !a.EqualProviderAddress(b) {
   101  			t.Errorf("a should be equal to b")
   102  		}
   103  		if !b.EqualProviderAddress(a) {
   104  			t.Errorf("b should be equal to a")
   105  		}
   106  	}
   107  	nonEqualProviderAddressBothWays := func(t *testing.T, a, b *Locks) {
   108  		t.Helper()
   109  		if a.EqualProviderAddress(b) {
   110  			t.Errorf("a should be equal to b")
   111  		}
   112  		if b.EqualProviderAddress(a) {
   113  			t.Errorf("b should be equal to a")
   114  		}
   115  	}
   116  
   117  	t.Run("both empty", func(t *testing.T) {
   118  		a := NewLocks()
   119  		b := NewLocks()
   120  		equalProviderAddressBothWays(t, a, b)
   121  	})
   122  	t.Run("an extra provider lock", func(t *testing.T) {
   123  		a := NewLocks()
   124  		b := NewLocks()
   125  		b.SetProvider(boopProvider, v2, v2GtConstraints, nil)
   126  		nonEqualProviderAddressBothWays(t, a, b)
   127  	})
   128  	t.Run("both have boop provider with different versions", func(t *testing.T) {
   129  		a := NewLocks()
   130  		b := NewLocks()
   131  		a.SetProvider(boopProvider, v2, v2EqConstraints, nil)
   132  		b.SetProvider(boopProvider, v2LocalBuild, v2EqConstraints, nil)
   133  		equalProviderAddressBothWays(t, a, b)
   134  	})
   135  	t.Run("both have boop provider with same version but different hashes", func(t *testing.T) {
   136  		a := NewLocks()
   137  		b := NewLocks()
   138  		hashesA := []getproviders.Hash{hash1, hash2}
   139  		hashesB := []getproviders.Hash{hash1, hash3}
   140  		a.SetProvider(boopProvider, v2, v2EqConstraints, hashesA)
   141  		b.SetProvider(boopProvider, v2, v2EqConstraints, hashesB)
   142  		equalProviderAddressBothWays(t, a, b)
   143  	})
   144  }
   145  
   146  func TestLocksProviderSetRemove(t *testing.T) {
   147  	beepProvider := addrs.NewDefaultProvider("beep")
   148  	boopProvider := addrs.NewDefaultProvider("boop")
   149  	v2 := getproviders.MustParseVersion("2.0.0")
   150  	v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
   151  	v2GtConstraints := getproviders.MustParseVersionConstraints(">= 2.0.0")
   152  	hash := getproviders.HashScheme("test").New("1")
   153  
   154  	locks := NewLocks()
   155  	if got, want := len(locks.AllProviders()), 0; got != want {
   156  		t.Fatalf("fresh locks object already has providers")
   157  	}
   158  
   159  	locks.SetProvider(boopProvider, v2, v2EqConstraints, []getproviders.Hash{hash})
   160  	{
   161  		got := locks.AllProviders()
   162  		want := map[addrs.Provider]*ProviderLock{
   163  			boopProvider: {
   164  				addr:               boopProvider,
   165  				version:            v2,
   166  				versionConstraints: v2EqConstraints,
   167  				hashes:             []getproviders.Hash{hash},
   168  			},
   169  		}
   170  		if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
   171  			t.Fatalf("wrong providers after SetProvider boop\n%s", diff)
   172  		}
   173  	}
   174  
   175  	locks.SetProvider(beepProvider, v2, v2GtConstraints, []getproviders.Hash{hash})
   176  	{
   177  		got := locks.AllProviders()
   178  		want := map[addrs.Provider]*ProviderLock{
   179  			boopProvider: {
   180  				addr:               boopProvider,
   181  				version:            v2,
   182  				versionConstraints: v2EqConstraints,
   183  				hashes:             []getproviders.Hash{hash},
   184  			},
   185  			beepProvider: {
   186  				addr:               beepProvider,
   187  				version:            v2,
   188  				versionConstraints: v2GtConstraints,
   189  				hashes:             []getproviders.Hash{hash},
   190  			},
   191  		}
   192  		if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
   193  			t.Fatalf("wrong providers after SetProvider beep\n%s", diff)
   194  		}
   195  	}
   196  
   197  	locks.RemoveProvider(boopProvider)
   198  	{
   199  		got := locks.AllProviders()
   200  		want := map[addrs.Provider]*ProviderLock{
   201  			beepProvider: {
   202  				addr:               beepProvider,
   203  				version:            v2,
   204  				versionConstraints: v2GtConstraints,
   205  				hashes:             []getproviders.Hash{hash},
   206  			},
   207  		}
   208  		if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
   209  			t.Fatalf("wrong providers after RemoveProvider boop\n%s", diff)
   210  		}
   211  	}
   212  
   213  	locks.RemoveProvider(beepProvider)
   214  	{
   215  		got := locks.AllProviders()
   216  		want := map[addrs.Provider]*ProviderLock{}
   217  		if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
   218  			t.Fatalf("wrong providers after RemoveProvider beep\n%s", diff)
   219  		}
   220  	}
   221  }
   222  
   223  func TestProviderLockContainsAll(t *testing.T) {
   224  	provider := addrs.NewDefaultProvider("provider")
   225  	v2 := getproviders.MustParseVersion("2.0.0")
   226  	v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
   227  
   228  	t.Run("non-symmetric", func(t *testing.T) {
   229  		target := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   230  			"9r3i9a9QmASqMnQM",
   231  			"K43RHM2klOoywtyW",
   232  			"swJPXfuCNhJsTM5c",
   233  		})
   234  
   235  		original := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   236  			"9r3i9a9QmASqMnQM",
   237  			"1ZAChGWUMWn4zmIk",
   238  			"K43RHM2klOoywtyW",
   239  			"HWjRvIuWZ1LVatnc",
   240  			"swJPXfuCNhJsTM5c",
   241  			"KwhJK4p/U2dqbKhI",
   242  		})
   243  
   244  		if !original.ContainsAll(target) {
   245  			t.Errorf("orginal should contain all hashes in target")
   246  		}
   247  		if target.ContainsAll(original) {
   248  			t.Errorf("target should not contain all hashes in orginal")
   249  		}
   250  	})
   251  
   252  	t.Run("symmetric", func(t *testing.T) {
   253  		target := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   254  			"9r3i9a9QmASqMnQM",
   255  			"K43RHM2klOoywtyW",
   256  			"swJPXfuCNhJsTM5c",
   257  		})
   258  
   259  		original := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   260  			"9r3i9a9QmASqMnQM",
   261  			"K43RHM2klOoywtyW",
   262  			"swJPXfuCNhJsTM5c",
   263  		})
   264  
   265  		if !original.ContainsAll(target) {
   266  			t.Errorf("orginal should contain all hashes in target")
   267  		}
   268  		if !target.ContainsAll(original) {
   269  			t.Errorf("target should not contain all hashes in orginal")
   270  		}
   271  	})
   272  
   273  	t.Run("edge case - null", func(t *testing.T) {
   274  		original := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   275  			"9r3i9a9QmASqMnQM",
   276  			"K43RHM2klOoywtyW",
   277  			"swJPXfuCNhJsTM5c",
   278  		})
   279  
   280  		if !original.ContainsAll(nil) {
   281  			t.Fatalf("orginal should report true on nil")
   282  		}
   283  	})
   284  
   285  	t.Run("edge case - empty", func(t *testing.T) {
   286  		original := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   287  			"9r3i9a9QmASqMnQM",
   288  			"K43RHM2klOoywtyW",
   289  			"swJPXfuCNhJsTM5c",
   290  		})
   291  
   292  		target := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{})
   293  
   294  		if !original.ContainsAll(target) {
   295  			t.Fatalf("orginal should report true on empty")
   296  		}
   297  	})
   298  
   299  	t.Run("edge case - original empty", func(t *testing.T) {
   300  		original := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{})
   301  
   302  		target := NewProviderLock(provider, v2, v2EqConstraints, []getproviders.Hash{
   303  			"9r3i9a9QmASqMnQM",
   304  			"K43RHM2klOoywtyW",
   305  			"swJPXfuCNhJsTM5c",
   306  		})
   307  
   308  		if original.ContainsAll(target) {
   309  			t.Fatalf("orginal should report false when empty")
   310  		}
   311  	})
   312  }