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



68
69
70
71
72
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 68

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



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

def clean_up_cloned_simulators(clones)
  return if clones.nil?

  clones.flatten.each(&:delete)
end

#derived_data_path_for_worker(worker_index) ⇒ Object



74
75
76
77
78
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 74

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



40
41
42
43
44
45
46
47
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 40

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



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

def parallel_scan_options(worker_index)
  options = @options.reject { |key| i[device devices].include?(key) }
  options[:destination] = destination_for_worker(worker_index)
  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
# 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)
  )
  @simhelper.setup
  @clones = @simhelper.clone_destination_simulators
  main_pid = Process.pid
  at_exit do
    clean_up_cloned_simulators(@clones) if Process.pid == main_pid
  end
  # boot all the simulators _before_ calling `xcodebuilt test` to avoid
  # testmanagerd connection failures.
  @clones.flatten.each(&:boot)
  @clones
end

#setup_parallel_workersObject



49
50
51
52
53
54
55
56
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 49

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



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

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

#wait_for_all_workersObject



116
117
118
119
120
121
122
123
124
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 116

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
    busy_workers.each { |w| w.process_results }
  end
end

#wait_for_workerObject



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/fastlane/plugin/test_center/helper/multi_scan_manager/test_batch_worker_pool.rb', line 92

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