/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
1
# Copyright (C) 2008 Canonical Ltd
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
16
17
"""Tests for the fifo_cache module."""
18
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
19
from .. import (
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
20
    fifo_cache,
21
    tests,
22
    )
23
24
25
class TestFIFOCache(tests.TestCase):
26
    """Test that FIFO cache properly keeps track of entries."""
27
28
    def test_add_is_present(self):
29
        c = fifo_cache.FIFOCache()
30
        c[1] = 2
31
        self.assertTrue(1 in c)
32
        self.assertEqual(1, len(c))
33
        self.assertEqual(2, c[1])
34
        self.assertEqual(2, c.get(1))
35
        self.assertEqual(2, c.get(1, None))
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
36
        self.assertEqual([1], list(c))
7479.2.1 by Jelmer Vernooij
Drop python2 support.
37
        self.assertEqual({1}, c.keys())
38
        self.assertEqual([(1, 2)], sorted(c.items()))
39
        self.assertEqual([2], sorted(c.values()))
3885.1.4 by John Arbash Meinel
Implement setdefault.
40
        self.assertEqual({1: 2}, c)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
41
3882.6.11 by John Arbash Meinel
comment update
42
    def test_cache_size(self):
43
        c = fifo_cache.FIFOCache()
44
        self.assertEqual(100, c.cache_size())
45
        c.resize(20, 5)
46
        self.assertEqual(20, c.cache_size())
47
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
48
    def test_missing(self):
49
        c = fifo_cache.FIFOCache()
50
        self.assertRaises(KeyError, c.__getitem__, 1)
51
        self.assertFalse(1 in c)
52
        self.assertEqual(0, len(c))
53
        self.assertEqual(None, c.get(1))
54
        self.assertEqual(None, c.get(1, None))
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
55
        self.assertEqual([], list(c))
7479.2.1 by Jelmer Vernooij
Drop python2 support.
56
        self.assertEqual(set(), c.keys())
57
        self.assertEqual([], list(c.items()))
58
        self.assertEqual([], list(c.values()))
3885.1.4 by John Arbash Meinel
Implement setdefault.
59
        self.assertEqual({}, c)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
60
61
    def test_add_maintains_fifo(self):
62
        c = fifo_cache.FIFOCache(4, 4)
63
        c[1] = 2
64
        c[2] = 3
65
        c[3] = 4
66
        c[4] = 5
