Class: MiniAutobot::Parallel

Inherits:
Object
  • Object
show all
Defined in:
lib/mini_autobot/parallel.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(simultaneous_jobs, all_tests) ⇒ Parallel

Returns a new instance of Parallel.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# File 'lib/mini_autobot/parallel.rb', line 6

def initialize(simultaneous_jobs, all_tests)
  @start_time = Time.now
  clean_result!

  connector = MiniAutobot.settings.connector
  @on_sauce = true if connector.include? 'saucelabs'
  @platform = connector.split(':')[2] || ''

  @simultaneous_jobs = simultaneous_jobs
  @simultaneous_jobs = 10 if run_on_mac? # saucelabs account limit for parallel is 10 for mac
  @all_tests = all_tests

  @pids = []
  @static_run_command = "mini_autobot -c #{MiniAutobot.settings.connector} -e #{MiniAutobot.settings.env}"
  if MiniAutobot.settings.rerun_failure
    @static_run_command += " -R #{MiniAutobot.settings.rerun_failure}"
  end
  tap_reporter_path = MiniAutobot.gem_root.join('lib/tapout/custom_reporters/fancy_tap_reporter.rb')
  @pipe_tap = "--tapy | tapout --no-color -r #{tap_reporter_path.to_s} fancytap"
end

Instance Attribute Details

#all_testsObject (readonly)

Returns the value of attribute all_tests.



4
5
6
# File 'lib/mini_autobot/parallel.rb', line 4

def all_tests
  @all_tests
end

#simultaneous_jobsObject (readonly)

Returns the value of attribute simultaneous_jobs.



4
5
6
# File 'lib/mini_autobot/parallel.rb', line 4

def simultaneous_jobs
  @simultaneous_jobs
end

Instance Method Details

#clean_result!Object

remove all results files under logs/tap_results/ if there’s any



34
35
36
37
# File 'lib/mini_autobot/parallel.rb', line 34

def clean_result!
  FileUtils.rm_rf(Dir.glob('logs/tap_results/*')) unless Dir.glob('logs/tap_results/*').empty?
  puts "Cleaning result files.\n"
end

#count_autobot_processObject



39
40
41
42
# File 'lib/mini_autobot/parallel.rb', line 39

def count_autobot_process
  counting_process_output = IO.popen "ps -ef | grep 'bin/#{@static_run_command}' -c"
  counting_process_output.readlines[0].to_i - 1 # minus grep process
end

#keep_running_full(all_to_run) ⇒ Object

recursively keep running ##simultaneous_jobs number of tests in parallel exit when no test left to run



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/mini_autobot/parallel.rb', line 77

def keep_running_full(all_to_run)
  running_subprocess_count = count_autobot_process - 1 # minus parent process
  puts "WARNING: running_subprocess_count = #{running_subprocess_count}
        is more than what it is supposed to run(#{simultaneous_jobs}),
        notify mini_autobot maintainers" if running_subprocess_count > simultaneous_jobs + 1
  while running_subprocess_count >= simultaneous_jobs
    sleep 5
    running_subprocess_count = count_autobot_process - 1
  end
  to_run_count = simultaneous_jobs - running_subprocess_count
  tests_to_run = all_to_run.slice!(0, to_run_count)

  run_test_set(tests_to_run)

  keep_running_full(all_to_run) if all_to_run.size > 0
end

#run_in_parallel!Object

run multiple commands with logging to start multiple tests in parallel n = number of tests will be running in parallel

Parameters:

  • (Integer, Array)


47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/mini_autobot/parallel.rb', line 47

def run_in_parallel!
  size = all_tests.size
  if size <= simultaneous_jobs
    run_test_set(all_tests)
    puts "CAUTION! All #{size} tests are starting at the same time!"
    puts "will not really run it since computer will die" if size > 30
    sleep 20
  else
    first_test_set = all_tests[0, simultaneous_jobs]
    all_to_run = all_tests[(simultaneous_jobs + 1)...(all_tests.size - 1)]
    run_test_set(first_test_set)
    keep_running_full(all_to_run)
  end

  Process.waitall
  puts "\nAll Complete! Started at #{@start_time} and finished at #{Time.now}\n"
  exit
end

#run_on_mac?boolean

return true only if specified to run on mac in connector

Returns:

  • (boolean)


29
30
31
# File 'lib/mini_autobot/parallel.rb', line 29

def run_on_mac?
  @platform.include?('osx')
end

#run_test_set(test_set) ⇒ Object

runs each test from a test set in a separate child process



67
68
69
70
71
72
73
# File 'lib/mini_autobot/parallel.rb', line 67

def run_test_set(test_set)
  test_set.each do |test|
    run_command = "#{@static_run_command} -n #{test} #{@pipe_tap} > logs/tap_results/#{test}.t"
    pipe = IO.popen(run_command)
    puts "Running #{test}  #{pipe.pid}"
  end
end

#wait_all_done_saucelabsObject

Deprecated.

Too time consuming and fragile, should use more native wait/check of Process



110
111
112
113
114
115
116
117
118
# File 'lib/mini_autobot/parallel.rb', line 110

def wait_all_done_saucelabs
  size = all_tests.size
  job_statuses = saucelabs_last_n_statuses(size)
  while job_statuses.include?('in progress')
    puts "There are tests still running, waiting..."
    sleep 20
    job_statuses = saucelabs_last_n_statuses(size)
  end
end

#wait_for_pids(pids) ⇒ Object

Deprecated.

Use more native wait/check of Process



95
96
97
98
99
100
101
102
103
104
105
106
107
# File 'lib/mini_autobot/parallel.rb', line 95

def wait_for_pids(pids)
  running_pids = pids # assume all pids are running at this moment
  while running_pids.size > 1
    sleep 5
    puts "running_pids = #{running_pids}"
    running_pids.each do |pid|
      unless process_running?(pid)
        puts "#{pid} is not running, removing it from pool"
        running_pids.delete(pid)
      end
    end
  end
end