states/statefile: consistently sort resources across modules (#25498)

If a statefile had resources with the same name in different modules,
the sort order could be inconsistent between state refreshes. This adds
the module to the Less() function used in sorting and a minimal test to
verify consistent ordering.
This commit is contained in:
Kristin Laemmert 2020-08-11 11:50:07 -04:00 committed by GitHub
parent 3cfe888057
commit 5964e928dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 43 additions and 0 deletions

View File

@ -535,6 +535,8 @@ func (sr sortResourcesV4) Len() int { return len(sr) }
func (sr sortResourcesV4) Swap(i, j int) { sr[i], sr[j] = sr[j], sr[i] } func (sr sortResourcesV4) Swap(i, j int) { sr[i], sr[j] = sr[j], sr[i] }
func (sr sortResourcesV4) Less(i, j int) bool { func (sr sortResourcesV4) Less(i, j int) bool {
switch { switch {
case sr[i].Module != sr[j].Module:
return sr[i].Module < sr[j].Module
case sr[i].Mode != sr[j].Mode: case sr[i].Mode != sr[j].Mode:
return sr[i].Mode < sr[j].Mode return sr[i].Mode < sr[j].Mode
case sr[i].Type != sr[j].Type: case sr[i].Type != sr[j].Type:

View File

@ -0,0 +1,41 @@
package statefile
import (
"sort"
"testing"
)
// This test verifies that modules are sorted before resources:
// https://github.com/hashicorp/terraform/issues/21552
func TestVersion4_sort(t *testing.T) {
resources := sortResourcesV4{
{
Module: "module.child",
Type: "test_instance",
Name: "foo",
},
{
Type: "test_instance",
Name: "foo",
},
{
Module: "module.kinder",
Type: "test_instance",
Name: "foo",
},
{
Module: "module.child.grandchild",
Type: "test_instance",
Name: "foo",
},
}
sort.Stable(resources)
moduleOrder := []string{"", "module.child", "module.child.grandchild", "module.kinder"}
for i, resource := range resources {
if resource.Module != moduleOrder[i] {
t.Errorf("wrong sort order: expected %q, got %q\n", moduleOrder[i], resource.Module)
}
}
}