github.com/pmcatominey/terraform@v0.7.0-rc2.0.20160708105029-1401a52a5cc5/helper/resource/state_test.go (about) 1 package resource 2 3 import ( 4 "errors" 5 "testing" 6 "time" 7 ) 8 9 func FailedStateRefreshFunc() StateRefreshFunc { 10 return func() (interface{}, string, error) { 11 return nil, "", errors.New("failed") 12 } 13 } 14 15 func TimeoutStateRefreshFunc() StateRefreshFunc { 16 return func() (interface{}, string, error) { 17 time.Sleep(100 * time.Second) 18 return nil, "", errors.New("failed") 19 } 20 } 21 22 func SuccessfulStateRefreshFunc() StateRefreshFunc { 23 return func() (interface{}, string, error) { 24 return struct{}{}, "running", nil 25 } 26 } 27 28 type StateGenerator struct { 29 position int 30 stateSequence []string 31 } 32 33 func (r *StateGenerator) NextState() (int, string, error) { 34 p, v := r.position, "" 35 if len(r.stateSequence)-1 >= p { 36 v = r.stateSequence[p] 37 } else { 38 return -1, "", errors.New("No more states available") 39 } 40 41 r.position += 1 42 43 return p, v, nil 44 } 45 46 func NewStateGenerator(sequence []string) *StateGenerator { 47 r := &StateGenerator{} 48 r.stateSequence = sequence 49 50 return r 51 } 52 53 func InconsistentStateRefreshFunc() StateRefreshFunc { 54 sequence := []string{ 55 "done", "replicating", 56 "done", "done", "done", 57 "replicating", 58 "done", "done", "done", 59 } 60 61 r := NewStateGenerator(sequence) 62 63 return func() (interface{}, string, error) { 64 idx, s, err := r.NextState() 65 if err != nil { 66 return nil, "", err 67 } 68 69 return idx, s, nil 70 } 71 } 72 73 func TestWaitForState_inconsistent_positive(t *testing.T) { 74 conf := &StateChangeConf{ 75 Pending: []string{"replicating"}, 76 Target: []string{"done"}, 77 Refresh: InconsistentStateRefreshFunc(), 78 Timeout: 10 * time.Second, 79 ContinuousTargetOccurence: 3, 80 } 81 82 idx, err := conf.WaitForState() 83 84 if err != nil { 85 t.Fatalf("err: %s", err) 86 } 87 88 if idx != 4 { 89 t.Fatalf("Expected index 4, given %d", idx.(int)) 90 } 91 } 92 93 func TestWaitForState_inconsistent_negative(t *testing.T) { 94 conf := &StateChangeConf{ 95 Pending: []string{"replicating"}, 96 Target: []string{"done"}, 97 Refresh: InconsistentStateRefreshFunc(), 98 Timeout: 10 * time.Second, 99 ContinuousTargetOccurence: 4, 100 } 101 102 _, err := conf.WaitForState() 103 104 if err == nil && err.Error() != "timeout while waiting for state to become 'done'" { 105 t.Fatalf("err: %s", err) 106 } 107 } 108 109 func TestWaitForState_timeout(t *testing.T) { 110 conf := &StateChangeConf{ 111 Pending: []string{"pending", "incomplete"}, 112 Target: []string{"running"}, 113 Refresh: TimeoutStateRefreshFunc(), 114 Timeout: 1 * time.Millisecond, 115 } 116 117 obj, err := conf.WaitForState() 118 119 if err == nil && err.Error() != "timeout while waiting for state to become 'running'" { 120 t.Fatalf("err: %s", err) 121 } 122 123 if obj != nil { 124 t.Fatalf("should not return obj") 125 } 126 127 } 128 129 func TestWaitForState_success(t *testing.T) { 130 conf := &StateChangeConf{ 131 Pending: []string{"pending", "incomplete"}, 132 Target: []string{"running"}, 133 Refresh: SuccessfulStateRefreshFunc(), 134 Timeout: 200 * time.Second, 135 } 136 137 obj, err := conf.WaitForState() 138 if err != nil { 139 t.Fatalf("err: %s", err) 140 } 141 if obj == nil { 142 t.Fatalf("should return obj") 143 } 144 } 145 146 func TestWaitForState_successEmpty(t *testing.T) { 147 conf := &StateChangeConf{ 148 Pending: []string{"pending", "incomplete"}, 149 Target: []string{}, 150 Refresh: func() (interface{}, string, error) { 151 return nil, "", nil 152 }, 153 Timeout: 200 * time.Second, 154 } 155 156 obj, err := conf.WaitForState() 157 if err != nil { 158 t.Fatalf("err: %s", err) 159 } 160 if obj != nil { 161 t.Fatalf("obj should be nil") 162 } 163 } 164 165 func TestWaitForState_failure(t *testing.T) { 166 conf := &StateChangeConf{ 167 Pending: []string{"pending", "incomplete"}, 168 Target: []string{"running"}, 169 Refresh: FailedStateRefreshFunc(), 170 Timeout: 200 * time.Second, 171 } 172 173 obj, err := conf.WaitForState() 174 if err == nil && err.Error() != "failed" { 175 t.Fatalf("err: %s", err) 176 } 177 if obj != nil { 178 t.Fatalf("should not return obj") 179 } 180 }