diff options
author | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-08 08:45:41 +0000 |
---|---|---|
committer | hsbt <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-09-08 08:45:41 +0000 |
commit | 8598f8c2dc78c6d1ae87cb6ae19c34ba2cb29241 (patch) | |
tree | 0bbd28f684e745cb212761b7c74fe08668f85cc8 /spec/bundler/realworld | |
parent | f2e04b77aa8a363d7e36ce5a9cdb60714a537a3c (diff) | |
download | ruby-8598f8c2dc78c6d1ae87cb6ae19c34ba2cb29241.tar.gz |
Merge bundler to standard libraries.
rubygems 2.7.x depends bundler-1.15.x. This is preparation for
rubygems and bundler migration.
* lib/bundler.rb, lib/bundler/*: files of bundler-1.15.4
* spec/bundler/*: rspec examples of bundler-1.15.4. I applied patches.
* https://github.com/bundler/bundler/pull/6007
* Exclude not working examples on ruby repository.
* Fake ruby interpriter instead of installed ruby.
* Makefile.in: Added test task named `test-bundler`. This task is only
working macOS/linux yet. I'm going to support Windows environment later.
* tool/sync_default_gems.rb: Added sync task for bundler.
[Feature #12733][ruby-core:77172]
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@59779 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'spec/bundler/realworld')
-rw-r--r-- | spec/bundler/realworld/dependency_api_spec.rb | 49 | ||||
-rw-r--r-- | spec/bundler/realworld/edgecases_spec.rb | 382 | ||||
-rw-r--r-- | spec/bundler/realworld/gemfile_source_header_spec.rb | 53 | ||||
-rw-r--r-- | spec/bundler/realworld/mirror_probe_spec.rb | 143 | ||||
-rw-r--r-- | spec/bundler/realworld/parallel_spec.rb | 81 |
5 files changed, 708 insertions, 0 deletions
diff --git a/spec/bundler/realworld/dependency_api_spec.rb b/spec/bundler/realworld/dependency_api_spec.rb new file mode 100644 index 0000000000..468fa3644c --- /dev/null +++ b/spec/bundler/realworld/dependency_api_spec.rb @@ -0,0 +1,49 @@ +# frozen_string_literal: true +require "spec_helper" + +RSpec.describe "gemcutter's dependency API", :realworld => true do + context "when Gemcutter API takes too long to respond" do + before do + require_rack + + port = find_unused_port + @server_uri = "http://127.0.0.1:#{port}" + + require File.expand_path("../../support/artifice/endpoint_timeout", __FILE__) + require "thread" + @t = Thread.new do + server = Rack::Server.start(:app => EndpointTimeout, + :Host => "0.0.0.0", + :Port => port, + :server => "webrick", + :AccessLog => [], + :Logger => Spec::SilentLogger.new) + server.start + end + @t.run + + wait_for_server("127.0.0.1", port) + end + + after do + Artifice.deactivate + @t.kill + @t.join + end + + it "times out and falls back on the modern index" do + gemfile <<-G + source "#{@server_uri}" + gem "rack" + + old_v, $VERBOSE = $VERBOSE, nil + Bundler::Fetcher.api_timeout = 1 + $VERBOSE = old_v + G + + bundle :install + expect(out).to include("Fetching source index from #{@server_uri}/") + expect(the_bundle).to include_gems "rack 1.0.0" + end + end +end diff --git a/spec/bundler/realworld/edgecases_spec.rb b/spec/bundler/realworld/edgecases_spec.rb new file mode 100644 index 0000000000..302fd57cf0 --- /dev/null +++ b/spec/bundler/realworld/edgecases_spec.rb @@ -0,0 +1,382 @@ +# frozen_string_literal: true +require "spec_helper" + +RSpec.describe "real world edgecases", :realworld => true, :sometimes => true do + def rubygems_version(name, requirement) + require "bundler/source/rubygems/remote" + require "bundler/fetcher" + source = Bundler::Source::Rubygems::Remote.new(URI("https://rubygems.org")) + fetcher = Bundler::Fetcher.new(source) + index = fetcher.specs([name], nil) + rubygem = index.search(Gem::Dependency.new(name, requirement)).last + if rubygem.nil? + raise "Could not find #{name} (#{requirement}) on rubygems.org!\n" \ + "Found specs:\n#{index.send(:specs).inspect}" + end + "#{name} (#{rubygem.version})" + end + + # there is no rbx-relative-require gem that will install on 1.9 + it "ignores extra gems with bad platforms", :ruby => "~> 1.8.7" do + gemfile <<-G + source "https://rubygems.org" + gem "linecache", "0.46" + G + bundle :lock + expect(err).to lack_errors + expect(exitstatus).to eq(0) if exitstatus + end + + # https://github.com/bundler/bundler/issues/1202 + it "bundle cache works with rubygems 1.3.7 and pre gems", + :ruby => "~> 1.8.7", :rubygems => "~> 1.3.7" do + install_gemfile <<-G + source "https://rubygems.org" + gem "rack", "1.3.0.beta2" + gem "will_paginate", "3.0.pre2" + G + bundle :cache + expect(out).not_to include("Removing outdated .gem files from vendor/cache") + end + + # https://github.com/bundler/bundler/issues/1486 + # this is a hash collision that only manifests on 1.8.7 + it "finds the correct child versions", :ruby => "~> 1.8.7" do + gemfile <<-G + source "https://rubygems.org" + + gem 'i18n', '~> 0.6.0' + gem 'activesupport', '~> 3.0.5' + gem 'activerecord', '~> 3.0.5' + gem 'builder', '~> 2.1.2' + G + bundle :lock + expect(lockfile).to include("activemodel (3.0.5)") + end + + it "resolves dependencies correctly", :ruby => "1.9.3" do + gemfile <<-G + source "https://rubygems.org" + + gem 'rails', '~> 3.0' + gem 'capybara', '~> 2.2.0' + gem 'rack-cache', '1.2.0' # last version that works on Ruby 1.9 + G + bundle! :lock + expect(lockfile).to include(rubygems_version("rails", "~> 3.0")) + expect(lockfile).to include("capybara (2.2.1)") + end + + it "installs the latest version of gxapi_rails", :ruby => "1.9.3" do + gemfile <<-G + source "https://rubygems.org" + + gem "sass-rails" + gem "rails", "~> 3" + gem "gxapi_rails", "< 0.1.0" # 0.1.0 was released way after the test was written + gem 'rack-cache', '1.2.0' # last version that works on Ruby 1.9 + G + bundle :lock + expect(lockfile).to include("gxapi_rails (0.0.6)") + end + + it "installs the latest version of i18n" do + gemfile <<-G + source "https://rubygems.org" + + gem "i18n", "~> 0.6.0" + gem "activesupport", "~> 3.0" + gem "activerecord", "~> 3.0" + gem "builder", "~> 2.1.2" + G + bundle :lock + expect(lockfile).to include(rubygems_version("i18n", "~> 0.6.0")) + expect(lockfile).to include(rubygems_version("activesupport", "~> 3.0")) + end + + it "is able to update a top-level dependency when there is a conflict on a shared transitive child", :ruby => "2.1" do + # from https://github.com/bundler/bundler/issues/5031 + + gemfile <<-G + source "https://rubygems.org" + gem 'rails', '~> 4.2.7.1' + gem 'paperclip', '~> 5.1.0' + G + + lockfile <<-L + GEM + remote: https://rubygems.org/ + specs: + actionmailer (4.2.7.1) + actionpack (= 4.2.7.1) + actionview (= 4.2.7.1) + activejob (= 4.2.7.1) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 1.0, >= 1.0.5) + actionpack (4.2.7.1) + actionview (= 4.2.7.1) + activesupport (= 4.2.7.1) + rack (~> 1.6) + rack-test (~> 0.6.2) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (4.2.7.1) + activesupport (= 4.2.7.1) + builder (~> 3.1) + erubis (~> 2.7.0) + rails-dom-testing (~> 1.0, >= 1.0.5) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + activejob (4.2.7.1) + activesupport (= 4.2.7.1) + globalid (>= 0.3.0) + activemodel (4.2.7.1) + activesupport (= 4.2.7.1) + builder (~> 3.1) + activerecord (4.2.7.1) + activemodel (= 4.2.7.1) + activesupport (= 4.2.7.1) + arel (~> 6.0) + activesupport (4.2.7.1) + i18n (~> 0.7) + json (~> 1.7, >= 1.7.7) + minitest (~> 5.1) + thread_safe (~> 0.3, >= 0.3.4) + tzinfo (~> 1.1) + arel (6.0.3) + builder (3.2.2) + climate_control (0.0.3) + activesupport (>= 3.0) + cocaine (0.5.8) + climate_control (>= 0.0.3, < 1.0) + concurrent-ruby (1.0.2) + erubis (2.7.0) + globalid (0.3.7) + activesupport (>= 4.1.0) + i18n (0.7.0) + json (1.8.3) + loofah (2.0.3) + nokogiri (>= 1.5.9) + mail (2.6.4) + mime-types (>= 1.16, < 4) + mime-types (3.1) + mime-types-data (~> 3.2015) + mime-types-data (3.2016.0521) + mimemagic (0.3.2) + mini_portile2 (2.1.0) + minitest (5.9.1) + nokogiri (1.6.8) + mini_portile2 (~> 2.1.0) + pkg-config (~> 1.1.7) + paperclip (5.1.0) + activemodel (>= 4.2.0) + activesupport (>= 4.2.0) + cocaine (~> 0.5.5) + mime-types + mimemagic (~> 0.3.0) + pkg-config (1.1.7) + rack (1.6.4) + rack-test (0.6.3) + rack (>= 1.0) + rails (4.2.7.1) + actionmailer (= 4.2.7.1) + actionpack (= 4.2.7.1) + actionview (= 4.2.7.1) + activejob (= 4.2.7.1) + activemodel (= 4.2.7.1) + activerecord (= 4.2.7.1) + activesupport (= 4.2.7.1) + bundler (>= 1.3.0, < 2.0) + railties (= 4.2.7.1) + sprockets-rails + rails-deprecated_sanitizer (1.0.3) + activesupport (>= 4.2.0.alpha) + rails-dom-testing (1.0.7) + activesupport (>= 4.2.0.beta, < 5.0) + nokogiri (~> 1.6.0) + rails-deprecated_sanitizer (>= 1.0.1) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + railties (4.2.7.1) + actionpack (= 4.2.7.1) + activesupport (= 4.2.7.1) + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (11.3.0) + sprockets (3.7.0) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.0) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.19.1) + thread_safe (0.3.5) + tzinfo (1.2.2) + thread_safe (~> 0.1) + + PLATFORMS + ruby + + DEPENDENCIES + paperclip (~> 5.1.0) + rails (~> 4.2.7.1) + + BUNDLED WITH + 1.13.1 + L + + bundle! "lock --update paperclip" + + expect(lockfile).to include(rubygems_version("paperclip", "~> 5.1.0")) + end + + # https://github.com/bundler/bundler/issues/1500 + it "does not fail install because of gem plugins" do + realworld_system_gems("open_gem --version 1.4.2", "rake --version 0.9.2") + gemfile <<-G + source "https://rubygems.org" + + gem 'rack', '1.0.1' + G + + bundle "install --path vendor/bundle" + expect(err).not_to include("Could not find rake") + expect(err).to lack_errors + end + + it "checks out git repos when the lockfile is corrupted" do + gemfile <<-G + source "https://rubygems.org" + + gem 'activerecord', :github => 'carlhuda/rails-bundler-test', :branch => 'master' + gem 'activesupport', :github => 'carlhuda/rails-bundler-test', :branch => 'master' + gem 'actionpack', :github => 'carlhuda/rails-bundler-test', :branch => 'master' + G + + lockfile <<-L + GIT + remote: git://github.com/carlhuda/rails-bundler-test.git + revision: 369e28a87419565f1940815219ea9200474589d4 + branch: master + specs: + actionpack (3.2.2) + activemodel (= 3.2.2) + activesupport (= 3.2.2) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.1) + rack (~> 1.4.0) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.1.2) + activemodel (3.2.2) + activesupport (= 3.2.2) + builder (~> 3.0.0) + activerecord (3.2.2) + activemodel (= 3.2.2) + activesupport (= 3.2.2) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activesupport (3.2.2) + i18n (~> 0.6) + multi_json (~> 1.0) + + GIT + remote: git://github.com/carlhuda/rails-bundler-test.git + revision: 369e28a87419565f1940815219ea9200474589d4 + branch: master + specs: + actionpack (3.2.2) + activemodel (= 3.2.2) + activesupport (= 3.2.2) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.1) + rack (~> 1.4.0) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.1.2) + activemodel (3.2.2) + activesupport (= 3.2.2) + builder (~> 3.0.0) + activerecord (3.2.2) + activemodel (= 3.2.2) + activesupport (= 3.2.2) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activesupport (3.2.2) + i18n (~> 0.6) + multi_json (~> 1.0) + + GIT + remote: git://github.com/carlhuda/rails-bundler-test.git + revision: 369e28a87419565f1940815219ea9200474589d4 + branch: master + specs: + actionpack (3.2.2) + activemodel (= 3.2.2) + activesupport (= 3.2.2) + builder (~> 3.0.0) + erubis (~> 2.7.0) + journey (~> 1.0.1) + rack (~> 1.4.0) + rack-cache (~> 1.2) + rack-test (~> 0.6.1) + sprockets (~> 2.1.2) + activemodel (3.2.2) + activesupport (= 3.2.2) + builder (~> 3.0.0) + activerecord (3.2.2) + activemodel (= 3.2.2) + activesupport (= 3.2.2) + arel (~> 3.0.2) + tzinfo (~> 0.3.29) + activesupport (3.2.2) + i18n (~> 0.6) + multi_json (~> 1.0) + + GEM + remote: https://rubygems.org/ + specs: + arel (3.0.2) + builder (3.0.0) + erubis (2.7.0) + hike (1.2.1) + i18n (0.6.0) + journey (1.0.3) + multi_json (1.1.0) + rack (1.4.1) + rack-cache (1.2) + rack (>= 0.4) + rack-test (0.6.1) + rack (>= 1.0) + sprockets (2.1.2) + hike (~> 1.2) + rack (~> 1.0) + tilt (~> 1.1, != 1.3.0) + tilt (1.3.3) + tzinfo (0.3.32) + + PLATFORMS + ruby + + DEPENDENCIES + actionpack! + activerecord! + activesupport! + L + + bundle :lock + expect(err).to eq("") + expect(exitstatus).to eq(0) if exitstatus + end + + it "outputs a helpful error message when gems have invalid gemspecs" do + install_gemfile <<-G, :standalone => true + source 'https://rubygems.org' + gem "resque-scheduler", "2.2.0" + G + expect(out).to include("You have one or more invalid gemspecs that need to be fixed.") + expect(out).to include("resque-scheduler 2.2.0 has an invalid gemspec") + end +end diff --git a/spec/bundler/realworld/gemfile_source_header_spec.rb b/spec/bundler/realworld/gemfile_source_header_spec.rb new file mode 100644 index 0000000000..ba888d43bd --- /dev/null +++ b/spec/bundler/realworld/gemfile_source_header_spec.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true +require "spec_helper" +require "thread" + +RSpec.describe "fetching dependencies with a mirrored source", :realworld => true, :rubygems => ">= 2.0" do + let(:mirror) { "https://server.example.org" } + let(:original) { "http://127.0.0.1:#{@port}" } + + before do + setup_server + bundle "config --local mirror.#{mirror} #{original}" + end + + after do + Artifice.deactivate + @t.kill + @t.join + end + + it "sets the 'X-Gemfile-Source' header and bundles successfully" do + gemfile <<-G + source "#{mirror}" + gem 'weakling' + G + + bundle :install + + expect(out).to include("Installing weakling") + expect(out).to include("Bundle complete") + expect(the_bundle).to include_gems "weakling 0.0.3" + end + + private + + def setup_server + require_rack + @port = find_unused_port + @server_uri = "http://127.0.0.1:#{@port}" + + require File.expand_path("../../support/artifice/endpoint_mirror_source", __FILE__) + + @t = Thread.new do + Rack::Server.start(:app => EndpointMirrorSource, + :Host => "0.0.0.0", + :Port => @port, + :server => "webrick", + :AccessLog => [], + :Logger => Spec::SilentLogger.new) + end.run + + wait_for_server("127.0.0.1", @port) + end +end diff --git a/spec/bundler/realworld/mirror_probe_spec.rb b/spec/bundler/realworld/mirror_probe_spec.rb new file mode 100644 index 0000000000..93dca0c173 --- /dev/null +++ b/spec/bundler/realworld/mirror_probe_spec.rb @@ -0,0 +1,143 @@ +# frozen_string_literal: true +require "spec_helper" +require "thread" + +RSpec.describe "fetching dependencies with a not available mirror", :realworld => true do + let(:mirror) { @mirror_uri } + let(:original) { @server_uri } + let(:server_port) { @server_port } + let(:host) { "127.0.0.1" } + + before do + require_rack + setup_server + setup_mirror + end + + after do + Artifice.deactivate + @server_thread.kill + @server_thread.join + end + + context "with a specific fallback timeout" do + before do + global_config("BUNDLE_MIRROR__HTTP://127__0__0__1:#{server_port}/__FALLBACK_TIMEOUT/" => "true", + "BUNDLE_MIRROR__HTTP://127__0__0__1:#{server_port}/" => mirror) + end + + it "install a gem using the original uri when the mirror is not responding" do + gemfile <<-G + source "#{original}" + gem 'weakling' + G + + bundle :install + + expect(out).to include("Installing weakling") + expect(out).to include("Bundle complete") + expect(the_bundle).to include_gems "weakling 0.0.3" + end + end + + context "with a global fallback timeout" do + before do + global_config("BUNDLE_MIRROR__ALL__FALLBACK_TIMEOUT/" => "1", + "BUNDLE_MIRROR__ALL" => mirror) + end + + it "install a gem using the original uri when the mirror is not responding" do + gemfile <<-G + source "#{original}" + gem 'weakling' + G + + bundle :install + + expect(out).to include("Installing weakling") + expect(out).to include("Bundle complete") + expect(the_bundle).to include_gems "weakling 0.0.3" + end + end + + context "with a specific mirror without a fallback timeout" do + before do + global_config("BUNDLE_MIRROR__HTTP://127__0__0__1:#{server_port}/" => mirror) + end + + it "fails to install the gem with a timeout error" do + gemfile <<-G + source "#{original}" + gem 'weakling' + G + + bundle :install + + expect(out).to include("Fetching source index from #{mirror}") + expect(out).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}") + expect(out).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}") + expect(out).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}") + expect(out).to include("Could not fetch specs from #{mirror}") + end + + it "prints each error and warning on a new line" do + gemfile <<-G + source "#{original}" + gem 'weakling' + G + + bundle :install + + expect(out).to eq "Fetching source index from #{mirror}/ + +Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ +Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ +Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}/ +Could not fetch specs from #{mirror}/" + end + end + + context "with a global mirror without a fallback timeout" do + before do + global_config("BUNDLE_MIRROR__ALL" => mirror) + end + + it "fails to install the gem with a timeout error" do + gemfile <<-G + source "#{original}" + gem 'weakling' + G + + bundle :install + + expect(out).to include("Fetching source index from #{mirror}") + expect(out).to include("Retrying fetcher due to error (2/4): Bundler::HTTPError Could not fetch specs from #{mirror}") + expect(out).to include("Retrying fetcher due to error (3/4): Bundler::HTTPError Could not fetch specs from #{mirror}") + expect(out).to include("Retrying fetcher due to error (4/4): Bundler::HTTPError Could not fetch specs from #{mirror}") + expect(out).to include("Could not fetch specs from #{mirror}") + end + end + + def setup_server + @server_port = find_unused_port + @server_uri = "http://#{host}:#{@server_port}" + + require File.expand_path("../../support/artifice/endpoint", __FILE__) + + @server_thread = Thread.new do + Rack::Server.start(:app => Endpoint, + :Host => host, + :Port => @server_port, + :server => "webrick", + :AccessLog => [], + :Logger => Spec::SilentLogger.new) + end.run + + wait_for_server(host, @server_port) + end + + def setup_mirror + mirror_port = find_unused_port + @mirror_uri = "http://#{host}:#{mirror_port}" + end +end diff --git a/spec/bundler/realworld/parallel_spec.rb b/spec/bundler/realworld/parallel_spec.rb new file mode 100644 index 0000000000..6950bead19 --- /dev/null +++ b/spec/bundler/realworld/parallel_spec.rb @@ -0,0 +1,81 @@ +# frozen_string_literal: true +require "spec_helper" + +RSpec.describe "parallel", :realworld => true, :sometimes => true do + it "installs" do + gemfile <<-G + source "https://rubygems.org" + gem 'activesupport', '~> 3.2.13' + gem 'faker', '~> 1.1.2' + gem 'i18n', '~> 0.6.0' # Because 0.7+ requires Ruby 1.9.3+ + G + + bundle :install, :jobs => 4, :env => { "DEBUG" => "1" } + + if Bundler.rubygems.provides?(">= 2.1.0") + expect(out).to match(/[1-3]: /) + else + expect(out).to include("is not threadsafe") + end + + bundle "show activesupport" + expect(out).to match(/activesupport/) + + bundle "show faker" + expect(out).to match(/faker/) + + bundle "config jobs" + expect(out).to match(/: "4"/) + end + + it "updates" do + install_gemfile <<-G + source "https://rubygems.org" + gem 'activesupport', '3.2.12' + gem 'faker', '~> 1.1.2' + G + + gemfile <<-G + source "https://rubygems.org" + gem 'activesupport', '~> 3.2.12' + gem 'faker', '~> 1.1.2' + gem 'i18n', '~> 0.6.0' # Because 0.7+ requires Ruby 1.9.3+ + G + + bundle :update, :jobs => 4, :env => { "DEBUG" => "1" } + + if Bundler.rubygems.provides?(">= 2.1.0") + expect(out).to match(/[1-3]: /) + else + expect(out).to include("is not threadsafe") + end + + bundle "show activesupport" + expect(out).to match(/activesupport-3\.2\.\d+/) + + bundle "show faker" + expect(out).to match(/faker/) + + bundle "config jobs" + expect(out).to match(/: "4"/) + end + + it "works with --standalone" do + gemfile <<-G, :standalone => true + source "https://rubygems.org" + gem "diff-lcs" + G + + bundle :install, :standalone => true, :jobs => 4 + + ruby <<-RUBY, :no_lib => true + $:.unshift File.expand_path("bundle") + require "bundler/setup" + + require "diff/lcs" + puts Diff::LCS + RUBY + + expect(out).to eq("Diff::LCS") + end +end |