Skip to content

Commit

Permalink
Add initial unit tests for runs delete
Browse files Browse the repository at this point in the history
Signed-off-by: Eamonn Mansour <[email protected]>
  • Loading branch information
eamansour committed Sep 2, 2024
1 parent fd1bf6d commit 87efb62
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 97 deletions.
2 changes: 1 addition & 1 deletion docs/generated/galasactl_runs.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ Assembles, submits and monitors test runs in Galasa Ecosystem

* [galasactl](galasactl.md) - CLI for Galasa
* [galasactl runs cancel](galasactl_runs_cancel.md) - cancel an active run in the ecosystem
* [galasactl runs delete](galasactl_runs_delete.md) - Get the details of a test runname which ran or is running.
* [galasactl runs delete](galasactl_runs_delete.md) - Delete a named test run.
* [galasactl runs download](galasactl_runs_download.md) - Download the artifacts of a test run which ran.
* [galasactl runs get](galasactl_runs_get.md) - Get the details of a test runname which ran or is running.
* [galasactl runs prepare](galasactl_runs_prepare.md) - prepares a list of tests
Expand Down
6 changes: 3 additions & 3 deletions docs/generated/galasactl_runs_delete.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## galasactl runs delete

Get the details of a test runname which ran or is running.
Delete a named test run.

### Synopsis

Get the details of a test runname which ran or is running, displaying the results to the caller.
Delete a named test run.

