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