summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPablo Carranza <pcarranza@gmail.com>2015-12-10 00:36:40 +0000
committerPablo Carranza <pcarranza@gmail.com>2015-12-27 22:19:55 +0100
commitdb40676ecbe97c834ff69c35a50178191b0f6dd4 (patch)
treebbe58e51da0353f7de3fa7a3e8802abf274ad4ab
parent206639df28fe4768dd41e0c572c10867aa1ce23e (diff)
downloadbundler-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.rb80
-rw-r--r--lib/bundler/settings.rb4
-rw-r--r--spec/bundler/mirror_spec.rb75
-rw-r--r--spec/bundler/settings_spec.rb2
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