~bzr/ubuntu/hardy/dulwich/bzr-ppa

« back to all changes in this revision

Viewing changes to dulwich/tests/compat/test_client.py

  • Committer: Jelmer Vernooij
  • Date: 2010-07-30 11:36:34 UTC
  • mfrom: (400.1.234)
  • Revision ID: git-v1:2ceb54b2dfc5f8b22a9257f1c6784ddd8d652e04
Tags: 0.6.1-1
* New upstream release.
* Bump standards version to 3.9.1.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
import os
23
23
import shutil
24
24
import signal
 
25
import subprocess
25
26
import tempfile
26
27
 
27
28
from dulwich import client
29
30
from dulwich import file
30
31
from dulwich import index
31
32
from dulwich import protocol
32
 
from dulwich import object_store
33
33
from dulwich import objects
34
34
from dulwich import repo
35
35
from dulwich.tests import (
43
43
    run_git,
44
44
    )
45
45
 
46
 
class DulwichClientTest(CompatTestCase):
 
46
class DulwichClientTestBase(object):
47
47
    """Tests for client/server compatibility."""
48
48
 
49
49
    def setUp(self):
50
 
        if check_for_daemon(limit=1):
51
 
            raise TestSkipped('git-daemon was already running on port %s' %
52
 
                              protocol.TCP_GIT_PORT)
53
 
        CompatTestCase.setUp(self)
54
 
        fd, self.pidfile = tempfile.mkstemp(prefix='dulwich-test-git-client',
55
 
                                            suffix=".pid")
56
 
        os.fdopen(fd).close()
57
50
        self.gitroot = os.path.dirname(import_repo_to_dir('server_new.export'))
58
51
        dest = os.path.join(self.gitroot, 'dest')
59
52
        file.ensure_dir_exists(dest)
60
 
        run_git(['init', '--bare'], cwd=dest)
61
 
        run_git(
62
 
            ['daemon', '--verbose', '--export-all',
63
 
             '--pid-file=%s' % self.pidfile, '--base-path=%s' % self.gitroot,
64
 
             '--detach', '--reuseaddr', '--enable=receive-pack',
65
 
             '--listen=localhost', self.gitroot], cwd=self.gitroot)
66
 
        if not check_for_daemon():
67
 
            raise TestSkipped('git-daemon failed to start')
 
53
        run_git(['init', '--quiet', '--bare'], cwd=dest)
68
54
 
69
55
    def tearDown(self):
70
 
        CompatTestCase.tearDown(self)
71
 
        try:
72
 
            os.kill(int(open(self.pidfile).read().strip()), signal.SIGKILL)
73
 
            os.unlink(self.pidfile)
74
 
        except (OSError, IOError):
75
 
            pass
76
56
        shutil.rmtree(self.gitroot)
77
57
 
78
58
    def assertDestEqualsSrc(self):
80
60
        dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
81
61
        self.assertReposEqual(src, dest)
82
62
 
 
63
    def _client(self):
 
64
        raise NotImplementedError()
 
65
 
 
66
    def _build_path(self):
 
67
        raise NotImplementedError()
 
68
 
83
69
    def _do_send_pack(self):
84
 
        c = client.TCPGitClient('localhost')
 
70
        c = self._client()
85
71
        srcpath = os.path.join(self.gitroot, 'server_new.export')
86
72
        src = repo.Repo(srcpath)
87
73
        sendrefs = dict(src.get_refs())
88
74
        del sendrefs['HEAD']
89
 
        c.send_pack('/dest', lambda _: sendrefs,
 
75
        c.send_pack(self._build_path('/dest'), lambda _: sendrefs,
90
76
                    src.object_store.generate_pack_contents)
91
77
 
92
78
    def test_send_pack(self):
100
86
        self._do_send_pack()
101
87
 
102
88
    def test_send_without_report_status(self):
103
 
        c = client.TCPGitClient('localhost')
 
89
        c = self._client()
104
90
        c._send_capabilities.remove('report-status')
105
91
        srcpath = os.path.join(self.gitroot, 'server_new.export')
106
92
        src = repo.Repo(srcpath)
107
93
        sendrefs = dict(src.get_refs())
108
94
        del sendrefs['HEAD']
109
 
        c.send_pack('/dest', lambda _: sendrefs,
 
95
        c.send_pack(self._build_path('/dest'), lambda _: sendrefs,
110
96
                    src.object_store.generate_pack_contents)
111
97
        self.assertDestEqualsSrc()
112
98
 
113
99
    def disable_ff_and_make_dummy_commit(self):
114
100
        # disable non-fast-forward pushes to the server
115
101
        dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
116
 
        run_git(['config', 'receive.denyNonFastForwards', 'true'], cwd=dest.path)
 
102
        run_git(['config', 'receive.denyNonFastForwards', 'true'],
 
103
                cwd=dest.path)
117
104
        b = objects.Blob.from_string('hi')
118
105
        dest.object_store.add_object(b)
119
106
        t = index.commit_tree(dest.object_store, [('hi', b.id, 0100644)])
137
124
        dest, dummy_commit = self.disable_ff_and_make_dummy_commit()
138
125
        dest.refs['refs/heads/master'] = dummy_commit
139
126
        sendrefs, gen_pack = self.compute_send()
140
 
        c = client.TCPGitClient('localhost')
 
127
        c = self._client()
141
128
        try:
142
 
            c.send_pack('/dest', lambda _: sendrefs, gen_pack)
 
129
            c.send_pack(self._build_path('/dest'), lambda _: sendrefs, gen_pack)
143
130
        except errors.UpdateRefsError, e:
144
131
            self.assertEqual('refs/heads/master failed to update', str(e))
145
132
            self.assertEqual({'refs/heads/branch': 'ok',
151
138
        # set up for two non-ff errors
152
139
        dest.refs['refs/heads/branch'] = dest.refs['refs/heads/master'] = dummy
153
140
        sendrefs, gen_pack = self.compute_send()
154
 
        c = client.TCPGitClient('localhost')
 
141
        c = self._client()
155
142
        try:
156
 
            c.send_pack('/dest', lambda _: sendrefs, gen_pack)
 
143
            c.send_pack(self._build_path('/dest'), lambda _: sendrefs, gen_pack)
157
144
        except errors.UpdateRefsError, e:
158
145
            self.assertEqual('refs/heads/branch, refs/heads/master failed to '
159
146
                             'update', str(e))
162
149
                             e.ref_status)
163
150
 
164
151
    def test_fetch_pack(self):
165
 
        c = client.TCPGitClient('localhost')
 
152
        c = self._client()
166
153
        dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
167
 
        refs = c.fetch('/server_new.export', dest)
 
154
        refs = c.fetch(self._build_path('/server_new.export'), dest)
168
155
        map(lambda r: dest.refs.set_if_equals(r[0], None, r[1]), refs.items())
169
156
        self.assertDestEqualsSrc()
170
157
 
172
159
        self.test_fetch_pack()
173
160
        dest, dummy = self.disable_ff_and_make_dummy_commit()
174
161
        dest.refs['refs/heads/master'] = dummy
175
 
        c = client.TCPGitClient('localhost')
 
162
        c = self._client()
176
163
        dest = repo.Repo(os.path.join(self.gitroot, 'server_new.export'))
177
 
        refs = c.fetch('/dest', dest)
 
164
        refs = c.fetch(self._build_path('/dest'), dest)
178
165
        map(lambda r: dest.refs.set_if_equals(r[0], None, r[1]), refs.items())
179
166
        self.assertDestEqualsSrc()
 
167
 
 
168
 
 
169
class DulwichTCPClientTest(CompatTestCase, DulwichClientTestBase):
 
170
    def setUp(self):
 
171
        CompatTestCase.setUp(self)
 
172
        DulwichClientTestBase.setUp(self)
 
173
        if check_for_daemon(limit=1):
 
174
            raise TestSkipped('git-daemon was already running on port %s' %
 
175
                              protocol.TCP_GIT_PORT)
 
176
        fd, self.pidfile = tempfile.mkstemp(prefix='dulwich-test-git-client',
 
177
                                            suffix=".pid")
 
178
        os.fdopen(fd).close()
 
179
        run_git(
 
180
            ['daemon', '--verbose', '--export-all',
 
181
             '--pid-file=%s' % self.pidfile, '--base-path=%s' % self.gitroot,
 
182
             '--detach', '--reuseaddr', '--enable=receive-pack',
 
183
             '--listen=localhost', self.gitroot], cwd=self.gitroot)
 
184
        if not check_for_daemon():
 
185
            raise TestSkipped('git-daemon failed to start')
 
186
 
 
187
    def tearDown(self):
 
188
        try:
 
189
            os.kill(int(open(self.pidfile).read().strip()), signal.SIGKILL)
 
190
            os.unlink(self.pidfile)
 
191
        except (OSError, IOError):
 
192
            pass
 
193
        DulwichClientTestBase.tearDown(self)
 
194
        CompatTestCase.tearDown(self)
 
195
 
 
196
    def _client(self):
 
197
        return client.TCPGitClient('localhost')
 
198
 
 
199
    def _build_path(self, path):
 
200
        return path
 
201
 
 
202
 
 
203
class TestSSHVendor(object):
 
204
    @staticmethod
 
205
    def connect_ssh(host, command, username=None, port=None):
 
206
        cmd, path = command[0].replace("'", '').split(' ')
 
207
        cmd = cmd.split('-', 1)
 
208
        p = subprocess.Popen(cmd + [path], stdin=subprocess.PIPE,
 
209
                             stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 
210
        return client.SubprocessWrapper(p)
 
211
 
 
212
 
 
213
class DulwichMockSSHClientTest(CompatTestCase, DulwichClientTestBase):
 
214
    def setUp(self):
 
215
        CompatTestCase.setUp(self)
 
216
        DulwichClientTestBase.setUp(self)
 
217
        self.real_vendor = client.get_ssh_vendor
 
218
        client.get_ssh_vendor = TestSSHVendor
 
219
 
 
220
    def tearDown(self):
 
221
        DulwichClientTestBase.tearDown(self)
 
222
        CompatTestCase.tearDown(self)
 
223
        client.get_ssh_vendor = self.real_vendor
 
224
 
 
225
    def _client(self):
 
226
        return client.SSHGitClient('localhost')
 
227
 
 
228
    def _build_path(self, path):
 
229
        return self.gitroot + path
 
230
 
 
231
 
 
232
class DulwichSubprocessClientTest(CompatTestCase, DulwichClientTestBase):
 
233
    def setUp(self):
 
234
        CompatTestCase.setUp(self)
 
235
        DulwichClientTestBase.setUp(self)
 
236
 
 
237
    def tearDown(self):
 
238
        DulwichClientTestBase.tearDown(self)
 
239
        CompatTestCase.tearDown(self)
 
240
 
 
241
    def _client(self):
 
242
        return client.SubprocessGitClient()
 
243
 
 
244
    def _build_path(self, path):
 
245
        return self.gitroot + path