require 'test/unit' require 'unicache' class TestableUniCache < UniCache attr_reader :cb attr_accessor :cb_table end class UniCacheTest < Test::Unit::TestCase def test_put_get c = UniCache.new( 2 ) assert_equal( 2, c.size ) c.put( 'foo', 'bar' ) assert_equal( 1, c.length ) c.put( 'dii', 'duu' ) assert_equal( 2, c.length ) assert_equal( 'duu', c.get( 'dii' ) ) assert_equal( 'bar', c.get( 'foo' ) ) c[ 'foo2' ] = 'bar' assert_equal( 2, c.length ) c[ 'dii2' ] = 'duu' assert_equal( 2, c.length ) assert_equal( 'duu', c[ 'dii2' ] ) assert_equal( 'bar', c[ 'foo2' ] ) assert_equal( nil, c.get( 'dii' ) ) assert_equal( nil, c.get( 'foo' ) ) end def test_eviction c = UniCache.new( 2 ) c[0] = 0 c[1] = 1 c[2] = 2 # 0 evicted. assert_equal( nil, c[0] ) assert_equal( 1, c[1] ) assert_equal( 2, c[2] ) # 1 latest. c[1] c[0] = 0 # 2 evicted as oldest. assert_equal( nil, c[2] ) assert_equal( 0, c[0] ) assert_equal( 1, c[1] ) assert_equal( nil, c[3] ) end def test_resize c = UniCache.new( 2 ) assert_equal( 2, c.size ) c.put( 'foo', 'bar' ) c.put( 'dii', 'duu' ) assert_equal( 2, c.length ) c.resize( 1 ) assert_equal( 1, c.length ) exception = false begin c.resize( 0 ) rescue UniCache::SizeError exception = true end assert_equal( true, exception ) c.put( 'foo', 'bar' ) c.put( 'dii', 'duu' ) assert_equal( 'duu', c.get( 'dii' ) ) assert_equal( nil, c.get( 'foo' ) ) end def test_existance c = UniCache.new( 2 ) c[0] = 0 c[2] = 2 c[1] = 1 assert_equal( nil, c.peek(0) ) assert_equal( 1, c.peek(1) ) assert_equal( 2, c.peek(2) ) assert_equal( false, c.exist?(0) ) assert_equal( true, c.exist?(1) ) assert_equal( true, c.exist?(2) ) # 2 should be evicted. c[0] = 0 assert_equal( true, c.exist?(0) ) assert_equal( true, c.exist?(1) ) assert_equal( false, c.exist?(2) ) c.remove( 0 ) assert_equal( 1, c.length ) assert_equal( true, c.exist?(1) ) assert_equal( 1, c.length ) c[2] = 2 assert_equal( 2, c.length ) oldest = c.remove assert_equal( [1,1], oldest ) c.clear exception = false begin c.remove( 0 ) rescue UniCache::RemoveError exception = true end assert_equal( true, exception ) assert_equal( 0, c.length ) assert_equal( 2, c.size ) assert_equal( false, c.exist?(1) ) assert_equal( false, c.exist?(0) ) # Clear for empty cache. c.clear end def test_callbacks c = TestableUniCache.new( 2 ) c.cb_table = {} # Register dummy callbacks. c.cb.ids.each do |type| eval "c.registerCallback( :#{type.to_s}, Proc.new{ |k,v,o| o.cb_table[ :#{type.to_s} ] = [ k, v ] } )" end c.removeCallback( :getdata ) c.registerCallback( :getdata, Proc.new{ |k| k+1 } ) # Wrong type. exception = false begin c.registerCallback( :my_callback, Proc.new {} ) rescue UniCache::CallbackError exception = true end assert_equal( true, exception ) # Invalid proc. exception = false begin c.registerCallback( :add, true ) rescue UniCache::CallbackError exception = true end assert_equal( true, exception ) c[0] = 0 assert_equal( {:add=>[0, 0], :put=>[0, 0]}, c.cb_table ) c.cb_table.clear c[0] = 1 assert_equal( {:overwrite=>[0, 1], :valueremove=>[0, 0], :put=>[0, 1]}, c.cb_table ) c.cb_table.clear c[0] assert_equal( {:hit=>[0, 1]}, c.cb_table ) c.cb_table.clear c[1] assert_equal( {:miss=>[1, nil], :add=>[1, 2], :put=>[1, 2]}, c.cb_table ) c.cb_table.clear c.removeCallback c.resize( 1 ) c[0] = 0 c[1] assert_equal( {}, c.cb_table ) c.cb_table.clear end def test_callbacks_open_close c = TestableUniCache.new( 2 ) c.registerCallback( :open, Proc.new{ |k,v,o| o.put( 'foo', 'bar' ) o.put( 'dii', 'duu' ) } ) c.registerCallback( :close, Proc.new{ |k,v,o| o.clear } ) c.open assert_equal( 'bar', c['foo'] ) assert_equal( 'duu', c['dii'] ) c.close assert_equal( nil, c['foo'] ) end def test_thread c = UniCache.new( 2 ) # Trying to destroy entry. t1 = Thread.new do sleep( 1 ) c.remove( 0 ) end c.registerCallback( :getdata, Proc.new do 'data' end ) gotValue = nil # Block value through get. t2 = Thread.new do c.get( 0 ) do |val| sleep( 4 ) gotValue = val end end # Distractions. t3 = Thread.new do sleep( 1 ) 100.times do c[0] c[0] = 2 end end [t1, t2, t3].each do |t| t.join end assert_equal( 'data', gotValue ) end def test_nosize c = UniCache.new( nil ) assert_equal( nil, c.size ) c.put( 'foo', 'bar' ) assert_equal( 1, c.length ) c.put( 'dii', 'duu' ) assert_equal( 2, c.length ) assert_equal( 'duu', c.get( 'dii' ) ) assert_equal( 'bar', c.get( 'foo' ) ) c[ 'foo2' ] = 'bar' assert_equal( 3, c.length ) c[ 'dii2' ] = 'duu' assert_equal( 4, c.length ) end end