Skip to content

Commit

Permalink
chore: add acceptance tests for account and variable resources (#121
Browse files Browse the repository at this point in the history
)

* add service account import test

* add import state tests

* minor doc things

* add variable resource test

* add variable resource test

* add tiny account test

* add account and variable datasource tests
  • Loading branch information
parkedwards authored Nov 10, 2023
1 parent 7f5acb9 commit b4c5f78
Show file tree
Hide file tree
Showing 16 changed files with 304 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/resources/account.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ Import is supported using the following syntax:

```shell
# Prefect Accounts can be imported using the account's UUID
terraform import prefect_account.example account-uuid
terraform import prefect_account.example 00000000-0000-0000-0000-000000000000
```
2 changes: 1 addition & 1 deletion docs/resources/variable.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ Import is supported using the following syntax:
terraform import prefect_variable.example name/name-of-variable

# Prefect Variables can also be imported via UUID
terraform import prefect_variable.example variable-uuid
terraform import prefect_variable.example 00000000-0000-0000-0000-000000000000
```
2 changes: 1 addition & 1 deletion docs/resources/workspace.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,5 +47,5 @@ Import is supported using the following syntax:
terraform import prefect_workspace.example handle/workspace-handle

# Prefect Workspaces can also be imported via UUID
terraform import prefect_workspace.example workspace-uuid
terraform import prefect_workspace.example 00000000-0000-0000-0000-000000000000
```
2 changes: 1 addition & 1 deletion docs/resources/workspace_role.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,5 +48,5 @@ Import is supported using the following syntax:

```shell
# Prefect Workspace Roles can be imported using the workspace role's UUID
terraform import prefect_workspace_role.example workspace-role-uuid
terraform import prefect_workspace_role.example 00000000-0000-0000-0000-000000000000
```
2 changes: 1 addition & 1 deletion examples/resources/prefect_account/import.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Prefect Accounts can be imported using the account's UUID
terraform import prefect_account.example account-uuid
terraform import prefect_account.example 00000000-0000-0000-0000-000000000000
2 changes: 1 addition & 1 deletion examples/resources/prefect_variable/import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
terraform import prefect_variable.example name/name-of-variable

# Prefect Variables can also be imported via UUID
terraform import prefect_variable.example variable-uuid
terraform import prefect_variable.example 00000000-0000-0000-0000-000000000000
2 changes: 1 addition & 1 deletion examples/resources/prefect_workspace/import.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
terraform import prefect_workspace.example handle/workspace-handle

# Prefect Workspaces can also be imported via UUID
terraform import prefect_workspace.example workspace-uuid
terraform import prefect_workspace.example 00000000-0000-0000-0000-000000000000
2 changes: 1 addition & 1 deletion examples/resources/prefect_workspace_role/import.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Prefect Workspace Roles can be imported using the workspace role's UUID
terraform import prefect_workspace_role.example workspace-role-uuid
terraform import prefect_workspace_role.example 00000000-0000-0000-0000-000000000000
37 changes: 37 additions & 0 deletions internal/provider/datasources/account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package datasources_test

import (
"fmt"
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/prefecthq/terraform-provider-prefect/internal/testutils"
)

func fixtureAccAccount() string {
return fmt.Sprintf(`
data "prefect_account" "test" {
id = "%s"
}
`, os.Getenv("PREFECT_CLOUD_ACCOUNT_ID"))
}

//nolint:paralleltest // we use the resource.ParallelTest helper instead
func TestAccDatasource_account(t *testing.T) {
datasourceName := "data.prefect_account.test"
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
PreCheck: func() { testutils.AccTestPreCheck(t) },
Steps: []resource.TestStep{
{
Config: fixtureAccAccount(),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttr(datasourceName, "id", os.Getenv("PREFECT_CLOUD_ACCOUNT_ID")),
resource.TestCheckResourceAttrSet(datasourceName, "name"),
resource.TestCheckResourceAttrSet(datasourceName, "handle"),
),
},
},
})
}
42 changes: 42 additions & 0 deletions internal/provider/datasources/variable_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package datasources_test

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/prefecthq/terraform-provider-prefect/internal/testutils"
)

func fixtureAccVariableByName(name string) string {
return fmt.Sprintf(`
data "prefect_workspace" "evergreen" {
handle = "evergreen-workspace"
}
data "prefect_variable" "test" {
name = "%s"
workspace_id = data.prefect_workspace.evergreen.id
}
`, name)
}

