Skip to content

Commit

Permalink
feat: Test imports and small fixes (#3276)
Browse files Browse the repository at this point in the history
Improve and test imports for functions and procedures
  • Loading branch information
sfc-gh-asawicki authored Dec 12, 2024
1 parent b3d6b9e commit a712195
Show file tree
Hide file tree
Showing 15 changed files with 164 additions and 17 deletions.
11 changes: 11 additions & 0 deletions pkg/resources/function_and_procedure_commons.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ func readFunctionOrProcedureArguments(d *schema.ResourceData, args []sdk.Normali
}
}

func importFunctionOrProcedureArguments(d *schema.ResourceData, args []sdk.NormalizedArgument) error {
currentArgs := make([]map[string]any, len(args))
for i, arg := range args {
currentArgs[i] = map[string]any{
"arg_name": arg.Name,
"arg_data_type": arg.DataType.ToSql(),
}
}
return d.Set("arguments", currentArgs)
}

func readFunctionOrProcedureImports(d *schema.ResourceData, imports []sdk.NormalizedPath) error {
if len(imports) == 0 {
// don't do anything if imports not present
Expand Down
36 changes: 36 additions & 0 deletions pkg/resources/function_commons.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"slices"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/schemas"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
Expand Down Expand Up @@ -511,6 +512,41 @@ func UpdateFunction(language string, readFunc func(ctx context.Context, d *schem
}
}

func ImportFunction(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
logging.DebugLogger.Printf("[DEBUG] Starting function import")
client := meta.(*provider.Context).Client
id, err := sdk.ParseSchemaObjectIdentifierWithArguments(d.Id())
if err != nil {
return nil, err
}

functionDetails, err := client.Functions.DescribeDetails(ctx, id)
if err != nil {
return nil, err
}

function, err := client.Functions.ShowByID(ctx, id)
if err != nil {
return nil, err
}

err = errors.Join(
d.Set("database", id.DatabaseName()),
d.Set("schema", id.SchemaName()),
d.Set("name", id.Name()),
d.Set("is_secure", booleanStringFromBool(function.IsSecure)),
setOptionalFromStringPtr(d, "null_input_behavior", functionDetails.NullHandling),
setOptionalFromStringPtr(d, "return_results_behavior", functionDetails.Volatility),
importFunctionOrProcedureArguments(d, functionDetails.NormalizedArguments),
// all others are set in read
)
if err != nil {
return nil, err
}

return []*schema.ResourceData{d}, nil
}

// TODO [SNOW-1850370]: Make the rest of the functions in this file generic (for reuse with procedures)
func parseFunctionArgumentsCommon(d *schema.ResourceData) ([]sdk.FunctionArgumentRequest, error) {
args := make([]sdk.FunctionArgumentRequest, 0)
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/function_java.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func FunctionJava() *schema.Resource {

Schema: collections.MergeMaps(javaFunctionSchema, functionParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.FunctionJava, ImportFunction),
},
}
}
Expand Down
40 changes: 37 additions & 3 deletions pkg/resources/function_java_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import (
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config/model"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/importchecks"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testdatatypes"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
Expand All @@ -27,7 +28,6 @@ import (
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

// TODO [SNOW-1348103]: test import
// TODO [SNOW-1348103]: test external changes
// TODO [SNOW-1348103]: test changes of attributes separately

Expand Down Expand Up @@ -77,6 +77,20 @@ func TestAcc_FunctionJava_InlineBasic(t *testing.T) {
assert.Check(resource.TestCheckResourceAttr(functionModel.ResourceReference(), "arguments.0.arg_default_value", "")),
),
},
// IMPORT
{
ResourceName: functionModel.ResourceReference(),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"is_secure", "arguments.0.arg_data_type", "null_input_behavior", "return_results_behavior"},
ImportStateCheck: assert.AssertThatImport(t,
resourceassert.ImportedFunctionJavaResource(t, id.FullyQualifiedName()).
HasFullyQualifiedNameString(id.FullyQualifiedName()),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_name", argName)),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_data_type", "VARCHAR(16777216)")),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_default_value", "")),
),
},
// RENAME
{
Config: config.FromModels(t, functionModelRenamed),
Expand Down Expand Up @@ -220,6 +234,9 @@ func TestAcc_FunctionJava_InlineFull(t *testing.T) {
}).
WithTargetPathParts(stage.ID().FullyQualifiedName(), jarName).
WithRuntimeVersion("11").
WithIsSecure("false").
WithNullInputBehavior(string(sdk.NullInputBehaviorCalledOnNullInput)).
WithReturnResultsBehavior(string(sdk.ReturnResultsBehaviorVolatile)).
WithComment("some comment")

functionModelUpdateWithoutRecreation := model.FunctionJavaBasicInline("w", id, dataType, handler, definition).
Expand All @@ -235,6 +252,9 @@ func TestAcc_FunctionJava_InlineFull(t *testing.T) {
}).
WithTargetPathParts(stage.ID().FullyQualifiedName(), jarName).
WithRuntimeVersion("11").
WithIsSecure(r.BooleanFalse).
WithNullInputBehavior(string(sdk.NullInputBehaviorCalledOnNullInput)).
WithReturnResultsBehavior(string(sdk.ReturnResultsBehaviorVolatile)).
WithComment("some other comment")

