~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__simple_set.py

Merge the 2.1-simple-set branch

But revert the changes to bzrlib/_btree_serializer_pyx.pyx that didn't end up in that branch.
And restore the export and import headers.

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
    tests,
25
25
    )
26
26
 
27
 
from bzrlib.tests import (
28
 
    test__static_tuple,
29
 
    )
30
 
try:
31
 
    from bzrlib import _simple_set_pyx as _module
32
 
except ImportError:
33
 
    _module = None
34
 
try:
35
 
    from bzrlib._static_tuple_c import StaticTuple
36
 
except ImportError:
37
 
    from bzrlib._static_tuple_py import StaticTuple
 
27
try:
 
28
    from bzrlib import _simple_set_pyx
 
29
except ImportError:
 
30
    _simple_set_pyx = None
38
31
 
39
32
 
40
33
# Even though this is an extension, we don't permute the tests for a python
41
34
# version. As the plain python version is just a dict or set
42
35
 
43
 
class _CompiledStaticTupleInterned(tests.Feature):
 
36
class _CompiledSimpleSet(tests.Feature):
44
37
 
45
38
    def _probe(self):
46
 
        if _module is None:
 
39
        if _simple_set_pyx is None:
47
40
            return False
48
41
        return True
49
42
 
50
43
    def feature_name(self):
51
44
        return 'bzrlib._simple_set_pyx'
52
45
 
53
 
CompiledStaticTupleInterned = _CompiledStaticTupleInterned()
54
 
 
55
 
 
56
 
class TestStaticTupleInterned(tests.TestCase):
57
 
 
58
 
    _test_needs_features = [CompiledStaticTupleInterned, 
59
 
                            test__static_tuple.CompiledStaticTuple]
 
46
CompiledSimpleSet = _CompiledSimpleSet()
 
47
 
 
48
 
 
49
class TestSimpleSet(tests.TestCase):
 
50
 
 
51
    _test_needs_features = [CompiledSimpleSet]
 
52
    module = _simple_set_pyx
60
53
 
61
54
    def assertIn(self, obj, container):
