fastlane-plugin-test_center 3.6.2 → 3.6.3.parallelizing

Sign up to get free protection for your applications and to get access to all the features.
Files changed (22) hide show
  1. checksums.yaml +5 -5
  2. data/lib/fastlane/plugin/test_center.rb +1 -1
  3. data/lib/fastlane/plugin/test_center/actions/collate_test_result_bundles.rb +1 -1
  4. data/lib/fastlane/plugin/test_center/actions/multi_scan.rb +28 -4
  5. data/lib/fastlane/plugin/test_center/actions/restart_core_simulator_service.rb +37 -0
  6. data/lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb +1 -1
  7. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager.rb +5 -0
  8. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/device_manager.rb +26 -0
  9. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/interstitial.rb +143 -0
  10. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/report_collator.rb +113 -0
  11. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb +72 -0
  12. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb +236 -0
  13. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/runner.rb +272 -0
  14. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_helper.rb +59 -0
  15. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_manager.rb +317 -0
  16. data/lib/fastlane/plugin/test_center/helper/reportname_helper.rb +15 -6
  17. data/lib/fastlane/plugin/test_center/helper/test_collector.rb +47 -3
  18. data/lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb +9 -0
  19. data/lib/fastlane/plugin/test_center/helper/xctestrun_info.rb +42 -0
  20. data/lib/fastlane/plugin/test_center/version.rb +1 -1
  21. metadata +21 -12
  22. data/lib/fastlane/plugin/test_center/helper/correcting_scan_helper.rb +0 -293
@@ -1,3 +1,8 @@
1
+ module TestCenter
2
+ module Helper
3
+ MUST_SHELLESCAPE_TESTIDENTIFIER = Gem::Version.new(Fastlane::VERSION) < Gem::Version.new('2.114.0')
4
+ end
5
+ end
1
6
 
2
7
  class String
3
8
  def testsuite_swift?
@@ -11,4 +16,8 @@ class String
11
16
  self
12
17
  end
13
18
  end
19
+
20
+ def shellsafe_testidentifier
21
+ TestCenter::Helper::MUST_SHELLESCAPE_TESTIDENTIFIER ? self.shellescape : self
22
+ end
14
23
  end
@@ -0,0 +1,42 @@
1
+ module TestCenter
2
+ module Helper
3
+ require 'plist'
4
+
5
+ class XCTestrunInfo
6
+ def initialize(xctestrun_filepath)
7
+ raise Errno::ENOENT, xctestrun_filepath unless File.exist?(xctestrun_filepath)
8
+
9
+ @xctestrun = Plist.parse_xml(xctestrun_filepath)
10
+ @xctestrun_rootpath = File.dirname(xctestrun_filepath)
11
+ end
12
+
13
+ def app_path_for_testable(testable)
14
+ @xctestrun[testable].fetch('UITargetAppPath') do |_|
15
+ @xctestrun[testable]['TestHostPath']
16
+ end.sub('__TESTROOT__', @xctestrun_rootpath)
17
+ end
18
+
19
+ def app_plist_for_testable(testable)
20
+ binary_plistfile = File.join(app_path_for_testable(testable), 'Info.plist')
21
+
22
+ Plist.parse_binary_xml(binary_plistfile)
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ require 'plist'
29
+
30
+ class Hash
31
+ def save_binary_plist(filename, options = {})
32
+ Plist::Emit.save_plist(self, filename)
33
+ `plutil -convert binary1 \"#{filename}\"`
34
+ end
35
+ end
36
+
37
+ module Plist
38
+ def self.parse_binary_xml(filename)
39
+ `plutil -convert xml1 \"#{filename}\"`
40
+ Plist.parse_xml(filename)
41
+ end
42
+ end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
2
  module TestCenter
