/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__static_tuple.py

  • Committer: Robert Collins
  • Date: 2010-05-11 08:36:16 UTC
  • mto: This revision was merged to the branch mainline in revision 5223.
  • Revision ID: robertc@robertcollins.net-20100511083616-b8fjb19zomwupid0
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.

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
16
16
 
17
17
"""Tests for the StaticTuple type."""
18
18
 
19
 
try:
20
 
    import cPickle as pickle
21
 
except ImportError:
22
 
    import pickle
23
 
import operator
 
19
import cPickle
 
20
import gc
24
21
import sys
25
22
 
26
 
from breezy import (
 
23
from bzrlib import (
27
24
    _static_tuple_py,
28
25
    debug,
 
26
    errors,
29
27
    osutils,
30
28
    static_tuple,
31
29
    tests,
32
30
    )
33
 
from breezy.sixish import (
34
 
    PY3,
35
 
    text_type,
36
 
    )
37
 
from breezy.tests import (
38
 
    features,
39
 
    )
40
 
 
41
 
 
42
 
def load_tests(loader, standard_tests, pattern):
 
31
 
 
32
 
 
33
def load_tests(standard_tests, module, loader):
43
34
    """Parameterize tests for all versions of groupcompress."""
44
35
    global compiled_static_tuple_feature
45
36
    suite, compiled_static_tuple_feature = tests.permute_tests_for_extension(
46
 
        standard_tests, loader, 'breezy._static_tuple_py',
47
 
        'breezy._static_tuple_c')
 
37
        standard_tests, loader, 'bzrlib._static_tuple_py',
 
38
        'bzrlib._static_tuple_c')
48
39
    return suite
49
40
 
50
41
 
 
42
class _Meliae(tests.Feature):
 
43
 
 
44
    def _probe(self):
 
45
        try:
 
46
            from meliae import scanner
 
47
        except ImportError:
 
48
            return False
 
49
        return True
 
50
 
 
51
    def feature_name(self):
 
52
        return "Meliae - python memory debugger"
 
53
 
 
54
Meliae = _Meliae()
 
55
 
 
56
 
51
57
class TestStaticTuple(tests.TestCase):
52
58
 
53
59
    def assertRefcount(self, count, obj):
62
68
        # self.assertEqual(count, sys.getrefcount(obj)-1)
63
69
        # Then it works fine. Something about passing it to assertRefcount is
64
70
        # actually double-incrementing (and decrementing) the refcount
65
 
        self.assertEqual(count, sys.getrefcount(obj) - 3)
 
71
        self.assertEqual(count, sys.getrefcount(obj)-3)
66
72
 
67
73
    def test_create(self):
68
74
        k = self.module.StaticTuple('foo')
69
75
        k = self.module.StaticTuple('foo', 'bar')
70
76
 
71
77
    def test_create_bad_args(self):
72
 
        args_256 = ['a'] * 256
 
78
        args_256 = ['a']*256
73
79
        # too many args
74
80
        self.assertRaises(TypeError, self.module.StaticTuple, *args_256)
75
 
        args_300 = ['a'] * 300
 
81
        args_300 = ['a']*300
76
82
        self.assertRaises(TypeError, self.module.StaticTuple, *args_300)
77
83
        # not a string
78
84
        self.assertRaises(TypeError, self.module.StaticTuple, object())
112
118
    def test_concat_with_non_tuple(self):
113
119
        st1 = self.module.StaticTuple('foo')
114
120
        self.assertRaises(TypeError, lambda: st1 + 10)
115
 
 
 
121
        
116
122
    def test_as_tuple(self):
117
123
        k = self.module.StaticTuple('foo')
118
124
        t = k.as_tuple()
155
161
        self.assertEqual(2, len(k))
156
162
        k = self.module.StaticTuple('foo', 'bar', 'b', 'b', 'b', 'b', 'b')
157
163
        self.assertEqual(7, len(k))
158
 
        args = ['foo'] * 255
 
164
        args = ['foo']*255
159
165
        k = self.module.StaticTuple(*args)
160
166
        self.assertEqual(255, len(k))
161
167
 
174
180
        self.assertEqual('z', k[6])
175
181
        self.assertEqual('z', k[-1])
176
182
        self.assertRaises(IndexError, k.__getitem__, 7)
177
 
        self.assertRaises(IndexError, k.__getitem__, 256 + 7)
 
183
        self.assertRaises(IndexError, k.__getitem__, 256+7)
178
184
        self.assertRaises(IndexError, k.__getitem__, 12024)
