fastlane-plugin-test_center 3.6.3 → 3.7.0.parallelizing.alpha.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (26) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +4 -0
  3. data/lib/fastlane/plugin/test_center.rb +1 -1
  4. data/lib/fastlane/plugin/test_center/actions/collate_test_result_bundles.rb +1 -1
  5. data/lib/fastlane/plugin/test_center/actions/multi_scan.rb +109 -25
  6. data/lib/fastlane/plugin/test_center/actions/restart_core_simulator_service.rb +38 -0
  7. data/lib/fastlane/plugin/test_center/actions/tests_from_xctestrun.rb +16 -4
  8. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager.rb +5 -0
  9. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/device_manager.rb +30 -0
  10. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/interstitial.rb +143 -0
  11. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/parallel_test_batch_worker.rb +27 -0
  12. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/report_collator.rb +115 -0
  13. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan.rb +74 -0
  14. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/retrying_scan_helper.rb +255 -0
  15. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/runner.rb +356 -0
  16. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_helper.rb +49 -0
  17. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/simulator_manager.rb +317 -0
  18. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker.rb +20 -0
  19. data/lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb +129 -0
  20. data/lib/fastlane/plugin/test_center/helper/reportname_helper.rb +15 -6
  21. data/lib/fastlane/plugin/test_center/helper/test_collector.rb +49 -3
  22. data/lib/fastlane/plugin/test_center/helper/xcodebuild_string.rb +4 -0
  23. data/lib/fastlane/plugin/test_center/helper/xctestrun_info.rb +42 -0
  24. data/lib/fastlane/plugin/test_center/version.rb +1 -1
  25. metadata +38 -10
  26. data/lib/fastlane/plugin/test_center/helper/correcting_scan_helper.rb +0 -293
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: d4b6e643411a6c7dc79cc1ffdf6f2e92d6eca01a2a31c14c8f2904290f0792a3
4
- data.tar.gz: d57683f16900bd9460adfe2c613dff614dc11af4a3cccbb315391a773f7ffd12
2
+ SHA1:
3
+ metadata.gz: ac1d3616de1a2ad7f95123d43b899227325b485c
4
+ data.tar.gz: 6cdd4e31e41ef0c998b52ad8666c8eb08c0c5e8d
5
5
  SHA512:
6
- metadata.gz: 2662f68881f0cfd6e75721f7fd13e9ee229981d1ddaf6b01ba3c1effd1510ba3e0df7542cf04b89ac7f36d9a83c94f11f201bed01246f376a30ad561c806d610
7
- data.tar.gz: 5855c0fd93652ac1a034a8a268268c9587ffe5de8420b65d4c1fa4fe614198d4ab9190f63589abaacd961e20517b879b8508453db719c1aff78dd57337b21495
6
+ metadata.gz: '09d7060687e873c399e8d77833db3ba1c7a804e94b9de5ec7b4cd32fda0a5b9813a3b02942d3f9dbe2c26d7df9cab3f369842dc246ac9dd6efac8f94b339133a'
7
+ data.tar.gz: 8b027123c0ff018e9227326652a6a298e9ed2a90b8b795d1a6c6841a35188f5cf1efb148f156c4c7e706dc72c3ab4d8a693e4833487301763ba90b0a45bb0618
data/README.md CHANGED
@@ -107,6 +107,10 @@ Do you have multiple test targets and the normal operation of `:scan` is providi
107
107
 
108
108
  `test_result` bundles are particularly useful because they contain screenshots of the UI when a UI test fails so you can review what was actually there compared to what you expected.
109
109
 
