package stackit_test import ( "context" _ "embed" "fmt" "net/http" "os" "reflect" "regexp" "testing" "time" "github.com/golang-jwt/jwt/v5" test "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/jarcoal/httpmock" "github.com/stackitcloud/stackit-sdk-go/core/clients" "github.com/stackitcloud/stackit-sdk-go/core/utils" "github.com/stretchr/testify/require" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/postgresflexalpha" 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" sqlserverflexalphaDatabase "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/database" sqlserverFlexAlphaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/flavor" 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" sqlserverFlexBetaFlavor "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexbeta/flavor" 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/resource" ) //go:embed testdata/provider-credentials.tf var providerCredentialConfig string //go:embed testdata/provider-invalid-attribute.tf var providerInvalidAttribute string //go:embed testdata/provider-all-attributes.tf var providerValidAttributes string var testConfigProviderCredentials config.Variables func TestMain(m *testing.M) { testutils.Setup() code := m.Run() // shutdown() os.Exit(code) } func TestMshTest(t *testing.T) { httpmock.Activate() defer httpmock.DeactivateAndReset() testutils.ActivateEnvironmentHttpMocks() httpmock.RegisterResponder("POST", `https://service-account.api.stackit.cloud/token`, func(req *http.Request) (*http.Response, error) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "foo": "bar", "nbf": time.Date(2015, 10, 10, 12, 0, 0, 0, time.UTC).Unix(), }) // Sign and get the complete encoded token as a string using the secret tokenString, err := token.SignedString([]byte("mySecret")) if err != nil { panic(err) } tR := clients.TokenResponseBody{ AccessToken: tokenString, ExpiresIn: 3600, RefreshToken: "", Scope: "", TokenType: "", } return httpmock.NewJsonResponse(http.StatusOK, tR) }) httpmock.RegisterResponder("GET", `https://postgres-flex-service.api.eu01.stackit.cloud/v3alpha1/projects/xyz-project-id/regions/eu01/flavors?page=1&size=25&sort=id.asc`, func(req *http.Request) (*http.Response, error) { res := postgresflexalpha.GetFlavorsResponse{ Flavors: &[]postgresflexalpha.ListFlavors{ { Cpu: nil, Description: nil, Id: nil, MaxGB: nil, Memory: nil, MinGB: nil, NodeType: nil, StorageClasses: nil, }, }, Pagination: &postgresflexalpha.Pagination{ Page: utils.Ptr(int64(1)), Size: utils.Ptr(int64(25)), Sort: nil, TotalPages: utils.Ptr(int64(1)), TotalRows: utils.Ptr(int64(0)), }, } return httpmock.NewJsonResponse( http.StatusOK, res, ) }, ) test.Test(t, test.TestCase{ IsUnitTest: true, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []test.TestStep{ { ConfigVariables: map[string]config.Variable{ "project_id": config.StringVariable("xyz-project-id"), }, Config: fmt.Sprintf(` provider "stackitprivatepreview" { default_region = "%[1]s" service_account_key_path = "%[2]s" } variable "project_id" { type = string } data "stackitprivatepreview_postgresflexalpha_flavor" "all" { project_id = var.project_id region = "eu01" cpu = 2 ram = 4 node_type = "Single" storage_class = "premium-perf2-stackit" }`, os.Getenv("TF_ACC_REGION"), os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"), ), }, }, }) } func TestUnitProviderHasChildDataSources_Basic(t *testing.T) { expectedDataSources := []datasource.DataSource{ postgresFlexAlphaFlavor.NewFlavorDataSource(), // postgresFlexAlphaFlavor.NewFlavorListDataSource, postgresFlexAlphaDatabase.NewDatabaseDataSource(), postgresFlexAlphaInstance.NewInstanceDataSource(), postgresFlexAlphaUser.NewUserDataSource(), postgresflexalphaFlavors.NewFlavorsDataSource(), sqlserverFlexAlphaFlavor.NewFlavorDataSource(), sqlserverFlexAlphaInstance.NewInstanceDataSource(), sqlserverFlexAlphaUser.NewUserDataSource(), sqlserverflexalphaDatabase.NewDatabaseDataSource(), sqlserverflexBetaDatabase.NewDatabaseDataSource(), sqlserverFlexBetaInstance.NewInstanceDataSource(), sqlserverFlexBetaUser.NewUserDataSource(), sqlserverFlexBetaFlavor.NewFlavorDataSource(), } datasources := stackit.New("testing")().(*stackit.Provider).DataSources(context.Background()) if !reflect.DeepEqual(len(expectedDataSources), len(datasources)) { for _, d := range datasources { require.Containsf(t, expectedDataSources, d(), "Data source %+v was not expected", reflect.TypeOf(d())) } } } 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(), } resources := stackit.New("testing")().(*stackit.Provider).Resources(context.Background()) if !reflect.DeepEqual(len(expectedResources), len(resources)) { for _, d := range resources { require.Containsf(t, expectedResources, d(), "Resource %+v was not expected", reflect.TypeOf(d())) } } } 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) return } // t.Setenv("STACKIT_CREDENTIALS_PATH", "") 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 TestAccEnvVarServiceAccountPathInvalid(t *testing.T) { t.Skip("needs refactoring") t.Setenv("STACKIT_CREDENTIALS_PATH", "") 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", "") 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", "") 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) return } t.Setenv("STACKIT_CREDENTIALS_PATH", "") 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) return } t.Setenv("STACKIT_CREDENTIALS_PATH", "") 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\.`), }, }, }) }