fastlane-plugin-test_center 3.9.0 → 3.9.1.b.1

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
  SHA256:
3
- metadata.gz: 7dd99b394133508622e5daab51025772002b0b0369e6b7cfd04055dbb51cc0aa
4
- data.tar.gz: 30abd18975a3259a86ded79a1e466b386f86ef5f56cab4fefa04397bc80fa25a
3
+ metadata.gz: 1046d5102edf4921dec9466f721da07edffa749f3f24fe597873f8542a37d52b
4
+ data.tar.gz: f269d6a491a84575b7442c9a7642ee69dc3005b596c682a5aa30d19eb76a67d9
5
5
  SHA512:
6
- metadata.gz: 225ffa3158f7bf9b8bea8c6d47c897d4926e003a90f4eae9cd4f6cb1074e5de3943bcaf4111d2d819b611260503f9c2fb537cb334fd8d0ee07c0f501dc75b136
7
- data.tar.gz: 449cb428920924775c5aa28c236d367c34453e0ef68d534981c03f8292eb0e8a582043c4992b28e3dff4d21dee6fd96957d2280d39322f34c19a26845aa0e3df
6
+ metadata.gz: e1cf6be83ddcff5317cd8681aa44e36c3d24e061abdff7fad5c47ec883a91ec09d15ff24eb8727141dacdd04c88327f057bcbdb9ac3504a29b85b26608a6689b
7
+ data.tar.gz: d8c2523c66da3b53c937720ac16d46d1c4b97953b3940db29a418eeab7a8f9342a72c4d0a1a4882928ac3a7c925806eed9c22c3f78baab49c0416360be96276b
@@ -14,25 +14,17 @@ module Fastlane
14
14
  class MultiScanAction < Action
15
15
  def self.run(params)
16
16
  params[:quit_simulators] = params._values[:force_quit_simulator] if params._values[:force_quit_simulator]
17
- if params[:output_types]
18
- params[:output_types] = params[:output_types].split(',').map(&:strip).join(',')
19
- end
20
- if params[:output_files]
21
- params[:output_files] = params[:output_files].split(',').map(&:strip).join(',')
22
- end
23
17
 
24
- if FastlaneCore::Helper.xcode_at_least?('11.0.0')
25
- if params[:result_bundle]
26
- UI.important('As of Xcode 11, test_result bundles created in the output directory are actually symbolic links to an xcresult bundle')
27
- end
28
- elsif params[:output_types]&.include?('xcresult')
29
- UI.important("The 'xcresult' :output_type is only supported for Xcode 11 and greater. You are using #{FastlaneCore::Helper.xcode_version}.")
30
- end
18
+ strip_leading_and_trailing_whitespace_from_output_types(params)
19
+
20
+ warn_of_xcode11_result_bundle_incompatability(params)
21
+ warn_of_parallelism_with_circle_ci(params)
22
+
31
23
  print_multi_scan_parameters(params)
32
24
  force_quit_simulator_processes if params[:quit_simulators]
33
25
 
34
26
  prepare_for_testing(params.values)
35
-
27
+
36
28
  coerce_destination_to_array(params)
37
29
  platform = :mac
38
30
  platform = :ios_simulator if Scan.config[:destination].any? { |d| d.include?('platform=iOS Simulator') }
@@ -43,17 +35,43 @@ module Fastlane
43
35
 
44
36
  summary = run_summary(params, tests_passed)
45
37
  print_run_summary(summary)
46
-
38
+
47
39
  if params[:fail_build] && !tests_passed
48
40
  raise UI.test_failure!('Tests have failed')
49
41
  end
50
42
  summary
51
43
  end
52
44
 
45
+ def self.warn_of_parallelism_with_circle_ci(params)
46
+ if params[:parallel_testrun_count] > 1 && Helper.is_circle_ci?
47
+ UI.important("Warning: problems have occurreed when running parallel simulators on Circle CI.")
48
+ UI.message(" See https://github.com/lyndsey-ferguson/fastlane-plugin-test_center/issues/179")
49
+ end
50
+ end
51
+
52
+ def self.strip_leading_and_trailing_whitespace_from_output_types(params)
53
+ if params[:output_types]
54
+ params[:output_types] = params[:output_types].split(',').map(&:strip).join(',')
55
+ end
56
+ if params[:output_files]
57
+ params[:output_files] = params[:output_files].split(',').map(&:strip).join(',')
58
+ end
59
+ end
60
+
61
+ def self.warn_of_xcode11_result_bundle_incompatability(params)
62
+ if FastlaneCore::Helper.xcode_at_least?('11.0.0')
63
+ if params[:result_bundle]
64
+ UI.important('As of Xcode 11, test_result bundles created in the output directory are actually symbolic links to an xcresult bundle')
65
+ end
66
+ elsif params[:output_types]&.include?('xcresult')
67
+ UI.important("The 'xcresult' :output_type is only supported for Xcode 11 and greater. You are using #{FastlaneCore::Helper.xcode_version}.")
68
+ end
69
+ end
70
+
53
71
  def self.coerce_destination_to_array(params)
