Skip to content

Commit

Permalink
test: including unit testing for search deployments state transition …
Browse files Browse the repository at this point in the history
…logic and model conversions (#1653)

* test: including unit testing for search deployments state transition logic and model conversions adjusting to new file structure

* fix file change detection criteria for search deployment

* adjust naming of files
  • Loading branch information
AgustinBettati committed Nov 27, 2023
1 parent bc94bf7 commit bd446ef
Show file tree
Hide file tree
Showing 9 changed files with 514 additions and 135 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/acceptance-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ jobs:
cluster:
- 'mongodbatlas/**mongodbatlas_cluster**.go'
search_deployment:
- 'mongodbatlas/**search_deployment**.go'
- 'internal/service/searchdeployment/*.go'
generic:
- 'mongodbatlas/data_source_mongodbatlas_backup_compliance_policy*.go'
- 'mongodbatlas/resource_mongodbatlas_backup_compliance_policy*.go'
Expand Down
9 changes: 9 additions & 0 deletions internal/common/retrystrategy/time_config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package retrystrategy

import "time"

type TimeConfig struct {
Timeout time.Duration
MinTimeout time.Duration
Delay time.Duration
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ func (d *searchDeploymentDS) Read(ctx context.Context, req datasource.ReadReques
return
}

newSearchDeploymentModel, diagnostics := newTFSearchDeployment(ctx, clusterName, deploymentResp, nil)
newSearchDeploymentModel, diagnostics := NewTFSearchDeployment(ctx, clusterName, deploymentResp, nil)
resp.Diagnostics.Append(diagnostics...)
if resp.Diagnostics.HasError() {
return
Expand All @@ -89,7 +89,7 @@ func (d *searchDeploymentDS) Read(ctx context.Context, req datasource.ReadReques
resp.Diagnostics.Append(resp.State.Set(ctx, dsModel)...)
}

func convertToDSModel(inputModel *tfSearchDeploymentRSModel) tfSearchDeploymentDSModel {
func convertToDSModel(inputModel *TFSearchDeploymentRSModel) tfSearchDeploymentDSModel {
return tfSearchDeploymentDSModel{
ID: inputModel.ID,
ClusterName: inputModel.ClusterName,
Expand Down
60 changes: 60 additions & 0 deletions internal/service/searchdeployment/model_search_deployment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package searchdeployment

import (
"context"

"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts"
"github.com/hashicorp/terraform-plugin-framework/diag"
"github.com/hashicorp/terraform-plugin-framework/types"
"go.mongodb.org/atlas-sdk/v20231115001/admin"
)

func NewSearchDeploymentReq(ctx context.Context, searchDeploymentPlan *TFSearchDeploymentRSModel) admin.ApiSearchDeploymentRequest {
var specs []TFSearchNodeSpecModel
searchDeploymentPlan.Specs.ElementsAs(ctx, &specs, true)

resultSpecs := make([]admin.ApiSearchDeploymentSpec, len(specs))
for i, spec := range specs {
resultSpecs[i] = admin.ApiSearchDeploymentSpec{
InstanceSize: spec.InstanceSize.ValueString(),
NodeCount: int(spec.NodeCount.ValueInt64()),
}
}

return admin.ApiSearchDeploymentRequest{
Specs: resultSpecs,
}
}

func NewTFSearchDeployment(ctx context.Context, clusterName string, deployResp *admin.ApiSearchDeploymentResponse, timeout *timeouts.Value) (*TFSearchDeploymentRSModel, diag.Diagnostics) {
result := TFSearchDeploymentRSModel{
ID: types.StringPointerValue(deployResp.Id),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringPointerValue(deployResp.GroupId),
StateName: types.StringPointerValue(deployResp.StateName),
}

if timeout != nil {
result.Timeouts = *timeout
}

specsList, diagnostics := types.ListValueFrom(ctx, SpecObjectType, newTFSpecsModel(deployResp.Specs))
if diagnostics.HasError() {
return nil, diagnostics
}

result.Specs = specsList
return &result, nil
}

func newTFSpecsModel(specs []admin.ApiSearchDeploymentSpec) []TFSearchNodeSpecModel {
result := make([]TFSearchNodeSpecModel, len(specs))
for i, v := range specs {
result[i] = TFSearchNodeSpecModel{
InstanceSize: types.StringValue(v.InstanceSize),
NodeCount: types.Int64Value(int64(v.NodeCount)),
}
}

return result
}
118 changes: 118 additions & 0 deletions internal/service/searchdeployment/model_search_deployment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
package searchdeployment_test

import (
"context"
"reflect"
"testing"

"github.com/hashicorp/terraform-plugin-framework/types"
"github.com/hashicorp/terraform-plugin-framework/types/basetypes"
"github.com/mongodb/terraform-provider-mongodbatlas/internal/service/searchdeployment"
"go.mongodb.org/atlas-sdk/v20231115001/admin"
)

type sdkToTFModelTestCase struct {
SDKResp *admin.ApiSearchDeploymentResponse
expectedTFModel *searchdeployment.TFSearchDeploymentRSModel
name string
clusterName string
}

const (
dummyDeploymentID = "111111111111111111111111"
dummyProjectID = "222222222222222222222222"
stateName = "IDLE"
clusterName = "Cluster0"
instanceSize = "S20_HIGHCPU_NVME"
nodeCount = 2
)

func TestSearchDeploymentSDKToTFModel(t *testing.T) {
testCases := []sdkToTFModelTestCase{
{
name: "Complete SDK response",
clusterName: clusterName,
SDKResp: &admin.ApiSearchDeploymentResponse{
Id: admin.PtrString(dummyDeploymentID),
GroupId: admin.PtrString(dummyProjectID),
StateName: admin.PtrString(stateName),
Specs: []admin.ApiSearchDeploymentSpec{
{
InstanceSize: instanceSize,
NodeCount: nodeCount,
},
},
},
expectedTFModel: &searchdeployment.TFSearchDeploymentRSModel{
ID: types.StringValue(dummyDeploymentID),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringValue(dummyProjectID),
StateName: types.StringValue(stateName),
Specs: tfSpecsList(t, instanceSize, nodeCount),
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
resultModel, diags := searchdeployment.NewTFSearchDeployment(context.Background(), tc.clusterName, tc.SDKResp, nil)
if diags.HasError() {
t.Errorf("unexpected errors found: %s", diags.Errors()[0].Summary())
}
if !reflect.DeepEqual(resultModel, tc.expectedTFModel) {
t.Errorf("created terraform model did not match expected output")
}
})
}
}

type tfToSDKModelTestCase struct {
name string
tfModel *searchdeployment.TFSearchDeploymentRSModel
expectedSDKReq admin.ApiSearchDeploymentRequest
}

func TestSearchDeploymentTFModelToSDK(t *testing.T) {
testCases := []tfToSDKModelTestCase{
{
name: "Complete TF state",
tfModel: &searchdeployment.TFSearchDeploymentRSModel{
ID: types.StringValue(dummyDeploymentID),
ClusterName: types.StringValue(clusterName),
ProjectID: types.StringValue(dummyProjectID),
StateName: types.StringValue(stateName),
Specs: tfSpecsList(t, instanceSize, nodeCount),
},
expectedSDKReq: admin.ApiSearchDeploymentRequest{
Specs: []admin.ApiSearchDeploymentSpec{
{
InstanceSize: instanceSize,
NodeCount: nodeCount,
},
},
},
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
apiReqResult := searchdeployment.NewSearchDeploymentReq(context.Background(), tc.tfModel)
if !reflect.DeepEqual(apiReqResult, tc.expectedSDKReq) {
t.Errorf("created sdk model did not match expected output")
}
})
}
}

func tfSpecsList(t *testing.T, instanceSize string, nodeCount int64) basetypes.ListValue {
tfSpecsList, diags := types.ListValueFrom(context.Background(), searchdeployment.SpecObjectType, []searchdeployment.TFSearchNodeSpecModel{
{
InstanceSize: types.StringValue(instanceSize),
NodeCount: types.Int64Value(nodeCount),
},
})
if diags.HasError() {
t.Errorf("failed to create terraform spec lists model: %s", diags.Errors()[0].Summary())
}
return tfSpecsList
}

0 comments on commit bd446ef

Please sign in to comment.