fastlane-plugin-test_center 3.8.0.parallelizing.beta.7 → 3.8.0.parallelizing.beta.8

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: 7d7647dee8a9311b8e18eeba2a4afbc906d0c751
4
- data.tar.gz: 0074ac993896e002df67534365fe1e367a2bc71d
3
+ metadata.gz: 4e73880166b9ba845963df59878b80eba77ca64d
4
+ data.tar.gz: 182b6aea7cbb03dfd121efc35dc832ca85a1bb6c
5
5
  SHA512:
6
- metadata.gz: 2da85b784f6d88a4b0022c07ec3d6b2def13c1a7f47d8634ae1a665255d814de59c783ff85d39765fdc523cba1bb260200c01f314d25cff846cd946747425f7c
7
- data.tar.gz: 8fdec1723d3d712a5907c240a0121997553b3aa5750cd2eb856721d7b09e7a2f14d7358f41eb730522993508fa190e37d05e1ac34cb60249292d9eb0a853c0e4
6
+ metadata.gz: 8d6998f5f5f3515b8aaf10c75a2b804e32e192088be2323ff442208034c01568c013122a8db9c602856fce420f66983eeaf3b32769b7ddcbbb522ffdbb758d86
7
+ data.tar.gz: cd1f2ff6cbe717c40564514dff042a747a082d5e82e33212cdab478c83899d788154f867d16f23964669e38a0e7231b9bc7cfee9e3c54b46ff7806fa75653cd4
@@ -5,27 +5,18 @@ module Fastlane
5
5
  require 'shellwords'
6
6
  require 'xctest_list'
7
7
  require 'plist'
8
- require_relative '../helper/multi_scan_manager/runner'
9
8
 
10
9
  class MultiScanAction < Action
11
10
  def self.run(params)
12
- # :nocov:
13
- unless Helper.test?
14
- scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
15
- FastlaneCore::PrintTable.print_values(
16
- config: params._values.reject { |k, _| scan_keys.include?(k) },
17
- title: "Summary for multi_scan (test_center v#{Fastlane::TestCenter::VERSION})"
18
- )
19
- end
20
- # :nocov:
21
11
  params[:quit_simulators] ||= params._values[:force_quit_simulator]
22
12
 
13
+ print_multi_scan_parameters(params)
23
14
  force_quit_simulator_processes if params[:quit_simulators]
24
15
 
25
16
  prepare_for_testing(params.values)
26
17
 
27
18
  platform = :mac
28
- platform = :ios if Scan.config[:destination].any? { |d| d.include?('platform=iOS Simulator') }
19
+ platform = :ios_simulator if Scan.config[:destination].any? { |d| d.include?('platform=iOS Simulator') }
29
20
 
30
21
  runner_options = params.values.merge(platform: platform)
31
22
  runner = ::TestCenter::Helper::MultiScanManager::Runner.new(runner_options)
@@ -35,14 +26,7 @@ module Fastlane
35
26
  end
36
27
 
37
28
  summary = run_summary(params, tests_passed, runner.retry_total_count)
38
- # :nocov:
39
- unless Helper.test?
40
- FastlaneCore::PrintTable.print_values(
41
- config: summary,
42
- title: "multi_scan results"
43
- )
44
- end
45
- # :nocov:
29
+ print_run_summary(summary)
46
30
 
47
31
  if params[:fail_build] && !tests_passed
48
32
  raise UI.test_failure!('Tests have failed')
@@ -50,6 +34,28 @@ module Fastlane
50
34
  summary
51
35
  end
52
36
 
37
+ def self.print_multi_scan_parameters(params)
38
+ return if Helper.test?
39
+ # :nocov:
40
+ scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
41
+ FastlaneCore::PrintTable.print_values(
42
+ config: params._values.reject { |k, _| scan_keys.include?(k) },
43
+ title: "Summary for multi_scan (test_center v#{Fastlane::TestCenter::VERSION})"
44
+ )
45
+ # :nocov:
46
+ end
47
+
48
+ def self.print_run_summary(summary)
49
+ return if Helper.test?
50
+
51
+ # :nocov:
52
+ FastlaneCore::PrintTable.print_values(
53
+ config: summary,
54
+ title: "multi_scan results"
55
+ )
56
+ # :nocov:
57
+ end
58
+
53
59
  def self.run_summary(scan_options, tests_passed, retry_total_count)
