~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_knit.py

  • Committer: John Arbash Meinel
  • Date: 2011-05-11 11:35:28 UTC
  • mto: This revision was merged to the branch mainline in revision 5851.
  • Revision ID: john@arbash-meinel.com-20110511113528-qepibuwxicjrbb2h
Break compatibility with python <2.6.

This includes auditing the code for places where we were doing
explicit 'sys.version' checks and removing them as appropriate.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006-2011 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
17
17
"""Tests for Knit data structure"""
18
18
 
19
19
from cStringIO import StringIO
20
 
import difflib
21
20
import gzip
22
21
import sys
23
22
 
24
23
from bzrlib import (
25
24
    errors,
26
 
    generate_ids,
27
25
    knit,
28
26
    multiparent,
29
27
    osutils,
30
28
    pack,
31
29
    tests,
 
30
    transport,
32
31
    )
33
32
from bzrlib.errors import (
34
 
    RevisionAlreadyPresent,
35
33
    KnitHeaderError,
36
 
    RevisionNotPresent,
37
34
    NoSuchFile,
38
35
    )
39
36
from bzrlib.index import *
40
37
from bzrlib.knit import (
41
38
    AnnotatedKnitContent,
42
39
    KnitContent,
43
 
    KnitSequenceMatcher,
44
40
    KnitVersionedFiles,
45
41
    PlainKnitContent,
46
42
    _VFContentMapGenerator,
47
 
    _DirectPackAccess,
48
43
    _KndxIndex,
49
44
    _KnitGraphIndex,
50
45
    _KnitKeyAccess,
51
46
    make_file_factory,
52
47
    )
53
 
from bzrlib.repofmt import pack_repo
 
48
from bzrlib.patiencediff import PatienceSequenceMatcher
 
49
from bzrlib.repofmt import (
 
50
    knitpack_repo,
 
51
    pack_repo,
 
52
    )
54
53
from bzrlib.tests import (
55
 
    Feature,
56
 
    KnownFailure,
57
54
    TestCase,
58
55
    TestCaseWithMemoryTransport,
59
56
    TestCaseWithTransport,
60
57
    TestNotApplicable,
61
58
    )
62
 
from bzrlib.transport import get_transport
63
 
from bzrlib.transport.memory import MemoryTransport
64
 