3
- VERSION = "3.6.2"
3
+ VERSION = "3.6.3.parallelizing"
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.6.2
4
+ version: 3.6.3.parallelizing
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-02-07 00:00:00.000000000 Z
11
+ date: 2019-05-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: json
@@ -67,13 +67,13 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: 1.1.7
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: colorize
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
- type: :development
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: colorize
84
+ name: bundler
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -100,14 +100,14 @@ dependencies:
100
100
  requirements:
101
101
  - - ">="
102
102
  - !ruby/object:Gem::Version
103
- version: 2.56.0
103
+ version: 2.108.0
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
108
  - - ">="
109
109
  - !ruby/object:Gem::Version
110
- version: 2.56.0
110
+ version: 2.108.0
111
111
  - !ruby/object:Gem::Dependency
112
112
  name: pry
113
113
  requirement: !ruby/object:Gem::Requirement
@@ -235,16 +235,26 @@ files:
235
235
  - lib/fastlane/plugin/test_center/actions/collate_junit_reports.rb
236
236
  - lib/fastlane/plugin/test_center/actions/collate_test_result_bundles.rb
237
237
  - lib/fastlane/plugin/test_center/actions/multi_scan.rb
238
+ - lib/fastlane/plugin/test_center/actions/restart_core_simulator_service.rb
238
239
  - lib/fastlane/plugin/test_center/actions/suppress_tests.rb
239
240
  - lib/fastlane/plugin/test_center/actions/suppress_tests_from_junit.rb
240
241
  - lib/fastlane/plugin/test_center/actions/suppressed_tests.rb
241
242
  - lib/fastlane/plugin/test_center/actions/tests_from_junit.rb
242
243
  - lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb
243
- - lib/fastlane/plugin/test_center/helper/correcting_scan_helper.rb
244
244
  - lib/fastlane/plugin/test_center/helper/junit_helper.rb
245
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager.rb
246
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/device_manager.rb
247
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/interstitial.rb
248
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/report_collator.rb
249
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb
250
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb
251
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/runner.rb
252
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_helper.rb
253
+ - lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_manager.rb
245
254
  - lib/fastlane/plugin/test_center/helper/reportname_helper.rb
246
255
  - lib/fastlane/plugin/test_center/helper/test_collector.rb
247
256
  - lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb
257
+ - lib/fastlane/plugin/test_center/helper/xctestrun_info.rb
248
258
  - lib/fastlane/plugin/test_center/version.rb
249
259
  homepage: https://github.com/lyndsey-ferguson/fastlane-plugin-test_center
250
260
  licenses:
@@ -261,12 +271,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
261
271
  version: '0'
262
272
  required_rubygems_version: !ruby/object:Gem::Requirement
263
273
  requirements:
264
- - - ">="
274
+ - - ">"
265
275
  - !ruby/object:Gem::Version
266
- version: '0'
276
+ version: 1.3.1
267
277
  requirements: []
268
- rubyforge_project:
269
- rubygems_version: 2.6.11
278
+ rubygems_version: 3.0.2
270
279
  signing_key:
271
280
  specification_version: 4
272
281
  summary: Makes testing your iOS app easier
