github.com/bitrise-io/go-xamarin@v0.0.0-20211005113058-bf60a8bae851/tools/testcloud/testcloud.go (about) 1 package testcloud 2 3 import ( 4 "bufio" 5 "fmt" 6 7 "github.com/bitrise-io/go-utils/command" 8 "github.com/bitrise-io/go-utils/pathutil" 9 "github.com/bitrise-io/go-xamarin/constants" 10 ) 11 12 // Parallelization ... 13 type Parallelization string 14 15 const ( 16 // ParallelizationUnknown ... 17 ParallelizationUnknown Parallelization = "unkown" 18 // ParallelizationByTestFixture ... 19 ParallelizationByTestFixture Parallelization = "by_test_fixture" 20 // ParallelizationByTestChunk ... 21 ParallelizationByTestChunk Parallelization = "by_test_chunk" 22 ) 23 24 // ParseParallelization ... 25 func ParseParallelization(parallelization string) (Parallelization, error) { 26 switch parallelization { 27 case "by_test_fixture": 28 return ParallelizationByTestFixture, nil 29 case "by_test_chunk": 30 return ParallelizationByTestChunk, nil 31 default: 32 return ParallelizationUnknown, fmt.Errorf("Unkown parallelization (%s)", parallelization) 33 } 34 } 35 36 // Model ... 37 type Model struct { 38 testCloudExePth string 39 40 apkPth string 41 ipaPth string 42 dsymPth string 43 44 apiKey string 45 user string 46 assemblyDir string 47 devices string 48 isAsyncJSON bool 49 series string 50 nunitXMLPth string 51 parallelization Parallelization 52 53 signOptions []string 54 customOptions []string 55 } 56 57 // NewModel ... 58 func NewModel(testCloudExexPth string) (*Model, error) { 59 absTestCloudExexPth, err := pathutil.AbsPath(testCloudExexPth) 60 if err != nil { 61 return nil, fmt.Errorf("Failed to expand path (%s), error: %s", testCloudExexPth, err) 62 } 63 64 return &Model{testCloudExePth: absTestCloudExexPth}, nil 65 } 66 67 // SetAPKPth ... 68 func (testCloud *Model) SetAPKPth(apkPth string) *Model { 69 testCloud.apkPth = apkPth 70 return testCloud 71 } 72 73 // SetIPAPth ... 74 func (testCloud *Model) SetIPAPth(ipaPth string) *Model { 75 testCloud.ipaPth = ipaPth 76 return testCloud 77 } 78 79 // SetDSYMPth ... 80 func (testCloud *Model) SetDSYMPth(dsymPth string) *Model { 81 testCloud.dsymPth = dsymPth 82 return testCloud 83 } 84 85 // SetAPIKey ... 86 func (testCloud *Model) SetAPIKey(apiKey string) *Model { 87 testCloud.apiKey = apiKey 88 return testCloud 89 } 90 91 // SetUser ... 92 func (testCloud *Model) SetUser(user string) *Model { 93 testCloud.user = user 94 return testCloud 95 } 96 97 // SetAssemblyDir ... 98 func (testCloud *Model) SetAssemblyDir(assemblyDir string) *Model { 99 testCloud.assemblyDir = assemblyDir 100 return testCloud 101 } 102 103 // SetDevices ... 104 func (testCloud *Model) SetDevices(devices string) *Model { 105 testCloud.devices = devices 106 return testCloud 107 } 108 109 // SetIsAsyncJSON ... 110 func (testCloud *Model) SetIsAsyncJSON(isAsyncJSON bool) *Model { 111 testCloud.isAsyncJSON = isAsyncJSON 112 return testCloud 113 } 114 115 // SetSeries ... 116 func (testCloud *Model) SetSeries(series string) *Model { 117 testCloud.series = series 118 return testCloud 119 } 120 121 // SetNunitXMLPth ... 122 func (testCloud *Model) SetNunitXMLPth(nunitXMLPth string) *Model { 123 testCloud.nunitXMLPth = nunitXMLPth 124 return testCloud 125 } 126 127 // SetParallelization ... 128 func (testCloud *Model) SetParallelization(parallelization Parallelization) *Model { 129 testCloud.parallelization = parallelization 130 return testCloud 131 } 132 133 // SetSignOptions ... 134 func (testCloud *Model) SetSignOptions(options ...string) *Model { 135 testCloud.signOptions = options 136 return testCloud 137 } 138 139 // SetCustomOptions ... 140 func (testCloud *Model) SetCustomOptions(options ...string) *Model { 141 testCloud.customOptions = options 142 return testCloud 143 } 144 145 func (testCloud *Model) submitCommandSlice() []string { 146 cmdSlice := []string{constants.MonoPath} 147 cmdSlice = append(cmdSlice, testCloud.testCloudExePth) 148 cmdSlice = append(cmdSlice, "submit") 149 150 if testCloud.apkPth != "" { 151 cmdSlice = append(cmdSlice, testCloud.apkPth) 152 } 153 154 if testCloud.ipaPth != "" { 155 cmdSlice = append(cmdSlice, testCloud.ipaPth) 156 } 157 if testCloud.dsymPth != "" { 158 cmdSlice = append(cmdSlice, "--dsym", testCloud.dsymPth) 159 } 160 161 cmdSlice = append(cmdSlice, testCloud.apiKey) 162 cmdSlice = append(cmdSlice, testCloud.signOptions...) 163 cmdSlice = append(cmdSlice, "--user", testCloud.user) 164 cmdSlice = append(cmdSlice, "--assembly-dir", testCloud.assemblyDir) 165 cmdSlice = append(cmdSlice, "--devices", testCloud.devices) 166 167 if testCloud.isAsyncJSON { 168 cmdSlice = append(cmdSlice, "--async-json") 169 } 170 171 cmdSlice = append(cmdSlice, "--series", testCloud.series) 172 173 if testCloud.nunitXMLPth != "" { 174 cmdSlice = append(cmdSlice, "--nunit-xml", testCloud.nunitXMLPth) 175 } 176 177 if testCloud.parallelization == ParallelizationByTestChunk { 178 cmdSlice = append(cmdSlice, "--test-chunk") 179 } else if testCloud.parallelization == ParallelizationByTestFixture { 180 cmdSlice = append(cmdSlice, "--fixture-chunk") 181 } 182 183 cmdSlice = append(cmdSlice, testCloud.customOptions...) 184 185 return cmdSlice 186 } 187 188 // String ... 189 func (testCloud Model) String() string { 190 cmdSlice := testCloud.submitCommandSlice() 191 return command.PrintableCommandArgs(true, cmdSlice) 192 } 193 194 // CaptureLineCallback ... 195 type CaptureLineCallback func(line string) 196 197 // Submit ... 198 func (testCloud Model) Submit(callback CaptureLineCallback) error { 199 cmdSlice := testCloud.submitCommandSlice() 200 201 command, err := command.NewFromSlice(cmdSlice) 202 if err != nil { 203 return err 204 } 205 206 cmd := *command.GetCmd() 207 208 // Redirect output 209 stdoutReader, err := cmd.StdoutPipe() 210 if err != nil { 211 return err 212 } 213 214 scanner := bufio.NewScanner(stdoutReader) 215 go func() { 216 for scanner.Scan() { 217 line := scanner.Text() 218 if callback != nil { 219 callback(line) 220 } 221 } 222 }() 223 if err := scanner.Err(); err != nil { 224 return err 225 } 226 227 if err := cmd.Start(); err != nil { 228 return err 229 } 230 231 return cmd.Wait() 232 }