xamarin-test-cloud 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a0cec22a46900529476eefcfd387d5dc97dedbbc
4
- data.tar.gz: 7b7bb6d17156291186b684fcd83c5349047f966d
3
+ metadata.gz: 17f8c6ea03350ae24d3607f63bff1dfd571da5c9
4
+ data.tar.gz: 60ee93aec5aaaecb1423640398a62c1494a8108c
5
5
  SHA512:
6
- metadata.gz: 75b50f5a7d3d502f59f1380aedc19df50d3e35cc2b987c3625e45588f0a1ef3822ab618d56d41c70706793b0f23ce02143a094314c2e8c096c0da7205369ca27
7
- data.tar.gz: d54020a9a94b3920ead7dd866ce490688eeb1f76970e2b7cdecbc52bd7bcfdc127ca5ae7b0517396fbc75bba1c80227620b9eafc83f86b043d3c664367d647a4
6
+ metadata.gz: a3fbc8ce41b25019819ed4684c8a5d7edea38b4709f9c88d7463ebf0979ccfcc851973469f2933a8935cd6846870b0e8d232348a74a076de23bacb76c77a47d8
7
+ data.tar.gz: d6f5ada84fcd0143b49369f28c041a7466786308d11c6e90d6f25b7789571b46d6602fc7e4ac1b89c40c78eab4a7f28aa11710ba8d74819e1d72044725e58a45
data/README.md CHANGED
@@ -1 +1,12 @@
1
- Run ``rake -T`` to see the available Rake tasks.
1
+ ## Test Cloud Command Line
2
+
3
+ ### Testing
4
+
5
+ ```
6
+ $ bundle update
7
+ $ rake test # All tests.
8
+ $ rake unit # Unit tests.
9
+ $ rake integration # Integration tests.
10
+ $ rake spec # rspec tests
11
+ ```
12
+
@@ -11,7 +11,10 @@ require 'tmpdir'
11
11
  require 'fileutils'
12
12
  require 'retriable'
13
13
  require 'xamarin-test-cloud/version'
14
+ require 'xamarin-test-cloud/retriable_options'
14
15
  require 'securerandom'
16
+ require 'open3'
17
+
15
18
 
16
19
  trap "SIGINT" do
17
20
  puts "Exiting"
@@ -28,7 +31,7 @@ module XamarinTestCloud
28
31
 
29
32
  attr_accessor :app, :api_key, :appname, :test_parameters, :user,
30
33
  :workspace, :config, :profile, :skip_config_check, :dry_run,
31
- :device_selection, :pretty, :async, :priority, :endpoint_path,
34
+ :device_selection, :pretty, :async, :async_json, :priority, :endpoint_path,
32
35
  :locale, :series,
33
36
  :dsym, :session_id
34
37
 
@@ -113,6 +116,11 @@ module XamarinTestCloud
113
116
  :type => :boolean,
114
117
  :default => false
115
118
 
119
+ method_option 'async-json',
120
+ :desc => "Don't block waiting for test results. Output results in json format.",
121
+ :type => :boolean,
122
+ :default => false
123
+
116
124
  method_option :priority,
117
125
  :desc => "Run as priority test execution. Please note: This is only available for some tiers, and priority test executions cost double.",
118
126
  :type => :boolean,
@@ -145,10 +153,23 @@ module XamarinTestCloud
145
153
  :type => :string
146
154
 
147
155
 
148
-
149
156
  def submit(app, api_key)
150
157
 
151
158
  self.pretty = options[:pretty]
159
+ self.async_json = options['async-json']
160
+ self.async = options[:async] || self.async_json
161
+
162
+ # Async mode wraps all console output in a json object
163
+ # So we need to intercept all writes to $stdout
164
+ if self.async_json
165
+ @async_log = StringIO.new
166
+ @async_result = {
167
+ test_run_id: nil,
168
+ error_messages: [],
169
+ log: []
170
+ }
171
+ $stdout = @async_log
172
+ end
152
173
 
