-
Notifications
You must be signed in to change notification settings - Fork 178
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
342 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package pushbasedlogexport_test | ||
|
||
import ( | ||
"context" | ||
"reflect" | ||
"testing" | ||
"time" | ||
|
||
"go.mongodb.org/atlas-sdk/v20231115010/admin" | ||
|
||
"github.com/hashicorp/terraform-plugin-framework-timeouts/resource/timeouts" | ||
"github.com/hashicorp/terraform-plugin-framework/types" | ||
|
||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" | ||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/service/pushbasedlogexport" | ||
) | ||
|
||
var ( | ||
testBucketName = "test-bucket-name" | ||
testIAMRoleID = "661fe3ad234b02027ddee196" | ||
testPrefixPath = "prefix/path" | ||
prefixPathEmpty = "" | ||
testProjectID = "661fe3ad234b02027dabcabc" | ||
) | ||
|
||
type sdkToTFModelTestCase struct { | ||
apiResp *admin.PushBasedLogExportProject | ||
timeout *timeouts.Value | ||
expectedTFModel *pushbasedlogexport.TFPushBasedLogExportRSModel | ||
name string | ||
projectID string | ||
} | ||
|
||
func TestNewTFPushBasedLogExport(t *testing.T) { | ||
currentTime := time.Now() | ||
|
||
testCases := []sdkToTFModelTestCase{ | ||
{ | ||
name: "Complete API response", | ||
projectID: testProjectID, | ||
apiResp: &admin.PushBasedLogExportProject{ | ||
BucketName: admin.PtrString(testBucketName), | ||
CreateDate: admin.PtrTime(currentTime), | ||
IamRoleId: admin.PtrString(testIAMRoleID), | ||
PrefixPath: admin.PtrString(testPrefixPath), | ||
State: admin.PtrString(activeState), | ||
}, | ||
expectedTFModel: &pushbasedlogexport.TFPushBasedLogExportRSModel{ | ||
ProjectID: types.StringValue(testProjectID), | ||
BucketName: types.StringValue(testBucketName), | ||
IamRoleID: types.StringValue(testIAMRoleID), | ||
PrefixPath: types.StringValue(testPrefixPath), | ||
State: types.StringValue(activeState), | ||
CreateDate: types.StringPointerValue(conversion.TimePtrToStringPtr(¤tTime)), | ||
}, | ||
}, | ||
{ | ||
name: "Complete API response with empty prefix path", | ||
projectID: testProjectID, | ||
apiResp: &admin.PushBasedLogExportProject{ | ||
BucketName: admin.PtrString(testBucketName), | ||
CreateDate: admin.PtrTime(currentTime), | ||
IamRoleId: admin.PtrString(testIAMRoleID), | ||
PrefixPath: admin.PtrString(prefixPathEmpty), | ||
State: admin.PtrString(activeState), | ||
}, | ||
expectedTFModel: &pushbasedlogexport.TFPushBasedLogExportRSModel{ | ||
ProjectID: types.StringValue(testProjectID), | ||
BucketName: types.StringValue(testBucketName), | ||
IamRoleID: types.StringValue(testIAMRoleID), | ||
PrefixPath: types.StringValue(prefixPathEmpty), | ||
State: types.StringValue(activeState), | ||
CreateDate: types.StringPointerValue(conversion.TimePtrToStringPtr(¤tTime)), | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
resultModel, _ := pushbasedlogexport.NewTFPushBasedLogExport(context.Background(), tc.projectID, tc.apiResp, tc.timeout) | ||
if !reflect.DeepEqual(resultModel, tc.expectedTFModel) { | ||
t.Errorf("result model does not match expected output: expected %+v, got %+v", tc.expectedTFModel, resultModel) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
type pushBasedLogExportReqTestCase struct { | ||
input *pushbasedlogexport.TFPushBasedLogExportRSModel | ||
expectedCreateReq *admin.CreatePushBasedLogExportProjectRequest | ||
expectedUpdateReq *admin.PushBasedLogExportProject | ||
name string | ||
} | ||
|
||
func TestNewPushBasedLogExportReq(t *testing.T) { | ||
testCases := []pushBasedLogExportReqTestCase{ | ||
{ | ||
name: "Valid TF state", | ||
input: &pushbasedlogexport.TFPushBasedLogExportRSModel{ | ||
BucketName: types.StringValue(testBucketName), | ||
IamRoleID: types.StringValue(testIAMRoleID), | ||
PrefixPath: types.StringValue(testPrefixPath), | ||
}, | ||
expectedCreateReq: &admin.CreatePushBasedLogExportProjectRequest{ | ||
BucketName: testBucketName, | ||
IamRoleId: testIAMRoleID, | ||
PrefixPath: testPrefixPath, | ||
}, | ||
expectedUpdateReq: &admin.PushBasedLogExportProject{ | ||
BucketName: admin.PtrString(testBucketName), | ||
IamRoleId: admin.PtrString(testIAMRoleID), | ||
PrefixPath: admin.PtrString(testPrefixPath), | ||
}, | ||
}, | ||
{ | ||
name: "Valid TF state", | ||
input: &pushbasedlogexport.TFPushBasedLogExportRSModel{ | ||
BucketName: types.StringValue(testBucketName), | ||
IamRoleID: types.StringValue(testIAMRoleID), | ||
PrefixPath: types.StringValue(prefixPathEmpty), | ||
}, | ||
expectedCreateReq: &admin.CreatePushBasedLogExportProjectRequest{ | ||
BucketName: testBucketName, | ||
IamRoleId: testIAMRoleID, | ||
PrefixPath: prefixPathEmpty, | ||
}, | ||
expectedUpdateReq: &admin.PushBasedLogExportProject{ | ||
BucketName: admin.PtrString(testBucketName), | ||
IamRoleId: admin.PtrString(testIAMRoleID), | ||
PrefixPath: admin.PtrString(prefixPathEmpty), | ||
}, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name+" Create", func(t *testing.T) { | ||
createReq := pushbasedlogexport.NewPushBasedLogExportCreateReq(tc.input) | ||
if !reflect.DeepEqual(createReq, tc.expectedCreateReq) { | ||
t.Errorf("Create request does not match expected output: expected %+v, got %+v", tc.expectedCreateReq, createReq) | ||
} | ||
}) | ||
t.Run(tc.name+" Update", func(t *testing.T) { | ||
updateReq := pushbasedlogexport.NewPushBasedLogExportUpdateReq(tc.input) | ||
if !reflect.DeepEqual(updateReq, tc.expectedUpdateReq) { | ||
t.Errorf("Update request does not match expected output: expected %+v, got %+v", tc.expectedUpdateReq, updateReq) | ||
} | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
166 changes: 166 additions & 0 deletions
166
internal/service/pushbasedlogexport/state_transition_test.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
package pushbasedlogexport_test | ||
|
||
import ( | ||
"context" | ||
"errors" | ||
"net/http" | ||
"testing" | ||
"time" | ||
|
||
"go.mongodb.org/atlas-sdk/v20231115010/admin" | ||
"go.mongodb.org/atlas-sdk/v20231115010/mockadmin" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"github.com/stretchr/testify/mock" | ||
|
||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/conversion" | ||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/common/retrystrategy" | ||
"github.com/mongodb/terraform-provider-mongodbatlas/internal/service/pushbasedlogexport" | ||
) | ||
|
||
var ( | ||
activeState = "ACTIVE" | ||
unconfiguredState = "UNCONFIGURED" | ||
initiatingState = "INITIATING" | ||
bucketVerifiedState = "BUCKET_VERIFIED" | ||
assumeRoleFailedState = "ASSUME_ROLE_FAILED" | ||
unknown = "" | ||
sc500 = conversion.IntPtr(500) | ||
currentTime = time.Now() | ||
) | ||
|
||
var testTimeoutConfig = retrystrategy.TimeConfig{ | ||
Timeout: 30 * time.Second, | ||
MinTimeout: 100 * time.Millisecond, | ||
Delay: 0, | ||
} | ||
|
||
type testCase struct { | ||
expectedState *string | ||
name string | ||
mockResponses []response | ||
expectedError bool | ||
} | ||
|
||
func TestPushBasedLogExportStateTransition(t *testing.T) { | ||
testCases := []testCase{ | ||
{ | ||
name: "Successful transition to ACTIVE", | ||
mockResponses: []response{ | ||
{state: &initiatingState}, | ||
{state: &bucketVerifiedState}, | ||
{state: &activeState}, | ||
}, | ||
expectedState: &activeState, | ||
expectedError: false, | ||
}, | ||
{ | ||
name: "Error when transitioning to an unknown state", | ||
mockResponses: []response{ | ||
{state: &initiatingState}, | ||
{state: &assumeRoleFailedState}, | ||
}, | ||
expectedState: nil, | ||
expectedError: true, | ||
}, | ||
{ | ||
name: "Error when API responds with error", | ||
mockResponses: []response{ | ||
{statusCode: sc500, err: errors.New("Internal server error")}, | ||
}, | ||
expectedState: nil, | ||
expectedError: true, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
m := mockadmin.NewPushBasedLogExportApi(t) | ||
m.EXPECT().GetPushBasedLogConfiguration(mock.Anything, mock.Anything).Return(admin.GetPushBasedLogConfigurationApiRequest{ApiService: m}) | ||
|
||
for _, resp := range tc.mockResponses { | ||
modelResp, httpResp, err := resp.get() | ||
m.EXPECT().GetPushBasedLogConfigurationExecute(mock.Anything).Return(modelResp, httpResp, err).Once() | ||
} | ||
resp, err := pushbasedlogexport.WaitStateTransition(context.Background(), testProjectID, m, testTimeoutConfig) | ||
assert.Equal(t, tc.expectedError, err != nil) | ||
assert.Equal(t, responseWithState(tc.expectedState), resp) | ||
}) | ||
} | ||
} | ||
|
||
func TestPushBasedLogExportStateTransitionForDelete(t *testing.T) { | ||
testCases := []testCase{ | ||
{ | ||
name: "Successful transition to UNCONFIGURED from ACTIVE", | ||
mockResponses: []response{ | ||
{state: &activeState}, | ||
{state: &unconfiguredState}, | ||
}, | ||
expectedError: false, | ||
}, | ||
{ | ||
name: "Successful transition to UNCONFIGURED", | ||
mockResponses: []response{ | ||
{state: &unconfiguredState}, | ||
}, | ||
expectedError: false, | ||
}, | ||
{ | ||
name: "Error when API responds with error", | ||
mockResponses: []response{ | ||
{statusCode: sc500, err: errors.New("Internal server error")}, | ||
}, | ||
expectedError: true, | ||
}, | ||
{ | ||
name: "Failed delete when responding with unknown state", | ||
mockResponses: []response{ | ||
{state: &activeState}, | ||
{state: &unknown}, | ||
}, | ||
expectedError: true, | ||
}, | ||
} | ||
|
||
for _, tc := range testCases { | ||
t.Run(tc.name, func(t *testing.T) { | ||
m := mockadmin.NewPushBasedLogExportApi(t) | ||
m.EXPECT().GetPushBasedLogConfiguration(mock.Anything, mock.Anything).Return(admin.GetPushBasedLogConfigurationApiRequest{ApiService: m}) | ||
|
||
for _, resp := range tc.mockResponses { | ||
modelResp, httpResp, err := resp.get() | ||
m.EXPECT().GetPushBasedLogConfigurationExecute(mock.Anything).Return(modelResp, httpResp, err).Once() | ||
} | ||
err := pushbasedlogexport.WaitResourceDelete(context.Background(), testProjectID, m, testTimeoutConfig) | ||
assert.Equal(t, tc.expectedError, err != nil) | ||
}) | ||
} | ||
} | ||
|
||
type response struct { | ||
state *string | ||
statusCode *int | ||
err error | ||
} | ||
|
||
func (r *response) get() (*admin.PushBasedLogExportProject, *http.Response, error) { | ||
var httpResp *http.Response | ||
if r.statusCode != nil { | ||
httpResp = &http.Response{StatusCode: *r.statusCode} | ||
} | ||
return responseWithState(r.state), httpResp, r.err | ||
} | ||
|
||
func responseWithState(state *string) *admin.PushBasedLogExportProject { | ||
if state == nil { | ||
return nil | ||
} | ||
return &admin.PushBasedLogExportProject{ | ||
BucketName: admin.PtrString(testBucketName), | ||
CreateDate: admin.PtrTime(currentTime), | ||
IamRoleId: admin.PtrString(testIAMRoleID), | ||
PrefixPath: admin.PtrString(testPrefixPath), | ||
State: state, | ||
} | ||
} |