7479.2.1 by Jelmer Vernooij
Drop python2 support.
67
        self.assertEqual({1, 2, 3, 4}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
68
        c[5] = 6
69
        # This should pop out the oldest entry
7479.2.1 by Jelmer Vernooij
Drop python2 support.
70
        self.assertEqual({2, 3, 4, 5}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
71
        # Replacing an item doesn't change the stored keys
72
        c[2] = 7
7479.2.1 by Jelmer Vernooij
Drop python2 support.
73
        self.assertEqual({2, 3, 4, 5}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
74
        # But it does change the position in the FIFO
75
        c[6] = 7
7479.2.1 by Jelmer Vernooij
Drop python2 support.
76
        self.assertEqual({2, 4, 5, 6}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
77
        self.assertEqual([4, 5, 2, 6], list(c._queue))
78
79
    def test_default_after_cleanup_count(self):
80
        c = fifo_cache.FIFOCache(5)
81
        self.assertEqual(4, c._after_cleanup_count)
82
        c[1] = 2
83
        c[2] = 3
84
        c[3] = 4
85
        c[4] = 5
86
        c[5] = 6
87
        # So far, everything fits
7479.2.1 by Jelmer Vernooij
Drop python2 support.
88
        self.assertEqual({1, 2, 3, 4, 5}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
89
        c[6] = 7
90
        # But adding one more should shrink down to after_cleanup_count
7479.2.1 by Jelmer Vernooij
Drop python2 support.
91
        self.assertEqual({3, 4, 5, 6}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
92
93
    def test_clear(self):
94
        c = fifo_cache.FIFOCache(5)
95
        c[1] = 2
96
        c[2] = 3
97
        c[3] = 4
98
        c[4] = 5
99
        c[5] = 6
100
        c.cleanup()
7479.2.1 by Jelmer Vernooij
Drop python2 support.
101
        self.assertEqual({2, 3, 4, 5}, c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
102
        c.clear()
7479.2.1 by Jelmer Vernooij
Drop python2 support.
103
        self.assertEqual(set(), c.keys())
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
104
        self.assertEqual([], list(c._queue))
3885.1.4 by John Arbash Meinel
Implement setdefault.
105
        self.assertEqual({}, c)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
106
107
    def test_copy_not_implemented(self):
108
        c = fifo_cache.FIFOCache()
109
        self.assertRaises(NotImplementedError, c.copy)
110
111
    def test_pop_not_implemeted(self):
112
        c = fifo_cache.FIFOCache()
113
        self.assertRaises(NotImplementedError, c.pop, 'key')
114
115
    def test_popitem_not_implemeted(self):
116
        c = fifo_cache.FIFOCache()
117
        self.assertRaises(NotImplementedError, c.popitem)
118
3882.6.11 by John Arbash Meinel
comment update
119
    def test_resize_smaller(self):
120
        c = fifo_cache.FIFOCache()
121
        c[1] = 2
122
        c[2] = 3
123
        c[3] = 4
124
        c[4] = 5
125
        c[5] = 6
126
        # No cleanup, because it is the exact size
127
        c.resize(5)
128
        self.assertEqual({1: 2, 2: 3, 3: 4, 4: 5, 5: 6}, c)
129
        self.assertEqual(5, c.cache_size())
130
        # Adding one more will trigger a cleanup, though
131
        c[6] = 7
132
        self.assertEqual({3: 4, 4: 5, 5: 6, 6: 7}, c)
133
        c.resize(3, 2)
134
        self.assertEqual({5: 6, 6: 7}, c)
135
136
    def test_resize_larger(self):
137
        c = fifo_cache.FIFOCache(5, 4)
138
        c[1] = 2
139
        c[2] = 3
140
        c[3] = 4
141
        c[4] = 5
142
        c[5] = 6
143
        # No cleanup, because it is the exact size
144
        c.resize(10)
145
        self.assertEqual({1: 2, 2: 3, 3: 4, 4: 5, 5: 6}, c)
146
        self.assertEqual(10, c.cache_size())
147
        c[6] = 7
148
        c[7] = 8
149
        c[8] = 9
150
        c[9] = 10
151
        c[10] = 11
152
        self.assertEqual({1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9,
153
                          9: 10, 10: 11}, c)
154
        c[11] = 12
155
        self.assertEqual({4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10, 10: 11,
156
                          11: 12}, c)
157
3885.1.4 by John Arbash Meinel
Implement setdefault.
158
    def test_setdefault(self):
159
        c = fifo_cache.FIFOCache(5, 4)
160
        c['one'] = 1
161
        c['two'] = 2
162
        c['three'] = 3
163
        myobj = object()
164
        self.assertIs(myobj, c.setdefault('four', myobj))
165
        self.assertEqual({'one': 1, 'two': 2, 'three': 3, 'four': myobj}, c)
166
        self.assertEqual(3, c.setdefault('three', myobj))
167
        c.setdefault('five', myobj)
168
        c.setdefault('six', myobj)
169
        self.assertEqual({'three': 3, 'four': myobj, 'five': myobj,
170
                          'six': myobj}, c)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
171
3885.1.3 by John Arbash Meinel
Implement update
172
    def test_update(self):
173
        c = fifo_cache.FIFOCache(5, 4)
174
        # We allow an iterable
175
        c.update([(1, 2), (3, 4)])
176
        self.assertEqual({1: 2, 3: 4}, c)
177
        # Or kwarg form
178
        c.update(foo=3, bar=4)
179
        self.assertEqual({1: 2, 3: 4, 'foo': 3, 'bar': 4}, c)
180
        # Even a dict (This triggers a cleanup)
181
        c.update({'baz': 'biz', 'bing': 'bang'})
182
        self.assertEqual({'foo': 3, 'bar': 4, 'baz': 'biz', 'bing': 'bang'}, c)
183
        # We only allow 1 iterable, just like dict
184
        self.assertRaises(TypeError, c.update, [(1, 2)], [(3, 4)])
185
        # But you can mix and match. kwargs take precedence over iterable
186
        c.update([('a', 'b'), ('d', 'e')], a='c', q='r')
187
        self.assertEqual({'baz': 'biz', 'bing': 'bang',
188
                          'a': 'c', 'd': 'e', 'q': 'r'}, c)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
189
190
    def test_cleanup_funcs(self):
191
        log = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
192
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
193
        def logging_cleanup(key, value):
194
            log.append((key, value))
195
        c = fifo_cache.FIFOCache(5, 4)
196
        c.add(1, 2, cleanup=logging_cleanup)
197
        c.add(2, 3, cleanup=logging_cleanup)
198
        c.add(3, 4, cleanup=logging_cleanup)
7143.15.2 by Jelmer Vernooij
Run autopep8.
199
        c.add(4, 5, cleanup=None)  # no cleanup for 4
200
        c[5] = 6  # no cleanup for 5
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
201
        self.assertEqual([], log)
202
        # Adding another key should cleanup 1 & 2
3885.1.5 by John Arbash Meinel
Add tests that *adding* an entry also triggers the cleanup code.
203
        c.add(6, 7, cleanup=logging_cleanup)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
204
        self.assertEqual([(1, 2), (2, 3)], log)
205
        del log[:]
3885.1.5 by John Arbash Meinel
Add tests that *adding* an entry also triggers the cleanup code.
206
        # replacing 3 should trigger a cleanup
207
        c.add(3, 8, cleanup=logging_cleanup)
3885.1.1 by John Arbash Meinel
Start working on a FIFOCache.
208
        self.assertEqual([(3, 4)], log)
3885.1.5 by John Arbash Meinel
Add tests that *adding* an entry also triggers the cleanup code.
209
        del log[:]
210
        c[3] = 9
211
        self.assertEqual([(3, 8)], log)
212
        del log[:]
213
        # Clearing everything should call all remaining cleanups
214
        c.clear()
215
        self.assertEqual([(6, 7)], log)
3885.1.6 by John Arbash Meinel
Test that del x[foo] also triggers a cleanup.
216
        del log[:]
217
        c.add(8, 9, cleanup=logging_cleanup)
218
        # __delitem__ should also trigger a cleanup
219
        del c[8]
220
        self.assertEqual([(8, 9)], log)
3885.1.2 by John Arbash Meinel
Add a test which fails because we don't call cleanup funcs during deconstruction.
221
222
    def test_cleanup_at_deconstruct(self):
223
        log = []
7143.15.2 by Jelmer Vernooij
Run autopep8.
224
3885.1.2 by John Arbash Meinel
Add a test which fails because we don't call cleanup funcs during deconstruction.
225
        def logging_cleanup(key, value):
226
            log.append((key, value))
227
        c = fifo_cache.FIFOCache()
228
        c.add(1, 2, cleanup=logging_cleanup)
229
        del c
5967.8.2 by Martin Pool
test_fifo_cache shouldn't have a knownfailure for something that's impossible
230
        # As a matter of design, bzr does not (can not) count on anything
231
        # being run from Python __del__ methods, because they may not run for
232
        # a long time, and because in cPython merely having them defined
233
        # interferes with garbage collection.
234
        self.assertEqual([], log)
3885.1.7 by John Arbash Meinel
Add a FIFOSizeCache which is constrained based on the size of the values.
235
236
237
class TestFIFOSizeCache(tests.TestCase):
238
239
    def test_add_is_present(self):
240
        c = fifo_cache.FIFOSizeCache()
241
        c[1] = '2'
242
        self.assertTrue(1 in c)
243
        self.assertEqual(1, len(c))
244
        self.assertEqual('2', c[1])
245
        self.assertEqual('2', c.get(1))
246
        self.assertEqual('2', c.get(1, None))
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
247
        self.assertEqual([1], list(c))
7479.2.1 by Jelmer Vernooij
Drop python2 support.
248
        self.assertEqual({1}, c.keys())
249
        self.assertEqual([(1, '2')], sorted(c.items()))
250
        self.assertEqual(['2'], sorted(c.values()))
3885.1.7 by John Arbash Meinel
Add a FIFOSizeCache which is constrained based on the size of the values.
251
        self.assertEqual({1: '2'}, c)
7143.15.2 by Jelmer Vernooij
Run autopep8.
252
        self.assertEqual(1024 * 1024, c.cache_size())
3885.1.7 by John Arbash Meinel
Add a FIFOSizeCache which is constrained based on the size of the values.
253
254
    def test_missing(self):
255
        c = fifo_cache.FIFOSizeCache()
256
        self.assertRaises(KeyError, c.__getitem__, 1)
257
        self.assertFalse(1 in c)
258
        self.assertEqual(0, len(c))
259
        self.assertEqual(None, c.get(1))
260
        self.assertEqual(None, c.get(1, None))
6656.1.1 by Martin
Apply 2to3 dict fixer and clean up resulting mess using view helpers
261
        self.assertEqual([], list(c))
7479.2.1 by Jelmer Vernooij
Drop python2 support.
262
        self.assertEqual(set(), c.keys())
263
        self.assertEqual([], list(c.items()))
264
        self.assertEqual([], list(c.values()))
3885.1.7 by John Arbash Meinel
Add a FIFOSizeCache which is constrained based on the size of the values.
265
        self.assertEqual({}, c)
266
267
    def test_add_maintains_fifo(self):
268
        c = fifo_cache.FIFOSizeCache(10, 8)
269
        c[1] = 'ab'
270
        c[2] = 'cde'
271
        c[3] = 'fghi'
272
        self.assertEqual({1: 'ab', 2: 'cde', 3: 'fghi'}, c)
7143.15.2 by Jelmer Vernooij
Run autopep8.
273
        c[4] = 'jkl'  # Collapse
3885.1.7 by John Arbash Meinel
Add a FIFOSizeCache which is constrained based on the size of the values.
274
        self.assertEqual({3: 'fghi', 4: 'jkl'}, c)
275
        # Replacing an item will bump it to the end of the queue
276
        c[3] = 'mnop'
277
        self.assertEqual({3: 'mnop', 4: 'jkl'}, c)
278
        c[5] = 'qrst'
279
        self.assertEqual({3: 'mnop', 5: 'qrst'}, c)
280
281
    def test_adding_large_key(self):
282
        c = fifo_cache.FIFOSizeCache(10, 8)
7143.15.2 by Jelmer Vernooij
Run autopep8.
283
        c[1] = 'abcdefgh'  # Adding a large key won't get cached at all
3885.1.7 by John Arbash Meinel
Add a FIFOSizeCache which is constrained based on the size of the values.
284
        self.assertEqual({}, c)
285
        c[1] = 'abcdefg'
286
        self.assertEqual({1: 'abcdefg'}, c)
287
        # Replacing with a too-large key will remove it
288
        c[1] = 'abcdefgh'
289
        self.assertEqual({}, c)
290
        self.assertEqual(0, c._value_size)
3882.6.11 by John Arbash Meinel
comment update
291
292
    def test_resize_smaller(self):
293
        c = fifo_cache.FIFOSizeCache(20, 16)
294
        c[1] = 'a'
295
        c[2] = 'bc'
296
        c[3] = 'def'
297
        c[4] = 'ghij'
298
        # No cleanup, because it is the exact size
299
        c.resize(10, 8)
300
        self.assertEqual({1: 'a', 2: 'bc', 3: 'def', 4: 'ghij'}, c)
301
        self.assertEqual(10, c.cache_size())
302
        # Adding one more will trigger a cleanup, though
303
        c[5] = 'k'
304
        self.assertEqual({3: 'def', 4: 'ghij', 5: 'k'}, c)
305
        c.resize(5, 4)
306
        self.assertEqual({5: 'k'}, c)
307
308
    def test_resize_larger(self):
309
        c = fifo_cache.FIFOSizeCache(10, 8)
310
        c[1] = 'a'
311
        c[2] = 'bc'
312
        c[3] = 'def'
313
        c[4] = 'ghij'
314
        c.resize(12, 10)
315
        self.assertEqual({1: 'a', 2: 'bc', 3: 'def', 4: 'ghij'}, c)
316
        c[5] = 'kl'
317
        self.assertEqual({1: 'a', 2: 'bc', 3: 'def', 4: 'ghij', 5: 'kl'}, c)
318
        c[6] = 'mn'
319
        self.assertEqual({4: 'ghij', 5: 'kl', 6: 'mn'}, c)