From 8cc45aae947d453acca029e13eb64f3f5f0bf942 Mon Sep 17 00:00:00 2001 From: drbrain Date: Mon, 31 Mar 2008 22:40:06 +0000 Subject: Import RubyGems 1.1.0 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@15873 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- test/rubygems/gem_installer_test_case.rb | 86 +++++ test/rubygems/gem_package_tar_test_case.rb | 146 +++++++++ test/rubygems/gemutilities.rb | 151 +++++++-- test/rubygems/mockgemui.rb | 18 +- test/rubygems/private_key.pem | 27 ++ test/rubygems/public_cert.pem | 20 ++ test/rubygems/test_gem.rb | 47 ++- test/rubygems/test_gem_command_manager.rb | 6 +- .../test_gem_commands_environment_command.rb | 15 + test/rubygems/test_gem_commands_fetch_command.rb | 9 +- test/rubygems/test_gem_commands_install_command.rb | 64 ++-- test/rubygems/test_gem_commands_query_command.rb | 159 +++++++-- test/rubygems/test_gem_commands_server_command.rb | 2 +- test/rubygems/test_gem_commands_sources_command.rb | 74 ++++- .../test_gem_commands_specification_command.rb | 2 +- test/rubygems/test_gem_commands_unpack_command.rb | 50 ++- test/rubygems/test_gem_commands_update_command.rb | 174 ++++++++++ test/rubygems/test_gem_dependency_installer.rb | 351 ++++++++++---------- test/rubygems/test_gem_ext_configure_builder.rb | 15 +- test/rubygems/test_gem_format.rb | 2 +- test/rubygems/test_gem_indexer.rb | 9 +- test/rubygems/test_gem_installer.rb | 89 +---- test/rubygems/test_gem_package_tar_header.rb | 137 ++++++++ test/rubygems/test_gem_package_tar_input.rb | 119 +++++++ test/rubygems/test_gem_package_tar_output.rb | 104 ++++++ test/rubygems/test_gem_package_tar_reader.rb | 53 +++ test/rubygems/test_gem_package_tar_reader_entry.rb | 116 +++++++ test/rubygems/test_gem_package_tar_writer.rb | 151 +++++++++ test/rubygems/test_gem_remote_fetcher.rb | 204 +++++++++++- test/rubygems/test_gem_source_index.rb | 359 +++++++++++++++++---- test/rubygems/test_gem_source_info_cache.rb | 232 ++++++++++--- test/rubygems/test_gem_source_info_cache_entry.rb | 51 ++- test/rubygems/test_gem_uninstaller.rb | 43 +++ 33 files changed, 2555 insertions(+), 530 deletions(-) create mode 100644 test/rubygems/gem_installer_test_case.rb create mode 100644 test/rubygems/gem_package_tar_test_case.rb create mode 100644 test/rubygems/private_key.pem create mode 100644 test/rubygems/public_cert.pem create mode 100644 test/rubygems/test_gem_commands_update_command.rb create mode 100644 test/rubygems/test_gem_package_tar_header.rb create mode 100644 test/rubygems/test_gem_package_tar_input.rb create mode 100644 test/rubygems/test_gem_package_tar_output.rb create mode 100644 test/rubygems/test_gem_package_tar_reader.rb create mode 100644 test/rubygems/test_gem_package_tar_reader_entry.rb create mode 100644 test/rubygems/test_gem_package_tar_writer.rb create mode 100644 test/rubygems/test_gem_uninstaller.rb (limited to 'test') diff --git a/test/rubygems/gem_installer_test_case.rb b/test/rubygems/gem_installer_test_case.rb new file mode 100644 index 0000000000..0d684eb1eb --- /dev/null +++ b/test/rubygems/gem_installer_test_case.rb @@ -0,0 +1,86 @@ +require 'test/unit' +require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities') +require 'rubygems/installer' + +class Gem::Installer + attr_accessor :gem_dir + + attr_writer :format + attr_writer :gem_home + attr_writer :env_shebang + attr_writer :ignore_dependencies + attr_writer :format_executable + attr_writer :security_policy + attr_writer :spec + attr_writer :wrappers +end + +class GemInstallerTestCase < RubyGemTestCase + + def setup + super + + @spec = quick_gem "a" + @gem = File.join @tempdir, "#{@spec.full_name}.gem" + + util_build_gem @spec + FileUtils.mv File.join(@gemhome, 'cache', "#{@spec.full_name}.gem"), + @tempdir + + @installer = Gem::Installer.new @gem + @installer.gem_dir = util_gem_dir + @installer.gem_home = @gemhome + @installer.spec = @spec + end + + def util_gem_bindir(version = '2') + File.join util_gem_dir(version), "bin" + end + + def util_gem_dir(version = '2') + File.join @gemhome, "gems", "a-#{version}" # HACK + end + + def util_inst_bindir + File.join @gemhome, "bin" + end + + def util_make_exec(version = '2', shebang = "#!/usr/bin/ruby") + @spec.executables = ["my_exec"] + + FileUtils.mkdir_p util_gem_bindir(version) + exec_file = @installer.formatted_program_filename "my_exec" + exec_path = File.join util_gem_bindir(version), exec_file + File.open exec_path, 'w' do |f| + f.puts shebang + end + end + + def util_setup_gem(ui = @ui) # HACK fix use_ui to make this automatic + @spec.files = File.join('lib', 'code.rb') + @spec.executables << 'executable' + @spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb') + + Dir.chdir @tempdir do + FileUtils.mkdir_p 'bin' + FileUtils.mkdir_p 'lib' + FileUtils.mkdir_p File.join('ext', 'a') + File.open File.join('bin', 'executable'), 'w' do |f| f.puts '1' end + File.open File.join('lib', 'code.rb'), 'w' do |f| f.puts '1' end + File.open File.join('ext', 'a', 'mkrf_conf.rb'), 'w' do |f| + f << <<-EOF + File.open 'Rakefile', 'w' do |rf| rf.puts "task :default" end + EOF + end + + use_ui ui do + FileUtils.rm @gem + Gem::Builder.new(@spec).build + end + end + + @installer = Gem::Installer.new @gem + end + +end + diff --git a/test/rubygems/gem_package_tar_test_case.rb b/test/rubygems/gem_package_tar_test_case.rb new file mode 100644 index 0000000000..756b30ef27 --- /dev/null +++ b/test/rubygems/gem_package_tar_test_case.rb @@ -0,0 +1,146 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities') +require 'rubygems/package' + +class File + + # straight from setup.rb + def self.dir?(path) + # for corrupted windows stat() + File.directory?((path[-1,1] == '/') ? path : path + '/') + end + + def self.read_b(name) + File.open(name, "rb") { |f| f.read } + end + +end + +class TarTestCase < RubyGemTestCase + + def ASCIIZ(str, length) + str + "\0" * (length - str.length) + end + + def SP(s) + s + " " + end + + def SP_Z(s) + s + " \0" + end + + def Z(s) + s + "\0" + end + + def assert_headers_equal(expected, actual) + expected = expected.to_s unless String === expected + actual = actual.to_s unless String === actual + + fields = %w[ + name 100 + mode 8 + uid 8 + gid 8 + size 12 + mtime 12 + checksum 8 + typeflag 1 + linkname 100 + magic 6 + version 2 + uname 32 + gname 32 + devmajor 8 + devminor 8 + prefix 155 + ] + + offset = 0 + + until fields.empty? do + name = fields.shift + length = fields.shift.to_i + + if name == "checksum" then + chksum_off = offset + offset += length + next + end + + assert_equal expected[offset, length], actual[offset, length], + "Field #{name} of the tar header differs." + + offset += length + end + + assert_equal expected[chksum_off, 8], actual[chksum_off, 8] + end + + def calc_checksum(header) + sum = header.unpack("C*").inject{|s,a| s + a} + SP(Z(to_oct(sum, 6))) + end + + def header(type, fname, dname, length, mode, checksum = nil) + checksum ||= " " * 8 + + arr = [ # struct tarfile_entry_posix + ASCIIZ(fname, 100), # char name[100]; ASCII + (Z unless filled) + Z(to_oct(mode, 7)), # char mode[8]; 0 padded, octal null + Z(to_oct(0, 7)), # char uid[8]; ditto + Z(to_oct(0, 7)), # char gid[8]; ditto + Z(to_oct(length, 11)), # char size[12]; 0 padded, octal, null + Z(to_oct(0, 11)), # char mtime[12]; 0 padded, octal, null + checksum, # char checksum[8]; 0 padded, octal, null, space + type, # char typeflag[1]; file: "0" dir: "5" + "\0" * 100, # char linkname[100]; ASCII + (Z unless filled) + "ustar\0", # char magic[6]; "ustar\0" + "00", # char version[2]; "00" + ASCIIZ("wheel", 32), # char uname[32]; ASCIIZ + ASCIIZ("wheel", 32), # char gname[32]; ASCIIZ + Z(to_oct(0, 7)), # char devmajor[8]; 0 padded, octal, null + Z(to_oct(0, 7)), # char devminor[8]; 0 padded, octal, null + ASCIIZ(dname, 155) # char prefix[155]; ASCII + (Z unless filled) + ] + + format = "C100C8C8C8C12C12C8CC100C6C2C32C32C8C8C155" + h = if RUBY_VERSION >= "1.9" then + arr.join + else + arr = arr.join("").split(//).map{|x| x[0]} + arr.pack format + end + ret = h + "\0" * (512 - h.size) + assert_equal(512, ret.size) + ret + end + + def tar_dir_header(name, prefix, mode) + h = header("5", name, prefix, 0, mode) + checksum = calc_checksum(h) + header("5", name, prefix, 0, mode, checksum) + end + + def tar_file_header(fname, dname, mode, length) + h = header("0", fname, dname, length, mode) + checksum = calc_checksum(h) + header("0", fname, dname, length, mode, checksum) + end + + def to_oct(n, pad_size) + "%0#{pad_size}o" % n + end + + def util_entry(tar) + io = TempIO.new tar + header = Gem::Package::TarHeader.from io + entry = Gem::Package::TarReader::Entry.new header, io + end + + def util_dir_entry + util_entry tar_dir_header("foo", "bar", 0) + end + +end + diff --git a/test/rubygems/gemutilities.rb b/test/rubygems/gemutilities.rb index fb41210ac8..f12f4e88a5 100644 --- a/test/rubygems/gemutilities.rb +++ b/test/rubygems/gemutilities.rb @@ -10,9 +10,10 @@ at_exit { $SAFE = 1 } require 'fileutils' require 'test/unit' require 'tmpdir' +require 'tempfile' require 'uri' -require 'rubygems/gem_open_uri' require 'rubygems/source_info_cache' +require 'rubygems/package' require File.join(File.expand_path(File.dirname(__FILE__)), 'mockgemui') @@ -56,6 +57,20 @@ class FakeFetcher data.respond_to?(:call) ? data.call : data.length end + def download spec, source_uri, install_dir = Gem.dir + name = "#{spec.full_name}.gem" + path = File.join(install_dir, 'cache', name) + + if source_uri =~ /^http/ then + File.open(path, "wb") do |f| + f.write fetch_path(File.join(source_uri, "gems", name)) + end + else + FileUtils.cp source_uri, path + end + + path + end end class RubyGemTestCase < Test::Unit::TestCase @@ -76,6 +91,7 @@ class RubyGemTestCase < Test::Unit::TestCase @gemhome = File.join @tempdir, "gemhome" @gemcache = File.join(@gemhome, "source_cache") @usrcache = File.join(@gemhome, ".gem", "user_cache") + @latest_usrcache = File.join(@gemhome, ".gem", "latest_user_cache") FileUtils.mkdir_p @gemhome @@ -101,6 +117,11 @@ class RubyGemTestCase < Test::Unit::TestCase end @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}" + + @private_key = File.expand_path File.join(File.dirname(__FILE__), + 'private_key.pem') + @public_cert = File.expand_path File.join(File.dirname(__FILE__), + 'public_cert.pem') end def teardown @@ -135,25 +156,52 @@ class RubyGemTestCase < Test::Unit::TestCase end def prep_cache_files(lc) - [ [lc.system_cache_file, 'sys'], - [lc.user_cache_file, 'usr'], - ].each do |fn, data| - FileUtils.mkdir_p File.dirname(fn).untaint - open(fn.dup.untaint, "wb") { |f| f.write(Marshal.dump({'key' => data})) } + @usr_si ||= Gem::SourceIndex.new + @usr_sice ||= Gem::SourceInfoCacheEntry.new @usr_si, 0 + + @sys_si ||= Gem::SourceIndex.new + @sys_sice ||= Gem::SourceInfoCacheEntry.new @sys_si, 0 + + latest_si = Gem::SourceIndex.new + latest_si.add_specs(*@sys_si.latest_specs) + latest_sys_sice = Gem::SourceInfoCacheEntry.new latest_si, 0 + + latest_si = Gem::SourceIndex.new + latest_si.add_specs(*@usr_si.latest_specs) + latest_usr_sice = Gem::SourceInfoCacheEntry.new latest_si, 0 + + [ [lc.system_cache_file, @sys_sice], + [lc.latest_system_cache_file, latest_sys_sice], + [lc.user_cache_file, @usr_sice], + [lc.latest_user_cache_file, latest_usr_sice], + ].each do |filename, data| + FileUtils.mkdir_p File.dirname(filename).untaint + + open filename.dup.untaint, 'wb' do |f| + f.write Marshal.dump({ @gem_repo => data }) + end + end + end + + def read_cache(path) + open path.dup.untaint, 'rb' do |io| + Marshal.load io.read end end - def read_cache(fn) - open(fn.dup.untaint) { |f| Marshal.load f.read } + def read_binary(path) + Gem.read_binary path end def write_file(path) path = File.join(@gemhome, path) dir = File.dirname path FileUtils.mkdir_p dir - File.open(path, "w") { |io| - yield(io) - } + + open path, 'wb' do |io| + yield io + end + path end @@ -204,6 +252,23 @@ class RubyGemTestCase < Test::Unit::TestCase end end + def util_gem(name, version, &block) + spec = quick_gem(name, version, &block) + + util_build_gem spec + + cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" + FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"), + cache_file + FileUtils.rm File.join(@gemhome, 'specifications', + "#{spec.full_name}.gemspec") + + spec.loaded_from = nil + spec.loaded = false + + [spec, cache_file] + end + def util_make_gems init = proc do |s| s.files = %w[lib/code.rb] @@ -212,6 +277,7 @@ class RubyGemTestCase < Test::Unit::TestCase @a1 = quick_gem('a', '1', &init) @a2 = quick_gem('a', '2', &init) + @a_evil9 = quick_gem('a_evil', '9', &init) @b2 = quick_gem('b', '2', &init) @c1_2 = quick_gem('c', '1.2', &init) @pl1 = quick_gem 'pl', '1' do |s| # l for legacy @@ -227,7 +293,7 @@ class RubyGemTestCase < Test::Unit::TestCase write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) do end write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) do end - [@a1, @a2, @b2, @c1_2, @pl1].each { |spec| util_build_gem spec } + [@a1, @a2, @a_evil9, @b2, @c1_2, @pl1].each { |spec| util_build_gem spec } FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name) @@ -256,32 +322,19 @@ class RubyGemTestCase < Test::Unit::TestCase @fetcher = FakeFetcher.new @fetcher.uri = @uri - @gem1 = quick_gem 'gem_one' do |gem| - gem.files = %w[Rakefile lib/gem_one.rb] - end - - @gem2 = quick_gem 'gem_two' do |gem| - gem.files = %w[Rakefile lib/gem_two.rb] - end - - @gem3 = quick_gem 'gem_three' do |gem| # missing gem - gem.files = %w[Rakefile lib/gem_three.rb] - end - - # this gem has a higher version and longer name than the gem we want - @gem4 = quick_gem 'gem_one_evil', '666' do |gem| - gem.files = %w[Rakefile lib/gem_one.rb] - end + util_make_gems - @all_gems = [@gem1, @gem2, @gem3, @gem4].sort + @all_gems = [@a1, @a2, @a_evil9, @b2, @c1_2].sort @all_gem_names = @all_gems.map { |gem| gem.full_name } - gem_names = [@gem1.full_name, @gem2.full_name, @gem4.full_name] + gem_names = [@a1.full_name, @a2.full_name, @b2.full_name] @gem_names = gem_names.sort.join("\n") - @source_index = Gem::SourceIndex.new @gem1.full_name => @gem1, - @gem2.full_name => @gem2, - @gem4.full_name => @gem4 + @source_index = Gem::SourceIndex.new + @source_index.add_spec @a1 + @source_index.add_spec @a2 + @source_index.add_spec @a_evil9 + @source_index.add_spec @c1_2 Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher end @@ -294,7 +347,12 @@ class RubyGemTestCase < Test::Unit::TestCase sice = Gem::SourceInfoCacheEntry.new si, 0 sic = Gem::SourceInfoCache.new + sic.set_cache_data( { @gem_repo => sice } ) + sic.update + sic.write_cache + sic.reset_cache_data + Gem::SourceInfoCache.instance_variable_set :@cache, sic si end @@ -313,3 +371,30 @@ class RubyGemTestCase < Test::Unit::TestCase end +class TempIO + + @@count = 0 + + def initialize(string = '') + @tempfile = Tempfile.new "TempIO-#{@@count ++ 1}" + @tempfile.binmode + @tempfile.write string + @tempfile.rewind + end + + def method_missing(meth, *args, &block) + @tempfile.send(meth, *args, &block) + end + + def respond_to?(meth) + @tempfile.respond_to? meth + end + + def string + @tempfile.flush + + Gem.read_binary @tempfile.path + end + +end + diff --git a/test/rubygems/mockgemui.rb b/test/rubygems/mockgemui.rb index d9bc2a8134..95a95fbf98 100644 --- a/test/rubygems/mockgemui.rb +++ b/test/rubygems/mockgemui.rb @@ -15,9 +15,8 @@ class MockGemUi < Gem::StreamUI def initialize(input="") super(StringIO.new(input), StringIO.new, StringIO.new) @terminated = false - @banged = false end - + def input @ins.string end @@ -30,22 +29,15 @@ class MockGemUi < Gem::StreamUI @errs.string end - def banged? - @banged - end - def terminated? @terminated end - def terminate_interaction!(status=1) - @terminated = true - @banged = true - fail TermError - end - def terminate_interaction(status=0) @terminated = true - fail TermError + + raise TermError end + end + diff --git a/test/rubygems/private_key.pem b/test/rubygems/private_key.pem new file mode 100644 index 0000000000..95b3dc76d8 --- /dev/null +++ b/test/rubygems/private_key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAm24C6xixiAxO+i1f3L8XRMwrmLkt6BvT60mZ7g8HsklH3af7 +KNHA6vo/G6sujs2UsNO4HY8BTEneiVOXXWQlcsJ+Z5wEPlIu4zFueAmLefx+n9lE +ulNIUDoyUenKX4spoMRnX8k4lXL05ho/6JFq0JdDY2DmAaQ4vvTz5mh9kZiybtHQ +fzcpbA51uY+sjdQRCPDHyUUfh0SmWJlLYMwcBdVeCiGUPBLi+iP5x1btO4uiJK6Q +IMaV1H3SUCYtKGQKl7qwFd8k8ZBcHYOtmK61tupg3vqWQc0em6SxPj5lws8+1MVK +twBNIDx24jF4ntxBRNKMZ7FN5SHbobAgDYkPAQIDAQABAoIBAGQilgK8X/PUajVH +clEXU3hhSV0VQHwfIYKeYms6h6zXBVPKW0dLC0zXeDztJgueasMZQ67XaPCrTpGO +px/l2zJ6F1HM8/bqn4aDXDY9f/xRLYryQRMBgL8fHzgitNylHWaT4j2Vt7yg2SI9 +mxrMRNKqASJPVR+Nm3l6+n9gpjVb99wEucWplPPHI6KhXLYPZOqSwt+zaH5roz3k +UQmMs0Bs4hF1SzVl0n+KNoXHOwswVrmBWXgWvm2OhnwY2e26jfejc8toJc/ShAJ7 +C9exnrdimcgEKbd22Sum4G00CDYhcrG5LHHqkgwifcAEVctrvBZBZHGgpxlO8a8U +eF2Vr7kCgYEAykdrBlzp7Fn9xzUInBQ3NXTTYAq51lpuJdmHQmPuTSY0buoHkd9f +xbUCZ2qR9QAesrx4hI0qGLetc8IOKDoWx2rPepCCvO3Kx61o1SB5fAvBue03qVoq +HqACX3Uk24Em8zAz9xuP13ETH/wU7sUbUxRHMCre6ZDmlxn4g5l+Nl8CgYEAxLVl +22yBx0dfRr3UsHY9rxll2gIlnfnYfiJzq8wetzt/TfztRV5ILz7FyWqL5d7IoqkA +fT2V4HAasRJASnKohwJe7z5M/H2ExwkGNFvY+jefb2CoUl5WouK9AlhbqBk3zmHi +sY5GqQkAp/kHMntEin+sErJw6mkgAGdser3a9p8CgYEAqi31w++tunRnxw4+RRnY +7Pdx0k6T1NxV6TAe1ONAHNY0rM/mOHqml65W7GzDiU1lhlh8SIB/VzZJDqfHw15D +xdh94A7uf0bMILwrA4wDyTIW9Xa3Kpq57vQNqwPiU25QN69pOM+Ob+IpBfLOJafc ++kOINOUMj5Kh/aQS6Zzci58CgYEAk24dlFKEBjbRCvU2FrfYTYcsljPru7ZJc2gg +588J6m0WYf5CWy5pzbcviGFpzvSlzXv7GOLylQ+QgcxbETFUbDPzsT4xd0AgJwj1 +dIKuYgMUZOa94VZBer2TydEtiRS1heJJhKhM/1329u4nXceTvHYqIq1JAfeee48I +eAoZtaMCgYBz1FjWFQnMTD5nmyPEEZneoBPAR5+9jwOps+IYOoHtazoMFszzd0qo +JZW3Ihn9KRrVSxfFApKS/ZwjiZ+tJUk7DE/v/0l0sszefY7s8b0pL1lpeZSoL71e +QoG1WLXUiDV3BRlmyOAF1h3p12KRTLgwubN51ajECwcs3QwE+ZT8Gg== +-----END RSA PRIVATE KEY----- diff --git a/test/rubygems/public_cert.pem b/test/rubygems/public_cert.pem new file mode 100644 index 0000000000..9b7c3d8e98 --- /dev/null +++ b/test/rubygems/public_cert.pem @@ -0,0 +1,20 @@ +-----BEGIN CERTIFICATE----- +MIIDNjCCAh6gAwIBAgIBADANBgkqhkiG9w0BAQUFADBBMRAwDgYDVQQDDAdkcmJy +YWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZFgNu +ZXQwHhcNMDcxMjIxMDIwNDE0WhcNMDgxMjIwMDIwNDE0WjBBMRAwDgYDVQQDDAdk +cmJyYWluMRgwFgYKCZImiZPyLGQBGRYIc2VnbWVudDcxEzARBgoJkiaJk/IsZAEZ +FgNuZXQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCbbgLrGLGIDE76 +LV/cvxdEzCuYuS3oG9PrSZnuDweySUfdp/so0cDq+j8bqy6OzZSw07gdjwFMSd6J +U5ddZCVywn5nnAQ+Ui7jMW54CYt5/H6f2US6U0hQOjJR6cpfiymgxGdfyTiVcvTm +Gj/okWrQl0NjYOYBpDi+9PPmaH2RmLJu0dB/NylsDnW5j6yN1BEI8MfJRR+HRKZY +mUtgzBwF1V4KIZQ8EuL6I/nHVu07i6IkrpAgxpXUfdJQJi0oZAqXurAV3yTxkFwd +g62YrrW26mDe+pZBzR6bpLE+PmXCzz7UxUq3AE0gPHbiMXie3EFE0oxnsU3lIduh +sCANiQ8BAgMBAAGjOTA3MAkGA1UdEwQCMAAwCwYDVR0PBAQDAgSwMB0GA1UdDgQW +BBS5k4Z75VSpdM0AclG2UvzFA/VW5DANBgkqhkiG9w0BAQUFAAOCAQEAHagT4lfX +kP/hDaiwGct7XPuVGbrOsKRVD59FF5kETBxEc9UQ1clKWngf8JoVuEoKD774dW19 +bU0GOVWO+J6FMmT/Cp7nuFJ79egMf/gy4gfUfQMuvfcr6DvZUPIs9P/TlK59iMYF +DIOQ3DxdF3rMzztNUCizN4taVscEsjCcgW6WkUJnGdqlu3OHWpQxZBJkBTjPCoc6 +UW6on70SFPmAy/5Cq0OJNGEWBfgD9q7rrs/X8GGwUWqXb85RXnUVi/P8Up75E0ag +14jEc90kN+C7oI/AGCBN0j6JnEtYIEJZibjjDJTSMWlUKKkj30kq7hlUC2CepJ4v +x52qPcexcYZR7w== +-----END CERTIFICATE----- diff --git a/test/rubygems/test_gem.rb b/test/rubygems/test_gem.rb index e0160950f8..b04d69d509 100644 --- a/test/rubygems/test_gem.rb +++ b/test/rubygems/test_gem.rb @@ -19,6 +19,7 @@ class TestGem < RubyGemTestCase expected = [ File.join(@gemhome, *%W[gems #{@a1.full_name} lib]), File.join(@gemhome, *%W[gems #{@a2.full_name} lib]), + File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]), File.join(@gemhome, *%W[gems #{@b2.full_name} lib]), File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]), File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]), @@ -213,6 +214,7 @@ class TestGem < RubyGemTestCase expected = [ File.join(@gemhome, *%W[gems #{@a2.full_name} lib]), + File.join(@gemhome, *%W[gems #{@a_evil9.full_name} lib]), File.join(@gemhome, *%W[gems #{@b2.full_name} lib]), File.join(@gemhome, *%W[gems #{@c1_2.full_name} lib]), File.join(@gemhome, *%W[gems #{@pl1.full_name} lib]), @@ -226,7 +228,7 @@ class TestGem < RubyGemTestCase install_gem foo Gem.source_index = nil - Gem.activate 'foo', false + Gem.activate 'foo' assert_equal true, Gem.loaded_specs.keys.include?('foo') end @@ -235,9 +237,29 @@ class TestGem < RubyGemTestCase assert_equal [Gem.dir], Gem.path end + def test_self_path_APPLE_GEM_HOME + Gem.clear_paths + Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home' + + assert Gem.path.include?('/tmp/apple_gem_home') + ensure + Gem.send :remove_const, :APPLE_GEM_HOME + end + + def test_self_path_APPLE_GEM_HOME_GEM_PATH + Gem.clear_paths + ENV['GEM_PATH'] = @gemhome + Gem.const_set :APPLE_GEM_HOME, '/tmp/apple_gem_home' + + assert !Gem.path.include?('/tmp/apple_gem_home') + ensure + Gem.send :remove_const, :APPLE_GEM_HOME + end + def test_self_path_ENV_PATH Gem.clear_paths path_count = Gem.path.size + path_count -= 1 if defined? APPLE_GEM_HOME Gem.clear_paths util_ensure_gem_dirs @@ -257,8 +279,8 @@ class TestGem < RubyGemTestCase ENV['GEM_PATH'] = dirs.join File::PATH_SEPARATOR assert_equal @gemhome, Gem.dir + paths = [Gem.dir] - paths << APPLE_GEM_HOME if defined? APPLE_GEM_HOME assert_equal @additional + paths, Gem.path end @@ -270,8 +292,8 @@ class TestGem < RubyGemTestCase ENV['GEM_PATH'] = @additional.join(File::PATH_SEPARATOR) assert_equal @gemhome, Gem.dir + paths = [Gem.dir] - paths.insert(0, APPLE_GEM_HOME) if defined? APPLE_GEM_HOME assert_equal @additional + paths, Gem.path end @@ -284,6 +306,18 @@ class TestGem < RubyGemTestCase assert_equal File.dirname(File.dirname(file_name)), Gem.prefix end + def test_self_prefix_odd + orig_sitelibdir = Gem::ConfigMap[:sitelibdir] + + file_name = File.expand_path __FILE__ + prefix = File.join File.dirname(File.dirname(file_name)), 'lib' + Gem::ConfigMap[:sitelibdir] = prefix.sub(/[\w]\//, '\&/') + + assert_nil Gem.prefix + ensure + Gem::ConfigMap[:sitelibdir] = orig_sitelibdir + end + def test_self_required_location util_make_gems @@ -295,6 +329,13 @@ class TestGem < RubyGemTestCase Gem.required_location("a", "code.rb", "= 2") end + def test_self_ruby_version + version = RUBY_VERSION.dup + version << ".#{RUBY_PATCHLEVEL}" if defined? RUBY_PATCHLEVEL + + assert_equal Gem::Version.new(version), Gem.ruby_version + end + def test_self_searcher assert_kind_of Gem::GemPathSearcher, Gem.searcher end diff --git a/test/rubygems/test_gem_command_manager.rb b/test/rubygems/test_gem_command_manager.rb index 4198bb9a2a..b7767f421d 100644 --- a/test/rubygems/test_gem_command_manager.rb +++ b/test/rubygems/test_gem_command_manager.rb @@ -67,11 +67,12 @@ class TestGemCommandManager < RubyGemTestCase assert_equal true, check_options[:wrappers] assert_equal Gem::Requirement.default, check_options[:version] assert_equal Gem.dir, check_options[:install_dir] + assert_equal nil, check_options[:bin_dir] #check settings check_options = nil @command_manager.process_args( - "install --force --test --local --rdoc --install-dir . --version 3.0 --no-wrapper") + "install --force --test --local --rdoc --install-dir . --version 3.0 --no-wrapper --bindir . ") assert_equal true, check_options[:test] assert_equal true, check_options[:generate_rdoc] assert_equal true, check_options[:force] @@ -79,6 +80,7 @@ class TestGemCommandManager < RubyGemTestCase assert_equal false, check_options[:wrappers] assert_equal Gem::Requirement.new('3.0'), check_options[:version] assert_equal Dir.pwd, check_options[:install_dir] + assert_equal Dir.pwd, check_options[:bin_dir] #check remote domain check_options = nil @@ -164,7 +166,7 @@ class TestGemCommandManager < RubyGemTestCase #check defaults @command_manager.process_args("query") - assert_equal(/.*/, check_options[:name]) + assert_equal(//, check_options[:name]) assert_equal :local, check_options[:domain] assert_equal false, check_options[:details] diff --git a/test/rubygems/test_gem_commands_environment_command.rb b/test/rubygems/test_gem_commands_environment_command.rb index 0913888a6d..5568478652 100644 --- a/test/rubygems/test_gem_commands_environment_command.rb +++ b/test/rubygems/test_gem_commands_environment_command.rb @@ -62,6 +62,21 @@ class TestGemCommandsEnvironmentCommand < RubyGemTestCase assert_equal '', @ui.error end + def test_execute_gempath_multiple + Gem.clear_paths + path = [@gemhome, "#{@gemhome}2"].join File::PATH_SEPARATOR + ENV['GEM_PATH'] = path + + @cmd.send :handle_options, %w[gempath] + + use_ui @ui do + @cmd.execute + end + + assert_equal "#{Gem.path.join File::PATH_SEPARATOR}\n", @ui.output + assert_equal '', @ui.error + end + def test_execute_packageversion @cmd.send :handle_options, %w[packageversion] diff --git a/test/rubygems/test_gem_commands_fetch_command.rb b/test/rubygems/test_gem_commands_fetch_command.rb index d8651680b0..5a42e4e81e 100644 --- a/test/rubygems/test_gem_commands_fetch_command.rb +++ b/test/rubygems/test_gem_commands_fetch_command.rb @@ -15,13 +15,12 @@ class TestGemCommandsFetchCommand < RubyGemTestCase def test_execute util_setup_fake_fetcher - util_build_gem @gem1 @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = @source_index.dump - @fetcher.data["#{@gem_repo}/gems/#{@gem1.full_name}.gem"] = - File.read(File.join(@gemhome, 'cache', "#{@gem1.full_name}.gem")) + @fetcher.data["#{@gem_repo}/gems/#{@a2.full_name}.gem"] = + File.read(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) - @cmd.options[:args] = [@gem1.name] + @cmd.options[:args] = [@a2.name] use_ui @ui do Dir.chdir @tempdir do @@ -29,7 +28,7 @@ class TestGemCommandsFetchCommand < RubyGemTestCase end end - assert File.exist?(File.join(@tempdir, "#{@gem1.full_name}.gem")) + assert File.exist?(File.join(@tempdir, "#{@a2.full_name}.gem")) end end diff --git a/test/rubygems/test_gem_commands_install_command.rb b/test/rubygems/test_gem_commands_install_command.rb index 78840be8c6..101195a43e 100644 --- a/test/rubygems/test_gem_commands_install_command.rb +++ b/test/rubygems/test_gem_commands_install_command.rb @@ -34,25 +34,26 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher @cmd.options[:domain] = :local - gem1 = quick_gem 'gem_one' - util_build_gem gem1 - FileUtils.mv File.join(@gemhome, 'cache', "#{@gem1.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), File.join(@tempdir) - @cmd.options[:args] = [gem1.name] + @cmd.options[:args] = [@a2.name] use_ui @ui do orig_dir = Dir.pwd begin Dir.chdir @tempdir - @cmd.execute + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 0, e.exit_code ensure Dir.chdir orig_dir end end out = @ui.output.split "\n" - assert_equal "Successfully installed #{@gem1.full_name}", out.shift + assert_equal "Successfully installed #{@a2.full_name}", out.shift assert_equal "1 gem installed", out.shift assert out.empty?, out.inspect end @@ -61,14 +62,17 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher @cmd.options[:domain] = :local - @cmd.options[:args] = %w[gem_one] + @cmd.options[:args] = %w[no_such_gem] use_ui @ui do - @cmd.execute + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 2, e.exit_code end # HACK no repository was checked - assert_equal "ERROR: could not find gem_one locally or in a repository\n", + assert_equal "ERROR: could not find no_such_gem locally or in a repository\n", @ui.error end @@ -88,7 +92,10 @@ class TestGemCommandsInstallCommand < RubyGemTestCase @cmd.options[:args] = %w[nonexistent] use_ui @ui do - @cmd.execute + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 2, e.exit_code end assert_equal "ERROR: could not find nonexistent locally or in a repository\n", @@ -100,25 +107,27 @@ class TestGemCommandsInstallCommand < RubyGemTestCase @cmd.options[:generate_ri] = true util_setup_fake_fetcher - util_build_gem @gem1 @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = @source_index.dump - @fetcher.data["#{@gem_repo}/gems/gem_one-0.0.2.gem"] = - File.read(File.join(@gemhome, 'cache', "#{@gem1.full_name}.gem")) + @fetcher.data["#{@gem_repo}/gems/#{@a2.full_name}.gem"] = + read_binary(File.join(@gemhome, 'cache', "#{@a2.full_name}.gem")) - @cmd.options[:args] = [@gem1.name] + @cmd.options[:args] = [@a2.name] use_ui @ui do - @cmd.execute + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 0, e.exit_code end out = @ui.output.split "\n" assert_match %r|Bulk updating|, out.shift - assert_equal "Successfully installed #{@gem1.full_name}", out.shift + assert_equal "Successfully installed #{@a2.full_name}", out.shift assert_equal "1 gem installed", out.shift - assert_equal "Installing ri documentation for #{@gem1.full_name}...", + assert_equal "Installing ri documentation for #{@a2.full_name}...", out.shift - assert_equal "Installing RDoc documentation for #{@gem1.full_name}...", + assert_equal "Installing RDoc documentation for #{@a2.full_name}...", out.shift assert out.empty?, out.inspect end @@ -127,31 +136,30 @@ class TestGemCommandsInstallCommand < RubyGemTestCase util_setup_fake_fetcher @cmd.options[:domain] = :local - gem1 = quick_gem 'gem_one' - util_build_gem gem1 - FileUtils.mv File.join(@gemhome, 'cache', "#{@gem1.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', "#{@a2.full_name}.gem"), File.join(@tempdir) - gem2 = quick_gem 'gem_two' - util_build_gem gem2 - FileUtils.mv File.join(@gemhome, 'cache', "#{@gem2.full_name}.gem"), + FileUtils.mv File.join(@gemhome, 'cache', "#{@b2.full_name}.gem"), File.join(@tempdir) - @cmd.options[:args] = [gem1.name, gem2.name] + @cmd.options[:args] = [@a2.name, @b2.name] use_ui @ui do orig_dir = Dir.pwd begin Dir.chdir @tempdir - @cmd.execute + e = assert_raises Gem::SystemExitException do + @cmd.execute + end + assert_equal 0, e.exit_code ensure Dir.chdir orig_dir end end out = @ui.output.split "\n" - assert_equal "Successfully installed #{@gem1.full_name}", out.shift - assert_equal "Successfully installed #{@gem2.full_name}", out.shift + assert_equal "Successfully installed #{@a2.full_name}", out.shift + assert_equal "Successfully installed #{@b2.full_name}", out.shift assert_equal "2 gems installed", out.shift assert out.empty?, out.inspect end diff --git a/test/rubygems/test_gem_commands_query_command.rb b/test/rubygems/test_gem_commands_query_command.rb index 4430ccfd33..7e71419089 100644 --- a/test/rubygems/test_gem_commands_query_command.rb +++ b/test/rubygems/test_gem_commands_query_command.rb @@ -7,20 +7,31 @@ class TestGemCommandsQueryCommand < RubyGemTestCase def setup super - @foo_gem = quick_gem 'foo' do |spec| - spec.summary = 'This is a lot of text. ' * 5 - end - @foo_gem_p = quick_gem 'foo' do |spec| - spec.summary = 'This is a lot of text. ' * 5 - spec.platform = Gem::Platform::CURRENT - end - @bar_gem = quick_gem 'bar' + util_make_gems + + @a2.summary = 'This is a lot of text. ' * 4 @cmd = Gem::Commands::QueryCommand.new + + @si = util_setup_source_info_cache @a1, @a2, @pl1 + util_setup_fake_fetcher + + @fetcher.data["#{@gem_repo}/Marshal.#{Gem.marshal_version}"] = proc do + raise Gem::RemoteFetcher::FetchError + end end def test_execute - util_setup_source_info_cache @foo_gem, @foo_gem_p + cache = Gem::SourceInfoCache.cache + cache.update + cache.write_cache + cache.reset_cache_data + + a2_name = @a2.full_name + @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = util_zip a2_name + @fetcher.data["#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{a2_name}.gemspec.rz"] = util_zip Marshal.dump(@a2) + @fetcher.data["#{@gem_repo}/Marshal.#{Gem.marshal_version}"] = + Marshal.dump @si @cmd.handle_options %w[-r] @@ -32,16 +43,50 @@ class TestGemCommandsQueryCommand < RubyGemTestCase *** REMOTE GEMS *** -foo (2) +a (2) EOF assert_equal expected, @ui.output assert_equal '', @ui.error end - def test_execute_details - util_setup_source_info_cache @foo_gem + def test_execute_all + cache = Gem::SourceInfoCache.cache + cache.update + cache.write_cache + cache.reset_cache_data + + a1_name = @a1.full_name + a2_name = @a2.full_name + @fetcher.data["#{@gem_repo}/quick/index.rz"] = + util_zip [a1_name, a2_name].join("\n") + @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = util_zip a2_name + @fetcher.data["#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{a1_name}.gemspec.rz"] = util_zip Marshal.dump(@a1) + @fetcher.data["#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{a2_name}.gemspec.rz"] = util_zip Marshal.dump(@a2) + @fetcher.data["#{@gem_repo}/Marshal.#{Gem.marshal_version}"] = + Marshal.dump @si + + @cmd.handle_options %w[-r --all] + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF +*** REMOTE GEMS *** + +Updating metadata for 1 gems from http://gems.example.com/ +. +complete +a (2, 1) + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + end + + def test_execute_details @cmd.handle_options %w[-r -d] use_ui @ui do @@ -52,18 +97,94 @@ foo (2) *** REMOTE GEMS *** -foo (2) - This is a lot of text. This is a lot of text. This is a lot of - text. This is a lot of text. This is a lot of text. +a (2, 1) + This is a lot of text. This is a lot of text. This is a lot of text. + This is a lot of text. + +pl (1) + this is a summary EOF assert_equal expected, @ui.output assert_equal '', @ui.error end - def test_execute_no_versions - util_setup_source_info_cache @foo_gem, @bar_gem + def test_execute_installed + @cmd.handle_options %w[-n c --installed] + e = assert_raise Gem::SystemExitException do + use_ui @ui do + @cmd.execute + end + end + + assert_equal 0, e.exit_code + + assert_equal "true\n", @ui.output + assert_equal '', @ui.error + end + + def test_execute_installed_no_name + @cmd.handle_options %w[--installed] + + e = assert_raise Gem::SystemExitException do + use_ui @ui do + @cmd.execute + end + end + + assert_equal '', @ui.output + assert_equal "ERROR: You must specify a gem name\n", @ui.error + + assert_equal 4, e.exit_code + end + + def test_execute_installed_not_installed + @cmd.handle_options %w[-n not_installed --installed] + + e = assert_raise Gem::SystemExitException do + use_ui @ui do + @cmd.execute + end + end + + assert_equal "false\n", @ui.output + assert_equal '', @ui.error + + assert_equal 1, e.exit_code + end + + def test_execute_installed_version + @cmd.handle_options %w[-n c --installed --version 1.2] + + e = assert_raise Gem::SystemExitException do + use_ui @ui do + @cmd.execute + end + end + + assert_equal "true\n", @ui.output + assert_equal '', @ui.error + + assert_equal 0, e.exit_code + end + + def test_execute_installed_version_not_installed + @cmd.handle_options %w[-n c --installed --version 2] + + e = assert_raise Gem::SystemExitException do + use_ui @ui do + @cmd.execute + end + end + + assert_equal "false\n", @ui.output + assert_equal '', @ui.error + + assert_equal 1, e.exit_code + end + + def test_execute_no_versions @cmd.handle_options %w[-r --no-versions] use_ui @ui do @@ -74,8 +195,8 @@ foo (2) *** REMOTE GEMS *** -bar -foo +a +pl EOF assert_equal expected, @ui.output diff --git a/test/rubygems/test_gem_commands_server_command.rb b/test/rubygems/test_gem_commands_server_command.rb index 3e6af2e11c..2985b036d8 100644 --- a/test/rubygems/test_gem_commands_server_command.rb +++ b/test/rubygems/test_gem_commands_server_command.rb @@ -20,7 +20,7 @@ class TestGemCommandsServerCommand < RubyGemTestCase @cmd.send :handle_options, %w[-p 9999 -d /nonexistent --daemon] assert_equal true, @cmd.options[:daemon] - assert_equal '/nonexistent', @cmd.options[:gemdir] + assert_equal File.expand_path('/nonexistent'), @cmd.options[:gemdir] assert_equal 9999, @cmd.options[:port] end end diff --git a/test/rubygems/test_gem_commands_sources_command.rb b/test/rubygems/test_gem_commands_sources_command.rb index 3d1ab801b1..7ba88fad98 100644 --- a/test/rubygems/test_gem_commands_sources_command.rb +++ b/test/rubygems/test_gem_commands_sources_command.rb @@ -31,10 +31,11 @@ class TestGemCommandsSourcesCommand < RubyGemTestCase def test_execute_add util_setup_fake_fetcher - @si = Gem::SourceIndex.new @gem1.full_name => @gem1.name + si = Gem::SourceIndex.new + si.add_spec @a1 @fetcher.data["http://beta-gems.example.com/Marshal.#{@marshal_version}"] = - @si.dump + si.dump @cmd.handle_options %w[--add http://beta-gems.example.com] @@ -45,7 +46,7 @@ class TestGemCommandsSourcesCommand < RubyGemTestCase end expected = <<-EOF -Bulk updating Gem source index for: http://beta-gems.example.com +Bulk updating Gem source index for: http://beta-gems.example.com/ http://beta-gems.example.com added to sources EOF @@ -60,14 +61,11 @@ http://beta-gems.example.com added to sources def test_execute_add_nonexistent_source util_setup_fake_fetcher - @si = Gem::SourceIndex.new @gem1.full_name => @gem1.name - @fetcher.data["http://beta-gems.example.com/Marshal.#{@marshal_version}"] = proc do raise Gem::RemoteFetcher::FetchError, 'it died' end - Gem::RemoteFetcher.instance_variable_set :@fetcher, @fetcher @cmd.handle_options %w[--add http://beta-gems.example.com] @@ -104,6 +102,41 @@ beta-gems.example.com is not a URI assert_equal '', @ui.error end + def test_execute_clear_all + @cmd.handle_options %w[--clear-all] + + util_setup_source_info_cache + + cache = Gem::SourceInfoCache.cache + cache.update + cache.write_cache + + assert File.exist?(cache.system_cache_file), + 'system cache file' + assert File.exist?(cache.latest_system_cache_file), + 'latest system cache file' + + use_ui @ui do + @cmd.execute + end + + expected = <<-EOF +*** Removed user source cache *** +*** Removed latest user source cache *** +*** Removed system source cache *** +*** Removed latest system source cache *** + EOF + + assert_equal expected, @ui.output + assert_equal '', @ui.error + + assert !File.exist?(cache.system_cache_file), + 'system cache file' + assert !File.exist?(cache.latest_system_cache_file), + 'latest system cache file' + + end + def test_execute_remove @cmd.handle_options %W[--remove #{@gem_repo}] @@ -122,20 +155,43 @@ beta-gems.example.com is not a URI assert_equal [], Gem::SourceInfoCache.cache_data.keys end + def test_execute_remove_no_network + @cmd.handle_options %W[--remove #{@gem_repo}] + + util_setup_fake_fetcher + + @fetcher.data["#{@gem_repo}/Marshal.#{Gem.marshal_version}"] = proc do + raise Gem::RemoteFetcher::FetchError + end + + use_ui @ui do + @cmd.execute + end + + expected = "#{@gem_repo} removed from sources\n" + + assert_equal expected, @ui.output + assert_equal '', @ui.error + + Gem::SourceInfoCache.cache.flush + assert_equal [], Gem::SourceInfoCache.cache_data.keys + end + def test_execute_update @cmd.handle_options %w[--update] util_setup_source_info_cache util_setup_fake_fetcher - @si = Gem::SourceIndex.new @gem1.full_name => @gem1.name - @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = @si.dump + si = Gem::SourceIndex.new + si.add_spec @a1 + @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump use_ui @ui do @cmd.execute end expected = <<-EOF -Bulk updating Gem source index for: #{@gem_repo} +Bulk updating Gem source index for: #{@gem_repo}/ source cache successfully updated EOF diff --git a/test/rubygems/test_gem_commands_specification_command.rb b/test/rubygems/test_gem_commands_specification_command.rb index c8f57fef58..f66f0c0d49 100644 --- a/test/rubygems/test_gem_commands_specification_command.rb +++ b/test/rubygems/test_gem_commands_specification_command.rb @@ -12,6 +12,7 @@ class TestGemCommandsSpecificationCommand < RubyGemTestCase def test_execute foo = quick_gem 'foo' + Gem.source_index.add_spec foo @cmd.options[:args] = %w[foo] @@ -87,7 +88,6 @@ class TestGemCommandsSpecificationCommand < RubyGemTestCase assert_match %r|\A--- !ruby/object:Gem::Specification|, @ui.output assert_match %r|name: foo|, @ui.output - assert_equal "WARNING: Remote information is not complete\n\n", @ui.error end end diff --git a/test/rubygems/test_gem_commands_unpack_command.rb b/test/rubygems/test_gem_commands_unpack_command.rb index 427f9403c3..3a62a914a4 100644 --- a/test/rubygems/test_gem_commands_unpack_command.rb +++ b/test/rubygems/test_gem_commands_unpack_command.rb @@ -17,15 +17,57 @@ class TestGemCommandsUnpackCommand < RubyGemTestCase @cmd.options[:args] = %w[a] - use_ui @ui do - Dir.chdir @tempdir do - @cmd.execute - end + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + assert File.exist?(File.join(@tempdir, 'a-2')) + end + + def test_execute_gem_path + util_make_gems + + Gem.clear_paths + + gemhome2 = File.join @tempdir, 'gemhome2' + + Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR) + Gem.send :set_home, gemhome2 + + @cmd.options[:args] = %w[a] + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute end + end assert File.exist?(File.join(@tempdir, 'a-2')) end + def test_execute_gem_path_missing + util_make_gems + + Gem.clear_paths + + gemhome2 = File.join @tempdir, 'gemhome2' + + Gem.send :set_paths, [gemhome2, @gemhome].join(File::PATH_SEPARATOR) + Gem.send :set_home, gemhome2 + + @cmd.options[:args] = %w[z] + + use_ui @ui do + Dir.chdir @tempdir do + @cmd.execute + end + end + + assert_equal '', @ui.output + end + def test_execute_with_target_option util_make_gems diff --git a/test/rubygems/test_gem_commands_update_command.rb b/test/rubygems/test_gem_commands_update_command.rb new file mode 100644 index 0000000000..1fcec6a075 --- /dev/null +++ b/test/rubygems/test_gem_commands_update_command.rb @@ -0,0 +1,174 @@ +require 'test/unit' +require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities') +require 'rubygems/commands/update_command' + +class TestGemCommandsUpdateCommand < RubyGemTestCase + + def setup + super + + @cmd = Gem::Commands::UpdateCommand.new + + util_setup_fake_fetcher + + @a1_path = File.join @gemhome, 'cache', "#{@a1.full_name}.gem" + @a2_path = File.join @gemhome, 'cache', "#{@a2.full_name}.gem" + + @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = + @source_index.dump + @fetcher.data["#{@gem_repo}/gems/#{@a1.full_name}.gem"] = read_binary @a1_path + @fetcher.data["#{@gem_repo}/gems/#{@a2.full_name}.gem"] = read_binary @a2_path + end + + def test_execute + util_remove_gems + + Gem::Installer.new(@a1_path).install + + @cmd.options[:args] = [] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_match %r|Bulk updating|, out.shift + assert_equal "Updating #{@a2.name}", out.shift + assert_equal "Successfully installed #{@a2.full_name}", out.shift + assert_equal "Gems updated: #{@a2.name}", out.shift + + assert out.empty?, out.inspect + end + + # before: + # a1 -> c1.2 + # after: + # a2 -> b2 # new dependency + # a2 -> c2 + + def test_execute_dependencies + @a1.add_dependency 'c', '1.2' + + @c2 = quick_gem 'c', '2' do |s| + s.files = %w[lib/code.rb] + s.require_paths = %w[lib] + end + + @a2.add_dependency 'c', '2' + @a2.add_dependency 'b', '2' + + @b2_path = File.join @gemhome, 'cache', "#{@b2.full_name}.gem" + @c1_2_path = File.join @gemhome, 'cache', "#{@c1_2.full_name}.gem" + @c2_path = File.join @gemhome, 'cache', "#{@c2.full_name}.gem" + + @source_index = Gem::SourceIndex.new + @source_index.add_spec @a1 + @source_index.add_spec @a2 + @source_index.add_spec @b2 + @source_index.add_spec @c1_2 + @source_index.add_spec @c2 + + util_build_gem @a1 + util_build_gem @a2 + util_build_gem @c2 + + @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = + @source_index.dump + @fetcher.data["#{@gem_repo}/gems/#{@a1.full_name}.gem"] = read_binary @a1_path + @fetcher.data["#{@gem_repo}/gems/#{@a2.full_name}.gem"] = read_binary @a2_path + @fetcher.data["#{@gem_repo}/gems/#{@b2.full_name}.gem"] = read_binary @b2_path + @fetcher.data["#{@gem_repo}/gems/#{@c1_2.full_name}.gem"] = + read_binary @c1_2_path + @fetcher.data["#{@gem_repo}/gems/#{@c2.full_name}.gem"] = read_binary @c2_path + + util_remove_gems + + Gem::Installer.new(@c1_2_path).install + Gem::Installer.new(@a1_path).install + + @cmd.options[:args] = [] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_match %r|Bulk updating|, out.shift + assert_equal "Updating #{@a2.name}", out.shift + assert_equal "Successfully installed #{@c2.full_name}", out.shift + assert_equal "Successfully installed #{@b2.full_name}", out.shift + assert_equal "Successfully installed #{@a2.full_name}", out.shift + assert_equal "Gems updated: #{@c2.name}, #{@b2.name}, #{@a2.name}", + out.shift + + assert out.empty?, out.inspect + end + + def test_execute_named + util_remove_gems + + Gem::Installer.new(@a1_path).install + + @cmd.options[:args] = [@a1.name] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_match %r|Bulk updating|, out.shift + assert_equal "Updating #{@a2.name}", out.shift + assert_equal "Successfully installed #{@a2.full_name}", out.shift + assert_equal "Gems updated: #{@a2.name}", out.shift + + assert out.empty?, out.inspect + end + + def test_execute_named_up_to_date + util_remove_gems + + Gem::Installer.new(@a2_path).install + + @cmd.options[:args] = [@a2.name] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_match %r|Bulk updating|, out.shift + assert_equal "Nothing to update", out.shift + + assert out.empty?, out.inspect + end + + def test_execute_up_to_date + util_remove_gems + + Gem::Installer.new(@a2_path).install + + @cmd.options[:args] = [] + + use_ui @ui do + @cmd.execute + end + + out = @ui.output.split "\n" + assert_equal "Updating installed gems", out.shift + assert_match %r|Bulk updating|, out.shift + assert_equal "Nothing to update", out.shift + + assert out.empty?, out.inspect + end + + def util_remove_gems + FileUtils.rm_r File.join(@gemhome, 'gems') + FileUtils.rm_r File.join(@gemhome, 'specifications') + end + +end + diff --git a/test/rubygems/test_gem_dependency_installer.rb b/test/rubygems/test_gem_dependency_installer.rb index d2d33fa313..576143904a 100644 --- a/test/rubygems/test_gem_dependency_installer.rb +++ b/test/rubygems/test_gem_dependency_installer.rb @@ -54,8 +54,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a' - inst.install + inst = Gem::DependencyInstaller.new + inst.install 'a' end assert_equal Gem::SourceIndex.new(@a1.full_name => @a1), @@ -70,8 +70,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'b' - inst.install + inst = Gem::DependencyInstaller.new + inst.install 'b' end assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } @@ -84,8 +84,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'b' - inst.install + inst = Gem::DependencyInstaller.new + inst.install 'b' end assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } @@ -102,8 +102,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'f' - inst.install + inst = Gem::DependencyInstaller.new + inst.install 'f' end assert_equal %w[f-2], inst.installed_gems.map { |s| s.full_name } @@ -114,19 +114,49 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a-1.gem' - inst.install + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'a-1.gem' end assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } end + def test_install_local_dependency + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'b-1.gem' + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_local_dependency_installed + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + + inst = nil + + Dir.chdir @tempdir do + Gem::Installer.new('a-1.gem').install + + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'b-1.gem' + end + + assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } + end + def test_install_local_subdir inst = nil - + Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'gems/a-1.gem' - inst.install + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'gems/a-1.gem' end assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } @@ -137,12 +167,11 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a', nil, :env_shebang => true, - :wrappers => true - inst.install + inst = Gem::DependencyInstaller.new :env_shebang => true, :wrappers => true + inst.install 'a' end - assert_match %r|\A#!/usr/bin/env ruby\n|, + assert_match %r|\A#!/usr/bin/env #{Gem::ConfigMap[:RUBY_INSTALL_NAME]}\n|, File.read(File.join(@gemhome, 'bin', 'a_bin')) end @@ -153,8 +182,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'b', nil, :force => true - inst.install + inst = Gem::DependencyInstaller.new :force => true + inst.install 'b' end assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } @@ -165,8 +194,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'b', nil, :ignore_dependencies => true - inst.install + inst = Gem::DependencyInstaller.new :ignore_dependencies => true + inst.install 'b' end assert_equal %w[b-1], inst.installed_gems.map { |s| s.full_name } @@ -179,8 +208,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a', nil, :install_dir => gemhome2 - inst.install + inst = Gem::DependencyInstaller.new :install_dir => gemhome2 + inst.install 'a' end assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } @@ -201,8 +230,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'b', nil, :domain => :both - inst.install + inst = Gem::DependencyInstaller.new :domain => :both + inst.install 'b' end assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } @@ -217,14 +246,34 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal b1_expected, b1.loaded_from end + def test_install_domain_both_no_network + Gem::SourceInfoCache.instance_variable_set :@cache, nil + + @fetcher.data["http://gems.example.com/gems/Marshal.#{@marshal_version}"] = + proc do + raise Gem::RemoteFetcher::FetchError + end + + FileUtils.mv @a1_gem, @tempdir + FileUtils.mv @b1_gem, @tempdir + inst = nil + + Dir.chdir @tempdir do + inst = Gem::DependencyInstaller.new :domain => :both + inst.install 'b' + end + + assert_equal %w[a-1 b-1], inst.installed_gems.map { |s| s.full_name } + end + def test_install_domain_local FileUtils.mv @b1_gem, @tempdir inst = nil Dir.chdir @tempdir do e = assert_raise Gem::InstallError do - inst = Gem::DependencyInstaller.new 'b', nil, :domain => :local - inst.install + inst = Gem::DependencyInstaller.new :domain => :local + inst.install 'b' end assert_equal 'b requires a (>= 0)', e.message end @@ -240,8 +289,43 @@ class TestGemDependencyInstaller < RubyGemTestCase @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data - inst = Gem::DependencyInstaller.new 'a', nil, :domain => :remote - inst.install + inst = Gem::DependencyInstaller.new :domain => :remote + inst.install 'a' + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_remote + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + + inst = Gem::DependencyInstaller.new + + Dir.chdir @tempdir do + inst.install 'a' + end + + assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } + end + + def test_install_remote_dep + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data + + inst = Gem::DependencyInstaller.new + + Dir.chdir @tempdir do + dep = Gem::Dependency.new @a1.name, @a1.version + inst.install dep + end assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } end @@ -266,8 +350,8 @@ class TestGemDependencyInstaller < RubyGemTestCase @fetcher.data["http://gems.example.com/gems/#{a2_o.full_name}.gem"] = a2_o_data - inst = Gem::DependencyInstaller.new 'a', nil, :domain => :remote - inst.install + inst = Gem::DependencyInstaller.new :domain => :remote + inst.install 'a' assert_equal %w[a-1], inst.installed_gems.map { |s| s.full_name } end @@ -278,8 +362,8 @@ class TestGemDependencyInstaller < RubyGemTestCase inst = nil Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a' - inst.install + inst = Gem::DependencyInstaller.new + inst.install 'a' end assert_equal Gem::SourceIndex.new(@a1.full_name => @a1), @@ -290,13 +374,17 @@ class TestGemDependencyInstaller < RubyGemTestCase if defined? OpenSSL then def test_install_security_policy - FileUtils.mv @a1_gem, @cache_dir - FileUtils.mv @b1_gem, @cache_dir + data = File.open(@a1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = data + + data = File.open(@b1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/b-1.gem'] = data + policy = Gem::Security::HighSecurity - inst = Gem::DependencyInstaller.new 'b', nil, :security_policy => policy + inst = Gem::DependencyInstaller.new :security_policy => policy e = assert_raise Gem::Exception do - inst.install + inst.install 'b' end assert_equal 'Unsigned gem', e.message @@ -305,145 +393,48 @@ class TestGemDependencyInstaller < RubyGemTestCase end end - def test_install_wrappers - FileUtils.mv @a1_gem, @cache_dir - inst = Gem::DependencyInstaller.new 'a', :wrappers => true + # Wrappers don't work on mswin + unless win_platform? then + def test_install_no_wrappers + @fetcher.data['http://gems.example.com/gems/a-1.gem'] = read_binary(@a1_gem) - inst.install + inst = Gem::DependencyInstaller.new :wrappers => false + inst.install 'a' - assert_match %r|This file was generated by RubyGems.|, - File.read(File.join(@gemhome, 'bin', 'a_bin')) - end - - def test_install_version - FileUtils.mv @d1_gem, @cache_dir - FileUtils.mv @d2_gem, @cache_dir - inst = Gem::DependencyInstaller.new 'd', '= 1' - - inst.install - - assert_equal %w[d-1], inst.installed_gems.map { |s| s.full_name } - end - - def test_install_version_default - FileUtils.mv @d1_gem, @cache_dir - FileUtils.mv @d2_gem, @cache_dir - inst = Gem::DependencyInstaller.new 'd' - - inst.install - - assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name } - end - - def test_download - a1_data = nil - File.open @a1_gem, 'rb' do |fp| - a1_data = fp.read + assert_no_match(%r|This file was generated by RubyGems.|, + File.read(File.join(@gemhome, 'bin', 'a_bin'))) end - - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data - - inst = Gem::DependencyInstaller.new 'a' - - a1_cache_gem = File.join(@gemhome, 'cache', "#{@a1.full_name}.gem") - assert_equal a1_cache_gem, inst.download(@a1, 'http://gems.example.com') - - assert File.exist?(a1_cache_gem) - end - - def test_download_cached - FileUtils.mv @a1_gem, @cache_dir - - inst = Gem::DependencyInstaller.new 'a' - - assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), - inst.download(@a1, 'http://gems.example.com') - end - - def test_download_local - FileUtils.mv @a1_gem, @tempdir - local_path = File.join @tempdir, "#{@a1.full_name}.gem" - inst = nil - - Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a' - end - - assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), - inst.download(@a1, local_path) end - def test_download_install_dir - a1_data = nil - File.open @a1_gem, 'rb' do |fp| - a1_data = fp.read - end - - @fetcher.data['http://gems.example.com/gems/a-1.gem'] = a1_data - - install_dir = File.join @tempdir, 'more_gems' - - inst = Gem::DependencyInstaller.new 'a', nil, :install_dir => install_dir - - a1_cache_gem = File.join install_dir, 'cache', "#{@a1.full_name}.gem" - assert_equal a1_cache_gem, inst.download(@a1, 'http://gems.example.com') + def test_install_version + data = File.open(@d2_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data - assert File.exist?(a1_cache_gem) - end + data = File.open(@d1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data - unless win_platform? then # File.chmod doesn't work - def test_download_local_read_only - FileUtils.mv @a1_gem, @tempdir - local_path = File.join @tempdir, "#{@a1.full_name}.gem" - inst = nil - File.chmod 0555, File.join(@gemhome, 'cache') + inst = Gem::DependencyInstaller.new - Dir.chdir @tempdir do - inst = Gem::DependencyInstaller.new 'a' - end + inst.install 'd', '= 1' - assert_equal File.join(@tempdir, "#{@a1.full_name}.gem"), - inst.download(@a1, local_path) - ensure - File.chmod 0755, File.join(@gemhome, 'cache') - end + assert_equal %w[d-1], inst.installed_gems.map { |s| s.full_name } end - def test_download_platform_legacy - original_platform = 'old-platform' - - e1, e1_gem = util_gem 'e', '1' do |s| - s.platform = Gem::Platform::CURRENT - s.instance_variable_set :@original_platform, original_platform - end - - e1_data = nil - File.open e1_gem, 'rb' do |fp| - e1_data = fp.read - end - - @fetcher.data["http://gems.example.com/gems/e-1-#{original_platform}.gem"] = e1_data - - inst = Gem::DependencyInstaller.new 'a' - - e1_cache_gem = File.join(@gemhome, 'cache', "#{e1.full_name}.gem") - assert_equal e1_cache_gem, inst.download(e1, 'http://gems.example.com') - - assert File.exist?(e1_cache_gem) - end + def test_install_version_default + data = File.open(@d2_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-2.gem'] = data - def test_download_unsupported - inst = Gem::DependencyInstaller.new 'a' + data = File.open(@d1_gem, 'rb') { |f| f.read } + @fetcher.data['http://gems.example.com/gems/d-1.gem'] = data - e = assert_raise Gem::InstallError do - inst.download @a1, 'ftp://gems.rubyforge.org' - end + inst = Gem::DependencyInstaller.new + inst.install 'd' - assert_equal 'unsupported URI scheme ftp', e.message + assert_equal %w[d-2], inst.installed_gems.map { |s| s.full_name } end def test_find_gems_gems_with_sources - inst = Gem::DependencyInstaller.new 'a' + inst = Gem::DependencyInstaller.new dep = Gem::Dependency.new 'b', '>= 0' assert_equal [[@b1, 'http://gems.example.com']], @@ -452,7 +443,7 @@ class TestGemDependencyInstaller < RubyGemTestCase def test_find_gems_with_sources_local FileUtils.mv @a1_gem, @tempdir - inst = Gem::DependencyInstaller.new 'b' + inst = Gem::DependencyInstaller.new dep = Gem::Dependency.new 'a', '>= 0' gems = nil @@ -462,7 +453,7 @@ class TestGemDependencyInstaller < RubyGemTestCase assert_equal 2, gems.length remote = gems.first - assert_equal @a1, remote.first, 'remote spec' + assert_equal 'a-1', remote.first.full_name, 'remote spec' assert_equal 'http://gems.example.com', remote.last, 'remote path' local = gems.last @@ -472,7 +463,9 @@ class TestGemDependencyInstaller < RubyGemTestCase end def test_gather_dependencies - inst = Gem::DependencyInstaller.new 'b' + inst = Gem::DependencyInstaller.new + inst.find_spec_by_name_and_version 'b' + inst.gather_dependencies assert_equal %w[a-1 b-1], inst.gems_to_install.map { |s| s.full_name } end @@ -488,7 +481,9 @@ class TestGemDependencyInstaller < RubyGemTestCase @fetcher.uri = URI.parse 'http://gems.example.com' @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml - inst = Gem::DependencyInstaller.new 'c' + inst = Gem::DependencyInstaller.new + inst.find_spec_by_name_and_version 'c' + inst.gather_dependencies assert_equal %w[b-2 c-1], inst.gems_to_install.map { |s| s.full_name } end @@ -496,14 +491,18 @@ class TestGemDependencyInstaller < RubyGemTestCase def test_gather_dependencies_platform_alternate util_set_arch 'cpu-my_platform1' - inst = Gem::DependencyInstaller.new 'w' + inst = Gem::DependencyInstaller.new + inst.find_spec_by_name_and_version 'w' + inst.gather_dependencies assert_equal %w[x-1-cpu-my_platform-1 w-1], inst.gems_to_install.map { |s| s.full_name } end def test_gather_dependencies_platform_bump - inst = Gem::DependencyInstaller.new 'z' + inst = Gem::DependencyInstaller.new + inst.find_spec_by_name_and_version 'z' + inst.gather_dependencies assert_equal %w[y-1 z-1], inst.gems_to_install.map { |s| s.full_name } end @@ -518,27 +517,11 @@ class TestGemDependencyInstaller < RubyGemTestCase @fetcher.uri = URI.parse 'http://gems.example.com' @fetcher.data['http://gems.example.com/gems/yaml'] = si.to_yaml - inst = Gem::DependencyInstaller.new 'e' + inst = Gem::DependencyInstaller.new + inst.find_spec_by_name_and_version 'e' + inst.gather_dependencies assert_equal %w[d-1 e-1], inst.gems_to_install.map { |s| s.full_name } end - - def util_gem(name, version, &block) - spec = quick_gem(name, version, &block) - - util_build_gem spec - - cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem" - FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"), - cache_file - FileUtils.rm File.join(@gemhome, 'specifications', - "#{spec.full_name}.gemspec") - - spec.loaded_from = nil - spec.loaded = false - - [spec, cache_file] - end - end diff --git a/test/rubygems/test_gem_ext_configure_builder.rb b/test/rubygems/test_gem_ext_configure_builder.rb index 25aa7412aa..d3d0efb489 100644 --- a/test/rubygems/test_gem_ext_configure_builder.rb +++ b/test/rubygems/test_gem_ext_configure_builder.rb @@ -47,16 +47,19 @@ class TestGemExtConfigureBuilder < RubyGemTestCase end end - expected = %r|configure failed: + shell_error_msg = %r{(\./configure: No such file or directory)|(Can't open \./configure)} + sh_prefix_configure = "sh ./configure --prefix=" + + expected = %r(configure failed: -sh \./configure --prefix=#{Regexp.escape @dest_path} -.*?: \./configure: No such file or directory -| +#{Regexp.escape sh_prefix_configure}#{Regexp.escape @dest_path} +.*?: #{shell_error_msg} +) assert_match expected, error.message - assert_equal "sh ./configure --prefix=#{@dest_path}", output.shift - assert_match %r|\./configure: No such file or directory\n|, output.shift + assert_equal "#{sh_prefix_configure}#{@dest_path}", output.shift + assert_match %r(#{shell_error_msg}\n), output.shift assert_equal true, output.empty? end diff --git a/test/rubygems/test_gem_format.rb b/test/rubygems/test_gem_format.rb index 35eee6bae2..4014acfed9 100644 --- a/test/rubygems/test_gem_format.rb +++ b/test/rubygems/test_gem_format.rb @@ -22,7 +22,7 @@ class TestGemFormat < RubyGemTestCase gems = Dir[File.join(@gemhome, 'cache', '*.gem')] - names = [@a1, @a2, @b2, @c1_2, @pl1].map do |spec| + names = [@a1, @a2, @a_evil9, @b2, @c1_2, @pl1].map do |spec| spec.original_name end diff --git a/test/rubygems/test_gem_indexer.rb b/test/rubygems/test_gem_indexer.rb index 9eb78500c9..12469b5d57 100644 --- a/test/rubygems/test_gem_indexer.rb +++ b/test/rubygems/test_gem_indexer.rb @@ -53,6 +53,11 @@ class TestGemIndexer < RubyGemTestCase assert_indexed quickdir, "index" assert_indexed quickdir, "index.rz" + assert_indexed quickdir, "latest_index" + assert_indexed quickdir, "latest_index.rz" + + assert_no_match %r|a-1|, File.read(File.join(quickdir, 'latest_index')) + assert_indexed quickdir, "#{@a1.full_name}.gemspec.rz" assert_indexed quickdir, "#{@a2.full_name}.gemspec.rz" assert_indexed quickdir, "#{@b2.full_name}.gemspec.rz" @@ -74,8 +79,8 @@ class TestGemIndexer < RubyGemTestCase end expected = <<-EOF -Generating index for 5 gems in #{@tempdir} -..... +Generating index for 6 gems in #{@tempdir} +...... Loaded all gems Generating master indexes (this may take a while) EOF diff --git a/test/rubygems/test_gem_installer.rb b/test/rubygems/test_gem_installer.rb index 442ed6cfc3..f7d36c66ed 100644 --- a/test/rubygems/test_gem_installer.rb +++ b/test/rubygems/test_gem_installer.rb @@ -4,63 +4,10 @@ # See LICENSE.txt for permissions. #++ -require 'test/unit' -require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities') -require 'rubygems/installer' - -class Gem::Installer - attr_accessor :gem_dir - - attr_writer :format - attr_writer :gem_home - attr_writer :env_shebang - attr_writer :ignore_dependencies - attr_writer :format_executable - attr_writer :security_policy - attr_writer :spec - attr_writer :wrappers -end - -class TestGemInstaller < RubyGemTestCase - - def setup - super - - @spec = quick_gem "a" - @gem = File.join @tempdir, "#{@spec.full_name}.gem" - - util_build_gem @spec - FileUtils.mv File.join(@gemhome, 'cache', "#{@spec.full_name}.gem"), - @tempdir - - @installer = Gem::Installer.new @gem - @installer.gem_dir = util_gem_dir - @installer.gem_home = @gemhome - @installer.spec = @spec - end - - def util_gem_dir(version = '2') - File.join @gemhome, "gems", "a-#{version}" # HACK - end - - def util_gem_bindir(version = '2') - File.join util_gem_dir(version), "bin" - end +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_installer_test_case') - def util_inst_bindir - File.join @gemhome, "bin" - end - - def util_make_exec(version = '2', shebang = "#!/usr/bin/ruby") - @spec.executables = ["my_exec"] - - FileUtils.mkdir_p util_gem_bindir(version) - exec_file = @installer.formatted_program_filename "my_exec" - exec_path = File.join util_gem_bindir(version), exec_file - File.open exec_path, 'w' do |f| - f.puts shebang - end - end +class TestGemInstaller < GemInstallerTestCase def test_app_script_text util_make_exec '2', '' @@ -162,7 +109,7 @@ load 'my_exec' @installer.gem_dir = '/nonexistent' expanded_gem_dir = @installer.send(:expand_and_validate_gem_dir) if win_platform? - expected = File.join(Config::CONFIG['bindir'][0..2], 'nonexistent').downcase + expected = File.expand_path('/nonexistent').downcase expanded_gem_dir = expanded_gem_dir.downcase else expected = '/nonexistent' @@ -768,7 +715,7 @@ load 'my_exec' @installer.env_shebang = true shebang = @installer.shebang 'my_exec' - assert_equal "#!/usr/bin/env ruby", shebang + assert_equal "#!/usr/bin/env #{Gem::ConfigMap[:RUBY_INSTALL_NAME]}", shebang end def test_shebang_nested @@ -855,31 +802,5 @@ load 'my_exec' File.join @gemhome, 'cache', "#{spec.full_name}.gem" end - def util_setup_gem - @spec.files = File.join('lib', 'code.rb') - @spec.executables << 'executable' - @spec.extensions << File.join('ext', 'a', 'mkrf_conf.rb') - - Dir.chdir @tempdir do - FileUtils.mkdir_p 'bin' - FileUtils.mkdir_p 'lib' - FileUtils.mkdir_p File.join('ext', 'a') - File.open File.join('bin', 'executable'), 'w' do |f| f.puts '1' end - File.open File.join('lib', 'code.rb'), 'w' do |f| f.puts '1' end - File.open File.join('ext', 'a', 'mkrf_conf.rb'), 'w' do |f| - f << <<-EOF - File.open 'Rakefile', 'w' do |rf| rf.puts "task :default" end - EOF - end - - use_ui @ui do - FileUtils.rm @gem - Gem::Builder.new(@spec).build - end - end - - @installer = Gem::Installer.new @gem - end - end diff --git a/test/rubygems/test_gem_package_tar_header.rb b/test/rubygems/test_gem_package_tar_header.rb new file mode 100644 index 0000000000..9b7708dca8 --- /dev/null +++ b/test/rubygems/test_gem_package_tar_header.rb @@ -0,0 +1,137 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_package_tar_test_case') +require 'rubygems/package' + +class TestGemPackageTarHeader < TarTestCase + + def setup + super + + header = { + :name => 'x', + :mode => 0644, + :uid => 1000, + :gid => 10000, + :size => 100, + :mtime => 12345, + :typeflag => '0', + :linkname => 'link', + :uname => 'user', + :gname => 'group', + :devmajor => 1, + :devminor => 2, + :prefix => 'y', + } + + @tar_header = Gem::Package::TarHeader.new header + end + + def test_self_from + io = TempIO.new @tar_header.to_s + + new_header = Gem::Package::TarHeader.from io + + assert_headers_equal @tar_header, new_header + end + + def test_initialize + assert_equal '', @tar_header.checksum, 'checksum' + assert_equal 1, @tar_header.devmajor, 'devmajor' + assert_equal 2, @tar_header.devminor, 'devminor' + assert_equal 10000, @tar_header.gid, 'gid' + assert_equal 'group', @tar_header.gname, 'gname' + assert_equal 'link', @tar_header.linkname, 'linkname' + assert_equal 'ustar', @tar_header.magic, 'magic' + assert_equal 0644, @tar_header.mode, 'mode' + assert_equal 12345, @tar_header.mtime, 'mtime' + assert_equal 'x', @tar_header.name, 'name' + assert_equal 'y', @tar_header.prefix, 'prefix' + assert_equal 100, @tar_header.size, 'size' + assert_equal '0', @tar_header.typeflag, 'typeflag' + assert_equal 1000, @tar_header.uid, 'uid' + assert_equal 'user', @tar_header.uname, 'uname' + assert_equal '00', @tar_header.version, 'version' + + assert !@tar_header.empty?, 'empty' + end + + def test_initialize_bad + assert_raises ArgumentError do + Gem::Package::TarHeader.new :name => '', :size => '', :mode => '' + end + + assert_raises ArgumentError do + Gem::Package::TarHeader.new :name => '', :size => '', :prefix => '' + end + + assert_raises ArgumentError do + Gem::Package::TarHeader.new :name => '', :prefix => '', :mode => '' + end + + assert_raises ArgumentError do + Gem::Package::TarHeader.new :prefix => '', :size => '', :mode => '' + end + end + + def test_empty_eh + assert !@tar_header.empty? + + @tar_header = Gem::Package::TarHeader.new :name => 'x', :prefix => '', + :mode => 0, :size => 0, + :empty => true + + assert @tar_header.empty? + end + + def test_equals2 + assert_equal @tar_header, @tar_header + assert_equal @tar_header, @tar_header.dup + end + + def test_to_s + expected = <<-EOF.split("\n").join +x\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\0000000644\0000001750\0000023420\00000000000144\00000000030071 +\000012467\000 0link\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000ustar\00000user\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +group\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\0000000001\0000000002\000y\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +\000\000\000\000\000\000\000\000\000\000 + EOF + + assert_headers_equal expected, @tar_header + end + + def test_update_checksum + assert_equal '', @tar_header.checksum + + @tar_header.update_checksum + + assert_equal '012467', @tar_header.checksum + end + +end + diff --git a/test/rubygems/test_gem_package_tar_input.rb b/test/rubygems/test_gem_package_tar_input.rb new file mode 100644 index 0000000000..279026b149 --- /dev/null +++ b/test/rubygems/test_gem_package_tar_input.rb @@ -0,0 +1,119 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_package_tar_test_case') +require 'rubygems/package/tar_input' + +class TestGemPackageTarInput < TarTestCase + + # Sometimes the setgid bit doesn't take. Don't know if this is a problem on + # all systems, or just some. But for now, we will ignore it in the tests. + SETGID_BIT = 02000 + + def setup + super + + inner_tar = tar_file_header("bla", "", 0612, 10) + inner_tar += "0123456789" + "\0" * 502 + inner_tar += tar_file_header("foo", "", 0636, 5) + inner_tar += "01234" + "\0" * 507 + inner_tar += tar_dir_header("__dir__", "", 0600) + inner_tar += "\0" * 1024 + str = TempIO.new + + begin + os = Zlib::GzipWriter.new str + os.write inner_tar + ensure + os.finish + end + + str.rewind + + @file = File.join @tempdir, 'bla.tar' + + File.open @file, 'wb' do |f| + f.write tar_file_header("data.tar.gz", "", 0644, str.string.size) + f.write str.string + f.write "\0" * ((512 - (str.string.size % 512)) % 512 ) + + @spec = Gem::Specification.new do |spec| + spec.author = "Mauricio :)" + end + + meta = @spec.to_yaml + + f.write tar_file_header("metadata", "", 0644, meta.size) + f.write meta + "\0" * (1024 - meta.size) + f.write "\0" * 1024 + end + + @entry_names = %w{bla foo __dir__} + @entry_sizes = [10, 5, 0] + #FIXME: are these modes system dependent? + @entry_modes = [0100612, 0100636, 040600] + @entry_files = %W[#{@tempdir}/bla #{@tempdir}/foo] + @entry_contents = %w[0123456789 01234] + end + + def test_each_works + open @file, 'rb' do |io| + Gem::Package::TarInput.open io do |tar_input| + count = 0 + + tar_input.each_with_index do |entry, i| + count = i + + assert_kind_of Gem::Package::TarReader::Entry, entry + assert_equal @entry_names[i], entry.header.name + assert_equal @entry_sizes[i], entry.header.size + end + + assert_equal 2, count + + assert_equal @spec, tar_input.metadata + end + end + end + + def test_extract_entry_works + open @file, 'rb' do |io| + Gem::Package::TarInput.open io do |tar_input| + assert_equal @spec, tar_input.metadata + + count = 0 + + tar_input.each_with_index do |entry, i| + count = i + tar_input.extract_entry @tempdir, entry + name = File.join @tempdir, entry.header.name + + if entry.directory? + assert File.dir?(name) + else + assert File.file?(name) + assert_equal @entry_sizes[i], File.stat(name).size + #FIXME: win32? !! + end + + unless Gem.win_platform? then + assert_equal @entry_modes[i], File.stat(name).mode & (~SETGID_BIT) + end + end + + assert_equal 2, count + end + end + + @entry_files.each_with_index do |x, i| + assert File.file?(x) + assert_equal @entry_contents[i], File.read_b(x) + end + end + +end + diff --git a/test/rubygems/test_gem_package_tar_output.rb b/test/rubygems/test_gem_package_tar_output.rb new file mode 100644 index 0000000000..06dbb1a4da --- /dev/null +++ b/test/rubygems/test_gem_package_tar_output.rb @@ -0,0 +1,104 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_package_tar_test_case') +require 'rubygems/package/tar_output' + +class TestGemPackageTarOutput < TarTestCase + + def setup + super + + @file = File.join @tempdir, 'bla2.tar' + end + + def test_self_open + open @file, 'wb' do |tar_io| + Gem::Package::TarOutput.open tar_io do |tar_writer| + tar_writer.add_file_simple 'README', 0, 17 do |io| + io.write "This is a README\n" + end + + tar_writer.metadata = "This is some metadata\n" + end + end + + files = util_extract + + name, data = files.shift + assert_equal 'data.tar.gz', name + + gz = Zlib::GzipReader.new StringIO.new(data) + + Gem::Package::TarReader.new gz do |tar_reader| + tar_reader.each do |entry| + assert_equal 'README', entry.full_name + assert_equal "This is a README\n", entry.read + end + end + + gz.close + + name, data = files.shift + assert_equal 'metadata.gz', name + + gz = Zlib::GzipReader.new StringIO.new(data) + assert_equal "This is some metadata\n", gz.read + + assert files.empty? + ensure + gz.close if gz + end + + if defined? OpenSSL then + def test_self_open_signed + signer = Gem::Security::Signer.new @private_key, [@public_cert] + + open @file, 'wb' do |tar_io| + Gem::Package::TarOutput.open tar_io, signer do |tar_writer| + tar_writer.add_file_simple 'README', 0, 17 do |io| + io.write "This is a README\n" + end + + tar_writer.metadata = "This is some metadata\n" + end + end + + files = util_extract + + name, data = files.shift + assert_equal 'data.tar.gz', name + + name, data = files.shift + assert_equal 'metadata.gz', name + + name, data = files.shift + assert_equal 'data.tar.gz.sig', name + + name, data = files.shift + assert_equal 'metadata.gz.sig', name + + assert files.empty? + end + end + + def util_extract + files = [] + + open @file, 'rb' do |io| + Gem::Package::TarReader.new io do |tar_reader| + tar_reader.each do |entry| + files << [entry.full_name, entry.read] + end + end + end + + files + end + +end + diff --git a/test/rubygems/test_gem_package_tar_reader.rb b/test/rubygems/test_gem_package_tar_reader.rb new file mode 100644 index 0000000000..6962088878 --- /dev/null +++ b/test/rubygems/test_gem_package_tar_reader.rb @@ -0,0 +1,53 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_package_tar_test_case') +require 'rubygems/package' + +class TestGemPackageTarReader < TarTestCase + + def test_each_entry + tar = tar_dir_header "foo", "bar", 0 + tar << tar_file_header("bar", "baz", 0, 0) + + io = TempIO.new tar + + entries = 0 + + Gem::Package::TarReader.new io do |tar_reader| + tar_reader.each_entry do |entry| + assert_kind_of Gem::Package::TarReader::Entry, entry + + entries += 1 + end + end + + assert_equal 2, entries + end + + def test_rewind + content = ('a'..'z').to_a.join(" ") + + str = tar_file_header("lib/foo", "", 010644, content.size) + content + + "\0" * (512 - content.size) + str << "\0" * 1024 + + Gem::Package::TarReader.new(TempIO.new(str)) do |tar_reader| + 3.times do + tar_reader.rewind + i = 0 + tar_reader.each_entry do |entry| + assert_equal(content, entry.read) + i += 1 + end + assert_equal(1, i) + end + end + end + +end + diff --git a/test/rubygems/test_gem_package_tar_reader_entry.rb b/test/rubygems/test_gem_package_tar_reader_entry.rb new file mode 100644 index 0000000000..7e25143a85 --- /dev/null +++ b/test/rubygems/test_gem_package_tar_reader_entry.rb @@ -0,0 +1,116 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_package_tar_test_case') +require 'rubygems/package' + +class TestGemPackageTarReaderEntry < TarTestCase + + def setup + super + + @contents = ('a'..'z').to_a.join * 100 + + @tar = '' + @tar << tar_file_header("lib/foo", "", 0, @contents.size) + @tar << @contents + @tar << "\0" * (512 - (@tar.size % 512)) + + @entry = util_entry @tar + end + + def test_bytes_read + assert_equal 0, @entry.bytes_read + + @entry.getc + + assert_equal 1, @entry.bytes_read + end + + def test_close + @entry.close + + assert @entry.bytes_read + + e = assert_raise IOError do @entry.eof? end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raise IOError do @entry.getc end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raise IOError do @entry.pos end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raise IOError do @entry.read end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + + e = assert_raise IOError do @entry.rewind end + assert_equal 'closed Gem::Package::TarReader::Entry', e.message + end + + def test_closed_eh + @entry.close + + assert @entry.closed? + end + + def test_eof_eh + @entry.read + + assert @entry.eof? + end + + def test_full_name + assert_equal 'lib/foo', @entry.full_name + end + + def test_getc + assert_equal ?a, @entry.getc + end + + def test_directory_eh + assert_equal false, @entry.directory? + assert_equal true, util_dir_entry.directory? + end + + def test_file_eh + assert_equal true, @entry.file? + assert_equal false, util_dir_entry.file? + end + + def test_pos + assert_equal 0, @entry.pos + + @entry.getc + + assert_equal 1, @entry.pos + end + + def test_read + assert_equal @contents, @entry.read + end + + def test_read_big + assert_equal @contents, @entry.read(@contents.size * 2) + end + + def test_read_small + assert_equal @contents[0...100], @entry.read(100) + end + + def test_rewind + char = @entry.getc + + @entry.rewind + + assert_equal 0, @entry.pos + + assert_equal char, @entry.getc + end + +end + diff --git a/test/rubygems/test_gem_package_tar_writer.rb b/test/rubygems/test_gem_package_tar_writer.rb new file mode 100644 index 0000000000..e066c2967f --- /dev/null +++ b/test/rubygems/test_gem_package_tar_writer.rb @@ -0,0 +1,151 @@ +#-- +# Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. +# All rights reserved. +# See LICENSE.txt for permissions. +#++ + +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_package_tar_test_case') +require 'rubygems/package/tar_writer' + +class TestTarWriter < TarTestCase + + def setup + super + + @data = 'abcde12345' + @io = TempIO.new + @tar_writer = Gem::Package::TarWriter.new @io + end + + def teardown + @tar_writer.close unless @tar_writer.closed? + + super + end + + def test_add_file + @tar_writer.add_file 'x', 0644 do |f| f.write 'a' * 10 end + + assert_headers_equal(tar_file_header('x', '', 0644, 10), + @io.string[0, 512]) + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_simple + @tar_writer.add_file_simple 'x', 0644, 10 do |io| io.write "a" * 10 end + + assert_headers_equal(tar_file_header('x', '', 0644, 10), + @io.string[0, 512]) + + assert_equal "aaaaaaaaaa#{"\0" * 502}", @io.string[512, 512] + assert_equal 1024, @io.pos + end + + def test_add_file_simple_padding + @tar_writer.add_file_simple 'x', 0, 100 + + assert_headers_equal tar_file_header('x', '', 0, 100), + @io.string[0, 512] + + assert_equal "\0" * 512, @io.string[512, 512] + end + + def test_add_file_simple_data + @tar_writer.add_file_simple("lib/foo/bar", 0, 10) { |f| f.write @data } + @tar_writer.flush + + assert_equal @data + ("\0" * (512-@data.size)), + @io.string[512, 512] + end + + def test_add_file_simple_size + assert_raise Gem::Package::TarWriter::FileOverflow do + @tar_writer.add_file_simple("lib/foo/bar", 0, 10) do |io| + io.write "1" * 11 + end + end + end + + def test_add_file_unseekable + assert_raise Gem::Package::NonSeekableIO do + Gem::Package::TarWriter.new(Object.new).add_file 'x', 0 + end + end + + def test_close + @tar_writer.close + + assert_equal "\0" * 1024, @io.string + + e = assert_raise IOError do + @tar_writer.close + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raise IOError do + @tar_writer.flush + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raise IOError do + @tar_writer.add_file 'x', 0 + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raise IOError do + @tar_writer.add_file_simple 'x', 0, 0 + end + assert_equal 'closed Gem::Package::TarWriter', e.message + + e = assert_raise IOError do + @tar_writer.mkdir 'x', 0 + end + assert_equal 'closed Gem::Package::TarWriter', e.message + end + + def test_mkdir + @tar_writer.mkdir 'foo', 0644 + + assert_headers_equal tar_dir_header('foo', '', 0644), + @io.string[0, 512] + assert_equal 512, @io.pos + end + + def test_split_name + assert_equal ['b' * 100, 'a' * 155], + @tar_writer.split_name("#{'a' * 155}/#{'b' * 100}") + + assert_equal ["#{'qwer/' * 19}bla", 'a' * 151], + @tar_writer.split_name("#{'a' * 151}/#{'qwer/' * 19}bla") + end + + def test_split_name_too_long_name + name = File.join 'a', 'b' * 100 + assert_equal ['b' * 100, 'a'], @tar_writer.split_name(name) + + assert_raise Gem::Package::TooLongFileName do + name = File.join 'a', 'b' * 101 + @tar_writer.split_name name + end + end + + def test_split_name_too_long_prefix + name = File.join 'a' * 155, 'b' + assert_equal ['b', 'a' * 155], @tar_writer.split_name(name) + + assert_raise Gem::Package::TooLongFileName do + name = File.join 'a' * 156, 'b' + @tar_writer.split_name name + end + end + + def test_split_name_too_long_total + assert_raise Gem::Package::TooLongFileName do + @tar_writer.split_name 'a' * 257 + end + end + +end + diff --git a/test/rubygems/test_gem_remote_fetcher.rb b/test/rubygems/test_gem_remote_fetcher.rb index 5ffaed24e3..1ac71aabc2 100644 --- a/test/rubygems/test_gem_remote_fetcher.rb +++ b/test/rubygems/test_gem_remote_fetcher.rb @@ -97,6 +97,13 @@ gems: @server_uri = base_server_uri + "/yaml" @server_z_uri = base_server_uri + "/yaml.Z" + # REFACTOR: copied from test_gem_dependency_installer.rb + @gems_dir = File.join @tempdir, 'gems' + @cache_dir = File.join @gemhome, 'cache' + FileUtils.mkdir @gems_dir + + @a1, @a1_gem = util_gem 'a', '1' do |s| s.executables << 'a_bin' end + Gem::RemoteFetcher.instance_variable_set :@fetcher, nil end @@ -156,6 +163,140 @@ gems: end end + def util_fuck_with_fetcher data, blow = false + fetcher = Gem::RemoteFetcher.fetcher + fetcher.instance_variable_set :@test_data, data + + unless blow then + def fetcher.fetch_path arg + @test_arg = arg + @test_data + end + else + def fetcher.fetch_path arg + # OMG I'm such an ass + class << self; remove_method :fetch_path; end + def self.fetch_path arg + @test_arg = arg + @test_data + end + + raise Gem::RemoteFetcher::FetchError, "haha!" + end + end + + fetcher + end + + def test_download + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + a1_cache_gem = File.join(@gemhome, 'cache', "#{@a1.full_name}.gem") + assert_equal a1_cache_gem, fetcher.download(@a1, 'http://gems.example.com') + assert_equal("http://gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(a1_cache_gem) + end + + def test_download_cached + FileUtils.mv @a1_gem, @cache_dir + + inst = Gem::RemoteFetcher.fetcher + + assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), + inst.download(@a1, 'http://gems.example.com') + end + + def test_download_local + FileUtils.mv @a1_gem, @tempdir + local_path = File.join @tempdir, "#{@a1.full_name}.gem" + inst = nil + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + assert_equal File.join(@gemhome, 'cache', "#{@a1.full_name}.gem"), + inst.download(@a1, local_path) + end + + def test_download_install_dir + a1_data = nil + File.open @a1_gem, 'rb' do |fp| + a1_data = fp.read + end + + fetcher = util_fuck_with_fetcher a1_data + + install_dir = File.join @tempdir, 'more_gems' + + a1_cache_gem = File.join install_dir, 'cache', "#{@a1.full_name}.gem" + actual = fetcher.download(@a1, 'http://gems.example.com', install_dir) + + assert_equal a1_cache_gem, actual + assert_equal("http://gems.example.com/gems/a-1.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + + assert File.exist?(a1_cache_gem) + end + + unless win_platform? then # File.chmod doesn't work + def test_download_local_read_only + FileUtils.mv @a1_gem, @tempdir + local_path = File.join @tempdir, "#{@a1.full_name}.gem" + inst = nil + File.chmod 0555, File.join(@gemhome, 'cache') + + Dir.chdir @tempdir do + inst = Gem::RemoteFetcher.fetcher + end + + assert_equal File.join(@tempdir, "#{@a1.full_name}.gem"), + inst.download(@a1, local_path) + ensure + File.chmod 0755, File.join(@gemhome, 'cache') + end + end + + def test_download_platform_legacy + original_platform = 'old-platform' + + e1, e1_gem = util_gem 'e', '1' do |s| + s.platform = Gem::Platform::CURRENT + s.instance_variable_set :@original_platform, original_platform + end + + e1_data = nil + File.open e1_gem, 'rb' do |fp| + e1_data = fp.read + end + + fetcher = util_fuck_with_fetcher e1_data, :blow_chunks + + e1_cache_gem = File.join(@gemhome, 'cache', "#{e1.full_name}.gem") + + assert_equal e1_cache_gem, fetcher.download(e1, 'http://gems.example.com') + + assert_equal("http://gems.example.com/gems/#{e1.original_name}.gem", + fetcher.instance_variable_get(:@test_arg).to_s) + assert File.exist?(e1_cache_gem) + end + + def test_download_unsupported + inst = Gem::RemoteFetcher.fetcher + + e = assert_raise Gem::InstallError do + inst.download @a1, 'ftp://gems.rubyforge.org' + end + + assert_equal 'unsupported URI scheme ftp', e.message + end + def test_explicit_proxy use_ui @ui do fetcher = Gem::RemoteFetcher.new @proxy_uri @@ -232,22 +373,6 @@ gems: assert_equal 'EOFError: EOFError reading uri', e.message end - def test_fetch_path_open_uri_http_error - fetcher = Gem::RemoteFetcher.new nil - - def fetcher.open_uri_or_path(uri) - io = StringIO.new 'went boom' - err = OpenURI::HTTPError.new 'error', io - raise err - end - - e = assert_raise Gem::RemoteFetcher::FetchError do - fetcher.fetch_path 'uri' - end - - assert_equal "OpenURI::HTTPError: error reading uri\n\twent boom", e.message - end - def test_fetch_path_socket_error fetcher = Gem::RemoteFetcher.new nil @@ -324,6 +449,53 @@ gems: end end + def test_open_uri_or_path + fetcher = Gem::RemoteFetcher.new nil + + conn = Object.new + def conn.started?() true end + def conn.request(req) + unless defined? @requested then + @requested = true + res = Net::HTTPRedirection.new nil, 301, nil + res.add_field 'Location', 'http://gems.example.com/real_path' + res + else + res = Net::HTTPOK.new nil, 200, nil + def res.body() 'real_path' end + res + end + end + + conn = { 'gems.example.com:80' => conn } + fetcher.instance_variable_set :@connections, conn + + fetcher.send :open_uri_or_path, 'http://gems.example.com/redirect' do |io| + assert_equal 'real_path', io.read + end + end + + def test_open_uri_or_path_limited_redirects + fetcher = Gem::RemoteFetcher.new nil + + conn = Object.new + def conn.started?() true end + def conn.request(req) + res = Net::HTTPRedirection.new nil, 301, nil + res.add_field 'Location', 'http://gems.example.com/redirect' + res + end + + conn = { 'gems.example.com:80' => conn } + fetcher.instance_variable_set :@connections, conn + + e = assert_raise Gem::RemoteFetcher::FetchError do + fetcher.send :open_uri_or_path, 'http://gems.example.com/redirect' + end + + assert_equal 'too many redirects', e.message + end + def test_zip use_ui @ui do self.class.enable_zip = true diff --git a/test/rubygems/test_gem_source_index.rb b/test/rubygems/test_gem_source_index.rb index 8fc8449814..74aa91d63e 100644 --- a/test/rubygems/test_gem_source_index.rb +++ b/test/rubygems/test_gem_source_index.rb @@ -36,7 +36,8 @@ class TestGemSourceIndex < RubyGemTestCase use_ui @ui do fetched_index = @source_index.fetch_bulk_index @uri - assert_equal [@gem1.full_name, @gem4.full_name, @gem2.full_name].sort, + assert_equal [@a1.full_name, @a2.full_name, @a_evil9.full_name, + @c1_2.full_name].sort, fetched_index.gems.map { |n,s| n }.sort end @@ -82,7 +83,8 @@ class TestGemSourceIndex < RubyGemTestCase use_ui @ui do fetched_index = @source_index.fetch_bulk_index @uri - assert_equal [@gem1.full_name, @gem4.full_name, @gem2.full_name].sort, + assert_equal [@a1.full_name, @a2.full_name, @a_evil9.full_name, + @c1_2.full_name].sort, fetched_index.gems.map { |n,s| n }.sort end @@ -105,7 +107,8 @@ class TestGemSourceIndex < RubyGemTestCase use_ui @ui do fetched_index = @source_index.fetch_bulk_index @uri - assert_equal [@gem1.full_name, @gem4.full_name, @gem2.full_name].sort, + assert_equal [@a1.full_name, @a2.full_name, @a_evil9.full_name, + @c1_2.full_name].sort, fetched_index.gems.map { |n,s| n }.sort end @@ -123,7 +126,8 @@ class TestGemSourceIndex < RubyGemTestCase util_setup_bulk_fetch false use_ui @ui do fetched_index = @source_index.fetch_bulk_index @uri - assert_equal [@gem1.full_name, @gem4.full_name, @gem2.full_name].sort, + assert_equal [@a1.full_name, @a2.full_name, @a_evil9.full_name, + @c1_2.full_name].sort, fetched_index.gems.map { |n,s| n }.sort end @@ -136,11 +140,32 @@ class TestGemSourceIndex < RubyGemTestCase end def test_fetch_quick_index - quick_index = util_zip @gem_names - @fetcher.data["#{@gem_repo}/quick/index.rz"] = quick_index + index = util_zip @gem_names + latest_index = util_zip [@a2.full_name, @b2.full_name].join("\n") + + @fetcher.data["#{@gem_repo}/quick/index.rz"] = index + @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = latest_index + + quick_index = @source_index.fetch_quick_index @uri, false + assert_equal [@a2.full_name, @b2.full_name].sort, + quick_index.sort + + paths = @fetcher.paths + + assert_equal "#{@gem_repo}/quick/latest_index.rz", paths.shift + + assert paths.empty?, paths.join(', ') + end + + def test_fetch_quick_index_all + index = util_zip @gem_names + latest_index = util_zip [@a2.full_name, @b2.full_name].join("\n") + + @fetcher.data["#{@gem_repo}/quick/index.rz"] = index + @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = latest_index - quick_index = @source_index.fetch_quick_index @uri - assert_equal [@gem1.full_name, @gem4.full_name, @gem2.full_name].sort, + quick_index = @source_index.fetch_quick_index @uri, true + assert_equal [@a1.full_name, @a2.full_name, @b2.full_name].sort, quick_index.sort paths = @fetcher.paths @@ -155,7 +180,7 @@ class TestGemSourceIndex < RubyGemTestCase proc { raise Exception } e = assert_raise Gem::OperationNotSupportedError do - @source_index.fetch_quick_index @uri + @source_index.fetch_quick_index @uri, true end assert_equal 'No quick index found: Exception', e.message @@ -167,41 +192,201 @@ class TestGemSourceIndex < RubyGemTestCase assert paths.empty?, paths.join(', ') end + def test_fetch_quick_index_fallback + index = util_zip @gem_names + + @fetcher.data["#{@gem_repo}/quick/index.rz"] = index + + quick_index = @source_index.fetch_quick_index @uri, false + assert_equal @gem_names.split, quick_index.sort + + paths = @fetcher.paths + + assert_equal "#{@gem_repo}/quick/latest_index.rz", paths.shift + assert_equal "#{@gem_repo}/quick/index.rz", paths.shift + + assert paths.empty?, paths.join(', ') + end + + def test_fetch_quick_index_subdir + latest_index = util_zip [@a2.full_name, @b2.full_name].join("\n") + repo = URI.parse "#{@gem_repo}/~nobody/mirror/" + + @fetcher.data["#{repo}quick/latest_index.rz"] = latest_index + + quick_index = @source_index.fetch_quick_index repo, false + assert_equal [@a2.full_name, @b2.full_name].sort, + quick_index.sort + + paths = @fetcher.paths + + assert_equal "#{repo}quick/latest_index.rz", paths.shift + + assert paths.empty?, paths.join(', ') + end + + def test_fetch_single_spec + a1_spec_url = "#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{@a1.full_name}.gemspec.rz" + @fetcher.data[a1_spec_url] = util_zip Marshal.dump(@a1) + + spec = @source_index.send :fetch_single_spec, URI.parse(@gem_repo), + @a1.full_name + + assert_equal @a1.full_name, spec.full_name + + paths = @fetcher.paths + + assert_equal a1_spec_url, paths.shift + + assert paths.empty?, paths.join(', ') + end + + def test_fetch_single_spec_subdir + repo = URI.parse "#{@gem_repo}/~nobody/mirror/" + + a1_spec_url = "#{repo}quick/Marshal.#{Gem.marshal_version}/#{@a1.full_name}.gemspec.rz" + @fetcher.data[a1_spec_url] = util_zip Marshal.dump(@a1) + + spec = @source_index.send :fetch_single_spec, repo, @a1.full_name + + assert_equal @a1.full_name, spec.full_name + + paths = @fetcher.paths + + assert_equal a1_spec_url, paths.shift + + assert paths.empty?, paths.join(', ') + end + + def test_fetch_single_spec_yaml + a1_spec_url = "#{@gem_repo}/quick/#{@a1.full_name}.gemspec.rz" + @fetcher.data[a1_spec_url] = util_zip @a1.to_yaml + + repo = URI.parse @gem_repo + + spec = @source_index.send :fetch_single_spec, repo, @a1.full_name + + assert_equal @a1.full_name, spec.full_name + + paths = @fetcher.paths + + assert_equal "#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{@a1.full_name}.gemspec.rz", paths.shift + assert_equal a1_spec_url, paths.shift + + assert paths.empty?, paths.join(', ') + end + + def test_fetch_single_spec_yaml_subdir + repo = URI.parse "#{@gem_repo}/~nobody/mirror/" + + a1_spec_url = "#{repo}quick/#{@a1.full_name}.gemspec.rz" + @fetcher.data[a1_spec_url] = util_zip @a1.to_yaml + + spec = @source_index.send :fetch_single_spec, repo, @a1.full_name + + assert_equal @a1.full_name, spec.full_name + + paths = @fetcher.paths + + assert_equal "#{repo}quick/Marshal.#{Gem.marshal_version}/#{@a1.full_name}.gemspec.rz", paths.shift + assert_equal a1_spec_url, paths.shift + + assert paths.empty?, paths.join(', ') + end + def test_find_missing - missing = @source_index.find_missing [@gem3.full_name] - assert_equal [@gem3.full_name], missing + missing = @source_index.find_missing [@b2.full_name] + assert_equal [@b2.full_name], missing end def test_find_missing_none_missing - missing = @source_index.find_missing @gem_names.split + missing = @source_index.find_missing [ + @a1.full_name, @a2.full_name, @c1_2.full_name + ] + assert_equal [], missing end def test_latest_specs - spec = quick_gem @gem1.name, '1' - @source_index.add_spec spec + p1_ruby = quick_gem 'p', '1' + p1_platform = quick_gem 'p', '1' do |spec| + spec.platform = Gem::Platform::CURRENT + end + + a1_platform = quick_gem @a1.name, (@a1.version) do |s| + s.platform = Gem::Platform.new 'x86-my_platform1' + end + + a2_platform = quick_gem @a2.name, (@a2.version) do |s| + s.platform = Gem::Platform.new 'x86-my_platform1' + end + + a2_platform_other = quick_gem @a2.name, (@a2.version) do |s| + s.platform = Gem::Platform.new 'x86-other_platform1' + end + + a3_platform_other = quick_gem @a2.name, (@a2.version.bump) do |s| + s.platform = Gem::Platform.new 'x86-other_platform1' + end + + @source_index.add_spec p1_ruby + @source_index.add_spec p1_platform + @source_index.add_spec a1_platform + @source_index.add_spec a2_platform + @source_index.add_spec a2_platform_other + @source_index.add_spec a3_platform_other expected = [ - @gem1.full_name, - @gem2.full_name, - @gem4.full_name, + @a2.full_name, + a2_platform.full_name, + a3_platform_other.full_name, + @c1_2.full_name, + @a_evil9.full_name, + p1_ruby.full_name, + p1_platform.full_name, ].sort - assert_equal expected, @source_index.latest_specs.map { |s| s.full_name }.sort + latest_specs = @source_index.latest_specs.map { |s| s.full_name }.sort + + assert_equal expected, latest_specs + end + + def test_load_gems_in + spec_dir1 = File.join @gemhome, 'specifications' + spec_dir2 = File.join @tempdir, 'gemhome2', 'specifications' + + FileUtils.rm_r spec_dir1 + + FileUtils.mkdir_p spec_dir1 + FileUtils.mkdir_p spec_dir2 + + a1 = quick_gem 'a', '1' do |spec| spec.author = 'author 1' end + a2 = quick_gem 'a', '1' do |spec| spec.author = 'author 2' end + + File.open File.join(spec_dir1, "#{a1.full_name}.gemspec"), 'w' do |fp| + fp.write a1.to_ruby + end + + File.open File.join(spec_dir2, "#{a2.full_name}.gemspec"), 'w' do |fp| + fp.write a2.to_ruby + end + + @source_index.load_gems_in spec_dir1, spec_dir2 + + assert_equal a1.author, @source_index.specification(a1.full_name).author end def test_outdated - sic = Gem::SourceInfoCache.new - Gem::SourceInfoCache.instance_variable_set :@cache, sic + util_setup_source_info_cache assert_equal [], @source_index.outdated - updated = quick_gem @gem1.name, (@gem1.version.bump) + updated = quick_gem @a2.name, (@a2.version.bump) util_setup_source_info_cache updated assert_equal [updated.name], @source_index.outdated - updated_platform = quick_gem @gem1.name, (updated.version.bump) do |s| + updated_platform = quick_gem @a2.name, (updated.version.bump) do |s| s.platform = Gem::Platform.new 'x86-other_platform1' end @@ -211,28 +396,34 @@ class TestGemSourceIndex < RubyGemTestCase end def test_remove_extra - @source_index.remove_extra [@gem1.full_name] - assert_equal [@gem1.full_name], @source_index.gems.map { |n,s| n } + @source_index.add_spec @a1 + @source_index.add_spec @a2 + + @source_index.remove_extra [@a1.full_name] + + assert_equal [@a1.full_name], @source_index.gems.map { |n,s| n } end def test_remove_extra_no_changes - gems = @gem_names.split.sort + gems = [@a1.full_name, @a2.full_name] + @source_index.add_spec @a1 + @source_index.add_spec @a2 + @source_index.remove_extra gems + assert_equal gems, @source_index.gems.map { |n,s| n }.sort end def test_search - assert_equal [@gem1, @gem4], @source_index.search("gem_one") - assert_equal [@gem1], @source_index.search("gem_one", "= 2") + assert_equal [@a1, @a2, @a_evil9], @source_index.search('a') + assert_equal [@a2], @source_index.search('a', '= 2') - assert_equal [], @source_index.search("bogusstring") - assert_equal [], @source_index.search("gem_one", "= 3.2.1") + assert_equal [], @source_index.search('bogusstring') + assert_equal [], @source_index.search('a', '= 3') - @a1 = quick_gem 'a', '1' - @a2 = quick_gem 'a', '2' - - source_index = Gem::SourceIndex.new @a1.full_name => @a1, - @a2.full_name => @a2 + source_index = Gem::SourceIndex.new + source_index.add_spec @a1 + source_index.add_spec @a2 assert_equal [@a1], source_index.search(@a1.name, '= 1') @@ -276,7 +467,7 @@ class TestGemSourceIndex < RubyGemTestCase end def test_specification - assert_equal @gem1, @source_index.specification(@gem1.full_name) + assert_equal @a1, @source_index.specification(@a1.full_name) assert_nil @source_index.specification("foo-1.2.4") end @@ -298,9 +489,11 @@ class TestGemSourceIndex < RubyGemTestCase assert_equal [], @source_index.gems.keys.sort use_ui @ui do - @source_index.update @uri + @source_index.update @uri, true - assert_equal @gem_names.split, @source_index.gems.keys.sort + assert_equal [@a1.full_name, @a2.full_name, @a_evil9.full_name, + @c1_2.full_name], + @source_index.gems.keys.sort end paths = @fetcher.paths @@ -315,15 +508,42 @@ class TestGemSourceIndex < RubyGemTestCase old_gem_conf = Gem.configuration Gem.configuration = Gem::ConfigFile.new([]) + latest_names = [@a2, @a_evil9, @b2, @c1_2].map { |s| s.full_name } + latest_index = util_zip latest_names.join("\n") + @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = latest_index + + marshal_uri = File.join @gem_repo, "quick", "Marshal.#{@marshal_version}", + "#{@b2.full_name}.gemspec.rz" + @fetcher.data[marshal_uri] = util_zip Marshal.dump(@b2) + + use_ui @ui do + @source_index.update @uri, false + + assert_equal latest_names, @source_index.gems.keys.sort + end + + paths = @fetcher.paths + assert_equal "#{@gem_repo}/quick/latest_index.rz", paths.shift + assert_equal marshal_uri, paths.shift + + assert paths.empty?, paths.join(', ') + ensure + Gem.configuration = old_gem_conf + end + + def test_update_incremental_all + old_gem_conf = Gem.configuration + Gem.configuration = Gem::ConfigFile.new([]) + quick_index = util_zip @all_gem_names.join("\n") @fetcher.data["#{@gem_repo}/quick/index.rz"] = quick_index marshal_uri = File.join @gem_repo, "quick", "Marshal.#{@marshal_version}", - "#{@gem3.full_name}.gemspec.rz" - @fetcher.data[marshal_uri] = util_zip Marshal.dump(@gem3) + "#{@b2.full_name}.gemspec.rz" + @fetcher.data[marshal_uri] = util_zip Marshal.dump(@b2) use_ui @ui do - @source_index.update @uri + @source_index.update @uri, true assert_equal @all_gem_names, @source_index.gems.keys.sort end @@ -345,13 +565,13 @@ class TestGemSourceIndex < RubyGemTestCase @fetcher.data["#{@gem_repo}/quick/index.rz"] = quick_index marshal_uri = File.join @gem_repo, "quick", "Marshal.#{@marshal_version}", - "#{@gem3.full_name}.gemspec.rz" + "#{@b2.full_name}.gemspec.rz" - yaml_uri = "#{@gem_repo}/quick/#{@gem3.full_name}.gemspec.rz" - @fetcher.data[yaml_uri] = util_zip @gem3.to_yaml + yaml_uri = "#{@gem_repo}/quick/#{@b2.full_name}.gemspec.rz" + @fetcher.data[yaml_uri] = util_zip @b2.to_yaml use_ui @ui do - @source_index.update @uri + @source_index.update @uri, true assert_equal @all_gem_names, @source_index.gems.keys.sort end @@ -374,16 +594,16 @@ class TestGemSourceIndex < RubyGemTestCase @fetcher.data["#{@gem_repo}/quick/index.rz"] = quick_index marshal_uri = File.join @gem_repo, "quick", "Marshal.#{@marshal_version}", - "#{@gem3.full_name}.gemspec.rz" - marshal_data = Marshal.dump(@gem3) + "#{@b2.full_name}.gemspec.rz" + marshal_data = Marshal.dump(@b2) marshal_data[0] = (Marshal::MAJOR_VERSION - 1).chr @fetcher.data[marshal_uri] = util_zip marshal_data - yaml_uri = "#{@gem_repo}/quick/#{@gem3.full_name}.gemspec.rz" - @fetcher.data[yaml_uri] = util_zip @gem3.to_yaml + yaml_uri = "#{@gem_repo}/quick/#{@b2.full_name}.gemspec.rz" + @fetcher.data[yaml_uri] = util_zip @b2.to_yaml use_ui @ui do - @source_index.update @uri + @source_index.update @uri, true assert_equal @all_gem_names, @source_index.gems.keys.sort end @@ -398,22 +618,48 @@ class TestGemSourceIndex < RubyGemTestCase Gem.configuration = old_gem_conf end + def test_update_subdir + @gem_repo = @gem_repo + "/subdir" + + util_setup_bulk_fetch true + + @source_index.gems.replace({}) + assert_equal [], @source_index.gems.keys.sort + + uri = @uri.to_s + "/subdir" + + use_ui @ui do + @source_index.update uri, true + + assert_equal [@a1.full_name, @a2.full_name, @a_evil9.full_name, + @c1_2.full_name], + @source_index.gems.keys.sort + end + + paths = @fetcher.paths + + assert_equal "#{@gem_repo}/quick/index.rz", paths.shift + assert_equal "#{@gem_repo}/Marshal.#{@marshal_version}.Z", paths.shift + + assert paths.empty?, paths.join(', ') + end + def test_update_with_missing marshal_uri = File.join @gem_repo, "quick", "Marshal.#{@marshal_version}", - "#{@gem3.full_name}.gemspec.rz" - dumped = Marshal.dump @gem3 + "#{@c1_2.full_name}.gemspec.rz" + dumped = Marshal.dump @c1_2 @fetcher.data[marshal_uri] = util_zip(dumped) use_ui @ui do - @source_index.update_with_missing @uri, [@gem3.full_name] + @source_index.update_with_missing @uri, [@c1_2.full_name] end - spec = @source_index.specification(@gem3.full_name) + spec = @source_index.specification(@c1_2.full_name) # We don't care about the equality of undumped attributes - @gem3.files = spec.files - @gem3.loaded_from = spec.loaded_from + @c1_2.files = spec.files + @c1_2.loaded_from = spec.loaded_from - assert_equal @gem3, spec + assert_equal @c1_2, spec end def util_setup_bulk_fetch(compressed) @@ -427,3 +673,4 @@ class TestGemSourceIndex < RubyGemTestCase end end + diff --git a/test/rubygems/test_gem_source_info_cache.rb b/test/rubygems/test_gem_source_info_cache.rb index 570b643bc5..3bdaef5aa9 100644 --- a/test/rubygems/test_gem_source_info_cache.rb +++ b/test/rubygems/test_gem_source_info_cache.rb @@ -25,7 +25,12 @@ class TestGemSourceInfoCache < RubyGemTestCase @sic = Gem::SourceInfoCache.new @sic.instance_variable_set :@fetcher, @fetcher + @si_new = Gem::SourceIndex.new + @sice_new = Gem::SourceInfoCacheEntry.new @si_new, 0 + prep_cache_files @sic + + @sic.reset_cache_data end def teardown @@ -35,8 +40,10 @@ class TestGemSourceInfoCache < RubyGemTestCase def test_self_cache_refreshes Gem.configuration.update_sources = true #true by default - source_index = Gem::SourceIndex.new 'key' => 'sys' - @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = source_index.dump + si = Gem::SourceIndex.new + si.add_spec @a1 + + @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump Gem.sources.replace %W[#{@gem_repo}] @@ -51,8 +58,10 @@ class TestGemSourceInfoCache < RubyGemTestCase def test_self_cache_skips_refresh_based_on_configuration Gem.configuration.update_sources = false - source_index = Gem::SourceIndex.new 'key' => 'sys' - @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = source_index.dump + si = Gem::SourceIndex.new + si.add_spec @a1 + + @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump Gem.sources.replace %w[#{@gem_repo}] @@ -66,20 +75,24 @@ class TestGemSourceInfoCache < RubyGemTestCase end def test_self_cache_data - source_index = Gem::SourceIndex.new 'key' => 'sys' - @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = source_index.dump + si = Gem::SourceIndex.new + si.add_spec @a1 + + @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump Gem::SourceInfoCache.instance_variable_set :@cache, nil - sice = Gem::SourceInfoCacheEntry.new source_index, 0 + sice = Gem::SourceInfoCacheEntry.new si, 0 use_ui @ui do - assert_equal source_index.gems, - Gem::SourceInfoCache.cache_data[@gem_repo].source_index.gems + gems = Gem::SourceInfoCache.cache_data[@gem_repo].source_index.gems + gem_names = gems.map { |_, spec| spec.full_name } + + assert_equal si.gems.map { |_,spec| spec.full_name }, gem_names end end def test_cache_data - assert_equal [['key','sys']], @sic.cache_data.to_a.sort + assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort end def test_cache_data_dirty @@ -97,7 +110,14 @@ class TestGemSourceInfoCache < RubyGemTestCase data = { @gem_repo => { 'totally' => 'borked' } } - [@sic.system_cache_file, @sic.user_cache_file].each do |fn| + cache_files = [ + @sic.system_cache_file, + @sic.latest_system_cache_file, + @sic.user_cache_file, + @sic.latest_user_cache_file + ] + + cache_files.each do |fn| FileUtils.mkdir_p File.dirname(fn) open(fn, "wb") { |f| f.write Marshal.dump(data) } end @@ -113,7 +133,9 @@ class TestGemSourceInfoCache < RubyGemTestCase def test_cache_data_none_readable FileUtils.chmod 0222, @sic.system_cache_file + FileUtils.chmod 0222, @sic.latest_system_cache_file FileUtils.chmod 0222, @sic.user_cache_file + FileUtils.chmod 0222, @sic.latest_user_cache_file return if (File.stat(@sic.system_cache_file).mode & 0222) != 0222 return if (File.stat(@sic.user_cache_file).mode & 0222) != 0222 # HACK for systems that don't support chmod @@ -129,6 +151,16 @@ class TestGemSourceInfoCache < RubyGemTestCase assert_equal 'unable to locate a writable cache file', e.message end + def test_cache_data_nonexistent + FileUtils.rm @sic.system_cache_file + FileUtils.rm @sic.latest_system_cache_file + FileUtils.rm @sic.user_cache_file + FileUtils.rm @sic.latest_user_cache_file + + # TODO test verbose output + assert_equal [], @sic.cache_data.to_a.sort + end + def test_cache_data_repair data = { @gem_repo => { @@ -152,7 +184,8 @@ class TestGemSourceInfoCache < RubyGemTestCase def test_cache_data_user_fallback FileUtils.chmod 0444, @sic.system_cache_file - assert_equal [['key','usr']], @sic.cache_data.to_a.sort + + assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort end def test_cache_file @@ -174,60 +207,118 @@ class TestGemSourceInfoCache < RubyGemTestCase end def test_flush - @sic.cache_data['key'] = 'new' + @sic.cache_data[@gem_repo] = @sice_new @sic.update @sic.flush - assert_equal [['key','new']], read_cache(@sic.system_cache_file).to_a.sort + assert_equal [[@gem_repo, @sice_new]], + read_cache(@sic.system_cache_file).to_a.sort + end + + def test_latest_cache_data + util_make_gems + + sice = Gem::SourceInfoCacheEntry.new @source_index, 0 + + @sic.set_cache_data @gem_repo => sice + latest = @sic.latest_cache_data + gems = latest[@gem_repo].source_index.search('a').map { |s| s.full_name } + + assert_equal %w[a-2 a_evil-9], gems + end + + def test_latest_cache_file + latest_cache_file = File.join File.dirname(@gemcache), + "latest_#{File.basename @gemcache}" + assert_equal latest_cache_file, @sic.latest_cache_file + end + + def test_latest_system_cache_file + assert_equal File.join(Gem.dir, "latest_source_cache"), + @sic.latest_system_cache_file + end + + def test_latest_user_cache_file + assert_equal @latest_usrcache, @sic.latest_user_cache_file end def test_read_system_cache - assert_equal [['key','sys']], @sic.cache_data.to_a.sort + assert_equal [[@gem_repo, @sys_sice]], @sic.cache_data.to_a.sort end def test_read_user_cache - FileUtils.chmod 0444, @sic.system_cache_file + FileUtils.chmod 0444, @sic.user_cache_file + FileUtils.chmod 0444, @sic.latest_user_cache_file + + @si = Gem::SourceIndex.new + @si.add_specs @a1, @a2 + + @sice = Gem::SourceInfoCacheEntry.new @si, 0 + + @sic.set_cache_data({ @gem_repo => @sice }) + @sic.update + @sic.write_cache + @sic.reset_cache_data - assert_equal [['key','usr']], @sic.cache_data.to_a.sort + user_cache_data = @sic.cache_data.to_a.sort + + assert_equal 1, user_cache_data.length + user_cache_data = user_cache_data.first + + assert_equal @gem_repo, user_cache_data.first + + gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name } + assert_equal [@a2.full_name], gems end def test_search - si = Gem::SourceIndex.new @gem1.full_name => @gem1 - cache_data = { - @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) - } + si = Gem::SourceIndex.new + si.add_spec @a1 + cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } @sic.instance_variable_set :@cache_data, cache_data - assert_equal [@gem1], @sic.search(//) + assert_equal [@a1], @sic.search(//) + end + + def test_search_all + util_make_gems + + sice = Gem::SourceInfoCacheEntry.new @source_index, 0 + + @sic.set_cache_data @gem_repo => sice + @sic.update + @sic.write_cache + @sic.reset_cache_data + + gem_names = @sic.search(//, false, true).map { |spec| spec.full_name } + + assert_equal %w[a-1 a-2 a_evil-9 c-1.2], gem_names end def test_search_dependency - si = Gem::SourceIndex.new @gem1.full_name => @gem1 - cache_data = { - @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) - } + si = Gem::SourceIndex.new + si.add_spec @a1 + cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } @sic.instance_variable_set :@cache_data, cache_data - dep = Gem::Dependency.new @gem1.name, @gem1.version + dep = Gem::Dependency.new @a1.name, @a1.version - assert_equal [@gem1], @sic.search(dep) + assert_equal [@a1], @sic.search(dep) end def test_search_no_matches - si = Gem::SourceIndex.new @gem1.full_name => @gem1 - cache_data = { - @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) - } + si = Gem::SourceIndex.new + si.add_spec @a1 + cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } @sic.instance_variable_set :@cache_data, cache_data assert_equal [], @sic.search(/nonexistent/) end def test_search_no_matches_in_source - si = Gem::SourceIndex.new @gem1.full_name => @gem1 - cache_data = { - @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) - } + si = Gem::SourceIndex.new + si.add_spec @a1 + cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } @sic.instance_variable_set :@cache_data, cache_data Gem.sources.replace %w[more-gems.example.com] @@ -235,13 +326,12 @@ class TestGemSourceInfoCache < RubyGemTestCase end def test_search_with_source - si = Gem::SourceIndex.new @gem1.full_name => @gem1 - cache_data = { - @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) - } + si = Gem::SourceIndex.new + si.add_spec @a1 + cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) } @sic.instance_variable_set :@cache_data, cache_data - assert_equal [[@gem1, @gem_repo]], + assert_equal [[@a1, @gem_repo]], @sic.search_with_source(//) end @@ -254,45 +344,81 @@ class TestGemSourceInfoCache < RubyGemTestCase end def test_write_cache - @sic.cache_data['key'] = 'new' + @sic.cache_data[@gem_repo] = @sice_new @sic.write_cache - assert_equal [['key', 'new']], + assert_equal [[@gem_repo, @sice_new]], read_cache(@sic.system_cache_file).to_a.sort - assert_equal [['key', 'usr']], + assert_equal [[@gem_repo, @usr_sice]], read_cache(@sic.user_cache_file).to_a.sort end def test_write_cache_user FileUtils.chmod 0444, @sic.system_cache_file - @sic.set_cache_data({'key' => 'new'}) + @sic.set_cache_data({@gem_repo => @sice_new}) @sic.update @sic.write_cache - assert_equal [['key', 'sys']], read_cache(@sic.system_cache_file).to_a.sort - assert_equal [['key', 'new']], read_cache(@sic.user_cache_file).to_a.sort + assert File.exist?(@sic.user_cache_file), 'user_cache_file' + assert File.exist?(@sic.latest_user_cache_file), + 'latest_user_cache_file exists' + + assert_equal [[@gem_repo, @sys_sice]], + read_cache(@sic.system_cache_file).to_a.sort + assert_equal [[@gem_repo, @sice_new]], + read_cache(@sic.user_cache_file).to_a.sort end def test_write_cache_user_from_scratch FileUtils.rm_rf @sic.user_cache_file + FileUtils.rm_rf @sic.latest_user_cache_file + FileUtils.chmod 0444, @sic.system_cache_file - @sic.set_cache_data({'key' => 'new'}) + FileUtils.chmod 0444, @sic.latest_system_cache_file + + @si = Gem::SourceIndex.new + @si.add_specs @a1, @a2 + + @sice = Gem::SourceInfoCacheEntry.new @si, 0 + + @sic.set_cache_data({ @gem_repo => @sice }) @sic.update @sic.write_cache - assert_equal [['key', 'sys']], read_cache(@sic.system_cache_file).to_a.sort - assert_equal [['key', 'new']], read_cache(@sic.user_cache_file).to_a.sort + assert File.exist?(@sic.user_cache_file), 'system_cache_file' + assert File.exist?(@sic.latest_user_cache_file), + 'latest_system_cache_file' + + user_cache_data = read_cache(@sic.user_cache_file).to_a.sort + assert_equal 1, user_cache_data.length + user_cache_data = user_cache_data.first + + assert_equal @gem_repo, user_cache_data.first + + gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name } + assert_equal [@a1.full_name, @a2.full_name], gems + + user_cache_data = read_cache(@sic.latest_user_cache_file).to_a.sort + assert_equal 1, user_cache_data.length + user_cache_data = user_cache_data.first + + assert_equal @gem_repo, user_cache_data.first + + gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name } + assert_equal [@a2.full_name], gems end def test_write_cache_user_no_directory FileUtils.rm_rf File.dirname(@sic.user_cache_file) FileUtils.chmod 0444, @sic.system_cache_file - @sic.set_cache_data({'key' => 'new'}) + @sic.set_cache_data({ @gem_repo => @sice_new }) @sic.update @sic.write_cache - assert_equal [['key','sys']], read_cache(@sic.system_cache_file).to_a.sort - assert_equal [['key','new']], read_cache(@sic.user_cache_file).to_a.sort + assert_equal [[@gem_repo, @sys_sice]], + read_cache(@sic.system_cache_file).to_a.sort + assert_equal [[@gem_repo, @sice_new]], + read_cache(@sic.user_cache_file).to_a.sort end end diff --git a/test/rubygems/test_gem_source_info_cache_entry.rb b/test/rubygems/test_gem_source_info_cache_entry.rb index 023baf948b..c1194e34bc 100644 --- a/test/rubygems/test_gem_source_info_cache_entry.rb +++ b/test/rubygems/test_gem_source_info_cache_entry.rb @@ -9,37 +9,68 @@ class TestGemSourceInfoCacheEntry < RubyGemTestCase util_setup_fake_fetcher - @si = Gem::SourceIndex.new @gem1.full_name => @gem1.name + @si = Gem::SourceIndex.new + @si.add_spec @a1 @sic_e = Gem::SourceInfoCacheEntry.new @si, @si.dump.size end def test_refresh @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}.Z"] = - proc { raise Exception } + proc { raise } @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = @si.dump - assert_nothing_raised do - @sic_e.refresh @gem_repo + use_ui @ui do + @sic_e.refresh @gem_repo, true + end + end + + def test_refresh_all + @si.add_spec @a2 + + a1_name = @a1.full_name + a2_name = @a2.full_name + + @fetcher.data["#{@gem_repo}/quick/index.rz"] = + util_zip [a1_name, a2_name].join("\n") + @fetcher.data["#{@gem_repo}/quick/latest_index.rz"] = util_zip a2_name + @fetcher.data["#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{a1_name}.gemspec.rz"] = util_zip Marshal.dump(@a1) + @fetcher.data["#{@gem_repo}/quick/Marshal.#{Gem.marshal_version}/#{a2_name}.gemspec.rz"] = util_zip Marshal.dump(@a2) + @fetcher.data["#{@gem_repo}/Marshal.#{Gem.marshal_version}"] = + Marshal.dump @si + + sic_e = Gem::SourceInfoCacheEntry.new Gem::SourceIndex.new, 0 + + use_ui @ui do + sic_e.refresh @gem_repo, false end + + assert_equal [a2_name], sic_e.source_index.map { |n,| n }.sort + + use_ui @ui do + sic_e.refresh @gem_repo, true + end + + assert_equal [a1_name, a2_name], sic_e.source_index.map { |n,| n }.sort end def test_refresh_bad_uri assert_raise URI::BadURIError do - @sic_e.refresh 'gems.example.com' + @sic_e.refresh 'gems.example.com', true end end def test_refresh_update - si = Gem::SourceIndex.new @gem1.full_name => @gem1, - @gem2.full_name => @gem2 + si = Gem::SourceIndex.new + si.add_spec @a1 + si.add_spec @b2 @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump use_ui @ui do - @sic_e.refresh @gem_repo + @sic_e.refresh @gem_repo, true end - new_gem = @sic_e.source_index.specification(@gem2.full_name) - assert_equal @gem2.full_name, new_gem.full_name + new_gem = @sic_e.source_index.specification(@b2.full_name) + assert_equal @b2.full_name, new_gem.full_name end end diff --git a/test/rubygems/test_gem_uninstaller.rb b/test/rubygems/test_gem_uninstaller.rb new file mode 100644 index 0000000000..d6e41814ed --- /dev/null +++ b/test/rubygems/test_gem_uninstaller.rb @@ -0,0 +1,43 @@ +require File.join(File.expand_path(File.dirname(__FILE__)), + 'gem_installer_test_case') +require 'rubygems/uninstaller' + +class TestGemUninstaller < GemInstallerTestCase + + def setup + super + + ui = MockGemUi.new + util_setup_gem ui + + use_ui ui do + @installer.install + end + end + + def test_remove_executables_force_keep + uninstaller = Gem::Uninstaller.new nil, :executables => false + + use_ui @ui do + uninstaller.remove_executables @spec + end + + assert_equal true, File.exist?(File.join(@gemhome, 'bin', 'executable')) + + assert_equal "Executables and scripts will remain installed.\n", @ui.output + end + + def test_remove_executables_force_remove + uninstaller = Gem::Uninstaller.new nil, :executables => true + + use_ui @ui do + uninstaller.remove_executables @spec + end + + assert_equal "Removing executable\n", @ui.output + + assert_equal false, File.exist?(File.join(@gemhome, 'bin', 'executable')) + end + +end + -- cgit v1.2.3