Updated MSpec source to 1c3ee1c8.
[rbx.git] / test / rubygems / test_gem_source_info_cache.rb
blob83cd100a9d4d55c30b80dfd6d2acc021e4f861f4
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     Gem::SourceInfoCache.instance_variable_set :@cache, nil
40   end
42   def test_self_cache_refreshes
43     Gem.configuration.update_sources = true #true by default
44     si = Gem::SourceIndex.new
45     si.add_spec @a1
47     @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump
49     Gem.sources.replace %W[#{@gem_repo}]
51     use_ui @ui do
52       assert_not_nil Gem::SourceInfoCache.cache
53       assert_kind_of Gem::SourceInfoCache, Gem::SourceInfoCache.cache
54       assert_equal Gem::SourceInfoCache.cache.object_id,
55                    Gem::SourceInfoCache.cache.object_id
56     end
58     assert_match %r|Bulk updating|, @ui.output
59   end
61   def test_self_cache_skips_refresh_based_on_configuration
62     Gem.configuration.update_sources = false
63     si = Gem::SourceIndex.new
64     si.add_spec @a1
66     @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump
68     Gem.sources.replace %w[#{@gem_repo}]
70     use_ui @ui do
71       assert_not_nil Gem::SourceInfoCache.cache
72       assert_kind_of Gem::SourceInfoCache, Gem::SourceInfoCache.cache
73       assert_equal Gem::SourceInfoCache.cache.object_id,
74                    Gem::SourceInfoCache.cache.object_id
75       assert_no_match %r|Bulk updating|, @ui.output
76     end
77   end
79   def test_self_cache_data
80     si = Gem::SourceIndex.new
81     si.add_spec @a1
83     @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = si.dump
85     Gem::SourceInfoCache.instance_variable_set :@cache, nil
86     sice = Gem::SourceInfoCacheEntry.new si, 0
88     use_ui @ui do
89       gems = Gem::SourceInfoCache.cache_data[@gem_repo].source_index.gems
90       gem_names = gems.map { |_, spec| spec.full_name }
92       assert_equal si.gems.map { |_,spec| spec.full_name }, gem_names
93     end
94   end
96   def test_cache_data
97     assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort
98   end
100   def test_cache_data_dirty
101     def @sic.dirty() @dirty; end
102     assert_equal false, @sic.dirty, 'clean on init'
103     @sic.cache_data
104     assert_equal false, @sic.dirty, 'clean on fetch'
105     @sic.update
106     @sic.cache_data
107     assert_equal true, @sic.dirty, 'still dirty'
108   end
110   def test_cache_data_irreparable
111     @fetcher.data["#{@gem_repo}Marshal.#{@marshal_version}"] = @source_index.dump
113     data = { @gem_repo => { 'totally' => 'borked' } }
115     cache_files = [
116       @sic.system_cache_file,
117       @sic.latest_system_cache_file,
118       @sic.user_cache_file,
119       @sic.latest_user_cache_file
120     ]
122     cache_files.each do |fn|
123       FileUtils.mkdir_p File.dirname(fn)
124       open(fn, "wb") { |f| f.write Marshal.dump(data) }
125     end
127     @sic.instance_eval { @cache_data = nil }
129     fetched = use_ui @ui do @sic.cache_data end
131     fetched_si = fetched["#{@gem_repo}"].source_index
133     assert_equal @source_index.index_signature, fetched_si.index_signature
134   end
136   def test_cache_data_none_readable
137     FileUtils.chmod 0222, @sic.system_cache_file
138     FileUtils.chmod 0222, @sic.latest_system_cache_file
139     FileUtils.chmod 0222, @sic.user_cache_file
140     FileUtils.chmod 0222, @sic.latest_user_cache_file
141     return if (File.stat(@sic.system_cache_file).mode & 0222) != 0222
142     return if (File.stat(@sic.user_cache_file).mode & 0222) != 0222
143     # HACK for systems that don't support chmod
144     assert_equal({}, @sic.cache_data)
145   end
147   def test_cache_data_none_writable
148     FileUtils.chmod 0444, @sic.system_cache_file
149     FileUtils.chmod 0444, @sic.user_cache_file
150     e = assert_raise RuntimeError do
151       @sic.cache_data
152     end
153     assert_equal 'unable to locate a writable cache file', e.message
154   end
156   def test_cache_data_nonexistent
157     FileUtils.rm @sic.system_cache_file
158     FileUtils.rm @sic.latest_system_cache_file
159     FileUtils.rm @sic.user_cache_file
160     FileUtils.rm @sic.latest_user_cache_file
162     # TODO test verbose output
163     assert_equal [], @sic.cache_data.to_a.sort
164   end
166   def test_cache_data_repair
167     data = {
168         @gem_repo => {
169           'cache' => Gem::SourceIndex.new,
170           'size' => 0,
171       }
172     }
173     [@sic.system_cache_file, @sic.user_cache_file].each do |fn|
174       FileUtils.mkdir_p File.dirname(fn)
175       open(fn, "wb") { |f| f.write Marshal.dump(data) }
176     end
178     @sic.instance_eval { @cache_data = nil }
180     expected = {
181         @gem_repo =>
182           Gem::SourceInfoCacheEntry.new(Gem::SourceIndex.new, 0)
183     }
184     assert_equal expected, @sic.cache_data
185   end
187   def test_cache_data_user_fallback
188     FileUtils.chmod 0444, @sic.system_cache_file
190     assert_equal [[@gem_repo, @usr_sice]], @sic.cache_data.to_a.sort
191   end
193   def test_cache_file
194     assert_equal @gemcache, @sic.cache_file
195   end
197   def test_cache_file_user_fallback
198     FileUtils.chmod 0444, @sic.system_cache_file
199     assert_equal @usrcache, @sic.cache_file
200   end
202   def test_cache_file_none_writable
203     FileUtils.chmod 0444, @sic.system_cache_file
204     FileUtils.chmod 0444, @sic.user_cache_file
205     e = assert_raise RuntimeError do
206       @sic.cache_file
207     end
208     assert_equal 'unable to locate a writable cache file', e.message
209   end
211   def test_flush
212     @sic.cache_data[@gem_repo] = @sice_new
213     @sic.update
214     @sic.flush
216     assert_equal [[@gem_repo, @sice_new]],
217                  read_cache(@sic.system_cache_file).to_a.sort
218   end
220   def test_latest_cache_data
221     util_make_gems
223     sice = Gem::SourceInfoCacheEntry.new @source_index, 0
225     @sic.set_cache_data @gem_repo => sice
226     latest = @sic.latest_cache_data
227     gems = latest[@gem_repo].source_index.search('a').map { |s| s.full_name }
229     assert_equal %w[a-2 a_evil-9], gems
230   end
232   def test_latest_cache_file
233     latest_cache_file = File.join File.dirname(@gemcache),
234                                   "latest_#{File.basename @gemcache}"
235     assert_equal latest_cache_file, @sic.latest_cache_file
236   end
238   def test_latest_system_cache_file
239     assert_equal File.join(Gem.dir, "latest_source_cache"),
240                  @sic.latest_system_cache_file
241   end
243   def test_latest_user_cache_file
244     assert_equal @latest_usrcache, @sic.latest_user_cache_file
245   end
247   def test_read_system_cache
248     assert_equal [[@gem_repo, @sys_sice]], @sic.cache_data.to_a.sort
249   end
251   def test_read_user_cache
252     FileUtils.chmod 0444, @sic.user_cache_file
253     FileUtils.chmod 0444, @sic.latest_user_cache_file
255     @si = Gem::SourceIndex.new
256     @si.add_specs @a1, @a2
258     @sice = Gem::SourceInfoCacheEntry.new @si, 0
260     @sic.set_cache_data({ @gem_repo => @sice })
261     @sic.update
262     @sic.write_cache
263     @sic.reset_cache_data
265     user_cache_data = @sic.cache_data.to_a.sort
267     assert_equal 1, user_cache_data.length
268     user_cache_data = user_cache_data.first
270     assert_equal @gem_repo, user_cache_data.first
272     gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name }
273     assert_equal [@a2.full_name], gems
274   end
276   def test_search
277     si = Gem::SourceIndex.new
278     si.add_spec @a1
279     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
280     @sic.instance_variable_set :@cache_data, cache_data
282     assert_equal [@a1], @sic.search(//)
283   end
285   def test_search_all
286     util_make_gems
288     sice = Gem::SourceInfoCacheEntry.new @source_index, 0
290     @sic.set_cache_data @gem_repo => sice
291     @sic.update
292     @sic.instance_variable_set :@only_latest, false
293     @sic.write_cache
294     @sic.reset_cache_data
296     gem_names = @sic.search(//, false, true).map { |spec| spec.full_name }
298     assert_equal %w[a-1 a-2 a_evil-9 c-1.2], gem_names
299   end
301   def test_search_dependency
302     si = Gem::SourceIndex.new
303     si.add_spec @a1
304     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
305     @sic.instance_variable_set :@cache_data, cache_data
307     dep = Gem::Dependency.new @a1.name, @a1.version
309     assert_equal [@a1], @sic.search(dep)
310   end
312   def test_search_no_matches
313     si = Gem::SourceIndex.new
314     si.add_spec @a1
315     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
316     @sic.instance_variable_set :@cache_data, cache_data
318     assert_equal [], @sic.search(/nonexistent/)
319   end
321   def test_search_no_matches_in_source
322     si = Gem::SourceIndex.new
323     si.add_spec @a1
324     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
325     @sic.instance_variable_set :@cache_data, cache_data
326     Gem.sources.replace %w[more-gems.example.com]
328     assert_equal [], @sic.search(/nonexistent/)
329   end
331   def test_search_with_source
332     si = Gem::SourceIndex.new
333     si.add_spec @a1
334     cache_data = { @gem_repo => Gem::SourceInfoCacheEntry.new(si, nil) }
335     @sic.instance_variable_set :@cache_data, cache_data
337     assert_equal [[@a1, @gem_repo]],
338                  @sic.search_with_source(//)
339   end
341   def test_system_cache_file
342     assert_equal File.join(Gem.dir, "source_cache"), @sic.system_cache_file
343   end
345   def test_user_cache_file
346     assert_equal @usrcache, @sic.user_cache_file
347   end
349   def test_write_cache
350     @sic.cache_data[@gem_repo] = @sice_new
351     @sic.write_cache
353     assert_equal [[@gem_repo, @sice_new]],
354                  read_cache(@sic.system_cache_file).to_a.sort
355     assert_equal [[@gem_repo, @usr_sice]],
356                  read_cache(@sic.user_cache_file).to_a.sort
357   end
359   def test_write_cache_user
360     FileUtils.chmod 0444, @sic.system_cache_file
361     @sic.set_cache_data({@gem_repo => @sice_new})
362     @sic.update
363     @sic.write_cache
364     @sic.instance_variable_set :@only_latest, false
366     assert File.exist?(@sic.user_cache_file), 'user_cache_file'
367     assert File.exist?(@sic.latest_user_cache_file),
368            'latest_user_cache_file exists'
370     assert_equal [[@gem_repo, @sys_sice]],
371                  read_cache(@sic.system_cache_file).to_a.sort
372     assert_equal [[@gem_repo, @sice_new]],
373                  read_cache(@sic.user_cache_file).to_a.sort
374   end
376   def test_write_cache_user_from_scratch
377     FileUtils.rm_rf @sic.user_cache_file
378     FileUtils.rm_rf @sic.latest_user_cache_file
380     FileUtils.chmod 0444, @sic.system_cache_file
381     FileUtils.chmod 0444, @sic.latest_system_cache_file
383     @si = Gem::SourceIndex.new
384     @si.add_specs @a1, @a2
386     @sice = Gem::SourceInfoCacheEntry.new @si, 0
388     @sic.set_cache_data({ @gem_repo => @sice })
389     @sic.update
391     @sic.write_cache
393     assert File.exist?(@sic.user_cache_file), 'system_cache_file'
394     assert File.exist?(@sic.latest_user_cache_file),
395            'latest_system_cache_file'
397     user_cache_data = read_cache(@sic.user_cache_file).to_a.sort
398     assert_equal 1, user_cache_data.length, 'user_cache_data length'
399     user_cache_data = user_cache_data.first
401     assert_equal @gem_repo, user_cache_data.first
403     gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name }
404     assert_equal [@a1.full_name, @a2.full_name], gems
406     user_cache_data = read_cache(@sic.latest_user_cache_file).to_a.sort
407     assert_equal 1, user_cache_data.length
408     user_cache_data = user_cache_data.first
410     assert_equal @gem_repo, user_cache_data.first
412     gems = user_cache_data.last.source_index.map { |_,spec| spec.full_name }
413     assert_equal [@a2.full_name], gems
414   end
416   def test_write_cache_user_no_directory
417     FileUtils.rm_rf File.dirname(@sic.user_cache_file)
418     FileUtils.chmod 0444, @sic.system_cache_file
419     @sic.set_cache_data({ @gem_repo => @sice_new })
420     @sic.update
421     @sic.write_cache
423     assert_equal [[@gem_repo, @sys_sice]],
424                  read_cache(@sic.system_cache_file).to_a.sort
425     assert_equal [[@gem_repo, @sys_sice]],
426                  read_cache(@sic.user_cache_file).to_a.sort
427     assert_equal [[@gem_repo, @sice_new]],
428                  read_cache(@sic.latest_user_cache_file).to_a.sort
429   end
431   def test_write_cache_user_only_latest
432     FileUtils.chmod 0444, @sic.system_cache_file
433     @sic.set_cache_data({@gem_repo => @sice_new})
434     @sic.update
435     @sic.write_cache
437     assert File.exist?(@sic.user_cache_file), 'user_cache_file'
438     assert File.exist?(@sic.latest_user_cache_file),
439            'latest_user_cache_file exists'
441     assert_equal [[@gem_repo, @sys_sice]],
442                  read_cache(@sic.system_cache_file).to_a.sort
443     assert_equal [[@gem_repo, @sice_new]],
444                  read_cache(@sic.user_cache_file).to_a.sort
445   end