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 }