resource.Test(t, resource.TestCase{
Expand All @@ -251,7 +271,7 @@ func TestAcc_FunctionJava_InlineFull(t *testing.T) {
Check: assert.AssertThat(t,
resourceassert.FunctionJavaResource(t, functionModel.ResourceReference()).
HasNameString(id.Name()).
HasIsSecureString(r.BooleanDefault).
HasIsSecureString(r.BooleanFalse).
HasImportsLength(2).
HasRuntimeVersionString("11").
HasFunctionDefinitionString(definition).
Expand All @@ -267,6 +287,20 @@ func TestAcc_FunctionJava_InlineFull(t *testing.T) {
HasIsSecure(false),
),
},
// IMPORT
{
ResourceName: functionModel.ResourceReference(),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"arguments.0.arg_data_type"},
ImportStateCheck: assert.AssertThatImport(t,
resourceassert.ImportedFunctionJavaResource(t, id.FullyQualifiedName()).
HasFullyQualifiedNameString(id.FullyQualifiedName()),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_name", argName)),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_data_type", "VARCHAR(16777216)")),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_default_value", "")),
),
},
// UPDATE WITHOUT RECREATION
{
ConfigPlanChecks: resource.ConfigPlanChecks{
Expand All @@ -278,7 +312,7 @@ func TestAcc_FunctionJava_InlineFull(t *testing.T) {
Check: assert.AssertThat(t,
resourceassert.FunctionJavaResource(t, functionModelUpdateWithoutRecreation.ResourceReference()).
HasNameString(id.Name()).
HasIsSecureString(r.BooleanDefault).
HasIsSecureString(r.BooleanFalse).
HasImportsLength(2).
HasRuntimeVersionString("11").
HasFunctionDefinitionString(definition).
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/function_javascript.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func FunctionJavascript() *schema.Resource {

Schema: collections.MergeMaps(javascriptFunctionSchema, functionParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.FunctionJavascript, ImportFunction),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/function_python.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func FunctionPython() *schema.Resource {

Schema: collections.MergeMaps(pythonFunctionSchema, functionParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.FunctionPython, ImportFunction),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/function_scala.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func FunctionScala() *schema.Resource {

Schema: collections.MergeMaps(scalaFunctionSchema, functionParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.FunctionScala, ImportFunction),
},
}
}
Expand Down
3 changes: 1 addition & 2 deletions pkg/resources/function_sql.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func FunctionSql() *schema.Resource {

Schema: collections.MergeMaps(sqlFunctionSchema, functionParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.FunctionSql, ImportFunction),
},
}
}
Expand Down Expand Up @@ -114,7 +114,6 @@ func ReadContextFunctionSql(ctx context.Context, d *schema.ResourceData, meta an
// not reading is_secure on purpose (handled as external change to show output)
readFunctionOrProcedureArguments(d, allFunctionDetails.functionDetails.NormalizedArguments),
d.Set("return_type", allFunctionDetails.functionDetails.ReturnDataType.ToSql()),
// not reading null_input_behavior on purpose (handled as external change to show output)
// not reading return_results_behavior on purpose (handled as external change to show output)
d.Set("comment", allFunctionDetails.function.Description),
setRequiredFromStringPtr(d, "handler", allFunctionDetails.functionDetails.Handler),
Expand Down
35 changes: 35 additions & 0 deletions pkg/resources/procedure_commons.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"slices"

"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/logging"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/internal/provider"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/schemas"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
Expand Down Expand Up @@ -480,6 +481,40 @@ func UpdateProcedure(language string, readFunc func(ctx context.Context, d *sche
}
}

func ImportProcedure(ctx context.Context, d *schema.ResourceData, meta any) ([]*schema.ResourceData, error) {
logging.DebugLogger.Printf("[DEBUG] Starting procedure import")
client := meta.(*provider.Context).Client
id, err := sdk.ParseSchemaObjectIdentifierWithArguments(d.Id())
if err != nil {
return nil, err
}

procedureDetails, err := client.Procedures.DescribeDetails(ctx, id)
if err != nil {
return nil, err
}

procedure, err := client.Procedures.ShowByID(ctx, id)
if err != nil {
return nil, err
}

err = errors.Join(
d.Set("database", id.DatabaseName()),
d.Set("schema", id.SchemaName()),
d.Set("name", id.Name()),
d.Set("is_secure", booleanStringFromBool(procedure.IsSecure)),
setOptionalFromStringPtr(d, "null_input_behavior", procedureDetails.NullHandling),
importFunctionOrProcedureArguments(d, procedureDetails.NormalizedArguments),
// all others are set in read
)
if err != nil {
return nil, err
}

return []*schema.ResourceData{d}, nil
}

func queryAllProcedureDetailsCommon(ctx context.Context, d *schema.ResourceData, client *sdk.Client, id sdk.SchemaObjectIdentifierWithArguments) (*allProcedureDetailsCommon, diag.Diagnostics) {
procedureDetails, err := client.Procedures.DescribeDetails(ctx, id)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/procedure_java.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func ProcedureJava() *schema.Resource {

Schema: collections.MergeMaps(javaProcedureSchema, procedureParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.ProcedureJava, ImportProcedure),
},
}
}
Expand Down
38 changes: 35 additions & 3 deletions pkg/resources/procedure_java_acceptance_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import (
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config/model"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/importchecks"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testdatatypes"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/testenvs"
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/helpers"
Expand All @@ -26,7 +27,6 @@ import (
"github.com/hashicorp/terraform-plugin-testing/tfversion"
)

// TODO [SNOW-1348103]: test import
// TODO [SNOW-1348103]: test external changes
// TODO [SNOW-1348103]: test changes of attributes separately

Expand Down Expand Up @@ -76,6 +76,20 @@ func TestAcc_ProcedureJava_InlineBasic(t *testing.T) {
assert.Check(resource.TestCheckResourceAttr(procedureModel.ResourceReference(), "arguments.0.arg_default_value", "")),
),
},
// IMPORT
{
ResourceName: procedureModel.ResourceReference(),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"is_secure", "arguments.0.arg_data_type", "null_input_behavior"},
ImportStateCheck: assert.AssertThatImport(t,
resourceassert.ImportedProcedureJavaResource(t, id.FullyQualifiedName()).
HasFullyQualifiedNameString(id.FullyQualifiedName()),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_name", argName)),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_data_type", "VARCHAR(16777216)")),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_default_value", "")),
),
},
// RENAME
{
Config: config.FromModels(t, procedureModelRenamed),
Expand Down Expand Up @@ -220,6 +234,8 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) {
}).
WithTargetPathParts(stage.ID().FullyQualifiedName(), jarName).
WithRuntimeVersion("11").
WithIsSecure("false").
WithNullInputBehavior(string(sdk.NullInputBehaviorCalledOnNullInput)).
WithComment("some comment")