```
galasactl runs delete [flags]
Expand All @@ -14,7 +14,7 @@ galasactl runs delete [flags]

```
-h, --help Displays the options for the 'runs delete' command.
--name string the name of the test run we want to delete. Cannot be used in conjunction with --requestor, --result or --active flags
--name string the name of the test run we want to delete.
```

### Options inherited from parent commands
Expand Down
2 changes: 1 addition & 1 deletion pkg/cmd/runsDelete.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
)

// Objective: Allow the user to do this:
// run get --runname 12345
// runs delete --name 12345
// And then show the results in a human-readable form.

// Variables set by cobra's command-line parsing.
Expand Down
6 changes: 4 additions & 2 deletions pkg/errors/errorMessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -249,8 +249,10 @@ var (
GALASA_ERROR_INVALID_TOKEN_ID_FORMAT = NewMessageType("GAL1154E: The provided token ID, '%s', does not match formatting requirements. The token ID can contain any character in the 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), or '_' (underscore) ranges only.", 1154, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_MISSING_USER_LOGIN_ID_FLAG = NewMessageType("GAL1155E: The id provided by the --id field cannot be an empty string.", 1155, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_LOGIN_ID_NOT_SUPPORTED = NewMessageType("GAL1156E: '%s' is not supported as a valid value. Valid values are 'me'.", 1156, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUN_FAILED = NewMessageType("GAL1157E: An attempt to delete a run failed. Cause is %s", 1157, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_SERVER_DELETE_RUNS_FAILED = NewMessageType("GAL1158E: An attempt to delete a run failed. The server responded with an error. Cause is %s", 1158, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUN_FAILED = NewMessageType("GAL1157E: An attempt to delete a run named '%s' failed. Cause is %s", 1157, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_SERVER_DELETE_RUNS_FAILED = NewMessageType("GAL1158E: An attempt to delete a run named '%s' failed. The server responded with an error. Cause is %s", 1158, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_NO_RESPONSE_CONTENT = NewMessageType("GAL1159E: Failed to delete a run named '%s'. The server responded with an unexpected status code '%v' and did not contain any content. Cause is %s", 1159, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_RUNS_BADLY_FORMATTED = NewMessageType("GAL1159E: Failed to delete a run named '%s'. The server responded with an unexpected status code '%v' and did not contain any content. Cause is %s", 1159, STACK_TRACE_NOT_WANTED)

// Warnings...
GALASA_WARNING_MAVEN_NO_GALASA_OBR_REPO = NewMessageType("GAL2000W: Warning: Maven configuration file settings.xml should contain a reference to a Galasa repository so that the galasa OBR can be resolved. The official release repository is '%s', and 'pre-release' repository is '%s'", 2000, STACK_TRACE_WANTED)
Expand Down
133 changes: 67 additions & 66 deletions pkg/runs/runsDelete.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ package runs

import (
"context"
"io"
"log"
"net/http"
"strconv"

"github.com/galasa-dev/cli/pkg/embedded"
galasaErrors "github.com/galasa-dev/cli/pkg/errors"
"github.com/galasa-dev/cli/pkg/galasaapi"
"github.com/galasa-dev/cli/pkg/spi"
Expand Down Expand Up @@ -48,6 +49,8 @@ func RunsDelete(

if err == nil {
err = deleteRuns(runs, apiClient)
} else {
console.WriteString(err.Error())
}
}
log.Printf("RunsDelete exiting. err is %v\n", err)
Expand All @@ -65,80 +68,78 @@ func deleteRuns(

var httpResponse *http.Response

for _, run := range runs {
runId := *run.RunId

apicall := apiClient.ResultArchiveStoreAPIApi.DeleteRasRunById(context, runId).ClientApiVersion(restApiVersion)
httpResponse, err = apicall.Execute()

// 200-299 http status codes manifest in an error.
if err != nil {
if httpResponse == nil {
// We never got a response, error sending it or something ?
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_SERVER_DELETE_RUNS_FAILED, err.Error())
} else {

contentType := httpResponse.Header.Get("Content-Type")
if contentType == "" {
// There is no content in the response
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_SERVER_DELETE_RUNS_FAILED, strconv.Itoa(httpResponse.StatusCode))
restApiVersion, err = embedded.GetGalasactlRestApiVersion()
if err == nil {
for _, run := range runs {
runId := run.GetRunId()
// runName := *run.GetTestStructure().RunName

apicall := apiClient.ResultArchiveStoreAPIApi.DeleteRasRunById(context, runId).ClientApiVersion(restApiVersion)
httpResponse, err = apicall.Execute()

// 200-299 http status codes manifest in an error.
if err != nil {
if httpResponse == nil {
// We never got a response, error sending it or something ?
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_SERVER_DELETE_RUNS_FAILED, err.Error())
} else {
// There is content in the response.
// Process the error response payload.
// err = convertToGalasaError(
// httpResponse,
// runName,
// GALASA_ERROR_DELETE_RUNS_NO_RESPONSE_CONTENT,
// GALASA_ERROR_DELETE_RUN_FAILED,

// TODO: Fix this bit.
// httpResponse.Body
// GetApiErrorFromResponse()
// )
}
}

if err != nil {
break
} else {
log.Printf("Run runId:%s runName: %s was deleted OK.\n", runId, run.TestStructure.GetRunName())
}
}
}

return err
}

func convertToGalasaError(
response *http.Response,
identifier string,
errorMsgUnexpectedStatusCodeNoResponseBody *galasaErrors.MessageType,
errorMsgUnableToReadResponseBody *galasaErrors.MessageType,
errorMsgReceivedFromApiServer *galasaErrors.MessageType,
errorMsgResponsePayloadInWrongFormat *galasaErrors.MessageType,
) error {
defer response.Body.Close()
var err error
var responseBodyBytes []byte
statusCode := response.StatusCode

if response.ContentLength == 0 {
log.Printf("Failed - HTTP response - status code: '%v'\n", statusCode)
err = galasaErrors.NewGalasaError(errorMsgUnexpectedStatusCodeNoResponseBody, identifier, statusCode)
} else {

responseBodyBytes, err = io.ReadAll(response.Body)
if err != nil {
break
err = galasaErrors.NewGalasaError(errorMsgUnableToReadResponseBody, identifier, statusCode, err.Error())
} else {
log.Printf("Run runId:%s runName: %s was deleted OK.\n", runId, run.TestStructure.GetRunName())

var errorFromServer *galasaErrors.GalasaAPIError
errorFromServer, err = galasaErrors.GetApiErrorFromResponse(responseBodyBytes)

if err != nil {
//unable to parse response into api error. It should have been json.
log.Printf("Failed - HTTP response - status code: '%v' payload in response is not json: '%v' \n", statusCode, string(responseBodyBytes))
err = galasaErrors.NewGalasaError(errorMsgResponsePayloadInWrongFormat, identifier, statusCode)
} else {
// server returned galasa api error structure we understand.
log.Printf("Failed - HTTP response - status code: '%v' server responded with error message: '%v' \n", statusCode, errorMsgReceivedFromApiServer)
err = galasaErrors.NewGalasaError(errorMsgReceivedFromApiServer, identifier, errorFromServer.Message)
}
}
}

return err
}

// func convertToGalasaError(
// response *http.Response,
// identifier string,
// errorMsgUnexpectedStatusCodeNoResponseBody *galasaErrors.MessageType,
// errorMsgUnableToReadResponseBody *galasaErrors.MessageType,
// msg3 *galasaErrors.MessageType,
// errorMsgResponsePayloadInWrongFormat *galasaErrors.MessageType,
// ) error {
// defer response.Body.Close()
// var err error
// var responseBodyBytes []byte
// statusCode := response.StatusCode

// if response.ContentLength == 0 {
// log.Printf("Failed - HTTP response - status code: '%v'\n", statusCode)
// err = galasaErrors.NewGalasaError(errorMsgUnexpectedStatusCodeNoResponseBody, identifier, statusCode)
// } else {

// responseBodyBytes, err = io.ReadAll(response.Body)
// if err != nil {
// err = galasaErrors.NewGalasaError(errorMsgUnableToReadResponseBody, identifier, statusCode, err.Error())
// } else {

// var errorFromServer *galasaErrors.GalasaAPIError
// errorFromServer, err = galasaErrors.GetApiErrorFromResponse(responseBodyBytes)

// if err != nil {
// //unable to parse response into api error. It should have been json.
// log.Printf("Failed - HTTP response - status code: '%v' payload in response is not json: '%v' \n", statusCode, string(responseBodyBytes))
// err = galasaErrors.NewGalasaError(errorMsgResponsePayloadInWrongFormat, identifier, statusCode)
// } else {
// // server returned galasa api error structure we understand.
// log.Printf("Failed - HTTP response - status code: '%v' server responded with error message: '%v' \n", statusCode,errorMsg)
// err = galasaErrors.NewGalasaError(errorMsg, identifier, errorFromServer.Message)
// }
// }
// }
// return err
// }
103 changes: 79 additions & 24 deletions pkg/runs/runsDelete_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,23 @@
package runs

import (
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

"github.com/galasa-dev/cli/pkg/api"
"github.com/galasa-dev/cli/pkg/galasaapi"
"github.com/galasa-dev/cli/pkg/utils"
"github.com/stretchr/testify/assert"
)

func NewRunsDeleteServletMock(
t *testing.T,
runName string,
runId string,
runResultStrings []string,
runResultJsonStrings []string,
deleteRunStatusCode int,
) *httptest.Server {

server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, req *http.Request) {
Expand All @@ -26,40 +31,90 @@ func NewRunsDeleteServletMock(
acceptHeader := req.Header.Get("Accept")
if req.URL.Path == "/ras/runs" {
assert.Equal(t, "application/json", acceptHeader, "Expected Accept: application/json header, got: %s", acceptHeader)
WriteMockRasRunsResponse(t, writer, req, runName, runResultStrings)
WriteMockRasRunsResponse(t, writer, req, runName, runResultJsonStrings)
} else if req.URL.Path == "/ras/runs/"+runId {
assert.Equal(t, "application/json", acceptHeader, "Expected Accept: application/json header, got: %s", acceptHeader)
WriteMockRasRunsPutStatusQueuedResponse(t, writer, req, runName)
WriteMockRasRunsDeleteResponse(t, writer, req, runName, deleteRunStatusCode)
}
}))

return server
}

// func TestCanDeleteARun(t *testing.T) {
// //Given
// runs := make([]galasaapi.Run, 0)
func WriteMockRasRunsDeleteResponse(
t *testing.T,
writer http.ResponseWriter,
req *http.Request,
runName string,
statusCode int) {

writer.WriteHeader(statusCode)

}

func createMockRun(runName string) galasaapi.Run {
run := *galasaapi.NewRun()
run.SetRunId(runName)
testStructure := *galasaapi.NewTestStructure()
testStructure.SetRunName(runName)

run.SetTestStructure(testStructure)
return run
}

// server := httptest.NewServer(http.HandlerFunc(func(writer http.ResponseWriter, req *http.Request) {
// assert.NotEmpty(t, req.Header.Get("ClientApiVersion"))
// }))
func TestCanDeleteARun(t *testing.T) {
// Given...
runName := "J20"

// runName := "J20"
// Create the mock run to be deleted
runToDelete := createMockRun(runName)
runToDeleteBytes, _ := json.Marshal(runToDelete)
runToDeleteJson := string(runToDeleteBytes)

// //When
// console := NewMockConsole()
// apiServerUrl := server.URL
// apiClient := api.InitialiseAPI(apiServerUrl)
// mockTimeService := utils.NewMockTimeService()
server := NewRunsDeleteServletMock(t, runName, runName, []string{ runToDeleteJson }, 204)

// err := RunsDelete(
// runName,
// console,
// apiServerUrl,
// apiClient,
// mockTimeService)
console := utils.NewMockConsole()
apiServerUrl := server.URL
apiClient := api.InitialiseAPI(apiServerUrl)
mockTimeService := utils.NewMockTimeService()

// //Then
// assert.NotNil(t, err, "RunsDelete returned an unexpected error %s", err.Error)
// When...
err := RunsDelete(
runName,
console,
apiServerUrl,
apiClient,
mockTimeService)

// }
// Then...
assert.Nil(t, err, "RunsDelete returned an unexpected error")
assert.Empty(t, console.ReadText(), "The console was written to on a successful deletion, it should be empty")
}

func TestDeleteNonExistantRunDisplaysError(t *testing.T) {
// Given...
nonExistantRunName := "run-does-not-exist"

existingRunName := "J20"
existingRun := createMockRun(existingRunName)
existingRunBytes, _ := json.Marshal(existingRun)
existingRunJson := string(existingRunBytes)

server := NewRunsDeleteServletMock(t, nonExistantRunName, nonExistantRunName, []string{ existingRunJson }, 404)

console := utils.NewMockConsole()
apiServerUrl := server.URL
apiClient := api.InitialiseAPI(apiServerUrl)
mockTimeService := utils.NewMockTimeService()

// When...
err := RunsDelete(
nonExistantRunName,
console,
apiServerUrl,
apiClient,
mockTimeService)

// Then...
assert.NotNil(t, err, "RunsDelete did not return an error but it should have")
}

0 comments on commit 87efb62

Please sign in to comment.