Beispiel #1
0
 def test_add_revision_inventory_sha1(self):
     inv = inventory.Inventory(revision_id='A')
     inv.root.revision = 'A'
     inv.root.file_id = 'fixed-root'
     # Insert the inventory on its own to an identical repository, to get
     # its sha1.
     reference_repo = self.make_repository('reference_repo')
     reference_repo.lock_write()
     reference_repo.start_write_group()
     inv_sha1 = reference_repo.add_inventory('A', inv, [])
     reference_repo.abort_write_group()
     reference_repo.unlock()
     # Now insert a revision with this inventory, and it should get the same
     # sha1.
     repo = self.make_repository('repo')
     repo.lock_write()
     repo.start_write_group()
     root_id = inv.root.file_id
     repo.texts.add_lines(('fixed-root', 'A'), [], [])
     repo.add_revision('A', _mod_revision.Revision(
             'A', committer='B', timestamp=0,
             timezone=0, message='C'), inv=inv)
     repo.commit_write_group()
     repo.unlock()
     repo.lock_read()
     self.assertEqual(inv_sha1, repo.get_revision('A').inventory_sha1)
     repo.unlock()
Beispiel #2
0
 def create_branch_with_ghost_text(self):
     builder = self.make_branch_builder('ghost')
     builder.build_snapshot(
         'A-id', None,
         [('add', ('', 'root-id', 'directory', None)),
          ('add', ('a', 'a-file-id', 'file', 'some content\n'))])
     b = builder.get_branch()
     old_rt = b.repository.revision_tree('A-id')
     new_inv = inventory.mutable_inventory_from_tree(old_rt)
     new_inv.revision_id = 'B-id'
     new_inv['a-file-id'].revision = 'ghost-id'
     new_rev = _mod_revision.Revision(
         'B-id',
         timestamp=time.time(),
         timezone=0,
         message='Committing against a ghost',
         committer='Joe Foo <*****@*****.**>',
         properties={},
         parent_ids=('A-id', 'ghost-id'),
     )
     b.lock_write()
     self.addCleanup(b.unlock)
     b.repository.start_write_group()
     b.repository.add_revision('B-id', new_rev, new_inv)
     self.disable_commit_write_group_paranoia(b.repository)
     b.repository.commit_write_group()
     return b
Beispiel #3
0
 def read_revision_from_string(self, text):
     # TODO: consider writing a Revision decoder, rather than using the
     #       generic bencode decoder
     #       However, to decode all 25k revisions of bzr takes approx 1.3s
     #       If we remove all extra validation that goes down to about 1.2s.
     #       Of that time, probably 0.6s is spend in bencode.bdecode().
     #       Regardless 'time bzr log' of everything is 7+s, so 1.3s to
     #       extract revision texts isn't a majority of time.
     ret = bencode.bdecode(text)
     if not isinstance(ret, list):
         raise ValueError("invalid revision text")
     schema = self._schema
     # timezone is allowed to be missing, but should be set
     bits = {'timezone': None}
     for key, value in ret:
         # Will raise KeyError if not a valid part of the schema, or an
         # entry is given 2 times.
         var_name, expected_type, validator = schema[key]
         if value.__class__ is not expected_type:
             raise ValueError('key %s did not conform to the expected type'
                              ' %s, but was %s'
                              % (key, expected_type, type(value)))
         if validator is not None:
             value = validator(value)
         bits[var_name] = value
     if len(bits) != len(schema):
         missing = [key for key, (var_name, _, _) in schema.iteritems()
                    if var_name not in bits]
         raise ValueError('Revision text was missing expected keys %s.'
                          ' text %r' % (missing, text))
     del bits[None]  # Get rid of 'format' since it doesn't get mapped
     rev = _mod_revision.Revision(**bits)
     return rev
Beispiel #4
0
 def add_revision(self, repo, revision_id, inv, parent_ids):
     inv.revision_id = revision_id
     inv.root.revision = revision_id
     repo.add_inventory(revision_id, inv, parent_ids)
     revision = _mod_revision.Revision(revision_id,
         committer='*****@*****.**', timestamp=0, inventory_sha1='',
         timezone=0, message='foo', parent_ids=parent_ids)
     repo.add_revision(revision_id,revision, inv)
Beispiel #5
0
 def test_get_apparent_authors(self):
     r = revision.Revision('1')
     r.committer = 'A'
     self.assertEqual(['A'], r.get_apparent_authors())
     r.properties['author'] = 'B'
     self.assertEqual(['B'], r.get_apparent_authors())
     r.properties['authors'] = 'C\nD'
     self.assertEqual(['C', 'D'], r.get_apparent_authors())
