Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions apptrust/commands/flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ var commandFlags = map[string][]string{
user,
accessToken,
serverId,
SyncFlag,
},
VersionUpdate: {
url,
Expand Down
5 changes: 4 additions & 1 deletion apptrust/commands/version/rollback_app_version_cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type rollbackAppVersionCommand struct {
version string
requestPayload *model.RollbackAppVersionRequest
fromStage string
sync bool
}

func (rv *rollbackAppVersionCommand) Run() error {
Expand All @@ -31,7 +32,7 @@ func (rv *rollbackAppVersionCommand) Run() error {
return err
}

return rv.versionService.RollbackAppVersion(ctx, rv.applicationKey, rv.version, rv.requestPayload)
return rv.versionService.RollbackAppVersion(ctx, rv.applicationKey, rv.version, rv.requestPayload, rv.sync)
}

func (rv *rollbackAppVersionCommand) ServerDetails() (*coreConfig.ServerDetails, error) {
Expand All @@ -51,6 +52,8 @@ func (rv *rollbackAppVersionCommand) prepareAndRunCommand(ctx *components.Contex
rv.version = ctx.Arguments[1]
rv.fromStage = ctx.Arguments[2]

rv.sync = ctx.GetBoolTFlagValue(commands.SyncFlag)

serverDetails, err := utils.ServerDetailsByFlags(ctx)
if err != nil {
return err
Expand Down
111 changes: 66 additions & 45 deletions apptrust/commands/version/rollback_app_version_cmd_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,57 +13,78 @@ import (
)

func TestRollbackAppVersionCommand_Run(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

serverDetails := &config.ServerDetails{Url: "https://example.com"}
applicationKey := "video-encoder"
version := "1.5.0"
requestPayload := &model.RollbackAppVersionRequest{
FromStage: "qa",
tests := []struct {
name string
applicationKey string
version string
fromStage string
sync bool
mockError error
expectedError bool
}{
{
name: "successful rollback with sync=false",
applicationKey: "video-encoder",
version: "1.5.0",
fromStage: "qa",
sync: false,
mockError: nil,
expectedError: false,
},
{
name: "successful rollback with sync=true",
applicationKey: "test-app",
version: "1.0.0",
fromStage: "qa",
sync: true,
mockError: nil,
expectedError: false,
},
{
name: "failed rollback",
applicationKey: "video-encoder",
version: "1.5.0",
fromStage: "qa",
sync: false,
mockError: errors.New("rollback service error occurred"),
expectedError: true,
},
}

mockVersionService := mockversions.NewMockVersionService(ctrl)
mockVersionService.EXPECT().RollbackAppVersion(gomock.Any(), applicationKey, version, requestPayload).
Return(nil).Times(1)

cmd := &rollbackAppVersionCommand{
versionService: mockVersionService,
serverDetails: serverDetails,
applicationKey: applicationKey,
version: version,
requestPayload: requestPayload,
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()

err := cmd.Run()
assert.NoError(t, err)
}
serverDetails := &config.ServerDetails{Url: "https://example.com"}
requestPayload := &model.RollbackAppVersionRequest{
FromStage: tt.fromStage,
}

func TestRollbackAppVersionCommand_Run_Error(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
mockVersionService := mockversions.NewMockVersionService(ctrl)
mockVersionService.EXPECT().RollbackAppVersion(gomock.Any(), tt.applicationKey, tt.version, requestPayload, tt.sync).
Return(tt.mockError).Times(1)

serverDetails := &config.ServerDetails{Url: "https://example.com"}
applicationKey := "video-encoder"
version := "1.5.0"
requestPayload := &model.RollbackAppVersionRequest{
FromStage: "qa",
}
expectedError := errors.New("rollback service error occurred")
cmd := &rollbackAppVersionCommand{
versionService: mockVersionService,
serverDetails: serverDetails,
applicationKey: tt.applicationKey,
version: tt.version,
requestPayload: requestPayload,
fromStage: tt.fromStage,
sync: tt.sync,
}

mockVersionService := mockversions.NewMockVersionService(ctrl)
mockVersionService.EXPECT().RollbackAppVersion(gomock.Any(), applicationKey, version, requestPayload).
Return(expectedError).Times(1)
err := cmd.Run()

cmd := &rollbackAppVersionCommand{
versionService: mockVersionService,
serverDetails: serverDetails,
applicationKey: applicationKey,
version: version,
requestPayload: requestPayload,
if tt.expectedError {
assert.Error(t, err)
if tt.mockError != nil {
assert.Contains(t, err.Error(), tt.mockError.Error())
}
} else {
assert.NoError(t, err)
}
})
}

err := cmd.Run()
assert.Error(t, err)
assert.Contains(t, err.Error(), "rollback service error occurred")
}
18 changes: 12 additions & 6 deletions apptrust/service/versions/version_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type VersionService interface {
CreateAppVersion(ctx service.Context, request *model.CreateAppVersionRequest) error
PromoteAppVersion(ctx service.Context, applicationKey string, version string, payload *model.PromoteAppVersionRequest, sync bool) error
ReleaseAppVersion(ctx service.Context, applicationKey string, version string, request *model.ReleaseAppVersionRequest, sync bool) error
RollbackAppVersion(ctx service.Context, applicationKey string, version string, request *model.RollbackAppVersionRequest) error
RollbackAppVersion(ctx service.Context, applicationKey string, version string, request *model.RollbackAppVersionRequest, sync bool) error
DeleteAppVersion(ctx service.Context, applicationKey string, version string) error
UpdateAppVersion(ctx service.Context, applicationKey string, version string, request *model.UpdateAppVersionRequest) error
}
Expand Down Expand Up @@ -76,19 +76,25 @@ func (vs *versionService) ReleaseAppVersion(ctx service.Context, applicationKey,
return nil
}

func (vs *versionService) RollbackAppVersion(ctx service.Context, applicationKey, version string, request *model.RollbackAppVersionRequest) error {
func (vs *versionService) RollbackAppVersion(ctx service.Context, applicationKey, version string, request *model.RollbackAppVersionRequest, sync bool) error {
endpoint := fmt.Sprintf("/v1/applications/%s/versions/%s/rollback", applicationKey, version)
response, responseBody, err := ctx.GetHttpClient().Post(endpoint, request, map[string]string{})
response, responseBody, err := ctx.GetHttpClient().Post(endpoint, request, map[string]string{"async": strconv.FormatBool(!sync)})
if err != nil {
return err
}

if response.StatusCode != http.StatusOK && response.StatusCode != http.StatusAccepted {
// Validate status code based on sync mode
expectedStatusCode := http.StatusAccepted
if sync {
expectedStatusCode = http.StatusOK
}

if response.StatusCode != expectedStatusCode {
return fmt.Errorf("failed to rollback app version. Status code: %d. \n%s",
response.StatusCode, responseBody)
}

log.Output("Application version deleted successfully")
log.Output(string(responseBody))
return nil
}

Expand All @@ -114,7 +120,7 @@ func (vs *versionService) UpdateAppVersion(ctx service.Context, applicationKey s
return err
}

if response.StatusCode != http.StatusAccepted {
if response.StatusCode != http.StatusOK {
return fmt.Errorf("failed to update app version. Status code: %d. \n%s",
response.StatusCode, responseBody)
}
Expand Down
42 changes: 34 additions & 8 deletions apptrust/service/versions/version_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -314,7 +314,7 @@ func TestUpdateAppVersion(t *testing.T) {
request: &model.UpdateAppVersionRequest{
Tag: "release/1.2.3",
},
mockResponse: &http.Response{StatusCode: http.StatusAccepted},
mockResponse: &http.Response{StatusCode: http.StatusOK},
mockResponseBody: "{}",
mockError: nil,
expectError: false,
Expand All @@ -327,7 +327,7 @@ func TestUpdateAppVersion(t *testing.T) {
"status": {"rc", "validated"},
},
},
mockResponse: &http.Response{StatusCode: http.StatusAccepted},
mockResponse: &http.Response{StatusCode: http.StatusOK},
mockResponseBody: "{}",
mockError: nil,
expectError: false,
Expand All @@ -338,7 +338,7 @@ func TestUpdateAppVersion(t *testing.T) {
request: &model.UpdateAppVersionRequest{
DeleteProperties: []string{"legacy_param", "toBeDeleted"},
},
mockResponse: &http.Response{StatusCode: http.StatusAccepted},
mockResponse: &http.Response{StatusCode: http.StatusOK},
mockResponseBody: "{}",
mockError: nil,
expectError: false,
Expand All @@ -353,7 +353,7 @@ func TestUpdateAppVersion(t *testing.T) {
},
DeleteProperties: []string{"old_param"},
},
mockResponse: &http.Response{StatusCode: http.StatusAccepted},
mockResponse: &http.Response{StatusCode: http.StatusOK},
mockResponseBody: "{}",
mockError: nil,
expectError: false,
Expand Down Expand Up @@ -422,26 +422,29 @@ func TestRollbackAppVersion(t *testing.T) {
applicationKey string
version string
payload *model.RollbackAppVersionRequest
sync bool
expectedStatus int
expectedError bool
}{
{
name: "successful rollback with 200",
name: "successful rollback with sync=true",
applicationKey: "video-encoder",
version: "1.5.0",
payload: &model.RollbackAppVersionRequest{
FromStage: "qa",
},
sync: true,
expectedStatus: http.StatusOK,
expectedError: false,
},
{
name: "successful rollback with 204",
name: "successful rollback with sync=false",
applicationKey: "video-encoder",
version: "1.5.0",
payload: &model.RollbackAppVersionRequest{
FromStage: "prod",
},
sync: false,
expectedStatus: http.StatusAccepted,
expectedError: false,
},
Expand All @@ -452,9 +455,32 @@ func TestRollbackAppVersion(t *testing.T) {
payload: &model.RollbackAppVersionRequest{
FromStage: "nonexistent",
},
sync: true,
expectedStatus: http.StatusBadRequest,
expectedError: true,
},
{
name: "failed rollback - sync=true but got 202",
applicationKey: "video-encoder",
version: "1.5.0",
payload: &model.RollbackAppVersionRequest{
FromStage: "qa",
},
sync: true,
expectedStatus: http.StatusAccepted,
expectedError: true,
},
{
name: "failed rollback - sync=false but got 200",
applicationKey: "video-encoder",
version: "1.5.0",
payload: &model.RollbackAppVersionRequest{
FromStage: "prod",
},
sync: false,
expectedStatus: http.StatusOK,
expectedError: true,
},
}

for _, tt := range tests {
Expand All @@ -467,11 +493,11 @@ func TestRollbackAppVersion(t *testing.T) {
mockCtx.EXPECT().GetHttpClient().Return(mockClient)

expectedEndpoint := "/v1/applications/" + tt.applicationKey + "/versions/" + tt.version + "/rollback"
mockClient.EXPECT().Post(expectedEndpoint, tt.payload, map[string]string{}).
mockClient.EXPECT().Post(expectedEndpoint, tt.payload, map[string]string{"async": strconv.FormatBool(!tt.sync)}).
Return(&http.Response{StatusCode: tt.expectedStatus}, []byte(""), nil)

service := NewVersionService()
err := service.RollbackAppVersion(mockCtx, tt.applicationKey, tt.version, tt.payload)
err := service.RollbackAppVersion(mockCtx, tt.applicationKey, tt.version, tt.payload, tt.sync)

if tt.expectedError {
assert.Error(t, err)
Expand Down