Skip to content

Commit

Permalink
Equalized the test load by placing an equal amount of test data in ea…
Browse files Browse the repository at this point in the history
…ch process. Removed fixtures as the spec now generates the files it needs in /tmp/pspecs.
  • Loading branch information
joakimk committed Jun 7, 2009
1 parent 3dcbf0d commit 6b876ad
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 33 deletions.
51 changes: 24 additions & 27 deletions lib/parallel_specs.rb
@@ -1,42 +1,39 @@
module ParallelSpecs
extend self

#find all specs and partition them into groups
# finds all specs and partitions them into groups
def specs_in_groups(root, num)
specs = (Dir["#{root}/spec/**/*_spec.rb"]).sort

groups = []
num.times{|i| groups[i]=[]}
return [ specs ] if num == 1
specs_with_sizes, total_size = find_sizes(specs)

# TODO:
# - test it
# - make it work with more than 2
groups = []
num.times { |i| groups[i] = [] }

group_size = (total_size / num.to_f)

i = 0
current_size = 0
specs_with_sizes.each do |spec|
current_size += spec[0]
i += 1 if current_size > group_size * (i+1)
groups[i] << spec[1]
end

groups
end

private

def find_sizes(specs)
total_size = 0
specs_with_sizes = []
specs.each do |file|
size = File.stat(file).size
specs_with_sizes << [ size, file ]
total_size += size
end

index = 0
current_size = 0
specs_with_sizes.each do |spec|
current_size += spec[0]
if index == 0 && current_size > total_size / 2
index += 1
end
groups[index] << spec[1]
end

groups
#
# loop do
# num.times do |i|
# return groups if specs.empty?
# groups[i] << specs.shift
# end
# end
return specs_with_sizes, total_size
end
end
end
Empty file.
Empty file removed spec/fixtures/spec/a/x2_spec.rb
Empty file.
Empty file removed spec/fixtures/spec/a/x3_spec.rb
Empty file.
Empty file removed spec/fixtures/spec/spec_helper.rb
Empty file.
Empty file removed spec/fixtures/spec/x1_spec.rb
Empty file.
Empty file removed spec/fixtures/spec/x4_spec.rb
Empty file.
46 changes: 40 additions & 6 deletions spec/parallel_specs_spec.rb
@@ -1,19 +1,53 @@
require File.dirname(__FILE__)+'/spec_helper'

FAKE_RAILS_ROOT = File.dirname(__FILE__)+'/fixtures'
FAKE_RAILS_ROOT = '/tmp/pspecs/fixtures'

describe ParallelSpecs do
def size_of(group)
group.inject(0) { |sum, spec| sum += File.stat(spec).size }
end

describe :specs_in_groups_of do
before :all do
system "rm -rf #{FAKE_RAILS_ROOT}; mkdir -p #{FAKE_RAILS_ROOT}/spec/temp"

1.upto(100) do |i|
size = 100 * i
File.open("#{FAKE_RAILS_ROOT}/spec/temp/x#{i}_spec.rb", 'w') { |f| f.puts 'x' * size }
end
end

it "finds all specs" do
ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT,1).should == [["./spec/fixtures/spec/a/x2_spec.rb", "./spec/fixtures/spec/a/x3_spec.rb", "./spec/fixtures/spec/x1_spec.rb", "./spec/fixtures/spec/x4_spec.rb"]]
ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT,1).should ==
[ Dir["#{FAKE_RAILS_ROOT}/spec/**/*_spec.rb"] ]
end

it "partitions them into groups" do
ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT,2).should == [["./spec/fixtures/spec/a/x2_spec.rb", "./spec/fixtures/spec/x1_spec.rb"], ["./spec/fixtures/spec/a/x3_spec.rb", "./spec/fixtures/spec/x4_spec.rb"]]
it "partitions them into groups by equal size" do
groups = ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT, 2)
groups.size.should == 2
group0 = size_of(groups[0])
group1 = size_of(groups[1])
diff = group0 * 0.1
group0.should be_close(group1, diff)
end

it 'should partition correctly with a group size of 4' do
groups = ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT, 4)
groups.size.should == 4
group_size = size_of(groups[0])
diff = group_size * 0.1
group_size.should be_close(size_of(groups[1]), diff)
group_size.should be_close(size_of(groups[2]), diff)
group_size.should be_close(size_of(groups[3]), diff)
end

it "leaves spots empty when spec number does not match" do
ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT,3).should == [["./spec/fixtures/spec/a/x2_spec.rb", "./spec/fixtures/spec/x4_spec.rb"], ["./spec/fixtures/spec/a/x3_spec.rb"], ["./spec/fixtures/spec/x1_spec.rb"]]
it 'should partition correctly with an uneven group size' do
groups = ParallelSpecs.specs_in_groups(FAKE_RAILS_ROOT, 3)
groups.size.should == 3
group_size = size_of(groups[0])
diff = group_size * 0.1
group_size.should be_close(size_of(groups[1]), diff)
group_size.should be_close(size_of(groups[2]), diff)
end
end
end

0 comments on commit 6b876ad

Please sign in to comment.