github.com/rstandt/terraform@v0.12.32-0.20230710220336-b1063613405c/states/statemgr/statemgr_test.go (about) 1 package statemgr 2 3 import ( 4 "context" 5 "encoding/json" 6 "flag" 7 "io/ioutil" 8 "log" 9 "os" 10 "testing" 11 "time" 12 13 "github.com/hashicorp/terraform/helper/logging" 14 ) 15 16 func TestNewLockInfo(t *testing.T) { 17 info1 := NewLockInfo() 18 info2 := NewLockInfo() 19 20 if info1.ID == "" { 21 t.Fatal("LockInfo missing ID") 22 } 23 24 if info1.Version == "" { 25 t.Fatal("LockInfo missing version") 26 } 27 28 if info1.Created.IsZero() { 29 t.Fatal("LockInfo missing Created") 30 } 31 32 if info1.ID == info2.ID { 33 t.Fatal("multiple LockInfo with identical IDs") 34 } 35 36 // test the JSON output is valid 37 newInfo := &LockInfo{} 38 err := json.Unmarshal(info1.Marshal(), newInfo) 39 if err != nil { 40 t.Fatal(err) 41 } 42 } 43 44 func TestLockWithContext(t *testing.T) { 45 s := NewFullFake(nil, TestFullInitialState()) 46 47 id, err := s.Lock(NewLockInfo()) 48 if err != nil { 49 t.Fatal(err) 50 } 51 52 // use a cancelled context for an immediate timeout 53 ctx, cancel := context.WithCancel(context.Background()) 54 cancel() 55 56 info := NewLockInfo() 57 info.Info = "lock with context" 58 _, err = LockWithContext(ctx, s, info) 59 if err == nil { 60 t.Fatal("lock should have failed immediately") 61 } 62 63 // block until LockwithContext has made a first attempt 64 attempted := make(chan struct{}) 65 postLockHook = func() { 66 close(attempted) 67 postLockHook = nil 68 } 69 70 // unlock the state during LockWithContext 71 unlocked := make(chan struct{}) 72 go func() { 73 defer close(unlocked) 74 <-attempted 75 if err := s.Unlock(id); err != nil { 76 t.Fatal(err) 77 } 78 }() 79 80 ctx, cancel = context.WithTimeout(context.Background(), 2*time.Second) 81 defer cancel() 82 83 id, err = LockWithContext(ctx, s, info) 84 if err != nil { 85 t.Fatal("lock should have completed within 2s:", err) 86 } 87 88 // ensure the goruotine completes 89 <-unlocked 90 } 91 92 func TestMain(m *testing.M) { 93 flag.Parse() 94 if testing.Verbose() { 95 // if we're verbose, use the logging requested by TF_LOG 96 logging.SetOutput() 97 } else { 98 // otherwise silence all logs 99 log.SetOutput(ioutil.Discard) 100 } 101 os.Exit(m.Run()) 102 }