Skip to content

Commit

Permalink
CLI now returns and filter test on group name (#321)
Browse files Browse the repository at this point in the history
* CLI now returns and filter test on group name

Signed-off-by: Aashir Siddiqui <[email protected]>

* Added validation for group name

Signed-off-by: Aashir Siddiqui <[email protected]>

* Added unit test

Signed-off-by: Aashir Siddiqui <[email protected]>

* Added a unit test for checking mutually exclusive flags

Signed-off-by: Aashir Siddiqui <[email protected]>

* Updated integration tests

Signed-off-by: Aashir Siddiqui <[email protected]>

* review: Formatting fixes, revert unwanted changes

Signed-off-by: Eamonn Mansour <[email protected]>

* review: Add group validation, stop erroring out when --age is not given with --group

Signed-off-by: Eamonn Mansour <[email protected]>

* Restore ecosystem script constants and add group name validation test

Signed-off-by: Eamonn Mansour <[email protected]>

* Add group to more unit tests

Signed-off-by: Eamonn Mansour <[email protected]>

* Add group to runs submit output, add runs get --group ecosystem tests

Signed-off-by: Eamonn Mansour <[email protected]>

* Empty commit to kick off build

Signed-off-by: Eamonn Mansour <[email protected]>

* Create RunsQuery struct to store run query parameters and get pages of runs

Signed-off-by: Eamonn Mansour <[email protected]>

* Replace Latin-1 validation for group and secret names with alphanumeric + dashes and underscores

Signed-off-by: Eamonn Mansour <[email protected]>

* Update role name validation to use common name validation function

Signed-off-by: Eamonn Mansour <[email protected]>

---------

Signed-off-by: Aashir Siddiqui <[email protected]>
Signed-off-by: Eamonn Mansour <[email protected]>
Co-authored-by: Eamonn Mansour <[email protected]>
  • Loading branch information
aashir21 and eamansour authored Jan 13, 2025
1 parent e486b86 commit ab2af78
Show file tree
Hide file tree
Showing 33 changed files with 757 additions and 481 deletions.
7 changes: 4 additions & 3 deletions docs/generated/errors-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ The `galasactl` tool can generate the following errors:
- GAL1076E: Badly formed from or to value '{}' specified in the age parameter. The value could not be converted into an integer value.
- GAL1077E: Invalid value '{}' detected for age parameter. The 'from' value must be greater than the 'to' value.
- GAL1078E: Badly formed '--age' parameter value '{}' specified. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be {}. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
- GAL1079E: The --age or the --name parameter must be used to identify which test run(s) you want see. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
- GAL1079E: The --age, --name, or --group parameter must be used to identify which test run(s) you want see. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
- GAL1080E: Invalid 'from' value '{}' in the '--age' parameter. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be {}. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
- GAL1081E: Unable use a negative value '{}' in the '--age' parameter. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be {}. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
- GAL1082E: Invalid time unit specified '{}' in the '--age' parameter. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be {}. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
Expand All @@ -105,6 +105,7 @@ The `galasactl` tool can generate the following errors:
- GAL1102E: name '{}' is invalid. '--name' is a mandatory flag for this command. Use the --help flag for more information, or refer to the documentation at https://galasa.dev/docs/reference/cli-commands.
- GAL1103E: Could not query CPS results. Reason: '{}'
- GAL1104E: Unable to delete the bearer token file '{}'.
- GAL1105E: Invalid group name provided. Group names must only contain characters in the following ranges: 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), '_' (underscore).
- GAL1106E: Could not get security bearer token from API server. Reason: '{}'. Ensure you have allocated a personal access token and configured your client program by setting your GALASA_TOKEN as an environment variable or by storing it in your galasactl.properties file
- GAL1107E: Could not get security bearer token from file '{}'. Reason: '{}'. Ensure you are authenticated by running 'galasactl auth login' and that your personal access token has not expired or been revoked
- GAL1108E: Invalid bearer token. Ensure you are authenticated by running 'galasactl auth login' and that your personal access token has not expired or been revoked
Expand Down Expand Up @@ -167,7 +168,7 @@ The `galasactl` tool can generate the following errors:
- GAL1169E: An attempt to delete a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in a valid json format. Cause: '{}'
- GAL1170E: An attempt to delete a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are: '{}'
- GAL1171E: An attempt to delete a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server are not in the json format.
- GAL1172E: Invalid secret name provided. The name provided with the --name flag cannot be empty, contain spaces or dots (.), and must only contain characters in the Latin-1 character set.
- GAL1172E: Invalid secret name provided. The name provided with the --name flag cannot be empty and must only contain characters in the following ranges: 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), '_' (underscore).
- GAL1173E: An attempt to delete a secret named '{}' failed. Sending the delete request to the Galasa service failed. Cause is {}
- GAL1174E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server.
- GAL1175E: An attempt to get a secret named '{}' failed. Unexpected http status code {} received from the server. Error details from the server could not be read. Cause: {}
Expand Down Expand Up @@ -204,7 +205,7 @@ The `galasactl` tool can generate the following errors:
- GAL1206E: Failed to get roles. Unexpected http status code {} received from the server. Error details from the server are not in a valid json format. Cause: '{}'
- GAL1207E: Failed to get roles. Unexpected http status code {} received from the server. Error details from the server are: '{}'
- GAL1208E: Failed to get roles. Unexpected http status code {} received from the server. Error details from the server are not in the json format.
- GAL1209E: Invalid role name provided. The name provided with the --name flag cannot be empty, contain spaces or dots (.), and must only contain characters in the Latin-1 character set.
- GAL1209E: Invalid role name provided. The name provided with the --name flag cannot be empty and must only contain characters in the following ranges: 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), '_' (underscore).
- GAL1210E: Role name {} is not known on the Galasa service.
- 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: {}
Expand Down
1 change: 1 addition & 0 deletions docs/generated/galasactl_runs_get.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ galasactl runs get [flags]
--active parameter to retrieve runs that have not finished yet. Cannot be used in conjunction with --name or --result flag.
--age string the age of the test run(s) we want information about. Supported formats are: 'FROM' or 'FROM:TO', where FROM and TO are each ages, made up of an integer and a time-unit qualifier. Supported time-units are 'w' (weeks), 'd' (days), 'h' (hours), 'm' (minutes). If missing, the TO part is defaulted to '0h'. Examples: '--age 1d', '--age 6h:1h' (list test runs which happened from 6 hours ago to 1 hour ago). The TO part must be a smaller time-span than the FROM part.
--format string output format for the data returned. Supported formats are: 'details', 'raw', 'summary'. (default "summary")
--group string the name of the group to return tests under that group. Cannot be used in conjunction with --name
-h, --help Displays the options for the 'runs get' command.
--name string the name of the test run we want information about. Cannot be used in conjunction with --requestor, --result or --active flags
--requestor string the requestor of the test run we want information about. Cannot be used in conjunction with --name flag.
Expand Down
5 changes: 5 additions & 0 deletions pkg/cmd/runsGet.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ type RunsGetCmdValues struct {
requestor string
result string
isActiveRuns bool
group string
}

