feat: refactor testing #35
6 changed files with 486 additions and 60 deletions
|
|
@ -1,4 +1,3 @@
|
||||||
|
|
||||||
provider:
|
provider:
|
||||||
name: stackitprivatepreview
|
name: stackitprivatepreview
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,7 @@ func mapGetInstanceResponseToModel(ctx context.Context, m *postgresflexalphareso
|
||||||
})
|
})
|
||||||
|
|
||||||
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
m.BackupSchedule = types.StringValue(resp.GetBackupSchedule())
|
||||||
|
m.Encryption = postgresflexalpharesource.NewEncryptionValueNull()
|
||||||
if resp.HasEncryption() {
|
if resp.HasEncryption() {
|
||||||
m.Encryption = postgresflexalpharesource.NewEncryptionValueMust(
|
m.Encryption = postgresflexalpharesource.NewEncryptionValueMust(
|
||||||
m.Encryption.AttributeTypes(ctx),
|
m.Encryption.AttributeTypes(ctx),
|
||||||
|
|
|
||||||
|
|
@ -293,9 +293,7 @@ func toUpdatePayload(
|
||||||
BackupSchedule: m.BackupSchedule.ValueStringPointer(),
|
BackupSchedule: m.BackupSchedule.ValueStringPointer(),
|
||||||
FlavorId: m.FlavorId.ValueStringPointer(),
|
FlavorId: m.FlavorId.ValueStringPointer(),
|
||||||
Name: m.Name.ValueStringPointer(),
|
Name: m.Name.ValueStringPointer(),
|
||||||
Network: &sqlserverflexbeta.UpdateInstanceRequestPayloadNetwork{
|
Network: sqlserverflexbeta.NewUpdateInstanceRequestPayloadNetwork(netAcl),
|
||||||
Acl: &netAcl,
|
|
||||||
},
|
|
||||||
Replicas: &replVal,
|
Replicas: &replVal,
|
||||||
RetentionDays: m.RetentionDays.ValueInt64Pointer(),
|
RetentionDays: m.RetentionDays.ValueInt64Pointer(),
|
||||||
Storage: &sqlserverflexbeta.StorageUpdate{Size: m.Storage.Size.ValueInt64Pointer()},
|
Storage: &sqlserverflexbeta.StorageUpdate{Size: m.Storage.Size.ValueInt64Pointer()},
|
||||||
|
|
|
||||||
|
|
@ -141,18 +141,6 @@ func (r *instanceResource) ModifyPlan(
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
var identityModel InstanceResourceIdentityModel
|
|
||||||
identityModel.ProjectID = planModel.ProjectId
|
|
||||||
identityModel.Region = planModel.Region
|
|
||||||
if !planModel.InstanceId.IsNull() && !planModel.InstanceId.IsUnknown() {
|
|
||||||
identityModel.InstanceID = planModel.InstanceId
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.Identity.Set(ctx, identityModel)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
resp.Diagnostics.Append(resp.Plan.Set(ctx, planModel)...)
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
|
|
@ -164,6 +152,7 @@ var modifiersFileByte []byte
|
||||||
|
|
||||||
func (r *instanceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
func (r *instanceResource) Create(ctx context.Context, req resource.CreateRequest, resp *resource.CreateResponse) {
|
||||||
var data sqlserverflexbetaResGen.InstanceModel
|
var data sqlserverflexbetaResGen.InstanceModel
|
||||||
|
crateErr := "[SQL Server Flex BETA - Create] error"
|
||||||
|
|
||||||
// Read Terraform plan data into the model
|
// Read Terraform plan data into the model
|
||||||
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||||
|
|
@ -172,17 +161,10 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read identity data
|
|
||||||
var identityData InstanceResourceIdentityModel
|
|
||||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
projectId := data.ProjectId.ValueString()
|
||||||
region := identityData.Region.ValueString()
|
region := data.Region.ValueString()
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
|
@ -192,7 +174,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
"Error creating Instance",
|
crateErr,
|
||||||
fmt.Sprintf("Creating API payload: %v", err),
|
fmt.Sprintf("Creating API payload: %v", err),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -204,7 +186,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
region,
|
region,
|
||||||
).CreateInstanceRequestPayload(*payload).Execute()
|
).CreateInstanceRequestPayload(*payload).Execute()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(ctx, &resp.Diagnostics, "Error creating Instance", fmt.Sprintf("Calling API: %v", err))
|
core.LogAndAddError(ctx, &resp.Diagnostics, crateErr, fmt.Sprintf("Calling API: %v", err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -240,7 +222,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
"Error creating Instance",
|
crateErr,
|
||||||
fmt.Sprintf("Instance creation waiting: %v", err),
|
fmt.Sprintf("Instance creation waiting: %v", err),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -250,7 +232,7 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
"Error creating Instance",
|
crateErr,
|
||||||
"Instance creation waiting: returned id is nil",
|
"Instance creation waiting: returned id is nil",
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
|
|
@ -262,8 +244,8 @@ func (r *instanceResource) Create(ctx context.Context, req resource.CreateReques
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
&resp.Diagnostics,
|
&resp.Diagnostics,
|
||||||
"Error creating Instance",
|
crateErr,
|
||||||
fmt.Sprintf("Processing API payload: %v", err),
|
fmt.Sprintf("processing API payload: %v", err),
|
||||||
)
|
)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
@ -292,8 +274,8 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
projectId := data.ProjectId.ValueString()
|
||||||
region := identityData.Region.ValueString()
|
region := data.Region.ValueString()
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
|
@ -325,9 +307,6 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save updated data into Terraform state
|
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
|
||||||
|
|
||||||
identity := InstanceResourceIdentityModel{
|
identity := InstanceResourceIdentityModel{
|
||||||
ProjectID: types.StringValue(projectId),
|
ProjectID: types.StringValue(projectId),
|
||||||
Region: types.StringValue(region),
|
Region: types.StringValue(region),
|
||||||
|
|
@ -338,6 +317,9 @@ func (r *instanceResource) Read(ctx context.Context, req resource.ReadRequest, r
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save updated data into Terraform state
|
||||||
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
|
||||||
tflog.Info(ctx, "sqlserverflexbeta.Instance read")
|
tflog.Info(ctx, "sqlserverflexbeta.Instance read")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -345,23 +327,15 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
var data sqlserverflexbetaResGen.InstanceModel
|
var data sqlserverflexbetaResGen.InstanceModel
|
||||||
updateInstanceError := "Error updating instance"
|
updateInstanceError := "Error updating instance"
|
||||||
|
|
||||||
// Read Terraform prior state data into the model
|
resp.Diagnostics.Append(req.Plan.Get(ctx, &data)...)
|
||||||
resp.Diagnostics.Append(req.State.Get(ctx, &data)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Read identity data
|
|
||||||
var identityData InstanceResourceIdentityModel
|
|
||||||
resp.Diagnostics.Append(req.Identity.Get(ctx, &identityData)...)
|
|
||||||
if resp.Diagnostics.HasError() {
|
if resp.Diagnostics.HasError() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx = core.InitProviderContext(ctx)
|
ctx = core.InitProviderContext(ctx)
|
||||||
|
|
||||||
projectId := identityData.ProjectID.ValueString()
|
projectId := data.ProjectId.ValueString()
|
||||||
region := identityData.Region.ValueString()
|
region := data.Region.ValueString()
|
||||||
ctx = tflog.SetField(ctx, "project_id", projectId)
|
ctx = tflog.SetField(ctx, "project_id", projectId)
|
||||||
ctx = tflog.SetField(ctx, "region", region)
|
ctx = tflog.SetField(ctx, "region", region)
|
||||||
|
|
||||||
|
|
@ -393,7 +367,11 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
waitResp, err := wait.UpdateInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
|
waitResp, err := wait.
|
||||||
|
UpdateInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).
|
||||||
|
SetSleepBeforeWait(15 * time.Second).
|
||||||
|
SetTimeout(45 * time.Minute).
|
||||||
|
WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -416,6 +394,16 @@ func (r *instanceResource) Update(ctx context.Context, req resource.UpdateReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
identity := InstanceResourceIdentityModel{
|
||||||
|
ProjectID: types.StringValue(projectId),
|
||||||
|
Region: types.StringValue(region),
|
||||||
|
InstanceID: types.StringValue(instanceId),
|
||||||
|
}
|
||||||
|
resp.Diagnostics.Append(resp.Identity.Set(ctx, identity)...)
|
||||||
|
if resp.Diagnostics.HasError() {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// Save updated data into Terraform state
|
// Save updated data into Terraform state
|
||||||
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
resp.Diagnostics.Append(resp.State.Set(ctx, &data)...)
|
||||||
|
|
||||||
|
|
@ -457,7 +445,7 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
|
|
||||||
ctx = core.LogResponse(ctx)
|
ctx = core.LogResponse(ctx)
|
||||||
|
|
||||||
_, err = wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
|
delResp, err := wait.DeleteInstanceWaitHandler(ctx, r.client, projectId, instanceId, region).WaitWithContext(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
core.LogAndAddError(
|
core.LogAndAddError(
|
||||||
ctx,
|
ctx,
|
||||||
|
|
@ -468,6 +456,18 @@ func (r *instanceResource) Delete(ctx context.Context, req resource.DeleteReques
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if delResp != nil {
|
||||||
|
core.LogAndAddError(
|
||||||
|
ctx,
|
||||||
|
&resp.Diagnostics,
|
||||||
|
"Error deleting instance",
|
||||||
|
"wait handler returned non nil result",
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.State.RemoveResource(ctx)
|
||||||
|
|
||||||
tflog.Info(ctx, "sqlserverflexbeta.Instance deleted")
|
tflog.Info(ctx, "sqlserverflexbeta.Instance deleted")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,430 @@
|
||||||
|
package sqlserverflexbeta
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/compare"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/helper/acctest"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/helper/resource"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/knownvalue"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/statecheck"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/terraform"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/tfjsonpath"
|
||||||
|
"github.com/hashicorp/terraform-plugin-testing/tfversion"
|
||||||
|
"github.com/stackitcloud/stackit-sdk-go/core/config"
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/pkg_gen/sqlserverflexbeta"
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/core"
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/testutil"
|
||||||
|
"tf-provider.git.onstackit.cloud/stackit-dev-tools/terraform-provider-stackitprivatepreview/stackit/internal/utils"
|
||||||
|
)
|
||||||
|
|
||||||
|
const resourceString = "stackitprivatepreview_sqlserverflexbeta_instance"
|
||||||
|
|
||||||
|
var (
|
||||||
|
validSingleFlavor = "4.16-Single"
|
||||||
|
kekKeyRingId = ""
|
||||||
|
kekKeyVersion = ""
|
||||||
|
kekKeySA = ""
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestMain(m *testing.M) {
|
||||||
|
resource.TestMain(m)
|
||||||
|
}
|
||||||
|
|
||||||
|
func init() {
|
||||||
|
resource.AddTestSweepers(resourceString, &resource.Sweeper{
|
||||||
|
Name: resourceString,
|
||||||
|
F: func(region string) error {
|
||||||
|
client, err := sharedClientForRegion(region)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error getting client: %s", err)
|
||||||
|
}
|
||||||
|
conn := client.(*sqlserverflexbeta.APIClient)
|
||||||
|
|
||||||
|
ctx := context.Background()
|
||||||
|
instances, err := conn.ListInstancesRequest(ctx, testutil.ProjectId, region).Execute()
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("error getting instances: %s", err)
|
||||||
|
}
|
||||||
|
for _, instance := range instances.GetInstances() {
|
||||||
|
if strings.HasPrefix(instance.GetName(), "test-acc") {
|
||||||
|
err := conn.DeleteInstanceRequestExecute(ctx, testutil.ProjectId, region, instance.GetId())
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("error destroying %s during sweep: %s", instance.GetName(), err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// sharedClientForRegion returns a common provider client configured for the specified region
|
||||||
|
func sharedClientForRegion(region string) (any, error) {
|
||||||
|
providerData := core.ProviderData{}
|
||||||
|
if region != "" {
|
||||||
|
providerData.DefaultRegion = region
|
||||||
|
}
|
||||||
|
apiClientConfigOptions := []config.ConfigurationOption{
|
||||||
|
config.WithCustomAuth(providerData.RoundTripper),
|
||||||
|
utils.UserAgentConfigOption(providerData.Version),
|
||||||
|
}
|
||||||
|
if providerData.SQLServerFlexCustomEndpoint != "" {
|
||||||
|
apiClientConfigOptions = append(apiClientConfigOptions, config.WithEndpoint(providerData.SQLServerFlexCustomEndpoint))
|
||||||
|
} else {
|
||||||
|
apiClientConfigOptions = append(apiClientConfigOptions, config.WithRegion(providerData.GetRegion()))
|
||||||
|
}
|
||||||
|
apiClient, err := sqlserverflexbeta.NewAPIClient(apiClientConfigOptions...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return apiClient, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccPreCheck(t *testing.T) {
|
||||||
|
// TODO: if needed ...
|
||||||
|
}
|
||||||
|
|
||||||
|
type resData struct {
|
||||||
|
WithEncryption bool
|
||||||
|
ServiceAccountFilePath string
|
||||||
|
ProjectID string
|
||||||
|
Region string
|
||||||
|
TfName string
|
||||||
|
Name string
|
||||||
|
FlavorID string
|
||||||
|
BackupSchedule string
|
||||||
|
RetentionDays uint32
|
||||||
|
Replicas uint32
|
||||||
|
PerformanceClass string
|
||||||
|
Size uint32
|
||||||
|
Acl string
|
||||||
|
AccessScope string
|
||||||
|
Version string
|
||||||
|
KekKeyId string
|
||||||
|
KekKeyRingId string
|
||||||
|
KekKeyVersion uint8
|
||||||
|
KekSaEmail string
|
||||||
|
}
|
||||||
|
|
||||||
|
func getSingleExample() resData {
|
||||||
|
tmpName := acctest.RandomWithPrefix("tf-acc")
|
||||||
|
return resData{
|
||||||
|
WithEncryption: false,
|
||||||
|
Region: testutil.Region,
|
||||||
|
ServiceAccountFilePath: testutil.ServiceAccountFile,
|
||||||
|
ProjectID: testutil.ProjectId,
|
||||||
|
Name: tmpName,
|
||||||
|
TfName: tmpName,
|
||||||
|
FlavorID: validSingleFlavor,
|
||||||
|
BackupSchedule: "0 0 * * *",
|
||||||
|
RetentionDays: 33,
|
||||||
|
PerformanceClass: "premium-perf2-stackit",
|
||||||
|
Size: 10,
|
||||||
|
Acl: "0.0.0.0/0",
|
||||||
|
AccessScope: "PUBLIC",
|
||||||
|
Version: "2022",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAccResourceExample_basic(t *testing.T) {
|
||||||
|
exData := getSingleExample()
|
||||||
|
t.Logf("[INFO] resource name: %s", exData.TfName)
|
||||||
|
|
||||||
|
exBefore := testAccResourceExampleConfig(exData)
|
||||||
|
|
||||||
|
updData := exData
|
||||||
|
// oldName := exData.Name
|
||||||
|
updData.Name = "newname"
|
||||||
|
updBefore := testAccResourceExampleConfig(updData)
|
||||||
|
|
||||||
|
resName := fmt.Sprintf("%s.%s", resourceString, exData.TfName)
|
||||||
|
var resourceID string
|
||||||
|
|
||||||
|
compareValuesSame := statecheck.CompareValue(compare.ValuesSame())
|
||||||
|
|
||||||
|
resource.Test(t, resource.TestCase{
|
||||||
|
PreCheck: func() { testAccPreCheck(t) },
|
||||||
|
ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
|
||||||
|
TerraformVersionChecks: []tfversion.TerraformVersionCheck{
|
||||||
|
tfversion.SkipBelow(tfversion.Version1_10_0),
|
||||||
|
},
|
||||||
|
CheckDestroy: testAccCheckExampleResourceDestroy,
|
||||||
|
Steps: []resource.TestStep{
|
||||||
|
// test create
|
||||||
|
{
|
||||||
|
Config: exBefore,
|
||||||
|
ConfigStateChecks: []statecheck.StateCheck{
|
||||||
|
compareValuesSame.AddStateValue(
|
||||||
|
resName,
|
||||||
|
tfjsonpath.New("edition"),
|
||||||
|
),
|
||||||
|
statecheck.ExpectKnownValue(
|
||||||
|
resName,
|
||||||
|
tfjsonpath.New("edition"),
|
||||||
|
knownvalue.StringExact("Standard"),
|
||||||
|
),
|
||||||
|
//statecheck.ExpectSensitiveValue(resName,
|
||||||
|
// tfjsonpath.New("sensitive_string_attribute")),
|
||||||
|
},
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
func(s *terraform.State) error {
|
||||||
|
t.Logf("[INFO] resourceID: %+v", resourceID)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
testAccGrabResourceID(resName, &resourceID),
|
||||||
|
func(s *terraform.State) error {
|
||||||
|
t.Logf("[INFO] resourceID: %s", resourceID)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
testCheckResourceExists(resName),
|
||||||
|
resource.TestCheckResourceAttrSet(resName, "id"),
|
||||||
|
//resource.TestCheckResourceAttr(resName, "id", resourceID),
|
||||||
|
resource.TestCheckResourceAttr(resName, "name", exData.Name),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// up to here we should see no plan drift
|
||||||
|
{
|
||||||
|
Config: exBefore,
|
||||||
|
PlanOnly: true,
|
||||||
|
ExpectNonEmptyPlan: false,
|
||||||
|
},
|
||||||
|
// test update
|
||||||
|
{
|
||||||
|
Config: updBefore,
|
||||||
|
Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
func(s *terraform.State) error {
|
||||||
|
t.Logf("[INFO] resourceID: %s", resourceID)
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
testCheckResourceExists(resName),
|
||||||
|
resource.TestCheckResourceAttrSet(resName, "id"),
|
||||||
|
//resource.TestCheckResourceAttr(resName, "id", resourceID),
|
||||||
|
resource.TestCheckResourceAttr(resName, "name", updData.Name),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
// check for plan drift after update
|
||||||
|
{
|
||||||
|
Config: exBefore,
|
||||||
|
PlanOnly: true,
|
||||||
|
ExpectNonEmptyPlan: false,
|
||||||
|
},
|
||||||
|
//// Import test
|
||||||
|
//{
|
||||||
|
// ResourceName: resName,
|
||||||
|
// ImportState: true,
|
||||||
|
// ImportStateVerify: true,
|
||||||
|
//},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccCheckExampleResourceDestroy(state *terraform.State) error {
|
||||||
|
//// retrieve the connection established in Provider configuration
|
||||||
|
//conn := testAccProvider.Meta().(*ExampleClient)
|
||||||
|
|
||||||
|
// loop through the resources in state, verifying each widget
|
||||||
|
// is destroyed
|
||||||
|
for _, rs := range state.RootModule().Resources {
|
||||||
|
if rs.Type != resourceString {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(rs.String())
|
||||||
|
// rs.Primary.ID
|
||||||
|
|
||||||
|
//// Retrieve our widget by referencing it's state ID for API lookup
|
||||||
|
//request := &example.DescribeWidgets{
|
||||||
|
// IDs: []string{rs.Primary.ID},
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//response, err := conn.DescribeWidgets(request)
|
||||||
|
//if err == nil {
|
||||||
|
// if len(response.Widgets) > 0 && *response.Widgets[0].ID == rs.Primary.ID {
|
||||||
|
// return fmt.Errorf("Widget (%s) still exists.", rs.Primary.ID)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return nil
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//// If the error is equivalent to 404 not found, the widget is destroyed.
|
||||||
|
//// otherwise return the error
|
||||||
|
//if !strings.Contains(err.Error(), "Widget not found") {
|
||||||
|
// return err
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccResourceExampleConfig(data resData) string {
|
||||||
|
tpl := `
|
||||||
|
resource "stackitprivatepreview_sqlserverflexbeta_instance" "{{ .TfName }}" {
|
||||||
|
project_id = "{{ .ProjectID }}"
|
||||||
|
name = "{{ .Name }}"
|
||||||
|
backup_schedule = "{{ .BackupSchedule }}"
|
||||||
|
retention_days = {{ .RetentionDays }}
|
||||||
|
flavor_id = "{{ .FlavorID }}"
|
||||||
|
storage = {
|
||||||
|
class = "{{ .PerformanceClass }}"
|
||||||
|
size = {{ .Size }}
|
||||||
|
}
|
||||||
|
network = {
|
||||||
|
acl = ["{{ .Acl }}"]
|
||||||
|
access_scope = "{{ .AccessScope }}"
|
||||||
|
}
|
||||||
|
{{ if .WithEncryption }}
|
||||||
|
encryption = {
|
||||||
|
kek_key_id = "{{ .KekKeyId }}"
|
||||||
|
kek_key_ring_id = "{{ .KekKeyRingId }}"
|
||||||
|
kek_key_version = {{ .KekKeyVersion }}
|
||||||
|
service_account = "{{ .KekSaEmail }}"
|
||||||
|
}
|
||||||
|
{{ end }}
|
||||||
|
version = "{{ .Version }}"
|
||||||
|
}
|
||||||
|
`
|
||||||
|
tmpl, err := template.New("").Parse(tpl)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
buff := new(bytes.Buffer)
|
||||||
|
err = tmpl.Execute(buff, data)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
res := fmt.Sprintf(`
|
||||||
|
%[1]s
|
||||||
|
|
||||||
|
%[2]s
|
||||||
|
`,
|
||||||
|
testutil.PostgresFlexProviderConfig(data.ServiceAccountFilePath),
|
||||||
|
buff.String(),
|
||||||
|
)
|
||||||
|
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
|
||||||
|
func testCheckResourceExists(resourceName string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[resourceName]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("resource not found: %s", resourceName)
|
||||||
|
}
|
||||||
|
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("resource ID not set")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify resource exists in the API
|
||||||
|
//client := testAccProvider.Meta().(*APIClient)
|
||||||
|
//_, err := client.GetResource(rs.Primary.ID)
|
||||||
|
//if err != nil {
|
||||||
|
// return fmt.Errorf("error fetching resource: %w", err)
|
||||||
|
//}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testAccGrabResourceID(resourceName string, id *string) resource.TestCheckFunc {
|
||||||
|
return func(s *terraform.State) error {
|
||||||
|
rs, ok := s.RootModule().Resources[resourceName]
|
||||||
|
if !ok {
|
||||||
|
return fmt.Errorf("ressource not found: %s", resourceName)
|
||||||
|
}
|
||||||
|
if rs.Primary.ID == "" {
|
||||||
|
return fmt.Errorf("no ID in state for %s", resourceName)
|
||||||
|
}
|
||||||
|
*id = rs.Primary.ID
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//func setupMockServer() *httptest.Server {
|
||||||
|
// mux := http.NewServeMux()
|
||||||
|
//
|
||||||
|
// mux.HandleFunc("/api/resources", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// switch r.Method {
|
||||||
|
// case http.MethodPost:
|
||||||
|
// w.WriteHeader(http.StatusCreated)
|
||||||
|
// json.NewEncoder(w).Encode(map[string]string{
|
||||||
|
// "id": "mock-id-123",
|
||||||
|
// "name": "test-resource",
|
||||||
|
// })
|
||||||
|
// case http.MethodGet:
|
||||||
|
// w.WriteHeader(http.StatusOK)
|
||||||
|
// json.NewEncoder(w).Encode([]map[string]string{})
|
||||||
|
// }
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// return httptest.NewServer(mux)
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//func TestUnitResourceCreate(t *testing.T) {
|
||||||
|
// server := setupMockServer()
|
||||||
|
// defer server.Close()
|
||||||
|
//
|
||||||
|
// // Configure provider to use mock server URL
|
||||||
|
// os.Setenv("API_ENDPOINT", server.URL)
|
||||||
|
//
|
||||||
|
// // Run unit tests against mock
|
||||||
|
//}
|
||||||
|
|
||||||
|
// type postgresFlexClientMocked struct {
|
||||||
|
// returnError bool
|
||||||
|
// getFlavorsResp *postgresflex.GetFlavorsResponse
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// func (c *postgresFlexClientMocked) ListFlavorsExecute(_ context.Context, _, _ string) (*postgresflex.GetFlavorsResponse, error) {
|
||||||
|
// if c.returnError {
|
||||||
|
// return nil, fmt.Errorf("get flavors failed")
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return c.getFlavorsResp, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
//func TestNewInstanceResource(t *testing.T) {
|
||||||
|
// exData := resData{
|
||||||
|
// Region: "eu01",
|
||||||
|
// ServiceAccountFilePath: sa_file,
|
||||||
|
// ProjectID: project_id,
|
||||||
|
// Name: "testRes",
|
||||||
|
// }
|
||||||
|
// resource.Test(t, resource.TestCase{
|
||||||
|
// ProtoV6ProviderFactories: testutil.TestAccProtoV6ProviderFactories,
|
||||||
|
// Steps: []resource.TestStep{
|
||||||
|
// {
|
||||||
|
// Config: testAccResourceEncryptionExampleConfig(exData),
|
||||||
|
// Check: resource.ComposeAggregateTestCheckFunc(
|
||||||
|
// resource.TestCheckResourceAttr("example_resource.test", "name", exData.Name),
|
||||||
|
// resource.TestCheckResourceAttrSet("example_resource.test", "id"),
|
||||||
|
// ),
|
||||||
|
// },
|
||||||
|
// },
|
||||||
|
// })
|
||||||
|
//
|
||||||
|
// //tests := []struct {
|
||||||
|
// // name string
|
||||||
|
// // want resource.Resource
|
||||||
|
// //}{
|
||||||
|
// // {
|
||||||
|
// // name: "create empty instance resource",
|
||||||
|
// // want: &instanceResource{},
|
||||||
|
// // },
|
||||||
|
// //}
|
||||||
|
// //for _, tt := range tests {
|
||||||
|
// // t.Run(tt.name, func(t *testing.T) {
|
||||||
|
// // if got := NewInstanceResource(); !reflect.DeepEqual(got, tt.want) {
|
||||||
|
// // t.Errorf("NewInstanceResource() = %v, want %v", got, tt.want)
|
||||||
|
// // }
|
||||||
|
// // })
|
||||||
|
// //}
|
||||||
|
//}
|
||||||
|
|
@ -96,7 +96,7 @@ func UpdateInstanceWaitHandler(ctx context.Context, a APIClientInterface, projec
|
||||||
tflog.Info(ctx, "request is being handled", map[string]interface{}{
|
tflog.Info(ctx, "request is being handled", map[string]interface{}{
|
||||||
"status": *s.Status,
|
"status": *s.Status,
|
||||||
})
|
})
|
||||||
return false, nil, nil
|
return false, s, nil
|
||||||
default:
|
default:
|
||||||
tflog.Info(ctx, "Wait (update) received unknown status", map[string]interface{}{
|
tflog.Info(ctx, "Wait (update) received unknown status", map[string]interface{}{
|
||||||
"instanceId": instanceId,
|
"instanceId": instanceId,
|
||||||
|
|
@ -105,17 +105,15 @@ func UpdateInstanceWaitHandler(ctx context.Context, a APIClientInterface, projec
|
||||||
return false, s, nil
|
return false, s, nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
handler.SetSleepBeforeWait(15 * time.Second)
|
|
||||||
handler.SetTimeout(45 * time.Minute)
|
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
// DeleteInstanceWaitHandler will wait for instance deletion
|
// DeleteInstanceWaitHandler will wait for instance deletion
|
||||||
func DeleteInstanceWaitHandler(ctx context.Context, a APIClientInterface, projectId, instanceId, region string) *wait.AsyncActionHandler[struct{}] {
|
func DeleteInstanceWaitHandler(ctx context.Context, a APIClientInterface, projectId, instanceId, region string) *wait.AsyncActionHandler[sqlserverflex.GetInstanceResponse] {
|
||||||
handler := wait.New(func() (waitFinished bool, response *struct{}, err error) {
|
handler := wait.New(func() (waitFinished bool, response *sqlserverflex.GetInstanceResponse, err error) {
|
||||||
_, err = a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
s, err := a.GetInstanceRequestExecute(ctx, projectId, region, instanceId)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return false, nil, nil
|
return false, s, nil
|
||||||
}
|
}
|
||||||
var oapiErr *oapierror.GenericOpenAPIError
|
var oapiErr *oapierror.GenericOpenAPIError
|
||||||
ok := errors.As(err, &oapiErr)
|
ok := errors.As(err, &oapiErr)
|
||||||
|
|
@ -127,7 +125,7 @@ func DeleteInstanceWaitHandler(ctx context.Context, a APIClientInterface, projec
|
||||||
}
|
}
|
||||||
return true, nil, nil
|
return true, nil, nil
|
||||||
})
|
})
|
||||||
handler.SetTimeout(15 * time.Minute)
|
handler.SetTimeout(30 * time.Minute)
|
||||||
return handler
|
return handler
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue