Example #1
0
 def setUp(self):
     super(ProtocolGraphWalkerEmptyTestCase, self).setUp()
     self._repo = MemoryRepo.init_bare([], {})
     backend = DictBackend({b'/': self._repo})
     self._walker = ProtocolGraphWalker(
         TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
         self._repo.object_store, self._repo.get_peeled)
Example #2
0
 def setUp(self):
     super(ProtocolGraphWalkerEmptyTestCase, self).setUp()
     self._repo = MemoryRepo.init_bare([], {})
     backend = DictBackend({b'/': self._repo})
     self._walker = ProtocolGraphWalker(
         TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
         self._repo.object_store, self._repo.get_peeled)
Example #3
0
    def handle(self):
        write = lambda x: self.proto.write_sideband(1, x)

        graph_walker = ProtocolGraphWalker(self, self.repo.object_store,
                                           self.repo.get_peeled)
        objects_iter = self.repo.fetch_objects(graph_walker.determine_wants,
                                               graph_walker,
                                               self.progress,
                                               get_tagged=self.get_tagged)

        # Do they want any objects?
        if len(objects_iter) == 0:
            return

        #self.progress("dul-daemon says what\n")
        self.progress("counting objects: %d, done.\n" % len(objects_iter))
        write_pack_data(ProtocolFile(None, write), objects_iter,
                        len(objects_iter))
        #self.progress("how was that, then?\n")
        size = self.backend.repository.info.size
        msg = _('Repository size: %s\n' % filesizeformat(size))
        logging.info(msg)
        self.progress(msg)
        # we are done
        self.proto.write("0000")
Example #4
0
 def setUp(self):
     super(ProtocolGraphWalkerTestCase, self).setUp()
     # Create the following commit tree:
     #   3---5
     #  /
     # 1---2---4
     commits = [
         make_commit(id=ONE, parents=[], commit_time=111),
         make_commit(id=TWO, parents=[ONE], commit_time=222),
         make_commit(id=THREE, parents=[ONE], commit_time=333),
         make_commit(id=FOUR, parents=[TWO], commit_time=444),
         make_commit(id=FIVE, parents=[THREE], commit_time=555),
     ]
     self._repo = MemoryRepo.init_bare(commits, {})
     backend = DictBackend({'/': self._repo})
     self._walker = ProtocolGraphWalker(
         TestUploadPackHandler(backend, ['/', 'host=lolcats'], TestProto()),
         self._repo.object_store, self._repo.get_peeled)
Example #5
0
 def setUp(self):
     # Create the following commit tree:
     #   3---5
     #  /
     # 1---2---4
     self._objects = {
         ONE: TestCommit(ONE, [], 111),
         TWO: TestCommit(TWO, [ONE], 222),
         THREE: TestCommit(THREE, [ONE], 333),
         FOUR: TestCommit(FOUR, [TWO], 444),
         FIVE: TestCommit(FIVE, [THREE], 555),
         }
     self._walker = ProtocolGraphWalker(
         TestHandler(self._objects, TestProto()))
Example #6
0
 def setUp(self):
     super(ProtocolGraphWalkerTestCase, self).setUp()
     # Create the following commit tree:
     #   3---5
     #  /
     # 1---2---4
     commits = [
       make_commit(id=ONE, parents=[], commit_time=111),
       make_commit(id=TWO, parents=[ONE], commit_time=222),
       make_commit(id=THREE, parents=[ONE], commit_time=333),
       make_commit(id=FOUR, parents=[TWO], commit_time=444),
       make_commit(id=FIVE, parents=[THREE], commit_time=555),
       ]
     self._repo = MemoryRepo.init_bare(commits, {})
     backend = DictBackend({b'/': self._repo})
     self._walker = ProtocolGraphWalker(
         TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
         self._repo.object_store, self._repo.get_peeled)