from bzrlib.tuned_gzip import GzipFile
65
59
from bzrlib.versionedfile import (
66
60
    AbsentContentFactory,
67
61
    ConstantMapper,
106
100
        line_delta = source_content.line_delta(target_content)
107
101
        delta_blocks = list(KnitContent.get_line_delta_blocks(line_delta,
108
102
            source_lines, target_lines))
109
 
        matcher = KnitSequenceMatcher(None, source_lines, target_lines)
110
 
        matcher_blocks = list(list(matcher.get_matching_blocks()))
 
103
        matcher = PatienceSequenceMatcher(None, source_lines, target_lines)
 
104
        matcher_blocks = list(matcher.get_matching_blocks())
111
105
        self.assertEqual(matcher_blocks, delta_blocks)
112
106
 
113
107
    def test_get_line_delta_blocks(self):
333
327
            transport.append_bytes(packname, bytes)
334
328
        writer = pack.ContainerWriter(write_data)
335
329
        writer.begin()
336
 
        access = _DirectPackAccess({})
 
330
        access = pack_repo._DirectPackAccess({})
337
331
        access.set_writer(writer, index, (transport, packname))
338
332
        return access, writer
339
333
 
346
340
        writer.end()
347
341
        return memos
348
342
 
 
343
    def test_pack_collection_pack_retries(self):
 
344
        """An explicit pack of a pack collection succeeds even when a
 
345
        concurrent pack happens.
 
346
        """
 
347
        builder = self.make_branch_builder('.')
 
348
        builder.start_series()
 
349
        builder.build_snapshot('rev-1', None, [
 
350
            ('add', ('', 'root-id', 'directory', None)),
 
351
            ('add', ('file', 'file-id', 'file', 'content\nrev 1\n')),
 
352
            ])
 
353
        builder.build_snapshot('rev-2', ['rev-1'], [
 
354
            ('modify', ('file-id', 'content\nrev 2\n')),
 
355
            ])
 
356
        builder.build_snapshot('rev-3', ['rev-2'], [
 
357
            ('modify', ('file-id', 'content\nrev 3\n')),
 
358
            ])
 
359
        self.addCleanup(builder.finish_series)
 
360
        b = builder.get_branch()
 
361
        self.addCleanup(b.lock_write().unlock)
 
362
        repo = b.repository
 
363
        collection = repo._pack_collection
 
364
        # Concurrently repack the repo.
 
365
        reopened_repo = repo.bzrdir.open_repository()
 
366
        reopened_repo.pack()
 
367
        # Pack the new pack.
 
368
        collection.pack()
 
369
 
349
370
    def make_vf_for_retrying(self):
350
371
        """Create 3 packs and a reload function.
351
372
 
378
399
        collection = repo._pack_collection
379
400
        collection.ensure_loaded()
380
401
        orig_packs = collection.packs
381
 
        packer = pack_repo.Packer(collection, orig_packs, '.testpack')
 
402
        packer = knitpack_repo.KnitPacker(collection, orig_packs, '.testpack')
382
403
        new_pack = packer.pack()
383
404
        # forget about the new pack
384
405
        collection.reset()
437
458
        memos.extend(access.add_raw_records([('key', 5)], 'alpha'))
438
459
        writer.end()
439
460
        transport = self.get_transport()
440
 
        access = _DirectPackAccess({"FOO":(transport, 'packfile'),
 
461
        access = pack_repo._DirectPackAccess({"FOO":(transport, 'packfile'),
441
462
            "FOOBAR":(transport, 'pack2'),
442
463
            "BAZ":(transport, 'pack3')})
443
464
        self.assertEqual(['1234567890', '12345', 'alpha'],
453
474
 
454
475
    def test_set_writer(self):
455
476
        """The writer should be settable post construction."""
456
 
        access = _DirectPackAccess({})
 
477
        access = pack_repo._DirectPackAccess({})
457
478
        transport = self.get_transport()
458
479
        packname = 'packfile'
459
480
        index = 'foo'
471
492
        transport = self.get_transport()
472
493
        reload_called, reload_func = self.make_reload_func()
473
494
        # Note that the index key has changed from 'foo' to 'bar'
474
 
        access = _DirectPackAccess({'bar':(transport, 'packname')},
 
495
        access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')},
475
496
                                   reload_func=reload_func)
476
497
        e = self.assertListRaises(errors.RetryWithNewPacks,
477
498
                                  access.get_raw_records, memos)
486
507
        memos = self.make_pack_file()
487
508
        transport = self.get_transport()
488
509
        # Note that the index key has changed from 'foo' to 'bar'
489
 
        access = _DirectPackAccess({'bar':(transport, 'packname')})
 
510
        access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')})
490
511
        e = self.assertListRaises(KeyError, access.get_raw_records, memos)
491
512
 
492
513
    def test_missing_file_raises_retry(self):
494
515
        transport = self.get_transport()
495
516
        reload_called, reload_func = self.make_reload_func()
496
517
        # Note that the 'filename' has been changed to 'different-packname'
497
 
        access = _DirectPackAccess({'foo':(transport, 'different-packname')},
498
 
                                   reload_func=reload_func)
 
518
        access = pack_repo._DirectPackAccess(
 
519
            {'foo':(transport, 'different-packname')},
 
520
            reload_func=reload_func)
499
521
        e = self.assertListRaises(errors.RetryWithNewPacks,
500
522
                                  access.get_raw_records, memos)
501
523
        # The file has gone missing, so we assume we need to reload
509
531
        memos = self.make_pack_file()
510
532
        transport = self.get_transport()
511
533
        # Note that the 'filename' has been changed to 'different-packname'
512
 
        access = _DirectPackAccess({'foo':(transport, 'different-packname')})
 
534
        access = pack_repo._DirectPackAccess(
 
535
            {'foo': (transport, 'different-packname')})
513
536
        e = self.assertListRaises(errors.NoSuchFile,
514
537
                                  access.get_raw_records, memos)
515
538
 
519
542
        failing_transport = MockReadvFailingTransport(
520
543
                                [transport.get_bytes('packname')])
521
544
        reload_called, reload_func = self.make_reload_func()
522
 
        access = _DirectPackAccess({'foo':(failing_transport, 'packname')},
523
 
                                   reload_func=reload_func)
 
545
        access = pack_repo._DirectPackAccess(
 
546
            {'foo': (failing_transport, 'packname')},
 
547
            reload_func=reload_func)
524
548
        # Asking for a single record will not trigger the Mock failure
525
549
        self.assertEqual(['1234567890'],
526
550
            list(access.get_raw_records(memos[:1])))
542
566
        failing_transport = MockReadvFailingTransport(
543
567
                                [transport.get_bytes('packname')])
544
568
        reload_called, reload_func = self.make_reload_func()
545
 
        access = _DirectPackAccess({'foo':(failing_transport, 'packname')})
 
569
        access = pack_repo._DirectPackAccess(
 
570
            {'foo':(failing_transport, 'packname')})
546
571
        # Asking for a single record will not trigger the Mock failure
547
572
        self.assertEqual(['1234567890'],
548
573
            list(access.get_raw_records(memos[:1])))
553
578
                                  access.get_raw_records, memos)
554
579
 
555
580
    def test_reload_or_raise_no_reload(self):
556
 
        access = _DirectPackAccess({}, reload_func=None)
 
581
        access = pack_repo._DirectPackAccess({}, reload_func=None)
557
582
        retry_exc = self.make_retry_exception()
558
583
        # Without a reload_func, we will just re-raise the original exception
559
584
        self.assertRaises(_TestException, access.reload_or_raise, retry_exc)
560
585
 
561
586
    def test_reload_or_raise_reload_changed(self):
562
587
        reload_called, reload_func = self.make_reload_func(return_val=True)
563
 
        access = _DirectPackAccess({}, reload_func=reload_func)
 
588
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
564
589
        retry_exc = self.make_retry_exception()
565
590
        access.reload_or_raise(retry_exc)
566
591
        self.assertEqual([1], reload_called)
570
595
 
571
596
    def test_reload_or_raise_reload_no_change(self):
572
597
        reload_called, reload_func = self.make_reload_func(return_val=False)
573
 
        access = _DirectPackAccess({}, reload_func=reload_func)
 
598
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
574
599
        retry_exc = self.make_retry_exception()
575
600
        # If reload_occurred is False, then we consider it an error to have
576
601
        # reload_func() return False (no changes).
1167
1192
            self.assertRaises(errors.KnitCorrupt, index.keys)
1168
1193
        except TypeError, e:
1169
1194
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1170
 
                           ' not exceptions.IndexError')
1171
 
                and sys.version_info[0:2] >= (2,5)):
 
1195
                           ' not exceptions.IndexError')):
1172
1196
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1173
1197
                                  ' raising new style exceptions with python'
1174
1198
                                  ' >=2.5')
1187
1211
            self.assertRaises(errors.KnitCorrupt, index.keys)
1188
1212
        except TypeError, e:
1189
1213
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1190
 
                           ' not exceptions.ValueError')
1191
 
                and sys.version_info[0:2] >= (2,5)):
 
1214
                           ' not exceptions.ValueError')):
1192
1215
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1193
1216
                                  ' raising new style exceptions with python'
1194
1217
                                  ' >=2.5')
1207
1230
            self.assertRaises(errors.KnitCorrupt, index.keys)
1208
1231
        except TypeError, e:
1209
1232
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1210
 
                           ' not exceptions.ValueError')
1211
 
                and sys.version_info[0:2] >= (2,5)):
 
1233
                           ' not exceptions.ValueError')):
1212
1234
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1213
1235
                                  ' raising new style exceptions with python'
1214
1236
                                  ' >=2.5')
1225
1247
            self.assertRaises(errors.KnitCorrupt, index.keys)
1226
1248
        except TypeError, e:
1227
1249
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1228
 
                           ' not exceptions.ValueError')
1229
 
                and sys.version_info[0:2] >= (2,5)):
 
1250
                           ' not exceptions.ValueError')):
1230
1251
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1231
1252
                                  ' raising new style exceptions with python'
1232
1253
                                  ' >=2.5')
1243
1264
            self.assertRaises(errors.KnitCorrupt, index.keys)
1244
1265
        except TypeError, e:
1245
1266
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1246
 
                           ' not exceptions.ValueError')
1247
 
                and sys.version_info[0:2] >= (2,5)):
 
1267
                           ' not exceptions.ValueError')):
1248
1268
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1249
1269
                                  ' raising new style exceptions with python'
1250
1270
                                  ' >=2.5')
1579
1599
        # could leave an empty .kndx file, which bzr would later claim was a
1580
1600
        # corrupted file since the header was not present. In reality, the file
1581
1601
        # just wasn't created, so it should be ignored.
1582
 
        t = get_transport('.')
 
1602
        t = transport.get_transport('.')
1583
1603
        t.put_bytes('test.kndx', '')
1584
1604
 
1585
1605
        knit = self.make_test_knit()
1586
1606
 
1587
1607
    def test_knit_index_checks_header(self):
1588
 
        t = get_transport('.')
 
1608
        t = transport.get_transport('.')
1589
1609
        t.put_bytes('test.kndx', '# not really a knit header\n\n')
1590
1610
        k = self.make_test_knit()
1591
1611
        self.assertRaises(KnitHeaderError, k.keys)