Class: TestCenter::Helper::MultiScanManager::TestBatchWorkerPool

Inherits:
Object
  • Object
show all
Defined in:
lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ TestBatchWorkerPool

Returns a new instance of TestBatchWorkerPool.



5
6
7
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 5

def initialize(options)
  @options = options
end

Instance Method Details

#buildlog_path_for_worker(worker_index) ⇒ Object



82
83
84
85
86
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 82

def buildlog_path_for_worker(worker_index)
  # ensure that simultaneous simulators are not writing to the same log
  # at the same time.
  "#{@options[:buildlog_path]}/worker-#{worker_index + 1}-logs"
end

#clean_up_cloned_simulators(clones) ⇒ Object



94
95
96
97
98
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 94

def clean_up_cloned_simulators(clones)
  return if clones.nil?

  clones.flatten.each(&:delete)
end

#derived_data_path_for_worker(worker_index) ⇒ Object



88
89
90
91
92
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 88

def derived_data_path_for_worker(worker_index)
  # ensure that simultaneous simulators are not writing diagnostics to
  # the same location at the same time.
  Dir.mktmpdir(['derived_data_path', "-worker-#{(worker_index + 1).to_s}"])
end

#destination_for_worker(worker_index) ⇒ Object



46
47
48
49
50
51
52
53
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 46

def destination_for_worker(worker_index)
  # each worker has its own simulators to work with
  return @options[:destination] unless @options[:platform] == :ios_simulator

  @clones[worker_index].map do |simulator|
    "platform=iOS Simulator,id=#{simulator.udid}"
  end
end

#is_serial?Boolean

Returns:

  • (Boolean)


9
10
11
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 9

def is_serial?
  @options.fetch(:parallel_testrun_count, 1) == 1
end

#parallel_scan_options(worker_index) ⇒ Object



69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 69

def parallel_scan_options(worker_index)
  options = @options.reject { |key| %i[device devices].include?(key) }
  options[:destination] = destination_for_worker(worker_index)
  if @options[:platform] == :ios_simulator
    options[:scan_devices_override] = simulator_devices_for_worker(worker_index)
  end
  options[:buildlog_path] = buildlog_path_for_worker(worker_index) if @options[:buildlog_path]
  options[:derived_data_path] = derived_data_path_for_worker(worker_index)
  options[:batch_index] = worker_index
  options[:test_batch_results] = @options[:test_batch_results]
  options
end

#setup_cloned_simulatorsObject



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 21

def setup_cloned_simulators
  return [] unless @options[:platform] == :ios_simulator

  @simhelper = SimulatorHelper.new(
    parallel_testrun_count: @options[:parallel_testrun_count],
    pre_delete_cloned_simulators: @options.fetch(:pre_delete_cloned_simulators, true),
    reuse_simulators_for_parallel_testruns: @options[:reuse_simulators_for_parallel_testruns] || false
  )
  @simhelper.setup
  @clones = @simhelper.parallel_destination_simulators
  main_pid = Process.pid
  unless @options[:reuse_simulators_for_parallel_testruns]
    at_exit do
      clean_up_cloned_simulators(@clones) if Process.pid == main_pid
    end
  end
  # boot all the simulators _before_ calling `xcodebuilt test` to avoid
  # testmanagerd connection failures.
  @clones.flatten.each(&:shutdown)
  @clones.flatten.each(&:disable_hardware_keyboard)
  @clones.flatten.each(&:boot)
  SimulatorHelper.call_simulator_started_callback(@options, @clones.flatten)
  @clones
end

#setup_parallel_workersObject



60
61
62
63
64
65
66
67
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 60

def setup_parallel_workers
  setup_cloned_simulators
  desired_worker_count = @options[:parallel_testrun_count]
  @workers = []
  (0...desired_worker_count).each do |worker_index|
    @workers << ParallelTestBatchWorker.new(parallel_scan_options(worker_index))
  end
end

#setup_serial_workersObject



106
107
108
109
110
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 106

def setup_serial_workers
  serial_scan_options = @options.reject { |key| %i[device devices].include?(key) }
  serial_scan_options[:destination] ||= Scan&.config&.fetch(:destination)
  @workers = [ TestBatchWorker.new(serial_scan_options) ]
end

#setup_workersObject



13
14
15
16
17
18
19
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 13

def setup_workers
  if is_serial?
    setup_serial_workers
  else
    setup_parallel_workers
  end
end

#shutdown_cloned_simulators(clones) ⇒ Object



100
101
102
103
104
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 100

def shutdown_cloned_simulators(clones)
  return if clones.nil?

  clones.flatten.each(&:shutdown)
end

#simulator_devices_for_worker(worker_index) ⇒ Object



55
56
57
58
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 55

def simulator_devices_for_worker(worker_index)
  return nil unless @options[:platform] == :ios_simulator
  @clones[worker_index]
end

#wait_for_all_workersObject



136
137
138
139
140
141
142
143
144
145
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 136

def wait_for_all_workers
  unless is_serial?
    busy_workers = @workers.each.select { |w| w.state == :working }
    busy_workers.map(&:pid).each do |pid|
      Process.wait(pid)
    end
    shutdown_cloned_simulators(@clones)
    busy_workers.each { |w| w.process_results }
  end
end

#wait_for_workerObject



112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 112

def wait_for_worker
  if is_serial?
    return @workers[0]
  else
    if_no_available_workers = Proc.new do
      worker = nil
      loop do
        freed_child_proc_pid = Process.wait
        worker = @workers.find do |w|
          w.pid == freed_child_proc_pid
        end

        break if worker
      end
      worker.process_results
      worker
    end

    first_ready_to_work_worker = @workers.find(if_no_available_workers) do |worker|
      worker.state == :ready_to_work
    end
  end
end