1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
require 'spec_helper'
describe PuppetForge::LruCache do
it 'creates a cache key from a list of strings' do
expect { subject.class.new_key('foo', 'bar', 'baz') }.not_to raise_error
end
it 'creates a new instance' do
expect { PuppetForge::LruCache.new(1) }.not_to raise_error
end
it 'raises an error if max_size is not a positive integer' do
expect { PuppetForge::LruCache.new(-1) }.to raise_error(ArgumentError)
expect { PuppetForge::LruCache.new(0) }.to raise_error(ArgumentError)
expect { PuppetForge::LruCache.new(1.5) }.to raise_error(ArgumentError)
end
it 'defaults to a max_size of 30' do
expect(PuppetForge::LruCache.new.max_size).to eq(30)
end
it 'allows max_size to be set via the max_size parameter' do
expect(PuppetForge::LruCache.new(42).max_size).to eq(42)
end
it 'provides a #get method' do
expect(PuppetForge::LruCache.new).to respond_to(:get)
end
it 'provides a #put method' do
expect(PuppetForge::LruCache.new).to respond_to(:put)
end
it 'provides a #clear method' do
expect(PuppetForge::LruCache.new).to respond_to(:clear)
end
context 'with environment variables' do
around(:each) do |example|
@old_max_size = ENV['PUPPET_FORGE_MAX_CACHE_SIZE']
ENV['PUPPET_FORGE_MAX_CACHE_SIZE'] = '42'
example.run
ENV['PUPPET_FORGE_MAX_CACHE_SIZE'] = @old_max_size
end
it 'uses the value of the PUPPET_FORGE_MAX_CACHE_SIZE environment variable if present' do
expect(PuppetForge::LruCache.new.max_size).to eq(42)
end
end
context '#get' do
it 'returns nil if the key is not present in the cache' do
expect(PuppetForge::LruCache.new.get('foo')).to be_nil
end
it 'returns the cached value for the given key' do
cache = PuppetForge::LruCache.new
cache.put('foo', 'bar')
expect(cache.get('foo')).to eq('bar')
end
it 'moves the key to the front of the LRU list' do
cache = PuppetForge::LruCache.new
cache.put('foo', 'bar')
cache.put('baz', 'qux')
cache.get('foo')
expect(cache.send(:lru)).to eq(['foo', 'baz'])
end
it 'is thread-safe for get calls' do
cache = PuppetForge::LruCache.new
# Populate the cache with initial values
cache.put('foo', 'bar')
cache.put('baz', 'qux')
# Create two threads for concurrent cache get operations
thread_one = Thread.new do
100.times { expect(cache.get('foo')).to eq('bar') }
end
thread_two = Thread.new do
100.times { expect(cache.get('baz')).to eq('qux') }
end
# Wait for both threads to complete
thread_one.join
thread_two.join
end
end
context '#put' do
it 'adds the key to the front of the LRU list' do
cache = PuppetForge::LruCache.new
cache.put('foo', 'bar')
expect(cache.send(:lru)).to eq(['foo'])
end
it 'adds the value to the cache' do
cache = PuppetForge::LruCache.new
cache.put('foo', 'bar')
expect(cache.send(:cache)).to eq({ 'foo' => 'bar' })
end
it 'removes the least recently used item if the cache is full' do
cache = PuppetForge::LruCache.new(2)
cache.put('foo', 'bar')
cache.put('baz', 'qux')
cache.put('quux', 'corge')
expect(cache.send(:lru)).to eq(['quux', 'baz'])
end
it 'is thread-safe' do
cache = PuppetForge::LruCache.new
# Create two threads for concurrent cache operations
thread_one = Thread.new do
100.times { cache.put('foo', 'bar') }
end
thread_two = Thread.new do
100.times { cache.put('baz', 'qux') }
end
# Wait for both threads to complete
thread_one.join
thread_two.join
# At this point, we don't need to compare the LRU list,
# because the order may change due to concurrent puts.
# Instead, we simply expect the code to run without errors.
expect { thread_one.value }.not_to raise_error
expect { thread_two.value }.not_to raise_error
end
end
context '#clear' do
it 'clears the cache' do
cache = PuppetForge::LruCache.new
cache.put('foo', 'bar')
cache.put('baz', 'qux')
cache.clear
expect(cache.send(:lru).empty?).to be_truthy
expect(cache.send(:cache).empty?).to be_truthy
end
end
end
|