aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog24
-rw-r--r--lib/rubygems/commands/sources_command.rb13
-rw-r--r--lib/rubygems/defaults.rb2
-rw-r--r--lib/rubygems/dependency_resolver.rb19
-rw-r--r--lib/rubygems/ext/builder.rb7
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb28
-rw-r--r--lib/rubygems/installer.rb6
-rw-r--r--lib/rubygems/source.rb10
-rw-r--r--lib/rubygems/spec_fetcher.rb28
-rw-r--r--lib/rubygems/specification.rb2
-rw-r--r--lib/rubygems/test_utilities.rb2
-rw-r--r--test/rubygems/test_gem.rb2
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb39
-rw-r--r--test/rubygems/test_gem_dependency_resolver_api_set.rb80
-rw-r--r--test/rubygems/test_gem_ext_ext_conf_builder.rb12
-rw-r--r--test/rubygems/test_gem_installer.rb5
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb3
-rw-r--r--test/rubygems/test_gem_source.rb11
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb47
19 files changed, 299 insertions, 41 deletions
diff --git a/ChangeLog b/ChangeLog
index 650cd9832c..2370432bc1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+Fri Mar 1 07:21:41 2013 Eric Hodel <drbrain@segment7.net>
+
+ * lib/rubygems/ext/builder.rb: Fix incompatibilities when installing
+ extensions. Patch by Nobu.
+ [ruby-trunk - Bug #7968] [ruby-trunk - Bug #7971]
+ * lib/rubygems/ext/ext_conf_builder.rb: ditto.
+ * lib/rubygems/installer.rb: ditto.
+ * test/rubygems/test_gem_ext_ext_conf_builder.rb: Test for the above.
+ * test/rubygems/test_gem_installer.rb: ditto.
+
+ * lib/rubygems/commands/sources_command.rb: Prefer HTTPS over HTTP.
+ * lib/rubygems/defaults.rb: ditto
+ * lib/rubygems/dependency_resolver.rb: Ditto.
+ * lib/rubygems/source.rb: ditto.
+ * lib/rubygems/spec_fetcher.rb: ditto.
+ * lib/rubygems/specification.rb: ditto.
+ * lib/rubygems/test_utilities.rb: ditto.
+ * test/rubygems/test_gem.rb: Test for the above.
+ * test/rubygems/test_gem_commands_sources_command.rb: ditto.
+ * test/rubygems/test_gem_dependency_resolver_api_set.rb: ditto.
+ * test/rubygems/test_gem_remote_fetcher.rb: ditto.
+ * test/rubygems/test_gem_source.rb: ditto.
+ * test/rubygems/test_gem_spec_fetcher.rb: ditto.
+
Fri Mar 1 03:25:00 2013 Zachary Scott <zachary@zacharyscott.net>
* ext/psych/lib/psych.rb: rdoc for Psych overview by Adam Stankiewicz
diff --git a/lib/rubygems/commands/sources_command.rb b/lib/rubygems/commands/sources_command.rb
index 97ed7329ea..f4cc3e57ae 100644
--- a/lib/rubygems/commands/sources_command.rb
+++ b/lib/rubygems/commands/sources_command.rb
@@ -65,6 +65,19 @@ class Gem::Commands::SourcesCommand < Gem::Command
end
if source_uri = options[:add] then
+ uri = URI source_uri
+
+ if uri.scheme and uri.scheme.downcase == 'http' and
+ uri.host.downcase == 'rubygems.org' then
+ question = <<-QUESTION.chomp
+https://rubygems.org is recommended for security over #{uri}
+
+Do you want to add this insecure source?
+ QUESTION
+
+ terminate_interaction 1 unless ask_yes_no question
+ end
+
source = Gem::Source.new source_uri
begin
diff --git a/lib/rubygems/defaults.rb b/lib/rubygems/defaults.rb
index ea84e5c018..6854e9b760 100644
--- a/lib/rubygems/defaults.rb
+++ b/lib/rubygems/defaults.rb
@@ -11,7 +11,7 @@ module Gem
# An Array of the default sources that come with RubyGems
def self.default_sources
- %w[http://rubygems.org/]
+ %w[https://rubygems.org/]
end
##
diff --git a/lib/rubygems/dependency_resolver.rb b/lib/rubygems/dependency_resolver.rb
index b841674d43..2c651aff2e 100644
--- a/lib/rubygems/dependency_resolver.rb
+++ b/lib/rubygems/dependency_resolver.rb
@@ -69,6 +69,8 @@ module Gem
# and dependencies.
#
class APISpecification
+ attr_reader :set # :nodoc:
+
def initialize(set, api_data)
@set = set
@name = api_data[:name]
@@ -80,6 +82,14 @@ module Gem
attr_reader :name, :version, :dependencies
+ def == other # :nodoc:
+ self.class === other and
+ @set == other.set and
+ @name == other.name and
+ @version == other.version and
+ @dependencies == other.dependencies
+ end
+
def full_name
"#{@name}-#{@version}"
end
@@ -91,6 +101,7 @@ module Gem
class APISet
def initialize
@data = Hash.new { |h,k| h[k] = [] }
+ @dep_uri = URI 'https://rubygems.org/api/v1/dependencies'
end
# Return data for all versions of the gem +name+.
@@ -100,8 +111,8 @@ module Gem
return @data[name]
end
- u = URI.parse "http://rubygems.org/api/v1/dependencies?gems=#{name}"
- str = Net::HTTP.get(u)
+ uri = @dep_uri + "?gems=#{name}"
+ str = Gem::RemoteFetcher.fetcher.fetch_path uri
Marshal.load(str).each do |ver|
@data[ver[:name]] << ver
@@ -134,8 +145,8 @@ module Gem
return if needed.empty?
- u = URI.parse "http://rubygems.org/api/v1/dependencies?gems=#{needed.join ','}"
- str = Net::HTTP.get(u)
+ uri = @dep_uri + "?gems=#{needed.sort.join ','}"
+ str = Gem::RemoteFetcher.fetcher.fetch_path uri
Marshal.load(str).each do |ver|
@data[ver[:name]] << ver
diff --git a/lib/rubygems/ext/builder.rb b/lib/rubygems/ext/builder.rb
index d7d953fec3..9b6ad304a2 100644
--- a/lib/rubygems/ext/builder.rb
+++ b/lib/rubygems/ext/builder.rb
@@ -16,13 +16,6 @@ class Gem::Ext::Builder
raise Gem::InstallError, "Makefile not found:\n\n#{results.join "\n"}"
end
- mf = Gem.read_binary 'Makefile'
- mf = mf.gsub(/^RUBYARCHDIR\s*=\s*\$[^$]*/, "RUBYARCHDIR = #{dest_path}")
- mf = mf.gsub(/^RUBYLIBDIR\s*=\s*\$[^$]*/, "RUBYLIBDIR = #{dest_path}")
- mf = mf.gsub(/\s*\S+\.time$/, "")
-
- File.open('Makefile', 'wb') {|f| f.print mf}
-
# try to find make program from Ruby configure arguments first
RbConfig::CONFIG['configure_args'] =~ /with-make-prog\=(\w+)/
make_program = $1 || ENV['MAKE'] || ENV['make']
diff --git a/lib/rubygems/ext/ext_conf_builder.rb b/lib/rubygems/ext/ext_conf_builder.rb
index 7ca322d3e5..3a439af502 100644
--- a/lib/rubygems/ext/ext_conf_builder.rb
+++ b/lib/rubygems/ext/ext_conf_builder.rb
@@ -6,16 +6,36 @@
require 'rubygems/ext/builder'
require 'rubygems/command'
+require 'fileutils'
+require 'tmpdir'
class Gem::Ext::ExtConfBuilder < Gem::Ext::Builder
def self.build(extension, directory, dest_path, results, args=[])
- cmd = "#{Gem.ruby} #{File.basename extension}"
+ pwd = Dir.pwd
+ cmd = "#{Gem.ruby} -r./siteconf #{File.join pwd, File.basename(extension)}"
cmd << " #{args.join ' '}" unless args.empty?
- run cmd, results
-
- make dest_path, results
+ Dir.mktmpdir("gem-install.") do |tmpdir|
+ Dir.chdir(tmpdir) do
+ open("siteconf.rb", "w") do |f|
+ f.puts "require 'rbconfig'"
+ f.puts "dest_path = #{dest_path.dump}"
+ %w[sitearchdir sitelibdir].each do |dir|
+ f.puts "RbConfig::MAKEFILE_CONFIG['#{dir}'] = dest_path"
+ f.puts "RbConfig::CONFIG['#{dir}'] = dest_path"
+ end
+ end
+
+ begin
+ run cmd, results
+
+ make dest_path, results
+ ensure
+ FileUtils.mv("mkmf.log", pwd) if $! and File.exist?("mkmf.log")
+ end
+ end
+ end
results
end
diff --git a/lib/rubygems/installer.rb b/lib/rubygems/installer.rb
index 3f4c6943df..4a41891b48 100644
--- a/lib/rubygems/installer.rb
+++ b/lib/rubygems/installer.rb
@@ -681,7 +681,7 @@ TEXT
say results.join("\n") if Gem.configuration.really_verbose
end
rescue
- extension_build_error(extension_dir, results.join("\n"))
+ extension_build_error(extension_dir, results.join("\n"), $@)
end
end
end
@@ -689,7 +689,7 @@ TEXT
##
# Logs the build +output+ in +build_dir+, then raises ExtensionBuildError.
- def extension_build_error(build_dir, output)
+ def extension_build_error(build_dir, output, backtrace = nil)
gem_make_out = File.join build_dir, 'gem_make.out'
open gem_make_out, 'wb' do |io| io.puts output end
@@ -703,7 +703,7 @@ Gem files will remain installed in #{gem_dir} for inspection.
Results logged to #{gem_make_out}
EOF
- raise ExtensionBuildError, message
+ raise ExtensionBuildError, message, backtrace
end
##
diff --git a/lib/rubygems/source.rb b/lib/rubygems/source.rb
index 96d57870e2..8f39cb1464 100644
--- a/lib/rubygems/source.rb
+++ b/lib/rubygems/source.rb
@@ -141,4 +141,14 @@ class Gem::Source
fetcher = Gem::RemoteFetcher.fetcher
fetcher.download spec, @uri.to_s, dir
end
+
+ ##
+ # Replaces the URI for this source with +uri+. Used for upgrading this
+ # source to HTTPS
+
+ def uri= uri # :nodoc:
+ @api_uri = nil
+ @uri = uri
+ end
+
end
diff --git a/lib/rubygems/spec_fetcher.rb b/lib/rubygems/spec_fetcher.rb
index 3345f6537e..aeed37ba5e 100644
--- a/lib/rubygems/spec_fetcher.rb
+++ b/lib/rubygems/spec_fetcher.rb
@@ -188,6 +188,8 @@ class Gem::SpecFetcher
list = {}
Gem.sources.each_source do |source|
+ source = upgrade_http_source source
+
begin
names = case type
when :latest
@@ -225,5 +227,31 @@ class Gem::SpecFetcher
cache[source.uri] ||= source.load_specs(type)
end
end
+
+ def upgrade_http_source source
+ uri = source.uri
+
+ return source unless uri.scheme.downcase == 'http'
+
+ https_uri = uri.dup
+ https_uri.scheme = 'https'
+ https_uri += '/'
+
+ Gem::RemoteFetcher.fetcher.fetch_path https_uri, nil, true
+
+ say "Upgraded #{uri} to HTTPS"
+
+ https_uri += uri.request_uri
+
+ source.uri = URI https_uri.to_s # cast to URI::HTTPS
+
+ source
+ rescue Gem::RemoteFetcher::FetchError
+ say "Upgrading #{uri} to HTTPS failed, continuing" if
+ Gem.configuration.really_verbose
+
+ source
+ end
+
end
diff --git a/lib/rubygems/specification.rb b/lib/rubygems/specification.rb
index cabdf8df7f..a94e64b36d 100644
--- a/lib/rubygems/specification.rb
+++ b/lib/rubygems/specification.rb
@@ -17,7 +17,7 @@
# s.authors = ["Ruby Coder"]
# s.email = 'rubycoder@example.com'
# s.files = ["lib/example.rb"]
-# s.homepage = 'http://rubygems.org/gems/example'
+# s.homepage = 'https://rubygems.org/gems/example'
# end
#
# Starting in RubyGems 1.9.0, a Specification can hold arbitrary
diff --git a/lib/rubygems/test_utilities.rb b/lib/rubygems/test_utilities.rb
index dc0d93e6c2..3da0b4ebc2 100644
--- a/lib/rubygems/test_utilities.rb
+++ b/lib/rubygems/test_utilities.rb
@@ -49,7 +49,7 @@ class Gem::FakeFetcher
@data[path]
end
- def fetch_path path, mtime = nil
+ def fetch_path path, mtime = nil, head = false
data = find_data(path)
if data.respond_to?(:call) then
diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb
index bf77009ca6..9be77e1375 100644
--- a/test/rubygems/test_gem.rb
+++ b/test/rubygems/test_gem.rb
@@ -665,7 +665,7 @@ class TestGem < Gem::TestCase
end
def test_self_default_sources
- assert_equal %w[http://rubygems.org/], Gem.default_sources
+ assert_equal %w[https://rubygems.org/], Gem.default_sources
end
def test_self_detect_gemdeps
diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb
index 6bae460c84..8dc2f91ed4 100644
--- a/test/rubygems/test_gem_commands_sources_command.rb
+++ b/test/rubygems/test_gem_commands_sources_command.rb
@@ -118,6 +118,45 @@ source #{@gem_repo} already present in the cache
assert_equal '', @ui.error
end
+ def test_execute_add_http_rubygems_org
+ http_rubygems_org = 'http://rubygems.org'
+ util_setup_fake_fetcher
+
+ install_specs @a1
+
+ specs = Gem::Specification.map { |spec|
+ [spec.name, spec.version, spec.original_platform]
+ }
+
+ specs_dump_gz = StringIO.new
+ Zlib::GzipWriter.wrap specs_dump_gz do |io|
+ Marshal.dump specs, io
+ end
+
+ @fetcher.data["#{http_rubygems_org}/specs.#{@marshal_version}.gz"] =
+ specs_dump_gz.string
+
+ @cmd.handle_options %W[--add #{http_rubygems_org}]
+
+ util_setup_spec_fetcher
+
+ ui = Gem::MockGemUi.new "n"
+
+ use_ui ui do
+ assert_raises Gem::MockGemUi::TermError do
+ @cmd.execute
+ end
+ end
+
+ assert_equal [@gem_repo], Gem.sources
+
+ expected = <<-EXPECTED
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ assert_empty @ui.error
+ end
+
def test_execute_add_bad_uri
@cmd.handle_options %w[--add beta-gems.example.com]
diff --git a/test/rubygems/test_gem_dependency_resolver_api_set.rb b/test/rubygems/test_gem_dependency_resolver_api_set.rb
new file mode 100644
index 0000000000..c1e7eda191
--- /dev/null
+++ b/test/rubygems/test_gem_dependency_resolver_api_set.rb
@@ -0,0 +1,80 @@
+require 'rubygems/test_case'
+require 'rubygems/dependency_resolver'
+
+class TestGemDependencyResolverAPISet < Gem::TestCase
+
+ def setup
+ super
+
+ @DR = Gem::DependencyResolver
+
+ @api_set = @DR::APISet.new
+ @uri = 'https://rubygems.org/api/v1/dependencies'
+ @fetcher = Gem::FakeFetcher.new
+ Gem::RemoteFetcher.fetcher = @fetcher
+ end
+
+ def test_find_all
+ b_entry = {
+ :name => 'b',
+ :number => '2',
+ :platform => 'ruby',
+ :dependencies => [['a', '>= 0']],
+ }
+
+ @fetcher.data["#{@uri}?gems=b"] = Marshal.dump [b_entry]
+
+ b_req = @DR::DependencyRequest.new dep('b', '>= 0'), nil
+
+ expected = [
+ @DR::APISpecification.new(@api_set, b_entry)
+ ]
+
+ assert_equal expected, @api_set.find_all(b_req)
+ end
+
+ def test_prefetch
+ b_entry = {
+ :name => 'b',
+ :number => '2',
+ :platform => 'ruby',
+ :dependencies => [['a', '>= 0']],
+ }
+
+ a_entry = {
+ :name => 'a',
+ :number => '2',
+ :platform => 'ruby',
+ :dependencies => [],
+ }
+
+ @fetcher.data["#{@uri}?gems=a,b"] = Marshal.dump [a_entry, b_entry]
+
+ a_req = @DR::DependencyRequest.new dep('a', '>= 0'), nil
+ b_req = @DR::DependencyRequest.new dep('b', '>= 0'), nil
+
+ @api_set.prefetch([b_req, a_req])
+
+ assert_equal [a_entry], @api_set.versions('a')
+ assert_equal [b_entry], @api_set.versions('b')
+ end
+
+ def test_versions_cache
+ entry = {
+ :name => 'b',
+ :number => '2',
+ :platform => 'ruby',
+ :dependencies => [['a', '>= 0']],
+ }
+
+ @fetcher.data["#{@uri}?gems=b"] = Marshal.dump [entry]
+
+ assert_equal [entry], @api_set.versions('b')
+
+ @fetcher.data["#{@uri}?gems=b"] = 'garbage'
+
+ assert_equal [entry], @api_set.versions('b'), 'version data must be cached'
+ end
+
+end
+
diff --git a/test/rubygems/test_gem_ext_ext_conf_builder.rb b/test/rubygems/test_gem_ext_ext_conf_builder.rb
index 4a492c1235..c899592442 100644
--- a/test/rubygems/test_gem_ext_ext_conf_builder.rb
+++ b/test/rubygems/test_gem_ext_ext_conf_builder.rb
@@ -30,7 +30,7 @@ class TestGemExtExtConfBuilder < Gem::TestCase
Gem::Ext::ExtConfBuilder.build 'extconf.rb', nil, @dest_path, output
end
- assert_match(/^#{Gem.ruby} extconf.rb/, output[0])
+ assert_match(/^#{Gem.ruby} .*extconf.rb/, output[0])
assert_equal "creating Makefile\n", output[1]
case RUBY_PLATFORM
when /mswin/ then
@@ -107,10 +107,10 @@ class TestGemExtExtConfBuilder < Gem::TestCase
assert_match(/\Aextconf failed:
-#{Gem.ruby} extconf.rb.*
+#{Gem.ruby} .*extconf.rb.*
checking for main\(\) in .*?nonexistent/m, error.message)
- assert_match(/^#{Gem.ruby} extconf.rb/, output[0])
+ assert_match(/^#{Gem.ruby} .*extconf.rb/, output[0])
end
def test_class_make
@@ -134,12 +134,6 @@ checking for main\(\) in .*?nonexistent/m, error.message)
assert_equal make_command, output[0]
assert_equal "#{make_command} install", output[2]
-
- edited_makefile = Gem.read_binary makefile_path
- edited_makefile.gsub!(/\r/, '') if Gem.win_platform?
-
- assert_match "\nRUBYARCHDIR = #{@ext}$(target_prefix)\n", edited_makefile
- assert_match "\nRUBYLIBDIR = #{@ext}$(target_prefix)\n", edited_makefile
end
def test_class_make_no_Makefile
diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb
index ddedd8144c..a4e6caf7df 100644
--- a/test/rubygems/test_gem_installer.rb
+++ b/test/rubygems/test_gem_installer.rb
@@ -81,7 +81,7 @@ load Gem.bin_path('a', 'executable', version)
gem_make_out = File.join @gemhome, 'gems', @spec.full_name, 'gem_make.out'
- assert_match %r%#{Regexp.escape Gem.ruby} extconf\.rb%,
+ assert_match %r%#{Regexp.escape Gem.ruby} .*extconf\.rb%,
File.read(gem_make_out)
assert_match %r%#{Regexp.escape Gem.ruby}: No such file%,
File.read(gem_make_out)
@@ -119,7 +119,8 @@ load Gem.bin_path('a', 'executable', version)
File.open File.join(@spec.gem_dir, "extconf.rb"), "w" do |f|
f.write <<-'RUBY'
puts "IN EXTCONF"
- File.open 'extconf_args', 'w' do |f|
+ extconf_args = File.join File.dirname(__FILE__), 'extconf_args'
+ File.open extconf_args, 'w' do |f|
f.puts ARGV.inspect
end
diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb
index d3cc388db4..c178edc0d9 100644
--- a/test/rubygems/test_gem_remote_fetcher.rb
+++ b/test/rubygems/test_gem_remote_fetcher.rb
@@ -399,6 +399,9 @@ gems:
@fetcher.instance_variable_set :@a1, @a1
@fetcher.instance_variable_set :@a2, @a2
def @fetcher.fetch_path uri, mtime = nil, head = false
+ raise Gem::RemoteFetcher::FetchError.new 'no http upgrade', uri if
+ uri.scheme != 'http'
+
case uri.request_uri
when /#{@a1.spec_name}/ then
Gem.deflate Marshal.dump @a1
diff --git a/test/rubygems/test_gem_source.rb b/test/rubygems/test_gem_source.rb
index 2629f180a9..3de9073f96 100644
--- a/test/rubygems/test_gem_source.rb
+++ b/test/rubygems/test_gem_source.rb
@@ -184,5 +184,16 @@ class TestGemSource < Gem::TestCase
end
end
+ def test_uri_equals
+ @source.api_uri # cached
+
+ refute_equal URI('https://secure.example'), @source.api_uri
+
+ @source.uri = URI 'https://secure.example'
+
+ assert_equal URI('https://secure.example'), @source.uri
+ assert_equal URI('https://secure.example'), @source.api_uri
+ end
+
end
diff --git a/test/rubygems/test_gem_spec_fetcher.rb b/test/rubygems/test_gem_spec_fetcher.rb
index b4aff095c0..ac48edde96 100644
--- a/test/rubygems/test_gem_spec_fetcher.rb
+++ b/test/rubygems/test_gem_spec_fetcher.rb
@@ -32,13 +32,14 @@ class TestGemSpecFetcher < Gem::TestCase
Gem::NameTuple.new(spec.name, spec.version, spec.original_platform)
}
- v = Gem.marshal_version
- s_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@specs)))
- l_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@latest_specs)))
- p_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@prerelease_specs)))
- @fetcher.data["#{@gem_repo}specs.#{v}.gz"] = s_zip
- @fetcher.data["#{@gem_repo}latest_specs.#{v}.gz"] = l_zip
- @fetcher.data["#{@gem_repo}prerelease_specs.#{v}.gz"] = p_zip
+ @v = Gem.marshal_version
+ @s_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@specs)))
+ @l_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@latest_specs)))
+ @p_zip = util_gzip(Marshal.dump(Gem::NameTuple.to_basic(@prerelease_specs)))
+
+ @fetcher.data["#{@gem_repo}specs.#{@v}.gz"] = @s_zip
+ @fetcher.data["#{@gem_repo}latest_specs.#{@v}.gz"] = @l_zip
+ @fetcher.data["#{@gem_repo}prerelease_specs.#{@v}.gz"] = @p_zip
@sf = Gem::SpecFetcher.new
@@ -200,7 +201,6 @@ class TestGemSpecFetcher < Gem::TestCase
assert_equal comp.sort, specs[@source].sort
end
-
def test_available_specs_cache
specs, _ = @sf.available_specs(:latest)
@@ -240,5 +240,36 @@ class TestGemSpecFetcher < Gem::TestCase
assert_kind_of Gem::SourceFetchProblem, errors.first
end
+ def test_upgrade_http_source
+ Gem.configuration.verbose = :really
+
+ source = Gem::Source.new URI 'http://example'
+ same_source = nil
+ https_source = nil
+
+ use_ui @ui do
+ same_source = @sf.upgrade_http_source source
+ end
+
+ assert_equal URI('http://example'), same_source.uri
+
+ @fetcher.data['https://example/'] = 'hello'
+
+ use_ui @ui do
+ https_source = @sf.upgrade_http_source source
+ end
+
+ assert_equal URI('https://example'), https_source.uri
+
+ assert_empty @ui.error
+
+ expected = <<-EXPECTED
+Upgrading http://example to HTTPS failed, continuing
+Upgraded http://example to HTTPS
+ EXPECTED
+
+ assert_equal expected, @ui.output
+ end
+
end