//nolint:paralleltest // we use the resource.ParallelTest helper instead
func TestAccDatasource_variable(t *testing.T) {
datasourceName := "data.prefect_variable.test"
variableName := "my_variable"
variableValue := "variable value goes here"
resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
PreCheck: func() { testutils.AccTestPreCheck(t) },
Steps: []resource.TestStep{
{
Config: fixtureAccVariableByName(variableName),
Check: resource.ComposeAggregateTestCheckFunc(
resource.TestCheckResourceAttrSet(datasourceName, "id"),
resource.TestCheckResourceAttr(datasourceName, "name", variableName),
resource.TestCheckResourceAttr(datasourceName, "value", variableValue),
),
},
},
})
}
35 changes: 35 additions & 0 deletions internal/provider/resources/account_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package resources_test

import (
"os"
"testing"

"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/prefecthq/terraform-provider-prefect/internal/testutils"
)

//nolint:paralleltest // we use the resource.ParallelTest helper instead
func TestAccResource_account(t *testing.T) {
resourceName := "prefect_account.test"

resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
PreCheck: func() { testutils.AccTestPreCheck(t) },
Steps: []resource.TestStep{
// Import State checks - import by ID (from environment)
// NOTE: the prefect_account resource is a little special in that
// we cannot create an account via API, meaning the TF lifecycle
// will be challenging to test. Instead, we'll ensure that the
// resource can be found and properly imported. Note that
// ImportStateVerify is set to false, as the resource can't be
// saved to state after a Create.
{
Config: `resource "prefect_account" "test" {}`,
ImportStateId: os.Getenv("PREFECT_CLOUD_ACCOUNT_ID"),
ImportState: true,
ResourceName: resourceName,
ImportStateVerify: false,
},
},
})
}
2 changes: 1 addition & 1 deletion internal/provider/resources/service_account.go
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,6 @@ func (r *ServiceAccountResource) ImportState(ctx context.Context, req resource.I
name := strings.TrimPrefix(req.ID, "name/")
resp.Diagnostics.Append(resp.State.SetAttribute(ctx, path.Root("name"), name)...)
} else {
resource.ImportStatePassthroughID(ctx, path.Root("name"), req, resp)
resource.ImportStatePassthroughID(ctx, path.Root("id"), req, resp)
}
}
17 changes: 17 additions & 0 deletions internal/provider/resources/service_account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,23 @@ func TestAccResource_service_account(t *testing.T) {
resource.TestCheckResourceAttr(botResourceName, "name", botRandomName2),
),
},
// Import State checks - import by name
{
ImportState: true,
ImportStateId: botRandomName2,
ImportStateIdPrefix: "name/",
ResourceName: botResourceName,
ImportStateVerify: true,
ImportStateVerifyIdentifierAttribute: "name",
ImportStateVerifyIgnore: []string{"api_key"},
},
// Import State checks - import by ID (default)
{
ImportState: true,
ResourceName: botResourceName,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"api_key"},
},
},
})
}
Expand Down
143 changes: 143 additions & 0 deletions internal/provider/resources/variable_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
package resources_test

import (
"context"
"fmt"
"testing"

"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/hashicorp/terraform-plugin-testing/terraform"
"github.com/prefecthq/terraform-provider-prefect/internal/api"
"github.com/prefecthq/terraform-provider-prefect/internal/testutils"
)

func fixtureAccVariableResource(name string, value string) string {
return fmt.Sprintf(`
data "prefect_workspace" "evergreen" {
handle = "evergreen-workspace"
}
resource "prefect_variable" "test" {
workspace_id = data.prefect_workspace.evergreen.id
name = "%s"
value = "%s"
}
`, name, value)
}

func fixtureAccVariableResourceWithTags(name string, value string) string {
return fmt.Sprintf(`
data "prefect_workspace" "evergreen" {
handle = "evergreen-workspace"
}
resource "prefect_variable" "test" {
workspace_id = data.prefect_workspace.evergreen.id
name = "%s"
value = "%s"
tags = ["foo", "bar"]
}
`, name, value)
}

//nolint:paralleltest // we use the resource.ParallelTest helper instead
func TestAccResource_variable(t *testing.T) {
resourceName := "prefect_variable.test"
const workspaceDatsourceName = "data.prefect_workspace.evergreen"

randomName := testutils.TestAccPrefix + acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
randomName2 := testutils.TestAccPrefix + acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)

randomValue := testutils.TestAccPrefix + acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)
randomValue2 := testutils.TestAccPrefix + acctest.RandStringFromCharSet(10, acctest.CharSetAlphaNum)

// We use this variable to store the fetched resource from the API
// and it will be shared between TestSteps via a pointer.
var variable api.Variable