54
72
  destination = params[:destination] || Scan.config[:destination] || []
55
73
  unless destination.kind_of?(Array)
56
- params[:destination] = Scan.config[:destination] = [destination]
74
+ params[:destination] = Scan.config[:destination] = [destination]
57
75
  end
58
76
  end
59
77
 
@@ -68,7 +86,7 @@ module Fastlane
68
86
  # :nocov:
69
87
  end
70
88
 
71
- def self.print_run_summary(summary)
89
+ def self.print_run_summary(summary)
72
90
  return if Helper.test?
73
91
 
74
92
  # :nocov:
@@ -147,6 +165,7 @@ module Fastlane
147
165
  def self.prepare_for_testing(scan_options)
148
166
  reset_scan_config_to_defaults
149
167
  use_scanfile_to_override_settings(scan_options)
168
+ turn_off_concurrent_workers(scan_options)
150
169
  ScanHelper.remove_preexisting_simulator_logs(scan_options)
151
170
  if scan_options[:test_without_building] || scan_options[:skip_build]
152
171
  UI.verbose("Preparing Scan config options for multi_scan testing")
@@ -157,6 +176,12 @@ module Fastlane
157
176
  end
158
177
  end
159
178
 
179
+ def self.turn_off_concurrent_workers(scan_options)
180
+ if Gem::Version.new(Fastlane::VERSION) >= Gem::Version.new('2.142.0')
181
+ scan_options.delete(:concurrent_workers) if scan_options[:concurrent_workers].to_i > 0
182
+ end
183
+ end
184
+
160
185
  def self.reset_scan_config_to_defaults
161
186
  return unless Scan.config
162
187
 
@@ -173,7 +198,7 @@ module Fastlane
173
198
  overridden_options = ScanHelper.options_from_configuration_file(
174
199
  ScanHelper.scan_options_from_multi_scan_options(scan_options)
175
200
  )
176
-
201
+
177
202
  unless overridden_options.empty?
178
203
  FastlaneCore::UI.important("Scanfile found: overriding multi_scan options with it's values.")
179
204
  overridden_options.each do |k,v|
@@ -303,6 +328,13 @@ module Fastlane
303
328
  UI.user_error!("Error: Batch counts must be greater than zero") unless count > 0
304
329
  end
305
330
  ),
