github.com/eliastor/durgaform@v0.0.0-20220816172711-d0ab2d17673e/internal/states/instance_object_test.go (about) 1 package states 2 3 import ( 4 "sync" 5 "testing" 6 7 "github.com/google/go-cmp/cmp" 8 "github.com/eliastor/durgaform/internal/addrs" 9 "github.com/zclconf/go-cty/cty" 10 ) 11 12 func TestResourceInstanceObject_encode(t *testing.T) { 13 value := cty.ObjectVal(map[string]cty.Value{ 14 "foo": cty.True, 15 }) 16 // The in-memory order of resource dependencies is random, since they're an 17 // unordered set. 18 depsOne := []addrs.ConfigResource{ 19 addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "honk"), 20 addrs.RootModule.Child("child").Resource(addrs.ManagedResourceMode, "test", "flub"), 21 addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "boop"), 22 } 23 depsTwo := []addrs.ConfigResource{ 24 addrs.RootModule.Child("child").Resource(addrs.ManagedResourceMode, "test", "flub"), 25 addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "boop"), 26 addrs.RootModule.Resource(addrs.ManagedResourceMode, "test", "honk"), 27 } 28 29 // multiple instances may have been assigned the same deps slice 30 objs := []*ResourceInstanceObject{ 31 &ResourceInstanceObject{ 32 Value: value, 33 Status: ObjectPlanned, 34 Dependencies: depsOne, 35 }, 36 &ResourceInstanceObject{ 37 Value: value, 38 Status: ObjectPlanned, 39 Dependencies: depsTwo, 40 }, 41 &ResourceInstanceObject{ 42 Value: value, 43 Status: ObjectPlanned, 44 Dependencies: depsOne, 45 }, 46 &ResourceInstanceObject{ 47 Value: value, 48 Status: ObjectPlanned, 49 Dependencies: depsOne, 50 }, 51 } 52 53 var encoded []*ResourceInstanceObjectSrc 54 55 // Encoding can happen concurrently, so we need to make sure the shared 56 // Dependencies are safely handled 57 var wg sync.WaitGroup 58 var mu sync.Mutex 59 60 for _, obj := range objs { 61 obj := obj 62 wg.Add(1) 63 go func() { 64 defer wg.Done() 65 rios, err := obj.Encode(value.Type(), 0) 66 if err != nil { 67 t.Errorf("unexpected error: %s", err) 68 } 69 mu.Lock() 70 encoded = append(encoded, rios) 71 mu.Unlock() 72 }() 73 } 74 wg.Wait() 75 76 // However, identical sets of dependencies should always be written to state 77 // in an identical order, so we don't do meaningless state updates on refresh. 78 for i := 0; i < len(encoded)-1; i++ { 79 if diff := cmp.Diff(encoded[i].Dependencies, encoded[i+1].Dependencies); diff != "" { 80 t.Errorf("identical dependencies got encoded in different orders:\n%s", diff) 81 } 82 } 83 }