resource.ParallelTest(t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
PreCheck: func() { testutils.AccTestPreCheck(t) },
Steps: []resource.TestStep{
{
// Check creation + existence of the variable resource
Config: fixtureAccVariableResource(randomName, randomValue),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVariableExists(resourceName, workspaceDatsourceName, &variable),
testAccCheckVariableValues(&variable, &api.Variable{Name: randomName, Value: randomValue}),
resource.TestCheckResourceAttr(resourceName, "name", randomName),
resource.TestCheckResourceAttr(resourceName, "value", randomValue),
),
},
{
// Check updating name + value of the variable resource
Config: fixtureAccVariableResource(randomName2, randomValue2),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVariableExists(resourceName, workspaceDatsourceName, &variable),
testAccCheckVariableValues(&variable, &api.Variable{Name: randomName2, Value: randomValue2}),
resource.TestCheckResourceAttr(resourceName, "name", randomName2),
resource.TestCheckResourceAttr(resourceName, "value", randomValue2),
),
},
{
// Check adding tags
Config: fixtureAccVariableResourceWithTags(randomName2, randomValue2),
Check: resource.ComposeAggregateTestCheckFunc(
testAccCheckVariableExists(resourceName, workspaceDatsourceName, &variable),
testAccCheckVariableValues(&variable, &api.Variable{Name: randomName2, Value: randomValue2}),
resource.TestCheckResourceAttr(resourceName, "name", randomName2),
resource.TestCheckResourceAttr(resourceName, "value", randomValue2),
resource.TestCheckResourceAttr(resourceName, "tags.#", "2"),
resource.TestCheckResourceAttr(resourceName, "tags.0", "foo"),
resource.TestCheckResourceAttr(resourceName, "tags.1", "bar"),
),
},
},
})
}

func testAccCheckVariableExists(variableResourceName string, workspaceDatasourceName string, variable *api.Variable) resource.TestCheckFunc {
return func(state *terraform.State) error {
variableResource, exists := state.RootModule().Resources[variableResourceName]
if !exists {
return fmt.Errorf("Resource not found in state: %s", variableResourceName)
}
variableResourceID, _ := uuid.Parse(variableResource.Primary.ID)

workspaceDatsource, exists := state.RootModule().Resources[workspaceDatasourceName]
if !exists {
return fmt.Errorf("Resource not found in state: %s", workspaceDatasourceName)
}
workspaceID, _ := uuid.Parse(workspaceDatsource.Primary.ID)

// Create a new client, and use the default configurations from the environment
c, _ := testutils.NewTestClient()
variablesClient, _ := c.Variables(uuid.Nil, workspaceID)

variableName := variableResource.Primary.Attributes["name"]

fetchedVariable, err := variablesClient.Get(context.Background(), variableResourceID)
if err != nil {
return fmt.Errorf("Error fetching variable: %w", err)
}
if fetchedVariable == nil {
return fmt.Errorf("Variable not found for name: %s", variableName)
}

*variable = *fetchedVariable

return nil
}
}
func testAccCheckVariableValues(fetchedVariable *api.Variable, valuesToCheck *api.Variable) resource.TestCheckFunc {
return func(state *terraform.State) error {
if fetchedVariable.Name != valuesToCheck.Name {
return fmt.Errorf("Expected variable name to be %s, got %s", valuesToCheck.Name, fetchedVariable.Name)
}
if fetchedVariable.Value != valuesToCheck.Value {
return fmt.Errorf("Expected variable value to be %s, got %s", valuesToCheck.Name, fetchedVariable.Name)
}

return nil
}
}
7 changes: 7 additions & 0 deletions internal/provider/resources/workspace_role_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,13 @@ func TestAccResource_workspace_role(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "scopes.2", "see_work_queues"),
),
},
// Import State checks - import by ID (default)
{
ImportState: true,
ResourceName: resourceName,
ImportStateVerify: true,
ImportStateVerifyIgnore: []string{"scopes"},
},
},
})
}
Expand Down
14 changes: 14 additions & 0 deletions internal/provider/resources/workspace_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,20 @@ func TestAccResource_workspace(t *testing.T) {
resource.TestCheckResourceAttr(resourceName, "description", randomDescription),
),
},
// Import State checks - import by handle
{
ImportState: true,
ResourceName: resourceName,
ImportStateId: randomName2,
ImportStateIdPrefix: "handle/",
ImportStateVerify: true,
},
// Import State checks - import by ID (default)
{
ImportState: true,
ResourceName: resourceName,
ImportStateVerify: true,
},
},
})
}
Expand Down

0 comments on commit b4c5f78

Please sign in to comment.