diff options
author | Pablo Carranza <pcarranza@gmail.com> | 2015-12-10 00:36:40 +0000 |
---|---|---|
committer | Pablo Carranza <pcarranza@gmail.com> | 2015-12-27 22:19:55 +0100 |
commit | db40676ecbe97c834ff69c35a50178191b0f6dd4 (patch) | |
tree | bbe58e51da0353f7de3fa7a3e8802abf274ad4ab | |
parent | 206639df28fe4768dd41e0c572c10867aa1ce23e (diff) | |
download | bundler-db40676ecbe97c834ff69c35a50178191b0f6dd4.tar.gz |
WIP - mirror is picked depending on the probing working or not, all has precedence
Still no implementation for probing
-rw-r--r-- | lib/bundler/mirror.rb | 80 | ||||
-rw-r--r-- | lib/bundler/settings.rb | 4 | ||||
-rw-r--r-- | spec/bundler/mirror_spec.rb | 75 | ||||
-rw-r--r-- | spec/bundler/settings_spec.rb | 2 |
4 files changed, 129 insertions, 32 deletions
diff --git a/lib/bundler/mirror.rb b/lib/bundler/mirror.rb index 9824629635..538c803f76 100644 --- a/lib/bundler/mirror.rb +++ b/lib/bundler/mirror.rb @@ -2,26 +2,28 @@ module Bundler class Settings class Mirrors def initialize(prober = nil) - @prober = prober || TCPProbe.new @all = Mirror.new - @mirrors = Hash.new { |h, k| h[k] = Mirror.new } - end - - def [](key) - @mirrors[URI(key.to_s)] + @prober = prober || MirrorProber.new + @mirrors = Hash.new end def for(uri) - return @all.uri if @all.valid? uri = AbsoluteURI.normalize(uri) - return uri unless @mirrors[uri] - mirror = @mirrors[uri] - @prober.probe(mirror) - mirror.uri + validate_mirror_for_all + validate_mirror_for(uri) + if @all.valid? + @all + else + mirror = fetch_valid_mirror_for(uri) || Mirror.new(uri) + mirror + end end - def fetch(key, &block) - @mirrors.fetch(key, &block) + def fetch_valid_mirror_for(uri) + mirror = @mirrors[uri] + return nil if mirror.nil? + return nil unless mirror.valid? + mirror end def each @@ -35,10 +37,22 @@ module Bundler if config.all? mirror = @all else - mirror = self[config.uri] + mirror = @mirrors[config.uri] || Mirror.new + @mirrors[config.uri] = mirror end config.update_mirror(mirror) end + + private + + def validate_mirror_for_all + MirrorProbing.new(@all, @prober).probe! if @all.valid? + end + + def validate_mirror_for(uri) + mirror = @mirrors[uri] + MirrorProbing.new(mirror, @prober).probe! unless mirror.nil? + end end class Mirror @@ -49,6 +63,7 @@ module Bundler def initialize(uri = nil, fallback_timeout = 0) self.uri = uri self.fallback_timeout = fallback_timeout + @valid = nil end def uri=(uri) @@ -71,21 +86,52 @@ module Bundler end def ==(o) - self.class == o.class && self.uri == o.uri && self.fallback_timeout == o.fallback_timeout + o != nil && self.uri == o.uri && self.fallback_timeout == o.fallback_timeout end def valid? + return @valid unless @valid.nil? ! @uri.nil? end + + def validate! + @valid = true + end + + def invalidate! + @valid = false + end + + def validated_already? + ! @valid.nil? + end end - class TCPProbe - def probe(uri) + class MirrorProber + def probe_availability(mirror) + true end end private + class MirrorProbing + def initialize(mirror, prober) + @mirror = mirror + @prober = prober + end + + def probe! + return @mirror if @mirror.validated_already? + if @prober.probe_availability(@mirror) + @mirror.validate! + else + @mirror.invalidate! + end + @mirror + end + end + class MirrorConfig attr_accessor :uri, :value diff --git a/lib/bundler/settings.rb b/lib/bundler/settings.rb index f3eed3b3df..4f2fbe1050 100644 --- a/lib/bundler/settings.rb +++ b/lib/bundler/settings.rb @@ -63,10 +63,8 @@ module Bundler def mirror_for(uri) uri = URI(uri.to_s) unless uri.is_a?(URI) - # Settings keys are all downcased - normalized_key = AbsoluteURI.normalize(uri.to_s.downcase) - (gem_mirrors.fetch(normalized_key) { Mirror.new(uri) }).uri + gem_mirrors.for(uri.to_s.downcase).uri end def credentials_for(uri) diff --git a/spec/bundler/mirror_spec.rb b/spec/bundler/mirror_spec.rb index 49b1276aa4..6217cf2ed3 100644 --- a/spec/bundler/mirror_spec.rb +++ b/spec/bundler/mirror_spec.rb @@ -39,41 +39,94 @@ describe Bundler::Settings::Mirrors do let(:mirrors) { Bundler::Settings::Mirrors.new } it "returns an empty mirror for a new uri" do - mirror = mirrors["http://rubygems.org/"] - expect(mirror).to eq(Bundler::Settings::Mirror.new) + mirror = mirrors.for("http://rubygems.org/") + expect(mirror).to eq(Bundler::Settings::Mirror.new("http://rubygems.org/")) end it "takes a mirror key and assings the uri" do mirrors.parse("mirror.http://rubygems.org/", "http://localhost:9292") - expect(mirrors["http://rubygems.org/"].uri).to eq(URI("http://localhost:9292")) + expect(mirrors.for("http://rubygems.org/").uri).to eq(URI("http://localhost:9292")) end it "takes a mirror fallback_timeout and assigns the timeout" do + mirrors.parse("mirror.http://rubygems.org/", "http://localhost:9292") mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "2") - expect(mirrors["http://rubygems.org/"].fallback_timeout).to eq(2) + expect(mirrors.for("http://rubygems.org/").fallback_timeout).to eq(2) end end - context "with a stubbed with a successfull probe mirrors" do + context "with a stubbed with a successfull probe mirrors and a fallback timeout" do let(:mirrors) do probe = double() - allow(probe).to receive(:probe) + allow(probe).to receive(:probe_availability).and_return(true) Bundler::Settings::Mirrors.new(probe) end context "with a default fallback_timeout defined" do - before { mirrors.parse("mirror.http://rubygems.org/", "http://localhost:9292") } + before do + mirrors.parse("mirror.http://rubygems.org/", "http://localhost:9292") + mirrors.parse("mirror.http://rubygems.org.fallback_timeout", "true") + end it "returns the mirrored uri" do - expect(mirrors.for("http://rubygems.org")).to eq(URI("http://localhost:9292")) + expect(mirrors.for("http://rubygems.org").uri).to eq(URI("http://localhost:9292")) end end context "setup to fallback all uris" do - before { mirrors.parse("mirror.all", "http://localhost:9292") } + let(:localhost_uri) { URI("http://localhost:9292") } - it "returns the mirrored uri" do - expect(mirrors.for("http://rubygems.org")).to eq(URI("http://localhost:9292")) + before do + mirrors.parse("mirror.all", localhost_uri) + end + + it "returns the same mirror for any uri" do + expect(mirrors.for("http://bla/").uri).to eq(localhost_uri) + expect(mirrors.for("http://1.com/").uri).to eq(localhost_uri) + expect(mirrors.for("http://any.org").uri).to eq(localhost_uri) + end + + it "returns the mirrored uri for rubygems" do + expect(mirrors.for("http://rubygems.org").uri).to eq(localhost_uri) + end + it "returns the mirrored uri for any other url" do + expect(mirrors.for("http://whatever.com/").uri).to eq(localhost_uri) + end + end + end + + context "with a stubbed with an unsuccessfull probe mirrors and a fallback timeout" do + let(:localhost_uri) { URI("http://localhost:9292") } + let(:mirrors) do + probe = double() + allow(probe).to receive(:probe_availability).and_return(false) + Bundler::Settings::Mirrors.new(probe) + end + + context "mirroring all the urls with a fallback timeout" do + before do + mirrors.parse("mirror.all", localhost_uri) + mirrors.parse("mirror.all.fallback_timeout", true) + end + + context "with a default fallback_timeout defined" do + it "returns the original uri" do + expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + end + end + end + + context "mirroring one url with a default fallback timeout" do + before do + mirrors.parse("mirror.http://rubygems.org/", "http://localhost:9292") + mirrors.parse("mirror.http://rubygems.org/.fallback_timeout", "true") + end + + it "returns the original uri for a different uri" do + expect(mirrors.for("http://whatever.com").uri).to eq(URI("http://whatever.com/")) + end + it "returns the original uri for the mirrored uri" do + expect(mirrors.for("http://rubygems.org/").uri).to eq(URI("http://rubygems.org/")) end end end diff --git a/spec/bundler/settings_spec.rb b/spec/bundler/settings_spec.rb index 914f600357..c215b79eb3 100644 --- a/spec/bundler/settings_spec.rb +++ b/spec/bundler/settings_spec.rb @@ -111,7 +111,7 @@ describe Bundler::Settings do end it "returns the fallback timeout" do - expect(settings.gem_mirrors[uri].fallback_timeout).to eq(1) + expect(settings.gem_mirrors.for(uri).fallback_timeout).to eq(1) end end end |