package sqlserverflexalpha_test import ( "context" _ "embed" "fmt" "log" "os" "strconv" "strings" "testing" "github.com/hashicorp/terraform-plugin-testing/helper/acctest" "github.com/hashicorp/terraform-plugin-testing/helper/resource" "github.com/stackitcloud/stackit-sdk-go/core/config" "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/internal/testutils" sqlserverflexalphaPkgGen "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexalpha" sqlserverflexalpha "tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/services/sqlserverflexalpha/instance" // The fwresource import alias is so there is no collision // with the more typical acceptance testing import: // "github.com/hashicorp/terraform-plugin-testing/helper/resource" fwresource "github.com/hashicorp/terraform-plugin-framework/resource" ) const providerPrefix = "stackitprivatepreview_sqlserverflexalpha" var testInstances []string func init() { sweeperName := fmt.Sprintf("%s_%s", providerPrefix, "sweeper") resource.AddTestSweepers(sweeperName, &resource.Sweeper{ Name: sweeperName, F: func(region string) error { ctx := context.Background() apiClientConfigOptions := []config.ConfigurationOption{} apiClient, err := sqlserverflexalphaPkgGen.NewAPIClient(apiClientConfigOptions...) if err != nil { log.Fatalln(err) } instances, err := apiClient.ListInstancesRequest(ctx, testutils.ProjectId, region). Size(100). Execute() if err != nil { log.Fatalln(err) } for _, inst := range instances.GetInstances() { if strings.HasPrefix(inst.GetName(), "tf-acc-") { for _, item := range testInstances { if inst.GetName() == item { delErr := apiClient.DeleteInstanceRequestExecute(ctx, testutils.ProjectId, region, inst.GetId()) if delErr != nil { // TODO: maybe just warn? log.Fatalln(delErr) } } } } } return nil }, }) } func TestInstanceResourceSchema(t *testing.T) { t.Parallel() ctx := context.Background() schemaRequest := fwresource.SchemaRequest{} schemaResponse := &fwresource.SchemaResponse{} // Instantiate the resource.Resource and call its Schema method sqlserverflexalpha.NewInstanceResource().Schema(ctx, schemaRequest, schemaResponse) if schemaResponse.Diagnostics.HasError() { t.Fatalf("Schema method diagnostics: %+v", schemaResponse.Diagnostics) } // Validate the schema diagnostics := schemaResponse.Schema.ValidateImplementation(ctx) if diagnostics.HasError() { t.Fatalf("Schema validation diagnostics: %+v", diagnostics) } } func TestMain(m *testing.M) { testutils.Setup() code := m.Run() // shutdown() os.Exit(code) } func testAccPreCheck(t *testing.T) { if _, ok := os.LookupEnv("TF_ACC_PROJECT_ID"); !ok { t.Fatalf("could not find env var TF_ACC_PROJECT_ID") } } type resData struct { ServiceAccountFilePath string ProjectId string Region string Name string TfName string FlavorId string BackupSchedule string UseEncryption bool KekKeyId string KekKeyRingId string KekKeyVersion uint8 KekServiceAccount string PerformanceClass string Size uint32 AclString string AccessScope string RetentionDays uint32 Version string Users []User Databases []Database } type User struct { Name string ProjectId string Roles []string } type Database struct { Name string ProjectId string Owner string Collation string Compatibility string } func resName(res, name string) string { return fmt.Sprintf("%s_%s.%s", providerPrefix, res, name) } func getExample() resData { name := acctest.RandomWithPrefix("tf-acc") return resData{ Region: os.Getenv("TF_ACC_REGION"), ServiceAccountFilePath: os.Getenv("TF_ACC_SERVICE_ACCOUNT_FILE"), ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), Name: name, TfName: name, FlavorId: "4.16-Single", BackupSchedule: "0 0 * * *", UseEncryption: false, RetentionDays: 33, PerformanceClass: "premium-perf2-stackit", Size: 10, AclString: "0.0.0.0/0", AccessScope: "PUBLIC", Version: "2022", } } func TestAccInstance(t *testing.T) { exData := getExample() updNameData := exData updNameData.Name = "name-updated" updSizeData := exData updSizeData.Size = 25 resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", exData.TfName) testInstances = append(testInstances, exData.TfName) }, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", exData, ), Check: resource.ComposeAggregateTestCheckFunc( resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", exData.Name), resource.TestCheckResourceAttrSet(resName("instance", exData.TfName), "id"), // TODO: check all fields ), }, // Update name and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", updNameData, ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr(resName("instance", exData.TfName), "name", updNameData.Name), ), }, // Update size and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", updSizeData, ), Check: resource.ComposeTestCheckFunc( resource.TestCheckResourceAttr( testutils.ResStr(providerPrefix, "instance", exData.TfName), "storage.size", strconv.Itoa(int(updSizeData.Size)), ), ), }, { RefreshState: true, }, //// Import test //{ // ResourceName: resName("instance", exData.TfName), // ImportState: true, // ImportStateVerify: true, // }, }, }) } func TestAccInstanceNoEncryption(t *testing.T) { data := getExample() dbName := "testDb" userName := "testUser" data.Users = []User{ { Name: userName, ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), Roles: []string{ "##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##", "##STACKIT_ProcessManager##", "##STACKIT_SQLAgentManager##", "##STACKIT_SQLAgentUser##", "##STACKIT_ServerManager##", }, }, } data.Databases = []Database{ { Name: dbName, ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), Owner: userName, }, } resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", data.TfName) testInstances = append(testInstances, data.TfName) }, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", data, ), Check: resource.ComposeAggregateTestCheckFunc( // check instance values are set resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"), resource.TestCheckNoResourceAttr(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"), // check instance values are correct resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name), // check user values are set resource.TestCheckResourceAttrSet(resName("user", userName), "id"), resource.TestCheckResourceAttrSet(resName("user", userName), "username"), // resource.TestCheckResourceAttrSet(resName("user", userName), "roles"), // func(s *terraform.State) error { // return nil // }, // check user values are correct resource.TestCheckResourceAttr(resName("user", userName), "username", userName), resource.TestCheckResourceAttr(resName("user", userName), "roles.#", strconv.Itoa(len(data.Users[0].Roles))), // check database values are set resource.TestCheckResourceAttrSet(resName("database", dbName), "id"), resource.TestCheckResourceAttrSet(resName("database", dbName), "name"), resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"), resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"), resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"), // check database values are correct resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName), resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName), ), }, }, }) } func TestAccInstanceEncryption(t *testing.T) { data := getExample() dbName := "testDb" userName := "testUser" data.Users = []User{ { Name: userName, ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), Roles: []string{"##STACKIT_DatabaseManager##", "##STACKIT_LoginManager##"}, }, } data.Databases = []Database{ { Name: dbName, ProjectId: os.Getenv("TF_ACC_PROJECT_ID"), Owner: userName, }, } data.UseEncryption = true data.KekKeyId = "fe039bcf-8d7b-431a-801d-9e81371a6b7b" data.KekKeyRingId = "6a2d95ab-3c4c-4963-a2bb-08d17a320e27" data.KekKeyVersion = 1 data.KekServiceAccount = "henselinm-u2v3ex1@sa.stackit.cloud" resource.ParallelTest(t, resource.TestCase{ PreCheck: func() { testAccPreCheck(t) t.Logf(" ... working on instance %s", data.TfName) testInstances = append(testInstances, data.TfName) }, ProtoV6ProviderFactories: testutils.TestAccProtoV6ProviderFactories, Steps: []resource.TestStep{ // Create and verify { Config: testutils.StringFromTemplateMust( "testdata/instance_template.gompl", data, ), Check: resource.ComposeAggregateTestCheckFunc( // check instance values are set resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "id"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "backup_schedule"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "edition"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "flavor_id"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "instance_id"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "is_deletable"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "name"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "replicas"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "retention_days"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "status"), resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "version"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_id"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_version"), //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.kek_key_ring_id"), //resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "encryption.service_account"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.access_scope"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.acl"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.instance_address"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "network.router_address"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.class"), // resource.TestCheckResourceAttrSet(resName("instance", data.TfName), "storage.size"), // check instance values are correct resource.TestCheckResourceAttr(resName("instance", data.TfName), "name", data.Name), // check user values are set resource.TestCheckResourceAttrSet(resName("user", userName), "id"), resource.TestCheckResourceAttrSet(resName("user", userName), "username"), // func(s *terraform.State) error { // return nil // }, // check user values are correct resource.TestCheckResourceAttr(resName("user", userName), "username", userName), resource.TestCheckResourceAttr(resName("user", userName), "roles.#", "2"), // check database values are set resource.TestCheckResourceAttrSet(resName("database", dbName), "id"), resource.TestCheckResourceAttrSet(resName("database", dbName), "name"), resource.TestCheckResourceAttrSet(resName("database", dbName), "owner"), resource.TestCheckResourceAttrSet(resName("database", dbName), "compatibility"), resource.TestCheckResourceAttrSet(resName("database", dbName), "collation"), // check database values are correct resource.TestCheckResourceAttr(resName("database", dbName), "name", dbName), resource.TestCheckResourceAttr(resName("database", dbName), "owner", userName), ), }, }, }) }