From 0b6786ffd037a242e82fc118429cbffbf0dfc120 Mon Sep 17 00:00:00 2001 From: Aashir Siddiqui Date: Fri, 20 Sep 2024 13:41:26 +0100 Subject: [PATCH 1/2] CLI now supports access tokens by loginId Signed-off-by: Aashir Siddiqui --- docs/generated/errors-list.md | 2 + docs/generated/galasactl_auth_tokens_get.md | 3 +- pkg/auth/authTokensGet.go | 80 ++++++-- pkg/auth/authTokensGet_test.go | 92 ++++++++- pkg/cmd/authTokens.go | 2 + pkg/cmd/authTokensGet.go | 13 +- pkg/errors/errorMessage.go | 18 +- test-galasactl-ecosystem.sh | 3 + test-scripts/auth-tests.sh | 217 ++++++++++++++++++++ 9 files changed, 399 insertions(+), 31 deletions(-) create mode 100755 test-scripts/auth-tests.sh diff --git a/docs/generated/errors-list.md b/docs/generated/errors-list.md index 3b75dd85..6ea0a1a6 100644 --- a/docs/generated/errors-list.md +++ b/docs/generated/errors-list.md @@ -160,6 +160,8 @@ The `galasactl` tool can generate the following errors: - GAL1162E: An attempt to delete a run named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are: '{}' - GAL1163E: The run named '{}' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete - GAL1164E: An attempt to delete a run named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in the json format. +- GAL1165E: '{}' is not supported as a valid value. LoginId should not contain spaces. +- GAL1166E: The loginId provided by the --user field cannot be an empty string. - GAL1225E: Failed to open file '{}' cause: {}. Check that this file exists, and that you have read permissions. - GAL1226E: Internal failure. Contents of gzip could be read, but not decoded. New gzip reader failed: file: {} error: {} - GAL1227E: Internal failure. Contents of gzip could not be decoded. {} error: {} diff --git a/docs/generated/galasactl_auth_tokens_get.md b/docs/generated/galasactl_auth_tokens_get.md index 20bfe461..14cfe9f3 100644 --- a/docs/generated/galasactl_auth_tokens_get.md +++ b/docs/generated/galasactl_auth_tokens_get.md @@ -13,7 +13,8 @@ galasactl auth tokens get [flags] ### Options ``` - -h, --help Displays the options for the 'auth tokens get' command. + -h, --help Displays the options for the 'auth tokens get' command. + --user string Optional. Retrieves a list of access tokens for the user with the given username. ``` ### Options inherited from parent commands diff --git a/pkg/auth/authTokensGet.go b/pkg/auth/authTokensGet.go index bf23cbdd..4c9af276 100644 --- a/pkg/auth/authTokensGet.go +++ b/pkg/auth/authTokensGet.go @@ -8,6 +8,8 @@ package auth import ( "context" "log" + "net/http" + "strings" galasaErrors "github.com/galasa-dev/cli/pkg/errors" "github.com/galasa-dev/cli/pkg/galasaapi" @@ -19,38 +21,82 @@ import ( func GetTokens( apiClient *galasaapi.APIClient, console spi.Console, + loginId string, ) error { - authTokens, err := getAuthTokensFromRestApi(apiClient) + authTokens, err := getAuthTokensFromRestApi(apiClient, loginId) if err == nil { - summaryFormatter := tokensformatter.NewTokenSummaryFormatter() + err = formatFetchedTokensAndWriteToConsole(authTokens, console) + } + + return err +} + +func getAuthTokensFromRestApi(apiClient *galasaapi.APIClient, loginId string) ([]galasaapi.AuthToken, error) { + var context context.Context = nil + var authTokens []galasaapi.AuthToken + var err error + + apiCall := apiClient.AuthenticationAPIApi.GetTokens(context) - var outputText string - outputText, err = summaryFormatter.FormatTokens(authTokens) + if loginId != "" { + + loginId, err = validateLoginIdFlag(loginId) if err == nil { - console.WriteString(outputText) + apiCall = apiCall.LoginId(loginId) + } + } + + if err == nil { + + var tokens *galasaapi.AuthTokens + var resp *http.Response + + tokens, resp, err = apiCall.Execute() + + if err != nil { + log.Println("getAuthTokensFromRestApi - Failed to retrieve list of tokens from API server") + err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_RETRIEVING_TOKEN_LIST_FROM_API_SERVER, err.Error()) + } else { + defer resp.Body.Close() + authTokens = tokens.GetTokens() + log.Printf("getAuthTokensFromRestApi - %v tokens collected", len(authTokens)) } } + return authTokens, err +} + +func formatFetchedTokensAndWriteToConsole(authTokens []galasaapi.AuthToken, console spi.Console) error { + + summaryFormatter := tokensformatter.NewTokenSummaryFormatter() + + outputText, err := summaryFormatter.FormatTokens(authTokens) + + if err == nil { + console.WriteString(outputText) + } + return err + } -func getAuthTokensFromRestApi(apiClient *galasaapi.APIClient) ([]galasaapi.AuthToken, error) { - var context context.Context = nil - var authTokens []galasaapi.AuthToken +func validateLoginIdFlag(loginId string) (string, error) { - tokens, resp, err := apiClient.AuthenticationAPIApi.GetTokens(context).Execute() + var err error - if err != nil { - log.Println("getAuthTokensFromRestApi - Failed to retrieve list of tokens from API server") - err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_RETRIEVING_TOKEN_LIST_FROM_API_SERVER, err.Error()) - } else { - defer resp.Body.Close() - authTokens = tokens.GetTokens() - log.Printf("getAuthTokensFromRestApi - %v tokens collected", len(authTokens)) + loginId = strings.TrimSpace(loginId) + hasSpace := strings.Contains(loginId, " ") + + if loginId == "" { + err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_INVALID_USER_FLAG_VALUE) } - return authTokens, err + if hasSpace { + err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_INVALID_LOGIN_ID, loginId) + } + + return loginId, err } diff --git a/pkg/auth/authTokensGet_test.go b/pkg/auth/authTokensGet_test.go index f9813f56..b9a03511 100644 --- a/pkg/auth/authTokensGet_test.go +++ b/pkg/auth/authTokensGet_test.go @@ -61,6 +61,33 @@ func mockAuthTokensServlet(t *testing.T, writer http.ResponseWriter, request *ht body = `{ "tokens":[] }` + } else if state == "missingLoginIdFlag" { + statusCode = 400 + body = `{"error_code": 1155,"error_message": "GAL1155E: The id provided by the --id field cannot be an empty string."}` + } else if state == "invalidLoginIdFlag" { + statusCode = 400 + body = `{"error_code": 1157,"error_message": "GAL1157E: '%s' is not supported as a valid value. Valid value should not contain spaces. A value of 'admin' is valid but 'galasa admin' is not."}` + } else if state == "populatedByLoginId" { + body = `{ + "tokens":[ + { + "token_id":"098234980123-1283182389", + "creation_time":"2023-12-03T18:25:43.511Z", + "owner": { + "login_id":"mcobbett" + }, + "description":"So I can access ecosystem1 from my laptop." + }, + { + "token_id":"8218971d287s1-dhj32er2323", + "creation_time":"2024-03-03T09:36:50.511Z", + "owner": { + "login_id":"mcobbett" + }, + "description":"Automated build of example repo can change CPS properties" + } + ] + }` } else { statusCode = 500 body = `{"error_code": 5000,"error_message": "GAL5000E: Error occured when trying to access the endpoint. Report the problem to your Galasa Ecosystem owner."}` @@ -86,7 +113,7 @@ Total:3 ` //When - err := GetTokens(apiClient, console) + err := GetTokens(apiClient, console, "") //Then assert.Nil(t, err) @@ -104,7 +131,7 @@ func TestNoTokensPathReturnsOk(t *testing.T) { expectedOutput := "Total:0\n" //When - err := GetTokens(apiClient, console) + err := GetTokens(apiClient, console, "") //Then assert.Nil(t, err) @@ -121,10 +148,69 @@ func TestInvalidPathReturnsError(t *testing.T) { console := utils.NewMockConsole() //When - err := GetTokens(apiClient, console) + err := GetTokens(apiClient, console, "admin") //Then assert.NotNil(t, err) assert.Contains(t, err.Error(), "GAL1146E") assert.Contains(t, err.Error(), "Could not get list of tokens from API server") } + +func TestMissingLoginIdFlagReturnsBadRequest(t *testing.T) { + //Given... + serverState := "missingLoginId" + server := NewAuthTokensServletMock(t, serverState) + apiClient := api.InitialiseAPI(server.URL) + defer server.Close() + + console := utils.NewMockConsole() + expectedOutput := `GAL1166E: The loginId provided by the --user field cannot be an empty string.` + + //When + err := GetTokens(apiClient, console, " ") + + //Then + assert.NotNil(t, err) + assert.Equal(t, expectedOutput, err.Error()) +} + +func TestLoginIdWithSpacesReturnsBadRequest(t *testing.T) { + //Given... + serverState := "invalidLoginIdFlag" + server := NewAuthTokensServletMock(t, serverState) + apiClient := api.InitialiseAPI(server.URL) + defer server.Close() + + console := utils.NewMockConsole() + expectedOutput := `GAL1165E: 'galasa admin' is not supported as a valid value. LoginId should not contain spaces.` + + //When + err := GetTokens(apiClient, console, "galasa admin") + + //Then + assert.NotNil(t, err) + assert.Equal(t, expectedOutput, err.Error()) +} + +func TestGetTokensByLoginIdReturnsOK(t *testing.T) { + //Given... + serverState := "populatedByLoginId" + server := NewAuthTokensServletMock(t, serverState) + apiClient := api.InitialiseAPI(server.URL) + defer server.Close() + + console := utils.NewMockConsole() + expectedOutput := `tokenid created(YYYY-MM-DD) user description +098234980123-1283182389 2023-12-03 mcobbett So I can access ecosystem1 from my laptop. +8218971d287s1-dhj32er2323 2024-03-03 mcobbett Automated build of example repo can change CPS properties + +Total:2 +` + + //When + err := GetTokens(apiClient, console, "mcobbett") + + //Then + assert.Nil(t, err) + assert.Equal(t, expectedOutput, console.ReadText()) +} diff --git a/pkg/cmd/authTokens.go b/pkg/cmd/authTokens.go index 3363ff8a..5016c699 100644 --- a/pkg/cmd/authTokens.go +++ b/pkg/cmd/authTokens.go @@ -16,6 +16,7 @@ import ( type AuthTokensCmdValues struct { bootstrap string + loginId string } type AuthTokensCommand struct { @@ -76,3 +77,4 @@ func (cmd *AuthTokensCommand) createAuthTokensCobraCmd( return authTokensCmd, err } + diff --git a/pkg/cmd/authTokensGet.go b/pkg/cmd/authTokensGet.go index 49b583b7..7b32d306 100644 --- a/pkg/cmd/authTokensGet.go +++ b/pkg/cmd/authTokensGet.go @@ -74,6 +74,7 @@ func (cmd *AuthTokensGetCommand) createCobraCmd( var err error + authTokensGetCommandValues := authTokensCommand.Values().(*AuthTokensCmdValues) authGetTokensCobraCmd := &cobra.Command{ Use: "get", Short: "Get a list of authentication tokens", @@ -84,6 +85,7 @@ func (cmd *AuthTokensGetCommand) createCobraCmd( }, } + addLoginIdFlagToAuthTokensGet(authGetTokensCobraCmd, authTokensGetCommandValues) authTokensCommand.CobraCommand().AddCommand(authGetTokensCobraCmd) return authGetTokensCobraCmd, err @@ -133,8 +135,7 @@ func (cmd *AuthTokensGetCommand) executeAuthTokensGet( apiClient, err = authenticator.GetAuthenticatedAPIClient() if err == nil { - // Call to process the command in a unit-testable way. - err = auth.GetTokens(apiClient, console) + err = auth.GetTokens(apiClient, console, authTokenCmdValues.loginId) } } } @@ -142,3 +143,11 @@ func (cmd *AuthTokensGetCommand) executeAuthTokensGet( return err } + +func addLoginIdFlagToAuthTokensGet(cmd *cobra.Command, authTokensGetCmdValues *AuthTokensCmdValues) { + + flagName := "user" + var description string = "Optional. Retrieves a list of access tokens for the user with the given username." + + cmd.Flags().StringVar(&authTokensGetCmdValues.loginId, flagName, "", description) +} diff --git a/pkg/errors/errorMessage.go b/pkg/errors/errorMessage.go index 69206fbd..ed177419 100644 --- a/pkg/errors/errorMessage.go +++ b/pkg/errors/errorMessage.go @@ -250,16 +250,18 @@ var ( 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 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. Sending the delete request to the Galasa service failed. Cause is %v", 1158, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_SERVER_DELETE_RUNS_FAILED = NewMessageType("GAL1158E: An attempt to delete a run named '%s' failed. Sending the delete request to the Galasa service failed. Cause is %v", 1158, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_INVALID_LOGIN_ID = NewMessageType("GAL1165E: '%s' is not supported as a valid value. LoginId should not contain spaces.", 1165, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_INVALID_USER_FLAG_VALUE = NewMessageType("GAL1166E: The loginId provided by the --user field cannot be an empty string.", 1166, STACK_TRACE_NOT_WANTED) - // 4 related but slightly different errors, when an HTTP response arrives from the Galasa server, and we can/can't parse the payload to get the message details out. - GALASA_ERROR_DELETE_RUNS_NO_RESPONSE_CONTENT = NewMessageType("GAL1159E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server.", 1159, STACK_TRACE_NOT_WANTED) - GALASA_ERROR_DELETE_RUNS_RESPONSE_PAYLOAD_UNREADABLE = NewMessageType("GAL1160E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server could not be read. Cause: %s", 1160, STACK_TRACE_NOT_WANTED) - GALASA_ERROR_DELETE_RUNS_UNPARSEABLE_CONTENT = NewMessageType("GAL1161E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in a valid json format. Cause: '%s'", 1161, STACK_TRACE_NOT_WANTED) - GALASA_ERROR_DELETE_RUNS_SERVER_REPORTED_ERROR = NewMessageType("GAL1162E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are: '%s'", 1162, STACK_TRACE_NOT_WANTED) + // 4 related but slightly different errors, when an HTTP response arrives from the Galasa server, and we can/can't parse the payload to get the message details out. + GALASA_ERROR_DELETE_RUNS_NO_RESPONSE_CONTENT = NewMessageType("GAL1159E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server.", 1159, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_DELETE_RUNS_RESPONSE_PAYLOAD_UNREADABLE = NewMessageType("GAL1160E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server could not be read. Cause: %s", 1160, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_DELETE_RUNS_UNPARSEABLE_CONTENT = NewMessageType("GAL1161E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in a valid json format. Cause: '%s'", 1161, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_DELETE_RUNS_SERVER_REPORTED_ERROR = NewMessageType("GAL1162E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are: '%s'", 1162, STACK_TRACE_NOT_WANTED) - GALASA_ERROR_SERVER_DELETE_RUN_NOT_FOUND = NewMessageType("GAL1163E: The run named '%s' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete", 1163, STACK_TRACE_NOT_WANTED) - GALASA_ERROR_DELETE_RUNS_EXPLANATION_NOT_JSON = NewMessageType("GAL1164E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in the json format.", 1164, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_SERVER_DELETE_RUN_NOT_FOUND = NewMessageType("GAL1163E: The run named '%s' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete", 1163, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_DELETE_RUNS_EXPLANATION_NOT_JSON = NewMessageType("GAL1164E: An attempt to delete a run named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in the json format.", 1164, 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) diff --git a/test-galasactl-ecosystem.sh b/test-galasactl-ecosystem.sh index 2b139c14..f95d3414 100755 --- a/test-galasactl-ecosystem.sh +++ b/test-galasactl-ecosystem.sh @@ -114,6 +114,9 @@ properties_tests source ${BASEDIR}/test-scripts/resources-tests.sh --bootstrap "${bootstrap}" resources_tests +source ${BASEDIR}/test-scripts/auth-tests.sh --bootstrap "${bootstrap}" +auth_tests + # Test the hybrid configuration where the local test runs locally, but # draws it's CPS properties from a remote ecosystem via a REST extension. source ${BASEDIR}/test-scripts/test-local-run-remote-cps.sh diff --git a/test-scripts/auth-tests.sh b/test-scripts/auth-tests.sh new file mode 100755 index 00000000..b8545810 --- /dev/null +++ b/test-scripts/auth-tests.sh @@ -0,0 +1,217 @@ +#!/bin/bash + +# +# Copyright contributors to the Galasa project +# +# SPDX-License-Identifier: EPL-2.0 +# +echo "Running script runs-tests.sh" +# This script can be ran locally or executed in a pipeline to test the various built binaries of galasactl +# This script tests the 'galasactl runs submit' command against a test that is in our ecosystem's testcatalog already +# Pre-requesite: the CLI must have been built first so the binaries are present in the /bin directory + +if [[ "$CALLED_BY_MAIN" == "" ]]; then + # Where is this script executing from ? + BASEDIR=$(dirname "$0");pushd $BASEDIR 2>&1 >> /dev/null ;BASEDIR=$(pwd);popd 2>&1 >> /dev/null + export ORIGINAL_DIR=$(pwd) + cd "${BASEDIR}" + + #-------------------------------------------------------------------------- + # + # Set Colors + # + #-------------------------------------------------------------------------- + bold=$(tput bold) + underline=$(tput sgr 0 1) + reset=$(tput sgr0) + + red=$(tput setaf 1) + green=$(tput setaf 76) + white=$(tput setaf 7) + tan=$(tput setaf 202) + blue=$(tput setaf 25) + + #-------------------------------------------------------------------------- + # + # Headers and Logging + # + #-------------------------------------------------------------------------- + underline() { printf "${underline}${bold}%s${reset}\n" "$@" ;} + h1() { printf "\n${underline}${bold}${blue}%s${reset}\n" "$@" ;} + h2() { printf "\n${underline}${bold}${white}%s${reset}\n" "$@" ;} + debug() { printf "${white}%s${reset}\n" "$@" ;} + info() { printf "${white}➜ %s${reset}\n" "$@" ;} + success() { printf "${green}✔ %s${reset}\n" "$@" ;} + error() { printf "${red}✖ %s${reset}\n" "$@" ;} + warn() { printf "${tan}➜ %s${reset}\n" "$@" ;} + bold() { printf "${bold}%s${reset}\n" "$@" ;} + note() { printf "\n${underline}${bold}${blue}Note:${reset} ${blue}%s${reset}\n" "$@" ;} + + #----------------------------------------------------------------------------------------- + # Process parameters + #----------------------------------------------------------------------------------------- + bootstrap="" + + while [ "$1" != "" ]; do + case $1 in + --bootstrap ) shift + bootstrap="$1" + ;; + -h | --help ) usage + exit + ;; + * ) error "Unexpected argument $1" + usage + exit 1 + esac + shift + done + + # Can't really verify that the bootstrap provided is a valid one, but galasactl will pick this up later if not + if [[ "${bootstrap}" == "" ]]; then + export bootstrap="https://prod1-galasa-dev.cicsk8s.hursley.ibm.com/api/bootstrap" + info "No bootstrap supplied. Defaulting the --bootstrap to be ${bootstrap}" + fi + + info "Running tests against ecosystem bootstrap ${bootstrap}" + + #----------------------------------------------------------------------------------------- + # Constants + #----------------------------------------------------------------------------------------- + export GALASA_TEST_NAME_SHORT="local.CoreLocalJava11Ubuntu" + export GALASA_TEST_NAME_LONG="dev.galasa.inttests.core.${GALASA_TEST_NAME_SHORT}" + export GALASA_TEST_RUN_GET_EXPECTED_SUMMARY_LINE_COUNT="4" + export GALASA_TEST_RUN_GET_EXPECTED_DETAILS_LINE_COUNT="13" + export GALASA_TEST_RUN_GET_EXPECTED_RAW_PIPE_COUNT="10" + export GALASA_TEST_RUN_GET_EXPECTED_NUMBER_ARTIFACT_RUNNING_COUNT="10" + +fi + +# generate a random number to append to test names to avoid multiple running at once overriding each other +function get_random_property_name_number { + minimum=100 + maximum=999 + PROP_NUM=$(($minimum + $RANDOM % $maximum)) + echo $PROP_NUM +} + +#----------------------------------------------------------------------------------------- +# Tests +#----------------------------------------------------------------------------------------- + +function auth_tokens_get { + + h2 "Performing auth tokens get without loginId: get..." + + set -o pipefail # Fail everything if anything in the pipeline fails. Else we are just checking the 'tee' return code. + + cmd="${BINARY_LOCATION} auth tokens get \ + --bootstrap $bootstrap \ + --log - + " + + info "Command is: $cmd" + + $cmd + rc=$? + + # We expect a return code of 0 because this is a properly formed auth tokens get command. + if [[ "${rc}" != "0" ]]; then + error "Failed to get access tokens." + exit 1 + fi + + output_file="$ORIGINAL_DIR/temp/auth-get-output.txt" + $cmd | tee $output_file + + if [[ "${rc}" != "0" ]]; then + error "Failed to get access tokens." + exit 1 + fi + + # Check that the previous properties set created a property + cat $output_file | grep "Total:" -q + + success "All access tokens fetched from database successfully." + +} + +function auth_tokens_get_with_missing_loginId_throws_error { + + h2 "Performing auth tokens get with loginId: get..." + loginId="" + + cmd="${BINARY_LOCATION} auth tokens get \ + --user $loginId \ + --bootstrap $bootstrap \ + --log - + " + + info "Command is: $cmd" + + output_file="$ORIGINAL_DIR/temp/auth-get-output.txt" + set -o pipefail # Fail everything if anything in the pipeline fails. Else we are just checking the 'tee' return code. + $cmd | tee $output_file + + rc=$? + if [[ "${rc}" != "1" ]]; then + error "Failed to get access tokens." + exit 1 + fi + + success "galasactl auth tokens get command correctly threw an error due to missing loginId" + +} + +function auth_tokens_get_by_loginId { + + h2 "Performing auth tokens get with loginId: get..." + loginId="Aashir.Siddiqui@ibm.com" + + set -o pipefail # Fail everything if anything in the pipeline fails. Else we are just checking the 'tee' return code. + + cmd="${BINARY_LOCATION} auth tokens get \ + --user $loginId \ + --bootstrap $bootstrap \ + --log - + " + + info "Command is: $cmd" + + $cmd + rc=$? + + # We expect a return code of 0 because this is a properly formed auth tokens get command. + if [[ "${rc}" != "0" ]]; then + error "Failed to create property with name and value used." + exit 1 + fi + + output_file="$ORIGINAL_DIR/temp/auth-get-output.txt" + $cmd | tee $output_file + if [[ "${rc}" != "0" ]]; then + error "Failed to get property with name used: command failed." + exit 1 + fi + + # Check that the previous properties set created a property + cat $output_file | grep "Total: 1" -q + + success "All access tokens by loginId fetched from database successfully." + +} + +#-------------------------------------------------------------------------- + +function auth_tests { + auth_tokens_get + auth_tokens_get_by_loginId + auth_tokens_get_with_missing_loginId_throws_error +} + +# checks if it's been called by main, set this variable if it is +if [[ "$CALLED_BY_MAIN" == "" ]]; then + source $BASEDIR/calculate-galasactl-executables.sh + calculate_galasactl_executable + auth_tests +fi \ No newline at end of file From 54873687e8c3258a8b10f28d2a535bbcf7d270a5 Mon Sep 17 00:00:00 2001 From: Aashir Siddiqui Date: Fri, 20 Sep 2024 15:36:34 +0100 Subject: [PATCH 2/2] Implemented the changes requested Signed-off-by: Aashir Siddiqui --- docs/generated/errors-list.md | 2 +- docs/generated/galasactl_runs_submit_local.md | 2 +- pkg/auth/authTokensGet_test.go | 2 +- pkg/errors/errorMessage.go | 2 +- test-scripts/auth-tests.sh | 67 +++++-------------- 5 files changed, 21 insertions(+), 54 deletions(-) diff --git a/docs/generated/errors-list.md b/docs/generated/errors-list.md index 6ea0a1a6..d3ccc523 100644 --- a/docs/generated/errors-list.md +++ b/docs/generated/errors-list.md @@ -160,7 +160,7 @@ The `galasactl` tool can generate the following errors: - GAL1162E: An attempt to delete a run named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are: '{}' - GAL1163E: The run named '{}' could not be deleted because it was not found by the Galasa service. Try listing runs using 'galasactl runs get' to identify the one you wish to delete - GAL1164E: An attempt to delete a run named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in the json format. -- GAL1165E: '{}' is not supported as a valid value. LoginId should not contain spaces. +- GAL1165E: '{}' is not supported as a valid login ID. Login ID should not contain spaces. - GAL1166E: The loginId provided by the --user field cannot be an empty string. - GAL1225E: Failed to open file '{}' cause: {}. Check that this file exists, and that you have read permissions. - GAL1226E: Internal failure. Contents of gzip could be read, but not decoded. New gzip reader failed: file: {} error: {} diff --git a/docs/generated/galasactl_runs_submit_local.md b/docs/generated/galasactl_runs_submit_local.md index 9c58e085..a3108603 100644 --- a/docs/generated/galasactl_runs_submit_local.md +++ b/docs/generated/galasactl_runs_submit_local.md @@ -17,7 +17,7 @@ galasactl runs submit local [flags] --debug When set (or true) the debugger pauses on startup and tries to connect to a Java debugger. The connection is established using the --debugMode and --debugPort values. --debugMode string The mode to use when the --debug option causes the testcase to connect to a Java debugger. Valid values are 'listen' or 'attach'. 'listen' means the testcase JVM will pause on startup, waiting for the Java debugger to connect to the debug port (see the --debugPort option). 'attach' means the testcase JVM will pause on startup, trying to attach to a java debugger which is listening on the debug port. The default value is 'listen' but can be overridden by the 'galasactl.jvm.local.launch.debug.mode' property in the bootstrap file, which in turn can be overridden by this explicit parameter on the galasactl command. --debugPort uint32 The port to use when the --debug option causes the testcase to connect to a java debugger. The default value used is 2970 which can be overridden by the 'galasactl.jvm.local.launch.debug.port' property in the bootstrap file, which in turn can be overridden by this explicit parameter on the galasactl command. - --galasaVersion string the version of galasa you want to use to run your tests. This should match the version of the galasa obr you built your test bundles against. (default "0.37.0") + --galasaVersion string the version of galasa you want to use to run your tests. This should match the version of the galasa obr you built your test bundles against. (default "0.38.0") --gherkin strings Gherkin feature file URL. Should start with 'file://'. -h, --help Displays the options for the 'runs submit local' command. --localMaven string The url of a local maven repository are where galasa bundles can be loaded from on your local file system. Defaults to your home .m2/repository file. Please note that this should be in a URL form e.g. 'file:///Users/myuserid/.m2/repository', or 'file://C:/Users/myuserid/.m2/repository' diff --git a/pkg/auth/authTokensGet_test.go b/pkg/auth/authTokensGet_test.go index b9a03511..a51c1c2c 100644 --- a/pkg/auth/authTokensGet_test.go +++ b/pkg/auth/authTokensGet_test.go @@ -182,7 +182,7 @@ func TestLoginIdWithSpacesReturnsBadRequest(t *testing.T) { defer server.Close() console := utils.NewMockConsole() - expectedOutput := `GAL1165E: 'galasa admin' is not supported as a valid value. LoginId should not contain spaces.` + expectedOutput := `GAL1165E: 'galasa admin' is not supported as a valid login ID. Login ID should not contain spaces.` //When err := GetTokens(apiClient, console, "galasa admin") diff --git a/pkg/errors/errorMessage.go b/pkg/errors/errorMessage.go index ed177419..598f58c9 100644 --- a/pkg/errors/errorMessage.go +++ b/pkg/errors/errorMessage.go @@ -251,7 +251,7 @@ var ( 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 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. Sending the delete request to the Galasa service failed. Cause is %v", 1158, STACK_TRACE_NOT_WANTED) - GALASA_ERROR_INVALID_LOGIN_ID = NewMessageType("GAL1165E: '%s' is not supported as a valid value. LoginId should not contain spaces.", 1165, STACK_TRACE_NOT_WANTED) + GALASA_ERROR_INVALID_LOGIN_ID = NewMessageType("GAL1165E: '%s' is not supported as a valid login ID. Login ID should not contain spaces.", 1165, STACK_TRACE_NOT_WANTED) GALASA_ERROR_INVALID_USER_FLAG_VALUE = NewMessageType("GAL1166E: The loginId provided by the --user field cannot be an empty string.", 1166, STACK_TRACE_NOT_WANTED) // 4 related but slightly different errors, when an HTTP response arrives from the Galasa server, and we can/can't parse the payload to get the message details out. diff --git a/test-scripts/auth-tests.sh b/test-scripts/auth-tests.sh index b8545810..38dd11d3 100755 --- a/test-scripts/auth-tests.sh +++ b/test-scripts/auth-tests.sh @@ -5,9 +5,9 @@ # # SPDX-License-Identifier: EPL-2.0 # -echo "Running script runs-tests.sh" +echo "Running script auth-tests.sh" # This script can be ran locally or executed in a pipeline to test the various built binaries of galasactl -# This script tests the 'galasactl runs submit' command against a test that is in our ecosystem's testcatalog already +# This script tests the 'galasactl auth tokens get' command against a test that is in our ecosystem's testcatalog already # Pre-requesite: the CLI must have been built first so the binaries are present in the /bin directory if [[ "$CALLED_BY_MAIN" == "" ]]; then @@ -74,32 +74,13 @@ if [[ "$CALLED_BY_MAIN" == "" ]]; then fi info "Running tests against ecosystem bootstrap ${bootstrap}" - - #----------------------------------------------------------------------------------------- - # Constants - #----------------------------------------------------------------------------------------- - export GALASA_TEST_NAME_SHORT="local.CoreLocalJava11Ubuntu" - export GALASA_TEST_NAME_LONG="dev.galasa.inttests.core.${GALASA_TEST_NAME_SHORT}" - export GALASA_TEST_RUN_GET_EXPECTED_SUMMARY_LINE_COUNT="4" - export GALASA_TEST_RUN_GET_EXPECTED_DETAILS_LINE_COUNT="13" - export GALASA_TEST_RUN_GET_EXPECTED_RAW_PIPE_COUNT="10" - export GALASA_TEST_RUN_GET_EXPECTED_NUMBER_ARTIFACT_RUNNING_COUNT="10" - fi -# generate a random number to append to test names to avoid multiple running at once overriding each other -function get_random_property_name_number { - minimum=100 - maximum=999 - PROP_NUM=$(($minimum + $RANDOM % $maximum)) - echo $PROP_NUM -} - #----------------------------------------------------------------------------------------- # Tests #----------------------------------------------------------------------------------------- -function auth_tokens_get { +function auth_tokens_get_all_tokens_without_loginId { h2 "Performing auth tokens get without loginId: get..." @@ -112,25 +93,18 @@ function auth_tokens_get { info "Command is: $cmd" - $cmd - rc=$? - - # We expect a return code of 0 because this is a properly formed auth tokens get command. - if [[ "${rc}" != "0" ]]; then - error "Failed to get access tokens." - exit 1 - fi - output_file="$ORIGINAL_DIR/temp/auth-get-output.txt" $cmd | tee $output_file + rc=$? + # We expect a return code of 0 because this is a properly formed auth tokens get command. if [[ "${rc}" != "0" ]]; then error "Failed to get access tokens." exit 1 fi - # Check that the previous properties set created a property - cat $output_file | grep "Total:" -q + # Checks that the tokens were fetched successfully + cat $output_file | grep "Total: 1" -q success "All access tokens fetched from database successfully." @@ -155,7 +129,7 @@ function auth_tokens_get_with_missing_loginId_throws_error { rc=$? if [[ "${rc}" != "1" ]]; then - error "Failed to get access tokens." + error "Failed to get access tokens due to missing login ID. Bad Request" exit 1 fi @@ -163,10 +137,10 @@ function auth_tokens_get_with_missing_loginId_throws_error { } -function auth_tokens_get_by_loginId { +function auth_tokens_get_all_tokens_by_loginId { h2 "Performing auth tokens get with loginId: get..." - loginId="Aashir.Siddiqui@ibm.com" + loginId="Galasadelivery@ibm.com" set -o pipefail # Fail everything if anything in the pipeline fails. Else we are just checking the 'tee' return code. @@ -177,24 +151,17 @@ function auth_tokens_get_by_loginId { " info "Command is: $cmd" - - $cmd - rc=$? - - # We expect a return code of 0 because this is a properly formed auth tokens get command. - if [[ "${rc}" != "0" ]]; then - error "Failed to create property with name and value used." - exit 1 - fi - output_file="$ORIGINAL_DIR/temp/auth-get-output.txt" + $cmd | tee $output_file + rc=$? + if [[ "${rc}" != "0" ]]; then - error "Failed to get property with name used: command failed." + error "Failed to fetch access tokens by login ID" exit 1 fi - # Check that the previous properties set created a property + # Checks that the tokens were fetched successfully cat $output_file | grep "Total: 1" -q success "All access tokens by loginId fetched from database successfully." @@ -204,9 +171,9 @@ function auth_tokens_get_by_loginId { #-------------------------------------------------------------------------- function auth_tests { - auth_tokens_get - auth_tokens_get_by_loginId + auth_tokens_get_all_tokens_without_loginId auth_tokens_get_with_missing_loginId_throws_error + auth_tokens_get_all_tokens_by_loginId } # checks if it's been called by main, set this variable if it is