PageRenderTime 78ms CodeModel.GetById 20ms RepoModel.GetById 0ms app.codeStats 0ms

/src/subversion/subversion/bindings/swig/python/tests/ra.py

https://github.com/schwern/alien-svn
Python | 395 lines | 370 code | 3 blank | 22 comment | 2 complexity | efb970e32cdbb0624bb1fb845def9930 MD5 | raw file
Possible License(s): Apache-2.0
  1. #
  2. #
  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
  10. #
  11. # http://www.apache.org/licenses/LICENSE-2.0
  12. #
  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
  18. # under the License.
  19. #
  20. #
  21. import unittest, setup_path
  22. from svn import core, repos, fs, delta, ra
  23. from sys import version_info # For Python version check
  24. if version_info[0] >= 3:
  25. # Python >=3.0
  26. from io import StringIO
  27. else:
  28. # Python <3.0
  29. from StringIO import StringIO
  30. import utils
  31. class SubversionRepositoryAccessTestCase(unittest.TestCase):
  32. """Test cases for the Subversion repository layer"""
  33. def setUp(self):
  34. """Load a Subversion repository"""
  35. ra.initialize()
  36. self.temper = utils.Temper()
  37. # Isolate each test from the others with a fresh repository.
  38. # Open repository directly for cross-checking
  39. (self.repos, _, self.repos_uri) = self.temper.alloc_known_repo(
  40. 'trac/versioncontrol/tests/svnrepos.dump', suffix='-ra')
  41. self.fs = repos.fs(self.repos)
  42. self.callbacks = ra.Callbacks()
  43. self.ra_ctx = ra.open2(self.repos_uri, self.callbacks, {})
  44. def tearDown(self):
  45. self.ra_ctx = None
  46. self.fs = None
  47. self.repos = None
  48. self.temper.cleanup()
  49. def test_get_file(self):
  50. # Test getting the properties of a file
  51. fs_revnum = fs.youngest_rev(self.fs)
  52. rev, properties = ra.get_file(self.ra_ctx, "trunk/README2.txt",
  53. core.SVN_INVALID_REVNUM, None)
  54. self.assertEqual(rev, fs_revnum)
  55. self.assertEqual(properties["svn:mime-type"], "text/plain")
  56. # Test getting the contents of a file
  57. filestream = StringIO()
  58. rev, properties = ra.get_file(self.ra_ctx, "trunk/README2.txt",
  59. fs_revnum, filestream)
  60. self.assertEqual("A test.\n", filestream.getvalue())
  61. def test_get_repos_root(self):
  62. root = ra.get_repos_root(self.ra_ctx)
  63. self.assertEqual(root,self.repos_uri)
  64. def test_get_uuid(self):
  65. ra_uuid = ra.get_uuid(self.ra_ctx)
  66. fs_uuid = fs.get_uuid(self.fs)
  67. self.assertEqual(ra_uuid,fs_uuid)
  68. def test_get_latest_revnum(self):
  69. ra_revnum = ra.get_latest_revnum(self.ra_ctx)
  70. fs_revnum = fs.youngest_rev(self.fs)
  71. self.assertEqual(ra_revnum, fs_revnum)
  72. def test_get_dir2(self):
  73. (dirents, _, props) = ra.get_dir2(self.ra_ctx, '', 1, core.SVN_DIRENT_KIND)
  74. self.assert_('trunk' in dirents)
  75. self.assert_('branches' in dirents)
  76. self.assert_('tags' in dirents)
  77. self.assertEqual(dirents['trunk'].kind, core.svn_node_dir)
  78. self.assertEqual(dirents['branches'].kind, core.svn_node_dir)
  79. self.assertEqual(dirents['tags'].kind, core.svn_node_dir)
  80. self.assert_(core.SVN_PROP_ENTRY_UUID in props)
  81. self.assert_(core.SVN_PROP_ENTRY_LAST_AUTHOR in props)
  82. (dirents, _, _) = ra.get_dir2(self.ra_ctx, 'trunk', 1, core.SVN_DIRENT_KIND)
  83. self.assertEqual(dirents, {})
  84. (dirents, _, _) = ra.get_dir2(self.ra_ctx, 'trunk', 10,
  85. core.SVN_DIRENT_KIND)
  86. self.assert_('README2.txt' in dirents)
  87. self.assertEqual(dirents['README2.txt'].kind, core.svn_node_file)
  88. def test_commit3(self):
  89. commit_info = []
  90. def my_callback(info, pool):
  91. commit_info.append(info)
  92. revprops = {"svn:log": "foobar", "testprop": ""}
  93. editor, edit_baton = ra.get_commit_editor3(self.ra_ctx, revprops, my_callback, None, False)
  94. root = editor.open_root(edit_baton, 4)
  95. self.assertNotEqual(root, None)
  96. child = editor.add_directory("bla3", root, None, 0)
  97. self.assertNotEqual(child, None)
  98. editor.close_edit(edit_baton)
  99. info = commit_info[0]
  100. self.assertEqual(info.revision, fs.youngest_rev(self.fs))
  101. revprops['svn:author'] = info.author
  102. revprops['svn:date'] = info.date
  103. self.assertEqual(ra.rev_proplist(self.ra_ctx, info.revision), revprops)
  104. def test_commit2(self):
  105. def my_callback(info, pool):
  106. self.assertEqual(info.revision, fs.youngest_rev(self.fs))
  107. editor, edit_baton = ra.get_commit_editor2(self.ra_ctx, "foobar", my_callback, None, False)
  108. root = editor.open_root(edit_baton, 4)
  109. self.assertNotEqual(root, None)
  110. child = editor.add_directory("bla", root, None, 0)
  111. self.assertNotEqual(child, None)
  112. editor.close_edit(edit_baton)
  113. def test_commit(self):
  114. def my_callback(revision, date, author):
  115. self.assertEqual(revision, fs.youngest_rev(self.fs))
  116. editor, edit_baton = ra.get_commit_editor(self.ra_ctx, "foobar", my_callback, None, False)
  117. root = editor.open_root(edit_baton, 4)
  118. child = editor.add_directory("blah", root, None, 0)
  119. editor.close_edit(edit_baton)
  120. def test_delta_driver_commit(self):
  121. # Setup paths we'll commit in this test.
  122. to_delete = ['trunk/README.txt', 'trunk/dir1/dir2']
  123. to_mkdir = ['test_delta_driver_commit.d', 'test_delta_driver_commit2.d']
  124. to_add = ['test_delta_driver_commit', 'test_delta_driver_commit2']
  125. to_dir_prop = ['trunk/dir1/dir3', 'test_delta_driver_commit2.d']
  126. to_file_prop = ['trunk/README2.txt', 'test_delta_driver_commit2']
  127. all_paths = {}
  128. for i in to_delete + to_mkdir + to_add + to_dir_prop + to_file_prop:
  129. all_paths[i] = True
  130. # base revision for the commit
  131. revision = fs.youngest_rev(self.fs)
  132. commit_info = []
  133. def commit_cb(info, pool):
  134. commit_info.append(info)
  135. revprops = {"svn:log": "foobar", "testprop": ""}
  136. (editor, edit_baton) = ra.get_commit_editor3(self.ra_ctx, revprops,
  137. commit_cb, None, False)
  138. try:
  139. def driver_cb(parent, path, pool):
  140. self.assert_(path in all_paths)
  141. dir_baton = file_baton = None
  142. if path in to_delete:
  143. # Leave dir_baton alone, as it must be None for delete.
  144. editor.delete_entry(path, revision, parent, pool)
  145. elif path in to_mkdir:
  146. dir_baton = editor.add_directory(path, parent,
  147. None, -1, # copyfrom
  148. pool)
  149. elif path in to_add:
  150. file_baton = editor.add_file(path, parent,
  151. None, -1, # copyfrom
  152. pool)
  153. # wc.py:test_commit tests apply_textdelta .
  154. if path in to_dir_prop:
  155. if dir_baton is None:
  156. dir_baton = editor.open_directory(path, parent, revision, pool)
  157. editor.change_dir_prop(dir_baton,
  158. 'test_delta_driver_commit', 'foo', pool)
  159. elif path in to_file_prop:
  160. if file_baton is None:
  161. file_baton = editor.open_file(path, parent, revision, pool)
  162. editor.change_file_prop(file_baton,
  163. 'test_delta_driver_commit', 'foo', pool)
  164. if file_baton is not None:
  165. editor.close_file(file_baton, None, pool)
  166. return dir_baton
  167. delta.path_driver(editor, edit_baton, -1, list(all_paths.keys()), driver_cb)
  168. editor.close_edit(edit_baton)
  169. except:
  170. try:
  171. editor.abort_edit(edit_baton)
  172. except:
  173. # We already have an exception in progress, not much we can do
  174. # about this.
  175. pass
  176. raise
  177. info = commit_info[0]
  178. if info.author is not None:
  179. revprops['svn:author'] = info.author
  180. revprops['svn:date'] = info.date
  181. self.assertEqual(ra.rev_proplist(self.ra_ctx, info.revision), revprops)
  182. receiver_called = [False]
  183. def receiver(changed_paths, revision, author, date, message, pool):
  184. receiver_called[0] = True
  185. self.assertEqual(revision, info.revision)
  186. self.assertEqual(author, info.author)
  187. self.assertEqual(date, info.date)
  188. self.assertEqual(message, revprops['svn:log'])
  189. for (path, change) in changed_paths.items():
  190. path = path.lstrip('/')
  191. self.assert_(path in all_paths)
  192. if path in to_delete:
  193. self.assertEqual(change.action, 'D')
  194. elif path in to_mkdir or path in to_add:
  195. self.assertEqual(change.action, 'A')
  196. elif path in to_dir_prop or path in to_file_prop:
  197. self.assertEqual(change.action, 'M')
  198. ra.get_log(self.ra_ctx, [''], info.revision, info.revision,
  199. 0, # limit
  200. True, # discover_changed_paths
  201. True, # strict_node_history
  202. receiver)
  203. self.assert_(receiver_called[0])
  204. def test_do_diff2(self):
  205. class ChangeReceiver(delta.Editor):
  206. def __init__(self):
  207. self.textdeltas = []
  208. def apply_textdelta(self, file_baton, base_checksum, pool=None):
  209. def textdelta_handler(textdelta):
  210. if textdelta is not None:
  211. self.textdeltas.append(textdelta)
  212. return textdelta_handler
  213. editor = ChangeReceiver()
  214. e_ptr, e_baton = delta.make_editor(editor)
  215. fs_revnum = fs.youngest_rev(self.fs)
  216. sess_url = ra.get_session_url(self.ra_ctx)
  217. try:
  218. ra.reparent(self.ra_ctx, self.repos_uri+"/trunk")
  219. reporter, reporter_baton = ra.do_diff2(self.ra_ctx, fs_revnum,
  220. "README.txt", 0, 0, 1,
  221. self.repos_uri
  222. +"/trunk/README.txt",
  223. e_ptr, e_baton)
  224. reporter.set_path(reporter_baton, "", 0, True, None)
  225. reporter.finish_report(reporter_baton)
  226. finally:
  227. ra.reparent(self.ra_ctx, sess_url)
  228. self.assertEqual("A test.\n", editor.textdeltas[0].new_data)
  229. self.assertEqual(1, len(editor.textdeltas))
  230. def test_get_locations(self):
  231. locations = ra.get_locations(self.ra_ctx, "trunk/README.txt", 2, list(range(1, 5)))
  232. self.assertEqual(locations, {
  233. 2: '/trunk/README.txt',
  234. 3: '/trunk/README.txt',
  235. 4: '/trunk/README.txt'})
  236. def test_has_capability(self):
  237. self.assertEqual(True, ra.has_capability(self.ra_ctx,
  238. ra.SVN_RA_CAPABILITY_DEPTH))
  239. def test_get_file_revs(self):
  240. def rev_handler(path, rev, rev_props, prop_diffs, pool):
  241. self.assert_(rev == 2 or rev == 3)
  242. self.assertEqual(path, "/trunk/README.txt")
  243. if rev == 2:
  244. self.assertEqual(rev_props, {
  245. 'svn:log': 'Added README.',
  246. 'svn:author': 'john',
  247. 'svn:date': '2005-04-01T13:12:18.216267Z'
  248. })
  249. self.assertEqual(prop_diffs, {})
  250. elif rev == 3:
  251. self.assertEqual(rev_props, {
  252. 'svn:log': 'Fixed README.\n',
  253. 'svn:author': 'kate',
  254. 'svn:date': '2005-04-01T13:24:58.234643Z'
  255. })
  256. self.assertEqual(prop_diffs, {'svn:mime-type': 'text/plain', 'svn:eol-style': 'native'})
  257. ra.get_file_revs(self.ra_ctx, "trunk/README.txt", 0, 10, rev_handler)
  258. def test_lock(self):
  259. def callback(baton, path, do_lock, lock, ra_err, pool):
  260. pass
  261. # This test merely makes sure that the arguments can be wrapped
  262. # properly. svn.ra.lock() currently fails because it is not possible
  263. # to retrieve the username from the auth_baton yet.
  264. self.assertRaises(core.SubversionException,
  265. lambda: ra.lock(self.ra_ctx, {"": 0}, "sleutel", False, callback))
  266. def test_get_log2(self):
  267. # Get an interesting commmit.
  268. self.test_commit3()
  269. rev = fs.youngest_rev(self.fs)
  270. revprops = ra.rev_proplist(self.ra_ctx, rev)
  271. self.assert_("svn:log" in revprops)
  272. self.assert_("testprop" in revprops)
  273. def receiver(log_entry, pool):
  274. called[0] = True
  275. self.assertEqual(log_entry.revision, rev)
  276. if discover_changed_paths:
  277. self.assertEqual(list(log_entry.changed_paths.keys()), ['/bla3'])
  278. changed_path = log_entry.changed_paths['/bla3']
  279. self.assert_(changed_path.action in ['A', 'D', 'R', 'M'])
  280. self.assertEqual(changed_path.copyfrom_path, None)
  281. self.assertEqual(changed_path.copyfrom_rev, -1)
  282. else:
  283. self.assertEqual(log_entry.changed_paths, None)
  284. if log_revprops is None:
  285. self.assertEqual(log_entry.revprops, revprops)
  286. elif len(log_revprops) == 0:
  287. self.assert_(log_entry.revprops == None or len(log_entry.revprops) == 0)
  288. else:
  289. revprop_names = sorted(log_entry.revprops.keys())
  290. log_revprops.sort()
  291. self.assertEqual(revprop_names, log_revprops)
  292. for i in log_revprops:
  293. self.assertEqual(log_entry.revprops[i], revprops[i],
  294. msg="%s != %s on %s"
  295. % (log_entry.revprops[i], revprops[i],
  296. (log_revprops, discover_changed_paths)))
  297. for log_revprops in (
  298. # Retrieve the standard three.
  299. ["svn:author", "svn:date", "svn:log"],
  300. # Retrieve just testprop.
  301. ["testprop"],
  302. # Retrieve all.
  303. None,
  304. # Retrieve none.
  305. [],
  306. ):
  307. for discover_changed_paths in [True, False]:
  308. called = [False]
  309. ra.get_log2(self.ra_ctx, [""],
  310. rev, rev, # start, end
  311. 1, # limit
  312. discover_changed_paths,
  313. True, # strict_node_history
  314. False, # include_merged_revisions
  315. log_revprops, receiver)
  316. self.assert_(called[0])
  317. def test_update(self):
  318. class TestEditor(delta.Editor):
  319. pass
  320. editor = TestEditor()
  321. e_ptr, e_baton = delta.make_editor(editor)
  322. reporter, reporter_baton = ra.do_update(self.ra_ctx, 10, "", True, e_ptr, e_baton)
  323. reporter.set_path(reporter_baton, "", 0, True, None)
  324. reporter.finish_report(reporter_baton)
  325. def test_namestring(self):
  326. # Only ra-{svn,serf} support this right now.
  327. uri = self.repos_uri
  328. if uri.startswith('http') or uri.startswith('svn'):
  329. called = [False]
  330. def cb(pool):
  331. called[0] = True
  332. return 'namestring_test'
  333. self.callbacks.get_client_string = cb
  334. ra.stat(self.ra_ctx, "", 1)
  335. self.assert_(called[0])
  336. def suite():
  337. return unittest.defaultTestLoader.loadTestsFromTestCase(
  338. SubversionRepositoryAccessTestCase)
  339. if __name__ == '__main__':
  340. runner = unittest.TextTestRunner()
  341. runner.run(suite())