|
1 | 1 | # frozen_string_literal: true |
2 | 2 |
|
3 | 3 | require 'spec_helper' |
4 | | -require 'datadog/appsec/api_security/lru_cache' |
| 4 | +require 'datadog/core/utils/lru_cache' |
5 | 5 |
|
6 | | -RSpec.describe Datadog::AppSec::APISecurity::LRUCache do |
| 6 | +RSpec.describe Datadog::Core::Utils::LRUCache do |
7 | 7 | describe '#initialize' do |
8 | 8 | it { expect(described_class.new(3)).to be_empty } |
9 | 9 | it { expect { described_class.new('0') }.to raise_error(ArgumentError) } |
|
19 | 19 | end |
20 | 20 |
|
21 | 21 | context 'when key exists' do |
22 | | - before { lru_cache.fetch_or_store(:key) { 'value' } } |
| 22 | + before { lru_cache[:key] = 'value' } |
23 | 23 |
|
24 | 24 | it { expect(lru_cache[:key]).to eq('value') } |
25 | 25 | end |
26 | 26 |
|
27 | 27 | context 'when key exists and is accessed' do |
28 | 28 | it 'updates the key order' do |
29 | | - lru_cache.fetch_or_store(:key1) { 'value1' } |
30 | | - lru_cache.fetch_or_store(:key2) { 'value2' } |
31 | | - lru_cache.fetch_or_store(:key3) { 'value3' } |
| 29 | + lru_cache[:key1] = 'value1' |
| 30 | + lru_cache[:key2] = 'value2' |
| 31 | + lru_cache[:key3] = 'value3' |
32 | 32 |
|
33 | 33 | lru_cache[:key1] # NOTE: as key accessed, it's moved to the end of the list |
34 | | - lru_cache.fetch_or_store(:key4) { 'value4' } |
| 34 | + lru_cache[:key4] = 'value4' |
35 | 35 |
|
36 | 36 | aggregate_failures 'verifying LRU cache state after key access and eviction' do |
37 | 37 | expect(lru_cache[:key2]).to be_nil |
|
43 | 43 | end |
44 | 44 | end |
45 | 45 |
|
46 | | - describe '#store' do |
| 46 | + describe '#[]=' do |
47 | 47 | let(:lru_cache) { described_class.new(3) } |
48 | 48 |
|
49 | 49 | it 'stores a key-value pair' do |
50 | | - expect { lru_cache.store(:key, 'value') }.to change { lru_cache[:key] } |
| 50 | + expect { lru_cache[:key] = 'value' }.to change { lru_cache[:key] } |
51 | 51 | .from(nil).to('value') |
52 | 52 | end |
53 | 53 |
|
54 | 54 | it 'overwrites existing values' do |
55 | | - lru_cache.store(:key, 'old-value') |
| 55 | + lru_cache[:key] = 'old-value' |
56 | 56 |
|
57 | | - expect { lru_cache.store(:key, 'new-value') }.to change { lru_cache[:key] } |
| 57 | + expect { lru_cache[:key] = 'new-value' }.to change { lru_cache[:key] } |
58 | 58 | .from('old-value').to('new-value') |
59 | 59 | end |
60 | 60 |
|
61 | 61 | context 'when cache is full and an existing key is updated' do |
62 | 62 | it 'does not remove other entries' do |
63 | | - lru_cache.store(:key2, 'value2') |
64 | | - lru_cache.store(:key3, 'value3') |
65 | | - lru_cache.store(:key1, 'value1') |
| 63 | + lru_cache[:key2] = 'value2' |
| 64 | + lru_cache[:key3] = 'value3' |
| 65 | + lru_cache[:key1] = 'value1' |
66 | 66 |
|
67 | | - lru_cache.store(:key1, 'new-value1') |
68 | | - lru_cache.store(:key3, 'new-value3') |
69 | | - lru_cache.store(:key2, 'new-value2') |
| 67 | + lru_cache[:key1] = 'new-value1' |
| 68 | + lru_cache[:key3] = 'new-value3' |
| 69 | + lru_cache[:key2] = 'new-value2' |
70 | 70 |
|
71 | 71 | aggregate_failures 'verifying LRU cache contents' do |
72 | 72 | expect(lru_cache[:key1]).to eq('new-value1') |
|
78 | 78 |
|
79 | 79 | context 'when maximum size is reached' do |
80 | 80 | it 'evicts the least recently used item' do |
81 | | - lru_cache.store(:key1, 'value1') |
82 | | - lru_cache.store(:key2, 'value2') |
83 | | - lru_cache.store(:key3, 'value3') |
84 | | - lru_cache.store(:key4, 'value4') |
85 | | - |
86 | | - aggregate_failures 'verifying LRU cache state after eviction' do |
87 | | - expect(lru_cache[:key1]).to be_nil |
88 | | - expect(lru_cache[:key2]).to eq('value2') |
89 | | - expect(lru_cache[:key3]).to eq('value3') |
90 | | - expect(lru_cache[:key4]).to eq('value4') |
91 | | - end |
92 | | - end |
93 | | - end |
94 | | - end |
95 | | - |
96 | | - describe '#fetch_or_store' do |
97 | | - context 'when key does not exist' do |
98 | | - let(:lru_cache) { described_class.new(3) } |
99 | | - |
100 | | - it 'computes and stores the value' do |
101 | | - expect(lru_cache.fetch_or_store(:key) { 'value' }).to eq('value') |
102 | | - expect(lru_cache[:key]).to eq('value') |
103 | | - end |
104 | | - |
105 | | - it 'computes the missing key only once' do |
106 | | - expect { lru_cache.fetch_or_store(:key) { 'value' } } |
107 | | - .to change { lru_cache[:key] }.from(nil).to('value') |
108 | | - |
109 | | - expect { lru_cache.fetch_or_store(:key) { 'new-value' } } |
110 | | - .not_to(change { lru_cache[:key] }) |
111 | | - end |
112 | | - end |
113 | | - |
114 | | - context 'when maximum size is reached' do |
115 | | - let(:lru_cache) { described_class.new(3) } |
116 | | - |
117 | | - it 'evicts the least recently used item' do |
118 | | - lru_cache.fetch_or_store(:key1) { 'value1' } |
119 | | - lru_cache.fetch_or_store(:key2) { 'value2' } |
120 | | - lru_cache.fetch_or_store(:key3) { 'value3' } |
121 | | - lru_cache.fetch_or_store(:key4) { 'value4' } |
| 81 | + lru_cache[:key1] = 'value1' |
| 82 | + lru_cache[:key2] = 'value2' |
| 83 | + lru_cache[:key3] = 'value3' |
| 84 | + lru_cache[:key4] = 'value4' |
122 | 85 |
|
123 | 86 | aggregate_failures 'verifying LRU cache state after eviction' do |
124 | 87 | expect(lru_cache[:key1]).to be_nil |
|
134 | 97 | let(:lru_cache) { described_class.new(3) } |
135 | 98 |
|
136 | 99 | it 'removes all items from the cache' do |
137 | | - lru_cache.fetch_or_store(:key1) { 'value1' } |
138 | | - lru_cache.fetch_or_store(:key2) { 'value2' } |
| 100 | + lru_cache[:key1] = 'value1' |
| 101 | + lru_cache[:key2] = 'value2' |
139 | 102 |
|
140 | 103 | expect { lru_cache.clear }.to change { lru_cache[:key1] }.from('value1').to(nil) |
141 | 104 | .and change { lru_cache[:key2] }.from('value2').to(nil) |
|
147 | 110 | let(:lru_cache) { described_class.new(3) } |
148 | 111 |
|
149 | 112 | it 'returns false when cache has items' do |
150 | | - expect { lru_cache.fetch_or_store(:key) { 'value' } } |
| 113 | + expect { lru_cache[:key] = 'value' } |
151 | 114 | .to change { lru_cache.empty? }.from(true).to(false) |
152 | 115 | end |
153 | 116 | end |
|
0 commit comments