class ParallelTests::Test::Runner
Public Class Methods
execute_command(cmd, process_number, options)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 42 def self.execute_command(cmd, process_number, options) cmd = "TEST_ENV_NUMBER=#{test_env_number(process_number, options)} ; export TEST_ENV_NUMBER; #{cmd}" f = open("|#{cmd}", 'r') output = fetch_output(f) f.close {:stdout => output, :exit_status => $?.exitstatus} end
find_results(test_output)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 50 def self.find_results(test_output) test_output.split("\n").map {|line| line = line.gsub(/\.|F|\*/,'').gsub(/\e\[\d+m/,'') next unless line_is_result?(line) line }.compact end
line_is_result?(line)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 24 def self.line_is_result?(line) line =~ /\d+ failure/ end
run_tests(test_files, process_number, options)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 18 def self.run_tests(test_files, process_number, options) require_list = test_files.map { |filename| %{"#{File.expand_path filename}"} }.join(",") cmd = "ruby -Itest -e '[#{require_list}].each {|f| require f }' -- #{options[:test_options]}" execute_command(cmd, process_number, options) end
runtime_log()
click to toggle source
— usually overwritten by other runners
# File lib/parallel_tests/test/runner.rb, line 6 def self.runtime_log 'tmp/parallel_runtime_test.log' end
summarize_results(results)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 63 def self.summarize_results(results) sums = sum_up_results(results) sums.sort.map{|word, number| "#{number} #{word}#{'s' if number != 1}" }.join(', ') end
test_env_number(process_number, options)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 58 def self.test_env_number(process_number, options) n = options[:advance_number].to_i + process_number + 1 n == 0 ? '' : n end
test_file_name()
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 14 def self.test_file_name "test" end
test_suffix()
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 10 def self.test_suffix "_test.rb" end
tests_in_groups(tests, num_groups, options={})
click to toggle source
finds all tests and partitions them into groups
# File lib/parallel_tests/test/runner.rb, line 31 def self.tests_in_groups(tests, num_groups, options={}) tests = find_tests(tests, options) tests = if options[:group_by] == :found tests.map { |t| [t, 1] } else with_runtime_info(tests) end Grouper.in_even_groups_by_size(tests, num_groups, options) end
Protected Class Methods
fetch_output(process)
click to toggle source
read output of the process and print it in chunks
# File lib/parallel_tests/test/runner.rb, line 82 def self.fetch_output(process) all = '' while buffer = process.readpartial(1000000) all << buffer $stdout.print buffer $stdout.flush end rescue EOFError all end
files_in_folder(folder, options={})
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 122 def self.files_in_folder(folder, options={}) pattern = if options[:symlinks] == false # not nil or true "**/*" else # follow one symlink and direct children # http://stackoverflow.com/questions/357754/can-i-traverse-symlinked-directories-in-ruby-with-a-glob "**{,/*/**}/*" end Dir[File.join(folder, pattern)].uniq end
find_tests(tests, options = {})
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 111 def self.find_tests(tests, options = {}) (tests || []).map do |file_or_folder| if File.directory?(file_or_folder) files = files_in_folder(file_or_folder, options) files.grep(/#{Regexp.escape test_suffix}$/).grep(options[:pattern]||//) else file_or_folder end end.flatten.uniq end
sum_up_results(results)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 70 def self.sum_up_results(results) results = results.join(' ').gsub(/s\b/,'') # combine and singularize results counts = results.scan(/(\d+) (\w+)/) sums = counts.inject(Hash.new(0)) do |sum, (number, word)| sum[word] += number.to_i sum end sums end
with_runtime_info(tests)
click to toggle source
# File lib/parallel_tests/test/runner.rb, line 93 def self.with_runtime_info(tests) lines = File.read(runtime_log).split("\n") rescue [] # use recorded test runtime if we got enough data if lines.size * 1.5 > tests.size puts "Using recorded test runtime" times = Hash.new(1) lines.each do |line| test, time = line.split(":") next unless test and time times[File.expand_path(test)] = time.to_f end tests.sort.map{|test| [test, times[File.expand_path(test)]] } else # use file sizes tests.sort.map{|test| [test, File.stat(test).size] } end end