feat: initial copy of v0.1.0
All checks were successful
Publish / Check GoReleaser config (push) Successful in 5s
Publish / Publish provider (push) Successful in 16m14s

This commit is contained in:
Marcel S. Henselin 2026-03-13 09:03:49 +01:00
parent 4cc801a7f3
commit 7d4cbb6b08
538 changed files with 63361 additions and 55213 deletions

View file

@ -1,20 +1,38 @@
// Copyright (c) STACKIT
package stackit_test
import (
"context"
_ "embed"
"fmt"
"os"
"path"
"reflect"
"regexp"
"runtime"
"testing"
"github.com/google/go-cmp/cmp"
sqlserverflexalphaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database"
//nolint:staticcheck // used for acceptance testing
postgresFlexAlphaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavor"
"github.com/hashicorp/terraform-plugin-framework/datasource"
tfResource "github.com/hashicorp/terraform-plugin-framework/resource"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit"
postgresFlexAlphaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/database"
postgresflexalphaFlavors "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/flavors"
postgresFlexAlphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/instance"
postgresFlexAlphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/postgresflexalpha/user"
sqlserverFlexAlphaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance"
sqlserverFlexAlphaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/user"
sqlserverflexBetaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/database"
sqlserverFlexBetaInstance "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/instance"
sqlserverFlexBetaUser "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/user"
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils"
"github.com/hashicorp/terraform-plugin-testing/config"
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
"github.com/stackitcloud/terraform-provider-stackit/stackit/internal/testutil"
"github.com/hashicorp/terraform-plugin-testing/helper/resource" //nolint:staticcheck // used for acceptance testing
)
//go:embed testdata/provider-credentials.tf
@ -26,236 +44,228 @@ var providerInvalidAttribute string
//go:embed testdata/provider-all-attributes.tf
var providerValidAttributes string
var testConfigProviderCredentials = config.Variables{
"project_id": config.StringVariable(testutil.ProjectId),
"name": config.StringVariable(fmt.Sprintf("tf-acc-prov%s", acctest.RandStringFromCharSet(3, acctest.CharSetAlphaNum))),
var testConfigProviderCredentials config.Variables
func TestMain(m *testing.M) {
testutils.Setup()
code := m.Run()
// shutdown()
os.Exit(code)
}
// Helper function to obtain the home directory on different systems.
// Based on os.UserHomeDir().
func getHomeEnvVariableName() string {
env := "HOME"
switch runtime.GOOS {
case "windows":
env = "USERPROFILE"
case "plan9":
env = "home"
}
return env
}
func TestUnitProviderHasChildDataSources_Basic(t *testing.T) {
expectedDataSources := []datasource.DataSource{
postgresFlexAlphaFlavor.NewFlavorDataSource(),
// postgresFlexAlphaFlavor.NewFlavorListDataSource,
postgresFlexAlphaDatabase.NewDatabaseDataSource(),
postgresFlexAlphaInstance.NewInstanceDataSource(),
postgresFlexAlphaUser.NewUserDataSource(),
postgresflexalphaFlavors.NewFlavorsDataSource(),
// create temporary home and initialize the credentials file as well
func createTemporaryHome(createValidCredentialsFile bool, t *testing.T) string {
// create a temporary file
tempHome, err := os.MkdirTemp("", "tempHome")
if err != nil {
t.Fatalf("Failed to create temporary home directory: %v", err)
// sqlserverFlexAlphaFlavor.NewFlavorDataSource(),
sqlserverFlexAlphaInstance.NewInstanceDataSource(),
sqlserverFlexAlphaUser.NewUserDataSource(),
sqlserverflexalphaDatabase.NewDatabaseDataSource(),
sqlserverflexBetaDatabase.NewDatabaseDataSource(),
sqlserverFlexBetaInstance.NewInstanceDataSource(),
sqlserverFlexBetaUser.NewUserDataSource(),
// sqlserverFlexBetaFlavor.NewFlavorDataSource(),
}
provider, ok := stackit.New("testing")().(*stackit.Provider)
if !ok {
t.Fatal("could not assert provider type")
}
datasources := provider.DataSources(context.Background())
expectedMap := map[string]struct{}{}
for _, d := range expectedDataSources {
expectedMap[reflect.TypeOf(d).String()] = struct{}{}
}
// create credentials file in temp directory
stackitFolder := path.Join(tempHome, ".stackit")
if err := os.Mkdir(stackitFolder, 0o750); err != nil {
t.Fatalf("Failed to create stackit folder: %v", err)
actualMap := map[string]struct{}{}
for _, d := range datasources {
actualMap[reflect.TypeOf(d()).String()] = struct{}{}
}
filePath := path.Join(stackitFolder, "credentials.json")
file, err := os.Create(filePath)
if err != nil {
t.Fatalf("Failed to create credentials file: %v", err)
}
defer func() {
if err := file.Close(); err != nil {
t.Fatalf("Error while closing the file: %v", err)
}
}()
// Define content, default = invalid token
token := "foo_token"
if createValidCredentialsFile {
token = testutil.GetTestProjectServiceAccountToken("")
}
content := fmt.Sprintf(`
{
"STACKIT_SERVICE_ACCOUNT_TOKEN": "%s"
}`, token)
if _, err = file.WriteString(content); err != nil {
t.Fatalf("Error writing to file: %v", err)
}
return tempHome
}
// Function to overwrite the home folder
func setTemporaryHome(tempHomePath string) {
env := getHomeEnvVariableName()
if err := os.Setenv(env, tempHomePath); err != nil {
fmt.Printf("Error setting temporary home directory %v", err)
if diff := cmp.Diff(expectedMap, actualMap); diff != "" {
t.Errorf("DataSources mismatch (-expected +actual):\n%s", diff)
}
}
// cleanup the temporary home and reset the environment variable
func cleanupTemporaryHome(tempHomePath string, t *testing.T) {
if err := os.RemoveAll(tempHomePath); err != nil {
t.Fatalf("Error cleaning up temporary folder: %v", err)
func TestUnitProviderHasChildResources_Basic(t *testing.T) {
expectedResources := []tfResource.Resource{
postgresFlexAlphaInstance.NewInstanceResource(),
postgresFlexAlphaUser.NewUserResource(),
postgresFlexAlphaDatabase.NewDatabaseResource(),
sqlserverFlexAlphaInstance.NewInstanceResource(),
sqlserverFlexAlphaUser.NewUserResource(),
sqlserverflexalphaDatabase.NewDatabaseResource(),
sqlserverFlexBetaInstance.NewInstanceResource(),
sqlserverFlexBetaUser.NewUserResource(),
sqlserverflexBetaDatabase.NewDatabaseResource(),
}
originalHomeDir, err := os.UserHomeDir()
if err != nil {
t.Fatalf("Failed to restore home directory back to normal: %v", err)
provider, ok := stackit.New("testing")().(*stackit.Provider)
if !ok {
t.Fatal("could not assert provider type")
}
// revert back to original home folder
env := getHomeEnvVariableName()
if err := os.Setenv(env, originalHomeDir); err != nil {
fmt.Printf("Error resetting temporary home directory %v", err)
resources := provider.Resources(context.Background())
expectedMap := map[string]struct{}{}
for _, r := range expectedResources {
expectedMap[reflect.TypeOf(r).String()] = struct{}{}
}
actualMap := map[string]struct{}{}
for _, r := range resources {
actualMap[reflect.TypeOf(r()).String()] = struct{}{}
}
if diff := cmp.Diff(expectedMap, actualMap); diff != "" {
t.Errorf("Resources mismatch (-expected +actual):\n%s", diff)
}
}
func getServiceAccountToken() (string, error) {
token, set := os.LookupEnv("TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN")
if !set || token == "" {
return "", fmt.Errorf("Token not set, please set TF_ACC_TEST_PROJECT_SERVICE_ACCOUNT_TOKEN to a valid token to perform tests")
}
return token, nil
}
func TestAccEnvVarTokenValid(t *testing.T) {
func TestAccEnvVarServiceAccountPathValid(t *testing.T) {
t.Skip("needs refactoring")
// Check if acceptance tests should be run
if v := os.Getenv(resource.EnvTfAcc); v == "" {
t.Skipf(
"Acceptance tests skipped unless env '%s' set",
resource.EnvTfAcc)
resource.EnvTfAcc,
)
return
}
token, err := getServiceAccountToken()
if err != nil {
t.Fatalf("Can't get token: %v", err)
}
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
t.Setenv("STACKIT_SERVICE_ACCOUNT_TOKEN", token)
tempHomeFolder := createTemporaryHome(false, t)
defer cleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { setTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
},
},
},
})
)
}
func TestAccEnvVarTokenInvalid(t *testing.T) {
func TestAccEnvVarServiceAccountPathInvalid(t *testing.T) {
t.Skip("needs refactoring")
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
t.Setenv("STACKIT_SERVICE_ACCOUNT_TOKEN", "foo")
tempHomeFolder := createTemporaryHome(false, t)
defer cleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { setTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`undefined response type, status code 401`),
tempHomeFolder := testutils.CreateTemporaryHome(false, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`undefined response type, status code 401`),
},
},
},
})
)
}
func TestAccCredentialsFileValid(t *testing.T) {
t.Skip("needs refactoring")
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
t.Setenv("STACKIT_SERVICE_ACCOUNT_TOKEN", "")
tempHomeFolder := createTemporaryHome(true, t)
defer cleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { setTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
},
},
},
})
)
}
func TestAccCredentialsFileInvalid(t *testing.T) {
t.Skip("needs refactoring")
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
t.Setenv("STACKIT_SERVICE_ACCOUNT_TOKEN", "")
tempHomeFolder := createTemporaryHome(false, t)
defer cleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { setTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`Jwt is not in(\r\n|\r|\n)the form of Header.Payload.Signature`),
tempHomeFolder := testutils.CreateTemporaryHome(false, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
PreConfig: func() { testutils.SetTemporaryHome(tempHomeFolder) },
ConfigVariables: testConfigProviderCredentials,
Config: providerCredentialConfig,
ExpectError: regexp.MustCompile(`Jwt is not in(\r\n|\r|\n)the form of Header.Payload.Signature`),
},
},
},
})
)
}
func TestAccProviderConfigureValidValues(t *testing.T) {
t.Skip("needs refactoring")
// Check if acceptance tests should be run
if v := os.Getenv(resource.EnvTfAcc); v == "" {
t.Skipf(
"Acceptance tests skipped unless env '%s' set",
resource.EnvTfAcc)
resource.EnvTfAcc,
)
return
}
// use service account token for these tests
token, err := getServiceAccountToken()
if err != nil {
t.Fatalf("Can't get token: %v", err)
}
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
t.Setenv("STACKIT_SERVICE_ACCOUNT_TOKEN", token)
tempHomeFolder := createTemporaryHome(true, t)
defer cleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{ // valid provider attributes
ConfigVariables: testConfigProviderCredentials,
Config: providerValidAttributes,
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
// valid provider attributes
ConfigVariables: testConfigProviderCredentials,
Config: providerValidAttributes,
},
},
},
})
)
}
func TestAccProviderConfigureAnInvalidValue(t *testing.T) {
t.Skip("needs refactoring")
// Check if acceptance tests should be run
if v := os.Getenv(resource.EnvTfAcc); v == "" {
t.Skipf(
"Acceptance tests skipped unless env '%s' set",
resource.EnvTfAcc)
resource.EnvTfAcc,
)
return
}
// use service account token for these tests
token, err := getServiceAccountToken()
if err != nil {
t.Fatalf("Can't get token: %v", err)
}
t.Setenv("STACKIT_CREDENTIALS_PATH", "")
t.Setenv("STACKIT_SERVICE_ACCOUNT_TOKEN", token)
tempHomeFolder := createTemporaryHome(true, t)
defer cleanupTemporaryHome(tempHomeFolder, t)
resource.Test(t, resource.TestCase{
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{ // invalid test attribute should throw an error
ConfigVariables: testConfigProviderCredentials,
Config: providerInvalidAttribute,
ExpectError: regexp.MustCompile(`An argument named "test" is not expected here\.`),
tempHomeFolder := testutils.CreateTemporaryHome(true, t)
defer testutils.CleanupTemporaryHome(tempHomeFolder, t)
resource.Test(
t, resource.TestCase{
ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories,
Steps: []resource.TestStep{
{
// invalid test attribute should throw an error
ConfigVariables: testConfigProviderCredentials,
Config: providerInvalidAttribute,
ExpectError: regexp.MustCompile(`An argument named "test" is not expected here\.`),
},
},
},
})
)
}