diff options
Diffstat (limited to 'spec/bundler/bundler/mirror_spec.rb')
-rw-r--r-- | spec/bundler/bundler/mirror_spec.rb | 329 |
1 files changed, 329 insertions, 0 deletions
diff --git a/spec/bundler/bundler/mirror_spec.rb b/spec/bundler/bundler/mirror_spec.rb new file mode 100644 index 0000000000..9051a80465 --- /dev/null +++ b/spec/bundler/bundler/mirror_spec.rb @@ -0,0 +1,329 @@ +# frozen_string_literal: true +require "spec_helper" +require "bundler/mirror" + +RSpec.describe Bundler::Settings::Mirror do + let(:mirror) { Bundler::Settings::Mirror.new } + + it "returns zero when fallback_timeout is not set" do + expect(mirror.fallback_timeout).to eq(0) + end + + it "takes a number as a fallback_timeout" do + mirror.fallback_timeout = 1 + expect(mirror.fallback_timeout).to eq(1) + end + + it "takes truthy as a default fallback timeout" do + mirror.fallback_timeout = true + expect(mirror.fallback_timeout).to eq(0.1) + end + + it "takes falsey as a zero fallback timeout" do + mirror.fallback_timeout = false + expect(mirror.fallback_timeout).to eq(0) + end + + it "takes a string with 'true' as a default fallback timeout" do + mirror.fallback_timeout = "true" + expect(mirror.fallback_timeout).to eq(0.1) + end + + it "takes a string with 'false' as a zero fallback timeout" do + mirror.fallback_timeout = "false" + expect(mirror.fallback_timeout).to eq(0) + end + + it "takes a string for the uri but returns an uri object" do + mirror.uri = "http://localhost:9292" + expect(mirror.uri).to eq(URI("http://localhost:9292")) + end + + it "takes an uri object for the uri" do + mirror.uri = URI("http://localhost:9293") + expect(mirror.uri).to eq(URI("http://localhost:9293")) + end + + context "without a uri" do + it "invalidates the mirror" do + mirror.validate! + expect(mirror.valid?).to be_falsey + end + end + + context "with an uri" do + before { mirror.uri = "http://localhost:9292" } + + context "without a fallback timeout" do + it "is not valid by default" do + expect(mirror.valid?).to be_falsey + end + + context "when probed" do + let(:probe) { double } + + context "with a replying mirror" do + before do + allow(probe).to receive(:replies?).and_return(true) + mirror.validate!(probe) + end + + it "is valid" do + expect(mirror.valid?).to be_truthy + end + end + + context "with a non replying mirror" do + before do + allow(probe).to receive(:replies?).and_return(false) + mirror.validate!(probe) + end + + it "is still valid" do + expect(mirror.valid?).to be_truthy + end + end + end + end + + context "with a fallback timeout" do + before { mirror.fallback_timeout = 1 } + + it "is not valid by default" do + expect(mirror.valid?).to be_falsey + end + + context "when probed" do + let(:probe) { double } + + context "with a replying mirror" do + before do + allow(probe).to receive(:replies?).and_return(true) + mirror.validate!(probe) + end + + it "is valid" do + expect(mirror.valid?).to be_truthy + end + + it "is validated only once" do + allow(probe).to receive(:replies?).and_raise("Only once!") + mirror.validate!(probe) + expect(mirror.valid?).to be_truthy + end + end + + context "with a non replying mirror" do + before do + allow(probe).to receive(:replies?).and_return(false) + mirror.validate!(probe) + end + + it "is not valid" do + expect(mirror.valid?).to be_falsey + end + + it "is validated only once" do + allow(probe).to receive(:replies?).and_raise("Only once!") + mirror.validate!(probe) + expect(mirror.valid?).to be_falsey + end + end + end + end + + describe "#==" do + it "returns true if uri and fallback timeout are the same" do + uri = "https://ruby.taobao.org" + mirror = Bundler::Settings::Mirror.new(uri, 1) + another_mirror = Bundler::Settings::Mirror.new(uri, 1) + + expect(mirror == another_mirror).to be true + end + end + end +end + +RSpec.describe Bundler::Settings::Mirrors do + let(:localhost_uri) { URI("http://localhost:9292") } + + context "with a just created mirror" do + let(:mirrors) do + probe = double + allow(probe).to receive(:replies?).and_return(true) + Bundler::Settings::Mirrors.new(probe) + end + + it "returns a mirror that contains the source uri for an unknown uri" do + mirror = mirrors.for("http://rubygems.org/") + expect(mirror).to eq(Bundler::Settings::Mirror.new("http://rubygems.org/")) + end + + it "parses a mirror key and returns a mirror for the parsed uri" do + mirrors.parse("mirror.http://rubygems.org/", localhost_uri) + expect(mirrors.for("http://rubygems.org/").uri).to eq(localhost_uri) + end + + it "parses a relative mirror key and returns a mirror for the parsed http uri" do + mirrors.parse("mirror.rubygems.org", localhost_uri) + expect(mirrors.for("http://rubygems.org/").uri).to eq(localhost_uri) + end + + it "parses a relative mirror key and returns a mirror for the parsed https uri" do + mirrors.parse("mirror.rubygems.org", localhost_uri) + expect(mirrors.for("https://rubygems.org/").uri).to eq(localhost_uri) + end + + context "with a uri parsed already" do + before { mirrors.parse("mirror.http://rubygems.org/", localhost_uri) } + + it "takes a mirror fallback_timeout and assigns the timeout" do + mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "2") + expect(mirrors.for("http://rubygems.org/").fallback_timeout).to eq(2) + end + + it "parses a 'true' fallback timeout and sets the default timeout" do + mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "true") + expect(mirrors.for("http://rubygems.org/").fallback_timeout).to eq(0.1) + end + + it "parses a 'false' fallback timeout and sets it to zero" do + mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "false") + expect(mirrors.for("http://rubygems.org/").fallback_timeout).to eq(0) + end + end + end + + context "with a mirror prober that replies on time" do + let(:mirrors) do + probe = double + allow(probe).to receive(:replies?).and_return(true) + Bundler::Settings::Mirrors.new(probe) + end + + context "with a default fallback_timeout for rubygems.org" do + before do + mirrors.parse("mirror.http://rubygems.org/", localhost_uri) + mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "true") + end + + it "returns localhost" do + expect(mirrors.for("http://rubygems.org").uri).to eq(localhost_uri) + end + end + + context "with a mirror for all" do + before do + mirrors.parse("mirror.all", localhost_uri) + end + + context "without a fallback timeout" do + it "returns localhost uri for rubygems" do + expect(mirrors.for("http://rubygems.org").uri).to eq(localhost_uri) + end + + it "returns localhost for any other url" do + expect(mirrors.for("http://whatever.com/").uri).to eq(localhost_uri) + end + end + context "with a fallback timeout" do + before { mirrors.parse("mirror.all.fallback_timeout", "1") } + + it "returns localhost uri for rubygems" do + expect(mirrors.for("http://rubygems.org").uri).to eq(localhost_uri) + end + + it "returns localhost for any other url" do + expect(mirrors.for("http://whatever.com/").uri).to eq(localhost_uri) + end + end + end + end + + context "with a mirror prober that does not reply on time" do + let(:mirrors) do + probe = double + allow(probe).to receive(:replies?).and_return(false) + Bundler::Settings::Mirrors.new(probe) + end + + context "with a localhost mirror for all" do + before { mirrors.parse("mirror.all", localhost_uri) } + + context "without a fallback timeout" do + it "returns localhost" do + expect(mirrors.for("http://whatever.com").uri).to eq(localhost_uri) + end + end + + context "with a fallback timeout" do + before { mirrors.parse("mirror.all.fallback_timeout", "true") } + + it "returns the source uri, not localhost" do + expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + end + end + end + + context "with localhost as a mirror for rubygems.org" do + before { mirrors.parse("mirror.http://rubygems.org/", localhost_uri) } + + context "without a fallback timeout" do + it "returns the uri that is not mirrored" do + expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + end + + it "returns localhost for rubygems.org" do + expect(mirrors.for("http://rubygems.org/").uri).to eq(localhost_uri) + end + end + + context "with a fallback timeout" do + before { mirrors.parse("mirror.http://rubygems.org/.fallback_timeout", "true") } + + it "returns the uri that is not mirrored" do + expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + end + + it "returns rubygems.org for rubygems.org" do + expect(mirrors.for("http://rubygems.org/").uri).to eq(URI("http://rubygems.org/")) + end + end + end + end +end + +RSpec.describe Bundler::Settings::TCPSocketProbe do + let(:probe) { Bundler::Settings::TCPSocketProbe.new } + + context "with a listening TCP Server" do + def with_server_and_mirror + server = TCPServer.new("127.0.0.1", 0) + mirror = Bundler::Settings::Mirror.new("http://localhost:#{server.addr[1]}", 1) + yield server, mirror + server.close unless server.closed? + end + + it "probes the server correctly" do + with_server_and_mirror do |server, mirror| + expect(server.closed?).to be_falsey + expect(probe.replies?(mirror)).to be_truthy + end + end + + it "probes falsey when the server is down" do + with_server_and_mirror do |server, mirror| + server.close + expect(probe.replies?(mirror)).to be_falsey + end + end + end + + context "with an invalid mirror" do + let(:mirror) { Bundler::Settings::Mirror.new("http://127.0.0.127:9292", true) } + + it "fails with a timeout when there is nothing to tcp handshake" do + expect(probe.replies?(mirror)).to be_falsey + end + end +end |