@@ -12,6 +12,7 @@ import (
12
12
13
13
"github.com/google/go-cmp/cmp"
14
14
"github.com/google/go-cmp/cmp/cmpopts"
15
+ "github.com/hashicorp/hcl/v2"
15
16
"github.com/hashicorp/terraform/internal/addrs"
16
17
"github.com/hashicorp/terraform/internal/configs/configschema"
17
18
"github.com/hashicorp/terraform/internal/plans"
@@ -24,15 +25,16 @@ import (
24
25
25
26
func TestContext2Plan_queryList (t * testing.T ) {
26
27
cases := []struct {
27
- name string
28
- mainConfig string
29
- queryConfig string
30
- generatedPath string
31
- diagCount int
32
- expectedErrMsg []string
33
- assertState func (* states.State )
34
- assertChanges func (providers.ProviderSchema , * plans.ChangesSrc )
35
- listResourceFn func (request providers.ListResourceRequest ) providers.ListResourceResponse
28
+ name string
29
+ mainConfig string
30
+ queryConfig string
31
+ generatedPath string
32
+ expectedErrMsg []string
33
+ transformSchema func (* providers.GetProviderSchemaResponse )
34
+ assertState func (* states.State )
35
+ assertValidateDiags func (t * testing.T , diags tfdiags.Diagnostics )
36
+ assertChanges func (providers.ProviderSchema , * plans.ChangesSrc )
37
+ listResourceFn func (request providers.ListResourceRequest ) providers.ListResourceResponse
36
38
}{
37
39
{
38
40
name : "valid list reference - generates config" ,
@@ -262,7 +264,68 @@ func TestContext2Plan_queryList(t *testing.T) {
262
264
},
263
265
},
264
266
{
265
- name : "valid list with empty config" ,
267
+ // want this to fail
268
+ name : "with empty config when it is required" ,
269
+ mainConfig : `
270
+ terraform {
271
+ required_providers {
272
+ test = {
273
+ source = "hashicorp/test"
274
+ version = "1.0.0"
275
+ }
276
+ }
277
+ }
278
+ ` ,
279
+ queryConfig : `
280
+ variable "input" {
281
+ type = string
282
+ default = "foo"
283
+ }
284
+
285
+ list "test_resource" "test" {
286
+ provider = test
287
+ }
288
+ ` ,
289
+
290
+ transformSchema : func (schema * providers.GetProviderSchemaResponse ) {
291
+ schema .ListResourceTypes ["test_resource" ].Body .BlockTypes = map [string ]* configschema.NestedBlock {
292
+ "config" : {
293
+ Block : configschema.Block {
294
+ Attributes : map [string ]* configschema.Attribute {
295
+ "filter" : {
296
+ Required : true ,
297
+ NestedType : & configschema.Object {
298
+ Nesting : configschema .NestingSingle ,
299
+ Attributes : map [string ]* configschema.Attribute {
300
+ "attr" : {
301
+ Type : cty .String ,
302
+ Optional : true ,
303
+ },
304
+ },
305
+ },
306
+ },
307
+ },
308
+ },
309
+ Nesting : configschema .NestingSingle ,
310
+ MinItems : 1 ,
311
+ MaxItems : 1 ,
312
+ },
313
+ }
314
+
315
+ },
316
+ assertValidateDiags : func (t * testing.T , diags tfdiags.Diagnostics ) {
317
+ tfdiags .AssertDiagnosticCount (t , diags , 1 )
318
+ var exp tfdiags.Diagnostics
319
+ exp = exp .Append (& hcl.Diagnostic {
320
+ Summary : "Missing config block" ,
321
+ Detail : "A block of type \" config\" is required here." ,
322
+ Subject : diags [0 ].Source ().Subject .ToHCL ().Ptr (),
323
+ })
324
+ tfdiags .AssertDiagnosticsMatch (t , diags , exp )
325
+ },
326
+ },
327
+ {
328
+ name : "with empty optional config" ,
266
329
mainConfig : `
267
330
terraform {
268
331
required_providers {
@@ -283,6 +346,30 @@ func TestContext2Plan_queryList(t *testing.T) {
283
346
provider = test
284
347
}
285
348
` ,
349
+ transformSchema : func (schema * providers.GetProviderSchemaResponse ) {
350
+ schema .ListResourceTypes ["test_resource" ].Body .BlockTypes = map [string ]* configschema.NestedBlock {
351
+ "config" : {
352
+ Block : configschema.Block {
353
+ Attributes : map [string ]* configschema.Attribute {
354
+ "filter" : {
355
+ Optional : true ,
356
+ NestedType : & configschema.Object {
357
+ Nesting : configschema .NestingSingle ,
358
+ Attributes : map [string ]* configschema.Attribute {
359
+ "attr" : {
360
+ Type : cty .String ,
361
+ Optional : true ,
362
+ },
363
+ },
364
+ },
365
+ },
366
+ },
367
+ },
368
+ Nesting : configschema .NestingSingle ,
369
+ },
370
+ }
371
+
372
+ },
286
373
listResourceFn : func (request providers.ListResourceRequest ) providers.ListResourceResponse {
287
374
madeUp := []cty.Value {
288
375
cty .ObjectVal (map [string ]cty.Value {"instance_type" : cty .StringVal ("ami-123456" )}),
@@ -397,10 +484,17 @@ func TestContext2Plan_queryList(t *testing.T) {
397
484
}
398
485
}
399
486
` ,
400
- diagCount : 1 ,
401
- expectedErrMsg : []string {
402
- "Invalid list resource traversal" ,
403
- "The first step in the traversal for a list resource must be an attribute \" data\" " ,
487
+ assertValidateDiags : func (t * testing.T , diags tfdiags.Diagnostics ) {
488
+ tfdiags .AssertDiagnosticCount (t , diags , 1 )
489
+ var exp tfdiags.Diagnostics
490
+ exp = exp .Append (& hcl.Diagnostic {
491
+ Severity : hcl .DiagError ,
492
+ Summary : "Invalid list resource traversal" ,
493
+ Detail : "The first step in the traversal for a list resource must be an attribute \" data\" ." ,
494
+ Subject : diags [0 ].Source ().Subject .ToHCL ().Ptr (),
495
+ })
496
+
497
+ tfdiags .AssertDiagnosticsMatch (t , diags , exp )
404
498
},
405
499
},
406
500
{
@@ -428,9 +522,18 @@ func TestContext2Plan_queryList(t *testing.T) {
428
522
}
429
523
}
430
524
` ,
431
- diagCount : 1 ,
432
- expectedErrMsg : []string {
433
- "A list resource \" non_existent\" \" attr\" has not been declared in the root module." ,
525
+ assertValidateDiags : func (t * testing.T , diags tfdiags.Diagnostics ) {
526
+ tfdiags .AssertDiagnosticCount (t , diags , 1 )
527
+ var exp tfdiags.Diagnostics
528
+
529
+ exp = exp .Append (& hcl.Diagnostic {
530
+ Severity : hcl .DiagError ,
531
+ Summary : "Reference to undeclared resource" ,
532
+ Detail : "A list resource \" non_existent\" \" attr\" has not been declared in the root module." ,
533
+ Subject : diags [0 ].Source ().Subject .ToHCL ().Ptr (),
534
+ })
535
+
536
+ tfdiags .AssertDiagnosticsMatch (t , diags , exp )
434
537
},
435
538
},
436
539
{
@@ -469,9 +572,18 @@ func TestContext2Plan_queryList(t *testing.T) {
469
572
}
470
573
}
471
574
` ,
472
- diagCount : 1 ,
473
- expectedErrMsg : []string {
474
- "Unsupported attribute: This object has no argument, nested block, or exported attribute named \" invalid_attr\" ." ,
575
+ assertValidateDiags : func (t * testing.T , diags tfdiags.Diagnostics ) {
576
+ tfdiags .AssertDiagnosticCount (t , diags , 1 )
577
+ var exp tfdiags.Diagnostics
578
+
579
+ exp = exp .Append (& hcl.Diagnostic {
580
+ Severity : hcl .DiagError ,
581
+ Summary : "Unsupported attribute" ,
582
+ Detail : "This object has no argument, nested block, or exported attribute named \" invalid_attr\" ." ,
583
+ Subject : diags [0 ].Source ().Subject .ToHCL ().Ptr (),
584
+ })
585
+
586
+ tfdiags .AssertDiagnosticsMatch (t , diags , exp )
475
587
},
476
588
listResourceFn : func (request providers.ListResourceRequest ) providers.ListResourceResponse {
477
589
madeUp := []cty.Value {
@@ -540,9 +652,14 @@ func TestContext2Plan_queryList(t *testing.T) {
540
652
}
541
653
}
542
654
` ,
543
- diagCount : 1 ,
544
- expectedErrMsg : []string {
545
- "Cycle: list.test_resource" ,
655
+ assertValidateDiags : func (t * testing.T , diags tfdiags.Diagnostics ) {
656
+ tfdiags .AssertDiagnosticCount (t , diags , 1 )
657
+ if ! strings .Contains (diags [0 ].Description ().Summary , "Cycle: list.test_resource" ) {
658
+ t .Errorf ("Expected error message to contain 'Cycle: list.test_resource', got %q" , diags [0 ].Description ().Summary )
659
+ }
660
+ if diags [0 ].Severity () != tfdiags .Error {
661
+ t .Errorf ("Expected error severity to be Error, got %s" , diags [0 ].Severity ())
662
+ }
546
663
},
547
664
},
548
665
{
@@ -661,7 +778,7 @@ func TestContext2Plan_queryList(t *testing.T) {
661
778
},
662
779
{
663
780
// Test list reference with index but without data field
664
- name : "list reference with index but without data field " ,
781
+ name : "list reference as for_each " ,
665
782
mainConfig : `
666
783
terraform {
667
784
required_providers {
@@ -784,6 +901,9 @@ func TestContext2Plan_queryList(t *testing.T) {
784
901
provider := testProvider ("test" )
785
902
provider .ConfigureProvider (providers.ConfigureProviderRequest {})
786
903
provider .GetProviderSchemaResponse = getListProviderSchemaResp ()
904
+ if tc .transformSchema != nil {
905
+ tc .transformSchema (provider .GetProviderSchemaResponse )
906
+ }
787
907
var requestConfigs = make (map [string ]cty.Value )
788
908
provider .ListResourceFn = func (request providers.ListResourceRequest ) providers.ListResourceResponse {
789
909
if request .Config .IsNull () || request .Config .GetAttr ("config" ).IsNull () {
@@ -804,15 +924,20 @@ func TestContext2Plan_queryList(t *testing.T) {
804
924
})
805
925
tfdiags .AssertNoDiagnostics (t , diags )
806
926
927
+ diags = ctx .Validate (mod , & ValidateOpts {})
928
+ if tc .assertValidateDiags != nil {
929
+ tc .assertValidateDiags (t , diags )
930
+ return
931
+ } else {
932
+ tfdiags .AssertNoDiagnostics (t , diags )
933
+ }
934
+
807
935
plan , diags := ctx .Plan (mod , states .NewState (), & PlanOpts {
808
936
Mode : plans .NormalMode ,
809
937
SetVariables : testInputValuesUnset (mod .Module .Variables ),
810
938
Query : true ,
811
939
GenerateConfigPath : tc .generatedPath ,
812
940
})
813
- if len (diags ) != tc .diagCount {
814
- t .Fatalf ("expected %d diagnostics, got %d \n -diags: %s" , tc .diagCount , len (diags ), diags )
815
- }
816
941
817
942
if tc .assertChanges != nil {
818
943
sch , err := ctx .Schemas (mod , states .NewState ())
@@ -821,15 +946,6 @@ func TestContext2Plan_queryList(t *testing.T) {
821
946
}
822
947
tc .assertChanges (sch .Providers [providerAddr ], plan .Changes )
823
948
}
824
-
825
- if tc .diagCount > 0 {
826
- for _ , err := range tc .expectedErrMsg {
827
- if ! strings .Contains (diags .Err ().Error (), err ) {
828
- t .Fatalf ("expected error message %q, but got %q" , err , diags .Err ().Error ())
829
- }
830
- }
831
- }
832
-
833
949
})
834
950
}
835
951
}
0 commit comments