153
174
  app_path = File.expand_path(app)
154
175
  unless File.exist?(app_path)
@@ -173,8 +194,6 @@ module XamarinTestCloud
173
194
 
174
195
  self.user = options['user']
175
196
 
176
- self.async = options[:async]
177
-
178
197
  self.dry_run = options['dry-run']
179
198
 
180
199
  self.api_key = api_key
@@ -211,7 +230,7 @@ module XamarinTestCloud
211
230
 
212
231
  workspace_basename = File.basename(workspace_path)
213
232
  if workspace_basename.downcase == 'features'
214
- self.workspace = File.expand_path(File.join(workspace_path,'..'))
233
+ self.workspace = File.expand_path(File.join(workspace_path, '..'))
215
234
  puts "Deriving workspace #{self.workspace} from features folder #{workspace_basename}"
216
235
  else
217
236
  self.workspace = File.expand_path(workspace_path)
@@ -230,7 +249,7 @@ module XamarinTestCloud
230
249
 
231
250
  parse_and_set_config_and_profile
232
251
  unless self.skip_config_check
233
- default_config = File.join(self.workspace,'config','cucumber.yml')
252
+ default_config = File.join(self.workspace, 'config', 'cucumber.yml')
234
253
  if File.exist?(default_config) && self.config.nil?
235
254
  log_header 'Warning: Detected cucumber.yml config file, but no --config specified'
236
255
  puts "Please specify --config #{default_config}"
@@ -275,7 +294,7 @@ module XamarinTestCloud
275
294
  rejected_devices = json['rejected_devices']
276
295
  if rejected_devices && rejected_devices.size > 0
277
296
  puts 'Skipping devices (you can update your selections via https://testcloud.xamarin.com)'
278
- rejected_devices.each {|d| puts d}
297
+ rejected_devices.each { |d| puts d }
279
298
  end
280
299
  puts ''
281
300
 
@@ -290,10 +309,25 @@ module XamarinTestCloud
290
309
  wait_for_job(json['id'])
291
310
  else
292
311
  log 'Async mode: not awaiting test results'
312
+ @async_result[:test_run_id] = json['id'] if self.async_json
293
313
  end
294
314
 
315
+ rescue XamarinTestCloud::ValidationError => e
316
+ if self.async_json
317
+ @async_result[:error_messages] << e.message
318
+ else
319
+ raise
295
320
  end
296
321
 
322
+ ensure
323
+ $stdout = STDOUT
324
+ if self.async_json
325
+ process_async_log
326
+ puts @async_result.to_json
327
+ end
328
+ end
329
+
330
+
297
331
  default_task :submit
298
332
 
299
333
  no_tasks do
@@ -302,13 +336,20 @@ module XamarinTestCloud
302
336
  ENV['DEBUG'] == '1'
303
337
  end
304
338
 
