Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add additional testOptions for xcuitest #819

Merged
merged 13 commits into from
Aug 11, 2023
24 changes: 24 additions & 0 deletions api/saucectl.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -2176,6 +2176,30 @@
"notClass": {
"description": "Run all classes except those specified here.",
"type": "array"
},
"testLanguage": {
"description": "Specifies ISO 639-1 language during testing. Supported on Simulators only.",
"type": "string"
},
"testRegion": {
"description": "Specifies ISO 3166-1 region during testing.",
"type": "string"
},
"testTimeoutsEnabled": {
"description": "By default there is no timeout, if enabled, then the timeout is 600 seconds. This can be changed by adding the defaultTestExecutionTimeAllowance value. Supported on Simulators only.",
"type": "string",
"enum": [
"Yes",
"No"
]
},
"maximumTestExecutionTimeAllowance": {
"description": "The maximum execution time, in seconds, an individual test is given to execute, regardless of the test's preferred allowance. Supported on Simulators only.",
"type": "number"
},
"defaultTestExecutionTimeAllowance": {
"description": "The default execution time, in seconds, an individual test is given to execute if test timeouts are enabled. Supported on Simulators only.",
"type": "number"
}
},
"additionalProperties": false
Expand Down
21 changes: 21 additions & 0 deletions api/v1alpha/framework/xcuitest.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,27 @@
"notClass": {
"description": "Run all classes except those specified here.",
"type": "array"
},
"testLanguage": {
"description": "Specifies ISO 639-1 language during testing. Supported on Simulators only.",
"type": "string"
},
"testRegion": {
"description": "Specifies ISO 3166-1 region during testing.",
"type": "string"
},
"testTimeoutsEnabled": {
"description": "By default there is no timeout, if enabled, then the timeout is 600 seconds. This can be changed by adding the defaultTestExecutionTimeAllowance value. Supported on Simulators only.",
"type": "string",
"enum": ["Yes", "No"]
},
"maximumTestExecutionTimeAllowance": {
"description": "The maximum execution time, in seconds, an individual test is given to execute, regardless of the test's preferred allowance. Supported on Simulators only.",
"type": "number"
},
"defaultTestExecutionTimeAllowance": {
"description": "The default execution time, in seconds, an individual test is given to execute if test timeouts are enabled. Supported on Simulators only.",
"type": "number"
}
},
"additionalProperties": false
Expand Down
5 changes: 1 addition & 4 deletions internal/saucecloud/xcuitest.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,7 @@ func (r *XcuitestRunner) startJob(jobOpts chan<- job.StartOptions, appFileID, te
SmartRetry: job.SmartRetry{
FailedOnly: s.SmartRetry.IsRetryFailedOnly(),
},
TestOptions: map[string]interface{}{
"class": s.TestOptions.Class,
"notClass": s.TestOptions.NotClass,
},
TestOptions: s.TestOptions.ToMap(),

// RDC Specific flags
RealDevice: d.isRealDevice,
Expand Down
42 changes: 40 additions & 2 deletions internal/xcuitest/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"os"
"reflect"
"strings"
"time"

Expand Down Expand Up @@ -55,8 +56,45 @@ type Xcuitest struct {

// TestOptions represents the xcuitest test filter options configuration.
type TestOptions struct {
NotClass []string `yaml:"notClass,omitempty" json:"notClass"`
Class []string `yaml:"class,omitempty" json:"class"`
NotClass []string `yaml:"notClass,omitempty" json:"notClass"`
Class []string `yaml:"class,omitempty" json:"class"`
TestLanguage string `yaml:"testLanguage,omitempty" json:"testLanguage"`
TestRegion string `yaml:"testRegion,omitempty" json:"testRegion"`
TestTimeoutsEnabled string `yaml:"testTimeoutsEnabled,omitempty" json:"testTimeoutsEnabled"`
MaximumTestExecutionTimeAllowance int `yaml:"maximumTestExecutionTimeAllowance,omitempty" json:"maximumTestExecutionTimeAllowance"`
DefaultTestExecutionTimeAllowance int `yaml:"defaultTestExecutionTimeAllowance,omitempty" json:"defaultTestExecutionTimeAllowance"`
}

// ToMap converts the TestOptions to a map where the keys are derived from json struct tags.
func (t TestOptions) ToMap() map[string]interface{} {
tianfeng92 marked this conversation as resolved.
Show resolved Hide resolved
m := make(map[string]interface{})
v := reflect.ValueOf(t)
tt := v.Type()

count := v.NumField()
for i := 0; i < count; i++ {
if v.Field(i).CanInterface() {
tag := tt.Field(i).Tag
tname, ok := tag.Lookup("json")
if ok && tname != "-" {
fv := v.Field(i).Interface()
ft := v.Field(i).Type()
switch ft.Kind() {
// Convert int to string to match chef expectation that all test option values are strings
case reflect.Int:
mhan83 marked this conversation as resolved.
Show resolved Hide resolved
// Conventionally, test options with value "" will be ignored.
if fv.(int) == 0 {
m[tname] = ""
} else {
m[tname] = fmt.Sprintf("%v", fv)
}
default:
m[tname] = fv
}
}
}
}
return m
}

// Suite represents the xcuitest test suite configuration.
Expand Down
29 changes: 29 additions & 0 deletions internal/xcuitest/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,35 @@ import (
"gotest.tools/v3/fs"
)

func TestTestOptions_ToMap(t *testing.T) {
opts := TestOptions{
Class: []string{},
NotClass: []string{},
TestLanguage: "",
TestRegion: "",
TestTimeoutsEnabled: "",
MaximumTestExecutionTimeAllowance: 20,
DefaultTestExecutionTimeAllowance: 0,
}
wantLength := 7

m := opts.ToMap()

if len(m) != wantLength {
t.Errorf("Length of converted TestOptions should match original, got (%v) want (%v)", len(m), wantLength)
}

v := reflect.ValueOf(m["maximumTestExecutionTimeAllowance"])
vtype := v.Type()
if vtype.Kind() != reflect.String {
t.Errorf("ints should be converted to strings when mapping, got (%v) want (%v)", vtype, reflect.String)
}

if v := m["defaultTestExecutionTimeAllowance"]; v != "" {
t.Errorf("0 values should be cast to empty strings, got (%v)", v)
}
}

func TestValidate(t *testing.T) {
dir := fs.NewDir(t, "xcuitest-config",
fs.WithFile("test.ipa", "", fs.WithMode(0655)),
Expand Down