type RunsGetCommand struct {
Expand Down Expand Up @@ -93,6 +94,8 @@ func (cmd *RunsGetCommand) createCobraCommand(
formatters := runs.GetFormatterNamesString(runs.CreateFormatters())
runsGetCobraCmd.PersistentFlags().StringVar(&cmd.values.runName, "name", "", "the name of the test run we want information about."+
" Cannot be used in conjunction with --requestor, --result or --active flags")
runsGetCobraCmd.PersistentFlags().StringVar(&cmd.values.group, "group", "", "the name of the group to return tests under that group."+
" Cannot be used in conjunction with --name")
runsGetCobraCmd.PersistentFlags().StringVar(&cmd.values.age, "age", "", "the age of the test run(s) we want information about. Supported formats are: 'FROM' or 'FROM:TO', where FROM and TO are each ages,"+
" made up of an integer and a time-unit qualifier. Supported time-units are "+units+". If missing, the TO part is defaulted to '0h'. Examples: '--age 1d',"+
" '--age 6h:1h' (list test runs which happened from 6 hours ago to 1 hour ago)."+
Expand All @@ -109,6 +112,7 @@ func (cmd *RunsGetCommand) createCobraCommand(
runsGetCobraCmd.MarkFlagsMutuallyExclusive("name", "result")
runsGetCobraCmd.MarkFlagsMutuallyExclusive("name", "active")
runsGetCobraCmd.MarkFlagsMutuallyExclusive("result", "active")
runsGetCobraCmd.MarkFlagsMutuallyExclusive("group", "name")

runsCommand.CobraCommand().AddCommand(runsGetCobraCmd)

Expand Down Expand Up @@ -165,6 +169,7 @@ func (cmd *RunsGetCommand) executeRunsGet(
cmd.values.result,
cmd.values.isActiveRuns,
cmd.values.outputFormatString,
cmd.values.group,
timeService,
console,
apiServerUrl,
Expand Down
36 changes: 36 additions & 0 deletions pkg/cmd/runsGet_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,25 @@ func TestRunsGetNameFlagReturnsOk(t *testing.T) {
assert.Contains(t, cmd.Values().(*RunsGetCmdValues).runName, "gerald")
}

func TestRunsGetGroupFlagReturnsOk(t *testing.T) {
// Given...
factory := utils.NewMockFactory()
commandCollection, cmd := setupTestCommandCollection(COMMAND_NAME_RUNS_GET, factory, t)

var args []string = []string{"runs", "get", "--group", "someGroup"}

// When...
err := commandCollection.Execute(args)

// Then...
assert.Nil(t, err)

// Check what the user saw was reasonable
checkOutput("", "", factory, t)

assert.Contains(t, cmd.Values().(*RunsGetCmdValues).group, "someGroup")
}

func TestRunsGetageFlagReturnsOk(t *testing.T) {
// Given...
factory := utils.NewMockFactory()
Expand Down Expand Up @@ -297,3 +316,20 @@ func TestRunsGetResultActiveMutuallyExclusive(t *testing.T) {
// Check what the user saw is reasonable.
checkOutput("", "Error: if any flags in the group [result active] are set none of the others can be; [active result] were all set", factory, t)
}

func TestRunsGetGroupRunNameMutuallyExclusive(t *testing.T) {
// Given...
factory := utils.NewMockFactory()

var args []string = []string{"runs", "get", "--group", "group-1", "--name", "CV123"}

// When...
err := Execute(factory, args)

// Then...
assert.NotNil(t, err)
assert.Contains(t, err.Error(), "if any flags in the group [group name] are set none of the others can be; [group name] were all set")

// Check what the user saw is reasonable.
checkOutput("", "Error: if any flags in the group [group name] are set none of the others can be; [group name] were all set", factory, t)
}
7 changes: 4 additions & 3 deletions pkg/errors/errorMessage.go
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ var (
GALASA_ERROR_INVALID_FROM_OR_TO_PARAMETER = NewMessageType("GAL1076E: Badly formed from or to value '%s' specified in the age parameter. The value could not be converted into an integer value.", 1076, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_FROM_AGE_SMALLER_THAN_TO_AGE = NewMessageType("GAL1077E: Invalid value '%s' detected for age parameter. The 'from' value must be greater than the 'to' value.", 1077, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_AGE_PARAMETER = NewMessageType("GAL1078E: Badly formed '--age' parameter value '%s' specified. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be %s. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified."+SEE_COMMAND_REFERENCE, 1078, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_NO_RUNNAME_OR_AGE_SPECIFIED = NewMessageType("GAL1079E: The --age or the --name parameter must be used to identify which test run(s) you want see."+SEE_COMMAND_REFERENCE, 1079, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_NO_TEST_RUN_IDENTIFIER_FLAG_SPECIFIED = NewMessageType("GAL1079E: The --age, --name, or --group parameter must be used to identify which test run(s) you want see."+SEE_COMMAND_REFERENCE, 1079, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_FROM_AGE_SPECIFIED = NewMessageType("GAL1080E: Invalid 'from' value '%s' in the '--age' parameter. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be %s. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified."+SEE_COMMAND_REFERENCE, 1080, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_NEGATIVE_AGE_SPECIFIED = NewMessageType("GAL1081E: Unable use a negative value '%s' in the '--age' parameter. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be %s. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified."+SEE_COMMAND_REFERENCE, 1081, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_BAD_TIME_UNIT_AGE_SPECIFIED = NewMessageType("GAL1082E: Invalid time unit specified '%s' in the '--age' parameter. Age of the test runs should be specified in the format '{FROM}{TIME-UNIT}:{TO}{TIME-UNIT}' or '{FROM}{TIME-UNIT}', where 'FROM' is a positive, non-zero integer, 'TO' is a non-negative integer, and 'TIME-UNIT' can be %s. 'FROM' must be greater than 'TO'. 'TO' defaults to 0 if not specified."+SEE_COMMAND_REFERENCE, 1082, STACK_TRACE_NOT_WANTED)
Expand All @@ -268,6 +268,7 @@ var (
GALASA_ERROR_MISSING_NAME_FLAG = NewMessageType("GAL1102E: name '%s' is invalid. '--name' is a mandatory flag for this command."+SEE_COMMAND_REFERENCE, 1102, STACK_TRACE_WANTED)
GALASA_ERROR_QUERY_CPS_FAILED = NewMessageType("GAL1103E: Could not query CPS results. Reason: '%s'", 1103, STACK_TRACE_WANTED)
GALASA_ERROR_UNABLE_TO_DELETE_BEARER_TOKEN_FILE = NewMessageType("GAL1104E: Unable to delete the bearer token file '%s'.", 1104, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_GROUP_NAME_PROVIDED = NewMessageType("GAL1105E: Invalid group name provided. Group names must only contain characters in the following ranges: 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), '_' (underscore).", 1105, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_RETRIEVING_BEARER_TOKEN_FROM_API_SERVER = NewMessageType("GAL1106E: Could not get security bearer token from API server. Reason: '%s'. Ensure you have allocated a personal access token and configured your client program by setting your GALASA_TOKEN as an environment variable or by storing it in your galasactl.properties file", 1106, STACK_TRACE_WANTED)
GALASA_ERROR_RETRIEVING_BEARER_TOKEN_FROM_FILE = NewMessageType("GAL1107E: Could not get security bearer token from file '%s'. Reason: '%s'. Ensure you are authenticated by running 'galasactl auth login' and that your personal access token has not expired or been revoked", 1107, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_BEARER_TOKEN = NewMessageType("GAL1108E: Invalid bearer token. Ensure you are authenticated by running 'galasactl auth login' and that your personal access token has not expired or been revoked", 1108, STACK_TRACE_NOT_WANTED)
Expand Down Expand Up @@ -345,7 +346,7 @@ var (
GALASA_ERROR_DELETE_SECRET_UNPARSEABLE_CONTENT = NewMessageType("GAL1169E: An attempt to delete a secret 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'", 1169, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_SECRET_SERVER_REPORTED_ERROR = NewMessageType("GAL1170E: An attempt to delete a secret named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are: '%s'", 1170, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_SECRET_EXPLANATION_NOT_JSON = NewMessageType("GAL1171E: An attempt to delete a secret named '%s' failed. Unexpected http status code %v received from the server. Error details from the server are not in the json format.", 1171, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_SECRET_NAME = NewMessageType("GAL1172E: Invalid secret name provided. The name provided with the --name flag cannot be empty, contain spaces or dots (.), and must only contain characters in the Latin-1 character set.", 1172, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_SECRET_NAME = NewMessageType("GAL1172E: Invalid secret name provided. The name provided with the --name flag cannot be empty and must only contain characters in the following ranges: 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), '_' (underscore).", 1172, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_DELETE_SECRET_REQUEST_FAILED = NewMessageType("GAL1173E: An attempt to delete a secret named '%s' failed. Sending the delete request to the Galasa service failed. Cause is %v", 1173, STACK_TRACE_NOT_WANTED)

GALASA_ERROR_GET_SECRET_NO_RESPONSE_CONTENT = NewMessageType("GAL1174E: An attempt to get a secret named '%s' failed. Unexpected http status code %v received from the server.", 1174, STACK_TRACE_NOT_WANTED)
Expand Down Expand Up @@ -390,7 +391,7 @@ var (
GALASA_ERROR_GET_ROLES_EXPLANATION_NOT_JSON = NewMessageType("GAL1208E: Failed to get roles. Unexpected http status code %v received from the server. Error details from the server are not in the json format.", 1208, STACK_TRACE_NOT_WANTED)

// When getting a single named role...
GALASA_ERROR_INVALID_ROLE_NAME = NewMessageType("GAL1209E: Invalid role name provided. The name provided with the --name flag cannot be empty, contain spaces or dots (.), and must only contain characters in the Latin-1 character set.", 1209, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_INVALID_ROLE_NAME = NewMessageType("GAL1209E: Invalid role name provided. The name provided with the --name flag cannot be empty and must only contain characters in the following ranges: 'a'-'z', 'A'-'Z', '0'-'9', '-' (dash), '_' (underscore).", 1209, STACK_TRACE_NOT_WANTED)
GALASA_ERROR_ROLE_NAME_NOT_FOUND = NewMessageType("GAL1210E: Role name %v is not known on the Galasa service.", 1210, STACK_TRACE_NOT_WANTED)

// Warnings...
Expand Down
18 changes: 2 additions & 16 deletions pkg/roles/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,15 @@ import (
"strings"

galasaErrors "github.com/galasa-dev/cli/pkg/errors"
"github.com/galasa-dev/cli/pkg/utils"
)

func validateRoleName(nameToValidate string) (string, error) {
var err error
name := strings.TrimSpace(nameToValidate)

if name == "" || !usesValidRoleCharacters(name) {
if name == "" || !utils.IsNameValid(name) {
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_INVALID_ROLE_NAME)
}
return name, err
}

// Checks if a given string contains only characters in the Latin-1 character set (codepoints 0-255),
// returning true if so, and false otherwise
func usesValidRoleCharacters(str string) bool {
isValidLatin1 := true
for _, character := range str {
if !((character >= 'a' && character <= 'z') ||
(character >= 'A' && character <= 'Z') ||
(character >= '0' && character <= '9')) {
isValidLatin1 = false
break
}
}
return isValidLatin1
}
23 changes: 23 additions & 0 deletions pkg/runs/groups.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright contributors to the Galasa project
*
* SPDX-License-Identifier: EPL-2.0
*/
package runs

import (
"strings"

galasaErrors "github.com/galasa-dev/cli/pkg/errors"
"github.com/galasa-dev/cli/pkg/utils"
)

func validateGroupname(groupName string) (string, error) {
var err error
trimmedName := strings.TrimSpace(groupName)

if trimmedName == "" || !utils.IsNameValid(trimmedName) {
err = galasaErrors.NewGalasaError(galasaErrors.GALASA_ERROR_INVALID_GROUP_NAME_PROVIDED)
}
return trimmedName, err
}
Loading

0 comments on commit ab2af78

Please sign in to comment.