1
import unittest, os, weakref, tempfile, types, setup_path
3
from svn import core, repos, fs, delta, client, wc
4
from svn.core import SubversionException
6
from trac.versioncontrol.tests.svn_fs import SubversionRepositoryTestSetup, \
8
from urlparse import urljoin
3
# Licensed to the Apache Software Foundation (ASF) under one
4
# or more contributor license agreements. See the NOTICE file
5
# distributed with this work for additional information
6
# regarding copyright ownership. The ASF licenses this file
7
# to you under the Apache License, Version 2.0 (the
8
# "License"); you may not use this file except in compliance
9
# with the License. You may obtain a copy of the License at
11
# http://www.apache.org/licenses/LICENSE-2.0
13
# Unless required by applicable law or agreed to in writing,
14
# software distributed under the License is distributed on an
15
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16
# KIND, either express or implied. See the License for the
17
# specific language governing permissions and limitations
21
import unittest, os, weakref, setup_path, utils
23
from svn import core, client, wc
27
from urllib.parse import urljoin
30
from urlparse import urljoin
10
32
class SubversionClientTestCase(unittest.TestCase):
11
33
"""Test cases for the basic SWIG Subversion client layer"""
43
69
self.client_ctx.auth_baton = core.svn_auth_open(providers)
71
self.temper = utils.Temper()
72
(_, self.repos_path, self.repos_uri) = self.temper.alloc_known_repo(
73
'trac/versioncontrol/tests/svnrepos.dump', suffix='-client')
76
# We have to free client_ctx first, since it may be holding handles
45
81
def testBatonPlay(self):
46
82
"""Test playing with C batons"""
47
self.client_ctx.log_msg_baton2 = self.client_ctx.auth_baton
48
self.assertEquals(str(self.client_ctx.log_msg_baton2),
49
str(self.client_ctx.auth_baton))
50
self.client_ctx.log_msg_baton2 = self.client_ctx.log_msg_baton2
51
self.assertEquals(str(self.client_ctx.log_msg_baton2),
52
str(self.client_ctx.auth_baton))
84
weakref_baton = weakref.ref(baton)
85
self.client_ctx.log_msg_baton2 = baton
87
self.assertEquals(self.client_ctx.log_msg_baton2(), 1)
88
self.assertEquals(weakref_baton()(), 1)
53
89
self.client_ctx.log_msg_baton2 = None
54
90
self.assertEquals(self.client_ctx.log_msg_baton2, None)
91
self.assertEquals(weakref_baton(), None)
56
93
# External objects should retain their current parent pool
57
94
self.assertNotEquals(self.client_ctx._parent_pool,
122
159
rev = core.svn_opt_revision_t()
123
160
rev.kind = core.svn_opt_revision_head
125
path = tempfile.mktemp('-checkout')
162
path = self.temper.alloc_empty_dir('-checkout')
127
164
self.assertRaises(ValueError, client.checkout2,
128
REPOS_URL, path, None, None, True, True,
165
self.repos_uri, path, None, None, True, True,
131
client.checkout2(REPOS_URL, path, rev, rev, True, True,
168
client.checkout2(self.repos_uri, path, rev, rev, True, True,
134
171
def test_info(self):
138
175
revt = core.svn_opt_revision_t()
139
176
revt.kind = core.svn_opt_revision_head
140
client.info(REPOS_URL, revt, revt, self.info_receiver,
177
client.info(self.repos_uri, revt, revt, self.info_receiver,
141
178
False, self.client_ctx)
143
180
# Check output from running info. This also serves to verify that
144
181
# the internal 'info' object is still valid
145
self.assertEqual(self.path, os.path.basename(REPOS_PATH))
182
self.assertEqual(self.path, os.path.basename(self.repos_path))
146
183
self.info.assert_valid()
147
self.assertEqual(self.info.URL, REPOS_URL)
148
self.assertEqual(self.info.repos_root_URL, REPOS_URL)
184
self.assertEqual(self.info.URL, self.repos_uri)
185
self.assertEqual(self.info.repos_root_URL, self.repos_uri)
150
187
def test_mkdir_url(self):
151
188
"""Test svn_client_mkdir2 on a file:// URL"""
152
dir = urljoin(REPOS_URL+"/", "dir1")
189
directory = urljoin(self.repos_uri+"/", "dir1")
154
commit_info = client.mkdir2((dir,), self.client_ctx)
191
commit_info = client.mkdir2((directory,), self.client_ctx)
155
192
self.assertEqual(commit_info.revision, 13)
156
193
self.assertEqual(self.log_message_func_calls, 1)
158
195
def test_mkdir_url_with_revprops(self):
159
196
"""Test svn_client_mkdir3 on a file:// URL, with added revprops"""
160
dir = urljoin(REPOS_URL+"/", "some/deep/subdir")
197
directory = urljoin(self.repos_uri+"/", "some/deep/subdir")
162
commit_info = client.mkdir3((dir,), 1, {'customprop':'value'},
199
commit_info = client.mkdir3((directory,), 1, {'customprop':'value'},
164
self.assertEqual(commit_info.revision, 14)
201
self.assertEqual(commit_info.revision, 13)
165
202
self.assertEqual(self.log_message_func_calls, 1)
167
204
def test_log3_url(self):
168
205
"""Test svn_client_log3 on a file:// URL"""
169
dir = urljoin(REPOS_URL+"/", "trunk/dir1")
206
directory = urljoin(self.repos_uri+"/", "trunk/dir1")
171
208
start = core.svn_opt_revision_t()
172
209
end = core.svn_opt_revision_t()
173
210
core.svn_opt_parse_revision(start, end, "4:0")
174
client.log3((dir,), start, start, end, 1, True, False, self.log_receiver,
211
client.log3((directory,), start, start, end, 1, True, False,
212
self.log_receiver, self.client_ctx)
176
213
self.assertEqual(self.change_author, "john")
177
214
self.assertEqual(self.log_message, "More directories.")
178
215
self.assertEqual(len(self.changed_paths), 3)
180
217
self.assert_(dir in self.changed_paths)
181
218
self.assertEqual(self.changed_paths[dir].action, 'A')
221
"""Test svn_client_log5."""
222
start = core.svn_opt_revision_t()
223
start.kind = core.svn_opt_revision_number
224
start.value.number = 0
226
end = core.svn_opt_revision_t()
227
end.kind = core.svn_opt_revision_number
230
rev_range = core.svn_opt_revision_range_t()
231
rev_range.start = start
234
self.received_revisions = []
236
client.log5((self.repos_uri,), end, (rev_range,), 0, False, True, False, (),
237
self.log_entry_receiver, self.client_ctx)
239
self.assertEqual(self.received_revisions, range(0, 5))
183
241
def test_uuid_from_url(self):
184
242
"""Test svn_client_uuid_from_url on a file:// URL"""
185
243
self.assert_(isinstance(
186
client.uuid_from_url(REPOS_URL, self.client_ctx),
244
client.uuid_from_url(self.repos_uri, self.client_ctx),
189
247
def test_url_from_path(self):
190
248
"""Test svn_client_url_from_path for a file:// URL"""
191
self.assertEquals(client.url_from_path(REPOS_URL), REPOS_URL)
249
self.assertEquals(client.url_from_path(self.repos_uri), self.repos_uri)
193
251
rev = core.svn_opt_revision_t()
194
252
rev.kind = core.svn_opt_revision_head
196
path = tempfile.mktemp('-url_from_path')
254
path = self.temper.alloc_empty_dir('-url_from_path')
198
client.checkout2(REPOS_URL, path, rev, rev, True, True,
256
client.checkout2(self.repos_uri, path, rev, rev, True, True,
201
self.assertEquals(client.url_from_path(path), REPOS_URL)
259
self.assertEquals(client.url_from_path(path), self.repos_uri)
203
261
def test_uuid_from_path(self):
204
262
"""Test svn_client_uuid_from_path."""
205
263
rev = core.svn_opt_revision_t()
206
264
rev.kind = core.svn_opt_revision_head
208
path = tempfile.mktemp('uuid_from_path')
266
path = self.temper.alloc_empty_dir('-uuid_from_path')
210
client.checkout2(REPOS_URL, path, rev, rev, True, True,
268
client.checkout2(self.repos_uri, path, rev, rev, True, True,
213
271
wc_adm = wc.adm_open3(None, path, False, 0, None)
215
273
self.assertEquals(client.uuid_from_path(path, wc_adm, self.client_ctx),
216
client.uuid_from_url(REPOS_URL, self.client_ctx))
274
client.uuid_from_url(self.repos_uri, self.client_ctx))
218
276
self.assert_(isinstance(client.uuid_from_path(path, wc_adm,
219
self.client_ctx), types.StringTypes))
277
self.client_ctx), basestring))
221
279
def test_open_ra_session(self):
222
280
"""Test svn_client_open_ra_session()."""
223
client.open_ra_session(REPOS_URL, self.client_ctx)
281
client.open_ra_session(self.repos_uri, self.client_ctx)
226
284
def test_info_file(self):
230
288
# in the repository.
231
289
rev = core.svn_opt_revision_t()
232
290
rev.kind = core.svn_opt_revision_head
233
wc_path = core.svn_path_canonicalize(tempfile.mktemp())
291
wc_path = self.temper.alloc_empty_dir('-info_file')
235
client.checkout2(REPOS_URL, wc_path, rev, rev, True, True,
293
client.checkout2(self.repos_uri, wc_path, rev, rev, True, True,
237
295
adm_access = wc.adm_open3(None, wc_path, True, -1, None)
275
333
self.assertEqual(self.info.size, 8)
277
335
wc.adm_close(adm_access)
278
core.svn_io_remove_dir(wc_path)
337
def test_merge_peg3(self):
338
"""Test svn_client_merge_peg3."""
339
head = core.svn_opt_revision_t()
340
head.kind = core.svn_opt_revision_head
341
wc_path = self.temper.alloc_empty_dir('-merge_peg3')
343
client.checkout3(self.repos_uri, wc_path, head, head, core.svn_depth_infinity,
344
True, False, self.client_ctx)
346
# Let's try to backport a change from the v1x branch
347
trunk_path = core.svn_dirent_join(wc_path, 'trunk')
348
v1x_path = core.svn_dirent_join(wc_path, 'branches/v1x')
350
start = core.svn_opt_revision_t()
351
start.kind = core.svn_opt_revision_number
352
start.value.number = 8
354
end = core.svn_opt_revision_t()
355
end.kind = core.svn_opt_revision_number
358
rrange = core.svn_opt_revision_range_t()
362
client.merge_peg3(v1x_path, (rrange,), end, trunk_path,
363
core.svn_depth_infinity, False, False, False, False,
364
None, self.client_ctx)
366
# Did it take effect?
367
readme_path_native = core.svn_dirent_local_style(
368
core.svn_dirent_join(trunk_path, 'README.txt')
371
readme = open(readme_path_native, 'r')
372
readme_text = readme.read()
375
self.assertEqual(readme_text, 'This is a test.\n')
377
def test_platform_providers(self):
378
providers = core.svn_auth_get_platform_specific_client_providers(None, None)
379
# Not much more we can test in this minimal environment.
380
self.assert_(isinstance(providers, list))
381
self.assert_(not filter(lambda x:
382
not isinstance(x, core.svn_auth_provider_object_t),
281
return unittest.makeSuite(SubversionClientTestCase, 'test',
282
suiteClass=SubversionRepositoryTestSetup)
386
return unittest.defaultTestLoader.loadTestsFromTestCase(
387
SubversionClientTestCase)
284
389
if __name__ == '__main__':
285
390
runner = unittest.TextTestRunner()