331
+ FastlaneCore::ConfigItem.new(
332
+ key: :retry_test_runner_failures,
333
+ description: "Set to true If you want to treat build failures during testing, like 'Test runner exited before starting test execution', as 'all tests failed'",
334
+ type: Boolean,
335
+ default_value: false,
336
+ optional: true
337
+ ),
306
338
  FastlaneCore::ConfigItem.new(
307
339
  key: :invocation_based_tests,
308
340
  description: "Set to true If your test suit have invocation based tests like Kiwi",
@@ -374,7 +406,7 @@ module Fastlane
374
406
  UI.important(
375
407
  'example: ' \\
376
408
  'split the tests into 4 batches and run each batch of tests in ' \\
377
- 'parallel up to 3 times if tests fail. Abort the testing early ' \\
409
+ 'parallel up to 3 times if tests fail. Abort the testing early ' \\
378
410
  'if there are too many failing tests by passing in a ' \\
379
411
  ':testrun_completed_block that is called by :multi_scan ' \\
380
412
  'after each run of tests.'
@@ -88,11 +88,12 @@ module TestCenter
88
88
 
89
89
  def scan_options
90
90
  valid_scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
91
- xcargs = @options[:xcargs]
91
+ xcargs = @options[:xcargs] || ''
92
92
  if xcargs&.include?('build-for-testing')
93
93
  FastlaneCore::UI.important(":xcargs, #{xcargs}, contained 'build-for-testing', removing it")
94
94
  xcargs.slice!('build-for-testing')
95
95
  end
96
+ xcargs.gsub!(/-parallel-testing-enabled(=|\s+)(YES|NO)/, '')
96
97
  retrying_scan_options = @reportnamer.scan_options.merge(
97
98
  {
98
99
  output_directory: output_directory,
@@ -125,7 +126,11 @@ module TestCenter
125
126
  after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
126
127
  FastlaneCore::UI.verbose(after_testrun_message)
127
128
 
128
- handle_build_failure(exception)
129
+ if @options[:retry_test_runner_failures]
130
+ continue_with_build_failure(exception)
131
+ else
132
+ handle_build_failure(exception)
133
+ end
129
134
  else
130
135
  after_testrun_message = "Scan passed the tests"
131
136
  after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
@@ -240,12 +245,27 @@ module TestCenter
240
245
  junit: File.absolute_path(report_filepath)
241
246
  }
242
247
  )
243
- @options[:only_testing] = Fastlane::Actions::TestsFromJunitAction.run(config)[:failed].map(&:shellsafe_testidentifier)
248
+ @options[:only_testing] = @options[:only_testing] - Fastlane::Actions::TestsFromJunitAction.run(config).fetch(:passing, Hash.new).map(&:shellsafe_testidentifier)
244
249
  if @options[:invocation_based_tests]
245
250
  @options[:only_testing] = @options[:only_testing].map(&:strip_testcase).uniq
246
251
  end
247
252
  end
248
253
 
254
+ def continue_with_build_failure(exception)
255
+ test_session_last_messages = last_lines_of_test_session_log
256
+ failure = retrieve_test_operation_failure(test_session_last_messages)
257
+ case failure
258
+ when /Lost connection to testmanagerd/
259
+ FastlaneCore::UI.important("com.apple.CoreSimulator.CoreSimulatorService may have become corrupt, consider quitting it")
260
+ if @options[:quit_core_simulator_service]
261
+ Fastlane::Actions::RestartCoreSimulatorServiceAction.run
262
+ end
263
+ else
264
+ FastlaneCore::UI.important(test_session_last_messages)
265
+ end
266
+ send_callback_testrun_info(test_operation_failure: failure)
267
+ end
268
+
249
269
  def handle_build_failure(exception)
250
270
  test_session_last_messages = last_lines_of_test_session_log
251
271
  failure = retrieve_test_operation_failure(test_session_last_messages)
@@ -262,11 +282,31 @@ module TestCenter
262
282
  FastlaneCore::UI.error(test_session_last_messages)
263
283
  send_callback_testrun_info(test_operation_failure: failure)
264
284
  raise exception
285
+ FastlaneCore::UI.important(test_session_last_messages)
265
286
  end
266
287
  send_callback_testrun_info(test_operation_failure: failure)
267
288
  end
268
289
 
269
290
  def retrieve_test_operation_failure(test_session_last_messages)
291
+ if FastlaneCore::Helper.xcode_at_least?(11)
292
+ retrieve_test_operation_failure_post_xcode11(test_session_last_messages)
293
+ else
294
+ retrieve_test_operation_failure_pre_xcode11(test_session_last_messages)
295
+ end
296
+ end
297
+
298
+ def retrieve_test_operation_failure_post_xcode11(test_session_last_messages)
299
+ if /Connection peer refused channel request/ =~ test_session_last_messages
300
+ test_operation_failure = 'Lost connection to testmanagerd'
301
+ elsif /Please unlock your device and reattach/ =~ test_session_last_messages
302
+ test_operation_failure = 'Test device locked'
303
+ elsif /Test runner exited before starting test execution/ =~ test_session_last_messages
304
+ test_operation_failure = 'Test runner exited before starting test execution'
305
+ end
306
+ test_operation_failure
307
+ end
308
+
309
+ def retrieve_test_operation_failure_pre_xcode11(test_session_last_messages)
270
310
  test_operation_failure_match = /Test operation failure: (?<test_operation_failure>.*)$/ =~ test_session_last_messages
271
311
  if test_operation_failure_match.nil?
272
312
  test_operation_failure = 'Unknown test operation failure'
@@ -7,7 +7,7 @@ module TestCenter
7
7
  require 'json'
8
8
  require 'shellwords'
9
9
  require 'snapshot/reset_simulators'
10
-
10
+
11
11
  class Runner
12
12
  attr_reader :retry_total_count
13
13
 
@@ -66,12 +66,12 @@ module TestCenter
66
66
  end
67
67
 
68
68
  unless tests_passed || @options[:try_count] < 1
69
- setup_testcollector
69
+ setup_testcollector
70
70
  tests_passed = run_test_batches
71
71
  end
72
72
  tests_passed
73
73
  end
74
-
74
+
75
75
  def should_run_tests_through_single_try?
76
76
  should_run_for_invocation_tests = @options[:invocation_based_tests] && @options[:only_testing].nil?
77
77
  should_run_for_skip_build = @options[:skip_build]
@@ -114,16 +114,16 @@ module TestCenter
114
114
  end
115
115
  @options[:output_directory] = output_directory
116
116
  @options[:destination] = Scan.config[:destination]
117
-
117
+
118
118
  # We do not want Scan.config to _not_ have :device :devices, we want to
119
119
  # use :destination. We remove :force_quit_simulator as we do not want
120
120
  # Scan to handle it as multi_scan takes care of it in its own way
121
121
  options = @options.reject { |key| %i[device devices force_quit_simulator].include?(key) }
122
122
  options[:try_count] = 1
123
-
123
+
124
124
  tests_passed = RetryingScan.run(options)
125
125
  @options[:try_count] -= 1
126
-
126
+
127
127
  reportnamer = ReportNameHelper.new(
128
128
  @options[:output_types],
129
129
  @options[:output_files],
@@ -138,12 +138,12 @@ module TestCenter
138
138
  )
139
139
  @options[:only_testing] = retrieve_failed_single_try_tests
140
140
  @options[:only_testing] = @options[:only_testing].map(&:strip_testcase).uniq
141
-
141
+
142
142
  symlink_result_bundle_to_xcresult(output_directory, reportnamer)
143
143
 
144
144
  tests_passed
145
145
  end
146
-
146
+
147
147
  def retrieve_failed_single_try_tests
148
148
  reportnamer = ReportNameHelper.new(
149
149
  @options[:output_types],
@@ -168,10 +168,10 @@ module TestCenter
168
168
 
169
169
  pool = TestBatchWorkerPool.new(pool_options)
170
170
  pool.setup_workers
171
-
171
+
172
172
  remaining_test_batches = @test_collector.test_batches.clone
173
173
  remaining_test_batches.each_with_index do |test_batch, current_batch_index|
174
- worker = pool.wait_for_worker
174
+ worker = pool.wait_for_worker
175
175
  FastlaneCore::UI.message("Starting test run #{current_batch_index + 1}")
176
176
  worker.run(scan_options_for_worker(test_batch, current_batch_index))
177
177
  end
@@ -189,7 +189,7 @@ module TestCenter
189
189
  batch: batch_index + 1
190
190
  }
191
191
  end
192
-
192
+
193
193
  def collate_batched_reports
194
194
  return unless @batch_count > 1
195
195
  return unless @options[:collate_reports]
@@ -16,11 +16,22 @@ module TestCenter
16
16
  cloned_simulators = []
17
17
 
18
18
  run_count = @options[:parallel_testrun_count] || 0
19
- destination_simulator_ids = Scan.config[:destination].map do |destination|
20
- destination.split(',id=').last
21
- end
22
19
  original_simulators = FastlaneCore::DeviceManager.simulators('iOS').find_all do |simulator|
23
- destination_simulator_ids.include?(simulator.udid)
20
+ found_match = false
21
+ Scan.config[:destination].each do |destination|
22
+ match = destination.match(/id=(?<udid>[^,]+)/)
23
+ if match
24
+ found_match = (match[:udid] == simulator.udid)
25
+ else
26
+ match = destination.match(/name=(?<name>[^,]+)/)
27
+ name = match[:name] || ''
28
+ match = destination.match(/OS=(?<os_version>[^,]+)/)
29
+ os_version = match[:os_version] || ''
30
+
31
+ found_match = (name == simulator.name && os_version == simulator.os_version)
32
+ end
33
+ end
34
+ found_match
24
35
  end
25
36
  original_simulators.each(&:shutdown)
26
37
  (0...run_count).each do |batch_index|
@@ -80,7 +80,7 @@ module TestCenter
80
80
  known_tests += xctestrun_known_tests[testable]
81
81
  test_components = test.split('/')
82
82
  testsuite = test_components.size == 1 ? test_components[0] : test_components[1]
83
- @testables_tests[testable][index] = known_tests.select { |known_test| known_test.include?(testsuite) }
83
+ @testables_tests[testable][index] = known_tests.select { |known_test| known_test.include?(testsuite) }
84
84
  end
85
85
  end
86
86
  @testables_tests[testable].flatten!
@@ -106,7 +106,7 @@ module TestCenter
106
106
  end
107
107
  end
108
108
  end
109
-
109
+
110
110
  @testables_tests
111
111
  end
112
112
 
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.9.0"
3
+ VERSION = "3.9.1.b.1"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane-plugin-test_center
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.9.0
4
+ version: 3.9.1.b.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lyndsey Ferguson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-02-20 00:00:00.000000000 Z
11
+ date: 2020-03-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -302,9 +302,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
302
302
  version: '0'
303
303
  required_rubygems_version: !ruby/object:Gem::Requirement
304
304
  requirements:
305
- - - ">="
305
+ - - ">"
306
306
  - !ruby/object:Gem::Version
307
- version: '0'
307
+ version: 1.3.1
308
308
  requirements: []
309
309
  rubygems_version: 3.0.6
310
310
  signing_key: