2018-11-02 23:07:56 +00:00
# frozen_string_literal: true
RSpec . describe " compact index api " do
let ( :source_hostname ) { " localgemserver.test " }
let ( :source_uri ) { " http:// #{ source_hostname } " }
it " should use the API " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " should URI encode gem names " do
gemfile <<-G
source " #{ source_uri } "
gem " sinatra "
G
bundle :install , :artifice = > " compact_index "
2019-04-14 06:01:35 +00:00
expect ( err ) . to include ( " ' sinatra' is not a valid gem name because it contains whitespace. " )
2018-11-02 23:07:56 +00:00
end
it " should handle nested dependencies " do
gemfile <<-G
source " #{ source_uri } "
gem " rails "
G
bundle! :install , :artifice = > " compact_index "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems (
" rails 2.3.2 " ,
" actionpack 2.3.2 " ,
" activerecord 2.3.2 " ,
" actionmailer 2.3.2 " ,
" activeresource 2.3.2 " ,
" activesupport 2.3.2 "
)
end
it " should handle case sensitivity conflicts " do
build_repo4 do
build_gem " rack " , " 1.0 " do | s |
s . add_runtime_dependency ( " Rack " , " 0.1 " )
end
build_gem " Rack " , " 0.1 "
end
install_gemfile! <<-G, :artifice => "compact_index", :env => { "BUNDLER_SPEC_GEM_REPO" => gem_repo4 }
source " #{ source_uri } "
gem " rack " , " 1.0 "
gem " Rack " , " 0.1 "
G
# can't use `include_gems` here since the `require` will conflict on a
# case-insensitive FS
run! " Bundler.require; puts Gem.loaded_specs.values_at('rack', 'Rack').map(&:full_name) "
expect ( last_command . stdout ) . to eq ( " rack-1.0 \n Rack-0.1 " )
end
it " should handle multiple gem dependencies on the same gem " do
gemfile <<-G
source " #{ source_uri } "
gem " net-sftp "
G
bundle! :install , :artifice = > " compact_index "
expect ( the_bundle ) . to include_gems " net-sftp 1.1.1 "
end
it " should use the endpoint when using --deployment " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index "
bundle! :install , forgotten_command_line_options ( :deployment = > true , :path = > " vendor/bundle " ) . merge ( :artifice = > " compact_index " )
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " handles git dependencies that are in rubygems " do
build_git " foo " do | s |
s . executables = " foobar "
s . add_dependency " rails " , " 2.3.2 "
end
gemfile <<-G
source " #{ source_uri } "
git " file:/// #{ lib_path ( " foo-1.0 " ) } " do
gem 'foo'
end
G
bundle! :install , :artifice = > " compact_index "
expect ( the_bundle ) . to include_gems ( " rails 2.3.2 " )
end
it " handles git dependencies that are in rubygems using --deployment " do
build_git " foo " do | s |
s . executables = " foobar "
s . add_dependency " rails " , " 2.3.2 "
end
gemfile <<-G
source " #{ source_uri } "
gem 'foo' , :git = > " file:/// #{ lib_path ( " foo-1.0 " ) } "
G
bundle! :install , :artifice = > " compact_index "
bundle " install --deployment " , :artifice = > " compact_index "
expect ( the_bundle ) . to include_gems ( " rails 2.3.2 " )
end
it " doesn't fail if you only have a git gem with no deps when using --deployment " do
build_git " foo "
gemfile <<-G
source " #{ source_uri } "
gem 'foo' , :git = > " file:/// #{ lib_path ( " foo-1.0 " ) } "
G
bundle " install " , :artifice = > " compact_index "
bundle! :install , forgotten_command_line_options ( :deployment = > true ) . merge ( :artifice = > " compact_index " )
expect ( the_bundle ) . to include_gems ( " foo 1.0 " )
end
it " falls back when the API errors out " do
simulate_platform mswin
gemfile <<-G
source " #{ source_uri } "
gem " rcov "
G
bundle! :install , :artifice = > " windows "
expect ( out ) . to include ( " Fetching source index from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rcov 1.0.0 "
end
it " falls back when the API URL returns 403 Forbidden " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle! :install , :verbose = > true , :artifice = > " compact_index_forbidden "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " falls back when the versions endpoint has a checksum mismatch " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle! :install , :verbose = > true , :artifice = > " compact_index_checksum_mismatch "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( out ) . to include <<-'WARN'
The checksum of / versions does not match the checksum provided by the server! Something is wrong (local checksum is " \ "d41d8cd98f00b204e9800998ecf8427e \ "", was expecting " \ "123 \ "").
WARN
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " falls back when the user's home directory does not exist or is not writable " do
ENV [ " HOME " ] = tmp ( " missing_home " ) . to_s
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " handles host redirects " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index_host_redirect "
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " handles host redirects without Net::HTTP::Persistent " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
FileUtils . mkdir_p lib_path
File . open ( lib_path ( " disable_net_http_persistent.rb " ) , " w " ) do | h |
h . write <<-H
module Kernel
alias require_without_disabled_net_http require
def require ( * args )
raise LoadError , 'simulated' if args . first == 'openssl' && ! caller . grep ( / vendored_persistent / ) . empty?
require_without_disabled_net_http ( * args )
end
end
H
end
bundle! :install , :artifice = > " compact_index_host_redirect " , :requires = > [ lib_path ( " disable_net_http_persistent.rb " ) ]
expect ( out ) . to_not match ( / Too many redirects / )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " times out when Bundler::Fetcher redirects too much " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle :install , :artifice = > " compact_index_redirects "
2019-04-14 06:01:35 +00:00
expect ( err ) . to match ( / Too many redirects / )
2018-11-02 23:07:56 +00:00
end
context " when --full-index is specified " do
it " should use the modern index for install " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle " install --full-index " , :artifice = > " compact_index "
expect ( out ) . to include ( " Fetching source index from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " should use the modern index for update " do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
2019-04-14 06:01:35 +00:00
bundle! " update --full-index " , :artifice = > " compact_index " , :all = > true
2018-11-02 23:07:56 +00:00
expect ( out ) . to include ( " Fetching source index from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
end
it " does not double check for gems that are only installed locally " do
system_gems %w[ rack-1.0.0 thin-1.0 net_a-1.0 ]
2019-04-14 06:01:35 +00:00
bundle! " config set --local path.system true "
2018-11-02 23:07:56 +00:00
ENV [ " BUNDLER_SPEC_ALL_REQUESTS " ] = strip_whitespace ( <<-EOS).strip
#{source_uri}/versions
#{source_uri}/info/rack
EOS
install_gemfile! <<-G, :artifice => "compact_index", :verbose => true
source " #{ source_uri } "
gem " rack "
G
expect ( last_command . stdboth ) . not_to include " Double checking "
end
2019-01-04 13:10:58 +00:00
it " fetches again when more dependencies are found in subsequent sources " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
build_repo2 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
FileUtils . rm_rf Dir [ gem_repo2 ( " gems/foo-*.gem " ) ]
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra "
gem " back_deps "
G
bundle! :install , :artifice = > " compact_index_extra "
expect ( the_bundle ) . to include_gems " back_deps 1.0 " , " foo 1.0 "
end
it " fetches again when more dependencies are found in subsequent sources with source blocks " do
build_repo2 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
FileUtils . rm_rf Dir [ gem_repo2 ( " gems/foo-*.gem " ) ]
end
install_gemfile! <<-G, :artifice => "compact_index_extra", :verbose => true
source " #{ source_uri } "
source " #{ source_uri } /extra " do
gem " back_deps "
end
G
expect ( the_bundle ) . to include_gems " back_deps 1.0 " , " foo 1.0 "
end
it " fetches gem versions even when those gems are already installed " do
gemfile <<-G
source " #{ source_uri } "
gem " rack " , " 1.0.0 "
G
bundle! :install , :artifice = > " compact_index_extra_api "
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
build_repo4 do
build_gem " rack " , " 1.2 " do | s |
s . executables = " rackup "
end
end
gemfile <<-G
source " #{ source_uri } " do ; end
source " #{ source_uri } /extra "
gem " rack " , " 1.2 "
G
bundle! :install , :artifice = > " compact_index_extra_api "
expect ( the_bundle ) . to include_gems " rack 1.2 "
end
2019-01-04 13:10:58 +00:00
it " considers all possible versions of dependencies from all api gem sources " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
# repo and installs it.
build_repo4 do
build_gem " activesupport " , " 1.2.0 "
build_gem " somegem " , " 1.0.0 " do | s |
s . add_dependency " activesupport " , " 1.2.3 " # This version exists only in repo1
end
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra "
gem 'somegem' , '1.0.0'
G
bundle! :install , :artifice = > " compact_index_extra_api "
expect ( the_bundle ) . to include_gems " somegem 1.0.0 "
expect ( the_bundle ) . to include_gems " activesupport 1.2.3 "
end
2019-01-04 13:10:58 +00:00
it " considers all possible versions of dependencies from all api gem sources when using blocks " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
# In this scenario, the gem "somegem" only exists in repo4. It depends on specific version of activesupport that
# exists only in repo1. There happens also be a version of activesupport in repo4, but not the one that version 1.0.0
# of somegem wants. This test makes sure that bundler actually finds version 1.2.3 of active support in the other
# repo and installs it.
build_repo4 do
build_gem " activesupport " , " 1.2.0 "
build_gem " somegem " , " 1.0.0 " do | s |
s . add_dependency " activesupport " , " 1.2.3 " # This version exists only in repo1
end
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra " do
gem 'somegem' , '1.0.0'
end
G
bundle! :install , :artifice = > " compact_index_extra_api "
expect ( the_bundle ) . to include_gems " somegem 1.0.0 "
expect ( the_bundle ) . to include_gems " activesupport 1.2.3 "
end
it " prints API output properly with back deps " do
build_repo2 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
FileUtils . rm_rf Dir [ gem_repo2 ( " gems/foo-*.gem " ) ]
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra " do
gem " back_deps "
end
G
bundle! :install , :artifice = > " compact_index_extra "
expect ( out ) . to include ( " Fetching gem metadata from http://localgemserver.test/ " )
expect ( out ) . to include ( " Fetching source index from http://localgemserver.test/extra " )
end
it " does not fetch every spec if the index of gems is large when doing back deps " do
build_repo2 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
build_gem " missing "
# need to hit the limit
1 . upto ( Bundler :: Source :: Rubygems :: API_REQUEST_LIMIT ) do | i |
build_gem " gem #{ i } "
end
FileUtils . rm_rf Dir [ gem_repo2 ( " gems/foo-*.gem " ) ]
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra " do
gem " back_deps "
end
G
bundle! :install , :artifice = > " compact_index_extra_missing "
expect ( the_bundle ) . to include_gems " back_deps 1.0 "
end
it " does not fetch every spec if the index of gems is large when doing back deps & everything is the compact index " do
build_repo4 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
build_gem " missing "
# need to hit the limit
1 . upto ( Bundler :: Source :: Rubygems :: API_REQUEST_LIMIT ) do | i |
build_gem " gem #{ i } "
end
FileUtils . rm_rf Dir [ gem_repo4 ( " gems/foo-*.gem " ) ]
end
install_gemfile! <<-G, :artifice => "compact_index_extra_api_missing"
source " #{ source_uri } "
source " #{ source_uri } /extra " do
gem " back_deps "
end
G
expect ( the_bundle ) . to include_gem " back_deps 1.0 "
end
it " uses the endpoint if all sources support it " do
gemfile <<-G
source " #{ source_uri } "
gem 'foo'
G
bundle! :install , :artifice = > " compact_index_api_missing "
expect ( the_bundle ) . to include_gems " foo 1.0 "
end
2019-01-04 13:10:58 +00:00
it " fetches again when more dependencies are found in subsequent sources using --deployment " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
build_repo2 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
FileUtils . rm_rf Dir [ gem_repo2 ( " gems/foo-*.gem " ) ]
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra "
gem " back_deps "
G
bundle! :install , :artifice = > " compact_index_extra "
bundle " install --deployment " , :artifice = > " compact_index_extra "
expect ( the_bundle ) . to include_gems " back_deps 1.0 "
end
it " fetches again when more dependencies are found in subsequent sources using --deployment with blocks " do
build_repo2 do
build_gem " back_deps " do | s |
s . add_dependency " foo "
end
FileUtils . rm_rf Dir [ gem_repo2 ( " gems/foo-*.gem " ) ]
end
gemfile <<-G
source " #{ source_uri } "
source " #{ source_uri } /extra " do
gem " back_deps "
end
G
bundle! :install , :artifice = > " compact_index_extra "
bundle " install --deployment " , :artifice = > " compact_index_extra "
expect ( the_bundle ) . to include_gems " back_deps 1.0 "
end
it " does not refetch if the only unmet dependency is bundler " do
gemfile <<-G
source " #{ source_uri } "
gem " bundler_dep "
G
bundle! :install , :artifice = > " compact_index "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
end
it " should install when EndpointSpecification has a bin dir owned by root " , :sudo = > true do
sudo " mkdir -p #{ system_gem_path ( " bin " ) } "
sudo " chown -R root #{ system_gem_path ( " bin " ) } "
gemfile <<-G
source " #{ source_uri } "
gem " rails "
G
bundle! :install , :artifice = > " compact_index "
expect ( the_bundle ) . to include_gems " rails 2.3.2 "
end
2019-01-04 13:10:58 +00:00
it " installs the binstubs " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle " install --binstubs " , :artifice = > " compact_index "
gembin " rackup "
expect ( out ) . to eq ( " 1.0.0 " )
end
2019-01-04 13:10:58 +00:00
it " installs the bins when using --path and uses autoclean " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle " install --path vendor/bundle " , :artifice = > " compact_index "
expect ( vendored_gems ( " bin/rackup " ) ) . to exist
end
2019-01-04 13:10:58 +00:00
it " installs the bins when using --path and uses bundle clean " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
bundle " install --path vendor/bundle --no-clean " , :artifice = > " compact_index "
expect ( vendored_gems ( " bin/rackup " ) ) . to exist
end
it " prints post_install_messages " do
gemfile <<-G
source " #{ source_uri } "
gem 'rack-obama'
G
bundle! :install , :artifice = > " compact_index "
expect ( out ) . to include ( " Post-install message from rack: " )
end
it " should display the post install message for a dependency " do
gemfile <<-G
source " #{ source_uri } "
gem 'rack_middleware'
G
bundle! :install , :artifice = > " compact_index "
expect ( out ) . to include ( " Post-install message from rack: " )
expect ( out ) . to include ( " Rack's post install message " )
end
context " when using basic authentication " do
let ( :user ) { " user " }
let ( :password ) { " pass " }
let ( :basic_auth_source_uri ) do
uri = URI . parse ( source_uri )
uri . user = user
uri . password = password
uri
end
it " passes basic authentication details and strips out creds " do
gemfile <<-G
source " #{ basic_auth_source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index_basic_authentication "
expect ( out ) . not_to include ( " #{ user } : #{ password } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " strips http basic authentication creds for modern index " do
gemfile <<-G
source " #{ basic_auth_source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " endopint_marshal_fail_basic_authentication "
expect ( out ) . not_to include ( " #{ user } : #{ password } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " strips http basic auth creds when it can't reach the server " do
gemfile <<-G
source " #{ basic_auth_source_uri } "
gem " rack "
G
bundle :install , :artifice = > " endpoint_500 "
expect ( out ) . not_to include ( " #{ user } : #{ password } " )
end
2019-01-04 13:10:58 +00:00
it " strips http basic auth creds when warning about ambiguous sources " , :bundler = > " < 3 " do
2018-11-02 23:07:56 +00:00
gemfile <<-G
source " #{ basic_auth_source_uri } "
source " file:// #{ gem_repo1 } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index_basic_authentication "
2019-04-14 06:01:35 +00:00
expect ( err ) . to include ( " Warning: the gem 'rack' was found in multiple sources. " )
expect ( err ) . not_to include ( " #{ user } : #{ password } " )
2018-11-02 23:07:56 +00:00
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " does not pass the user / password to different hosts on redirect " do
gemfile <<-G
source " #{ basic_auth_source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index_creds_diff_host "
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
describe " with authentication details in bundle config " do
before do
gemfile <<-G
source " #{ source_uri } "
gem " rack "
G
end
it " reads authentication details by host name from bundle config " do
2019-04-14 06:01:35 +00:00
bundle " config set #{ source_hostname } #{ user } : #{ password } "
2018-11-02 23:07:56 +00:00
bundle! :install , :artifice = > " compact_index_strict_basic_authentication "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " reads authentication details by full url from bundle config " do
# The trailing slash is necessary here; Fetcher canonicalizes the URI.
2019-04-14 06:01:35 +00:00
bundle " config set #{ source_uri } / #{ user } : #{ password } "
2018-11-02 23:07:56 +00:00
bundle! :install , :artifice = > " compact_index_strict_basic_authentication "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " should use the API " do
2019-04-14 06:01:35 +00:00
bundle " config set #{ source_hostname } #{ user } : #{ password } "
2018-11-02 23:07:56 +00:00
bundle! :install , :artifice = > " compact_index_strict_basic_authentication "
expect ( out ) . to include ( " Fetching gem metadata from #{ source_uri } " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " prefers auth supplied in the source uri " do
gemfile <<-G
source " #{ basic_auth_source_uri } "
gem " rack "
G
2019-04-14 06:01:35 +00:00
bundle " config set #{ source_hostname } otheruser:wrong "
2018-11-02 23:07:56 +00:00
bundle! :install , :artifice = > " compact_index_strict_basic_authentication "
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " shows instructions if auth is not provided for the source " do
bundle :install , :artifice = > " compact_index_strict_basic_authentication "
2019-04-14 06:01:35 +00:00
expect ( err ) . to include ( " bundle config set #{ source_hostname } username:password " )
2018-11-02 23:07:56 +00:00
end
it " fails if authentication has already been provided, but failed " do
2019-04-14 06:01:35 +00:00
bundle " config set #{ source_hostname } #{ user } :wrong "
2018-11-02 23:07:56 +00:00
bundle :install , :artifice = > " compact_index_strict_basic_authentication "
2019-04-14 06:01:35 +00:00
expect ( err ) . to include ( " Bad username or password " )
2018-11-02 23:07:56 +00:00
end
end
describe " with no password " do
let ( :password ) { nil }
it " passes basic authentication details " do
gemfile <<-G
source " #{ basic_auth_source_uri } "
gem " rack "
G
bundle! :install , :artifice = > " compact_index_basic_authentication "
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
end
end
context " when ruby is compiled without openssl " do
before do
# Install a monkeypatch that reproduces the effects of openssl being
# missing when the fetcher runs, as happens in real life. The reason
# we can't just overwrite openssl.rb is that Artifice uses it.
bundled_app ( " broken_ssl " ) . mkpath
bundled_app ( " broken_ssl/openssl.rb " ) . open ( " w " ) do | f |
f . write <<-RUBY
raise LoadError , " cannot load such file -- openssl "
RUBY
end
end
it " explains what to do to get it " do
gemfile <<-G
source " #{ source_uri . gsub ( / http / , " https " ) } "
gem " rack "
G
bundle :install , :env = > { " RUBYOPT " = > " -I #{ bundled_app ( " broken_ssl " ) } " }
2019-04-14 06:01:35 +00:00
expect ( err ) . to include ( " OpenSSL " )
2018-11-02 23:07:56 +00:00
end
end
context " when SSL certificate verification fails " do
it " explains what happened " do
# Install a monkeypatch that reproduces the effects of openssl raising
# a certificate validation error when RubyGems tries to connect.
gemfile <<-G
class Net :: HTTP
def start
raise OpenSSL :: SSL :: SSLError , " certificate verify failed "
end
end
source " #{ source_uri . gsub ( / http / , " https " ) } "
gem " rack "
G
bundle :install
2019-04-14 06:01:35 +00:00
expect ( err ) . to match ( / could not verify the SSL certificate /i )
2018-11-02 23:07:56 +00:00
end
end
context " .gemrc with sources is present " do
before do
File . open ( home ( " .gemrc " ) , " w " ) do | file |
file . puts ( { :sources = > [ " https://rubygems.org " ] } . to_yaml )
end
end
after do
home ( " .gemrc " ) . rmtree
end
it " uses other sources declared in the Gemfile " do
gemfile <<-G
source " #{ source_uri } "
gem 'rack'
G
bundle! :install , :artifice = > " compact_index_forbidden "
end
end
it " performs partial update with a non-empty range " do
gemfile <<-G
source " #{ source_uri } "
gem 'rack' , '0.9.1'
G
# Initial install creates the cached versions file
bundle! :install , :artifice = > " compact_index "
# Update the Gemfile so we can check subsequent install was successful
gemfile <<-G
source " #{ source_uri } "
gem 'rack' , '1.0.0'
G
# Second install should make only a partial request to /versions
bundle! :install , :artifice = > " compact_index_partial_update "
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " performs partial update while local cache is updated by another process " do
gemfile <<-G
source " #{ source_uri } "
gem 'rack'
G
# Create an empty file to trigger a partial download
versions = File . join ( Bundler . rubygems . user_home , " .bundle " , " cache " , " compact_index " ,
" localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5 " , " versions " )
FileUtils . mkdir_p ( File . dirname ( versions ) )
FileUtils . touch ( versions )
bundle! :install , :artifice = > " compact_index_concurrent_download "
expect ( File . read ( versions ) ) . to start_with ( " created_at " )
expect ( the_bundle ) . to include_gems " rack 1.0.0 "
end
it " performs full update of compact index info cache if range is not satisfiable " do
gemfile <<-G
source " #{ source_uri } "
gem 'rack' , '0.9.1'
G
rake_info_path = File . join ( Bundler . rubygems . user_home , " .bundle " , " cache " , " compact_index " ,
" localgemserver.test.80.dd34752a738ee965a2a4298dc16db6c5 " , " info " , " rack " )
bundle! :install , :artifice = > " compact_index "
expected_rack_info_content = File . read ( rake_info_path )
# Modify the cache files. We expect them to be reset to the normal ones when we re-run :install
File . open ( rake_info_path , " w " ) { | f | f << ( expected_rack_info_content + " this is different " ) }
# Update the Gemfile so the next install does its normal things
gemfile <<-G
source " #{ source_uri } "
gem 'rack' , '1.0.0'
G
# The cache files now being longer means the requested range is going to be not satisfiable
# Bundler must end up requesting the whole file to fix things up.
bundle! :install , :artifice = > " compact_index_range_not_satisfiable "
resulting_rack_info_content = File . read ( rake_info_path )
expect ( resulting_rack_info_content ) . to eq ( expected_rack_info_content )
end
it " fails gracefully when the source URI has an invalid scheme " do
install_gemfile <<-G
source " htps://rubygems.org "
gem " rack "
G
expect ( exitstatus ) . to eq ( 15 ) if exitstatus
2019-04-14 06:01:35 +00:00
expect ( err ) . to end_with ( <<-E.strip)
2018-11-02 23:07:56 +00:00
The request uri ` htps://index.rubygems.org/versions ` has an invalid scheme ( ` htps ` ) . Did you mean ` http ` or ` https ` ?
E
end
2019-04-14 06:01:35 +00:00
describe " checksum validation " do
2018-11-02 23:07:56 +00:00
it " raises when the checksum does not match " do
install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum"
source " #{ source_uri } "
gem " rack "
G
expect ( exitstatus ) . to eq ( 19 ) if exitstatus
2019-04-14 06:01:35 +00:00
expect ( err ) .
2018-11-02 23:07:56 +00:00
to include ( " Bundler cannot continue installing rack (1.0.0). " ) .
and include ( " The checksum for the downloaded `rack-1.0.0.gem` does not match the checksum given by the server. " ) .
and include ( " This means the contents of the downloaded gem is different from what was uploaded to the server, and could be a potential security issue. " ) .
and include ( " To resolve this issue: " ) .
and include ( " 1. delete the downloaded gem located at: ` #{ default_bundle_path } /gems/rack-1.0.0/rack-1.0.0.gem` " ) .
and include ( " 2. run `bundle install` " ) .
and include ( " If you wish to continue installing the downloaded gem, and are certain it does not pose a security issue despite the mismatching checksum, do the following: " ) .
2019-04-14 06:01:35 +00:00
and include ( " 1. run `bundle config set disable_checksum_validation true` to turn off checksum verification " ) .
2018-11-02 23:07:56 +00:00
and include ( " 2. run `bundle install` " ) .
and match ( / \ (More info: The expected SHA256 checksum was " #{ " ab " * 22 } ", but the checksum for the downloaded gem was ".+?" \ . \ ) / )
end
it " raises when the checksum is the wrong length " do
install_gemfile <<-G, :artifice => "compact_index_wrong_gem_checksum", :env => { "BUNDLER_SPEC_RACK_CHECKSUM" => "checksum!" }
source " #{ source_uri } "
gem " rack "
G
expect ( exitstatus ) . to eq ( 5 ) if exitstatus
2019-04-14 06:01:35 +00:00
expect ( err ) . to include ( " The given checksum for rack-1.0.0 ( \" checksum! \" ) is not a valid SHA256 hexdigest nor base64digest " )
2018-11-02 23:07:56 +00:00
end
it " does not raise when disable_checksum_validation is set " do
2019-04-14 06:01:35 +00:00
bundle! " config set disable_checksum_validation true "
2018-11-02 23:07:56 +00:00
install_gemfile! <<-G, :artifice => "compact_index_wrong_gem_checksum"
source " #{ source_uri } "
gem " rack "
G
end
end
it " works when cache dir is world-writable " do
install_gemfile! <<-G, :artifice => "compact_index"
File . umask ( 0000 )
source " #{ source_uri } "
gem " rack "
G
end
it " doesn't explode when the API dependencies are wrong " do
install_gemfile <<-G, :artifice => "compact_index_wrong_dependencies", :env => { "DEBUG" => "true" }
source " #{ source_uri } "
gem " rails "
G
2019-04-14 06:01:35 +00:00
deps = [ Gem :: Dependency . new ( " rake " , " = 12.3.2 " ) ,
2018-11-02 23:07:56 +00:00
Gem :: Dependency . new ( " actionpack " , " = 2.3.2 " ) ,
Gem :: Dependency . new ( " activerecord " , " = 2.3.2 " ) ,
Gem :: Dependency . new ( " actionmailer " , " = 2.3.2 " ) ,
Gem :: Dependency . new ( " activeresource " , " = 2.3.2 " ) ]
expect ( out ) . to include ( <<-E.strip).and include("rails-2.3.2 from rubygems remote at #{source_uri}/ has either corrupted API or lockfile dependencies")
Bundler :: APIResponseMismatchError : Downloading rails - 2 . 3 . 2 revealed dependencies not in the API or the lockfile ( #{deps.map(&:to_s).join(", ")}).
Either installing with ` --full-index ` or running ` bundle update rails ` should fix the problem .
E
end
it " does not duplicate specs in the lockfile when updating and a dependency is not installed " do
install_gemfile! <<-G, :artifice => "compact_index"
source " #{ source_uri } " do
gem " rails "
gem " activemerchant "
end
G
gem_command! :uninstall , " activemerchant "
bundle! " update rails " , :artifice = > " compact_index "
expect ( lockfile . scan ( / activemerchant \ ( / ) . size ) . to eq ( 1 )
end
end