Beispiel #6
0
 def test_get_summary(self):
     r = revision.Revision('1')
     r.message = 'a'
     self.assertEqual('a', r.get_summary())
     r.message = 'a\nb'
     self.assertEqual('a', r.get_summary())
     r.message = '\na\nb'
     self.assertEqual('a', r.get_summary())
Beispiel #7
0
    def setUp(self):
        super(TestCaseWithCorruptRepository, self).setUp()
        # a inventory with no parents and the revision has parents..
        # i.e. a ghost.
        repo = self.make_repository('inventory_with_unnecessary_ghost')
        repo.lock_write()
        repo.start_write_group()
        inv = inventory.Inventory(revision_id = 'ghost')
        inv.root.revision = 'ghost'
        if repo.supports_rich_root():
            root_id = inv.root.file_id
            repo.texts.add_lines((root_id, 'ghost'), [], [])
        sha1 = repo.add_inventory('ghost', inv, [])
        rev = _mod_revision.Revision(
            timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>",
            message="Message", inventory_sha1=sha1, revision_id='ghost')
        rev.parent_ids = ['the_ghost']
        try:
            repo.add_revision('ghost', rev)
        except (errors.NoSuchRevision, errors.RevisionNotPresent):
            raise tests.TestNotApplicable(
                "Cannot test with ghosts for this format.")

        inv = inventory.Inventory(revision_id = 'the_ghost')
        inv.root.revision = 'the_ghost'
        if repo.supports_rich_root():
            root_id = inv.root.file_id
            repo.texts.add_lines((root_id, 'the_ghost'), [], [])
        sha1 = repo.add_inventory('the_ghost', inv, [])
        rev = _mod_revision.Revision(
            timestamp=0, timezone=None, committer="Foo Bar <*****@*****.**>",
            message="Message", inventory_sha1=sha1, revision_id='the_ghost')
        rev.parent_ids = []
        repo.add_revision('the_ghost', rev)
        # check its setup usefully
        inv_weave = repo.inventories
        possible_parents = (None, (('ghost',),))
        self.assertSubset(inv_weave.get_parent_map([('ghost',)])[('ghost',)],
            possible_parents)
        repo.commit_write_group()
        repo.unlock()
Beispiel #8
0
 def test_some_bugs(self):
     r = revision.Revision('1',
                           properties={
                               'bugs':
                               bugtracker.encode_fixes_bug_urls([
                                   'http://example.com/bugs/1',
                                   'http://launchpad.net/bugs/1234'
                               ])
                           })
     self.assertEqual(
         [('http://example.com/bugs/1', bugtracker.FIXED),
          ('http://launchpad.net/bugs/1234', bugtracker.FIXED)],
         list(r.iter_bugs()))
Beispiel #9
0
    def make_broken_repository(self):
        # XXX: This function is borrowed from Aaron's "Reconcile can fix bad
        # parent references" branch which is due to land in bzr.dev soon.  Once
        # it does, this duplication should be removed.
        repo = self.make_repository('broken-repo')
        cleanups = []
        try:
            repo.lock_write()
            cleanups.append(repo.unlock)
            repo.start_write_group()
            cleanups.append(repo.commit_write_group)
            # make rev1a: A well-formed revision, containing 'file1'
            inv = inventory.Inventory(revision_id='rev1a')
            inv.root.revision = 'rev1a'
            self.add_file(repo, inv, 'file1', 'rev1a', [])
            repo.add_inventory('rev1a', inv, [])
            revision = _mod_revision.Revision('rev1a',
                committer='*****@*****.**', timestamp=0,
                inventory_sha1='', timezone=0, message='foo', parent_ids=[])
            repo.add_revision('rev1a',revision, inv)

            # make rev1b, which has no Revision, but has an Inventory, and
            # file1
            inv = inventory.Inventory(revision_id='rev1b')
            inv.root.revision = 'rev1b'
            self.add_file(repo, inv, 'file1', 'rev1b', [])
            repo.add_inventory('rev1b', inv, [])

            # make rev2, with file1 and file2
            # file2 is sane
            # file1 has 'rev1b' as an ancestor, even though this is not
            # mentioned by 'rev1a', making it an unreferenced ancestor
            inv = inventory.Inventory()
            self.add_file(repo, inv, 'file1', 'rev2', ['rev1a', 'rev1b'])
            self.add_file(repo, inv, 'file2', 'rev2', [])
            self.add_revision(repo, 'rev2', inv, ['rev1a'])

            # make ghost revision rev1c
            inv = inventory.Inventory()
            self.add_file(repo, inv, 'file2', 'rev1c', [])

            # make rev3 with file2
            # file2 refers to 'rev1c', which is a ghost in this repository, so
            # file2 cannot have rev1c as its ancestor.
            inv = inventory.Inventory()
            self.add_file(repo, inv, 'file2', 'rev3', ['rev1c'])
            self.add_revision(repo, 'rev3', inv, ['rev1c'])
            return repo
        finally:
            for cleanup in reversed(cleanups):
                cleanup()