339
+ def process_async_log
340
+ @async_result[:log] = @async_log.string
341
+ .split(/\n/).map { |string| string.gsub(/\e\[(\d+)m/, '').strip }
342
+ .select { |string| string.length > 0 }
343
+ end
344
+
305
345
  def exit_on_failure?
306
346
  true
307
347
  end
308
348
 
309
349
  def wait_for_job(id)
350
+ retry_opts = XamarinTestCloud::RetriableOptions.tries_and_interval(60, 10)
310
351
  while(true)
311
- status_json = Retriable.retriable :tries => 60, :interval => 10 do
352
+ status_json = Retriable.retriable(retry_opts) do
312
353
  JSON.parse(http_post("status_v3", {'id' => id, 'api_key' => api_key, 'user' => user}))
313
354
  end
314
355
 
@@ -367,7 +408,14 @@ module XamarinTestCloud
367
408
 
368
409
  ENV['BUNDLE_GEMFILE'] = File.join(tmpdir, "Gemfile")
369
410
  FileUtils.cd(self.workspace) do
370
- unless system('bundle package --all')
411
+ if self.async_json
412
+ bundle_log, status = Open3.capture2e('bundle package --all')
413
+ puts bundle_log
414
+ else
415
+ system('bundle package --all')
416
+ status = $?
417
+ end
418
+ if status != 0
371
419
  log_and_abort 'Bundler failed. Please check command: bundle package'
372
420
  end
373
421
  end
@@ -434,36 +482,17 @@ module XamarinTestCloud
434
482
  when 200..202
435
483
  response
436
484
  when 400
437
- abort do
438
- puts 'Bad request'
439
- puts response.body
440
- end
485
+ error_message = JSON.parse(response.body)['error_message'] rescue 'Bad request'
486
+ log_and_abort(error_message)
441
487
  when 403
442
- abort do
443
- puts 'Forbidden'
444
- puts JSON.parse(response.body)['message']
445
- end
488
+ error_message = JSON.parse(response.body)['message'] rescue 'Forbidden'
489
+ log_and_abort(error_message)
446
490
  when 413
447
- abort do
448
- puts 'Files too large'
449
- end
491
+ error_message = 'Files are too large'
492
+ log_and_abort(error_message)
450
493
  else
451
- begin
452
- r = JSON.parse(response)
453
- if r["invalid_platform"]
454
- abort do
455
- if r["invalid_platform"] == "android"
456
- log "#{app} cannot be tested on Android devices. Please create a new device selection on the Xamarin Test Cloud website."
457
- else
458
- log "#{app} cannot be tested on iOS devices. Please create a new device selection on the Xamarin Test Cloud website."
459
- end
460
- end
461
- end
462
- rescue
463
- end
464
- abort do
465
- log 'Unexpected Error. Please contact support at testcloud@xamarin.com.'
466
- end
494
+ error_message = 'Unexpected Error. Please contact support at testcloud@xamarin.com.'
495
+ log_and_abort(error_message)
467
496
  end
468
497
  end
469
498
 
@@ -520,8 +549,8 @@ module XamarinTestCloud
520
549
 
521
550
  dsym_digest= nil
522
551
  if dsym
523
- FileUtils.cp_r(dsym,tmpdir)
524
- files_in_dwarf = Dir.glob(File.join(tmpdir, File.basename(dsym), 'Contents','Resources','DWARF','*'))
552
+ FileUtils.cp_r(dsym, tmpdir)
553
+ files_in_dwarf = Dir.glob(File.join(tmpdir, File.basename(dsym), 'Contents', 'Resources', 'DWARF', '*'))
525
554
  unless files_in_dwarf.count == 1
526
555
  raise ValidationError, "dSym #{dsym} contains more than one file in Contents/Resources/DWARF: #{files_in_dwarf}"
527
556
  end
@@ -645,7 +674,7 @@ module XamarinTestCloud
645
674
  files << config
646
675
  end
647
676
 
648
- files += Dir.glob(File.join(tmpdir,"vendor", 'cache', '*'))
677
+ files += Dir.glob(File.join(tmpdir, "vendor", 'cache', '*'))
649
678
 
650
679
  if workspace and workspace.strip != ''
651
680
  files += Dir.glob("#{workspace}Gemfile")
@@ -735,7 +764,7 @@ module XamarinTestCloud
735
764
 
736
765
  def log(message)
737
766
  if message.is_a? Array
738
- message.each{ |m| log(m)}
767
+ message.each { |m| log(m) }
739
768
  else
740
769
  puts "#{Time.now } #{message}"
741
770
  $stdout.flush
@@ -784,7 +813,9 @@ module XamarinTestCloud
784
813
  end
785
814
 
786
815
  def log_and_abort(message)
816
+ raise XamarinTestCloud::ValidationError.new(message) if self.async_json
787
817
  abort do
818
+ print 'Error: '
788
819
  puts message
789
820
  end
790
821
  end
@@ -795,7 +826,7 @@ module XamarinTestCloud
795
826
  f.any? do |file|
796
827
  filename = file[:filename]
797
828
  if filename.end_with?("libmonodroid.so")
798
- file[:size] < 120 * 1024 && f.none?{ |x| x[:filename] == filename.sub("libmonodroid.so", "libmonosgen-2.0.so")}
829
+ file[:size] < 120 * 1024 && f.none? { |x| x[:filename] == filename.sub("libmonodroid.so", "libmonosgen-2.0.so") }
799
830
  end
800
831
  end
801
832
  end
@@ -803,7 +834,7 @@ module XamarinTestCloud
803
834
  def files(app)
804
835
  Zip::File.open(app) do |zip_file|
805
836
  zip_file.collect do |entry|
806
- {:filename => entry.to_s, :size => entry.size }
837
+ {:filename => entry.to_s, :size => entry.size}
807
838
  end
808
839
  end
809
840
  end
@@ -0,0 +1,26 @@
1
+ require 'retriable'
2
+
3
+ module XamarinTestCloud
4
+ # A class to bridge the gap between retriable 1.x and 2.0.
5
+ class RetriableOptions
6
+
7
+ def self.retriable_version
8
+ parts = Retriable::VERSION.split('.')
9
+ {
10
+ :major => parts[0] ? parts[0].to_i : nil,
11
+ :minor => parts[1] ? parts[1].to_i : nil,
12
+ :patch => parts[2] ? parts[2].to_i : nil
13
+ }
14
+ end
15
+
16
+ def self.tries_and_interval(tries, interval)
17
+ version = self.retriable_version[:major]
18
+ if version >= 2
19
+ {:intervals => Array.new(tries, interval)}
20
+ else
21
+ {:tries => tries, :interval => interval}
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -1,3 +1,3 @@
1
1
  module XamarinTestCloud
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xamarin-test-cloud
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Karl Krukow
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-01-28 00:00:00.000000000 Z
12
+ date: 2015-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: thor
@@ -18,6 +18,9 @@ dependencies:
18
18
  - - '>='
19
19
  - !ruby/object:Gem::Version
20
20
  version: 0.18.1
21
+ - - <
22
+ - !ruby/object:Gem::Version
23
+ version: '1.0'
21
24
  type: :runtime
22
25
  prerelease: false
23
26
  version_requirements: !ruby/object:Gem::Requirement
@@ -25,6 +28,9 @@ dependencies:
25
28
  - - '>='
26
29
  - !ruby/object:Gem::Version
27
30
  version: 0.18.1
31
+ - - <
32
+ - !ruby/object:Gem::Version
33
+ version: '1.0'
28
34
  - !ruby/object:Gem::Dependency
29
35
  name: bundler
30
36
  requirement: !ruby/object:Gem::Requirement
@@ -110,7 +116,7 @@ dependencies:
110
116
  version: 1.3.3.1
111
117
  - - <
112
118
  - !ruby/object:Gem::Version
113
- version: '2.0'
119
+ version: '2.1'
114
120
  type: :runtime
115
121
  prerelease: false
116
122
  version_requirements: !ruby/object:Gem::Requirement
@@ -120,7 +126,7 @@ dependencies:
120
126
  version: 1.3.3.1
121
127
  - - <
122
128
  - !ruby/object:Gem::Version
123
- version: '2.0'
129
+ version: '2.1'
124
130
  - !ruby/object:Gem::Dependency
125
131
  name: rake
126
132
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +155,110 @@ dependencies:
149
155
  - - ~>
150
156
  - !ruby/object:Gem::Version
151
157
  version: 3.0.9
158
+ - !ruby/object:Gem::Dependency
159
+ name: rspec
160
+ requirement: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - ~>
163
+ - !ruby/object:Gem::Version
164
+ version: '3.0'
165
+ type: :development
166
+ prerelease: false
167
+ version_requirements: !ruby/object:Gem::Requirement
168
+ requirements:
169
+ - - ~>
170
+ - !ruby/object:Gem::Version
171
+ version: '3.0'
172
+ - !ruby/object:Gem::Dependency
173
+ name: guard-rspec
174
+ requirement: !ruby/object:Gem::Requirement
175
+ requirements:
176
+ - - ~>
177
+ - !ruby/object:Gem::Version
178
+ version: '4.3'
179
+ type: :development
180
+ prerelease: false
181
+ version_requirements: !ruby/object:Gem::Requirement
182
+ requirements:
183
+ - - ~>
184
+ - !ruby/object:Gem::Version
185
+ version: '4.3'
186
+ - !ruby/object:Gem::Dependency
187
+ name: guard-bundler
188
+ requirement: !ruby/object:Gem::Requirement
189
+ requirements:
190
+ - - ~>
191
+ - !ruby/object:Gem::Version
192
+ version: '2.0'
193
+ type: :development
194
+ prerelease: false
195
+ version_requirements: !ruby/object:Gem::Requirement
196
+ requirements:
197
+ - - ~>
198
+ - !ruby/object:Gem::Version
199
+ version: '2.0'
200
+ - !ruby/object:Gem::Dependency
201
+ name: growl
202
+ requirement: !ruby/object:Gem::Requirement
203
+ requirements:
204
+ - - ~>
205
+ - !ruby/object:Gem::Version
206
+ version: '1.0'
207
+ type: :development
208
+ prerelease: false
209
+ version_requirements: !ruby/object:Gem::Requirement
210
+ requirements:
211
+ - - ~>
212
+ - !ruby/object:Gem::Version
213
+ version: '1.0'
214
+ - !ruby/object:Gem::Dependency
215
+ name: stub_env
216
+ requirement: !ruby/object:Gem::Requirement
217
+ requirements:
218
+ - - '>='
219
+ - !ruby/object:Gem::Version
220
+ version: 1.0.1
221
+ - - <
222
+ - !ruby/object:Gem::Version
223
+ version: '2.0'
224
+ type: :development
225
+ prerelease: false
226
+ version_requirements: !ruby/object:Gem::Requirement
227
+ requirements:
228
+ - - '>='
229
+ - !ruby/object:Gem::Version
230
+ version: 1.0.1
231
+ - - <
232
+ - !ruby/object:Gem::Version
233
+ version: '2.0'
234
+ - !ruby/object:Gem::Dependency
235
+ name: pry
236
+ requirement: !ruby/object:Gem::Requirement
237
+ requirements:
238
+ - - '>='
239
+ - !ruby/object:Gem::Version
240
+ version: '0'
241
+ type: :development
242
+ prerelease: false
243
+ version_requirements: !ruby/object:Gem::Requirement
244
+ requirements:
245
+ - - '>='
246
+ - !ruby/object:Gem::Version
247
+ version: '0'
248
+ - !ruby/object:Gem::Dependency
249
+ name: pry-nav
250
+ requirement: !ruby/object:Gem::Requirement
251
+ requirements:
252
+ - - '>='
253
+ - !ruby/object:Gem::Version
254
+ version: '0'
255
+ type: :development
256
+ prerelease: false
257
+ version_requirements: !ruby/object:Gem::Requirement
258
+ requirements:
259
+ - - '>='
260
+ - !ruby/object:Gem::Version
261
+ version: '0'
152
262
  description: Xamarin Test Cloud lets you automatically test your app on hundreds of
153
263
  mobile devices
154
264
  email:
@@ -163,6 +273,7 @@ files:
163
273
  - README.md
164
274
  - bin/test-cloud
165
275
  - lib/xamarin-test-cloud/cli.rb
276
+ - lib/xamarin-test-cloud/retriable_options.rb
166
277
  - lib/xamarin-test-cloud/version.rb
167
278
  - test/ipa/features/step_definitions/calabash_steps.rb
168
279
  - test/ipa/features/step_definitions/my_first_steps.rb