From ac76596ddef30f096cc6143cd3edd4ce541a3eb5 Mon Sep 17 00:00:00 2001 From: VenelinMartinov Date: Wed, 30 Oct 2024 14:03:04 +0000 Subject: [PATCH] Type checker integration tests (#2461) This adds integration tests for the type checker added in https://github.com/pulumi/pulumi-terraform-bridge/pull/2000 Not all the cases can be tested still, as some are caught by the language runtime. Will look into that more to expand the feature flag for the YAML runtime. Depends on a debug feature flag for the YAML runtime from https://github.com/pulumi/pulumi-yaml/pull/634 fixes https://github.com/pulumi/pulumi-terraform-bridge/issues/2418 --- pkg/tests/schema_pulumi_test.go | 96 +++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) diff --git a/pkg/tests/schema_pulumi_test.go b/pkg/tests/schema_pulumi_test.go index 7f3e26350..7b86abe57 100644 --- a/pkg/tests/schema_pulumi_test.go +++ b/pkg/tests/schema_pulumi_test.go @@ -6436,3 +6436,99 @@ func TestUnknownCollectionForceNewDetailedDiff(t *testing.T) { }) }) } + +func TestTypeChecker(t *testing.T) { + t.Setenv("PULUMI_DEBUG_YAML_DISABLE_TYPE_CHECKING", "true") + resMap := map[string]*schema.Resource{ + "prov_test": { + Schema: map[string]*schema.Schema{ + "tags": { + Type: schema.TypeMap, + Elem: &schema.Schema{Type: schema.TypeString}, + Optional: true, + }, + "network_configuration": { + Type: schema.TypeList, + Optional: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "assign_public_ip": { + Type: schema.TypeBool, + Optional: true, + Default: false, + }, + "security_groups": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + "subnets": { + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + }, + }, + }, + }, + }, + }, + } + + runTest := func(t *testing.T, resMap map[string]*schema.Resource, props interface{}, expectedError string) { + propsJSON, err := json.Marshal(props) + require.NoError(t, err) + program := fmt.Sprintf(` +name: test +runtime: yaml +resources: + mainRes: + type: prov:index:Test + properties: %s`, propsJSON) + + bridgedProvider := pulcheck.BridgedProvider(t, "prov", &schema.Provider{ResourcesMap: resMap}) + pt := pulcheck.PulCheck(t, bridgedProvider, program) + _, err = pt.CurrentStack().Up(pt.Context()) + + require.ErrorContains(t, err, "Unexpected type at field") + require.ErrorContains(t, err, expectedError) + } + + t.Run("flat type instead of array", func(t *testing.T) { + runTest(t, resMap, map[string]interface{}{"networkConfiguration": map[string]any{"subnets": "subnet"}}, "expected array type, got") + }) + + t.Run("flat type instead of map", func(t *testing.T) { + runTest(t, resMap, map[string]interface{}{"tags": "tag"}, "expected object type, got") + }) + + t.Run("flat type instead of object", func(t *testing.T) { + t.Skip("This is caught by the YAML runtime, not the type checker") + runTest(t, resMap, map[string]interface{}{"network_configuration": "config"}, "expected object type, got") + }) + + t.Run("array instead of object", func(t *testing.T) { + t.Skip("This is caught by the YAML runtime, not the type checker") + runTest(t, resMap, map[string]interface{}{"network_configuration": []string{"config"}}, "expected object type, got") + }) + + t.Run("array instead of map", func(t *testing.T) { + runTest(t, resMap, map[string]interface{}{"tags": []string{"tag"}}, "expected object type, got") + }) + + t.Run("array instead of flat type", func(t *testing.T) { + t.Skip("This is caught by the YAML runtime, not the type checker") + runTest(t, resMap, map[string]interface{}{"network_configuration": map[string]interface{}{"assign_public_ip": []any{true}}}, "expected array type, got") + }) + + t.Run("map instead of array", func(t *testing.T) { + runTest(t, resMap, + map[string]interface{}{"networkConfiguration": map[string]any{"subnets": map[string]any{"sub": "sub"}}}, + "expected array type, got") + }) + + t.Run("map instead of flat type", func(t *testing.T) { + t.Skip("This is caught by the YAML runtime, not the type checker") + runTest(t, resMap, map[string]interface{}{"network_configuration": map[string]interface{}{"assign_public_ip": map[string]any{"val": true}}}, "expected array type, got") + }) +}