require File.expand_path("../../../base", __FILE__) require "vagrant/util/retryable" describe Vagrant::Util::Retryable do let(:klass) do Class.new do extend Vagrant::Util::Retryable end end it "doesn't retry by default" do tries = 0 block = lambda do tries += 1 raise RuntimeError, "Try" end # It should re-raise the error expect { klass.retryable(&block) }. to raise_error(RuntimeError) # It should've tried once tries.should == 1 end it "retries the set number of times" do tries = 0 block = lambda do tries += 1 raise RuntimeError, "Try" end # It should re-raise the error expect { klass.retryable(:tries => 5, &block) }. to raise_error(RuntimeError) # It should've tried all specified times tries.should == 5 end it "only retries on the given exception" do tries = 0 block = lambda do tries += 1 raise StandardError, "Try" end # It should re-raise the error expect { klass.retryable(:tries => 5, :on => RuntimeError, &block) }. to raise_error(StandardError) # It should've never tried since it was a different kind of error tries.should == 1 end it "can retry on multiple types of errors" do tries = 0 foo_error = Class.new(StandardError) bar_error = Class.new(StandardError) block = lambda do tries += 1 raise foo_error, "Try" if tries == 1 raise bar_error, "Try" if tries == 2 raise RuntimeError, "YAY" end # It should re-raise the error expect { klass.retryable(:tries => 5, :on => [foo_error, bar_error], &block) }. to raise_error(RuntimeError) # It should've never tried since it was a different kind of error tries.should == 3 end it "doesn't sleep between tries by default" do block = lambda do raise RuntimeError, "Try" end # Sleep should never be called klass.should_not_receive(:sleep) # Run it. expect { klass.retryable(:tries => 5, &block) }. to raise_error(RuntimeError) end it "sleeps specified amount between retries" do block = lambda do raise RuntimeError, "Try" end # Sleep should be called between each retry klass.should_receive(:sleep).with(10).exactly(4).times # Run it. expect { klass.retryable(:tries => 5, :sleep => 10, &block) }. to raise_error(RuntimeError) end end