fastlane-plugin-test_center 2.3.1 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 270262acce80a1f4e13f63b7e3926d3a2664932b
|
4
|
+
data.tar.gz: 42ccbeb22f3661ef6c770f4f020a2e72c44b68da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aaefef06f68566da00b2bd6e4c6ffaeb0e734e0cf9b1f2eb2b504c08c7e7dba6f1189d8d0061f45ea54821fb65094949c3433a2836b596ec5066985aa0b387eb
|
7
|
+
data.tar.gz: e258386f7567d2e2c4297628c73e97f0387446632bea9c05bd31c6da0feab3fcd74e3bf6cf48cce5e3629312f1df2ec0dc638062ead05d0312b73f59012384be
|
@@ -2,11 +2,12 @@ module Fastlane
|
|
2
2
|
module Actions
|
3
3
|
require 'fastlane/actions/scan'
|
4
4
|
require 'shellwords'
|
5
|
+
require 'xctest_list'
|
6
|
+
require 'plist'
|
5
7
|
|
6
8
|
class MultiScanAction < Action
|
7
9
|
def self.run(params)
|
8
|
-
|
9
|
-
scan_options = params.values.reject { |k| k == :try_count }
|
10
|
+
scan_options = params.values.reject { |k| %i[try_count batch_count].include?(k) }
|
10
11
|
|
11
12
|
unless Helper.test?
|
12
13
|
FastlaneCore::PrintTable.print_values(
|
@@ -23,21 +24,38 @@ module Fastlane
|
|
23
24
|
scan_options[:test_without_building] = true
|
24
25
|
end
|
25
26
|
|
27
|
+
batch_count = params[:batch_count]
|
28
|
+
if batch_count == 1
|
29
|
+
try_scan_with_retry(scan_options, params[:try_count])
|
30
|
+
else
|
31
|
+
tests = tests_to_batch(scan_options)
|
32
|
+
tests.each_slice((tests.length / batch_count.to_f).round).to_a.each do |tests_batch|
|
33
|
+
scan_options.reject! { |key| key == :skip_testing }
|
34
|
+
scan_options[:only_testing] = tests_batch
|
35
|
+
try_scan_with_retry(scan_options, params[:try_count])
|
36
|
+
end
|
37
|
+
end
|
38
|
+
collate_reports(scan_options)
|
39
|
+
end
|
40
|
+
|
41
|
+
def self.try_scan_with_retry(scan_options, maximum_try_count)
|
42
|
+
try_count = 0
|
26
43
|
begin
|
27
44
|
try_count += 1
|
28
45
|
config = FastlaneCore::Configuration.create(Fastlane::Actions::ScanAction.available_options, scan_options)
|
29
46
|
Fastlane::Actions::ScanAction.run(config)
|
30
47
|
rescue FastlaneCore::Interface::FastlaneTestFailure => e
|
31
48
|
UI.verbose("Scan failed with #{e}")
|
32
|
-
if try_count <
|
49
|
+
if try_count < maximum_try_count
|
33
50
|
report_filepath = junit_report_filepath(scan_options)
|
34
51
|
failed_tests = other_action.tests_from_junit(junit: report_filepath)[:failed]
|
35
52
|
scan_options[:only_testing] = failed_tests.map(&:shellescape)
|
36
53
|
increment_report_filenames(scan_options)
|
37
54
|
retry
|
38
55
|
end
|
56
|
+
else
|
57
|
+
increment_report_filenames(scan_options)
|
39
58
|
end
|
40
|
-
collate_reports(scan_options)
|
41
59
|
end
|
42
60
|
|
43
61
|
def self.collate_reports(scan_options)
|
@@ -53,18 +71,98 @@ module Fastlane
|
|
53
71
|
final_report_name = "#{match[:filename]}#{extension}"
|
54
72
|
end
|
55
73
|
other_action.collate_junit_reports(
|
56
|
-
reports: report_files.
|
74
|
+
reports: report_files.sort { |f1, f2| File.mtime(f1) <=> File.mtime(f2) },
|
57
75
|
collated_report: File.absolute_path(File.join(scan_options[:output_directory], final_report_name))
|
58
76
|
)
|
59
77
|
end
|
60
78
|
FileUtils.rm_f(Dir.glob("#{scan_options[:output_directory]}/*-[1-9]*#{extension}"))
|
61
79
|
end
|
62
80
|
|
81
|
+
def self.kill(program)
|
82
|
+
Actions.sh("killall -9 '#{program}' &> /dev/null || true", log: false)
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.quit_simulators
|
86
|
+
kill('iPhone Simulator')
|
87
|
+
kill('Simulator')
|
88
|
+
kill('SimulatorBridge')
|
89
|
+
|
90
|
+
launchctl_list_count = 0
|
91
|
+
while Actions.sh('launchctl list | grep com.apple.CoreSimulator.CoreSimulatorService || true', log: false) != ''
|
92
|
+
break if (launchctl_list_count += 1) > 10
|
93
|
+
Actions.sh('launchctl remove com.apple.CoreSimulator.CoreSimulatorService &> /dev/null || true', log: false)
|
94
|
+
sleep(1)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.tests_to_batch(scan_options)
|
99
|
+
unless scan_options[:only_testing].nil?
|
100
|
+
return scan_options[:only_testing]
|
101
|
+
end
|
102
|
+
|
103
|
+
xctestrun_path = scan_options[:xctestrun] || testrun_path(scan_options)
|
104
|
+
if xctestrun_path.nil? || !File.exist?(xctestrun_path)
|
105
|
+
UI.user_error!("Error: cannot find expected xctestrun file '#{xctestrun_path}'")
|
106
|
+
end
|
107
|
+
tests = xctestrun_tests(xctestrun_path)
|
108
|
+
remove_skipped_tests(tests, scan_options[:skip_testing])
|
109
|
+
end
|
110
|
+
|
111
|
+
def self.remove_skipped_tests(tests_to_batch, tests_to_skip)
|
112
|
+
if tests_to_skip.nil?
|
113
|
+
return tests_to_batch
|
114
|
+
end
|
115
|
+
|
116
|
+
if tests_to_skip
|
117
|
+
tests_to_skip = tests_to_skip
|
118
|
+
testsuites_to_skip = tests_to_skip.select do |testsuite|
|
119
|
+
testsuite.count('/') == 1 # just the testable/testsuite
|
120
|
+
end
|
121
|
+
tests_to_skip -= testsuites_to_skip
|
122
|
+
tests_to_batch.reject! do |test_identifier|
|
123
|
+
test_suite = test_identifier.split('/').first(2).join('/')
|
124
|
+
testsuites_to_skip.include?(test_suite)
|
125
|
+
end
|
126
|
+
tests_to_batch -= tests_to_skip
|
127
|
+
end
|
128
|
+
tests_to_batch
|
129
|
+
end
|
130
|
+
|
131
|
+
def self.xctestrun_tests(xctestrun_path)
|
132
|
+
xctestrun = Plist.parse_xml(xctestrun_path)
|
133
|
+
xctestrun_rootpath = File.dirname(xctestrun_path)
|
134
|
+
tests = []
|
135
|
+
xctestrun.each do |testable_name, xctestrun_config|
|
136
|
+
test_identifiers = XCTestList.tests(xctest_bundle_path(xctestrun_rootpath, xctestrun_config))
|
137
|
+
if xctestrun_config.key?('SkipTestIdentifiers')
|
138
|
+
test_identifiers.reject! { |test_identifier| xctestrun_config['SkipTestIdentifiers'].include?(test_identifier) }
|
139
|
+
end
|
140
|
+
tests += test_identifiers.map do |test_identifier|
|
141
|
+
"#{testable_name.shellescape}/#{test_identifier}"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
tests
|
145
|
+
end
|
146
|
+
|
147
|
+
def self.xctest_bundle_path(xctestrun_rootpath, xctestrun_config)
|
148
|
+
xctest_host_path = xctestrun_config['TestHostPath'].sub('__TESTROOT__', xctestrun_rootpath)
|
149
|
+
xctestrun_config['TestBundlePath'].sub('__TESTHOST__', xctest_host_path)
|
150
|
+
end
|
151
|
+
|
152
|
+
def self.testrun_path(scan_options)
|
153
|
+
Dir.glob("#{scan_options[:derived_data_path]}/Build/Products/#{scan_options[:scheme]}*.xctestrun").first
|
154
|
+
end
|
155
|
+
|
156
|
+
def self.test_products_path(derived_data_path)
|
157
|
+
File.join(derived_data_path, "Build", "Products")
|
158
|
+
end
|
159
|
+
|
63
160
|
def self.build_for_testing(scan_options)
|
64
161
|
scan_options.delete(:test_without_building)
|
65
162
|
scan_options[:build_for_testing] = true
|
66
163
|
config = FastlaneCore::Configuration.create(Fastlane::Actions::ScanAction.available_options, scan_options)
|
67
164
|
Fastlane::Actions::ScanAction.run(config)
|
165
|
+
scan_options[:derived_data_path] = Scan.config[:derived_data_path]
|
68
166
|
end
|
69
167
|
|
70
168
|
def self.config_has_junit_report(config)
|
@@ -158,6 +256,18 @@ module Fastlane
|
|
158
256
|
type: Integer,
|
159
257
|
is_string: false,
|
160
258
|
default_value: 1
|
259
|
+
),
|
260
|
+
FastlaneCore::ConfigItem.new(
|
261
|
+
key: :batch_count,
|
262
|
+
env_name: "FL_MULTI_SCAN_BATCH_COUNT",
|
263
|
+
description: "The number of test batches to run through scan. Can be combined with :try_count",
|
264
|
+
type: Integer,
|
265
|
+
is_string: false,
|
266
|
+
default_value: 1,
|
267
|
+
optional: true,
|
268
|
+
verify_block: proc do |count|
|
269
|
+
UI.user_error!("Error: Batch counts must be greater than zero") unless count > 0
|
270
|
+
end
|
161
271
|
)
|
162
272
|
]
|
163
273
|
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: 2.
|
4
|
+
version: 2.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lyndsey Ferguson
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: xcodeproj
|
@@ -24,6 +24,34 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: xctest_list
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: plist
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
27
55
|
- !ruby/object:Gem::Dependency
|
28
56
|
name: bundler
|
29
57
|
requirement: !ruby/object:Gem::Requirement
|