mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
23395a1022
Previously we would only ever add new lock entries or update existing ones. However, it's possible that over time a module may _cease_ using a particular provider, at which point we ought to remove it from the lock file so that operations won't fail when seeing that the provider cache directory is inconsistent with the lock file. Now the provider installer (EnsureProviderVersions) will remove any lock file entries that relate to providers not included in the given requirements, which therefore makes the resulting lock file properly match the set of packages the installer wrote into the cache. This does potentially mean that someone could inadvertently defeat the lock by removing a provider dependency, running "terraform init", then undoing that removal, and finally running "terraform init" again. However, that seems relatively unlikely compared to the likelihood of removing a provider and keeping it removed, and in the event it _did_ happen the changes to the lock entry for that provider would be visible in the diff of the provider lock file as usual, and so could be noticed in code review just as for any other change to dependencies.
219 lines
6.9 KiB
Go
219 lines
6.9 KiB
Go
package depsfile
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
"github.com/hashicorp/terraform/internal/addrs"
|
|
"github.com/hashicorp/terraform/internal/getproviders"
|
|
)
|
|
|
|
func TestLocksEqual(t *testing.T) {
|
|
boopProvider := addrs.NewDefaultProvider("boop")
|
|
v2 := getproviders.MustParseVersion("2.0.0")
|
|
v2LocalBuild := getproviders.MustParseVersion("2.0.0+awesomecorp.1")
|
|
v2GtConstraints := getproviders.MustParseVersionConstraints(">= 2.0.0")
|
|
v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
|
|
hash1 := getproviders.HashScheme("test").New("1")
|
|
hash2 := getproviders.HashScheme("test").New("2")
|
|
hash3 := getproviders.HashScheme("test").New("3")
|
|
|
|
equalBothWays := func(t *testing.T, a, b *Locks) {
|
|
t.Helper()
|
|
if !a.Equal(b) {
|
|
t.Errorf("a should be equal to b")
|
|
}
|
|
if !b.Equal(a) {
|
|
t.Errorf("b should be equal to a")
|
|
}
|
|
}
|
|
nonEqualBothWays := func(t *testing.T, a, b *Locks) {
|
|
t.Helper()
|
|
if a.Equal(b) {
|
|
t.Errorf("a should be equal to b")
|
|
}
|
|
if b.Equal(a) {
|
|
t.Errorf("b should be equal to a")
|
|
}
|
|
}
|
|
|
|
t.Run("both empty", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
equalBothWays(t, a, b)
|
|
})
|
|
t.Run("an extra provider lock", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
b.SetProvider(boopProvider, v2, v2GtConstraints, nil)
|
|
nonEqualBothWays(t, a, b)
|
|
})
|
|
t.Run("both have boop provider with same version", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
// Note: the constraints are not part of the definition of "Equal", so they can differ
|
|
a.SetProvider(boopProvider, v2, v2GtConstraints, nil)
|
|
b.SetProvider(boopProvider, v2, v2EqConstraints, nil)
|
|
equalBothWays(t, a, b)
|
|
})
|
|
t.Run("both have boop provider with different versions", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
a.SetProvider(boopProvider, v2, v2EqConstraints, nil)
|
|
b.SetProvider(boopProvider, v2LocalBuild, v2EqConstraints, nil)
|
|
nonEqualBothWays(t, a, b)
|
|
})
|
|
t.Run("both have boop provider with same version and same hashes", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
hashes := []getproviders.Hash{hash1, hash2, hash3}
|
|
a.SetProvider(boopProvider, v2, v2EqConstraints, hashes)
|
|
b.SetProvider(boopProvider, v2, v2EqConstraints, hashes)
|
|
equalBothWays(t, a, b)
|
|
})
|
|
t.Run("both have boop provider with same version but different hashes", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
hashesA := []getproviders.Hash{hash1, hash2}
|
|
hashesB := []getproviders.Hash{hash1, hash3}
|
|
a.SetProvider(boopProvider, v2, v2EqConstraints, hashesA)
|
|
b.SetProvider(boopProvider, v2, v2EqConstraints, hashesB)
|
|
nonEqualBothWays(t, a, b)
|
|
})
|
|
}
|
|
|
|
func TestLocksEqualProviderAddress(t *testing.T) {
|
|
boopProvider := addrs.NewDefaultProvider("boop")
|
|
v2 := getproviders.MustParseVersion("2.0.0")
|
|
v2LocalBuild := getproviders.MustParseVersion("2.0.0+awesomecorp.1")
|
|
v2GtConstraints := getproviders.MustParseVersionConstraints(">= 2.0.0")
|
|
v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
|
|
hash1 := getproviders.HashScheme("test").New("1")
|
|
hash2 := getproviders.HashScheme("test").New("2")
|
|
hash3 := getproviders.HashScheme("test").New("3")
|
|
|
|
equalProviderAddressBothWays := func(t *testing.T, a, b *Locks) {
|
|
t.Helper()
|
|
if !a.EqualProviderAddress(b) {
|
|
t.Errorf("a should be equal to b")
|
|
}
|
|
if !b.EqualProviderAddress(a) {
|
|
t.Errorf("b should be equal to a")
|
|
}
|
|
}
|
|
nonEqualProviderAddressBothWays := func(t *testing.T, a, b *Locks) {
|
|
t.Helper()
|
|
if a.EqualProviderAddress(b) {
|
|
t.Errorf("a should be equal to b")
|
|
}
|
|
if b.EqualProviderAddress(a) {
|
|
t.Errorf("b should be equal to a")
|
|
}
|
|
}
|
|
|
|
t.Run("both empty", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
equalProviderAddressBothWays(t, a, b)
|
|
})
|
|
t.Run("an extra provider lock", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
b.SetProvider(boopProvider, v2, v2GtConstraints, nil)
|
|
nonEqualProviderAddressBothWays(t, a, b)
|
|
})
|
|
t.Run("both have boop provider with different versions", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
a.SetProvider(boopProvider, v2, v2EqConstraints, nil)
|
|
b.SetProvider(boopProvider, v2LocalBuild, v2EqConstraints, nil)
|
|
equalProviderAddressBothWays(t, a, b)
|
|
})
|
|
t.Run("both have boop provider with same version but different hashes", func(t *testing.T) {
|
|
a := NewLocks()
|
|
b := NewLocks()
|
|
hashesA := []getproviders.Hash{hash1, hash2}
|
|
hashesB := []getproviders.Hash{hash1, hash3}
|
|
a.SetProvider(boopProvider, v2, v2EqConstraints, hashesA)
|
|
b.SetProvider(boopProvider, v2, v2EqConstraints, hashesB)
|
|
equalProviderAddressBothWays(t, a, b)
|
|
})
|
|
}
|
|
|
|
func TestLocksProviderSetRemove(t *testing.T) {
|
|
beepProvider := addrs.NewDefaultProvider("beep")
|
|
boopProvider := addrs.NewDefaultProvider("boop")
|
|
v2 := getproviders.MustParseVersion("2.0.0")
|
|
v2EqConstraints := getproviders.MustParseVersionConstraints("2.0.0")
|
|
v2GtConstraints := getproviders.MustParseVersionConstraints(">= 2.0.0")
|
|
hash := getproviders.HashScheme("test").New("1")
|
|
|
|
locks := NewLocks()
|
|
if got, want := len(locks.AllProviders()), 0; got != want {
|
|
t.Fatalf("fresh locks object already has providers")
|
|
}
|
|
|
|
locks.SetProvider(boopProvider, v2, v2EqConstraints, []getproviders.Hash{hash})
|
|
{
|
|
got := locks.AllProviders()
|
|
want := map[addrs.Provider]*ProviderLock{
|
|
boopProvider: {
|
|
addr: boopProvider,
|
|
version: v2,
|
|
versionConstraints: v2EqConstraints,
|
|
hashes: []getproviders.Hash{hash},
|
|
},
|
|
}
|
|
if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
|
|
t.Fatalf("wrong providers after SetProvider boop\n%s", diff)
|
|
}
|
|
}
|
|
|
|
locks.SetProvider(beepProvider, v2, v2GtConstraints, []getproviders.Hash{hash})
|
|
{
|
|
got := locks.AllProviders()
|
|
want := map[addrs.Provider]*ProviderLock{
|
|
boopProvider: {
|
|
addr: boopProvider,
|
|
version: v2,
|
|
versionConstraints: v2EqConstraints,
|
|
hashes: []getproviders.Hash{hash},
|
|
},
|
|
beepProvider: {
|
|
addr: beepProvider,
|
|
version: v2,
|
|
versionConstraints: v2GtConstraints,
|
|
hashes: []getproviders.Hash{hash},
|
|
},
|
|
}
|
|
if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
|
|
t.Fatalf("wrong providers after SetProvider beep\n%s", diff)
|
|
}
|
|
}
|
|
|
|
locks.RemoveProvider(boopProvider)
|
|
{
|
|
got := locks.AllProviders()
|
|
want := map[addrs.Provider]*ProviderLock{
|
|
beepProvider: {
|
|
addr: beepProvider,
|
|
version: v2,
|
|
versionConstraints: v2GtConstraints,
|
|
hashes: []getproviders.Hash{hash},
|
|
},
|
|
}
|
|
if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
|
|
t.Fatalf("wrong providers after RemoveProvider boop\n%s", diff)
|
|
}
|
|
}
|
|
|
|
locks.RemoveProvider(beepProvider)
|
|
{
|
|
got := locks.AllProviders()
|
|
want := map[addrs.Provider]*ProviderLock{}
|
|
if diff := cmp.Diff(want, got, ProviderLockComparer); diff != "" {
|
|
t.Fatalf("wrong providers after RemoveProvider beep\n%s", diff)
|
|
}
|
|
}
|
|
}
|