Skip to content

Commit

Permalink
Merge pull request #312 from grosser/grosser/ruby
Browse files Browse the repository at this point in the history
Make sure to run test cases with target Ruby version
  • Loading branch information
grosser committed Nov 19, 2021
2 parents ae9c52f + 499e838 commit 8e0206c
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 49 deletions.
98 changes: 49 additions & 49 deletions spec/parallel_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def kill_process_with_name(file, signal = 'INT')
def execute_start_and_kill(command, amount, signal = 'INT')
t = nil
lambda {
t = Thread.new { `ruby spec/cases/parallel_start_and_kill.rb #{command} 2>&1 && echo "FINISHED"` }
t = Thread.new { ruby("spec/cases/parallel_start_and_kill.rb #{command} 2>&1 && echo 'FINISHED'") }
sleep 1.5
kill_process_with_name('spec/cases/parallel_start_and_kill.rb', signal)
sleep 1
Expand Down Expand Up @@ -70,27 +70,27 @@ def cpus
end

it "executes with detected cpus" do
`ruby spec/cases/parallel_with_detected_cpus.rb`.should == "HELLO\n" * cpus
ruby("spec/cases/parallel_with_detected_cpus.rb").should == "HELLO\n" * cpus
end

it "executes with detected cpus when nil was given" do
`ruby spec/cases/parallel_with_nil_uses_detected_cpus.rb`.should == "HELLO\n" * cpus
ruby("spec/cases/parallel_with_nil_uses_detected_cpus.rb").should == "HELLO\n" * cpus
end

it "executes with cpus from ENV" do
`PARALLEL_PROCESSOR_COUNT=10 ruby spec/cases/parallel_with_detected_cpus.rb`.should == "HELLO\n" * 10
end

it "set amount of parallel processes" do
`ruby spec/cases/parallel_with_set_processes.rb`.should == "HELLO\n" * 5
ruby("spec/cases/parallel_with_set_processes.rb").should == "HELLO\n" * 5
end

it "enforces only one worker type" do
-> { Parallel.map([1, 2, 3], in_processes: 2, in_threads: 3) }.should raise_error(ArgumentError)
end

it "does not influence outside data" do
`ruby spec/cases/parallel_influence_outside_data.rb`.should == "yes"
ruby("spec/cases/parallel_influence_outside_data.rb").should == "yes"
end

it "kills the processes when the main process gets killed through ctrl+c" do
Expand Down Expand Up @@ -133,7 +133,7 @@ def cpus

it "does not kill anything on ctrl+c when everything has finished" do
time_taken do
t = Thread.new { `ruby spec/cases/parallel_fast_exit.rb 2>&1` }
t = Thread.new { ruby("spec/cases/parallel_fast_exit.rb 2>&1") }
sleep 2
kill_process_with_name("spec/cases/parallel_fast_exit.rb") # simulates Ctrl+c
sleep 1
Expand All @@ -144,7 +144,7 @@ def cpus
end

it "preserves original intrrupts" do
t = Thread.new { `ruby spec/cases/double_interrupt.rb 2>&1 && echo FIN` }
t = Thread.new { ruby("spec/cases/double_interrupt.rb 2>&1 && echo FIN") }
sleep 2
kill_process_with_name("spec/cases/double_interrupt.rb") # simulates Ctrl+c
sleep 1
Expand All @@ -154,44 +154,44 @@ def cpus
end

it "restores original intrrupts" do
`ruby spec/cases/after_interrupt.rb 2>&1`.should == "DEFAULT\n"
ruby("spec/cases/after_interrupt.rb 2>&1").should == "DEFAULT\n"
end

it "saves time" do
time_taken do
`ruby spec/cases/parallel_sleeping_2.rb`
ruby("spec/cases/parallel_sleeping_2.rb")
end.should < 3.5
end

it "raises when one of the processes raises" do
`ruby spec/cases/parallel_raise.rb`.strip.should == 'TEST'
ruby("spec/cases/parallel_raise.rb").strip.should == 'TEST'
end

it "can raise an undumpable exception" do
out = `ruby spec/cases/parallel_raise_undumpable.rb`.strip
out = ruby("spec/cases/parallel_raise_undumpable.rb").strip
out.sub!(Dir.pwd, '.') # relative paths
out.gsub!(/(\d+):.*/, "\\1") # no diff in ruby version xyz.rb:123:in `block in <main>'
out.should == "MyException: MyException\nBACKTRACE: spec/cases/parallel_raise_undumpable.rb:14"
end

it "can handle Break exceptions when the better_errors gem is installed" do
out = `ruby spec/cases/parallel_break_better_errors.rb`.strip
out = ruby("spec/cases/parallel_break_better_errors.rb").strip
out.should == "NOTHING WAS RAISED"
end

it 'can handle to high fork rate' do
next if RbConfig::CONFIG["target_os"].include?("darwin1") # kills macs for some reason
`ruby spec/cases/parallel_high_fork_rate.rb`.should == 'OK'
ruby("spec/cases/parallel_high_fork_rate.rb").should == 'OK'
end

it 'does not leave processes behind while running' do
skip if ENV['TRAVIS'] # this randomly fails on travis all the time :(
`ruby spec/cases/closes_processes_at_runtime.rb`.gsub(/.* deprecated; use BigDecimal.*\n/, '').should == 'OK'
ruby("spec/cases/closes_processes_at_runtime.rb").gsub(/.* deprecated; use BigDecimal.*\n/, '').should == 'OK'
end

it "does not open unnecessary pipes" do
max = (RbConfig::CONFIG["target_os"].include?("darwin1") ? 10 : 1800) # somehow super bad on CI
`ruby spec/cases/count_open_pipes.rb`.to_i.should < max
ruby("spec/cases/count_open_pipes.rb").to_i.should < max
end
end

Expand Down Expand Up @@ -221,7 +221,7 @@ def cpus
describe ".map" do
it "saves time" do
time_taken do
`ruby spec/cases/parallel_map_sleeping.rb`
ruby("spec/cases/parallel_map_sleeping.rb")
end.should <= 3.5
end

Expand All @@ -230,16 +230,16 @@ def cpus
end

it "executes with given parameters" do
`ruby spec/cases/parallel_map.rb`.should == "-a- -b- -c- -d-"
ruby("spec/cases/parallel_map.rb").should == "-a- -b- -c- -d-"
end

it "can dump/load complex objects" do
`ruby spec/cases/parallel_map_complex_objects.rb`.should == "YES"
ruby("spec/cases/parallel_map_complex_objects.rb").should == "YES"
end

it "starts new process immediately when old exists" do
time_taken do
`ruby spec/cases/parallel_map_uneven.rb`
ruby("spec/cases/parallel_map_uneven.rb")
end.should <= 3.5
end

Expand All @@ -253,11 +253,11 @@ def cpus
end

it 'supports all Enumerable-s' do
`ruby spec/cases/parallel_map_range.rb`.should == '[1, 2, 3, 4, 5]'
ruby("spec/cases/parallel_map_range.rb").should == '[1, 2, 3, 4, 5]'
end

it 'handles nested arrays and nil correctly' do
`ruby spec/cases/map_with_nested_arrays_and_nil.rb`.should == '[nil, [2, 2], [[3], [3]]]'
ruby("spec/cases/map_with_nested_arrays_and_nil.rb").should == '[nil, [2, 2], [[3], [3]]]'
end

worker_types.each do |type|
Expand Down Expand Up @@ -388,23 +388,23 @@ def cpus
end

it "spits out a useful error when a worker dies before read" do
`ruby spec/cases/map_with_killed_worker_before_read.rb 2>&1`.should include "DEAD"
ruby("spec/cases/map_with_killed_worker_before_read.rb 2>&1").should include "DEAD"
end

it "spits out a useful error when a worker dies before write" do
`ruby spec/cases/map_with_killed_worker_before_write.rb 2>&1`.should include "DEAD"
ruby("spec/cases/map_with_killed_worker_before_write.rb 2>&1").should include "DEAD"
end

it "raises DeadWorker when using exit so people learn to not kill workers and do not crash main process" do
`ruby spec/cases/exit_in_process.rb 2>&1`.should include "Yep, DEAD"
ruby("spec/cases/exit_in_process.rb 2>&1").should include "Yep, DEAD"
end

it "rescues the Exception raised in child process" do
`ruby spec/cases/exception_raised_in_process.rb 2>&1`.should include "Yep, rescued the exception"
ruby("spec/cases/exception_raised_in_process.rb 2>&1").should include "Yep, rescued the exception"
end

it 'raises EOF (not DeadWorker) when a worker raises EOF in process' do
`ruby spec/cases/eof_in_process.rb 2>&1`.should include 'Yep, EOF'
ruby("spec/cases/eof_in_process.rb 2>&1").should include 'Yep, EOF'
end

it "threads can be killed instantly" do
Expand Down Expand Up @@ -454,7 +454,7 @@ def cpus
end

it "synchronizes :start and :finish" do
out = `ruby spec/cases/synchronizes_start_and_finish.rb`
out = ruby("spec/cases/synchronizes_start_and_finish.rb")
['a', 'b', 'c'].each do |letter|
out.sub! letter.downcase * 10, 'OK'
out.sub! letter.upcase * 10, 'OK'
Expand All @@ -468,29 +468,29 @@ def cpus
end

it 'can work in isolation' do
out = `ruby spec/cases/map_isolation.rb`
out = ruby("spec/cases/map_isolation.rb")
out.should == "1\n2\n3\n4\nOK"
end

it 'sets Parallel.worker_number when run with isolation' do
skip if ENV['TRAVIS'] # this randomly hangs on travis
out = `ruby spec/cases/map_worker_number_isolation.rb`
out = ruby("spec/cases/map_worker_number_isolation.rb")
out.should == "0,1\nOK"
end

it 'can use Timeout' do
out = `ruby spec/cases/timeout_in_threads.rb`
out = ruby("spec/cases/timeout_in_threads.rb")
out.should == "OK\n"
end
end

describe ".map_with_index" do
it "yields object and index" do
`ruby spec/cases/map_with_index.rb 2>&1`.should == 'a0b1'
ruby("spec/cases/map_with_index.rb 2>&1").should == 'a0b1'
end

it "does not crash with empty set" do
`ruby spec/cases/map_with_index_empty.rb 2>&1`.should == ''
ruby("spec/cases/map_with_index_empty.rb 2>&1").should == ''
end

it "can run with 0 threads" do
Expand All @@ -510,33 +510,33 @@ def cpus

describe ".flat_map" do
it "yields object and index" do
`ruby spec/cases/flat_map.rb 2>&1`.should == '["a", ["a"], "b", ["b"]]'
ruby("spec/cases/flat_map.rb 2>&1").should == '["a", ["a"], "b", ["b"]]'
end
end

describe ".any?" do
it "returns true if any result is truthy" do
`ruby spec/cases/any_true.rb`.split(',').should == ['true'] * 3 * 2
ruby("spec/cases/any_true.rb").split(',').should == ['true'] * 3 * 2
end

it "returns false if all results are falsy" do
`ruby spec/cases/any_false.rb`.split(',').should == ['false'] * 3 * 3
ruby("spec/cases/any_false.rb").split(',').should == ['false'] * 3 * 3
end
end

describe ".all?" do
it "returns true if all results are truthy" do
`ruby spec/cases/all_true.rb`.split(',').should == ['true'] * 3 * 3
ruby("spec/cases/all_true.rb").split(',').should == ['true'] * 3 * 3
end

it "returns false if any result is falsy" do
`ruby spec/cases/all_false.rb`.split(',').should == ['false'] * 3 * 2
ruby("spec/cases/all_false.rb").split(',').should == ['false'] * 3 * 2
end
end

describe ".each" do
it "returns original array, works like map" do
`ruby spec/cases/each.rb`.should == 'a b c d'
ruby("spec/cases/each.rb").should == 'a b c d'
end

it "passes result to :finish callback :in_processes`" do
Expand All @@ -556,15 +556,15 @@ def cpus
end

it "does not use marshal_dump" do
`ruby spec/cases/no_dump_with_each.rb 2>&1`.should == 'no dump for resultno dump for each'
ruby("spec/cases/no_dump_with_each.rb 2>&1").should == 'no dump for resultno dump for each'
end

it "does not slow down with lots of GC work in threads" do
Benchmark.realtime { `ruby spec/cases/no_gc_with_each.rb 2>&1` }.should <= (ENV["TRAVIS"] ? 15 : 10)
Benchmark.realtime { ruby("spec/cases/no_gc_with_each.rb 2>&1") }.should <= (ENV["TRAVIS"] ? 15 : 10)
end

it "can modify in-place" do
`ruby spec/cases/each_in_place.rb`.should == 'ab'
ruby("spec/cases/each_in_place.rb").should == 'ab'
end

worker_types.each do |type|
Expand Down Expand Up @@ -626,28 +626,28 @@ def cpus

describe ".each_with_index" do
it "yields object and index" do
["a0b1", "b1a0"].should include `ruby spec/cases/each_with_index.rb 2>&1`
["a0b1", "b1a0"].should include ruby("spec/cases/each_with_index.rb 2>&1")
end
end

describe "progress" do
it "takes the title from :progress" do
`ruby spec/cases/progress.rb 2>&1`.sub(/=+/, '==').strip.should == "Doing stuff: |==|"
ruby("spec/cases/progress.rb 2>&1").sub(/=+/, '==').strip.should == "Doing stuff: |==|"
end

it "takes true from :progress" do
`TITLE=true ruby spec/cases/progress.rb 2>&1`.sub(/=+/, '==').strip.should == "Progress: |==|"
end

it "works with :finish" do
`ruby spec/cases/progress_with_finish.rb 2>&1`.strip.sub(/=+/, '==').gsub(
ruby("spec/cases/progress_with_finish.rb 2>&1").strip.sub(/=+/, '==').gsub(
/\n+/,
"\n"
).should == "Doing stuff: |==|\n100"
end

it "takes the title from :progress[:title] and passes options along" do
`ruby spec/cases/progress_with_options.rb 2>&1`.should =~ /Reticulating Splines ;+ \d+ ;+/
ruby("spec/cases/progress_with_options.rb 2>&1").should =~ /Reticulating Splines ;+ \d+ ;+/
end
end

Expand All @@ -656,11 +656,11 @@ def cpus
let(:result) { "ITEM-1\nITEM-2\nITEM-3\n" }

it "runs in threads" do
`ruby spec/cases/with_#{thing}.rb THREADS 2>&1`.should == result
ruby("spec/cases/with_#{thing}.rb THREADS 2>&1").should == result
end

it "runs in processs" do
`ruby spec/cases/with_#{thing}.rb PROCESSES 2>&1`.should == result
ruby("spec/cases/with_#{thing}.rb PROCESSES 2>&1").should == result
end

it "refuses to use progress" do
Expand All @@ -673,7 +673,7 @@ def cpus

it "fails when running with a prefilled queue without stop since there are no threads to fill it" do
error = (RUBY_VERSION >= "2.0.0" ? "No live threads left. Deadlock?" : "deadlock detected (fatal)")
`ruby spec/cases/fatal_queue.rb 2>&1`.should include error
ruby("spec/cases/fatal_queue.rb 2>&1").should include error
end

describe "GC" do
Expand All @@ -688,7 +688,7 @@ def normalize(result)
it "does not leak memory in #{type}" do
pending if RUBY_ENGINE == 'jruby' # lots of objects ... GC does not seem to work ...
options = (RUBY_ENGINE == 'jruby' ? "-X+O" : "")
result = `ruby #{options} spec/cases/profile_memory.rb #{type} 2>&1`.strip.split("\n").last
result = ruby("#{options} spec/cases/profile_memory.rb #{type} 2>&1").strip.split("\n").last
normalize(result).should == []
end
end
Expand Down
7 changes: 7 additions & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,11 @@
config.expect_with(:rspec) { |c| c.syntax = :should }
config.mock_with(:rspec) { |c| c.syntax = :should }
config.around { |example| Timeout.timeout(30, &example) }
config.include(
Module.new do
def ruby(cmd)
`#{RbConfig.ruby} #{cmd}`
end
end
)
end

0 comments on commit 8e0206c

Please sign in to comment.