46
class DulwichClientTest(CompatTestCase):
46
class DulwichClientTestBase(object):
47
47
"""Tests for client/server compatibility."""
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',
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)
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)
69
55
def tearDown(self):
70
CompatTestCase.tearDown(self)
72
os.kill(int(open(self.pidfile).read().strip()), signal.SIGKILL)
73
os.unlink(self.pidfile)
74
except (OSError, IOError):
76
56
shutil.rmtree(self.gitroot)
78
58
def assertDestEqualsSrc(self):
80
60
dest = repo.Repo(os.path.join(self.gitroot, 'dest'))
81
61
self.assertReposEqual(src, dest)
64
raise NotImplementedError()
66
def _build_path(self):
67
raise NotImplementedError()
83
69
def _do_send_pack(self):
84
c = client.TCPGitClient('localhost')
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)
92
78
def test_send_pack(self):
100
86
self._do_send_pack()
102
88
def test_send_without_report_status(self):
103
c = client.TCPGitClient('localhost')
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()
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'],
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')
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')
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))
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')
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()
169
class DulwichTCPClientTest(CompatTestCase, DulwichClientTestBase):
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',
178
os.fdopen(fd).close()
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')
189
os.kill(int(open(self.pidfile).read().strip()), signal.SIGKILL)
190
os.unlink(self.pidfile)
191
except (OSError, IOError):
193
DulwichClientTestBase.tearDown(self)
194
CompatTestCase.tearDown(self)
197
return client.TCPGitClient('localhost')
199
def _build_path(self, path):
203
class TestSSHVendor(object):
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)
213
class DulwichMockSSHClientTest(CompatTestCase, DulwichClientTestBase):
215
CompatTestCase.setUp(self)
216
DulwichClientTestBase.setUp(self)
217
self.real_vendor = client.get_ssh_vendor
218
client.get_ssh_vendor = TestSSHVendor
221
DulwichClientTestBase.tearDown(self)
222
CompatTestCase.tearDown(self)
223
client.get_ssh_vendor = self.real_vendor
226
return client.SSHGitClient('localhost')
228
def _build_path(self, path):
229
return self.gitroot + path
232
class DulwichSubprocessClientTest(CompatTestCase, DulwichClientTestBase):
234
CompatTestCase.setUp(self)
235
DulwichClientTestBase.setUp(self)
238
DulwichClientTestBase.tearDown(self)
239
CompatTestCase.tearDown(self)
242
return client.SubprocessGitClient()
244
def _build_path(self, path):
245
return self.gitroot + path