~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-01-12 21:27:00 UTC
  • mto: This revision was merged to the branch mainline in revision 5605.
  • Revision ID: john@arbash-meinel.com-20110112212700-esqmtrmevddxrsq2
Clean up the test slightly, hoping to avoid race conditions, update NEWS

Show diffs side-by-side

added added

removed removed

Lines of Context:
40
40
    KnitVersionedFiles,
41
41
    PlainKnitContent,
42
42
    _VFContentMapGenerator,
 
43
    _DirectPackAccess,
43
44
    _KndxIndex,
44
45
    _KnitGraphIndex,
45
46
    _KnitKeyAccess,
46
47
    make_file_factory,
47
48
    )
48
49
from bzrlib.patiencediff import PatienceSequenceMatcher
49
 
from bzrlib.repofmt import (
50
 
    knitpack_repo,
51
 
    pack_repo,
52
 
    )
 
50
from bzrlib.repofmt import pack_repo
53
51
from bzrlib.tests import (
54
52
    TestCase,
55
53
    TestCaseWithMemoryTransport,
327
325
            transport.append_bytes(packname, bytes)
328
326
        writer = pack.ContainerWriter(write_data)
329
327
        writer.begin()
330
 
        access = pack_repo._DirectPackAccess({})
 
328
        access = _DirectPackAccess({})
331
329
        access.set_writer(writer, index, (transport, packname))
332
330
        return access, writer
333
331
 
340
338
        writer.end()
341
339
        return memos
342
340
 
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
 
 
370
341
    def make_vf_for_retrying(self):
371
342
        """Create 3 packs and a reload function.
372
343
 
399
370
        collection = repo._pack_collection
400
371
        collection.ensure_loaded()
401
372
        orig_packs = collection.packs
402
 
        packer = knitpack_repo.KnitPacker(collection, orig_packs, '.testpack')
 
373
        packer = pack_repo.Packer(collection, orig_packs, '.testpack')
403
374
        new_pack = packer.pack()
404
375
        # forget about the new pack
405
376
        collection.reset()
444
415
        except _TestException, e:
445
416
            retry_exc = errors.RetryWithNewPacks(None, reload_occurred=False,
446
417
                                                 exc_info=sys.exc_info())
447
 
        # GZ 2010-08-10: Cycle with exc_info affects 3 tests
448
418
        return retry_exc
449
419
 
450
420
    def test_read_from_several_packs(self):
459
429
        memos.extend(access.add_raw_records([('key', 5)], 'alpha'))
460
430
        writer.end()
461
431
        transport = self.get_transport()
462
 
        access = pack_repo._DirectPackAccess({"FOO":(transport, 'packfile'),
 
432
        access = _DirectPackAccess({"FOO":(transport, 'packfile'),
463
433
            "FOOBAR":(transport, 'pack2'),
464
434
            "BAZ":(transport, 'pack3')})
465
435
        self.assertEqual(['1234567890', '12345', 'alpha'],
475
445
 
476
446
    def test_set_writer(self):
477
447
        """The writer should be settable post construction."""
478
 
        access = pack_repo._DirectPackAccess({})
 
448
        access = _DirectPackAccess({})
479
449
        transport = self.get_transport()
480
450
        packname = 'packfile'
481
451
        index = 'foo'
493
463
        transport = self.get_transport()
494
464
        reload_called, reload_func = self.make_reload_func()
495
465
        # Note that the index key has changed from 'foo' to 'bar'
496
 
        access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')},
 
466
        access = _DirectPackAccess({'bar':(transport, 'packname')},
497
467
                                   reload_func=reload_func)
498
468
        e = self.assertListRaises(errors.RetryWithNewPacks,
499
469
                                  access.get_raw_records, memos)
508
478
        memos = self.make_pack_file()
509
479
        transport = self.get_transport()
510
480
        # Note that the index key has changed from 'foo' to 'bar'
511
 
        access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')})
 
481
        access = _DirectPackAccess({'bar':(transport, 'packname')})
512
482
        e = self.assertListRaises(KeyError, access.get_raw_records, memos)
513
483
 
514
484
    def test_missing_file_raises_retry(self):
516
486
        transport = self.get_transport()
517
487
        reload_called, reload_func = self.make_reload_func()
518
488
        # Note that the 'filename' has been changed to 'different-packname'
519
 
        access = pack_repo._DirectPackAccess(
520
 
            {'foo':(transport, 'different-packname')},
521
 
            reload_func=reload_func)
 
489
        access = _DirectPackAccess({'foo':(transport, 'different-packname')},
 
490
                                   reload_func=reload_func)
522
491
        e = self.assertListRaises(errors.RetryWithNewPacks,
523
492
                                  access.get_raw_records, memos)
524
493
        # The file has gone missing, so we assume we need to reload
532
501
        memos = self.make_pack_file()
533
502
        transport = self.get_transport()
534
503
        # Note that the 'filename' has been changed to 'different-packname'
535
 
        access = pack_repo._DirectPackAccess(
536
 
            {'foo': (transport, 'different-packname')})
 
504
        access = _DirectPackAccess({'foo':(transport, 'different-packname')})
537
505
        e = self.assertListRaises(errors.NoSuchFile,
538
506
                                  access.get_raw_records, memos)
539
507
 
543
511
        failing_transport = MockReadvFailingTransport(
544
512
                                [transport.get_bytes('packname')])
545
513
        reload_called, reload_func = self.make_reload_func()
546
 
        access = pack_repo._DirectPackAccess(
547
 
            {'foo': (failing_transport, 'packname')},
548
 
            reload_func=reload_func)
 
514
        access = _DirectPackAccess({'foo':(failing_transport, 'packname')},
 
515
                                   reload_func=reload_func)
549
516
        # Asking for a single record will not trigger the Mock failure
550
517
        self.assertEqual(['1234567890'],
551
518
            list(access.get_raw_records(memos[:1])))
567
534
        failing_transport = MockReadvFailingTransport(
568
535
                                [transport.get_bytes('packname')])
569
536
        reload_called, reload_func = self.make_reload_func()
570
 
        access = pack_repo._DirectPackAccess(
571
 
            {'foo':(failing_transport, 'packname')})
 
537
        access = _DirectPackAccess({'foo':(failing_transport, 'packname')})
572
538
        # Asking for a single record will not trigger the Mock failure
573
539
        self.assertEqual(['1234567890'],
574
540
            list(access.get_raw_records(memos[:1])))
579
545
                                  access.get_raw_records, memos)
580
546
 
581
547
    def test_reload_or_raise_no_reload(self):
582
 
        access = pack_repo._DirectPackAccess({}, reload_func=None)
 
548
        access = _DirectPackAccess({}, reload_func=None)
583
549
        retry_exc = self.make_retry_exception()
584
550
        # Without a reload_func, we will just re-raise the original exception
585
551
        self.assertRaises(_TestException, access.reload_or_raise, retry_exc)
586
552
 
587
553
    def test_reload_or_raise_reload_changed(self):
588
554
        reload_called, reload_func = self.make_reload_func(return_val=True)
589
 
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
 
555
        access = _DirectPackAccess({}, reload_func=reload_func)
590
556
        retry_exc = self.make_retry_exception()
591
557
        access.reload_or_raise(retry_exc)
592
558
        self.assertEqual([1], reload_called)
596
562
 
597
563
    def test_reload_or_raise_reload_no_change(self):
598
564
        reload_called, reload_func = self.make_reload_func(return_val=False)
599
 
        access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
 
565
        access = _DirectPackAccess({}, reload_func=reload_func)
600
566
        retry_exc = self.make_retry_exception()
601
567
        # If reload_occurred is False, then we consider it an error to have
602
568
        # reload_func() return False (no changes).
733
699
 
734
700
    def make_multiple_records(self):
735
701
        """Create the content for multiple records."""
736
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
702
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
737
703
        total_txt = []
738
704
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
739
705
                                        'foo\n'
742
708
                                        % (sha1sum,))
743
709
        record_1 = (0, len(gz_txt), sha1sum)
744
710
        total_txt.append(gz_txt)
745
 
        sha1sum = osutils.sha_string('baz\n')
 
711
        sha1sum = osutils.sha('baz\n').hexdigest()
746
712
        gz_txt = self.create_gz_content('version rev-id-2 1 %s\n'
747
713
                                        'baz\n'
748
714
                                        'end rev-id-2\n'
752
718
        return total_txt, record_1, record_2
753
719
 
754
720
    def test_valid_knit_data(self):
755
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
721
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
756
722
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
757
723
                                        'foo\n'
758
724
                                        'bar\n'
789
755
                         raw_contents)
790
756
 
791
757
    def test_not_enough_lines(self):
792
 
        sha1sum = osutils.sha_string('foo\n')
 
758
        sha1sum = osutils.sha('foo\n').hexdigest()
793
759
        # record says 2 lines data says 1
794
760
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
795
761
                                        'foo\n'
807
773
        self.assertEqual([(('rev-id-1',),  gz_txt, sha1sum)], raw_contents)
808
774
 
809
775
    def test_too_many_lines(self):
810
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
776
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
811
777
        # record says 1 lines data says 2
812
778
        gz_txt = self.create_gz_content('version rev-id-1 1 %s\n'
813
779
                                        'foo\n'
826
792
        self.assertEqual([(('rev-id-1',), gz_txt, sha1sum)], raw_contents)
827
793
 
828
794
    def test_mismatched_version_id(self):
829
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
795
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
830
796
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
831
797
                                        'foo\n'
832
798
                                        'bar\n'
845
811
            knit._read_records_iter_raw(records))
846
812
 
847
813
    def test_uncompressed_data(self):
848
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
814
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
849
815
        txt = ('version rev-id-1 2 %s\n'
850
816
               'foo\n'
851
817
               'bar\n'
865
831
            knit._read_records_iter_raw(records))
866
832
 
867
833
    def test_corrupted_data(self):
868
 
        sha1sum = osutils.sha_string('foo\nbar\n')
 
834
        sha1sum = osutils.sha('foo\nbar\n').hexdigest()
869
835
        gz_txt = self.create_gz_content('version rev-id-1 2 %s\n'
870
836
                                        'foo\n'
871
837
                                        'bar\n'
1193
1159
            self.assertRaises(errors.KnitCorrupt, index.keys)
1194
1160
        except TypeError, e:
1195
1161
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1196
 
                           ' not exceptions.IndexError')):
 
1162
                           ' not exceptions.IndexError')
 
1163
                and sys.version_info[0:2] >= (2,5)):
1197
1164
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1198
1165
                                  ' raising new style exceptions with python'
1199
1166
                                  ' >=2.5')
1212
1179
            self.assertRaises(errors.KnitCorrupt, index.keys)
1213
1180
        except TypeError, e:
1214
1181
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1215
 
                           ' not exceptions.ValueError')):
 
1182
                           ' not exceptions.ValueError')
 
1183
                and sys.version_info[0:2] >= (2,5)):
1216
1184
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1217
1185
                                  ' raising new style exceptions with python'
1218
1186
                                  ' >=2.5')
1231
1199
            self.assertRaises(errors.KnitCorrupt, index.keys)
1232
1200
        except TypeError, e:
1233
1201
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1234
 
                           ' not exceptions.ValueError')):
 
1202
                           ' not exceptions.ValueError')
 
1203
                and sys.version_info[0:2] >= (2,5)):
1235
1204
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1236
1205
                                  ' raising new style exceptions with python'
1237
1206
                                  ' >=2.5')
1248
1217
            self.assertRaises(errors.KnitCorrupt, index.keys)
1249
1218
        except TypeError, e:
1250
1219
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1251
 
                           ' not exceptions.ValueError')):
 
1220
                           ' not exceptions.ValueError')
 
1221
                and sys.version_info[0:2] >= (2,5)):
1252
1222
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1253
1223
                                  ' raising new style exceptions with python'
1254
1224
                                  ' >=2.5')
1265
1235
            self.assertRaises(errors.KnitCorrupt, index.keys)
1266
1236
        except TypeError, e:
1267
1237
            if (str(e) == ('exceptions must be strings, classes, or instances,'
1268
 
                           ' not exceptions.ValueError')):
 
1238
                           ' not exceptions.ValueError')
 
1239
                and sys.version_info[0:2] >= (2,5)):
1269
1240
                self.knownFailure('Pyrex <0.9.5 fails with TypeError when'
1270
1241
                                  ' raising new style exceptions with python'
1271
1242
                                  ' >=2.5')
2440
2411
        key_basis = ('bar',)
2441
2412
        key_missing = ('missing',)
2442
2413
        test.add_lines(key, (), ['foo\n'])
2443
 
        key_sha1sum = osutils.sha_string('foo\n')
 
2414
        key_sha1sum = osutils.sha('foo\n').hexdigest()
2444
2415
        sha1s = test.get_sha1s([key])
2445
2416
        self.assertEqual({key: key_sha1sum}, sha1s)
2446
2417
        self.assertEqual([], basis.calls)
2448
2419
        # directly (rather than via text reconstruction) so that remote servers
2449
2420
        # etc don't have to answer with full content.
2450
2421
        basis.add_lines(key_basis, (), ['foo\n', 'bar\n'])
2451
 
        basis_sha1sum = osutils.sha_string('foo\nbar\n')
 
2422
        basis_sha1sum = osutils.sha('foo\nbar\n').hexdigest()
2452
2423
        basis.calls = []
2453
2424
        sha1s = test.get_sha1s([key, key_missing, key_basis])
2454
2425
        self.assertEqual({key: key_sha1sum,