github.com/graywolf-at-work-2/terraform-vendor@v1.4.5/internal/configs/module_merge_test.go (about) 1 package configs 2 3 import ( 4 "fmt" 5 "testing" 6 7 "github.com/hashicorp/hcl/v2" 8 "github.com/hashicorp/hcl/v2/gohcl" 9 "github.com/hashicorp/terraform/internal/addrs" 10 "github.com/zclconf/go-cty/cty" 11 ) 12 13 func TestModuleOverrideVariable(t *testing.T) { 14 mod, diags := testModuleFromDir("testdata/valid-modules/override-variable") 15 assertNoDiagnostics(t, diags) 16 if mod == nil { 17 t.Fatalf("module is nil") 18 } 19 20 got := mod.Variables 21 want := map[string]*Variable{ 22 "fully_overridden": { 23 Name: "fully_overridden", 24 Description: "b_override description", 25 DescriptionSet: true, 26 Default: cty.StringVal("b_override"), 27 Nullable: false, 28 NullableSet: true, 29 Type: cty.String, 30 ConstraintType: cty.String, 31 ParsingMode: VariableParseLiteral, 32 DeclRange: hcl.Range{ 33 Filename: "testdata/valid-modules/override-variable/primary.tf", 34 Start: hcl.Pos{ 35 Line: 1, 36 Column: 1, 37 Byte: 0, 38 }, 39 End: hcl.Pos{ 40 Line: 1, 41 Column: 28, 42 Byte: 27, 43 }, 44 }, 45 }, 46 "partially_overridden": { 47 Name: "partially_overridden", 48 Description: "base description", 49 DescriptionSet: true, 50 Default: cty.StringVal("b_override partial"), 51 Nullable: true, 52 NullableSet: false, 53 Type: cty.String, 54 ConstraintType: cty.String, 55 ParsingMode: VariableParseLiteral, 56 DeclRange: hcl.Range{ 57 Filename: "testdata/valid-modules/override-variable/primary.tf", 58 Start: hcl.Pos{ 59 Line: 7, 60 Column: 1, 61 Byte: 103, 62 }, 63 End: hcl.Pos{ 64 Line: 7, 65 Column: 32, 66 Byte: 134, 67 }, 68 }, 69 }, 70 } 71 assertResultDeepEqual(t, got, want) 72 } 73 74 func TestModuleOverrideModule(t *testing.T) { 75 mod, diags := testModuleFromDir("testdata/valid-modules/override-module") 76 assertNoDiagnostics(t, diags) 77 if mod == nil { 78 t.Fatalf("module is nil") 79 } 80 81 if _, exists := mod.ModuleCalls["example"]; !exists { 82 t.Fatalf("no module 'example'") 83 } 84 if len(mod.ModuleCalls) != 1 { 85 t.Fatalf("wrong number of module calls in result %d; want 1", len(mod.ModuleCalls)) 86 } 87 88 got := mod.ModuleCalls["example"] 89 want := &ModuleCall{ 90 Name: "example", 91 SourceAddr: addrs.ModuleSourceLocal("./example2-a_override"), 92 SourceAddrRaw: "./example2-a_override", 93 SourceAddrRange: hcl.Range{ 94 Filename: "testdata/valid-modules/override-module/a_override.tf", 95 Start: hcl.Pos{ 96 Line: 3, 97 Column: 12, 98 Byte: 31, 99 }, 100 End: hcl.Pos{ 101 Line: 3, 102 Column: 35, 103 Byte: 54, 104 }, 105 }, 106 SourceSet: true, 107 DeclRange: hcl.Range{ 108 Filename: "testdata/valid-modules/override-module/primary.tf", 109 Start: hcl.Pos{ 110 Line: 2, 111 Column: 1, 112 Byte: 1, 113 }, 114 End: hcl.Pos{ 115 Line: 2, 116 Column: 17, 117 Byte: 17, 118 }, 119 }, 120 DependsOn: []hcl.Traversal{ 121 { 122 hcl.TraverseRoot{ 123 Name: "null_resource", 124 SrcRange: hcl.Range{ 125 Filename: "testdata/valid-modules/override-module/primary.tf", 126 Start: hcl.Pos{Line: 11, Column: 17, Byte: 149}, 127 End: hcl.Pos{Line: 11, Column: 30, Byte: 162}, 128 }, 129 }, 130 hcl.TraverseAttr{ 131 Name: "test", 132 SrcRange: hcl.Range{ 133 Filename: "testdata/valid-modules/override-module/primary.tf", 134 Start: hcl.Pos{Line: 11, Column: 30, Byte: 162}, 135 End: hcl.Pos{Line: 11, Column: 35, Byte: 167}, 136 }, 137 }, 138 }, 139 }, 140 Providers: []PassedProviderConfig{ 141 { 142 InChild: &ProviderConfigRef{ 143 Name: "test", 144 NameRange: hcl.Range{ 145 Filename: "testdata/valid-modules/override-module/b_override.tf", 146 Start: hcl.Pos{Line: 7, Column: 5, Byte: 97}, 147 End: hcl.Pos{Line: 7, Column: 9, Byte: 101}, 148 }, 149 }, 150 InParent: &ProviderConfigRef{ 151 Name: "test", 152 NameRange: hcl.Range{ 153 Filename: "testdata/valid-modules/override-module/b_override.tf", 154 Start: hcl.Pos{Line: 7, Column: 12, Byte: 104}, 155 End: hcl.Pos{Line: 7, Column: 16, Byte: 108}, 156 }, 157 Alias: "b_override", 158 AliasRange: &hcl.Range{ 159 Filename: "testdata/valid-modules/override-module/b_override.tf", 160 Start: hcl.Pos{Line: 7, Column: 16, Byte: 108}, 161 End: hcl.Pos{Line: 7, Column: 27, Byte: 119}, 162 }, 163 }, 164 }, 165 }, 166 } 167 168 // We're going to extract and nil out our hcl.Body here because DeepEqual 169 // is not a useful way to assert on that. 170 gotConfig := got.Config 171 got.Config = nil 172 173 assertResultDeepEqual(t, got, want) 174 175 type content struct { 176 Kept *string `hcl:"kept"` 177 Foo *string `hcl:"foo"` 178 New *string `hcl:"new"` 179 Newer *string `hcl:"newer"` 180 } 181 var gotArgs content 182 diags = gohcl.DecodeBody(gotConfig, nil, &gotArgs) 183 assertNoDiagnostics(t, diags) 184 185 wantArgs := content{ 186 Kept: stringPtr("primary kept"), 187 Foo: stringPtr("a_override foo"), 188 New: stringPtr("b_override new"), 189 Newer: stringPtr("b_override newer"), 190 } 191 192 assertResultDeepEqual(t, gotArgs, wantArgs) 193 } 194 195 func TestModuleOverrideDynamic(t *testing.T) { 196 schema := &hcl.BodySchema{ 197 Blocks: []hcl.BlockHeaderSchema{ 198 {Type: "foo"}, 199 {Type: "dynamic", LabelNames: []string{"type"}}, 200 }, 201 } 202 203 t.Run("base is dynamic", func(t *testing.T) { 204 mod, diags := testModuleFromDir("testdata/valid-modules/override-dynamic-block-base") 205 assertNoDiagnostics(t, diags) 206 if mod == nil { 207 t.Fatalf("module is nil") 208 } 209 210 if _, exists := mod.ManagedResources["test.foo"]; !exists { 211 t.Fatalf("no module 'example'") 212 } 213 if len(mod.ManagedResources) != 1 { 214 t.Fatalf("wrong number of managed resources in result %d; want 1", len(mod.ManagedResources)) 215 } 216 217 body := mod.ManagedResources["test.foo"].Config 218 content, diags := body.Content(schema) 219 assertNoDiagnostics(t, diags) 220 221 if len(content.Blocks) != 1 { 222 t.Fatalf("wrong number of blocks in result %d; want 1", len(content.Blocks)) 223 } 224 if got, want := content.Blocks[0].Type, "foo"; got != want { 225 t.Fatalf("wrong block type %q; want %q", got, want) 226 } 227 }) 228 t.Run("override is dynamic", func(t *testing.T) { 229 mod, diags := testModuleFromDir("testdata/valid-modules/override-dynamic-block-override") 230 assertNoDiagnostics(t, diags) 231 if mod == nil { 232 t.Fatalf("module is nil") 233 } 234 235 if _, exists := mod.ManagedResources["test.foo"]; !exists { 236 t.Fatalf("no module 'example'") 237 } 238 if len(mod.ManagedResources) != 1 { 239 t.Fatalf("wrong number of managed resources in result %d; want 1", len(mod.ManagedResources)) 240 } 241 242 body := mod.ManagedResources["test.foo"].Config 243 content, diags := body.Content(schema) 244 assertNoDiagnostics(t, diags) 245 246 if len(content.Blocks) != 1 { 247 t.Fatalf("wrong number of blocks in result %d; want 1", len(content.Blocks)) 248 } 249 if got, want := content.Blocks[0].Type, "dynamic"; got != want { 250 t.Fatalf("wrong block type %q; want %q", got, want) 251 } 252 if got, want := content.Blocks[0].Labels[0], "foo"; got != want { 253 t.Fatalf("wrong dynamic block label %q; want %q", got, want) 254 } 255 }) 256 } 257 258 func TestModuleOverrideSensitiveVariable(t *testing.T) { 259 type testCase struct { 260 sensitive bool 261 sensitiveSet bool 262 } 263 cases := map[string]testCase{ 264 "false_true": { 265 sensitive: true, 266 sensitiveSet: true, 267 }, 268 "true_false": { 269 sensitive: false, 270 sensitiveSet: true, 271 }, 272 "false_false_true": { 273 sensitive: true, 274 sensitiveSet: true, 275 }, 276 "true_true_false": { 277 sensitive: false, 278 sensitiveSet: true, 279 }, 280 "false_true_false": { 281 sensitive: false, 282 sensitiveSet: true, 283 }, 284 "true_false_true": { 285 sensitive: true, 286 sensitiveSet: true, 287 }, 288 } 289 290 mod, diags := testModuleFromDir("testdata/valid-modules/override-variable-sensitive") 291 292 assertNoDiagnostics(t, diags) 293 294 if mod == nil { 295 t.Fatalf("module is nil") 296 } 297 298 got := mod.Variables 299 300 for v, want := range cases { 301 t.Run(fmt.Sprintf("variable %s", v), func(t *testing.T) { 302 if got[v].Sensitive != want.sensitive { 303 t.Errorf("wrong result for sensitive\ngot: %t want: %t", got[v].Sensitive, want.sensitive) 304 } 305 306 if got[v].SensitiveSet != want.sensitiveSet { 307 t.Errorf("wrong result for sensitive set\ngot: %t want: %t", got[v].Sensitive, want.sensitive) 308 } 309 }) 310 } 311 } 312 313 func TestModuleOverrideResourceFQNs(t *testing.T) { 314 mod, diags := testModuleFromDir("testdata/valid-modules/override-resource-provider") 315 assertNoDiagnostics(t, diags) 316 317 got := mod.ManagedResources["test_instance.explicit"] 318 wantProvider := addrs.NewProvider(addrs.DefaultProviderRegistryHost, "bar", "test") 319 wantProviderCfg := &ProviderConfigRef{ 320 Name: "bar-test", 321 NameRange: hcl.Range{ 322 Filename: "testdata/valid-modules/override-resource-provider/a_override.tf", 323 Start: hcl.Pos{Line: 2, Column: 14, Byte: 51}, 324 End: hcl.Pos{Line: 2, Column: 22, Byte: 59}, 325 }, 326 } 327 328 if !got.Provider.Equals(wantProvider) { 329 t.Fatalf("wrong provider %s, want %s", got.Provider, wantProvider) 330 } 331 assertResultDeepEqual(t, got.ProviderConfigRef, wantProviderCfg) 332 333 // now verify that a resource with no provider config falls back to default 334 got = mod.ManagedResources["test_instance.default"] 335 wantProvider = addrs.NewDefaultProvider("test") 336 if !got.Provider.Equals(wantProvider) { 337 t.Fatalf("wrong provider %s, want %s", got.Provider, wantProvider) 338 } 339 if got.ProviderConfigRef != nil { 340 t.Fatalf("wrong result: found provider config ref %s, expected nil", got.ProviderConfigRef) 341 } 342 } 343 344 func TestModuleOverrideIgnoreAllChanges(t *testing.T) { 345 mod, diags := testModuleFromDir("testdata/valid-modules/override-ignore-changes") 346 assertNoDiagnostics(t, diags) 347 348 r := mod.ManagedResources["test_instance.foo"] 349 if !r.Managed.IgnoreAllChanges { 350 t.Fatalf("wrong result: expected r.Managed.IgnoreAllChanges to be true") 351 } 352 }