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