179
185
        # Python's [] resolver handles the negative arguments, so we can't
180
186
        # really test StaticTuple_item() with negative values.
183
189
 
184
190
    def test_refcount(self):
185
191
        f = 'fo' + 'oo'
186
 
        num_refs = sys.getrefcount(f) - 1  # sys.getrefcount() adds one
 
192
        num_refs = sys.getrefcount(f) - 1 #sys.getrefcount() adds one
187
193
        k = self.module.StaticTuple(f)
188
194
        self.assertRefcount(num_refs + 1, f)
189
195
        b = k[0]
215
221
 
216
222
    def test_holds_int(self):
217
223
        k1 = self.module.StaticTuple(1)
218
 
 
219
224
        class subint(int):
220
225
            pass
221
226
        # But not a subclass, because subint could introduce refcycles
222
227
        self.assertRaises(TypeError, self.module.StaticTuple, subint(2))
223
228
 
224
229
    def test_holds_long(self):
225
 
        if PY3:
226
 
            self.skipTest("No long type on Python 3")
227
 
        k1 = self.module.StaticTuple(2**65)
228
 
 
 
230
        k1 = self.module.StaticTuple(2L**65)
229
231
        class sublong(long):
230
232
            pass
231
233
        # But not a subclass
233
235
 
234
236
    def test_holds_float(self):
235
237
        k1 = self.module.StaticTuple(1.2)
236
 
 
237
238
        class subfloat(float):
238
239
            pass
239
240
        self.assertRaises(TypeError, self.module.StaticTuple, subfloat(1.5))
240
241
 
241
 
    def test_holds_bytes(self):
242
 
        k1 = self.module.StaticTuple(b'astring')
243
 
 
244
 
        class substr(bytes):
 
242
    def test_holds_str(self):
 
243
        k1 = self.module.StaticTuple('astring')
 
244
        class substr(str):
245
245
            pass
246
 
        self.assertRaises(TypeError, self.module.StaticTuple, substr(b'a'))
 
246
        self.assertRaises(TypeError, self.module.StaticTuple, substr('a'))
247
247
 
248
248
    def test_holds_unicode(self):
249
249
        k1 = self.module.StaticTuple(u'\xb5')
250
 
 
251
 
        class subunicode(text_type):
 
250
        class subunicode(unicode):
252
251
            pass
253
252
        self.assertRaises(TypeError, self.module.StaticTuple,
254
253
                          subunicode(u'\xb5'))
293
292
        k6 = self.module.StaticTuple(k3, k4)
294
293
        self.assertCompareEqual(k5, k6)
295
294
 
296
 
    def check_strict_compare(self, k1, k2, mismatched_types):
297
 
        """True if on Python 3 and stricter comparison semantics are used."""
298
 
        if PY3 and mismatched_types:
299
 
            for op in ("ge", "gt", "le", "lt"):
300
 
                self.assertRaises(TypeError, getattr(operator, op), k1, k2)
301
 
            return True
302
 
        return False
303
 
 
304
 
    def assertCompareDifferent(self, k_small, k_big, mismatched_types=False):
 
295
    def assertCompareDifferent(self, k_small, k_big):
305
296
        self.assertFalse(k_small == k_big)
 
297
        self.assertFalse(k_small >= k_big)
 
298
        self.assertFalse(k_small > k_big)
306
299
        self.assertTrue(k_small != k_big)
307
 
        if not self.check_strict_compare(k_small, k_big, mismatched_types):
308
 
            self.assertFalse(k_small >= k_big)
309
 
            self.assertFalse(k_small > k_big)
310
 
            self.assertTrue(k_small <= k_big)
311
 
            self.assertTrue(k_small < k_big)
 
300
        self.assertTrue(k_small <= k_big)
 
301
        self.assertTrue(k_small < k_big)
312
302
 
313
 
    def assertCompareNoRelation(self, k1, k2, mismatched_types=False):
 
303
    def assertCompareNoRelation(self, k1, k2):
314
304
        """Run the comparison operators, make sure they do something.
315
305
 
316
306
        However, we don't actually care what comes first or second. This is
319
309
        """
320
310
        self.assertFalse(k1 == k2)
321
311
        self.assertTrue(k1 != k2)
322
 
        if not self.check_strict_compare(k1, k2, mismatched_types):
323
 
            # Do the comparison, but we don't care about the result
324
 
            k1 >= k2
325
 
            k1 > k2
326
 
            k1 <= k2
327
 
            k1 < k2
 