procedureModelUpdateWithoutRecreation := model.ProcedureJavaBasicInline("w", id, dataType, handler, definition).
Expand All @@ -236,6 +252,8 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) {
}).
WithTargetPathParts(stage.ID().FullyQualifiedName(), jarName).
WithRuntimeVersion("11").
WithIsSecure("false").
WithNullInputBehavior(string(sdk.NullInputBehaviorCalledOnNullInput)).
WithComment("some other comment")

resource.Test(t, resource.TestCase{
Expand All @@ -252,7 +270,7 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) {
Check: assert.AssertThat(t,
resourceassert.ProcedureJavaResource(t, procedureModel.ResourceReference()).
HasNameString(id.Name()).
HasIsSecureString(r.BooleanDefault).
HasIsSecureString(r.BooleanFalse).
HasImportsLength(2).
HasRuntimeVersionString("11").
HasProcedureDefinitionString(definition).
Expand All @@ -269,6 +287,20 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) {
HasIsSecure(false),
),
},
// IMPORT
{
ResourceName: procedureModel.ResourceReference(),
ImportState: true,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"arguments.0.arg_data_type"},
ImportStateCheck: assert.AssertThatImport(t,
resourceassert.ImportedProcedureJavaResource(t, id.FullyQualifiedName()).
HasFullyQualifiedNameString(id.FullyQualifiedName()),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_name", argName)),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_data_type", "VARCHAR(16777216)")),
assert.CheckImport(importchecks.TestCheckResourceAttrInstanceState(helpers.EncodeResourceIdentifier(id), "arguments.0.arg_default_value", "")),
),
},
// UPDATE WITHOUT RECREATION
{
ConfigPlanChecks: resource.ConfigPlanChecks{
Expand All @@ -280,7 +312,7 @@ func TestAcc_ProcedureJava_InlineFull(t *testing.T) {
Check: assert.AssertThat(t,
resourceassert.ProcedureJavaResource(t, procedureModelUpdateWithoutRecreation.ResourceReference()).
HasNameString(id.Name()).
HasIsSecureString(r.BooleanDefault).
HasIsSecureString(r.BooleanFalse).
HasImportsLength(2).
HasRuntimeVersionString("11").
HasProcedureDefinitionString(definition).
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/procedure_javascript.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func ProcedureJavascript() *schema.Resource {

Schema: collections.MergeMaps(javascriptProcedureSchema, procedureParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.ProcedureJavascript, ImportProcedure),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/procedure_python.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func ProcedurePython() *schema.Resource {

Schema: collections.MergeMaps(pythonProcedureSchema, procedureParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.ProcedurePython, ImportProcedure),
},
}
}
Expand Down
2 changes: 1 addition & 1 deletion pkg/resources/procedure_scala.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func ProcedureScala() *schema.Resource {

Schema: collections.MergeMaps(scalaProcedureSchema, procedureParametersSchema),
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
StateContext: TrackingImportWrapper(resources.ProcedureScala, ImportProcedure),
},
}
}
Expand Down
Loading

0 comments on commit a712195

Please sign in to comment.