110
+ #### Invocation based tests
111
+
112
+ If your tests are invocation based like [Kiwi](https://github.com/kiwi-bdd/Kiwi) you need to set `:invocation_based_tests` to handle these tests, because unlike `XCTest`s the list of tests cannot be deterimned before running and also you can't try an exact test (The reruns run the whole file where the test failed).
113
+
110
114
  <details>
111
115
  <summary>Example Code (expand to view):</summary>
112
116
  <!-- multi_scan examples: begin -->
@@ -4,7 +4,7 @@ module Fastlane
4
4
  module TestCenter
5
5
  # Return all .rb files inside the "actions" and "helper" directory
6
6
  def self.all_classes
7
- Dir[File.expand_path('**/{actions,helper}/*.rb', File.dirname(__FILE__))]
7
+ Dir[File.expand_path('**/{actions,helper}/**/*.rb', File.dirname(__FILE__))]
8
8
  end
9
9
  end
10
10
  end
@@ -14,7 +14,7 @@ module Fastlane
14
14
  collate_bundles(base_bundle_path, other_bundlepath)
15
15
  end
16
16
  end
17
- FileUtils.rm_rf(params[:collated_bundle])
17
+ # FileUtils.rm_rf(params[:collated_bundle])
18
18
  FileUtils.cp_r(base_bundle_path, params[:collated_bundle])
19
19
  UI.message("Finished collating test_result bundle to '#{params[:collated_bundle]}'")
20
20
  end
@@ -5,23 +5,26 @@ module Fastlane
5
5
  require 'shellwords'
6
6
  require 'xctest_list'
7
7
  require 'plist'
8
+ require_relative '../helper/multi_scan_manager/runner'
8
9
 
9
10
  class MultiScanAction < Action
10
11
  def self.run(params)
11
12
  unless Helper.test?
12
13
  FastlaneCore::PrintTable.print_values(
13
- config: params._values.select { |k, _| %i[try_count batch_count fail_build quit_simulators].include?(k) },
14
+ config: params._values.select { |k, _| %i[try_count batch_count invocation_based_tests fail_build quit_simulators].include?(k) },
14
15
  title: "Summary for multi_scan (test_center v#{Fastlane::TestCenter::VERSION})"
15
16
  )
16
17
  end
17
- unless params[:test_without_building] || params[:skip_build]
18
- build_for_testing(
19
- params._values
20
- )
18
+
19
+ prepare_for_testing(params._values)
20
+
21
+ runner = ::TestCenter::Helper::MultiScanManager::Runner.new(params.values)
22
+ tests_passed = runner.run
23
+ if params[:fail_build] && !tests_passed
24
+ raise UI.test_failure!('Tests have failed')
21
25
  end
22
- smart_scanner = ::TestCenter::Helper::CorrectingScanHelper.new(params.values)
23
- tests_passed = smart_scanner.scan
24
- summary = run_summary(params, tests_passed, smart_scanner.retry_total_count)
26
+
27
+ summary = run_summary(params, tests_passed, runner.retry_total_count)
25
28
  unless Helper.test?
26
29
  FastlaneCore::PrintTable.print_values(
27
30
  config: summary,
@@ -80,26 +83,51 @@ module Fastlane
80
83
  }
81
84
  end
82
85
 
83
- def self.build_for_testing(scan_options)
84
- options_to_remove = %i[
85
- try_count
86
- batch_count
87
- quit_simulators
88
- testrun_completed_block
89
- test_without_building
90
- output_types
91
- output_files
92
- ]
93
- config = FastlaneCore::Configuration.create(
86
+ def self.prepare_for_testing(scan_options)
87
+ if scan_options[:test_without_building] || scan_options[:skip_build]
88
+ prepare_scan_config(scan_options)
89
+ else
90
+ build_for_testing(scan_options)
91
+ end
92
+ end
93
+
94
+ def self.prepare_scan_config(scan_options)
95
+ Scan.config ||= FastlaneCore::Configuration.create(
94
96
  Fastlane::Actions::ScanAction.available_options,
95
- scan_options.merge(build_for_testing: true).reject { |k, _| options_to_remove.include?(k) }
97
+ scan_options.select { |k,v| %i[project workspace scheme].include?(k) }
96
98
  )
97
- Fastlane::Actions::ScanAction.run(config)
99
+ end
100
+
101
+ def self.build_for_testing(scan_options)
102
+ valid_scan_keys = Fastlane::Actions::ScanAction.available_options.map(&:key)
103
+ scan_options = scan_options.select { |k,v| valid_scan_keys.include?(k) }
98
104
 
99
- scan_options.merge!(
100
- test_without_building: true,
101
- derived_data_path: Scan.config[:derived_data_path]
102
- ).delete(:build_for_testing)
105
+ Scan.config = FastlaneCore::Configuration.create(
106
+ Fastlane::Actions::ScanAction.available_options,
107
+ scan_options.merge(build_for_testing: true)
108
+ )
109
+ values = Scan.config.values(ask: false)
110
+ values[:xcode_path] = File.expand_path("../..", FastlaneCore::Helper.xcode_path)
111
+ FastlaneCore::PrintTable.print_values(
112
+ config: values,
113
+ hide_keys: [:destination, :slack_url],
114
+ title: "Summary for scan #{Fastlane::VERSION}"
115
+ )
116
+ Scan::Runner.new.run
117
+ remove_build_report_files
118
+
119
+ Scan.config._values.delete(:build_for_testing)
120
+ scan_options[:derived_data_path] = Scan.config[:derived_data_path]
121
+ end
122
+
123
+ def self.remove_build_report_files
124
+ report_options = Scan::XCPrettyReporterOptionsGenerator.generate_from_scan_config
125
+ output_files = report_options.instance_variable_get(:@output_files)
126
+ output_directory = report_options.instance_variable_get(:@output_directory)
127
+
128
+ output_files.each do |output_file|
129
+ FileUtils.rm_f(File.join(output_directory, output_file))
130
+ end
103
131
  end
104
132
 
105
133
  #####################################################
@@ -156,6 +184,20 @@ module Fastlane
156
184
  UI.user_error!("Error: Batch counts must be greater than zero") unless count > 0
157
185
  end
158
186
  ),
187
+ FastlaneCore::ConfigItem.new(
188
+ key: :invocation_based_tests,
189
+ description: "Set to true If your test suit have invocation based tests like Kiwi",
190
+ type: Boolean,
191
+ is_string: false,
192
+ default_value: false,
193
+ optional: true,
194
+ conflicting_options: [:batch_count],
195
+ conflict_block: proc do |value|
196
+ UI.user_error!(
197
+ "Error: Can't use 'invocation_based_tests' and 'batch_count' options in one run, "\
198
+ "because the number of tests is unkown.")
199
+ end
200
+ ),
159
201
  FastlaneCore::ConfigItem.new(
160
202
  key: :quit_simulators,
161
203
  env_name: "FL_MULTI_SCAN_QUIT_SIMULATORS",
@@ -172,6 +214,28 @@ module Fastlane
172
214
  description: "Comma separated list of the output types (e.g. html, junit, json, json-compilation-database)",
173
215
  default_value: "html,junit"
174
216
  ),
217
+ FastlaneCore::ConfigItem.new(
218
+ key: :parallelize,
219
+ description: 'Run each batch of tests and/or each test target in parallel on its own Simulator',
220
+ optional: true,
221
+ is_string: false,
222
+ default_value: false,
223
+ conflicting_options: [:parallel_simulator_count],
224
+ conflict_block: proc do |value|
225
+ UI.user_error!("You can't use 'parallelize' and 'parallel_simulator_count' options in one run")
226
+ end
227
+ ),
228
+ FastlaneCore::ConfigItem.new(
229
+ key: :parallel_simulator_fork_count,
230
+ description: 'Run simulators each batch of tests and/or each test target in parallel on its own Simulator',
231
+ optional: true,
232
+ is_string: false,
233
+ default_value: false,
234
+ conflicting_options: [:parallelize],
235
+ conflict_block: proc do |value|
236
+ UI.user_error!("You can't use 'parallelize' and 'parallel_simulator_count' options in one run")
237
+ end
238
+ ),
175
239
  FastlaneCore::ConfigItem.new(
176
240
  key: :testrun_completed_block,
177
241
  description: 'A block invoked each time a test run completes',
@@ -317,6 +381,26 @@ module Fastlane
317
381
  output_files: 'report.json',
318
382
  fail_build: false
319
383
  )
384
+ ",
385
+ "
386
+ UI.important(
387
+ 'example: ' \\
388
+ 'use the :xctestrun parameter instead of the :project parameter to find, ' \\
389
+ 'build, and test the iOS app.'
390
+ )
391
+ Dir.mktmpdir do |derived_data_path|
392
+ project_path = '/Users/lyndsey.ferguson/repo/fastlane-plugin-test_center/AtomicBoy/AtomicBoy.xcodeproj'
393
+ command = \"bundle exec fastlane scan --build_for_testing true --project '#{project_path}' --derived_data_path #{derived_data_path} --scheme AtomicBoy\"
394
+ `#{command}`
395
+ xctestrun_file = Dir.glob(\"#{derived_data_path}/Build/Products/AtomicBoy*.xctestrun\").first
396
+ multi_scan(
397
+ scheme: 'AtomicBoy',
398
+ try_count: 3,
399
+ fail_build: false,
400
+ xctestrun: xctestrun_file,
401
+ test_without_building: true
402
+ )
403
+ end
320
404
  "
321
405
  ]
322
406
  end
@@ -0,0 +1,38 @@
1
+ module Fastlane
2
+ module Actions
3
+ class QuitCoreSimulatorServiceAction < Action
4
+ def self.run(params)
5
+ launchctl_list_count = 0
6
+ commands = []
7
+ while Actions.sh('launchctl list | grep com.apple.CoreSimulator.CoreSimulatorService || true', log: false) != ''
8
+ UI.crash!('Unable to quit com.apple.CoreSimulator.CoreSimulatorService after 10 tries') if (launchctl_list_count += 1) > 10
9
+ commands << Actions.sh('launchctl remove com.apple.CoreSimulator.CoreSimulatorService &> /dev/null || true', log: false)
10
+ UI.verbose('Waiting for com.apple.CoreSimulator.CoreSimulatorService to quit')
11
+ sleep(0.5)
12
+ end
13
+ commands
14
+ end
15
+
16
+ #####################################################
17
+ # @!group Documentation
18
+ #####################################################
19
+
20
+ def self.description
21
+ "Force-quits the com.apple.CoreSimulator.CoreSimulatorService."
22
+ end
23
+
24
+ def self.details
25
+ "Sometimes the com.apple.CoreSimulator.CoreSimulatorService can hang. " \
26
+ "Use this action to force-quit it."
27
+ end
28
+
29
+ def self.authors
30
+ ["lyndsey-ferguson/@lyndseydf"]
31
+ end
32
+
33
+ def self.is_supported?(platform)
34
+ platform == :ios
35
+ end
36
+ end
37
+ end
38
+ end
@@ -5,15 +5,15 @@ module Fastlane
5
5
  class TestsFromXctestrunAction < Action
6
6
  def self.run(params)
7
7
  UI.verbose("Getting tests from xctestrun file at '#{params[:xctestrun]}'")
8
- return xctestrun_tests(params[:xctestrun])
8
+ return xctestrun_tests(params[:xctestrun], params[:invocation_based_tests])
9
9
  end
10
10
 
11
- def self.xctestrun_tests(xctestrun_path)
11
+ def self.xctestrun_tests(xctestrun_path, invocation_based_tests)
12
12
  xctestrun = Plist.parse_xml(xctestrun_path)
13
13
  xctestrun_rootpath = File.dirname(xctestrun_path)
14
14
  tests = Hash.new([])
15
15
  xctestrun.each do |testable_name, xctestrun_config|
16
- next if testable_name == '__xctestrun_metadata__'
16
+ next if ignoredTestables.include? testable_name
17
17
 
18
18
  xctest_path = xctest_bundle_path(xctestrun_rootpath, xctestrun_config)
19
19
  test_identifiers = XCTestList.tests(xctest_path)
@@ -23,7 +23,7 @@ module Fastlane
23
23
  UI.verbose("Removing skipped tests: #{skipped_tests.join("\n\t")}")
24
24
  test_identifiers.reject! { |test_identifier| skipped_tests.include?(test_identifier) }
25
25
  end
26
- if test_identifiers.empty?
26
+ if test_identifiers.empty? && !invocation_based_tests
27
27
  UI.error("No tests found in '#{xctest_path}'!")
28
28
  UI.important("Is the Build Setting, `ENABLE_TESTABILITY` enabled for the test target #{testable_name}?")
29
29
  end
@@ -39,6 +39,10 @@ module Fastlane
39
39
  xctestrun_config['TestBundlePath'].sub('__TESTHOST__', xctest_host_path).sub('__TESTROOT__', xctestrun_rootpath)
40
40
  end
41
41
 
42
+ def self.ignoredTestables
43
+ return ['__xctestrun_metadata__']
44
+ end
45
+
42
46
  #####################################################
43
47
  # @!group Documentation
44
48
  #####################################################
@@ -56,6 +60,14 @@ module Fastlane
56
60
  verify_block: proc do |path|
57
61
  UI.user_error!("Error: cannot find the xctestrun file '#{path}'") unless File.exist?(path)
58
62
  end
63
+ ),
64
+ FastlaneCore::ConfigItem.new(
65
+ key: :invocation_based_tests,
66
+ description: "Set to true If your test suit have invocation based tests like Kiwi",
67
+ type: Boolean,
68
+ is_string: false,
69
+ default_value: false,
70
+ optional: true
59
71
  )