Beispiel #10
0
    def make_repo_with_extra_ghost_index(self):
        """Make a corrupt repository.

        It will contain one revision, 'revision-id'.  The knit index will claim
        that it has one parent, 'incorrect-parent', but the revision text will
        claim it has no parents.

        Note: only the *cache* of the knit index is corrupted.  Thus the
        corruption will only last while the repository is locked.  For this
        reason, the returned repo is locked.
        """
        if not isinstance(self.repository_format, RepositoryFormatKnit):
            # XXX: Broken revision graphs can happen to weaves too, but they're
            # pretty deprecated.  Ideally these tests should apply to any repo
            # where repo.revision_graph_can_have_wrong_parents() is True, but
            # at the moment we only know how to corrupt knit repos.
            raise TestNotApplicable(
                "%s isn't a knit format" % self.repository_format)

        repo = self.make_repository('broken')
        repo.lock_write()
        repo.start_write_group()
        try:
            inv = inventory.Inventory(revision_id='revision-id')
            inv.root.revision = 'revision-id'
            inv_sha1 = repo.add_inventory('revision-id', inv, [])
            if repo.supports_rich_root():
                root_id = inv.root.file_id
                repo.texts.add_lines((root_id, 'revision-id'), [], [])
            revision = _mod_revision.Revision('revision-id',
                committer='*****@*****.**', timestamp=0,
                inventory_sha1=inv_sha1, timezone=0, message='message',
                parent_ids=[])
            # Manually add the revision text using the RevisionStore API, with
            # bad parents.
            rev_text = repo._serializer.write_revision_to_string(revision)
            repo.revisions.add_lines((revision.revision_id,),
                [('incorrect-parent',)],
                osutils.split_lines(rev_text))
        except:
            repo.abort_write_group()
            repo.unlock()
            raise
        else:
            repo.commit_write_group()
            repo.unlock()

        repo.lock_write()
        self.addCleanup(repo.unlock)
        return repo
 def add_commit(repo, revision_id, parent_ids):
     repo.lock_write()
     repo.start_write_group()
     inv = inventory.Inventory(revision_id=revision_id)
     inv.root.revision = revision_id
     root_id = inv.root.file_id
     sha1 = repo.add_inventory(revision_id, inv, [])
     repo.texts.add_lines((root_id, revision_id), [], [])
     rev = _mod_revision.Revision(timestamp=0,
                                  timezone=None,
                                  committer="Foo Bar <*****@*****.**>",
                                  message="Message",
                                  inventory_sha1=sha1,
                                  revision_id=revision_id)
     rev.parent_ids = parent_ids
     repo.add_revision(revision_id, rev)
     repo.commit_write_group()
     repo.unlock()
Beispiel #12
0
 def test_invalid_status(self):
     r = revision.Revision(
         '1', properties={'bugs': 'http://example.com/bugs/1 faxed'})
     self.assertRaises(InvalidBugStatus, list, r.iter_bugs())
Beispiel #13
0
 def test_too_much_information(self):
     r = revision.Revision(
         '1', properties={'bugs': 'http://example.com/bugs/1 fixed bar'})
     self.assertRaises(InvalidLineInBugsProperty, list, r.iter_bugs())
Beispiel #14
0
 def test_no_status(self):
     r = revision.Revision('1',
                           properties={'bugs': 'http://example.com/bugs/1'})
     self.assertRaises(InvalidLineInBugsProperty, list, r.iter_bugs())
Beispiel #15
0
 def test_get_apparent_authors_no_committer(self):
     r = revision.Revision('1')
     self.assertEqual([], r.get_apparent_authors())
Beispiel #16
0
 def test_get_apparent_author(self):
     r = revision.Revision('1')
     r.committer = 'A'
     self.assertEqual('A', r.get_apparent_author())
     r.properties['author'] = 'B'
     self.assertEqual('B', r.get_apparent_author())
Beispiel #17
0
 def test_no_bugs(self):
     r = revision.Revision('1')
     self.assertEqual([], list(r.iter_bugs()))