62
55
        self.assertTrue(obj in container,
76
69
        assertRefcount actually creates a new pointer, as does calling
77
70
        sys.getrefcount. So pass the expected value *before* the call.
78
71
        """
79
 
        # I don't understand why it is count+3 here, but it seems to be
80
 
        # correct. If I check in the calling function, with:
81
 
        # self.assertEqual(count+1, sys.getrefcount(obj))
82
 
        # Then it works fine. Something about passing it to assertRefcount is
83
 
        # actually double-incrementing (and decrementing) the refcount
84
 
        self.assertEqual(count+3, sys.getrefcount(obj))
 
72
        # I'm not sure why the offset is 3, but I've check that in the caller,
 
73
        # an offset of 1 works, which is expected. Not sure why assertRefcount
 
74
        # is incrementing/decrementing 2 times
 
75
        self.assertEqual(count, sys.getrefcount(obj)-3)
85
76
 
86
77
    def test_initial(self):
87
 
        obj = _module.SimpleSet()
 
78
        obj = self.module.SimpleSet()
88
79
        self.assertEqual(0, len(obj))
89
 
        st = StaticTuple('foo', 'bar')
 
80
        st = ('foo', 'bar')
90
81
        self.assertFillState(0, 0, 0x3ff, obj)
91
82
 
92
83
    def test__lookup(self):
98
89
        #  ('a', 'a'), ('f', '4'), ('p', 'r'), ('q', '1'), ('F', 'T'),
99
90
        #  ('Q', 'Q'), ('V', 'd'), ('7', 'C')
100
91
        # all collide @ 643
101
 
        obj = _module.SimpleSet()
102
 
        offset, val = obj._test_lookup(StaticTuple('a', 'a'))
103
 
        self.assertEqual(643, offset)
104
 
        self.assertEqual('<null>', val)
105
 
        offset, val = obj._test_lookup(StaticTuple('f', '4'))
106
 
        self.assertEqual(643, offset)
107
 
        self.assertEqual('<null>', val)
108
 
        offset, val = obj._test_lookup(StaticTuple('p', 'r'))
 
92
        obj = self.module.SimpleSet()
 
93
        offset, val = obj._test_lookup(('a', 'a'))
 
94
        self.assertEqual(643, offset)
 
95
        self.assertEqual('<null>', val)
 
96
        offset, val = obj._test_lookup(('f', '4'))
 
97
        self.assertEqual(643, offset)
 
98
        self.assertEqual('<null>', val)
 
99
        offset, val = obj._test_lookup(('p', 'r'))
109
100
        self.assertEqual(643, offset)
110
101
        self.assertEqual('<null>', val)
111
102
 
112
103
    def test_get_set_del_with_collisions(self):
113
 
        obj = _module.SimpleSet()
114
 
        k1 = StaticTuple('a', 'a')
115
 
        k2 = StaticTuple('f', '4') # collides
116
 
        k3 = StaticTuple('p', 'r')
117
 
        k4 = StaticTuple('q', '1')
 
104
        obj = self.module.SimpleSet()
 
105
        k1 = ('a', 'a')
 
106
        k2 = ('f', '4') # collides
 
107
        k3 = ('p', 'r')
 
108
        k4 = ('q', '1')
118
109
        self.assertEqual((643, '<null>'), obj._test_lookup(k1))
119
110
        self.assertEqual((643, '<null>'), obj._test_lookup(k2))
120
111
        self.assertEqual((643, '<null>'), obj._test_lookup(k3))
160
151
        self.assertNotIn(k4, obj)
161
152
 
162
153
    def test_add(self):
163
 
        obj = _module.SimpleSet()
 
154
        obj = self.module.SimpleSet()
164
155
        self.assertFillState(0, 0, 0x3ff, obj)
165
 
        k1 = StaticTuple('foo')
 
156
        # We use this clumsy notation, because otherwise the refcounts are off.
 
157
        # I'm guessing the python compiler sees it is a static tuple, and adds
 
158
        # it to the function variables, or somesuch
 
159
        k1 = tuple(['foo'])
166
160
        self.assertRefcount(1, k1)
167
161
        self.assertIs(k1, obj.add(k1))
168
162
        self.assertFillState(1, 1, 0x3ff, obj)
172
166
        self.assertIs(k1, ktest)
173
167
        del ktest
174
168
        self.assertRefcount(2, k1)
175
 
        k2 = StaticTuple('foo')
 
169
        k2 = tuple(['foo'])
176
170
        self.assertRefcount(1, k2)
177
171
        self.assertIsNot(k1, k2)
178
172
        # doesn't add anything, so the counters shouldn't be adjusted
188
182
        del obj[k1]
189
183
        self.assertFillState(0, 1, 0x3ff, obj)
190
184
        self.assertRefcount(1, k1)
191
 
        k3 = StaticTuple('bar')
 
185
        k3 = tuple(['bar'])
192
186
        self.assertRefcount(1, k3)
193
187
        self.assertIs(k3, obj.add(k3))
194
188
        self.assertFillState(1, 2, 0x3ff, obj)
200
194
        self.assertRefcount(2, k3)
201
195
 
202
196
    def test_discard(self):
203
 
        obj = _module.SimpleSet()
204
 
        k1 = StaticTuple('foo')
205
 
        k2 = StaticTuple('foo')
206
 
        k3 = StaticTuple('bar')
 
197
        obj = self.module.SimpleSet()
 
198
        k1 = tuple(['foo'])
 
199
        k2 = tuple(['foo'])
 
200
        k3 = tuple(['bar'])
207
201
        self.assertRefcount(1, k1)
208
202
        self.assertRefcount(1, k2)
209
203
        self.assertRefcount(1, k3)
217
211
        self.assertRefcount(1, k3)
218
212
 
219
213
    def test__delitem__(self):
220
 
        obj = _module.SimpleSet()
221
 
        k1 = StaticTuple('foo')
222
 
        k2 = StaticTuple('foo')
223
 
        k3 = StaticTuple('bar')
 
214
        obj = self.module.SimpleSet()
 
215
        k1 = tuple(['foo'])
 
216
        k2 = tuple(['foo'])
 
217
        k3 = tuple(['bar'])
224
218
        self.assertRefcount(1, k1)
225
219
        self.assertRefcount(1, k2)
226
220
        self.assertRefcount(1, k3)
234
228
        self.assertRefcount(1, k3)
235
229
 
236
230
    def test__resize(self):
237
 
        obj = _module.SimpleSet()
238
 
        k1 = StaticTuple('foo')
239
 
        k2 = StaticTuple('bar')
240
 
        k3 = StaticTuple('baz')
 
231
        obj = self.module.SimpleSet()
 
232
        k1 = ('foo',)
 
233
        k2 = ('bar',)
 
234
        k3 = ('baz',)
241
235
        obj.add(k1)
242
236
        obj.add(k2)
243
237
        obj.add(k3)
264
258
        self.assertEqual((591, '<null>'), obj._test_lookup(k2))
265
259
 
266
260
    def test_add_and_remove_lots_of_items(self):
267
 
        obj = _module.SimpleSet()
 
261
        obj = self.module.SimpleSet()
268
262
        chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
269
263
        for i in chars:
270
264
            for j in chars:
271
 
                k = StaticTuple(i, j)
 
265
                k = (i, j)
272
266
                obj.add(k)
273
267
        num = len(chars)*len(chars)
274
268
        self.assertFillState(num, num, 0x1fff, obj)
275
269
        # Now delete all of the entries and it should shrink again
276
270
        for i in chars:
277
271
            for j in chars:
278
 
                k = StaticTuple(i, j)
 
272
                k = (i, j)
279
273
                obj.discard(k)
280
274
        # It should be back to 1024 wide mask, though there may still be some
281
275
        # dummy values in there
284
278
        self.assertTrue(obj.fill < 1024 / 5)
285
279
 
286
280
    def test__iter__(self):
287
 
        obj = _module.SimpleSet()
288
 
        k1 = StaticTuple('1')
289
 
        k2 = StaticTuple('1', '2')
290
 
        k3 = StaticTuple('3', '4')
 
281
        obj = self.module.SimpleSet()
 
282
        k1 = ('1',)
 
283
        k2 = ('1', '2')
 
284
        k3 = ('3', '4')
291
285
        obj.add(k1)
292
286
        obj.add(k2)
293
287
        obj.add(k3)
297
291
        self.assertEqual(sorted([k1, k2, k3]), sorted(all))
298
292
        iterator = iter(obj)
299
293
        iterator.next()
300
 
        obj.add(StaticTuple('foo'))
 
294
        obj.add(('foo',))
301
295
        # Set changed size
302
296
        self.assertRaises(RuntimeError, iterator.next)
303
297
        # And even removing an item still causes it to fail