54
60
  reportnamer = ::TestCenter::Helper::ReportNameHelper.new(
55
61
  scan_options[:output_types],
@@ -98,8 +104,10 @@ module Fastlane
98
104
 
99
105
  def self.prepare_for_testing(scan_options)
100
106
  if scan_options[:test_without_building] || scan_options[:skip_build]
107
+ UI.verbose("Preparing Scan config options for multi_scan testing")
101
108
  prepare_scan_config(scan_options)
102
109
  else
110
+ UI.verbose("Building the project in preparation for multi_scan testing")
103
111
  build_for_testing(scan_options)
104
112
  end
105
113
  end
@@ -113,15 +121,7 @@ module Fastlane
113
121
 
114
122
  def self.build_for_testing(scan_options)
115
123
  values = prepare_scan_options_for_build_for_testing(scan_options)
116
- # :nocov:
117
- unless Helper.test?
118
- FastlaneCore::PrintTable.print_values(
119
- config: values,
120
- hide_keys: [:destination, :slack_url],
121
- title: "Summary for scan #{Fastlane::VERSION}"
122
- )
123
- end
124
- # :nocov:
124
+ ScanHelper.print_scan_parameters(values)
125
125
 
126
126
  remove_preexisting_xctestrun_files
127
127
  Scan::Runner.new.run
@@ -146,21 +146,30 @@ module Fastlane
146
146
  end
147
147
 
148
148
  def self.update_xctestrun_after_build(scan_options)
149
- scan_options[:xctestrun] = Dir.glob("#{Scan.config[:derived_data_path]}/Build/Products/*.xctestrun").first
149
+ xctestrun_files = Dir.glob("#{Scan.config[:derived_data_path]}/Build/Products/*.xctestrun")
150
+ UI.verbose("After building, found xctestrun files #{xctestrun_files} (choosing 1st)")
151
+ scan_options[:xctestrun] = xctestrun_files.first
150
152
  end
151
153
 
152
154
  def self.remove_preexisting_xctestrun_files
153
155
  xctestrun_files = Dir.glob("#{Scan.config[:derived_data_path]}/Build/Products/*.xctestrun")
156
+ UI.verbose("Before building, removing pre-existing xctestrun files: #{xctestrun_files}")
154
157
  FileUtils.rm_rf(xctestrun_files)
155
158
  end
156
159
 
157
160
  def self.remove_build_report_files
161
+ # When Scan builds, it generates empty report files. Trying to collate
162
+ # subsequent, valid, report files with the empty report file will fail
163
+ # because there is no shared XML elements
158
164
  report_options = Scan::XCPrettyReporterOptionsGenerator.generate_from_scan_config
159
165
  output_files = report_options.instance_variable_get(:@output_files)
160
166
  output_directory = report_options.instance_variable_get(:@output_directory)
161
167
 
168
+ UI.verbose("Removing report files generated by the build")
162
169
  output_files.each do |output_file|
163
- FileUtils.rm_f(File.join(output_directory, output_file))
170
+ report_file = File.join(output_directory, output_file)
171
+ UI.verbose(" #{report_file}")
172
+ FileUtils.rm_f(report_file)
164
173
  end
165
174
  end
166
175
 
@@ -198,6 +207,8 @@ module Fastlane
198
207
  end
199
208
 
200
209
  def self.scan_options
210
+ # multi_scan has its own enhanced version of `output_types` and we want to provide
211
+ # the help and validation for that new version.
201
212
  ScanAction.available_options.reject { |config| %i[output_types].include?(config.key) }
202
213
  end
203
214
 
@@ -234,7 +245,7 @@ module Fastlane
234
245
  conflict_block: proc do |value|
235
246
  UI.user_error!(
236
247
  "Error: Can't use 'invocation_based_tests' and 'batch_count' options in one run, "\
237
- "because the number of tests is unkown.")
248
+ "because the number of tests is unknown")
238
249
  end
239
250
  ),
240
251
  FastlaneCore::ConfigItem.new(
@@ -272,7 +283,7 @@ module Fastlane
272
283
  ),
