spec/retriable_spec.rb in retriable-2.0.0.beta2 vs spec/retriable_spec.rb in retriable-2.0.0.beta3

- old
+ new

@@ -1,51 +1,60 @@ -require_relative 'spec_helper' +require_relative "spec_helper" class TestError < Exception; end describe Retriable do subject do Retriable end - describe 'with sleep disabled' do + describe "with sleep disabled" do before do Retriable.configure do |c| c.sleep_disabled = true end end - it 'raises a LocalJumpError if retry is not given a block' do - lambda do + it "stops at first attempt if the block does not raise an exception" do + attempts = 0 + subject.retry do + attempts += 1 + end + + attempts.must_equal 1 + end + + it "raises a LocalJumpError if retry is not given a block" do + -> do subject.retry on: EOFError end.must_raise LocalJumpError end - describe 'retry block of code raising EOFError with no arguments' do + describe "retry block of code raising EOFError with no arguments" do before do @attempts = 0 subject.retry do @attempts += 1 raise EOFError.new if @attempts < 3 end end - it 'uses exponential backoff' do + it "uses exponential backoff" do @attempts.must_equal 3 end end - it 'retry on custom exception and re-raises the exception' do - lambda do + it "retry on custom exception and re-raises the exception" do + -> do subject.retry on: TestError do raise TestError.new end end.must_raise TestError end - it 'retry with 10 max tries' do + it "retry with 10 max tries" do attempts = 0 subject.retry( max_tries: 10 ) do @@ -54,25 +63,57 @@ end attempts.must_equal 10 end - it 'retry will timeout after 1 second' do - lambda do + it "retry will timeout after 1 second" do + -> do subject.retry timeout: 1 do sleep 2 end end.must_raise Timeout::Error end - describe 'retries with an on_retry handler, 6 max retries, and a 0.0 rand_factor' do + it "applies a randomized exponential backoff to each attempt" do + @attempts = 0 + @time_table = {} + + handler = ->(exception, attempt, elapsed_time, next_interval) do + exception.class.must_equal ArgumentError + @time_table[attempt] = next_interval + end + + -> do + Retriable.retry( + on: [EOFError, ArgumentError], + on_retry: handler, + rand_factor: 0.0, + max_tries: 9 + ) do + @attempts += 1 + raise ArgumentError.new + end + end.must_raise ArgumentError + + @time_table[1].between?(0.25, 0.75).must_equal true + @time_table[2].between?(0.375, 1.125).must_equal true + @time_table[3].between?(0.562, 1.687).must_equal true + @time_table[4].between?(0.8435, 2.53).must_equal true + @time_table[5].between?(1.265, 3.795).must_equal true + @time_table[6].between?(1.897, 5.692).must_equal true + @time_table[7].between?(2.846, 8.538).must_equal true + @time_table[8].between?(4.269, 12.807).must_equal true + @time_table[9].between?(6.403, 19.210).must_equal true + end + + describe "retries with an on_retry handler, 6 max retries, and a 0.0 rand_factor" do before do max_tries = 6 @attempts = 0 @time_table = {} - handler = Proc.new do |exception, attempt, elapsed_time, next_interval| + handler = ->(exception, attempt, elapsed_time, next_interval) do exception.class.must_equal ArgumentError @time_table[attempt] = next_interval end Retriable.retry( @@ -84,31 +125,31 @@ @attempts += 1 raise ArgumentError.new if @attempts < max_tries end end - it 'makes 6 attempts' do + it "makes 6 attempts" do @attempts.must_equal 6 end - it 'applies a non-randomized exponential backoff to each attempt' do + it "applies a non-randomized exponential backoff to each attempt" do @time_table.must_equal({ 1 => 0.5, 2 => 0.75, 3 => 1.125, 4 => 1.6875, 5 => 2.53125 }) end end - it 'retry has a max interval of 1.5 seconds' do + it "retry has a max interval of 1.5 seconds" do max_tries = 6 attempts = 0 time_table = {} - handler = Proc.new do |exception, attempt, elapsed_time, next_interval| + handler = ->(exception, attempt, elapsed_time, next_interval) do time_table[attempt] = next_interval end subject.retry( on: EOFError, @@ -128,42 +169,75 @@ 4 => 1.5, 5 => 1.5 }) end - it 'can call #retriable in the global' do - lambda do + it "retries with defined intervals" do + intervals = [ + 0.5, + 0.75, + 1.125, + 1.5, + 1.5 + ] + time_table = {} + + handler = ->(exception, attempt, elapsed_time, next_interval) do + time_table[attempt] = next_interval + end + + -> do + subject.retry( + on: EOFError, + on_retry: handler, + intervals: intervals + ) do + raise EOFError.new + end + end.must_raise EOFError + + time_table.must_equal({ + 1 => 0.5, + 2 => 0.75, + 3 => 1.125, + 4 => 1.5, + 5 => 1.5 + }) + end + + it "can call #retriable in the global" do + -> do retriable do - puts 'should raise NoMethodError' + puts "should raise NoMethodError" end end.must_raise NoMethodError - require_relative '../lib/retriable/core_ext/kernel' + require_relative "../lib/retriable/core_ext/kernel" i = 0 retriable do i += 1 raise EOFError.new if i < 3 end i.must_equal 3 end end - it 'retry runs for a max elapsed time of 2 seconds' do + it "retry runs for a max elapsed time of 2 seconds" do subject.configure do |c| c.sleep_disabled = false end subject.config.sleep_disabled.must_equal false attempts = 0 time_table = {} - handler = Proc.new do |exception, attempt, elapsed_time, next_interval| + handler = ->(exception, attempt, elapsed_time, next_interval) do time_table[attempt] = elapsed_time end - lambda do + -> do subject.retry( base_interval: 1.0, multiplier: 1.0, rand_factor: 0.0, max_elapsed_time: 2.0,