github.com/turtlemonvh/terraform@v0.6.9-0.20151204001754-8e40b6b855e8/terraform/eval_state_test.go (about) 1 package terraform 2 3 import ( 4 "sync" 5 "testing" 6 ) 7 8 func TestEvalRequireState(t *testing.T) { 9 ctx := new(MockEvalContext) 10 11 cases := []struct { 12 State *InstanceState 13 Exit bool 14 }{ 15 { 16 nil, 17 true, 18 }, 19 { 20 &InstanceState{}, 21 true, 22 }, 23 { 24 &InstanceState{ID: "foo"}, 25 false, 26 }, 27 } 28 29 var exitVal EvalEarlyExitError 30 for _, tc := range cases { 31 node := &EvalRequireState{State: &tc.State} 32 _, err := node.Eval(ctx) 33 if tc.Exit { 34 if err != exitVal { 35 t.Fatalf("should've exited: %#v", tc.State) 36 } 37 38 continue 39 } 40 if !tc.Exit && err != nil { 41 t.Fatalf("shouldn't exit: %#v", tc.State) 42 } 43 if err != nil { 44 t.Fatalf("err: %s", err) 45 } 46 } 47 } 48 49 func TestEvalUpdateStateHook(t *testing.T) { 50 mockHook := new(MockHook) 51 52 ctx := new(MockEvalContext) 53 ctx.HookHook = mockHook 54 ctx.StateState = &State{Serial: 42} 55 ctx.StateLock = new(sync.RWMutex) 56 57 node := &EvalUpdateStateHook{} 58 if _, err := node.Eval(ctx); err != nil { 59 t.Fatalf("err: %s", err) 60 } 61 62 if !mockHook.PostStateUpdateCalled { 63 t.Fatal("should call PostStateUpdate") 64 } 65 if mockHook.PostStateUpdateState.Serial != 42 { 66 t.Fatalf("bad: %#v", mockHook.PostStateUpdateState) 67 } 68 } 69 70 func TestEvalReadState(t *testing.T) { 71 var output *InstanceState 72 cases := map[string]struct { 73 Resources map[string]*ResourceState 74 Node EvalNode 75 ExpectedInstanceId string 76 }{ 77 "ReadState gets primary instance state": { 78 Resources: map[string]*ResourceState{ 79 "aws_instance.bar": &ResourceState{ 80 Primary: &InstanceState{ 81 ID: "i-abc123", 82 }, 83 }, 84 }, 85 Node: &EvalReadState{ 86 Name: "aws_instance.bar", 87 Output: &output, 88 }, 89 ExpectedInstanceId: "i-abc123", 90 }, 91 "ReadStateTainted gets tainted instance": { 92 Resources: map[string]*ResourceState{ 93 "aws_instance.bar": &ResourceState{ 94 Tainted: []*InstanceState{ 95 &InstanceState{ID: "i-abc123"}, 96 }, 97 }, 98 }, 99 Node: &EvalReadStateTainted{ 100 Name: "aws_instance.bar", 101 Output: &output, 102 Index: 0, 103 }, 104 ExpectedInstanceId: "i-abc123", 105 }, 106 "ReadStateDeposed gets deposed instance": { 107 Resources: map[string]*ResourceState{ 108 "aws_instance.bar": &ResourceState{ 109 Deposed: []*InstanceState{ 110 &InstanceState{ID: "i-abc123"}, 111 }, 112 }, 113 }, 114 Node: &EvalReadStateDeposed{ 115 Name: "aws_instance.bar", 116 Output: &output, 117 Index: 0, 118 }, 119 ExpectedInstanceId: "i-abc123", 120 }, 121 } 122 123 for k, c := range cases { 124 ctx := new(MockEvalContext) 125 ctx.StateState = &State{ 126 Modules: []*ModuleState{ 127 &ModuleState{ 128 Path: rootModulePath, 129 Resources: c.Resources, 130 }, 131 }, 132 } 133 ctx.StateLock = new(sync.RWMutex) 134 ctx.PathPath = rootModulePath 135 136 result, err := c.Node.Eval(ctx) 137 if err != nil { 138 t.Fatalf("[%s] Got err: %#v", k, err) 139 } 140 141 expected := c.ExpectedInstanceId 142 if !(result != nil && result.(*InstanceState).ID == expected) { 143 t.Fatalf("[%s] Expected return with ID %#v, got: %#v", k, expected, result) 144 } 145 146 if !(output != nil && output.ID == expected) { 147 t.Fatalf("[%s] Expected output with ID %#v, got: %#v", k, expected, output) 148 } 149 150 output = nil 151 } 152 } 153 154 func TestEvalWriteState(t *testing.T) { 155 state := &State{} 156 ctx := new(MockEvalContext) 157 ctx.StateState = state 158 ctx.StateLock = new(sync.RWMutex) 159 ctx.PathPath = rootModulePath 160 161 is := &InstanceState{ID: "i-abc123"} 162 node := &EvalWriteState{ 163 Name: "restype.resname", 164 ResourceType: "restype", 165 State: &is, 166 } 167 _, err := node.Eval(ctx) 168 if err != nil { 169 t.Fatalf("Got err: %#v", err) 170 } 171 172 checkStateString(t, state, ` 173 restype.resname: 174 ID = i-abc123 175 `) 176 } 177 178 func TestEvalWriteStateTainted(t *testing.T) { 179 state := &State{} 180 ctx := new(MockEvalContext) 181 ctx.StateState = state 182 ctx.StateLock = new(sync.RWMutex) 183 ctx.PathPath = rootModulePath 184 185 is := &InstanceState{ID: "i-abc123"} 186 node := &EvalWriteStateTainted{ 187 Name: "restype.resname", 188 ResourceType: "restype", 189 State: &is, 190 Index: -1, 191 } 192 _, err := node.Eval(ctx) 193 if err != nil { 194 t.Fatalf("Got err: %#v", err) 195 } 196 197 checkStateString(t, state, ` 198 restype.resname: (1 tainted) 199 ID = <not created> 200 Tainted ID 1 = i-abc123 201 `) 202 } 203 204 func TestEvalWriteStateDeposed(t *testing.T) { 205 state := &State{} 206 ctx := new(MockEvalContext) 207 ctx.StateState = state 208 ctx.StateLock = new(sync.RWMutex) 209 ctx.PathPath = rootModulePath 210 211 is := &InstanceState{ID: "i-abc123"} 212 node := &EvalWriteStateDeposed{ 213 Name: "restype.resname", 214 ResourceType: "restype", 215 State: &is, 216 Index: -1, 217 } 218 _, err := node.Eval(ctx) 219 if err != nil { 220 t.Fatalf("Got err: %#v", err) 221 } 222 223 checkStateString(t, state, ` 224 restype.resname: (1 deposed) 225 ID = <not created> 226 Deposed ID 1 = i-abc123 227 `) 228 }