1
# Copyright (C) 2006-2010 Canonical Ltd
1
# Copyright (C) 2006-2011 Canonical Ltd
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
325
325
transport.append_bytes(packname, bytes)
326
326
writer = pack.ContainerWriter(write_data)
328
access = _DirectPackAccess({})
328
access = pack_repo._DirectPackAccess({})
329
329
access.set_writer(writer, index, (transport, packname))
330
330
return access, writer
341
def test_pack_collection_pack_retries(self):
342
"""An explicit pack of a pack collection succeeds even when a
343
concurrent pack happens.
345
builder = self.make_branch_builder('.')
346
builder.start_series()
347
builder.build_snapshot('rev-1', None, [
348
('add', ('', 'root-id', 'directory', None)),
349
('add', ('file', 'file-id', 'file', 'content\nrev 1\n')),
351
builder.build_snapshot('rev-2', ['rev-1'], [
352
('modify', ('file-id', 'content\nrev 2\n')),
354
builder.build_snapshot('rev-3', ['rev-2'], [
355
('modify', ('file-id', 'content\nrev 3\n')),
357
self.addCleanup(builder.finish_series)
358
b = builder.get_branch()
359
self.addCleanup(b.lock_write().unlock)
361
collection = repo._pack_collection
362
# Concurrently repack the repo.
363
reopened_repo = repo.bzrdir.open_repository()
341
368
def make_vf_for_retrying(self):
342
369
"""Create 3 packs and a reload function.
429
456
memos.extend(access.add_raw_records([('key', 5)], 'alpha'))
431
458
transport = self.get_transport()
432
access = _DirectPackAccess({"FOO":(transport, 'packfile'),
459
access = pack_repo._DirectPackAccess({"FOO":(transport, 'packfile'),
433
460
"FOOBAR":(transport, 'pack2'),
434
461
"BAZ":(transport, 'pack3')})
435
462
self.assertEqual(['1234567890', '12345', 'alpha'],
446
473
def test_set_writer(self):
447
474
"""The writer should be settable post construction."""
448
access = _DirectPackAccess({})
475
access = pack_repo._DirectPackAccess({})
449
476
transport = self.get_transport()
450
477
packname = 'packfile'
463
490
transport = self.get_transport()
464
491
reload_called, reload_func = self.make_reload_func()
465
492
# Note that the index key has changed from 'foo' to 'bar'
466
access = _DirectPackAccess({'bar':(transport, 'packname')},
493
access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')},
467
494
reload_func=reload_func)
468
495
e = self.assertListRaises(errors.RetryWithNewPacks,
469
496
access.get_raw_records, memos)
478
505
memos = self.make_pack_file()
479
506
transport = self.get_transport()
480
507
# Note that the index key has changed from 'foo' to 'bar'
481
access = _DirectPackAccess({'bar':(transport, 'packname')})
508
access = pack_repo._DirectPackAccess({'bar':(transport, 'packname')})
482
509
e = self.assertListRaises(KeyError, access.get_raw_records, memos)
484
511
def test_missing_file_raises_retry(self):
486
513
transport = self.get_transport()
487
514
reload_called, reload_func = self.make_reload_func()
488
515
# Note that the 'filename' has been changed to 'different-packname'
489
access = _DirectPackAccess({'foo':(transport, 'different-packname')},
490
reload_func=reload_func)
516
access = pack_repo._DirectPackAccess(
517
{'foo':(transport, 'different-packname')},
518
reload_func=reload_func)
491
519
e = self.assertListRaises(errors.RetryWithNewPacks,
492
520
access.get_raw_records, memos)
493
521
# The file has gone missing, so we assume we need to reload
501
529
memos = self.make_pack_file()
502
530
transport = self.get_transport()
503
531
# Note that the 'filename' has been changed to 'different-packname'
504
access = _DirectPackAccess({'foo':(transport, 'different-packname')})
532
access = pack_repo._DirectPackAccess(
533
{'foo': (transport, 'different-packname')})
505
534
e = self.assertListRaises(errors.NoSuchFile,
506
535
access.get_raw_records, memos)
511
540
failing_transport = MockReadvFailingTransport(
512
541
[transport.get_bytes('packname')])
513
542
reload_called, reload_func = self.make_reload_func()
514
access = _DirectPackAccess({'foo':(failing_transport, 'packname')},
515
reload_func=reload_func)
543
access = pack_repo._DirectPackAccess(
544
{'foo': (failing_transport, 'packname')},
545
reload_func=reload_func)
516
546
# Asking for a single record will not trigger the Mock failure
517
547
self.assertEqual(['1234567890'],
518
548
list(access.get_raw_records(memos[:1])))
534
564
failing_transport = MockReadvFailingTransport(
535
565
[transport.get_bytes('packname')])
536
566
reload_called, reload_func = self.make_reload_func()
537
access = _DirectPackAccess({'foo':(failing_transport, 'packname')})
567
access = pack_repo._DirectPackAccess(
568
{'foo':(failing_transport, 'packname')})
538
569
# Asking for a single record will not trigger the Mock failure
539
570
self.assertEqual(['1234567890'],
540
571
list(access.get_raw_records(memos[:1])))
545
576
access.get_raw_records, memos)
547
578
def test_reload_or_raise_no_reload(self):
548
access = _DirectPackAccess({}, reload_func=None)
579
access = pack_repo._DirectPackAccess({}, reload_func=None)
549
580
retry_exc = self.make_retry_exception()
550
581
# Without a reload_func, we will just re-raise the original exception
551
582
self.assertRaises(_TestException, access.reload_or_raise, retry_exc)
553
584
def test_reload_or_raise_reload_changed(self):
554
585
reload_called, reload_func = self.make_reload_func(return_val=True)
555
access = _DirectPackAccess({}, reload_func=reload_func)
586
access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
556
587
retry_exc = self.make_retry_exception()
557
588
access.reload_or_raise(retry_exc)
558
589
self.assertEqual([1], reload_called)
563
594
def test_reload_or_raise_reload_no_change(self):
564
595
reload_called, reload_func = self.make_reload_func(return_val=False)
565
access = _DirectPackAccess({}, reload_func=reload_func)
596
access = pack_repo._DirectPackAccess({}, reload_func=reload_func)
566
597
retry_exc = self.make_retry_exception()
567
598
# If reload_occurred is False, then we consider it an error to have
568
599
# reload_func() return False (no changes).
693
724
def create_gz_content(self, text):
695
gz_file = tuned_gzip.GzipFile(mode='wb', fileobj=sio)
726
gz_file = gzip.GzipFile(mode='wb', fileobj=sio)
696
727
gz_file.write(text)
698
729
return sio.getvalue()