312
        # Do the comparison, but we don't care about the result
 
313
        k1 >= k2
 
314
        k1 > k2
 
315
        k1 <= k2
 
316
        k1 < k2
328
317
 
329
318
    def test_compare_vs_none(self):
330
319
        k1 = self.module.StaticTuple('baz', 'bing')
331
 
        self.assertCompareDifferent(None, k1, mismatched_types=True)
332
 
 
 
320
        self.assertCompareDifferent(None, k1)
 
321
    
333
322
    def test_compare_cross_class(self):
334
323
        k1 = self.module.StaticTuple('baz', 'bing')
335
 
        self.assertCompareNoRelation(10, k1, mismatched_types=True)
336
 
        self.assertCompareNoRelation('baz', k1, mismatched_types=True)
 
324
        self.assertCompareNoRelation(10, k1)
 
325
        self.assertCompareNoRelation('baz', k1)
337
326
 
338
327
    def test_compare_all_different_same_width(self):
339
328
        k1 = self.module.StaticTuple('baz', 'bing')
360
349
        k4 = self.module.StaticTuple(k1, k2)
361
350
        self.assertCompareDifferent(k3, k4)
362
351
        k5 = self.module.StaticTuple('foo', None)
363
 
        self.assertCompareDifferent(k5, k1, mismatched_types=True)
364
 
        self.assertCompareDifferent(k5, k2, mismatched_types=True)
 
352
        self.assertCompareDifferent(k5, k1)
 
353
        self.assertCompareDifferent(k5, k2)
365
354
 
366
355
    def test_compare_diff_width(self):
367
356
        k1 = self.module.StaticTuple('foo')
375
364
        k1 = self.module.StaticTuple('foo', 'bar')
376
365
        k2 = self.module.StaticTuple('foo', 1, None, u'\xb5', 1.2, 2**65, True,
377
366
                                     k1)
378
 
        self.assertCompareNoRelation(k1, k2, mismatched_types=True)
 
367
        self.assertCompareNoRelation(k1, k2)
379
368
        k3 = self.module.StaticTuple('foo')
380
369
        self.assertCompareDifferent(k3, k1)
381
370
        k4 = self.module.StaticTuple(None)
382
 
        self.assertCompareDifferent(k4, k1, mismatched_types=True)
 
371
        self.assertCompareDifferent(k4, k1)
383
372
        k5 = self.module.StaticTuple(1)
384
 
        self.assertCompareNoRelation(k1, k5, mismatched_types=True)
 
373
        self.assertCompareNoRelation(k1, k5)
385
374
 
386
375
    def test_compare_to_tuples(self):
387
376
        k1 = self.module.StaticTuple('foo')
397
386
        self.assertCompareDifferent(('foo',), k2)
398
387
        self.assertCompareDifferent(('foo', 'aaa'), k2)
399
388
        self.assertCompareDifferent(('baz', 'bing'), k2)
400
 
        self.assertCompareDifferent(('foo', 10), k2, mismatched_types=True)
 
389
        self.assertCompareDifferent(('foo', 10), k2)
401
390
 
402
391
        k3 = self.module.StaticTuple(k1, k2)
403
392
        self.assertCompareEqual(k3, (('foo',), ('foo', 'bar')))
413
402
        # This requires comparing a StaticTuple to a 'string', and then
414
403
        # interpreting that value in the next higher StaticTuple. This used to
415
404
        # generate a PyErr_BadIternalCall. We now fall back to *something*.
416
 
        self.assertCompareNoRelation(k1, k2, mismatched_types=True)
 
405
        self.assertCompareNoRelation(k1, k2)
417
406
 
418
407
    def test_hash(self):
419
408
        k = self.module.StaticTuple('foo')
441
430
        k = self.module.StaticTuple('foo', 'bar', 'baz', 'bing')
442
431
        self.assertEqual(('foo', 'bar'), k[:2])
443
432
        self.assertEqual(('baz',), k[2:-1])
444
 
        self.assertEqual(('foo', 'baz',), k[::2])
445
 
        self.assertRaises(TypeError, k.__getitem__, 'not_slice')
 
433
        try:
 
434
            val = k[::2]
 
435
        except TypeError:
 
436
            # C implementation raises a TypeError, we don't need the
 
437
            # implementation yet, so allow this to pass
 
438
            pass
 
439
        else:
 
440
            # Python implementation uses a regular Tuple, so make sure it gives
 
441
            # the right result
 
442
            self.assertEqual(('foo', 'baz'), val)
446
443
 