60
72
  ]
61
73
  end
@@ -0,0 +1,5 @@
1
+ require_relative 'multi_scan_manager/interstitial'
2
+ require_relative 'multi_scan_manager/report_collator'
3
+ require_relative 'multi_scan_manager/simulator_manager'
4
+ require_relative 'multi_scan_manager/runner'
5
+ require_relative 'xctestrun_info'
@@ -0,0 +1,30 @@
1
+ module FastlaneCore
2
+ class DeviceManager
3
+ class Device
4
+ def clone
5
+ raise 'Can only clone iOS Simulators' unless self.is_simulator
6
+ Device.new(
7
+ name: self.name,
8
+ udid: `xcrun simctl clone #{self.udid} '#{self.name}'`.chomp,
9
+ os_type: self.os_type,
10
+ os_version: self.os_version,
11
+ state: self.state,
12
+ is_simulator: self.is_simulator
13
+ )
14
+ end
15
+
16
+ def rename(newname)
17
+ `xcrun simctl rename #{self.udid} '#{newname}'`
18
+ self.name = newname
19
+ end
20
+
21
+ def boot
22
+ `xcrun simctl boot #{self.udid}`
23
+ end
24
+
25
+ def shutdown
26
+ `xcrun simctl shutdown #{self.udid}` unless self.state == "Shutdown"
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,143 @@
1
+ module TestCenter
2
+ module Helper
3
+ module MultiScanManager
4
+ class Interstitial
5
+
6
+ attr_writer :output_directory
7
+ attr_writer :batch
8
+
9
+ def initialize(options)
10
+ @output_directory = options[:output_directory]
11
+ @testrun_completed_block = options[:testrun_completed_block]
12
+ @result_bundle = options[:result_bundle]
13
+ @scheme = options[:scheme]
14
+ @batch = options[:batch]
15
+ @reportnamer = options[:reportnamer]
16
+ @xcpretty_json_file_output = ENV['XCPRETTY_JSON_FILE_OUTPUT']
17
+ @parallelize = options[:parallelize]
18
+
19
+ before_all
20
+ end
21
+
22
+ # TODO: Should we be creating a new interstitial for each batch? yes.
23
+ # Should we clear out the result bundles before each batch? --> should
24
+ # it not be done before all batches? Same with env var for json resports.
25
+ def before_all
26
+ if @result_bundle
27
+ remove_preexisting_test_result_bundles
28
+ end
29
+ set_json_env_if_necessary
30
+ if @parallelize
31
+ @original_derived_data_path = ENV['SCAN_DERIVED_DATA_PATH']
32
+ FileUtils.mkdir_p(@output_directory)
33
+ ENV['SCAN_DERIVED_DATA_PATH'] = Dir.mktmpdir(nil, @output_directory)
34
+ end
35
+ end
36
+
37
+ def after_all
38
+ FastlaneCore::UI.message("resetting JSON ENV var to #{@xcpretty_json_file_output}")
39
+ ENV['XCPRETTY_JSON_FILE_OUTPUT'] = @xcpretty_json_file_output
40
+ if @parallelize
41
+ ENV['SCAN_DERIVED_DATA_PATH'] = @original_derived_data_path
42
+ end
43
+ end
44
+
45
+ def remove_preexisting_test_result_bundles
46
+ glob_pattern = "#{@output_directory}/.*\.test_result"
47
+ preexisting_test_result_bundles = Dir.glob(glob_pattern)
48
+ FileUtils.rm_rf(preexisting_test_result_bundles)
49
+ end
50
+
51
+ def move_test_result_bundle_for_next_run
52
+ if @result_bundle
53
+ built_test_result, moved_test_result = test_result_bundlepaths
54
+ FileUtils.mv(built_test_result, moved_test_result)
55
+ end
56
+ end
57
+
58
+ def test_result_bundlepaths
59
+ [
60
+ File.join(@output_directory, @scheme) + '.test_result',
61
+ File.join(@output_directory, @scheme) + "_#{@reportnamer.report_count}.test_result"
62
+ ]
63
+ end
64
+
65
+ def reset_simulators
66
+ destinations = Scan.config[:destination]
67
+ simulators = FastlaneCore::DeviceManager.simulators('iOS')
68
+ simulator_ids_to_reset = []
69
+ destinations.each do |destination|
70
+ destination.split(',').each do |destination_pair|
71
+ key, value = destination_pair.split('=')
72
+ if key == 'id'
73
+ simulator_ids_to_reset << value
74
+ end
75
+ end
76
+ end
77
+ simulators_to_reset = simulators.each.select { |simulator| simulator_ids_to_reset.include?(simulator.udid) }
78
+ simulators_to_reset.each do |simulator|
79
+ simulator.reset
80
+ end
81
+ end
82
+
83
+ def send_info_for_try(try_count)
84
+ puts "in send_info_for_try for #{@batch}"
85
+ return unless @testrun_completed_block
86
+
87
+ report_filepath = File.join(@output_directory, @reportnamer.junit_last_reportname)
88
+
89
+ config = FastlaneCore::Configuration.create(
90
+ Fastlane::Actions::TestsFromJunitAction.available_options,
91
+ {
92
+ junit: File.absolute_path(report_filepath)
93
+ }
94
+ )
95
+ junit_results = Fastlane::Actions::TestsFromJunitAction.run(config)
96
+ info = {
97
+ failed: junit_results[:failed],
98
+ passing: junit_results[:passing],
99
+ batch: @batch,
100
+ try_count: try_count,
101
+ report_filepath: report_filepath
102
+ }
103
+
104
+ if @reportnamer.includes_html?
105
+ html_report_filepath = File.join(@output_directory, @reportnamer.html_last_reportname)
106
+ info[:html_report_filepath] = html_report_filepath
107
+ end
108
+ if @reportnamer.includes_json?
109
+ json_report_filepath = File.join(@output_directory, @reportnamer.json_last_reportname)
110
+ info[:json_report_filepath] = json_report_filepath
111
+ end
112
+ if @result_bundle
113
+ test_result_suffix = '.test_result'
114
+ test_result_suffix.prepend("-#{@reportnamer.report_count}") unless @reportnamer.report_count.zero?
115
+ test_result_bundlepath = File.join(@output_directory, @scheme) + test_result_suffix
116
+ info[:test_result_bundlepath] = test_result_bundlepath
117
+ end
118
+ puts "interstitial about to call #{@testrun_completed_block} for batch #{@batch}"
119
+ @testrun_completed_block.call(info)
120
+ end
121
+
122
+ def set_json_env_if_necessary
123
+ if @reportnamer && @reportnamer.includes_json?
124
+ ENV['XCPRETTY_JSON_FILE_OUTPUT'] = File.join(
125
+ @output_directory,
126
+ @reportnamer.json_last_reportname
127
+ )
128
+ end
129
+ end
130
+
131
+ def finish_try(try_count)
132
+ send_info_for_try(try_count)
133
+ reset_simulators
134
+ ENV['SCAN_DERIVED_DATA_PATH'] = Dir.mktmpdir(nil, @output_directory) if @parallelize
135
+ move_test_result_bundle_for_next_run
136
+ set_json_env_if_necessary
137
+ @reportnamer && @reportnamer.increment
138
+ end
139
+ end
140
+ end
141
+ end
142
+ end
143
+