Updated RubySpec submodule to 9f66d0b1.
[rbx.git] / test / rubygems / test_gem_source_info_cache.rb
blob523b4042806307fbbc645d2e2d25b5b32d9dec2c
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 require 'test/unit'
9 require File.join(File.expand_path(File.dirname(__FILE__)), 'gemutilities')
10 require 'rubygems/source_info_cache'
12 class Gem::SourceIndex
13   public :gems
14 end
16 class TestGemSourceInfoCache < RubyGemTestCase
18   def setup
19     @original_sources = Gem.sources
21     super
23     util_setup_fake_fetcher
25     @sic = Gem::SourceInfoCache.new
26     @sic.instance_variable_set :@fetcher, @fetcher
28     @si_new = Gem::SourceIndex.new
29     @sice_new = Gem::SourceInfoCacheEntry.new @si_new, 0
31     prep_cache_files @sic
33     @sic.reset_cache_data
34   end
36   def teardown
37     super
38     Gem.sources.replace @original_sources
39   end
41   def test_self_cache_refreshes
42     Gem.configuration.update_sources = true #true by default
43     si = Gem::SourceIndex.new
44     si.add_spec @a1
46     @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump
48     Gem.sources.replace %W[#{@gem_repo}]
50     use_ui @ui do
51       assert_not_nil Gem::SourceInfoCache.cache
52       assert_kind_of Gem::SourceInfoCache, Gem::SourceInfoCache.cache
53       assert_equal Gem::SourceInfoCache.cache.object_id,
54                    Gem::SourceInfoCache.cache.object_id
55       assert_match %r|Bulk updating|, @ui.output
56     end
57   end
59   def test_self_cache_skips_refresh_based_on_configuration
60     Gem.configuration.update_sources = false
61     si = Gem::SourceIndex.new
62     si.add_spec @a1
64     @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump
66     Gem.sources.replace %w[#{@gem_repo}]
68     use_ui @ui do
69       assert_not_nil Gem::SourceInfoCache.cache
70       assert_kind_of Gem::SourceInfoCache, Gem::SourceInfoCache.cache
71       assert_equal Gem::SourceInfoCache.cache.object_id,
72                    Gem::SourceInfoCache.cache.object_id
73       assert_no_match %r|Bulk updating|, @ui.output
74     end
75   end
77   def test_self_cache_data
78     si = Gem::SourceIndex.new
79     si.add_spec @a1
81     @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = si.dump
83     Gem::SourceInfoCache.instance_variable_set :@cache, nil
84     sice = Gem::SourceInfoCacheEntry.new si, 0
86     use_ui @ui do
87       gems = Gem::SourceInfoCache.cache_data[@gem_repo].source_index.gems
88       gem_names = gems.map { |_, spec| spec.full_name }
90       assert_equal si.gems.map { |_,spec| spec.full_name }, gem_names
91     end
92   end
94   def test_cache_data
95     assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort
96   end
98   def test_cache_data_dirty
99     def @sic.dirty() @dirty; end
100     assert_equal false, @sic.dirty, 'clean on init'
101     @sic.cache_data
102     assert_equal false, @sic.dirty, 'clean on fetch'
103     @sic.update
104     @sic.cache_data
105     assert_equal true, @sic.dirty, 'still dirty'
106   end
108   def test_cache_data_irreparable
109     @fetcher.data["#{@gem_repo}/Marshal.#{@marshal_version}"] = @source_index.dump
111     data = { @gem_repo => { 'totally' => 'borked' } }
113     cache_files = [
114       @sic.system_cache_file,
115       @sic.latest_system_cache_file,
116       @sic.user_cache_file,
117       @sic.latest_user_cache_file
118     ]
120     cache_files.each do |fn|
121       FileUtils.mkdir_p File.dirname(fn)
122       open(fn, "wb") { |f| f.write Marshal.dump(data) }
123     end
125     @sic.instance_eval { @cache_data = nil }
127     fetched = use_ui @ui do @sic.cache_data end
129     fetched_si = fetched["#{@gem_repo}"].source_index
131     assert_equal @source_index.index_signature, fetched_si.index_signature
132   end
134   def test_cache_data_none_readable
135     FileUtils.chmod 0222, @sic.system_cache_file
136     FileUtils.chmod 0222, @sic.latest_system_cache_file
137     FileUtils.chmod 0222, @sic.user_cache_file
138     FileUtils.chmod 0222, @sic.latest_user_cache_file
139     return if (File.stat(@sic.system_cache_file).mode & 0222) != 0222
140     return if (File.stat(@sic.user_cache_file).mode & 0222) != 0222
141     # HACK for systems that don't support chmod
142     assert_equal({}, @sic.cache_data)
143   end
145   def test_cache_data_none_writable
146     FileUtils.chmod 0444, @sic.system_cache_file
147     FileUtils.chmod 0444, @sic.user_cache_file
148     e = assert_raise RuntimeError do
149       @sic.cache_data
150     end
151     assert_equal 'unable to locate a writable cache file', e.message
152   end
154   def test_cache_data_nonexistent
155     FileUtils.rm @sic.system_cache_file
156     FileUtils.rm @sic.latest_system_cache_file
157     FileUtils.rm @sic.user_cache_file
158     FileUtils.rm @sic.latest_user_cache_file
160     # TODO test verbose output
161     assert_equal [], @sic.cache_data.to_a.sort
162   end
164   def test_cache_data_repair
165     data = {
166         @gem_repo => {
167           'cache' => Gem::SourceIndex.new,
168           'size' => 0,
169       }
170     }
171     [@sic.system_cache_file, @sic.user_cache_file].each do |fn|
172       FileUtils.mkdir_p File.dirname(fn)
173       open(fn, "wb") { |f| f.write Marshal.dump(data) }
174     end
176     @sic.instance_eval { @cache_data = nil }
178     expected = {
179         @gem_repo =>
180           Gem::SourceInfoCacheEntry.new(Gem::SourceIndex.new, 0)
181     }
182     assert_equal expected, @sic.cache_data
183   end
185   def test_cache_data_user_fallback
186     FileUtils.chmod 0444, @sic.system_cache_file
188     assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort
189   end
191   def test_cache_file
192     assert_equal @gemcache, @sic.cache_file
193   end
195   def test_cache_file_user_fallback
196     FileUtils.chmod 0444, @sic.system_cache_file
197     assert_equal @usrcache, @sic.cache_file
198   end
200   def test_cache_file_none_writable
201     FileUtils.chmod 0444, @sic.system_cache_file
202     FileUtils.chmod 0444, @sic.user_cache_file
203     e = assert_raise RuntimeError do
204       @sic.cache_file
205     end
206     assert_equal 'unable to locate a writable cache file', e.message
207   end
209   def test_flush
210     @sic.cache_data[@gem_repo] = @sice_new
211     @sic.update
212     @sic.flush
214     assert_equal [[@gem_repo, @sice_new]],
215                  read_cache(@sic.system_cache_file).to_a.sort
216   end
218   def test_latest_cache_data
219     util_make_gems
221     sice = Gem::SourceInfoCacheEntry.new @source_index, 0
223     @sic.set_cache_data @gem_repo => sice
224     latest = @sic.latest_cache_data
225     gems = latest[@gem_repo].source_index.search('a').map { |s| s.full_name }
227     assert_equal %w[a-2 a_evil-9], gems
228   end
230   def test_latest_cache_file
231     latest_cache_file = File.join File.dirname(@gemcache),
232                                   "latest_#{File.basename @gemcache}"
233     assert_equal latest_cache_file, @sic.latest_cache_file
234   end
236   def test_latest_system_cache_file
237     assert_equal File.join(Gem.dir, "latest_source_cache"),
238                  @sic.latest_system_cache_file
239   end
241   def test_latest_user_cache_file
242     assert_equal @latest_usrcache, @sic.latest_user_cache_file
243   end
245   def test_read_system_cache
246     assert_equal [[@gem_repo, @sys_sice]], @sic.cache_data.to_a.sort
247   end
249   def test_read_user_cache
250     FileUtils.chmod 0444, @sic.user_cache_file
251     FileUtils.chmod 0444, @sic.latest_user_cache_file
253     @si = Gem::SourceIndex.new
254     @si.add_specs @a1, @a2
256     @sice = Gem::SourceInfoCacheEntry.new @si, 0
258     @sic.set_cache_data({ @gem_repo => @sice })
259     @sic.update
260     @sic.write_cache
261     @sic.reset_cache_data
263     user_cache_data = @sic.cache_data.to_a.sort
265     assert_equal 1, user_cache_data.length
266     user_cache_data = user_cache_data.first
268     assert_equal @gem_repo, user_cache_data.first
270     gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name }
271     assert_equal [@a2.full_name], gems
272   end
274   def test_search
275     si = Gem::SourceIndex.new
276     si.add_spec @a1
277     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
278     @sic.instance_variable_set :@cache_data, cache_data
280     assert_equal [@a1], @sic.search(//)
281   end
283   def test_search_all
284     util_make_gems
286     sice = Gem::SourceInfoCacheEntry.new @source_index, 0
288     @sic.set_cache_data @gem_repo => sice
289     @sic.update
290     @sic.instance_variable_set :@only_latest, false
291     @sic.write_cache
292     @sic.reset_cache_data
294     gem_names = @sic.search(//, false, true).map { |spec| spec.full_name }
296     assert_equal %w[a-1 a-2 a_evil-9 c-1.2], gem_names
297   end
299   def test_search_dependency
300     si = Gem::SourceIndex.new
301     si.add_spec @a1
302     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
303     @sic.instance_variable_set :@cache_data, cache_data
305     dep = Gem::Dependency.new @a1.name, @a1.version
307     assert_equal [@a1], @sic.search(dep)
308   end
310   def test_search_no_matches
311     si = Gem::SourceIndex.new
312     si.add_spec @a1
313     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
314     @sic.instance_variable_set :@cache_data, cache_data
316     assert_equal [], @sic.search(/nonexistent/)
317   end
319   def test_search_no_matches_in_source
320     si = Gem::SourceIndex.new
321     si.add_spec @a1
322     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
323     @sic.instance_variable_set :@cache_data, cache_data
324     Gem.sources.replace %w[more-gems.example.com]
326     assert_equal [], @sic.search(/nonexistent/)
327   end
329   def test_search_with_source
330     si = Gem::SourceIndex.new
331     si.add_spec @a1
332     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
333     @sic.instance_variable_set :@cache_data, cache_data
335     assert_equal [[@a1, @gem_repo]],
336                  @sic.search_with_source(//)
337   end
339   def test_system_cache_file
340     assert_equal File.join(Gem.dir, "source_cache"), @sic.system_cache_file
341   end
343   def test_user_cache_file
344     assert_equal @usrcache, @sic.user_cache_file
345   end
347   def test_write_cache
348     @sic.cache_data[@gem_repo] = @sice_new
349     @sic.write_cache
351     assert_equal [[@gem_repo, @sice_new]],
352                  read_cache(@sic.system_cache_file).to_a.sort
353     assert_equal [[@gem_repo, @usr_sice]],
354                  read_cache(@sic.user_cache_file).to_a.sort
355   end
357   def test_write_cache_user
358     FileUtils.chmod 0444, @sic.system_cache_file
359     @sic.set_cache_data({@gem_repo => @sice_new})
360     @sic.update
361     @sic.write_cache
362     @sic.instance_variable_set :@only_latest, false
364     assert File.exist?(@sic.user_cache_file), 'user_cache_file'
365     assert File.exist?(@sic.latest_user_cache_file),
366            'latest_user_cache_file exists'
368     assert_equal [[@gem_repo, @sys_sice]],
369                  read_cache(@sic.system_cache_file).to_a.sort
370     assert_equal [[@gem_repo, @sice_new]],
371                  read_cache(@sic.user_cache_file).to_a.sort
372   end
374   def test_write_cache_user_from_scratch
375     FileUtils.rm_rf @sic.user_cache_file
376     FileUtils.rm_rf @sic.latest_user_cache_file
378     FileUtils.chmod 0444, @sic.system_cache_file
379     FileUtils.chmod 0444, @sic.latest_system_cache_file
381     @si = Gem::SourceIndex.new
382     @si.add_specs @a1, @a2
384     @sice = Gem::SourceInfoCacheEntry.new @si, 0
386     @sic.set_cache_data({ @gem_repo => @sice })
387     @sic.update
389     @sic.write_cache
391     assert File.exist?(@sic.user_cache_file), 'system_cache_file'
392     assert File.exist?(@sic.latest_user_cache_file),
393            'latest_system_cache_file'
395     user_cache_data = read_cache(@sic.user_cache_file).to_a.sort
396     assert_equal 1, user_cache_data.length, 'user_cache_data length'
397     user_cache_data = user_cache_data.first
399     assert_equal @gem_repo, user_cache_data.first
401     gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name }
402     assert_equal [@a1.full_name, @a2.full_name], gems
404     user_cache_data = read_cache(@sic.latest_user_cache_file).to_a.sort
405     assert_equal 1, user_cache_data.length
406     user_cache_data = user_cache_data.first
408     assert_equal @gem_repo, user_cache_data.first
410     gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name }
411     assert_equal [@a2.full_name], gems
412   end
414   def test_write_cache_user_no_directory
415     FileUtils.rm_rf File.dirname(@sic.user_cache_file)
416     FileUtils.chmod 0444, @sic.system_cache_file
417     @sic.set_cache_data({ @gem_repo => @sice_new })
418     @sic.update
419     @sic.write_cache
421     assert_equal [[@gem_repo, @sys_sice]],
422                  read_cache(@sic.system_cache_file).to_a.sort
423     assert_equal [[@gem_repo, @sys_sice]],
424                  read_cache(@sic.user_cache_file).to_a.sort
425     assert_equal [[@gem_repo, @sice_new]],
426                  read_cache(@sic.latest_user_cache_file).to_a.sort
427   end
429   def test_write_cache_user_only_latest
430     FileUtils.chmod 0444, @sic.system_cache_file
431     @sic.set_cache_data({@gem_repo => @sice_new})
432     @sic.update
433     @sic.write_cache
435     assert File.exist?(@sic.user_cache_file), 'user_cache_file'
436     assert File.exist?(@sic.latest_user_cache_file),
437            'latest_user_cache_file exists'
439     assert_equal [[@gem_repo, @sys_sice]],
440                  read_cache(@sic.system_cache_file).to_a.sort
441     assert_equal [[@gem_repo, @sice_new]],
442                  read_cache(@sic.user_cache_file).to_a.sort
443   end