lib/knapsack/distributors/report_distributor.rb in knapsack-3.0.0 vs lib/knapsack/distributors/report_distributor.rb in knapsack-3.1.0

- old
+ new

@@ -1,92 +1,71 @@ module Knapsack module Distributors class ReportDistributor < BaseDistributor def sorted_report - @sorted_report ||= report.sort_by { |test_path, time| time }.reverse + @sorted_report ||= report.sort_by { |_test_path, time| -time } end def sorted_report_with_existing_tests @sorted_report_with_existing_tests ||= sorted_report.select { |test_path, time| all_tests.include?(test_path) } end def total_time_execution - @total_time_execution ||= sorted_report_with_existing_tests.map(&:last).reduce(0, :+).to_f + @total_time_execution ||= sorted_report_with_existing_tests.map { |_test_path, time| time }.reduce(0, :+).to_f end def node_time_execution @node_time_execution ||= total_time_execution / ci_node_total end private def post_assign_test_files_to_node - assign_slow_test_files - assign_remaining_test_files + assign_test_files sort_assigned_test_files end def sort_assigned_test_files - ci_node_total.times do |index| - # sort by first key (file name) - # reverse it and then sort by second key (time) in reverse order - node_tests[index][:test_files_with_time].sort!.reverse!.sort! do |x, y| - y[1] <=> x[1] - end + node_tests.map do |node| + node[:test_files_with_time] + .sort_by! { |file_name, _time| file_name } + .reverse! + .sort_by! { |_file_name, time| time } + .reverse! end end def post_tests_for_node(node_index) node_test = node_tests[node_index] return unless node_test - node_test[:test_files_with_time].map(&:first) + node_test[:test_files_with_time].map { |file_name, _time| file_name } end def default_node_tests - @node_tests = [] - ci_node_total.times do |index| - @node_tests << { + @node_tests = Array.new(ci_node_total) do |index| + { node_index: index, time_left: node_time_execution, - test_files_with_time: [] + test_files_with_time: [], + weight: 0 } end end - def assign_slow_test_files - @not_assigned_test_files = [] - node_index = 0 - sorted_report_with_existing_tests.each do |test_file_with_time| - assign_slow_test_file(node_index, test_file_with_time) - node_index += 1 - node_index %= ci_node_total - end - end + def assign_test_files + sorted_report_with_existing_tests.map do |test_file_with_time| + test_execution_time = test_file_with_time.last - def assign_slow_test_file(node_index, test_file_with_time) - time = test_file_with_time[1] - time_left = node_tests[node_index][:time_left] - time + current_lightest_node = node_tests.min_by { |node| node[:weight] } - if time_left >= 0 or node_tests[node_index][:test_files_with_time].empty? - node_tests[node_index][:time_left] -= time - node_tests[node_index][:test_files_with_time] << test_file_with_time - else - @not_assigned_test_files << test_file_with_time - end - end + updated_node_data = { + time_left: current_lightest_node[:time_left] - test_execution_time, + weight: current_lightest_node[:weight] + test_execution_time, + test_files_with_time: current_lightest_node[:test_files_with_time] << test_file_with_time + } - def assign_remaining_test_files - @not_assigned_test_files.each do |test_file_with_time| - index = node_with_max_time_left - time = test_file_with_time[1] - node_tests[index][:time_left] -= time - node_tests[index][:test_files_with_time] << test_file_with_time + current_lightest_node.merge!(updated_node_data) end - end - - def node_with_max_time_left - node_test = node_tests.max { |a,b| a[:time_left] <=> b[:time_left] } - node_test[:node_index] end end end end