@@ -18,6 +18,7 @@ import (
18
18
"context"
19
19
"os"
20
20
"path/filepath"
21
+ "slices"
21
22
"testing"
22
23
23
24
"github.com/stretchr/testify/assert"
@@ -43,16 +44,13 @@ func TestExtractModuleContentWorks(t *testing.T) {
43
44
for _ , executor := range executors {
44
45
t .Run ("executor=" + executor , func (t * testing.T ) {
45
46
ctx := context .Background ()
46
- logger := & testLogger {}
47
+ logger := newTestLogger ( t )
47
48
source := TFModuleSource ("terraform-aws-modules/vpc/aws" )
48
49
version := TFModuleVersion ("5.18.1" )
49
50
tf := newTestRuntime (t , executor )
50
51
awsVpc , err := extractModuleContent (ctx , tf , source , version , logger )
51
52
assert .NoError (t , err , "failed to infer module schema for aws vpc module" )
52
53
assert .NotNil (t , awsVpc , "inferred module schema for aws vpc module is nil" )
53
- for _ , log := range logger .logs {
54
- t .Logf ("Log: %s" , log )
55
- }
56
54
})
57
55
}
58
56
}
@@ -303,7 +301,7 @@ func TestExtractModuleContentWorksFromLocalPath(t *testing.T) {
303
301
executors := getExecutorsFromEnv ()
304
302
for _ , executor := range executors {
305
303
t .Run ("executor=" + executor , func (t * testing.T ) {
306
- logger := & testLogger {}
304
+ logger := newTestLogger ( t )
307
305
tf := newTestRuntime (t , executor )
308
306
assert .NoError (t , err , "failed to pick module runtime" )
309
307
mod , err := extractModuleContent (ctx , tf , TFModuleSource (p ), "" , logger )
@@ -313,6 +311,100 @@ func TestExtractModuleContentWorksFromLocalPath(t *testing.T) {
313
311
}
314
312
}
315
313
314
+ func TestInferringInputsFromLocalPath (t * testing.T ) {
315
+ ctx := context .Background ()
316
+ src := filepath .Join (".." , ".." , "tests" , "testdata" , "modules" , "schema-inference-example" )
317
+ p , err := filepath .Abs (src )
318
+ require .NoError (t , err )
319
+ for _ , executor := range []string {"terraforn" , "opentofu" } {
320
+ logger := newTestLogger (t )
321
+ t .Run ("executor=" + executor , func (t * testing.T ) {
322
+ tf := newTestRuntime (t , executor )
323
+ assert .NoError (t , err , "failed to pick module runtime" )
324
+ inferredSchema , err := inferModuleSchema (ctx , tf ,
325
+ packageName ("schema-inference-example" ),
326
+ TFModuleSource (p ),
327
+ TFModuleVersion ("" ),
328
+ logger )
329
+ require .NoError (t , err )
330
+ require .NotNil (t , inferredSchema , "module schema should not be nil" )
331
+
332
+ expectedInputs := map [resource.PropertyKey ]* schema.PropertySpec {
333
+ "required_string" : {
334
+ Description : "required string" ,
335
+ TypeSpec : stringType ,
336
+ },
337
+ "optional_string_with_default" : {
338
+ Description : "optional string with default" ,
339
+ TypeSpec : stringType ,
340
+ },
341
+ "optional_string_without_default" : {
342
+ Description : "optional string without default" ,
343
+ TypeSpec : stringType ,
344
+ },
345
+ "required_string_using_nullable_false" : {
346
+ TypeSpec : stringType ,
347
+ },
348
+ "optional_string_using_nullable_true" : {
349
+ TypeSpec : stringType ,
350
+ },
351
+ "required_boolean" : {
352
+ TypeSpec : boolType ,
353
+ },
354
+ "optional_boolean_with_default" : {
355
+ TypeSpec : boolType ,
356
+ },
357
+ "required_number" : {
358
+ TypeSpec : numberType ,
359
+ },
360
+ "optional_number_with_default" : {
361
+ TypeSpec : numberType ,
362
+ },
363
+ "required_list_of_strings" : {
364
+ TypeSpec : arrayType (stringType ),
365
+ },
366
+ "optional_list_of_strings_with_default" : {
367
+ TypeSpec : arrayType (stringType ),
368
+ Description : "optional list of strings with default" ,
369
+ },
370
+ "optional_list_of_strings_without_default" : {
371
+ TypeSpec : arrayType (stringType ),
372
+ Description : "optional list of strings without default" ,
373
+ },
374
+ "required_map_of_strings" : {
375
+ TypeSpec : mapType (stringType ),
376
+ },
377
+ "optional_map_of_strings_with_default" : {
378
+ TypeSpec : mapType (stringType ),
379
+ Description : "optional map of strings with default" ,
380
+ },
381
+ }
382
+
383
+ for name , expected := range expectedInputs {
384
+ actual , ok := inferredSchema .Inputs [name ]
385
+ assert .True (t , ok , "input %s is missing from the schema" , name )
386
+ assert .Equal (t , expected .Description , actual .Description , "input %s description is incorrect" , name )
387
+ assert .Equal (t , expected .TypeSpec , actual .TypeSpec , "input %s type is incorrect" , name )
388
+ }
389
+
390
+ expectedRequiredInputs := []resource.PropertyKey {
391
+ "required_string" ,
392
+ "required_string_using_nullable_false" ,
393
+ "required_number" ,
394
+ "required_boolean" ,
395
+ "required_list_of_strings" ,
396
+ "required_map_of_strings" ,
397
+ }
398
+
399
+ actualRequiredInputs := inferredSchema .RequiredInputs
400
+
401
+ slices .Sort (expectedRequiredInputs )
402
+ slices .Sort (actualRequiredInputs )
403
+ assert .Equal (t , expectedRequiredInputs , actualRequiredInputs )
404
+ })
405
+ }
406
+ }
407
+
316
408
func TestInferModuleSchemaFromGitHubSource (t * testing.T ) {
317
409
ctx := context .Background ()
318
410
packageName := packageName ("demoWebsite" )
@@ -443,6 +535,22 @@ func TestInferModuleSchemaFromGitHubSourceWithSubModuleAndVersion(t *testing.T)
443
535
}
444
536
}
445
537
538
+ func TestInferRequiredInputsWorks (t * testing.T ) {
539
+ ctx := context .Background ()
540
+ packageName := packageName ("http" )
541
+ for _ , executor := range []string {"terraform" , "opentofu" } {
542
+ t .Run ("executor=" + executor , func (t * testing.T ) {
543
+ source := TFModuleSource ("terraform-aws-modules/security-group/aws//modules/http-80" )
544
+ version := TFModuleVersion ("5.3.0" )
545
+ tf := newTestRuntime (t , executor )
546
+ httpSchema , err := InferModuleSchema (ctx , tf , packageName , source , version )
547
+ assert .NoError (t , err , "failed to infer module schema for aws vpc module" )
548
+ assert .NotNil (t , httpSchema , "inferred module schema for aws vpc module is nil" )
549
+ assert .Contains (t , httpSchema .RequiredInputs , resource .PropertyKey ("vpc_id" ))
550
+ })
551
+ }
552
+ }
553
+
446
554
func TestResolveModuleSources (t * testing.T ) {
447
555
executors := getExecutorsFromEnv ()
448
556
for _ , executor := range executors {
0 commit comments