@@ -1,293 +0,0 @@
1
- module TestCenter
2
- module Helper
3
- require 'fastlane_core/ui/ui.rb'
4
- require 'plist'
5
- require 'json'
6
- class CorrectingScanHelper
7
- attr_reader :retry_total_count
8
-
9
- def initialize(multi_scan_options)
10
- @batch_count = multi_scan_options[:batch_count] || 1
11
- @output_directory = multi_scan_options[:output_directory] || 'test_results'
12
- @try_count = multi_scan_options[:try_count]
13
- @quit_simulators = multi_scan_options[:quit_simulators]
14
- @retry_total_count = 0
15
- @testrun_completed_block = multi_scan_options[:testrun_completed_block]
16
- @given_custom_report_file_name = multi_scan_options[:custom_report_file_name]
17
- @given_output_types = multi_scan_options[:output_types]
18
- @given_output_files = multi_scan_options[:output_files]
19
- @scan_options = multi_scan_options.reject do |option, _|
20
- %i[
21
- output_directory
22
- only_testing
23
- skip_testing
24
- clean
25
- try_count
26
- batch_count
27
- quit_simulators
28
- custom_report_file_name
29
- fail_build
30
- testrun_completed_block
31
- output_types
32
- output_files
33
- ].include?(option)
34
- end
35
- @scan_options[:clean] = false
36
- @test_collector = TestCollector.new(multi_scan_options)
37
- end
38
-
39
- def scan
40
- tests_passed = true
41
- @testables_count = @test_collector.testables.size
42
- @test_collector.testables.each do |testable|
43
- tests_passed = scan_testable(testable) && tests_passed
44
- end
45
- tests_passed
46
- end
47
-
48
- def scan_testable(testable)
49
- tests_passed = true
50
- reportnamer = ReportNameHelper.new(
51
- @given_output_types,
52
- @given_output_files,
53
- @given_custom_report_file_name
54
- )
55
- output_directory = @output_directory
56
- testable_tests = @test_collector.testables_tests[testable]
57
- if testable_tests.empty?
58
- FastlaneCore::UI.important("There are no tests to run in testable '#{testable}'. Skipping")
59
- return true
60
- end
61
-
62
- if @batch_count > 1 || @testables_count > 1
63
- current_batch = 1
64
- testable_tests.each_slice((testable_tests.length / @batch_count.to_f).round).to_a.each do |tests_batch|
65
- if @testables_count > 1
66
- output_directory = File.join(@output_directory, "results-#{testable}")
67
- end
68
- FastlaneCore::UI.header("Starting test run on testable '#{testable}'")
69
- if @scan_options[:result_bundle]
70
- FastlaneCore::UI.message("Clearing out previous test_result bundles in #{output_directory}")
71
- FileUtils.rm_rf(Dir.glob("#{output_directory}/*.test_result"))
72
- end
73
-
74
- tests_passed = correcting_scan(
75
- {
76
- only_testing: tests_batch,
77
- output_directory: output_directory
78
- },
79
- current_batch,
80
- reportnamer
81
- ) && tests_passed
82
- current_batch += 1
83
- reportnamer.increment
84
- end
85
- else
86
- options = {
87
- output_directory: output_directory,
88
- only_testing: testable_tests
89
- }
90
- tests_passed = correcting_scan(options, 1, reportnamer) && tests_passed
91
- end
92
- collate_reports(output_directory, reportnamer)
93
- tests_passed
94
- end
95
-
96
- def test_result_bundlepaths(output_directory, reportnamer)
97
- [
98
- File.join(output_directory, @scan_options[:scheme]) + '.test_result',
99
- File.join(output_directory, @scan_options[:scheme]) + "_#{reportnamer.report_count}.test_result"
100
- ]
101
- end
102
-
103
- def collate_reports(output_directory, reportnamer)
104
- collate_junit_reports(output_directory, reportnamer)
105
-
106
- if reportnamer.includes_html?
107
- collate_html_reports(output_directory, reportnamer)
108
- end
109
-
110
- if reportnamer.includes_json?
111
- collate_json_reports(output_directory, reportnamer)
112
- end
113
-
114
- if @scan_options[:result_bundle]
115
- collate_test_result_bundles(output_directory, reportnamer)
116
- end
117
- end
118
-
119
- def passed_test_count_from_summary(summary)
120
- /.*Executed (?<test_count>\d+) test, with (?<test_failures>\d+) failure/ =~ summary
121
- test_count.to_i - test_failures.to_i
122
- end
123
-
124
- def collate_test_result_bundles(output_directory, reportnamer)
125
- test_result_bundlepaths = Dir.glob("#{output_directory}/#{@scan_options[:scheme]}*.test_result").map do |relative_test_result_bundle_filepath|
126
- File.absolute_path(relative_test_result_bundle_filepath)
127
- end
128
- if test_result_bundlepaths.size > 1
129
- config = FastlaneCore::Configuration.create(
130
- Fastlane::Actions::CollateTestResultBundlesAction.available_options,
131
- {
132
- bundles: test_result_bundlepaths.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
133
- collated_bundle: File.join(output_directory, @scan_options[:scheme]) + '.test_result'
134
- }
135
- )
136
- Fastlane::Actions::CollateTestResultBundlesAction.run(config)
137
- end
138
- retried_test_result_bundlepaths = Dir.glob("#{output_directory}/#{@scan_options[:scheme]}_*.test_result")
139
- FileUtils.rm_rf(retried_test_result_bundlepaths)
140
- end
141
-
142
- def collate_json_reports(output_directory, reportnamer)
143
- report_filepaths = Dir.glob("#{output_directory}/#{reportnamer.json_fileglob}").map do |relative_filepath|
144
- File.absolute_path(relative_filepath)
145
- end
146
- if report_filepaths.size > 1
147
- config = FastlaneCore::Configuration.create(
148
- Fastlane::Actions::CollateJsonReportsAction.available_options,
149
- {
150
- reports: report_filepaths.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
151
- collated_report: File.absolute_path(File.join(output_directory, reportnamer.json_reportname))
152
- }
153
- )
154
- Fastlane::Actions::CollateJsonReportsAction.run(config)
155
- end
156
- retried_json_reportfiles = Dir.glob("#{output_directory}/#{reportnamer.json_numbered_fileglob}")
157
- FileUtils.rm_f(retried_json_reportfiles)
158
- end
159
-
160
- def collate_html_reports(output_directory, reportnamer)
161
- report_files = Dir.glob("#{output_directory}/#{reportnamer.html_fileglob}").map do |relative_filepath|
162
- File.absolute_path(relative_filepath)
163
- end
164
- if report_files.size > 1
165
- config = FastlaneCore::Configuration.create(
166
- Fastlane::Actions::CollateHtmlReportsAction.available_options,
167
- {
168
- reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
169
- collated_report: File.absolute_path(File.join(output_directory, reportnamer.html_reportname))
170
- }
171
- )
172
- Fastlane::Actions::CollateHtmlReportsAction.run(config)
173
- end
174
- retried_html_reportfiles = Dir.glob("#{output_directory}/#{reportnamer.html_numbered_fileglob}")
175
- FileUtils.rm_f(retried_html_reportfiles)
176
- end
177
-
178
- def collate_junit_reports(output_directory, reportnamer)
179
- report_files = Dir.glob("#{output_directory}/#{reportnamer.junit_fileglob}").map do |relative_filepath|
180
- File.absolute_path(relative_filepath)
181
- end
182
- if report_files.size > 1
183
- config = FastlaneCore::Configuration.create(
184
- Fastlane::Actions::CollateJunitReportsAction.available_options,
185
- {
186
- reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
187
- collated_report: File.absolute_path(File.join(output_directory, reportnamer.junit_reportname))
188
- }
189
- )
190
- Fastlane::Actions::CollateJunitReportsAction.run(config)
191
- end
192
- retried_junit_reportfiles = Dir.glob("#{output_directory}/#{reportnamer.junit_numbered_fileglob}")
193
- FileUtils.rm_f(retried_junit_reportfiles)
194
- end
195
-
196
- def correcting_scan(scan_run_options, batch, reportnamer)
197
- scan_options = @scan_options.merge(scan_run_options)
198
- try_count = 0
199
- tests_passed = true
200
- xcpretty_json_file_output = ENV['XCPRETTY_JSON_FILE_OUTPUT']
201
- begin
202
- try_count += 1
203
- config = FastlaneCore::Configuration.create(
204
- Fastlane::Actions::ScanAction.available_options,
205
- scan_options.merge(reportnamer.scan_options)
206
- )
207
- quit_simulators
208
- if reportnamer.includes_json?
209
- ENV['XCPRETTY_JSON_FILE_OUTPUT'] = File.join(
210
- scan_options[:output_directory],
211
- reportnamer.json_last_reportname
212
- )
213
- end
214
- Fastlane::Actions::ScanAction.run(config)
215
- @testrun_completed_block && @testrun_completed_block.call(
216
- testrun_info(batch, try_count, reportnamer, scan_options[:output_directory])
217
- )
218
- tests_passed = true
219
- rescue FastlaneCore::Interface::FastlaneTestFailure => e
220
- FastlaneCore::UI.verbose("Scan failed with #{e}")
221
- info = testrun_info(batch, try_count, reportnamer, scan_options[:output_directory])
222
- @testrun_completed_block && @testrun_completed_block.call(
223
- info
224
- )
225
- if try_count < @try_count
226
- @retry_total_count += 1
227
- scan_options.delete(:code_coverage)
228
- scan_options[:only_testing] = info[:failed].map(&:shellescape)
229
- FastlaneCore::UI.message('Re-running scan on only failed tests')
230
- reportnamer.increment
231
- if @scan_options[:result_bundle]
232
- built_test_result, moved_test_result = test_result_bundlepaths(
233
- scan_options[:output_directory], reportnamer
234
- )
235
- FileUtils.mv(built_test_result, moved_test_result)
236
- end
237
- retry
238
- end
239
- tests_passed = false
240
- ensure
241
- ENV['XCPRETTY_JSON_FILE_OUTPUT'] = xcpretty_json_file_output
242
- end
243
- tests_passed
244
- end
245
-
246
- def testrun_info(batch, try_count, reportnamer, output_directory)
247
- report_filepath = File.join(output_directory, reportnamer.junit_last_reportname)
248
- config = FastlaneCore::Configuration.create(
249
- Fastlane::Actions::TestsFromJunitAction.available_options,
250
- {
251
- junit: File.absolute_path(report_filepath)
252
- }
253
- )
254
- junit_results = Fastlane::Actions::TestsFromJunitAction.run(config)
255
-
256
- info = {
257
- failed: junit_results[:failed],
258
- passing: junit_results[:passing],
259
- batch: batch,
260
- try_count: try_count,
261
- report_filepath: report_filepath
262
- }
263
- if reportnamer.includes_html?
264
- html_report_filepath = File.join(output_directory, reportnamer.html_last_reportname)
265
- info[:html_report_filepath] = html_report_filepath
266
- end
267
- if reportnamer.includes_json?
268
- json_report_filepath = File.join(output_directory, reportnamer.json_last_reportname)
269
- info[:json_report_filepath] = json_report_filepath
270
- end
271
- if @scan_options[:result_bundle]
272
- test_result_suffix = '.test_result'
273
- test_result_suffix.prepend("_#{reportnamer.report_count}") unless reportnamer.report_count.zero?
274
- test_result_bundlepath = File.join(output_directory, @scan_options[:scheme]) + test_result_suffix
275
- info[:test_result_bundlepath] = test_result_bundlepath
276
- end
277
- info
278
- end
279
-
280
- def quit_simulators
281
- return unless @quit_simulators
282
-
283
- Fastlane::Actions.sh("killall -9 'iPhone Simulator' 'Simulator' 'SimulatorBridge' &> /dev/null || true", log: false)
284
- launchctl_list_count = 0
285
- while Fastlane::Actions.sh('launchctl list | grep com.apple.CoreSimulator.CoreSimulatorService || true', log: false) != ''
286
- break if (launchctl_list_count += 1) > 10
287
- Fastlane::Actions.sh('launchctl remove com.apple.CoreSimulator.CoreSimulatorService &> /dev/null || true', log: false)
288
- sleep(1)
289
- end
290
- end
291
- end
292
- end
293
- end