Example #7
0
class ProtocolGraphWalkerEmptyTestCase(TestCase):
    def setUp(self):
        super(ProtocolGraphWalkerEmptyTestCase, self).setUp()
        self._repo = MemoryRepo.init_bare([], {})
        backend = DictBackend({b'/': self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
            self._repo.object_store, self._repo.get_peeled)

    def test_empty_repository(self):
        # The server should wait for a flush packet.
        self._walker.proto.set_output([])
        self.assertRaises(HangupException, self._walker.determine_wants, {})
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())
Example #8
0
class ProtocolGraphWalkerEmptyTestCase(TestCase):
    def setUp(self):
        super(ProtocolGraphWalkerEmptyTestCase, self).setUp()
        self._repo = MemoryRepo.init_bare([], {})
        backend = DictBackend({b'/': self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
            self._repo.object_store, self._repo.get_peeled)

    def test_empty_repository(self):
        # The server should wait for a flush packet.
        self._walker.proto.set_output([])
        self.assertRaises(HangupException, self._walker.determine_wants, {})
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())
Example #9
0
class ProtocolGraphWalkerTestCase(TestCase):

    def setUp(self):
        super(ProtocolGraphWalkerTestCase, self).setUp()
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        commits = [
          make_commit(id=ONE, parents=[], commit_time=111),
          make_commit(id=TWO, parents=[ONE], commit_time=222),
          make_commit(id=THREE, parents=[ONE], commit_time=333),
          make_commit(id=FOUR, parents=[TWO], commit_time=444),
          make_commit(id=FIVE, parents=[THREE], commit_time=555),
          ]
        self._repo = MemoryRepo.init_bare(commits, {})
        backend = DictBackend({b'/': self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
            self._repo.object_store, self._repo.get_peeled)

    def test_all_wants_satisfied_no_haves(self):
        self._walker.set_wants([ONE])
        self.assertFalse(self._walker.all_wants_satisfied([]))
        self._walker.set_wants([TWO])
        self.assertFalse(self._walker.all_wants_satisfied([]))
        self._walker.set_wants([THREE])
        self.assertFalse(self._walker.all_wants_satisfied([]))

    def test_all_wants_satisfied_have_root(self):
        self._walker.set_wants([ONE])
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self._walker.set_wants([TWO])
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self._walker.set_wants([THREE])
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))

    def test_all_wants_satisfied_have_branch(self):
        self._walker.set_wants([TWO])
        self.assertTrue(self._walker.all_wants_satisfied([TWO]))
        # wrong branch
        self._walker.set_wants([THREE])
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_split_proto_line(self):
        allowed = (b'want', b'done', None)
        self.assertEqual((b'want', ONE),
                          _split_proto_line(b'want ' + ONE + b'\n', allowed))
        self.assertEqual((b'want', TWO),
                          _split_proto_line(b'want ' + TWO + b'\n', allowed))
        self.assertRaises(GitProtocolError, _split_proto_line,
                          b'want xxxx\n', allowed)
        self.assertRaises(UnexpectedCommandError, _split_proto_line,
                          b'have ' + THREE + b'\n', allowed)
        self.assertRaises(GitProtocolError, _split_proto_line,
                          b'foo ' + FOUR + b'\n', allowed)
        self.assertRaises(GitProtocolError, _split_proto_line, b'bar', allowed)
        self.assertEqual((b'done', None), _split_proto_line(b'done\n', allowed))
        self.assertEqual((None, None), _split_proto_line(b'', allowed))

    def test_determine_wants(self):
        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output([
          b'want ' + ONE + b' multi_ack',
          b'want ' + TWO,
          None,
          ])
        heads = {
          b'refs/heads/ref1': ONE,
          b'refs/heads/ref2': TWO,
          b'refs/heads/ref3': THREE,
          }
        self._repo.refs._update(heads)
        self.assertEqual([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.advertise_refs = True
        self.assertEqual([], self._walker.determine_wants(heads))
        self._walker.advertise_refs = False

        self._walker.proto.set_output([b'want ' + FOUR + b' multi_ack', None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants(heads))

        self._walker.proto.set_output([b'want ' + ONE + b' multi_ack', b'foo', None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([b'want ' + FOUR + b' multi_ack', None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

    def test_determine_wants_advertisement(self):
        self._walker.proto.set_output([None])
        # advertise branch tips plus tag
        heads = {
          b'refs/heads/ref4': FOUR,
          b'refs/heads/ref5': FIVE,
          b'refs/heads/tag6': SIX,
          }
        self._repo.refs._update(heads)
        self._repo.refs._update_peeled(heads)
        self._repo.refs._update_peeled({b'refs/heads/tag6': FIVE})
        self._walker.determine_wants(heads)
        lines = []
        while True:
            line = self._walker.proto.get_received_line()
            if line is None:
                break
            # strip capabilities list if present
            if b'\x00' in line:
                line = line[:line.index(b'\x00')]
            lines.append(line.rstrip())

        self.assertEqual([
          FOUR + b' refs/heads/ref4',
          FIVE + b' refs/heads/ref5',
          FIVE + b' refs/heads/tag6^{}',
          SIX + b' refs/heads/tag6',
          ], sorted(lines))

        # ensure peeled tag was advertised immediately following tag
        for i, line in enumerate(lines):
            if line.endswith(b' refs/heads/tag6'):
                self.assertEqual(FIVE + b' refs/heads/tag6^{}', lines[i+1])

    # TODO: test commit time cutoff

    def _handle_shallow_request(self, lines, heads):
        self._walker.proto.set_output(lines + [None])
        self._walker._handle_shallow_request(heads)

    def assertReceived(self, expected):
        self.assertEqual(
          expected, list(iter(self._walker.proto.get_received_line, None)))

    def test_handle_shallow_request_no_client_shallows(self):
        self._handle_shallow_request([b'deepen 2\n'], [FOUR, FIVE])
        self.assertEqual(set([TWO, THREE]), self._walker.shallow)
        self.assertReceived([
          b'shallow ' + TWO,
          b'shallow ' + THREE,
          ])

    def test_handle_shallow_request_no_new_shallows(self):
        lines = [
          b'shallow ' + TWO + b'\n',
          b'shallow ' + THREE + b'\n',
          b'deepen 2\n',
          ]
        self._handle_shallow_request(lines, [FOUR, FIVE])
        self.assertEqual(set([TWO, THREE]), self._walker.shallow)
        self.assertReceived([])

    def test_handle_shallow_request_unshallows(self):
        lines = [
          b'shallow ' + TWO + b'\n',
          b'deepen 3\n',
          ]
        self._handle_shallow_request(lines, [FOUR, FIVE])
        self.assertEqual(set([ONE]), self._walker.shallow)
        self.assertReceived([
          b'shallow ' + ONE,
          b'unshallow ' + TWO,
          # THREE is unshallow but was is not shallow in the client
          ])
Example #10
0
class ProtocolGraphWalkerTestCase(TestCase):
    def setUp(self):
        super(ProtocolGraphWalkerTestCase, self).setUp()
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        commits = [
            make_commit(id=ONE, parents=[], commit_time=111),
            make_commit(id=TWO, parents=[ONE], commit_time=222),
            make_commit(id=THREE, parents=[ONE], commit_time=333),
            make_commit(id=FOUR, parents=[TWO], commit_time=444),
            make_commit(id=FIVE, parents=[THREE], commit_time=555),
        ]
        self._repo = MemoryRepo.init_bare(commits, {})
        backend = DictBackend({'/': self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, ['/', 'host=lolcats'], TestProto()),
            self._repo.object_store, self._repo.get_peeled)

    def test_is_satisfied_no_haves(self):
        self.assertFalse(self._walker._is_satisfied([], ONE, 0))
        self.assertFalse(self._walker._is_satisfied([], TWO, 0))
        self.assertFalse(self._walker._is_satisfied([], THREE, 0))

    def test_is_satisfied_have_root(self):
        self.assertTrue(self._walker._is_satisfied([ONE], ONE, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], TWO, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], THREE, 0))

    def test_is_satisfied_have_branch(self):
        self.assertTrue(self._walker._is_satisfied([TWO], TWO, 0))
        # wrong branch
        self.assertFalse(self._walker._is_satisfied([TWO], THREE, 0))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_split_proto_line(self):
        allowed = ('want', 'done', None)
        self.assertEqual(('want', ONE),
                         _split_proto_line('want %s\n' % ONE, allowed))
        self.assertEqual(('want', TWO),
                         _split_proto_line('want %s\n' % TWO, allowed))
        self.assertRaises(GitProtocolError, _split_proto_line, 'want xxxx\n',
                          allowed)
        self.assertRaises(UnexpectedCommandError, _split_proto_line,
                          'have %s\n' % THREE, allowed)
        self.assertRaises(GitProtocolError, _split_proto_line,
                          'foo %s\n' % FOUR, allowed)
        self.assertRaises(GitProtocolError, _split_proto_line, 'bar', allowed)
        self.assertEqual(('done', None), _split_proto_line('done\n', allowed))
        self.assertEqual((None, None), _split_proto_line('', allowed))

    def test_determine_wants(self):
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output([
            'want %s multi_ack' % ONE,
            'want %s' % TWO,
        ])
        heads = {
            'refs/heads/ref1': ONE,
            'refs/heads/ref2': TWO,
            'refs/heads/ref3': THREE,
        }
        self._repo.refs._update(heads)
        self.assertEqual([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants,
                          heads)

        self._walker.proto.set_output([])
        self.assertEqual([], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % ONE, 'foo'])
        self.assertRaises(GitProtocolError, self._walker.determine_wants,
                          heads)

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants,
                          heads)

    def test_determine_wants_advertisement(self):
        self._walker.proto.set_output([])
        # advertise branch tips plus tag
        heads = {
            'refs/heads/ref4': FOUR,
            'refs/heads/ref5': FIVE,
            'refs/heads/tag6': SIX,
        }
        self._repo.refs._update(heads)
        self._repo.refs._update_peeled(heads)
        self._repo.refs._update_peeled({'refs/heads/tag6': FIVE})
        self._walker.determine_wants(heads)
        lines = []
        while True:
            line = self._walker.proto.get_received_line()
            if line is None:
                break
            # strip capabilities list if present
            if '\x00' in line:
                line = line[:line.index('\x00')]
            lines.append(line.rstrip())

        self.assertEqual([
            '%s refs/heads/ref4' % FOUR,
            '%s refs/heads/ref5' % FIVE,
            '%s refs/heads/tag6^{}' % FIVE,
            '%s refs/heads/tag6' % SIX,
        ], sorted(lines))

        # ensure peeled tag was advertised immediately following tag
        for i, line in enumerate(lines):
            if line.endswith(' refs/heads/tag6'):
                self.assertEqual('%s refs/heads/tag6^{}' % FIVE, lines[i + 1])
Example #11
0
class ProtocolGraphWalkerTestCase(TestCase):

    def setUp(self):
        super(ProtocolGraphWalkerTestCase, self).setUp()
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        commits = [
          make_commit(id=ONE, parents=[], commit_time=111),
          make_commit(id=TWO, parents=[ONE], commit_time=222),
          make_commit(id=THREE, parents=[ONE], commit_time=333),
          make_commit(id=FOUR, parents=[TWO], commit_time=444),
          make_commit(id=FIVE, parents=[THREE], commit_time=555),
          ]
        self._repo = MemoryRepo.init_bare(commits, {})
        backend = DictBackend({b'/': self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, [b'/', b'host=lolcats'], TestProto()),
            self._repo.object_store, self._repo.get_peeled)

    def test_all_wants_satisfied_no_haves(self):
        self._walker.set_wants([ONE])
        self.assertFalse(self._walker.all_wants_satisfied([]))
        self._walker.set_wants([TWO])
        self.assertFalse(self._walker.all_wants_satisfied([]))
        self._walker.set_wants([THREE])
        self.assertFalse(self._walker.all_wants_satisfied([]))

    def test_all_wants_satisfied_have_root(self):
        self._walker.set_wants([ONE])
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self._walker.set_wants([TWO])
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self._walker.set_wants([THREE])
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))

    def test_all_wants_satisfied_have_branch(self):
        self._walker.set_wants([TWO])
        self.assertTrue(self._walker.all_wants_satisfied([TWO]))
        # wrong branch
        self._walker.set_wants([THREE])
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_split_proto_line(self):
        allowed = (b'want', b'done', None)
        self.assertEqual((b'want', ONE),
                          _split_proto_line(b'want ' + ONE + b'\n', allowed))
        self.assertEqual((b'want', TWO),
                          _split_proto_line(b'want ' + TWO + b'\n', allowed))
        self.assertRaises(GitProtocolError, _split_proto_line,
                          b'want xxxx\n', allowed)
        self.assertRaises(UnexpectedCommandError, _split_proto_line,
                          b'have ' + THREE + b'\n', allowed)
        self.assertRaises(GitProtocolError, _split_proto_line,
                          b'foo ' + FOUR + b'\n', allowed)
        self.assertRaises(GitProtocolError, _split_proto_line, b'bar', allowed)
        self.assertEqual((b'done', None), _split_proto_line(b'done\n', allowed))
        self.assertEqual((None, None), _split_proto_line(b'', allowed))

    def test_determine_wants(self):
        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output([
          b'want ' + ONE + b' multi_ack',
          b'want ' + TWO,
          None,
          ])
        heads = {
          b'refs/heads/ref1': ONE,
          b'refs/heads/ref2': TWO,
          b'refs/heads/ref3': THREE,
          }
        self._repo.refs._update(heads)
        self.assertEqual([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.advertise_refs = True
        self.assertEqual([], self._walker.determine_wants(heads))
        self._walker.advertise_refs = False

        self._walker.proto.set_output([b'want ' + FOUR + b' multi_ack', None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants(heads))

        self._walker.proto.set_output([b'want ' + ONE + b' multi_ack', b'foo', None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([b'want ' + FOUR + b' multi_ack', None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

    def test_determine_wants_advertisement(self):
        self._walker.proto.set_output([None])
        # advertise branch tips plus tag
        heads = {
          b'refs/heads/ref4': FOUR,
          b'refs/heads/ref5': FIVE,
          b'refs/heads/tag6': SIX,
          }
        self._repo.refs._update(heads)
        self._repo.refs._update_peeled(heads)
        self._repo.refs._update_peeled({b'refs/heads/tag6': FIVE})
        self._walker.determine_wants(heads)
        lines = []
        while True:
            line = self._walker.proto.get_received_line()
            if line is None:
                break
            # strip capabilities list if present
            if b'\x00' in line:
                line = line[:line.index(b'\x00')]
            lines.append(line.rstrip())

        self.assertEqual([
          FOUR + b' refs/heads/ref4',
          FIVE + b' refs/heads/ref5',
          FIVE + b' refs/heads/tag6^{}',
          SIX + b' refs/heads/tag6',
          ], sorted(lines))

        # ensure peeled tag was advertised immediately following tag
        for i, line in enumerate(lines):
            if line.endswith(b' refs/heads/tag6'):
                self.assertEqual(FIVE + b' refs/heads/tag6^{}', lines[i+1])

    # TODO: test commit time cutoff

    def _handle_shallow_request(self, lines, heads):
        self._walker.proto.set_output(lines + [None])
        self._walker._handle_shallow_request(heads)

    def assertReceived(self, expected):
        self.assertEqual(
          expected, list(iter(self._walker.proto.get_received_line, None)))

    def test_handle_shallow_request_no_client_shallows(self):
        self._handle_shallow_request([b'deepen 1\n'], [FOUR, FIVE])
        self.assertEqual(set([TWO, THREE]), self._walker.shallow)
        self.assertReceived([
          b'shallow ' + TWO,
          b'shallow ' + THREE,
          ])

    def test_handle_shallow_request_no_new_shallows(self):
        lines = [
          b'shallow ' + TWO + b'\n',
          b'shallow ' + THREE + b'\n',
          b'deepen 1\n',
          ]
        self._handle_shallow_request(lines, [FOUR, FIVE])
        self.assertEqual(set([TWO, THREE]), self._walker.shallow)
        self.assertReceived([])

    def test_handle_shallow_request_unshallows(self):
        lines = [
          b'shallow ' + TWO + b'\n',
          b'deepen 2\n',
          ]
        self._handle_shallow_request(lines, [FOUR, FIVE])
        self.assertEqual(set([ONE]), self._walker.shallow)
        self.assertReceived([
          b'shallow ' + ONE,
          b'unshallow ' + TWO,
          # THREE is unshallow but was is not shallow in the client
          ])
Example #12
0
class ProtocolGraphWalkerTestCase(TestCase):

    def setUp(self):
        super(ProtocolGraphWalkerTestCase, self).setUp()
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        commits = [
          make_commit(id=ONE, parents=[], commit_time=111),
          make_commit(id=TWO, parents=[ONE], commit_time=222),
          make_commit(id=THREE, parents=[ONE], commit_time=333),
          make_commit(id=FOUR, parents=[TWO], commit_time=444),
          make_commit(id=FIVE, parents=[THREE], commit_time=555),
          ]
        self._repo = MemoryRepo.init_bare(commits, {})
        backend = DictBackend({'/': self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, ['/', 'host=lolcats'], TestProto()),
            self._repo.object_store, self._repo.get_peeled)

    def test_is_satisfied_no_haves(self):
        self.assertFalse(self._walker._is_satisfied([], ONE, 0))
        self.assertFalse(self._walker._is_satisfied([], TWO, 0))
        self.assertFalse(self._walker._is_satisfied([], THREE, 0))

    def test_is_satisfied_have_root(self):
        self.assertTrue(self._walker._is_satisfied([ONE], ONE, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], TWO, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], THREE, 0))

    def test_is_satisfied_have_branch(self):
        self.assertTrue(self._walker._is_satisfied([TWO], TWO, 0))
        # wrong branch
        self.assertFalse(self._walker._is_satisfied([TWO], THREE, 0))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_split_proto_line(self):
        allowed = ('want', 'done', None)
        self.assertEqual(('want', ONE),
                          _split_proto_line('want %s\n' % ONE, allowed))
        self.assertEqual(('want', TWO),
                          _split_proto_line('want %s\n' % TWO, allowed))
        self.assertRaises(GitProtocolError, _split_proto_line,
                          'want xxxx\n', allowed)
        self.assertRaises(UnexpectedCommandError, _split_proto_line,
                          'have %s\n' % THREE, allowed)
        self.assertRaises(GitProtocolError, _split_proto_line,
                          'foo %s\n' % FOUR, allowed)
        self.assertRaises(GitProtocolError, _split_proto_line, 'bar', allowed)
        self.assertEqual(('done', None), _split_proto_line('done\n', allowed))
        self.assertEqual((None, None), _split_proto_line('', allowed))

    def test_determine_wants(self):
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output([
          'want %s multi_ack' % ONE,
          'want %s' % TWO,
          ])
        heads = {
          'refs/heads/ref1': ONE,
          'refs/heads/ref2': TWO,
          'refs/heads/ref3': THREE,
          }
        self._repo.refs._update(heads)
        self.assertEqual([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.advertise_refs = True
        self.assertEqual([], self._walker.determine_wants(heads))
        self._walker.advertise_refs = False

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([])
        self.assertEqual([], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % ONE, 'foo'])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

    def test_determine_wants_advertisement(self):
        self._walker.proto.set_output([])
        # advertise branch tips plus tag
        heads = {
          'refs/heads/ref4': FOUR,
          'refs/heads/ref5': FIVE,
          'refs/heads/tag6': SIX,
          }
        self._repo.refs._update(heads)
        self._repo.refs._update_peeled(heads)
        self._repo.refs._update_peeled({'refs/heads/tag6': FIVE})
        self._walker.determine_wants(heads)
        lines = []
        while True:
            line = self._walker.proto.get_received_line()
            if line is None:
                break
            # strip capabilities list if present
            if '\x00' in line:
                line = line[:line.index('\x00')]
            lines.append(line.rstrip())

        self.assertEqual([
          '%s refs/heads/ref4' % FOUR,
          '%s refs/heads/ref5' % FIVE,
          '%s refs/heads/tag6^{}' % FIVE,
          '%s refs/heads/tag6' % SIX,
          ], sorted(lines))

        # ensure peeled tag was advertised immediately following tag
        for i, line in enumerate(lines):
            if line.endswith(' refs/heads/tag6'):
                self.assertEqual('%s refs/heads/tag6^{}' % FIVE, lines[i+1])
Example #13
0
class ProtocolGraphWalkerTestCase(TestCase):

    def setUp(self):
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        self._objects = {
            ONE: TestCommit(ONE, [], 111),
            TWO: TestCommit(TWO, [ONE], 222),
            THREE: TestCommit(THREE, [ONE], 333),
            FOUR: TestCommit(FOUR, [TWO], 444),
            FIVE: TestCommit(FIVE, [THREE], 555),
            }

        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(self._objects, TestProto()),
            self._objects, None)

    def test_is_satisfied_no_haves(self):
        self.assertFalse(self._walker._is_satisfied([], ONE, 0))
        self.assertFalse(self._walker._is_satisfied([], TWO, 0))
        self.assertFalse(self._walker._is_satisfied([], THREE, 0))

    def test_is_satisfied_have_root(self):
        self.assertTrue(self._walker._is_satisfied([ONE], ONE, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], TWO, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], THREE, 0))

    def test_is_satisfied_have_branch(self):
        self.assertTrue(self._walker._is_satisfied([TWO], TWO, 0))
        # wrong branch
        self.assertFalse(self._walker._is_satisfied([TWO], THREE, 0))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_read_proto_line(self):
        self._walker.proto.set_output([
            'want %s' % ONE,
            'want %s' % TWO,
            'have %s' % THREE,
            'foo %s' % FOUR,
            'bar',
            'done',
            ])
        self.assertEquals(('want', ONE), self._walker.read_proto_line())
        self.assertEquals(('want', TWO), self._walker.read_proto_line())
        self.assertEquals(('have', THREE), self._walker.read_proto_line())
        self.assertRaises(GitProtocolError, self._walker.read_proto_line)
        self.assertRaises(GitProtocolError, self._walker.read_proto_line)
        self.assertEquals(('done', None), self._walker.read_proto_line())
        self.assertEquals((None, None), self._walker.read_proto_line())

    def test_determine_wants(self):
        self.assertRaises(GitProtocolError, self._walker.determine_wants, {})

        self._walker.proto.set_output([
            'want %s multi_ack' % ONE,
            'want %s' % TWO,
            ])
        heads = {'ref1': ONE, 'ref2': TWO, 'ref3': THREE}
        self._walker.get_peeled = heads.get
        self.assertEquals([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([])
        self.assertEquals([], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % ONE, 'foo'])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

    def test_determine_wants_advertisement(self):
        self._walker.proto.set_output([])
        # advertise branch tips plus tag
        heads = {'ref4': FOUR, 'ref5': FIVE, 'tag6': SIX}
        peeled = {'ref4': FOUR, 'ref5': FIVE, 'tag6': FIVE}
        self._walker.get_peeled = peeled.get
        self._walker.determine_wants(heads)
        lines = []
        while True:
            line = self._walker.proto.get_received_line()
            if line == 'None':
                break
            # strip capabilities list if present
            if '\x00' in line:
                line = line[:line.index('\x00')]
            lines.append(line.rstrip())

        self.assertEquals([
            '%s ref4' % FOUR,
            '%s ref5' % FIVE,
            '%s tag6^{}' % FIVE,
            '%s tag6' % SIX,
            ], sorted(lines))

        # ensure peeled tag was advertised immediately following tag
        for i, line in enumerate(lines):
            if line.endswith(' tag6'):
                self.assertEquals('%s tag6^{}' % FIVE, lines[i+1])
Example #14
0
class ProtocolGraphWalkerTestCase(TestCase):
    def setUp(self):
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        self._objects = {
            ONE: TestCommit(ONE, [], 111),
            TWO: TestCommit(TWO, [ONE], 222),
            THREE: TestCommit(THREE, [ONE], 333),
            FOUR: TestCommit(FOUR, [TWO], 444),
            FIVE: TestCommit(FIVE, [THREE], 555),
            }
        self._walker = ProtocolGraphWalker(
            TestHandler(self._objects, TestProto()))

    def test_is_satisfied_no_haves(self):
        self.assertFalse(self._walker._is_satisfied([], ONE, 0))
        self.assertFalse(self._walker._is_satisfied([], TWO, 0))
        self.assertFalse(self._walker._is_satisfied([], THREE, 0))

    def test_is_satisfied_have_root(self):
        self.assertTrue(self._walker._is_satisfied([ONE], ONE, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], TWO, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], THREE, 0))

    def test_is_satisfied_have_branch(self):
        self.assertTrue(self._walker._is_satisfied([TWO], TWO, 0))
        # wrong branch
        self.assertFalse(self._walker._is_satisfied([TWO], THREE, 0))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_read_proto_line(self):
        self._walker.proto.set_output([
            'want %s' % ONE,
            'want %s' % TWO,
            'have %s' % THREE,
            'foo %s' % FOUR,
            'bar',
            'done',
            ])
        self.assertEquals(('want', ONE), self._walker.read_proto_line())
        self.assertEquals(('want', TWO), self._walker.read_proto_line())
        self.assertEquals(('have', THREE), self._walker.read_proto_line())
        self.assertRaises(GitProtocolError, self._walker.read_proto_line)
        self.assertRaises(GitProtocolError, self._walker.read_proto_line)
        self.assertEquals(('done', None), self._walker.read_proto_line())
        self.assertEquals((None, None), self._walker.read_proto_line())

    def test_determine_wants(self):
        self.assertRaises(GitProtocolError, self._walker.determine_wants, {})

        self._walker.proto.set_output([
            'want %s multi_ack' % ONE,
            'want %s' % TWO,
            ])
        heads = {'ref1': ONE, 'ref2': TWO, 'ref3': THREE}
        self.assertEquals([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([])
        self.assertEquals([], self._walker.determine_wants(heads))

        self._walker.proto.set_output(['want %s multi_ack' % ONE, 'foo'])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output(['want %s multi_ack' % FOUR])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)
Example #15
0
class ProtocolGraphWalkerTestCase(TestCase):
    def setUp(self):
        super(ProtocolGraphWalkerTestCase, self).setUp()
        # Create the following commit tree:
        #   3---5
        #  /
        # 1---2---4
        commits = [
            make_commit(id=ONE, parents=[], commit_time=111),
            make_commit(id=TWO, parents=[ONE], commit_time=222),
            make_commit(id=THREE, parents=[ONE], commit_time=333),
            make_commit(id=FOUR, parents=[TWO], commit_time=444),
            make_commit(id=FIVE, parents=[THREE], commit_time=555),
        ]
        self._repo = MemoryRepo.init_bare(commits, {})
        backend = DictBackend({"/": self._repo})
        self._walker = ProtocolGraphWalker(
            TestUploadPackHandler(backend, ["/", "host=lolcats"], TestProto()),
            self._repo.object_store,
            self._repo.get_peeled,
        )

    def test_is_satisfied_no_haves(self):
        self.assertFalse(self._walker._is_satisfied([], ONE, 0))
        self.assertFalse(self._walker._is_satisfied([], TWO, 0))
        self.assertFalse(self._walker._is_satisfied([], THREE, 0))

    def test_is_satisfied_have_root(self):
        self.assertTrue(self._walker._is_satisfied([ONE], ONE, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], TWO, 0))
        self.assertTrue(self._walker._is_satisfied([ONE], THREE, 0))

    def test_is_satisfied_have_branch(self):
        self.assertTrue(self._walker._is_satisfied([TWO], TWO, 0))
        # wrong branch
        self.assertFalse(self._walker._is_satisfied([TWO], THREE, 0))

    def test_all_wants_satisfied(self):
        self._walker.set_wants([FOUR, FIVE])
        # trivial case: wants == haves
        self.assertTrue(self._walker.all_wants_satisfied([FOUR, FIVE]))
        # cases that require walking the commit tree
        self.assertTrue(self._walker.all_wants_satisfied([ONE]))
        self.assertFalse(self._walker.all_wants_satisfied([TWO]))
        self.assertFalse(self._walker.all_wants_satisfied([THREE]))
        self.assertTrue(self._walker.all_wants_satisfied([TWO, THREE]))

    def test_split_proto_line(self):
        allowed = ("want", "done", None)
        self.assertEqual(("want", ONE), _split_proto_line("want %s\n" % ONE, allowed))
        self.assertEqual(("want", TWO), _split_proto_line("want %s\n" % TWO, allowed))
        self.assertRaises(GitProtocolError, _split_proto_line, "want xxxx\n", allowed)
        self.assertRaises(UnexpectedCommandError, _split_proto_line, "have %s\n" % THREE, allowed)
        self.assertRaises(GitProtocolError, _split_proto_line, "foo %s\n" % FOUR, allowed)
        self.assertRaises(GitProtocolError, _split_proto_line, "bar", allowed)
        self.assertEqual(("done", None), _split_proto_line("done\n", allowed))
        self.assertEqual((None, None), _split_proto_line("", allowed))

    def test_determine_wants(self):
        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants({}))
        self.assertEqual(None, self._walker.proto.get_received_line())

        self._walker.proto.set_output(["want %s multi_ack" % ONE, "want %s" % TWO, None])
        heads = {"refs/heads/ref1": ONE, "refs/heads/ref2": TWO, "refs/heads/ref3": THREE}
        self._repo.refs._update(heads)
        self.assertEqual([ONE, TWO], self._walker.determine_wants(heads))

        self._walker.advertise_refs = True
        self.assertEqual([], self._walker.determine_wants(heads))
        self._walker.advertise_refs = False

        self._walker.proto.set_output(["want %s multi_ack" % FOUR, None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output([None])
        self.assertEqual([], self._walker.determine_wants(heads))

        self._walker.proto.set_output(["want %s multi_ack" % ONE, "foo", None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

        self._walker.proto.set_output(["want %s multi_ack" % FOUR, None])
        self.assertRaises(GitProtocolError, self._walker.determine_wants, heads)

    def test_determine_wants_advertisement(self):
        self._walker.proto.set_output([None])
        # advertise branch tips plus tag
        heads = {"refs/heads/ref4": FOUR, "refs/heads/ref5": FIVE, "refs/heads/tag6": SIX}
        self._repo.refs._update(heads)
        self._repo.refs._update_peeled(heads)
        self._repo.refs._update_peeled({"refs/heads/tag6": FIVE})
        self._walker.determine_wants(heads)
        lines = []
        while True:
            line = self._walker.proto.get_received_line()
            if line is None:
                break
            # strip capabilities list if present
            if "\x00" in line:
                line = line[: line.index("\x00")]
            lines.append(line.rstrip())

        self.assertEqual(
            [
                "%s refs/heads/ref4" % FOUR,
                "%s refs/heads/ref5" % FIVE,
                "%s refs/heads/tag6^{}" % FIVE,
                "%s refs/heads/tag6" % SIX,
            ],
            sorted(lines),
        )

        # ensure peeled tag was advertised immediately following tag
        for i, line in enumerate(lines):
            if line.endswith(" refs/heads/tag6"):
                self.assertEqual("%s refs/heads/tag6^{}" % FIVE, lines[i + 1])

    # TODO: test commit time cutoff

    def _handle_shallow_request(self, lines, heads):
        self._walker.proto.set_output(lines + [None])
        self._walker._handle_shallow_request(heads)

    def assertReceived(self, expected):
        self.assertEquals(expected, list(iter(self._walker.proto.get_received_line, None)))

    def test_handle_shallow_request_no_client_shallows(self):
        self._handle_shallow_request(["deepen 1\n"], [FOUR, FIVE])
        self.assertEquals(set([TWO, THREE]), self._walker.shallow)
        self.assertReceived(["shallow %s" % TWO, "shallow %s" % THREE])

    def test_handle_shallow_request_no_new_shallows(self):
        lines = ["shallow %s\n" % TWO, "shallow %s\n" % THREE, "deepen 1\n"]
        self._handle_shallow_request(lines, [FOUR, FIVE])
        self.assertEquals(set([TWO, THREE]), self._walker.shallow)
        self.assertReceived([])

    def test_handle_shallow_request_unshallows(self):
        lines = ["shallow %s\n" % TWO, "deepen 2\n"]
        self._handle_shallow_request(lines, [FOUR, FIVE])
        self.assertEquals(set([ONE]), self._walker.shallow)
        self.assertReceived(
            [
                "shallow %s" % ONE,
                "unshallow %s" % TWO,
                # THREE is unshallow but was is not shallow in the client
            ]
        )