github.com/articulate/terraform@v0.6.13-0.20160303003731-8d31c93862de/terraform/context_test.go (about) 1 package terraform 2 3 import ( 4 "fmt" 5 "strings" 6 "testing" 7 "time" 8 ) 9 10 func testContext2(t *testing.T, opts *ContextOpts) *Context { 11 return NewContext(opts) 12 } 13 14 func testApplyFn( 15 info *InstanceInfo, 16 s *InstanceState, 17 d *InstanceDiff) (*InstanceState, error) { 18 if d.Destroy { 19 return nil, nil 20 } 21 22 id := "foo" 23 if idAttr, ok := d.Attributes["id"]; ok && !idAttr.NewComputed { 24 id = idAttr.New 25 } 26 27 result := &InstanceState{ 28 ID: id, 29 Attributes: make(map[string]string), 30 } 31 32 // Copy all the prior attributes 33 for k, v := range s.Attributes { 34 result.Attributes[k] = v 35 } 36 37 if d != nil { 38 result = result.MergeDiff(d) 39 } 40 return result, nil 41 } 42 43 func testDiffFn( 44 info *InstanceInfo, 45 s *InstanceState, 46 c *ResourceConfig) (*InstanceDiff, error) { 47 var diff InstanceDiff 48 diff.Attributes = make(map[string]*ResourceAttrDiff) 49 50 for k, v := range c.Raw { 51 if _, ok := v.(string); !ok { 52 continue 53 } 54 55 // Ignore __-prefixed keys since they're used for magic 56 if k[0] == '_' && k[1] == '_' { 57 continue 58 } 59 60 if k == "nil" { 61 return nil, nil 62 } 63 64 // This key is used for other purposes 65 if k == "compute_value" { 66 continue 67 } 68 69 if k == "compute" { 70 attrDiff := &ResourceAttrDiff{ 71 Old: "", 72 New: "", 73 NewComputed: true, 74 } 75 76 if cv, ok := c.Config["compute_value"]; ok { 77 if cv.(string) == "1" { 78 attrDiff.NewComputed = false 79 attrDiff.New = fmt.Sprintf("computed_%s", v.(string)) 80 } 81 } 82 83 diff.Attributes[v.(string)] = attrDiff 84 continue 85 } 86 87 // If this key is not computed, then look it up in the 88 // cleaned config. 89 found := false 90 for _, ck := range c.ComputedKeys { 91 if ck == k { 92 found = true 93 break 94 } 95 } 96 if !found { 97 v = c.Config[k] 98 } 99 100 attrDiff := &ResourceAttrDiff{ 101 Old: "", 102 New: v.(string), 103 } 104 105 if k == "require_new" { 106 attrDiff.RequiresNew = true 107 } 108 if _, ok := c.Raw["__"+k+"_requires_new"]; ok { 109 attrDiff.RequiresNew = true 110 } 111 diff.Attributes[k] = attrDiff 112 } 113 114 for _, k := range c.ComputedKeys { 115 diff.Attributes[k] = &ResourceAttrDiff{ 116 Old: "", 117 NewComputed: true, 118 } 119 } 120 121 for k, v := range diff.Attributes { 122 if v.NewComputed { 123 continue 124 } 125 126 old, ok := s.Attributes[k] 127 if !ok { 128 continue 129 } 130 if old == v.New { 131 delete(diff.Attributes, k) 132 } 133 } 134 135 if !diff.Empty() { 136 diff.Attributes["type"] = &ResourceAttrDiff{ 137 Old: "", 138 New: info.Type, 139 } 140 } 141 142 return &diff, nil 143 } 144 145 func testProvider(prefix string) *MockResourceProvider { 146 p := new(MockResourceProvider) 147 p.RefreshFn = func(info *InstanceInfo, s *InstanceState) (*InstanceState, error) { 148 return s, nil 149 } 150 p.ResourcesReturn = []ResourceType{ 151 ResourceType{ 152 Name: fmt.Sprintf("%s_instance", prefix), 153 }, 154 } 155 156 return p 157 } 158 159 func testProvisioner() *MockResourceProvisioner { 160 p := new(MockResourceProvisioner) 161 return p 162 } 163 164 func checkStateString(t *testing.T, state *State, expected string) { 165 actual := strings.TrimSpace(state.String()) 166 expected = strings.TrimSpace(expected) 167 168 if actual != expected { 169 t.Fatalf("state does not match! actual:\n%s\n\nexpected:\n%s", actual, expected) 170 } 171 } 172 173 func resourceState(resourceType, resourceID string) *ResourceState { 174 return &ResourceState{ 175 Type: resourceType, 176 Primary: &InstanceState{ 177 ID: resourceID, 178 }, 179 } 180 } 181 182 // Test helper that gives a function 3 seconds to finish, assumes deadlock and 183 // fails test if it does not. 184 func testCheckDeadlock(t *testing.T, f func()) { 185 timeout := make(chan bool, 1) 186 done := make(chan bool, 1) 187 go func() { 188 time.Sleep(3 * time.Second) 189 timeout <- true 190 }() 191 go func(f func(), done chan bool) { 192 defer func() { done <- true }() 193 f() 194 }(f, done) 195 select { 196 case <-timeout: 197 t.Fatalf("timed out! probably deadlock") 198 case <-done: 199 // ok 200 } 201 } 202 203 const testContextGraph = ` 204 root: root 205 aws_instance.bar 206 aws_instance.bar -> provider.aws 207 aws_instance.foo 208 aws_instance.foo -> provider.aws 209 provider.aws 210 root 211 root -> aws_instance.bar 212 root -> aws_instance.foo 213 ` 214 215 const testContextRefreshModuleStr = ` 216 aws_instance.web: (1 tainted) 217 ID = <not created> 218 Tainted ID 1 = bar 219 220 module.child: 221 aws_instance.web: 222 ID = new 223 ` 224 225 const testContextRefreshOutputStr = ` 226 aws_instance.web: 227 ID = foo 228 foo = bar 229 230 Outputs: 231 232 foo = bar 233 ` 234 235 const testContextRefreshOutputPartialStr = ` 236 <no state> 237 ` 238 239 const testContextRefreshTaintedStr = ` 240 aws_instance.web: (1 tainted) 241 ID = <not created> 242 Tainted ID 1 = foo 243 `