/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test__simple_set.py

  • Committer: Marius Kruger
  • Date: 2010-07-10 21:28:56 UTC
  • mto: (5384.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5385.
  • Revision ID: marius.kruger@enerweb.co.za-20100710212856-uq4ji3go0u5se7hx
* Update documentation
* add NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2009, 2010, 2011 Canonical Ltd
 
1
# Copyright (C) 2009, 2010 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
18
18
 
19
19
import sys
20
20
 
21
 
from breezy import (
 
21
from bzrlib import (
 
22
    errors,
 
23
    osutils,
22
24
    tests,
23
25
    )
24
 
from breezy.tests import (
25
 
    features,
26
 
    )
27
26
 
28
27
try:
29
 
    from breezy import _simple_set_pyx
 
28
    from bzrlib import _simple_set_pyx
30
29
except ImportError:
31
30
    _simple_set_pyx = None
32
31
 
35
34
    """A simple object which has a fixed hash value.
36
35
 
37
36
    We could have used an 'int', but it turns out that Int objects don't
38
 
    implement tp_richcompare in Python 2.
 
37
    implement tp_richcompare...
39
38
    """
40
39
 
41
40
    def __init__(self, the_hash):
69
68
    def __eq__(self, other):
70
69
        raise RuntimeError('I refuse to play nice')
71
70
 
72
 
    __hash__ = _Hashable.__hash__
73
 
 
74
71
 
75
72
class _NoImplementCompare(_Hashable):
76
73
 
77
74
    def __eq__(self, other):
78
75
        return NotImplemented
79
76
 
80
 
    __hash__ = _Hashable.__hash__
81
 
 
82
77
 
83
78
# Even though this is an extension, we don't permute the tests for a python
84
79
# version. As the plain python version is just a dict or set
85
 
compiled_simpleset_feature = features.ModuleAvailableFeature(
86
 
    'breezy._simple_set_pyx')
 
80
compiled_simpleset_feature = tests.ModuleAvailableFeature(
 
81
                                'bzrlib._simple_set_pyx')
87
82
 
88
83
 
89
84
class TestSimpleSet(tests.TestCase):
91
86
    _test_needs_features = [compiled_simpleset_feature]
92
87
    module = _simple_set_pyx
93
88
 
 
89
    def assertIn(self, obj, container):
 
90
        self.assertTrue(obj in container,
 
91
            '%s not found in %s' % (obj, container))
 
92
 
 
93
    def assertNotIn(self, obj, container):
 
94
        self.assertTrue(obj not in container,
 
95
            'We found %s in %s' % (obj, container))
 
96
 
94
97
    def assertFillState(self, used, fill, mask, obj):
95
98
        self.assertEqual((used, fill, mask), (obj.used, obj.fill, obj.mask))
96
99
 
107
110
        # I'm not sure why the offset is 3, but I've check that in the caller,
108
111
        # an offset of 1 works, which is expected. Not sure why assertRefcount
109
112
        # is incrementing/decrementing 2 times
110
 
        self.assertEqual(count, sys.getrefcount(obj) - 3)
 
113
        self.assertEqual(count, sys.getrefcount(obj)-3)
111
114
 
112
115
    def test_initial(self):
113
116
        obj = self.module.SimpleSet()
114
117
        self.assertEqual(0, len(obj))
 
118
        st = ('foo', 'bar')
115
119
        self.assertFillState(0, 0, 0x3ff, obj)
116
120
 
117
121
    def test__lookup(self):
120
124
        obj = self.module.SimpleSet()
121
125
        self.assertLookup(643, '<null>', obj, _Hashable(643))
122
126
        self.assertLookup(643, '<null>', obj, _Hashable(643 + 1024))
123
 
        self.assertLookup(643, '<null>', obj, _Hashable(643 + 50 * 1024))
 
127
        self.assertLookup(643, '<null>', obj, _Hashable(643 + 50*1024))
124
128
 
125
129
    def test__lookup_collision(self):
126
130
        obj = self.module.SimpleSet()
140
144
        obj.add(k2)
141
145
        self.assertLookup(643, k1, obj, k1)
142
146
        self.assertLookup(644, k2, obj, k2)
143
 
        obj._py_resize(2047)  # resized to 2048
 
147
        obj._py_resize(2047) # resized to 2048
144
148
        self.assertEqual(2048, obj.mask + 1)
145
149
        self.assertLookup(643, k1, obj, k1)
146
 
        self.assertLookup(643 + 1024, k2, obj, k2)
147
 
        obj._py_resize(1023)  # resized back to 1024
 
150
        self.assertLookup(643+1024, k2, obj, k2)
 
151
        obj._py_resize(1023) # resized back to 1024
148
152
        self.assertEqual(1024, obj.mask + 1)
149
153
        self.assertLookup(643, k1, obj, k1)
150
154
        self.assertLookup(644, k2, obj, k2)
154
158
 
155
159
        h1 = 643
156
160
        h2 = 643 + 1024
157
 
        h3 = 643 + 1024 * 50
158
 
        h4 = 643 + 1024 * 25
 
161
        h3 = 643 + 1024*50
 
162
        h4 = 643 + 1024*25
159
163
        h5 = 644
160
164
        h6 = 644 + 1024
161
165
 
236
240
        # doesn't add anything, so the counters shouldn't be adjusted
237
241
        self.assertIs(k1, obj.add(k2))
238
242
        self.assertFillState(1, 1, 0x3ff, obj)
239
 
        self.assertRefcount(2, k1)  # not changed
240
 
        self.assertRefcount(1, k2)  # not incremented
 
243
        self.assertRefcount(2, k1) # not changed
 
244
        self.assertRefcount(1, k2) # not incremented
241
245
        self.assertIs(k1, obj[k1])
242
246
        self.assertIs(k1, obj[k2])
243
247
        self.assertRefcount(2, k1)
276
280
 
277
281
    def test__resize(self):
278
282
        obj = self.module.SimpleSet()
279
 
        # Need objects with exact hash as checking offset of <null> later
280
 
        k1 = _Hashable(501)
281
 
        k2 = _Hashable(591)
282
 
        k3 = _Hashable(2051)
 
283
        k1 = ('foo',)
 
284
        k2 = ('bar',)
 
285
        k3 = ('baz',)
283
286
        obj.add(k1)
284
287
        obj.add(k2)
285
288
        obj.add(k3)
338
341
 
339
342
    def test_add_and_remove_lots_of_items(self):
340
343
        obj = self.module.SimpleSet()
341
 
        chars = ('ABCDEFGHIJKLMNOPQRSTUVWXYZ'
342
 
                 'abcdefghijklmnopqrstuvwxyz1234567890')
 
344
        chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'
343
345
        for i in chars:
344
346
            for j in chars:
345
347
                k = (i, j)
346
348
                obj.add(k)
347
 
        num = len(chars) * len(chars)
 
349
        num = len(chars)*len(chars)
348
350
        self.assertFillState(num, num, 0x1fff, obj)
349
351
        # Now delete all of the entries and it should shrink again
350
352
        for i in chars:
370
372
            all.add(key)
371
373
        self.assertEqual(sorted([k1, k2, k3]), sorted(all))
372
374
        iterator = iter(obj)
373
 
        self.assertIn(next(iterator), all)
 
375
        iterator.next()
374
376
        obj.add(('foo',))
375
377
        # Set changed size
376
 
        self.assertRaises(RuntimeError, next, iterator)
 
378
        self.assertRaises(RuntimeError, iterator.next)
377
379
        # And even removing an item still causes it to fail
378
380
        obj.discard(k2)
379
 
        self.assertRaises(RuntimeError, next, iterator)
380
 
 
381
 
    def test__sizeof__(self):
382
 
        # SimpleSet needs a custom sizeof implementation, because it allocates
383
 
        # memory that Python cannot directly see (_table).
384
 
        # Too much variability in platform sizes for us to give a fixed size
385
 
        # here. However without a custom implementation, __sizeof__ would give
386
 
        # us only the size of the object, and not its table. We know the table
387
 
        # is at least 4bytes*1024entries in size.
388
 
        obj = self.module.SimpleSet()
389
 
        self.assertTrue(obj.__sizeof__() > 4096)
 
381
        self.assertRaises(RuntimeError, iterator.next)