Skip to content

Commit 7b42fc7

Browse files
chore: Extend test coverage for notebooks (#4237)
<!-- summary of changes --> - Added more tests for the warehouse parameter - Added validation tests - Added integration test for setting a non-existing warehouse
1 parent 30d3546 commit 7b42fc7

File tree

8 files changed

+147
-12
lines changed

8 files changed

+147
-12
lines changed

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ We believe that code following the same conventions is easier to maintain and ex
106106

107107
### Introducing a new part of the SDK
108108

109-
To create new objects in our SDK we use quickly created generator that outputs the majority of the files needed. These files should be later edited and filled with the missing parts. We plan to improve the generator later on, but it should be enough for now. Please read more in the [generator readme](pkg/sdk/poc/README.md).
109+
To create new objects in our SDK we use quickly created generator that outputs the majority of the files needed. These files should be later edited and filled with the missing parts. We plan to improve the generator later on, but it should be enough for now. Please read more in the [generator readme](pkg/sdk/generator/README.md).
110110

111111
### Test the change
112112
Every introduced change should be tested. Depending on the type of the change it may require (any or mix of):

docs/resources/notebook.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ description: |-
99

1010
-> **Note** `secrets` is currently not supported. It will be supported in the following versions of the provider which may still affect this resource.
1111

12+
-> **Note** `warehouse` and `query_warehouse` parameters can only be set to upper-case identifiers.
13+
1214
!> **Caution: Preview Feature** This feature is considered a preview feature in the provider, regardless of the state of the resource in Snowflake. We do not guarantee its stability. It will be reworked and marked as a stable feature in future releases. Breaking changes are expected, even without bumping the major version. To use this feature, add the relevant feature name to `preview_features_enabled` field in the [provider configuration](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs#schema). Please always refer to the [Getting Help](https://github.com/snowflakedb/terraform-provider-snowflake?tab=readme-ov-file#getting-help) section in our Github repo to best determine how to get help for your questions.
1315

1416
# snowflake_notebook (Resource)
@@ -62,9 +64,9 @@ resource "snowflake_notebook" "complete" {
6264
- `from` (Block List) Specifies the location in a stage of an .ipynb file from which the notebook should be created. MAIN_FILE parameter a user-specified identifier for the notebook file name must also be set alongside it. (see [below for nested schema](#nestedblock--from))
6365
- `idle_auto_shutdown_time_seconds` (Number) Specifies the number of seconds of idle time before the notebook is shut down automatically.
6466
- `main_file` (String) Specifies a user-specified identifier for the notebook file name.
65-
- `query_warehouse` (String) Specifies the warehouse where SQL queries in the notebook are run.
67+
- `query_warehouse` (String) Specifies the warehouse where SQL queries in the notebook are run. Only upper-case identifiers are supported.
6668
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
67-
- `warehouse` (String) Specifies the warehouse that runs the notebook kernel and python code.
69+
- `warehouse` (String) Specifies the warehouse that runs the notebook kernel and python code. Only upper-case identifiers are supported.
6870

6971
### Read-Only
7072

pkg/acceptance/helpers/schema_client.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package helpers
22

33
import (
44
"context"
5+
"fmt"
56
"testing"
67

78
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/sdk"
@@ -154,3 +155,13 @@ func (c *SchemaClient) Alter(t *testing.T, id sdk.DatabaseObjectIdentifier, opts
154155
err := c.client().Alter(ctx, id, opts)
155156
require.NoError(t, err)
156157
}
158+
159+
func (c *SchemaClient) AlterDefaultStreamlitNotebookWarehouse(t *testing.T, id sdk.DatabaseObjectIdentifier, warehouse sdk.AccountObjectIdentifier) {
160+
t.Helper()
161+
ctx := context.Background()
162+
163+
query := fmt.Sprintf(`ALTER SCHEMA %s SET DEFAULT_STREAMLIT_NOTEBOOK_WAREHOUSE = '%s'`, id.FullyQualifiedName(), warehouse.Name())
164+
165+
_, err := c.context.client.ExecForTests(ctx, query)
166+
require.NoError(t, err)
167+
}

pkg/resources/notebook.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ var notebookSchema = map[string]*schema.Schema{
7878
"query_warehouse": {
7979
Type: schema.TypeString,
8080
Optional: true,
81-
Description: "Specifies the warehouse where SQL queries in the notebook are run.",
81+
Description: "Specifies the warehouse where SQL queries in the notebook are run. Only upper-case identifiers are supported.",
8282
ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](),
8383
DiffSuppressFunc: suppressIdentifierQuoting,
8484
},
@@ -91,7 +91,7 @@ var notebookSchema = map[string]*schema.Schema{
9191
"warehouse": {
9292
Type: schema.TypeString,
9393
Optional: true,
94-
Description: "Specifies the warehouse that runs the notebook kernel and python code.",
94+
Description: "Specifies the warehouse that runs the notebook kernel and python code. Only upper-case identifiers are supported.",
9595
ValidateDiagFunc: IsValidIdentifier[sdk.AccountObjectIdentifier](),
9696
DiffSuppressFunc: suppressIdentifierQuoting,
9797
},

pkg/sdk/notebooks_gen_test.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/sdk/testint/notebooks_integration_test.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ func TestInt_Notebooks(t *testing.T) {
125125

126126
request := sdk.NewCreateNotebookRequest(id)
127127

128-
err := client.Notebooks.Create(ctx, request)
128+
_, notebookCleanup := testClientHelper().Notebook.CreateWithRequest(t, request)
129+
t.Cleanup(notebookCleanup)
129130

130131
computePool, computePoolCleanup := testClientHelper().ComputePool.Create(t)
131132
t.Cleanup(computePoolCleanup)
@@ -146,7 +147,7 @@ func TestInt_Notebooks(t *testing.T) {
146147

147148
alterRequest := sdk.NewAlterNotebookRequest(id).WithSet(*setRequest)
148149

149-
err = client.Notebooks.Alter(ctx, alterRequest)
150+
err := client.Notebooks.Alter(ctx, alterRequest)
150151
require.NoError(t, err)
151152

152153
updatedNotebook, err := client.Notebooks.ShowByID(ctx, id)
@@ -196,6 +197,20 @@ func TestInt_Notebooks(t *testing.T) {
196197
)
197198
})
198199

200+
t.Run("alter: set non-existing warehouse", func(t *testing.T) {
201+
id := testClientHelper().Ids.RandomSchemaObjectIdentifier()
202+
request := sdk.NewCreateNotebookRequest(id)
203+
204+
_, notebookCleanup := testClientHelper().Notebook.CreateWithRequest(t, request)
205+
t.Cleanup(notebookCleanup)
206+
207+
setRequest := sdk.NewNotebookSetRequest().WithWarehouse(sdk.NewAccountObjectIdentifier("invalid warehouse"))
208+
alterRequest := sdk.NewAlterNotebookRequest(id).WithSet(*setRequest)
209+
210+
err := client.Notebooks.Alter(ctx, alterRequest)
211+
require.Error(t, err)
212+
})
213+
199214
t.Run("alter: unset", func(t *testing.T) {
200215
id := testClientHelper().Ids.RandomSchemaObjectIdentifier()
201216

pkg/testacc/resource_notebook_acceptance_test.go

Lines changed: 109 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,16 @@ package testacc
22

33
import (
44
"fmt"
5+
"regexp"
56
"strconv"
67
"testing"
78

89
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert"
910
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/invokeactionassert"
11+
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/objectassert"
1012
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/resourceassert"
1113
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/assert/resourceshowoutputassert"
14+
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config"
1215
accconfig "github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config"
1316
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/bettertestspoc/config/model"
1417
"github.com/Snowflake-Labs/terraform-provider-snowflake/pkg/acceptance/helpers/random"
@@ -22,7 +25,7 @@ import (
2225
"github.com/hashicorp/terraform-plugin-testing/tfversion"
2326
)
2427

25-
func TestAcc_Notebook_BasisUseCase(t *testing.T) {
28+
func TestAcc_Notebook_BasicUseCase(t *testing.T) {
2629
id := testClient().Ids.RandomSchemaObjectIdentifier()
2730
comment := random.Comment()
2831

@@ -554,7 +557,6 @@ func TestAcc_Notebook_ExternalWarehouseChange(t *testing.T) {
554557
t.Cleanup(warehouseCleanup)
555558

556559
modelBasic := model.NotebookFromId("test", id)
557-
warehouseNoQuotes := warehouse.ID().FullyQualifiedName()[1 : len(warehouse.ID().FullyQualifiedName())-1]
558560

559561
resource.Test(t, resource.TestCase{
560562
ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories,
@@ -607,8 +609,8 @@ func TestAcc_Notebook_ExternalWarehouseChange(t *testing.T) {
607609
ConfigPlanChecks: resource.ConfigPlanChecks{
608610
PreApply: []plancheck.PlanCheck{
609611
plancheck.ExpectResourceAction(modelBasic.ResourceReference(), plancheck.ResourceActionUpdate),
610-
planchecks.ExpectDrift("snowflake_notebook.test", "warehouse", nil, sdk.String(warehouseNoQuotes)),
611-
planchecks.ExpectChange("snowflake_notebook.test", "warehouse", tfjson.ActionUpdate, sdk.String(warehouseNoQuotes), nil),
612+
planchecks.ExpectDrift("snowflake_notebook.test", "warehouse", nil, sdk.String(warehouse.ID().Name())),
613+
planchecks.ExpectChange("snowflake_notebook.test", "warehouse", tfjson.ActionUpdate, sdk.String(warehouse.ID().Name()), nil),
612614
},
613615
},
614616
Check: assertThat(t,
@@ -644,3 +646,106 @@ func TestAcc_Notebook_ExternalWarehouseChange(t *testing.T) {
644646
},
645647
})
646648
}
649+
650+
func TestAcc_notebook_WarehouseSchemaLevelChange(t *testing.T) {
651+
schema, schemaCleanup := testClient().Schema.CreateSchema(t)
652+
t.Cleanup(schemaCleanup)
653+
654+
id := testClient().Ids.RandomSchemaObjectIdentifierInSchema(schema.ID())
655+
656+
warehouse, warehouseCleanup := testClient().Warehouse.CreateWarehouse(t)
657+
t.Cleanup(warehouseCleanup)
658+
659+
modelBasic := model.NotebookFromId("test", id)
660+
661+
assertBasic := []assert.TestCheckFuncProvider{
662+
objectassert.Notebook(t, id).
663+
HasName(id.Name()).
664+
HasDatabaseName(id.DatabaseName()).
665+
HasSchemaName(id.SchemaName()).
666+
HasNoComment().
667+
HasOwner(snowflakeroles.Accountadmin.Name()).
668+
HasOwnerRoleType("ROLE").
669+
HasCodeWarehouse(sdk.NewAccountObjectIdentifier("\"SYSTEM$STREAMLIT_NOTEBOOK_WH\"")),
670+
resourceassert.NotebookResource(t, modelBasic.ResourceReference()).
671+
HasNameString(id.Name()).
672+
HasDatabaseString(id.DatabaseName()).
673+
HasSchemaString(id.SchemaName()).
674+
HasNoFromString().
675+
HasNoMainFile().
676+
HasNoQueryWarehouse().
677+
HasNoIdleAutoShutdownTimeSeconds().
678+
HasNoWarehouse().
679+
HasCommentString("").
680+
HasFullyQualifiedNameString(id.FullyQualifiedName()),
681+
resourceshowoutputassert.NotebookShowOutput(t, modelBasic.ResourceReference()).
682+
HasCreatedOnNotEmpty().
683+
HasName(id.Name()).
684+
HasDatabaseName(id.DatabaseName()).
685+
HasSchemaName(id.SchemaName()).
686+
HasQueryWarehouse(sdk.NewAccountObjectIdentifier("")).
687+
HasCodeWarehouse(sdk.NewAccountObjectIdentifier("\"SYSTEM$STREAMLIT_NOTEBOOK_WH\"")).
688+
HasOwner(snowflakeroles.Accountadmin.Name()).
689+
HasOwnerRoleType("ROLE").
690+
HasComment(""),
691+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.name", id.Name())),
692+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.main_file", "notebook_app.ipynb")),
693+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.query_warehouse", "")),
694+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.idle_auto_shutdown_time_seconds", "1800")),
695+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.code_warehouse", "SYSTEM$STREAMLIT_NOTEBOOK_WH")),
696+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.owner", snowflakeroles.Accountadmin.Name())),
697+
assert.Check(resource.TestCheckResourceAttr(modelBasic.ResourceReference(), "describe_output.0.comment", "")),
698+
}
699+
700+
resource.Test(t, resource.TestCase{
701+
ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories,
702+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
703+
tfversion.RequireAbove(tfversion.Version1_5_0),
704+
},
705+
CheckDestroy: CheckDestroy(t, resources.Notebook),
706+
Steps: []resource.TestStep{
707+
{
708+
Config: accconfig.FromModels(t, modelBasic),
709+
Check: assertThat(t, assertBasic...),
710+
},
711+
{
712+
PreConfig: func() {
713+
testClient().Schema.AlterDefaultStreamlitNotebookWarehouse(t, sdk.NewDatabaseObjectIdentifier(id.DatabaseName(), id.SchemaName()), warehouse.ID())
714+
},
715+
Config: accconfig.FromModels(t, modelBasic),
716+
Check: assertThat(t, assertBasic...),
717+
},
718+
},
719+
})
720+
}
721+
722+
func TestAcc_Notebook_Validations(t *testing.T) {
723+
id := testClient().Ids.RandomSchemaObjectIdentifier()
724+
725+
modelInvalidIdleAutoShutdownTimeSeconds := model.NotebookFromId("test", id).WithIdleAutoShutdownTimeSeconds(0)
726+
727+
stage := testClient().Ids.RandomSchemaObjectIdentifier()
728+
path := "test/path"
729+
730+
modelFromWithoutMainFile := model.NotebookFromId("test", id).WithFrom(path, stage)
731+
732+
resource.Test(t, resource.TestCase{
733+
ProtoV6ProviderFactories: TestAccProtoV6ProviderFactories,
734+
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
735+
tfversion.RequireAbove(tfversion.Version1_5_0),
736+
},
737+
CheckDestroy: CheckDestroy(t, resources.Notebook),
738+
Steps: []resource.TestStep{
739+
{
740+
Config: config.FromModels(t, modelInvalidIdleAutoShutdownTimeSeconds),
741+
PlanOnly: true,
742+
ExpectError: regexp.MustCompile(`expected idle_auto_shutdown_time_seconds to be at least \(1\), got 0`),
743+
},
744+
{
745+
Config: config.FromModels(t, modelFromWithoutMainFile),
746+
PlanOnly: true,
747+
ExpectError: regexp.MustCompile("\"from\": all of `from,main_file` must be specified"),
748+
},
749+
},
750+
})
751+
}

templates/resources/notebook.md.tmpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ description: |-
1313

1414
-> **Note** `secrets` is currently not supported. It will be supported in the following versions of the provider which may still affect this resource.
1515

16+
-> **Note** `warehouse` and `query_warehouse` parameters can only be set to upper-case identifiers.
17+
1618
!> **Caution: Preview Feature** This feature is considered a preview feature in the provider, regardless of the state of the resource in Snowflake. We do not guarantee its stability. It will be reworked and marked as a stable feature in future releases. Breaking changes are expected, even without bumping the major version. To use this feature, add the relevant feature name to `preview_features_enabled` field in the [provider configuration](https://registry.terraform.io/providers/snowflakedb/snowflake/latest/docs#schema). Please always refer to the [Getting Help](https://github.com/snowflakedb/terraform-provider-snowflake?tab=readme-ov-file#getting-help) section in our Github repo to best determine how to get help for your questions.
1719

1820
# {{.Name}} ({{.Type}})

0 commit comments

Comments
 (0)