Change soft-fail to use the config, rather than env
[rbx.git] / test / rubygems / gemutilities.rb
blobd8818d0b0165917a6db99b5e581f64dcb94df2ce
1 #!/usr/bin/env ruby
2 #--
3 # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others.
4 # All rights reserved.
5 # See LICENSE.txt for permissions.
6 #++
8 at_exit { $SAFE = 1 }
10 require 'fileutils'
11 require 'test/unit'
12 require 'tmpdir'
13 require 'uri'
14 require 'rubygems/package'
15 require 'rubygems/test_utilities'
17 require File.join(File.expand_path(File.dirname(__FILE__)), 'mockgemui')
19 module Gem
20   def self.source_index=(si)
21     @@source_index = si
22   end
24   def self.win_platform=(val)
25     @@win_platform = val
26   end
27 end
29 class RubyGemTestCase < Test::Unit::TestCase
31   include Gem::DefaultUserInteraction
33   undef_method :default_test if instance_methods.include? 'default_test' or
34                                 instance_methods.include? :default_test
36   def setup
37     super
39     @ui = MockGemUi.new
40     tmpdir = nil
41     Dir.chdir Dir.tmpdir do tmpdir = Dir.pwd end # HACK OSX /private/tmp
42     @tempdir = File.join tmpdir, "test_rubygems_#{$$}"
43     @tempdir.untaint
44     @gemhome = File.join @tempdir, "gemhome"
45     @gemcache = File.join(@gemhome, "source_cache")
46     @usrcache = File.join(@gemhome, ".gem", "user_cache")
47     @latest_usrcache = File.join(@gemhome, ".gem", "latest_user_cache")
48     @userhome = File.join @tempdir, 'userhome'
50     ENV['HOME'] = @userhome
51     Gem.instance_variable_set :@user_home, nil
53     FileUtils.mkdir_p @gemhome
54     FileUtils.mkdir_p @userhome
56     ENV['GEMCACHE'] = @usrcache
57     Gem.use_paths(@gemhome)
58     Gem.loaded_specs.clear
60     Gem.configuration.verbose = true
61     Gem.configuration.update_sources = true
63     @gem_repo = "http://gems.example.com/"
64     @uri = URI.parse @gem_repo
65     Gem.sources.replace [@gem_repo]
67     Gem::SpecFetcher.fetcher = nil
69     @orig_BASERUBY = Gem::ConfigMap[:BASERUBY]
70     Gem::ConfigMap[:BASERUBY] = Gem::ConfigMap[:RUBY_INSTALL_NAME]
72     @orig_arch = Gem::ConfigMap[:arch]
74     if win_platform?
75       util_set_arch 'i386-mswin32'
76     else
77       util_set_arch 'i686-darwin8.10.1'
78     end
80     @marshal_version = "#{Marshal::MAJOR_VERSION}.#{Marshal::MINOR_VERSION}"
82     @private_key = File.expand_path File.join(File.dirname(__FILE__),
83                                               'private_key.pem')
84     @public_cert = File.expand_path File.join(File.dirname(__FILE__),
85                                               'public_cert.pem')
86   end
88   def teardown
89     Gem::ConfigMap[:BASERUBY] = @orig_BASERUBY
90     Gem::ConfigMap[:arch] = @orig_arch
92     if defined? Gem::RemoteFetcher then
93       Gem::RemoteFetcher.fetcher = nil
94     end
96     FileUtils.rm_rf @tempdir
98     ENV.delete 'GEMCACHE'
99     ENV.delete 'GEM_HOME'
100     ENV.delete 'GEM_PATH'
102     Gem.clear_paths
103   end
105   def install_gem gem
106     require 'rubygems/installer'
108     use_ui MockGemUi.new do
109       Dir.chdir @tempdir do
110         Gem::Builder.new(gem).build
111       end
112     end
114     gem = File.join(@tempdir, "#{gem.full_name}.gem").untaint
115     Gem::Installer.new(gem, :wrappers => true).install
116   end
118   def prep_cache_files(lc)
119     @usr_si ||= Gem::SourceIndex.new
120     @usr_sice ||= Gem::SourceInfoCacheEntry.new @usr_si, 0
122     @sys_si ||= Gem::SourceIndex.new
123     @sys_sice ||= Gem::SourceInfoCacheEntry.new @sys_si, 0
125     latest_si = Gem::SourceIndex.new
126     latest_si.add_specs(*@sys_si.latest_specs)
127     latest_sys_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
129     latest_si = Gem::SourceIndex.new
130     latest_si.add_specs(*@usr_si.latest_specs)
131     latest_usr_sice = Gem::SourceInfoCacheEntry.new latest_si, 0
133     [ [lc.system_cache_file, @sys_sice],
134       [lc.latest_system_cache_file, latest_sys_sice],
135       [lc.user_cache_file, @usr_sice],
136       [lc.latest_user_cache_file, latest_usr_sice],
137     ].each do |filename, data|
138       FileUtils.mkdir_p File.dirname(filename).untaint
140       open filename.dup.untaint, 'wb' do |f|
141         f.write Marshal.dump({ @gem_repo => data })
142       end
143     end
144   end
146   def read_cache(path)
147     open path.dup.untaint, 'rb' do |io|
148       Marshal.load io.read
149     end
150   end
152   def read_binary(path)
153     Gem.read_binary path
154   end
156   def write_file(path)
157     path = File.join(@gemhome, path)
158     dir = File.dirname path
159     FileUtils.mkdir_p dir
161     open path, 'wb' do |io|
162       yield io
163     end
165     path
166   end
168   def quick_gem(gemname, version='2')
169     require 'rubygems/specification'
171     spec = Gem::Specification.new do |s|
172       s.platform = Gem::Platform::RUBY
173       s.name = gemname
174       s.version = version
175       s.author = 'A User'
176       s.email = 'example@example.com'
177       s.homepage = 'http://example.com'
178       s.has_rdoc = true
179       s.summary = "this is a summary"
180       s.description = "This is a test description"
182       yield(s) if block_given?
183     end
185     path = File.join "specifications", "#{spec.full_name}.gemspec"
186     written_path = write_file path do |io|
187       io.write(spec.to_ruby)
188     end
190     spec.loaded_from = written_path
192     Gem.source_index.add_spec spec
194     return spec
195   end
197   def util_build_gem(spec)
198     dir = File.join(@gemhome, 'gems', spec.full_name)
199     FileUtils.mkdir_p dir
201     Dir.chdir dir do
202       spec.files.each do |file|
203         next if File.exist? file
204         FileUtils.mkdir_p File.dirname(file)
205         File.open file, 'w' do |fp| fp.puts "# #{file}" end
206       end
208       use_ui MockGemUi.new do
209         Gem::Builder.new(spec).build
210       end
212       FileUtils.mv "#{spec.full_name}.gem",
213                    File.join(@gemhome, 'cache', "#{spec.original_name}.gem")
214     end
215   end
217   def util_clear_gems
218     FileUtils.rm_r File.join(@gemhome, 'gems')
219     FileUtils.rm_r File.join(@gemhome, 'specifications')
220     Gem.source_index.refresh!
221   end
223   def util_gem(name, version, &block)
224     spec = quick_gem(name, version, &block)
226     util_build_gem spec
228     cache_file = File.join @tempdir, 'gems', "#{spec.original_name}.gem"
229     FileUtils.mv File.join(@gemhome, 'cache', "#{spec.original_name}.gem"),
230                  cache_file
231     FileUtils.rm File.join(@gemhome, 'specifications',
232                            "#{spec.full_name}.gemspec")
234     spec.loaded_from = nil
235     spec.loaded = false
237     [spec, cache_file]
238   end
240   def util_gzip(data)
241     out = StringIO.new
243     Zlib::GzipWriter.wrap out do |io|
244       io.write data
245     end
247     out.string
248   end
250   def util_make_gems
251     init = proc do |s|
252       s.files = %w[lib/code.rb]
253       s.require_paths = %w[lib]
254     end
256     @a1 = quick_gem('a', '1', &init)
257     @a2 = quick_gem('a', '2', &init)
258     @a_evil9 = quick_gem('a_evil', '9', &init)
259     @b2 = quick_gem('b', '2', &init)
260     @c1_2   = quick_gem('c', '1.2',   &init)
261     @pl1     = quick_gem 'pl', '1' do |s| # l for legacy
262       s.files = %w[lib/code.rb]
263       s.require_paths = %w[lib]
264       s.platform = Gem::Platform.new 'i386-linux'
265       s.instance_variable_set :@original_platform, 'i386-linux'
266     end
268     write_file File.join(*%W[gems #{@a1.original_name} lib code.rb]) do end
269     write_file File.join(*%W[gems #{@a2.original_name} lib code.rb]) do end
270     write_file File.join(*%W[gems #{@b2.original_name} lib code.rb]) do end
271     write_file File.join(*%W[gems #{@c1_2.original_name} lib code.rb]) do end
272     write_file File.join(*%W[gems #{@pl1.original_name} lib code.rb]) do end
274     [@a1, @a2, @a_evil9, @b2, @c1_2, @pl1].each { |spec| util_build_gem spec }
276     FileUtils.rm_r File.join(@gemhome, 'gems', @pl1.original_name)
278     Gem.source_index = nil
279   end
281   ##
282   # Set the platform to +arch+
284   def util_set_arch(arch)
285     Gem::ConfigMap[:arch] = arch
286     platform = Gem::Platform.new arch
288     Gem.instance_variable_set :@platforms, nil
289     Gem::Platform.instance_variable_set :@local, nil
291     platform
292   end
294   def util_setup_fake_fetcher
295     require 'zlib'
296     require 'socket'
297     require 'rubygems/remote_fetcher'
299     @fetcher = Gem::FakeFetcher.new
301     util_make_gems
303     @all_gems = [@a1, @a2, @a_evil9, @b2, @c1_2].sort
304     @all_gem_names = @all_gems.map { |gem| gem.full_name }
306     gem_names = [@a1.full_name, @a2.full_name, @b2.full_name]
307     @gem_names = gem_names.sort.join("\n")
309     @source_index = Gem::SourceIndex.new
310     @source_index.add_spec @a1
311     @source_index.add_spec @a2
312     @source_index.add_spec @a_evil9
313     @source_index.add_spec @c1_2
315     Gem::RemoteFetcher.fetcher = @fetcher
316   end
318   def util_setup_source_info_cache(*specs)
319     require 'rubygems/source_info_cache'
320     require 'rubygems/source_info_cache_entry'
322     specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
323     si = Gem::SourceIndex.new specs
325     sice = Gem::SourceInfoCacheEntry.new si, 0
326     sic = Gem::SourceInfoCache.new
328     sic.set_cache_data( { @gem_repo => sice } )
329     sic.update
330     sic.write_cache
331     sic.reset_cache_data
333     Gem::SourceInfoCache.instance_variable_set :@cache, sic
335     si
336   end
338   def util_setup_spec_fetcher(*specs)
339     specs = Hash[*specs.map { |spec| [spec.full_name, spec] }.flatten]
340     si = Gem::SourceIndex.new specs
342     spec_fetcher = Gem::SpecFetcher.fetcher
344     spec_fetcher.specs[@uri] = []
345     si.gems.sort_by { |_, spec| spec }.each do |_, spec|
346       spec_tuple = [spec.name, spec.version, spec.original_platform]
347       spec_fetcher.specs[@uri] << spec_tuple
348     end
350     spec_fetcher.latest_specs[@uri] = []
351     si.latest_specs.sort.each do |spec|
352       spec_tuple = [spec.name, spec.version, spec.original_platform]
353       spec_fetcher.latest_specs[@uri] << spec_tuple
354     end
356     si.gems.sort_by { |_,spec| spec }.each do |_, spec|
357       path = "#{@gem_repo}quick/Marshal.#{Gem.marshal_version}/#{spec.original_name}.gemspec.rz"
358       data = Marshal.dump spec
359       data_deflate = Zlib::Deflate.deflate data
360       @fetcher.data[path] = data_deflate
361     end
363     si
364   end
366   def util_zip(data)
367     Zlib::Deflate.deflate data
368   end
370   def self.win_platform?
371     Gem.win_platform?
372   end
374   def win_platform?
375     Gem.win_platform?
376   end
378   # NOTE Allow tests to use a random (but controlled) port number instead of
379   # a hardcoded one. This helps CI tools when running parallels builds on
380   # the same builder slave.
381   def self.process_based_port
382     @@process_based_port ||= 8000 + $$ % 1000
383   end
385   def process_based_port
386     self.class.process_based_port
387   end