273
284
  FastlaneCore::ConfigItem.new(
274
285
  key: :testrun_completed_block,
275
- description: 'A block invoked each time a test run completes',
286
+ description: 'A block invoked each time a test run completes. When combined with :parallel_testrun_count, will be called separately in each child process',
276
287
  optional: true,
277
288
  is_string: false,
278
289
  default_value: nil,
@@ -1,3 +1,10 @@
1
+ require_relative 'multi_scan_manager/device_manager'
2
+ require_relative 'multi_scan_manager/parallel_test_batch_worker'
1
3
  require_relative 'multi_scan_manager/report_collator'
4
+ require_relative 'multi_scan_manager/retrying_scan_helper.rb'
5
+ require_relative 'multi_scan_manager/retrying_scan'
2
6
  require_relative 'multi_scan_manager/runner'
7
+ require_relative 'multi_scan_manager/simulator_helper'
8
+ require_relative 'multi_scan_manager/test_batch_worker_pool'
9
+ require_relative 'multi_scan_manager/test_batch_worker'
3
10
  require_relative 'xctestrun_info'
@@ -1,13 +1,20 @@
1
1
  module TestCenter
2
2
  module Helper
3
3
  module MultiScanManager
4
- class ParallelTestBatchWorker < TestBatchWorker
4
+ require 'colorize'
5
5
 
6
+
7
+ class ParallelTestBatchWorker < TestBatchWorker
8
+
6
9
  attr_reader :pid
7
-
10
+
8
11
  def initialize(options)
9
12
  super(options)
10
13
  @pipe_endpoint = nil
14
+
15
+ @@colors ||= String.colors - %i[white black light_green default]
16
+ @color = @@colors.sample
17
+ @@colors = @@colors - [@color]
11
18
  end
12
19
 
13
20
  def state=(new_state)
@@ -15,9 +22,16 @@ module TestCenter
15
22
  end
16
23
 
17
24
  def process_results
25
+ # This is performed in the Parent process
18
26
  @pid = nil
27
+
28
+ worker_prefix = "[worker #{@options[:batch_index] + 1}] "
19
29
  File.foreach(@log_filepath) do |line|
20
- puts "[worker #{@options[:batch_index] + 1}] #{line}"
30
+ unless FastlaneCore::Helper.colors_disabled?
31
+ worker_prefix = worker_prefix.colorize(@color)
32
+ end
33
+ print worker_prefix
34
+ print line
21
35
  end
22
36
  state = :ready_to_work
23
37
  @options[:test_batch_results] << (@reader.gets == 'true')
@@ -44,6 +58,11 @@ module TestCenter
44
58
  end
45
59
 
46
60
  def open_interprocess_communication
61
+ # This is performed in the Parent process in preparation to setup
62
+ # the STDOUT and STDOUT for printing messages from the Child process
63
+ # to a file. This is done so that when multiple processes write
64
+ # messages, they will not be written to the console in a broken
65
+ # interlaced manner.
47
66
  @reader, @writer = IO.pipe
48
67
  @log_filepath = File.join(
49
68
  Dir.mktmpdir,
@@ -52,7 +71,8 @@ module TestCenter
52
71
  end
53
72
 
54
73
  def reroute_stdout_to_logfile
55
- @reader.close # we are now in the subprocess
74
+ @reader.close # we are now in the subprocess. Write all stdout to the
75
+ # log file to prevent interlaced messages
56
76
  @logfile = File.open(@log_filepath, 'w')
57
77
  @logfile.sync = true
58
78
  $stdout.reopen(@logfile)
@@ -60,6 +80,7 @@ module TestCenter
60
80
  end
61
81
 
62
82
  def handle_child_process_results(tests_passed)
83
+ # as suggested by the method name, this is done in the Child process
63
84
  @logfile.close
64
85
  @writer.puts tests_passed.to_s
65
86
  @writer.close
@@ -72,5 +93,3 @@ module TestCenter
72
93
  end
73
94
  end
74
95
  end
75
-
76
-
@@ -17,6 +17,7 @@ module TestCenter
17
17
  end
18
18
 
19
19
  def collate
20
+ FastlaneCore::UI.verbose("ReportCollator collating")
20
21
  collate_junit_reports
21
22
  collate_html_reports
22
23
  collate_json_reports
@@ -46,6 +47,7 @@ module TestCenter
46
47
  report_files = sort_globbed_files(glob)
47
48
  collated_file = File.absolute_path(File.join(@output_directory, @reportnamer.junit_reportname(@suffix)))
48
49
  if report_files.size > 1
50
+ FastlaneCore::UI.verbose("Collating junit report files #{report_files}")
49
51
  config = create_config(
50
52
  CollateJunitReportsAction,
51
53
  {
@@ -56,6 +58,7 @@ module TestCenter
56
58
  CollateJunitReportsAction.run(config)
57
59
  FileUtils.rm_rf(report_files - [collated_file])
58
60
  elsif report_files.size == 1 && report_files.first != collated_file
61
+ FastlaneCore::UI.verbose("Copying junit report file #{report_files.first}")
59
62
  FileUtils.mkdir_p(File.dirname(collated_file))
60
63
  FileUtils.mv(report_files.first, collated_file)
61
64
  end
@@ -67,6 +70,7 @@ module TestCenter
67
70
  report_files = sort_globbed_files("#{@source_reports_directory_glob}/#{@reportnamer.html_fileglob}")
68
71
  collated_file = File.absolute_path(File.join(@output_directory, @reportnamer.html_reportname(@suffix)))
69
72
  if report_files.size > 1
73
+ FastlaneCore::UI.verbose("Collating html report files #{report_files}")
70
74
  config = create_config(
71
75
  CollateJunitReportsAction,
72
76
  {
@@ -77,6 +81,7 @@ module TestCenter
77
81
  CollateHtmlReportsAction.run(config)
78
82
  FileUtils.rm_rf(report_files - [collated_file])
79
83
  elsif report_files.size == 1 && report_files.first != collated_file
84
+ FastlaneCore::UI.verbose("Copying html report file #{report_files.first}")
80
85
  FileUtils.mkdir_p(File.dirname(collated_file))
81
86
  FileUtils.mv(report_files.first, collated_file)
82
87
  end
@@ -88,6 +93,7 @@ module TestCenter
88
93
  report_files = sort_globbed_files("#{@source_reports_directory_glob}/#{@reportnamer.json_fileglob}")
89
94
  collated_file = File.absolute_path(File.join(@output_directory, @reportnamer.json_reportname(@suffix)))
90
95
  if report_files.size > 1
96
+ FastlaneCore::UI.verbose("Collating json report files #{report_files}")
91
97
  config = create_config(
92
98
  CollateJsonReportsAction,
93
99
  {
@@ -98,6 +104,7 @@ module TestCenter
98
104
  CollateJsonReportsAction.run(config)
99
105
  FileUtils.rm_rf(report_files - [collated_file])
100
106
  elsif report_files.size == 1 && report_files.first != collated_file
107
+ FastlaneCore::UI.verbose("Copying json report file #{report_files.first}")
101
108
  FileUtils.mkdir_p(File.dirname(collated_file))
102
109
  FileUtils.mv(report_files.first, collated_file)
103
110
  end
@@ -109,6 +116,7 @@ module TestCenter
109
116
  test_result_bundlepaths = sort_globbed_files("#{@source_reports_directory_glob}/#{@scheme}*.test_result")
110
117
  collated_test_result_bundlepath = File.absolute_path("#{File.join(@output_directory, @scheme)}.test_result")
111
118
  if test_result_bundlepaths.size > 1
119
+ FastlaneCore::UI.verbose("Collating test_result bundles #{test_result_bundlepaths}")
112
120
  config = create_config(
113
121
  CollateTestResultBundlesAction,
114
122
  {
@@ -119,6 +127,7 @@ module TestCenter
119
127
  CollateTestResultBundlesAction.run(config)
120
128
  FileUtils.rm_rf(test_result_bundlepaths - [collated_test_result_bundlepath])
121
129
  elsif test_result_bundlepaths.size == 1 && test_result_bundlepaths.first != collated_test_result_bundlepath
130
+ FastlaneCore::UI.verbose("Copying test_result bundle #{test_result_bundlepaths.first}")
122
131
  FileUtils.mkdir_p(File.dirname(collated_test_result_bundlepath))
123
132
  FileUtils.mv(test_result_bundlepaths.first, collated_test_result_bundlepath)
124
133
  end
@@ -44,28 +44,21 @@ module TestCenter
44
44
  def run
45
45
  try_count = @options[:try_count] || 1
46
46
  begin
47
- # TODO move delete_xcresults to `before_testrun`
48
47
  @retrying_scan_helper.before_testrun
49
48
  update_scan_options
50
49
 
51
50
  values = scan_config.values(ask: false)
52
51
  values[:xcode_path] = File.expand_path("../..", FastlaneCore::Helper.xcode_path)
53
- FastlaneCore::PrintTable.print_values(
54
- config: values,
55
- hide_keys: [:destination, :slack_url],
56
- title: "Summary for scan #{Fastlane::VERSION}"
57
- ) unless FastlaneCore::Helper.test?
52
+ ScanHelper.print_scan_parameters(values)
58
53
 
59
54
  Scan::Runner.new.run
60
55
  @retrying_scan_helper.after_testrun
61
56
  true
62
57
  rescue FastlaneCore::Interface::FastlaneTestFailure => e
63
- FastlaneCore::UI.message("retrying_scan after test failure")
64
58
  @retrying_scan_helper.after_testrun(e)
65
59
  retry if @retrying_scan_helper.testrun_count < try_count
66
60
  false
67
61
  rescue FastlaneCore::Interface::FastlaneBuildFailure => e
68
- FastlaneCore::UI.message("retrying_scan after build failure")
69
62
  @retrying_scan_helper.after_testrun(e)
70
63
  retry if @retrying_scan_helper.testrun_count < try_count
71
64
  false
@@ -1,8 +1,6 @@
1
1
  module TestCenter
2
2
  module Helper
3
3
  module MultiScanManager
4
- require_relative 'device_manager'
5
-
6
4
  class RetryingScanHelper
7
5
 
8
6
  attr_reader :testrun_count
@@ -19,7 +17,7 @@ module TestCenter
19
17
  @options[:custom_report_file_name]
20
18
  )
21
19
  end
22
-
20
+
23
21
  def before_testrun
24
22
  delete_xcresults # has to be performed _after_ moving a *.test_result
25
23
  quit_simulator
@@ -32,7 +30,9 @@ module TestCenter
32
30
 
33
31
  @options.fetch(:destination).each do |destination|
34
32
  if /id=(?<udid>\w+),?/ =~ destination
33
+ FastlaneCore::UI.verbose("Restarting Simulator #{udid}")
35
34
  `xcrun simctl shutdown #{udid} 2>/dev/null`
35
+ `xcrun simctl boot #{udid} 2>/dev/null`
36
36
  end
37
37
  end
38
38
  end
@@ -40,7 +40,10 @@ module TestCenter
40
40
  def delete_xcresults
41
41
  derived_data_path = File.expand_path(@options[:derived_data_path] || Scan.config[:derived_data_path])
42
42
  xcresults = Dir.glob("#{derived_data_path}/Logs/Test/*.xcresult")
43
- FastlaneCore::UI.message("Deleting xcresults: #{xcresults}")
43
+ FastlaneCore::UI.verbose("Deleting xcresults:")
44
+ xcresults.each do |xcresult|
45
+ FastlaneCore::UI.verbose(" #{xcresult}")
46
+ end
44
47
  FileUtils.rm_rf(xcresults)
45
48
  end
46
49
 
@@ -61,10 +64,12 @@ module TestCenter
61
64
  def set_json_env
62
65
  return unless @reportnamer.includes_json?
63
66
 
64
- ENV['XCPRETTY_JSON_FILE_OUTPUT'] = File.join(
67
+ xcpretty_json_file_output = File.join(
65
68
  output_directory,
66
69
  @reportnamer.json_last_reportname
67
70
  )
71
+ FastlaneCore::UI.verbose("Setting the XCPRETTY_JSON_FILE_OUTPUT to #{xcpretty_json_file_output}")
72
+ ENV['XCPRETTY_JSON_FILE_OUTPUT'] = xcpretty_json_file_output
68
73
  end
69
74
 
70
75
  def reset_json_env
@@ -91,10 +96,22 @@ module TestCenter
91
96
  def after_testrun(exception = nil)
92
97
  @testrun_count = @testrun_count + 1
93
98
  if exception.kind_of?(FastlaneCore::Interface::FastlaneTestFailure)
99
+ after_testrun_message = "Scan found failing tests"
100
+ after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
101
+ FastlaneCore::UI.verbose(after_testrun_message)
102
+
94
103
  handle_test_failure
95
104
  elsif exception.kind_of?(FastlaneCore::Interface::FastlaneBuildFailure)
105
+ after_testrun_message = "Scan unable to test"
106
+ after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
107
+ FastlaneCore::UI.verbose(after_testrun_message)
108
+
96
109
  handle_build_failure(exception)
97
110
  else
111
+ after_testrun_message = "Scan passed the tests"
112
+ after_testrun_message << " for batch ##{@options[:batch]}" unless @options[:batch].nil?
113
+ FastlaneCore::UI.verbose(after_testrun_message)
114
+
98
115
  handle_success
99
116
  end
100
117
  collate_reports
@@ -130,18 +147,7 @@ module TestCenter
130
147
  return unless @options[:testrun_completed_block]
131
148
 
132
149
  report_filepath = nil
133
- junit_results = {}
134
- unless additional_info.key?(:test_operation_failure)
135
- report_filepath = File.join(output_directory, @reportnamer.junit_last_reportname)
136
-
137
- config = FastlaneCore::Configuration.create(
138
- Fastlane::Actions::TestsFromJunitAction.available_options,
139
- {
140
- junit: File.absolute_path(report_filepath)
141
- }
142
- )
143
- junit_results = Fastlane::Actions::TestsFromJunitAction.run(config)
144
- end
150
+ junit_results, report_filepath = failure_details(additional_info)
145
151
 
146
152
  info = {
147
153
  failed: junit_results[:failed],
@@ -151,23 +157,51 @@ module TestCenter
151
157
  report_filepath: report_filepath
152
158
  }.merge(additional_info)
153
159
 
154
- if @reportnamer.includes_html?
155
- html_report_filepath = File.join(output_directory, @reportnamer.html_last_reportname)
156
- info[:html_report_filepath] = html_report_filepath
157
- end
158
- if @reportnamer.includes_json?
159
- json_report_filepath = File.join(output_directory, @reportnamer.json_last_reportname)
160
- info[:json_report_filepath] = json_report_filepath
161
- end
162
- if @options[:result_bundle]
163
- test_result_suffix = '.test_result'
164
- test_result_suffix.prepend("-#{@reportnamer.report_count}") unless @reportnamer.report_count.zero?
165
- test_result_bundlepath = File.join(output_directory, @options[:scheme]) + test_result_suffix
166
- info[:test_result_bundlepath] = test_result_bundlepath
167
- end
160
+ update_html_failure_details(info)
161
+ update_json_failure_details(info)
162
+ update_test_result_bundle_details(info)
163
+
168
164
  @options[:testrun_completed_block].call(info)
169
165
  end
170
166
 
167
+ def failure_details(additional_info)
168
+ return [{}, nil] if additional_info.key?(:test_operation_failure)
169
+
170
+ report_filepath = File.join(output_directory, @reportnamer.junit_last_reportname)
171
+ config = FastlaneCore::Configuration.create(
172
+ Fastlane::Actions::TestsFromJunitAction.available_options,
173
+ {
174
+ junit: File.absolute_path(report_filepath)
175
+ }
176
+ )
177
+ junit_results = Fastlane::Actions::TestsFromJunitAction.run(config)
178
+
179
+ [junit_results, report_filepath]
180
+ end
181
+
182
+ def update_html_failure_details(info)
183
+ return unless @reportnamer.includes_html?
184
+
185
+ html_report_filepath = File.join(output_directory, @reportnamer.html_last_reportname)
186
+ info[:html_report_filepath] = html_report_filepath
187
+ end
188
+
189
+ def update_json_failure_details(info)
190
+ return unless @reportnamer.includes_json?
191
+
192
+ json_report_filepath = File.join(output_directory, @reportnamer.json_last_reportname)
193
+ info[:json_report_filepath] = json_report_filepath
194
+ end
195
+
196
+ def update_test_result_bundle_details(info)
197
+ return unless @options[:result_bundle]
198
+
199
+ test_result_suffix = '.test_result'
200
+ test_result_suffix.prepend("-#{@reportnamer.report_count}") unless @reportnamer.report_count.zero?
201
+ test_result_bundlepath = File.join(output_directory, @options[:scheme]) + test_result_suffix
202
+ info[:test_result_bundlepath] = test_result_bundlepath
203
+ end
204
+
171
205
  def update_scan_options
172
206
  update_only_testing
173
207
  turn_off_code_coverage
@@ -193,30 +227,32 @@ module TestCenter
193
227
  end
194
228
  end
195
229
 
196
- def handle_build_failure(exception)
197
- test_operation_failure = ''
198
-
230
+ def handle_build_failure(exception)
199
231
  test_session_last_messages = last_lines_of_test_session_log
200
- test_operation_failure_match = /Test operation failure: (?<test_operation_failure>.*)$/ =~ test_session_last_messages
201
- if test_operation_failure_match.nil?
202
- test_operation_failure = 'Unknown test operation failure'
203
- end
204
-
205
- case test_operation_failure
232
+ failure = retrieve_test_operation_failure(test_session_last_messages)
233
+ case failure
206
234
  when /Test runner exited before starting test execution/
207
- FastlaneCore::UI.error(test_operation_failure)
235
+ FastlaneCore::UI.error(failure)
208
236
  when /Lost connection to testmanagerd/
209
- FastlaneCore::UI.error(test_operation_failure)
237
+ FastlaneCore::UI.error(failure)
210
238
  FastlaneCore::UI.important("com.apple.CoreSimulator.CoreSimulatorService may have become corrupt, consider quitting it")
211
239
  if @options[:quit_core_simulator_service]
212
240
  Fastlane::Actions::RestartCoreSimulatorServiceAction.run
213
241
  end
214
242
  else
215
243
  FastlaneCore::UI.error(test_session_last_messages)
216
- send_callback_testrun_info(test_operation_failure: test_operation_failure)
244
+ send_callback_testrun_info(test_operation_failure: failure)
217
245
  raise exception
218
246
  end
219
- send_callback_testrun_info(test_operation_failure: test_operation_failure)
247
+ send_callback_testrun_info(test_operation_failure: failure)
248
+ end
249
+
250
+ def retrieve_test_operation_failure(test_session_last_messages)
251
+ test_operation_failure_match = /Test operation failure: (?<test_operation_failure>.*)$/ =~ test_session_last_messages
252
+ if test_operation_failure_match.nil?
253
+ test_operation_failure = 'Unknown test operation failure'
254
+ end
255
+ test_operation_failure
220
256
  end
221
257
 
222
258
  def last_lines_of_test_session_log
@@ -44,7 +44,7 @@ module TestCenter
44
44
 
45
45
  tests_passed = false
46
46
  if @options[:invocation_based_tests] && @options[:only_testing].nil?
47
- tests_passed = run_invocation_based_tests
47
+ tests_passed = run_first_run_of_invocation_based_tests
48
48
  end
49
49
 
50
50
  unless tests_passed || @options[:try_count] < 1
@@ -58,14 +58,24 @@ module TestCenter
58
58
 
59
59
  glob_pattern = "#{output_directory}/**/*.test_result"
60
60
  preexisting_test_result_bundles = Dir.glob(glob_pattern)
61
- FileUtils.rm_rf(preexisting_test_result_bundles)
61
+ if preexisting_test_result_bundles.size > 0
62
+ FastlaneCore::UI.verbose("Removing pre-existing test_result bundles: ")
63
+ preexisting_test_result_bundles.each do |test_result_bundle|
64
+ FastlaneCore::UI.verbose(" #{test_result_bundle}")
65
+ end
66
+ FileUtils.rm_rf(preexisting_test_result_bundles)
67
+ end
62
68
  end
63
69
 
64
- def run_invocation_based_tests
70
+ def run_first_run_of_invocation_based_tests
71
+ FastlaneCore::UI.verbose("Running invocation tests")
65
72
  @options[:skip_testing] = @options[:skip_testing]&.map(&:strip_testcase)&.uniq
66
73
  @options[:output_directory] = output_directory
67
74
  @options[:destination] = Scan.config[:destination]
68
75
 
76
+ # We do not want Scan.config to _not_ have :device :devices, we want to
77
+ # use :destination. We remove :force_quit_simulator as we do not want
78
+ # Scan to handle it as multi_scan takes care of it in its own way
69
79
  options = @options.reject { |key| %i[device devices force_quit_simulator].include?(key) }
70
80
  options[:try_count] = 1
71
81
 
@@ -84,12 +94,28 @@ module TestCenter
84
94
  junit: File.absolute_path(report_filepath)
85
95
  }
86
96
  )
87
- @options[:only_testing] = Fastlane::Actions::TestsFromJunitAction.run(config)[:failed]
97
+ @options[:only_testing] = retrieve_failed_invocation_tests[:failed]
88
98
  @options[:only_testing] = @options[:only_testing].map(&:strip_testcase).uniq
89
99
 
90
100
  tests_passed
91
101
  end
92
102
 
103
+ def retrieve_failed_invocation_tests
104
+ reportnamer = ReportNameHelper.new(
105
+ @options[:output_types],
106
+ @options[:output_files],
107
+ @options[:custom_report_file_name]
108
+ )
109
+ report_filepath = File.join(output_directory, reportnamer.junit_last_reportname)
110
+ config = FastlaneCore::Configuration.create(
111
+ Fastlane::Actions::TestsFromJunitAction.available_options,
112
+ {
113
+ junit: File.absolute_path(report_filepath)
114
+ }
115
+ )
116
+ Fastlane::Actions::TestsFromJunitAction.run(config)
117
+ end
118
+
93
119
  def run_test_batches
94
120
  test_batch_results = []
95
121
  pool_options = @options.reject { |key| %i[device devices force_quit_simulator].include?(key) }
@@ -141,6 +167,8 @@ module TestCenter
141
167
  end
142
168
 
143
169
  def collate_batched_reports_for_testable(testable)
170
+ FastlaneCore::UI.verbose("Collating results for all batches")
171
+
144
172
  absolute_output_directory = File.join(
145
173
  File.absolute_path(output_directory),
146
174
  testable
@@ -169,4 +197,3 @@ module TestCenter
169
197
  end
170
198
  end
171
199
  end
172
-
@@ -19,7 +19,7 @@ module TestCenter
19
19
  end
20
20
 
21
21
  def setup_cloned_simulators
22
- return [] unless @options[:platform] == :ios
22
+ return [] unless @options[:platform] == :ios_simulator
23
23
 
24
24
  @simhelper = SimulatorHelper.new(
25
25
  parallel_testrun_count: @options[:parallel_testrun_count]
@@ -38,7 +38,7 @@ module TestCenter
38
38
 
39
39
  def destination_for_worker(worker_index)
40
40
  # each worker has its own simulators to work with
41
- return @options[:destination] unless @options[:platform] == :ios
41
+ return @options[:destination] unless @options[:platform] == :ios_simulator
42
42
 
43
43
  @clones[worker_index].map do |simulator|
44
44
  "platform=iOS Simulator,id=#{simulator.udid}"
@@ -85,9 +85,7 @@ module TestCenter
85
85
  def setup_serial_workers
86
86
  serial_scan_options = @options.reject { |key| %i[device devices].include?(key) }
87
87
  serial_scan_options[:destination] ||= Scan&.config&.fetch(:destination)
88
- @workers = [
89
- TestBatchWorker.new(serial_scan_options)
90
- ]
88
+ @workers = [ TestBatchWorker.new(serial_scan_options) ]
91
89
  end
92
90
 
93
91
  def wait_for_worker
@@ -0,0 +1,13 @@
1
+ module ScanHelper
2
+ def self.print_scan_parameters(params)
3
+ return if FastlaneCore::Helper.test?
4
+
5
+ # :nocov:
6
+ FastlaneCore::PrintTable.print_values(
7
+ config: params,
8
+ hide_keys: [:destination, :slack_url],
9
+ title: "Summary for scan #{Fastlane::VERSION}"
10
+ )
11
+ # :nocov:
12
+ end
13
+ end
@@ -31,8 +31,7 @@ module TestCenter
31
31
 
32
32
  def derived_testrun_path(derived_data_path, scheme)
33
33
  xctestrun_files = Dir.glob("#{derived_data_path}/Build/Products/*.xctestrun")
34
- xctestrun_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) }
35
- .last
34
+ xctestrun_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) }.last
36
35
  end
37
36
 
38
37
  def testables
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.8.0.parallelizing.beta.7"
3
+ VERSION = "3.8.0.parallelizing.beta.8"
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.8.0.parallelizing.beta.7
4
+ version: 3.8.0.parallelizing.beta.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lyndsey Ferguson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-07-07 00:00:00.000000000 Z
11
+ date: 2019-07-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -267,6 +267,7 @@ files:
267
267
  - lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker.rb
268
268
  - lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb
269
269
  - lib/fastlane/plugin/test_center/helper/reportname_helper.rb
270
+ - lib/fastlane/plugin/test_center/helper/scan_helper.rb
270
271
  - lib/fastlane/plugin/test_center/helper/test_collector.rb
271
272
  - lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb
272
273
  - lib/fastlane/plugin/test_center/helper/xctestrun_info.rb