447
444
    def test_referents(self):
448
445
        # We implement tp_traverse so that things like 'meliae' can measure the
449
446
        # amount of referenced memory. Unfortunately gc.get_referents() first
450
447
        # checks the IS_GC flag before it traverses anything. We could write a
451
448
        # helper func, but that won't work for the generic implementation...
452
 
        self.requireFeature(features.meliae)
 
449
        self.requireFeature(Meliae)
453
450
        from meliae import scanner
454
451
        strs = ['foo', 'bar', 'baz', 'bing']
455
452
        k = self.module.StaticTuple(*strs)
457
454
            refs = strs + [self.module.StaticTuple]
458
455
        else:
459
456
            refs = strs
460
 
        def key(k):
461
 
            if isinstance(k, type):
462
 
                return (0, k)
463
 
            if isinstance(k, str):
464
 
                return (1, k)
465
 
            raise TypeError(k)
466
 
        self.assertEqual(
467
 
            sorted(refs, key=key),
468
 
            sorted(scanner.get_referents(k), key=key))
 
457
        self.assertEqual(sorted(refs), sorted(scanner.get_referents(k)))
469
458
 
470
459
    def test_nested_referents(self):
471
 
        self.requireFeature(features.meliae)
 
460
        self.requireFeature(Meliae)
472
461
        from meliae import scanner
473
462
        strs = ['foo', 'bar', 'baz', 'bing']
474
463
        k1 = self.module.StaticTuple(*strs[:2])
477
466
        refs = [k1, k2]
478
467
        if self.module is _static_tuple_py:
479
468
            refs.append(self.module.StaticTuple)
480
 
        def key(k):
481
 
            if isinstance(k, type):
482
 
                return (0, k)
483
 
            if isinstance(k, self.module.StaticTuple):
484
 
                return (1, k)
485
 
            raise TypeError(k)
486
 
 
487
 
        self.assertEqual(sorted(refs, key=key),
488
 
                         sorted(scanner.get_referents(k3), key=key))
 
469
        self.assertEqual(sorted(refs),
 
470
                         sorted(scanner.get_referents(k3)))
489
471
 
490
472
    def test_empty_is_singleton(self):
491
473
        key = self.module.StaticTuple()
508
490
 
509
491
    def test__c_intern_handles_refcount(self):
510
492
        if self.module is _static_tuple_py:
511
 
            return  # Not applicable
 
493
            return # Not applicable
512
494
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
513
495
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
514
496
        key = self.module.StaticTuple(unique_str1, unique_str2)
543
525
 
544
526
    def test__c_keys_are_not_immortal(self):
545
527
        if self.module is _static_tuple_py:
546
 
            return  # Not applicable
 
528
            return # Not applicable
547
529
        unique_str1 = 'unique str ' + osutils.rand_chars(20)
548
530
        unique_str2 = 'unique str ' + osutils.rand_chars(20)
549
531
        key = self.module.StaticTuple(unique_str1, unique_str2)
614
596
 
615
597
    def test_pickle(self):
616
598
        st = self.module.StaticTuple('foo', 'bar')
617
 
        pickled = pickle.dumps(st)
618
 
        unpickled = pickle.loads(pickled)
 
599
        pickled = cPickle.dumps(st)
 
600
        unpickled = cPickle.loads(pickled)
619
601
        self.assertEqual(unpickled, st)
620
602
 
621
603
    def test_pickle_empty(self):
622
604
        st = self.module.StaticTuple()
623
 
        pickled = pickle.dumps(st)
624
 
        unpickled = pickle.loads(pickled)
 
605
        pickled = cPickle.dumps(st)
 
606
        unpickled = cPickle.loads(pickled)
625
607
        self.assertIs(st, unpickled)
626
608
 
627
609
    def test_pickle_nested(self):
628
610
        st = self.module.StaticTuple('foo', self.module.StaticTuple('bar'))
629
 
        pickled = pickle.dumps(st)
630
 
        unpickled = pickle.loads(pickled)
 
611
        pickled = cPickle.dumps(st)
 
612
        unpickled = cPickle.loads(pickled)
631
613
        self.assertEqual(unpickled, st)
632
614
 
633
615
    def test_static_tuple_thunk(self):
634
616
        # Make sure the right implementation is available from
635
 
        # breezy.static_tuple.StaticTuple.
 
617
        # bzrlib.static_tuple.StaticTuple.
636
618
        if self.module is _static_tuple_py:
637
619
            if compiled_static_tuple_feature.available():
638
620
                # We will be using the C version