github.com/grange74/terraform@v0.7.0-rc3.0.20160722171430-8c8803864753/config/config_string.go (about) 1 package config 2 3 import ( 4 "bytes" 5 "fmt" 6 "sort" 7 "strings" 8 ) 9 10 // TestString is a Stringer-like function that outputs a string that can 11 // be used to easily compare multiple Config structures in unit tests. 12 // 13 // This function has no practical use outside of unit tests and debugging. 14 func (c *Config) TestString() string { 15 if c == nil { 16 return "<nil config>" 17 } 18 19 var buf bytes.Buffer 20 if len(c.Modules) > 0 { 21 buf.WriteString("Modules:\n\n") 22 buf.WriteString(modulesStr(c.Modules)) 23 buf.WriteString("\n\n") 24 } 25 26 if len(c.Variables) > 0 { 27 buf.WriteString("Variables:\n\n") 28 buf.WriteString(variablesStr(c.Variables)) 29 buf.WriteString("\n\n") 30 } 31 32 if len(c.ProviderConfigs) > 0 { 33 buf.WriteString("Provider Configs:\n\n") 34 buf.WriteString(providerConfigsStr(c.ProviderConfigs)) 35 buf.WriteString("\n\n") 36 } 37 38 if len(c.Resources) > 0 { 39 buf.WriteString("Resources:\n\n") 40 buf.WriteString(resourcesStr(c.Resources)) 41 buf.WriteString("\n\n") 42 } 43 44 if len(c.Outputs) > 0 { 45 buf.WriteString("Outputs:\n\n") 46 buf.WriteString(outputsStr(c.Outputs)) 47 buf.WriteString("\n") 48 } 49 50 return strings.TrimSpace(buf.String()) 51 } 52 53 func modulesStr(ms []*Module) string { 54 result := "" 55 order := make([]int, 0, len(ms)) 56 ks := make([]string, 0, len(ms)) 57 mapping := make(map[string]int) 58 for i, m := range ms { 59 k := m.Id() 60 ks = append(ks, k) 61 mapping[k] = i 62 } 63 sort.Strings(ks) 64 for _, k := range ks { 65 order = append(order, mapping[k]) 66 } 67 68 for _, i := range order { 69 m := ms[i] 70 result += fmt.Sprintf("%s\n", m.Id()) 71 72 ks := make([]string, 0, len(m.RawConfig.Raw)) 73 for k, _ := range m.RawConfig.Raw { 74 ks = append(ks, k) 75 } 76 sort.Strings(ks) 77 78 result += fmt.Sprintf(" source = %s\n", m.Source) 79 80 for _, k := range ks { 81 result += fmt.Sprintf(" %s\n", k) 82 } 83 } 84 85 return strings.TrimSpace(result) 86 } 87 88 func outputsStr(os []*Output) string { 89 ns := make([]string, 0, len(os)) 90 m := make(map[string]*Output) 91 for _, o := range os { 92 ns = append(ns, o.Name) 93 m[o.Name] = o 94 } 95 sort.Strings(ns) 96 97 result := "" 98 for _, n := range ns { 99 o := m[n] 100 101 result += fmt.Sprintf("%s\n", n) 102 103 if len(o.RawConfig.Variables) > 0 { 104 result += fmt.Sprintf(" vars\n") 105 for _, rawV := range o.RawConfig.Variables { 106 kind := "unknown" 107 str := rawV.FullKey() 108 109 switch rawV.(type) { 110 case *ResourceVariable: 111 kind = "resource" 112 case *UserVariable: 113 kind = "user" 114 } 115 116 result += fmt.Sprintf(" %s: %s\n", kind, str) 117 } 118 } 119 } 120 121 return strings.TrimSpace(result) 122 } 123 124 // This helper turns a provider configs field into a deterministic 125 // string value for comparison in tests. 126 func providerConfigsStr(pcs []*ProviderConfig) string { 127 result := "" 128 129 ns := make([]string, 0, len(pcs)) 130 m := make(map[string]*ProviderConfig) 131 for _, n := range pcs { 132 ns = append(ns, n.Name) 133 m[n.Name] = n 134 } 135 sort.Strings(ns) 136 137 for _, n := range ns { 138 pc := m[n] 139 140 result += fmt.Sprintf("%s\n", n) 141 142 keys := make([]string, 0, len(pc.RawConfig.Raw)) 143 for k, _ := range pc.RawConfig.Raw { 144 keys = append(keys, k) 145 } 146 sort.Strings(keys) 147 148 for _, k := range keys { 149 result += fmt.Sprintf(" %s\n", k) 150 } 151 152 if len(pc.RawConfig.Variables) > 0 { 153 result += fmt.Sprintf(" vars\n") 154 for _, rawV := range pc.RawConfig.Variables { 155 kind := "unknown" 156 str := rawV.FullKey() 157 158 switch rawV.(type) { 159 case *ResourceVariable: 160 kind = "resource" 161 case *UserVariable: 162 kind = "user" 163 } 164 165 result += fmt.Sprintf(" %s: %s\n", kind, str) 166 } 167 } 168 } 169 170 return strings.TrimSpace(result) 171 } 172 173 // This helper turns a resources field into a deterministic 174 // string value for comparison in tests. 175 func resourcesStr(rs []*Resource) string { 176 result := "" 177 order := make([]int, 0, len(rs)) 178 ks := make([]string, 0, len(rs)) 179 mapping := make(map[string]int) 180 for i, r := range rs { 181 k := r.Id() 182 ks = append(ks, k) 183 mapping[k] = i 184 } 185 sort.Strings(ks) 186 for _, k := range ks { 187 order = append(order, mapping[k]) 188 } 189 190 for _, i := range order { 191 r := rs[i] 192 result += fmt.Sprintf( 193 "%s (x%s)\n", 194 r.Id(), 195 r.RawCount.Value()) 196 197 ks := make([]string, 0, len(r.RawConfig.Raw)) 198 for k, _ := range r.RawConfig.Raw { 199 ks = append(ks, k) 200 } 201 sort.Strings(ks) 202 203 for _, k := range ks { 204 result += fmt.Sprintf(" %s\n", k) 205 } 206 207 if len(r.Provisioners) > 0 { 208 result += fmt.Sprintf(" provisioners\n") 209 for _, p := range r.Provisioners { 210 result += fmt.Sprintf(" %s\n", p.Type) 211 212 ks := make([]string, 0, len(p.RawConfig.Raw)) 213 for k, _ := range p.RawConfig.Raw { 214 ks = append(ks, k) 215 } 216 sort.Strings(ks) 217 218 for _, k := range ks { 219 result += fmt.Sprintf(" %s\n", k) 220 } 221 } 222 } 223 224 if len(r.DependsOn) > 0 { 225 result += fmt.Sprintf(" dependsOn\n") 226 for _, d := range r.DependsOn { 227 result += fmt.Sprintf(" %s\n", d) 228 } 229 } 230 231 if len(r.RawConfig.Variables) > 0 { 232 result += fmt.Sprintf(" vars\n") 233 234 ks := make([]string, 0, len(r.RawConfig.Variables)) 235 for k, _ := range r.RawConfig.Variables { 236 ks = append(ks, k) 237 } 238 sort.Strings(ks) 239 240 for _, k := range ks { 241 rawV := r.RawConfig.Variables[k] 242 kind := "unknown" 243 str := rawV.FullKey() 244 245 switch rawV.(type) { 246 case *ResourceVariable: 247 kind = "resource" 248 case *UserVariable: 249 kind = "user" 250 } 251 252 result += fmt.Sprintf(" %s: %s\n", kind, str) 253 } 254 } 255 } 256 257 return strings.TrimSpace(result) 258 } 259 260 // This helper turns a variables field into a deterministic 261 // string value for comparison in tests. 262 func variablesStr(vs []*Variable) string { 263 result := "" 264 ks := make([]string, 0, len(vs)) 265 m := make(map[string]*Variable) 266 for _, v := range vs { 267 ks = append(ks, v.Name) 268 m[v.Name] = v 269 } 270 sort.Strings(ks) 271 272 for _, k := range ks { 273 v := m[k] 274 275 required := "" 276 if v.Required() { 277 required = " (required)" 278 } 279 280 declaredType := "" 281 if v.DeclaredType != "" { 282 declaredType = fmt.Sprintf(" (%s)", v.DeclaredType) 283 } 284 285 if v.Default == nil || v.Default == "" { 286 v.Default = "<>" 287 } 288 if v.Description == "" { 289 v.Description = "<>" 290 } 291 292 result += fmt.Sprintf( 293 "%s%s%s\n %v\n %s\n", 294 k, 295 required, 296 declaredType, 297 v.Default, 298 v.Description) 299 } 300 301 return strings.TrimSpace(result) 302 }