1 # Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
3 # This program is free software; you can redistribute it and/or modify
4 # it under the terms of the GNU General Public License as published by
5 # the Free Software Foundation; either version 2 of the License, or
6 # (at your option) any later version.
8 # This program is distributed in the hope that it will be useful,
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 # GNU General Public License for more details.
13 # You should have received a copy of the GNU General Public License
14 # along with this program; if not, write to the Free Software
15 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 from bzrlib.bzrdir import BzrDir
18 from bzrlib.errors import NoSuchRevision
19 from bzrlib.inventory import Inventory
23 from scheme import NoBranchingScheme, TrunkBranchingScheme
24 from tests import TestCaseWithSubversionRepository
25 from transport import SvnRaTransport
27 class TestLogWalker(TestCaseWithSubversionRepository):
29 super(TestLogWalker, self).setUp()
31 logwalker.cache_dir = os.path.join(self.test_dir, "cache-dir")
33 def test_create(self):
34 repos_url = self.make_client("a", "ac")
35 logwalker.LogWalker(transport=SvnRaTransport(repos_url))
37 def test_get_branch_log(self):
38 repos_url = self.make_client("a", "dc")
39 self.build_tree({'dc/foo': "data"})
40 self.client_add("dc/foo")
41 self.client_commit("dc", "My Message")
43 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
45 self.assertEqual(2, len(list(walker.follow_path("", 1))))
47 def test_get_revision_paths(self):
48 repos_url = self.make_client("a", "dc")
49 self.build_tree({'dc/foo': "data"})
50 self.client_add("dc/foo")
51 self.client_commit("dc", "My Message")
52 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
53 self.assertEqual({"foo": ('A', None, -1)}, walker.get_revision_paths(1))
54 self.assertEqual({"foo": ('A', None, -1)}, walker.get_revision_paths(1, "foo"))
55 self.assertEqual({"": ('A', None, -1)}, walker.get_revision_paths(0, "foo"))
57 def test_get_revision_paths_zero(self):
58 repos_url = self.make_client("a", "dc")
59 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
60 self.assertEqual({'': ('A', None, -1)}, walker.get_revision_paths(0))
62 def test_get_branch_invalid_revision(self):
63 repos_url = self.make_client("a", "dc")
64 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
65 self.assertRaises(NoSuchRevision, list,
66 walker.follow_path("/", 20))
68 def test_branch_log_all(self):
69 repos_url = self.make_client("a", "dc")
70 self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
71 self.client_add("dc/trunk")
72 self.client_add("dc/foo")
73 self.client_commit("dc", "My Message")
75 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
77 self.assertEqual(2, len(list(walker.follow_path("", 1))))
79 def test_branch_log_specific(self):
80 repos_url = self.make_client("a", "dc")
83 'dc/branches/brancha': None,
84 'dc/branches/branchab': None,
85 'dc/branches/brancha/data': "data",
86 "dc/branches/branchab/data":"data"})
87 self.client_add("dc/branches")
88 self.client_commit("dc", "My Message")
90 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
92 self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
95 def test_follow_path_ignore_unchanged(self):
96 repos_url = self.make_client("a", "dc")
97 self.build_tree({'dc/branches': None})
98 self.client_add("dc/branches")
100 'dc/branches/brancha': None,
101 'dc/branches/branchab': None,
102 'dc/branches/brancha/data': "data",
103 "dc/branches/branchab/data":"data"})
104 self.client_add("dc/branches/brancha")
105 self.client_commit("dc", "My Message")
107 self.client_add("dc/branches/branchab")
108 self.client_commit("dc", "My Message2")
110 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
112 self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
115 def test_find_latest_none(self):
116 repos_url = self.make_client("a", "dc")
117 self.build_tree({'dc/branches': None})
118 self.client_add("dc/branches")
119 self.client_commit("dc", "My Message")
121 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
123 self.assertEqual(0, walker.find_latest_change("", 1))
125 def test_find_latest_parent(self):
126 repos_url = self.make_client("a", "dc")
127 self.build_tree({'dc/branches/tmp/foo': None, 'dc/tags': None})
128 self.client_add("dc/branches")
129 self.client_add("dc/tags")
130 self.client_commit("dc", "My Message")
131 self.client_copy("dc/branches/tmp", "dc/tags/tmp");
132 self.client_commit("dc", "My Message2")
134 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
136 self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 2))
138 def test_find_latest_parent_just_modify(self):
139 repos_url = self.make_client("a", "dc")
140 self.build_tree({'dc/branches/tmp/foo': None, 'dc/tags': None})
141 self.client_add("dc/branches")
142 self.client_add("dc/tags")
143 self.client_commit("dc", "My Message")
144 self.client_copy("dc/branches/tmp", "dc/tags/tmp");
145 self.client_commit("dc", "My Message2")
146 self.client_update("dc")
147 self.client_set_prop("dc/tags", "myprop", "mydata")
148 self.client_commit("dc", "My Message3")
150 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
151 self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 3))
153 def test_find_latest_parentmoved(self):
154 repos_url = self.make_client("a", "dc")
155 self.build_tree({'dc/branches/tmp': None})
156 self.client_add("dc/branches")
157 self.client_commit("dc", "My Message")
159 self.client_copy("dc/branches", "dc/bla")
160 self.client_commit("dc", "My Message")
162 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
164 self.assertIs(2, walker.find_latest_change("bla/tmp", 2))
166 def test_find_latest_nonexistant(self):
167 repos_url = self.make_client("a", "dc")
168 self.build_tree({'dc/branches/tmp': None})
169 self.client_add("dc/branches")
170 self.client_commit("dc", "My Message")
172 self.client_copy("dc/branches", "dc/bla")
173 self.client_commit("dc", "My Message")
175 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
177 self.assertIs(None, walker.find_latest_change("bloe", 2))
178 self.assertIs(None, walker.find_latest_change("bloe/bla", 2))
180 def test_find_latest_change(self):
181 repos_url = self.make_client("a", "dc")
182 self.build_tree({'dc/branches': None})
183 self.client_add("dc/branches")
184 self.client_commit("dc", "My Message")
186 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
188 self.assertEqual(1, walker.find_latest_change("branches", 1))
190 def test_find_latest_change_children(self):
191 repos_url = self.make_client("a", "dc")
192 self.build_tree({'dc/branches': None})
193 self.client_add("dc/branches")
194 self.client_commit("dc", "My Message")
195 self.build_tree({'dc/branches/foo': 'data'})
196 self.client_add("dc/branches/foo")
197 self.client_commit("dc", "My Message2")
199 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
201 self.assertEqual(1, walker.find_latest_change("branches", 2))
203 def test_find_latest_change_prop(self):
204 repos_url = self.make_client("a", "dc")
205 self.build_tree({'dc/branches': None})
206 self.client_add("dc/branches")
207 self.client_commit("dc", "My Message")
208 self.build_tree({'dc/branches/foo': 'data'})
209 self.client_set_prop("dc/branches", "myprop", "mydata")
210 self.client_commit("dc", "propchange")
211 self.client_add("dc/branches/foo")
212 self.client_commit("dc", "My Message2")
214 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
216 self.assertEqual(2, walker.find_latest_change("branches", 3))
218 def test_find_latest_change_file(self):
219 repos_url = self.make_client("a", "dc")
220 self.build_tree({'dc/branches': None})
221 self.client_add("dc/branches")
222 self.client_commit("dc", "My Message")
223 self.build_tree({'dc/branches/foo': 'data'})
224 self.client_add("dc/branches/foo")
225 self.client_commit("dc", "propchange")
226 self.build_tree({'dc/branches/foo': 'data4'})
227 self.client_commit("dc", "My Message2")
229 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
231 self.assertEqual(3, walker.find_latest_change("branches/foo", 3))
233 def test_find_latest_change_newer(self):
234 repos_url = self.make_client("a", "dc")
235 self.build_tree({'dc/branches': None})
236 self.client_add("dc/branches")
237 self.client_commit("dc", "My Message")
238 self.build_tree({'dc/branches/foo': 'data'})
239 self.client_add("dc/branches/foo")
240 self.client_commit("dc", "propchange")
241 self.build_tree({'dc/branches/foo': 'data4'})
242 self.client_commit("dc", "My Message2")
244 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
246 self.assertEqual(2, walker.find_latest_change("branches/foo", 2))
248 def test_follow_history_branch_replace(self):
249 repos_url = self.make_client("a", "dc")
251 self.build_tree({'dc/trunk/data': "data"})
252 self.client_add("dc/trunk")
253 self.client_commit("dc", "Cm1")
255 self.client_delete("dc/trunk")
256 self.client_commit("dc", "Cm1")
258 self.build_tree({'dc/trunk/data': "data"})
259 self.client_add("dc/trunk")
260 self.client_commit("dc", "Cm1")
262 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
263 self.assertEqual([("trunk", {"trunk/data": ('A', None, -1),
264 "trunk": ('A', None, -1)}, 3)],
265 list(walker.follow_path("trunk", 3)))
267 def test_follow_history(self):
268 repos_url = self.make_client("a", "dc")
269 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
271 self.build_tree({'dc/foo': "data"})
272 self.client_add("dc/foo")
273 self.client_commit("dc", "My Message")
275 for (branch, paths, rev) in walker.follow_path("", 1):
276 self.assertEqual(branch, "")
277 self.assertTrue(rev == 0 or paths.has_key("foo"))
278 self.assertTrue(rev in (0,1))
280 def test_follow_history_nohist(self):
281 repos_url = self.make_client("a", "dc")
282 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
284 self.assertEqual([], list(walker.follow_path("", 0)))
286 def test_later_update(self):
287 repos_url = self.make_client("a", "dc")
289 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
291 self.build_tree({'dc/foo': "data"})
292 self.client_add("dc/foo")
293 self.client_commit("dc", "My Message")
295 for (branch, paths, rev) in walker.follow_path("", 1):
296 self.assertEqual(branch, "")
297 self.assertTrue(rev == 0 or paths.has_key("foo"))
298 self.assertTrue(rev in (0,1))
300 iter = walker.follow_path("", 2)
301 self.assertRaises(NoSuchRevision, list, iter)
303 def test_get_branch_log_follow(self):
304 repos_url = self.make_client("a", "dc")
305 self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
306 self.client_add("dc/trunk")
307 self.client_add("dc/branches")
308 self.client_commit("dc", "My Message")
310 self.client_copy("dc/trunk", "dc/branches/abranch")
311 self.client_commit("dc", "Create branch")
313 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
315 items = list(walker.follow_path("branches/abranch", 2))
316 self.assertEqual([('branches/abranch', {'branches/abranch': ('A', 'trunk', 1)}, 2),
317 ('trunk', {'trunk/afile': ('A', None, -1),
318 'trunk': (u'A', None, -1)}, 1)], items)
320 def test_touches_path(self):
321 repos_url = self.make_client("a", "dc")
322 self.build_tree({'dc/trunk/afile': "data"})
323 self.client_add("dc/trunk")
324 self.client_commit("dc", "My Message")
326 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
328 self.assertTrue(walker.touches_path("trunk", 1))
330 def test_touches_path_null(self):
331 repos_url = self.make_client("a", "dc")
332 self.build_tree({'dc/trunk/afile': "data"})
333 self.client_add("dc/trunk")
334 self.client_commit("dc", "My Message")
336 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
338 self.assertTrue(walker.touches_path("", 0))
340 def test_touches_path_not(self):
341 repos_url = self.make_client("a", "dc")
342 self.build_tree({'dc/trunk/afile': "data"})
343 self.client_add("dc/trunk")
344 self.client_commit("dc", "My Message")
346 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
348 self.assertFalse(walker.touches_path("", 1))
350 def test_touches_path_child(self):
351 repos_url = self.make_client("a", "dc")
352 self.build_tree({'dc/trunk/afile': "data"})
353 self.client_add("dc/trunk")
354 self.client_commit("dc", "My Message")
355 self.build_tree({'dc/trunk/afile': "data2"})
356 self.client_commit("dc", "My Message")
358 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
360 self.assertFalse(walker.touches_path("trunk", 2))
362 def test_get_previous_root(self):
363 repos_url = self.make_client("a", "dc")
365 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
367 self.assertEqual((None, -1), walker.get_previous("", 0))
369 def test_get_previous_simple(self):
370 repos_url = self.make_client("a", "dc")
371 self.build_tree({'dc/trunk/afile': "data"})
372 self.client_add("dc/trunk")
373 self.client_commit("dc", "My Message")
374 self.build_tree({'dc/trunk/afile': "data2"})
375 self.client_set_prop("dc/trunk", "myprop", "mydata")
376 self.client_commit("dc", "My Message")
378 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
380 self.assertEqual(("trunk", 1), walker.get_previous("trunk", 2))
382 def test_get_previous_added(self):
383 repos_url = self.make_client("a", "dc")
384 self.build_tree({'dc/trunk/afile': "data"})
385 self.client_add("dc/trunk")
386 self.client_commit("dc", "My Message")
387 self.build_tree({'dc/trunk/afile': "data2"})
388 self.client_set_prop("dc/trunk", "myprop", "mydata")
389 self.client_commit("dc", "My Message")
391 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
393 self.assertEqual((None, -1), walker.get_previous("trunk", 1))
395 def test_get_previous_copy(self):
396 repos_url = self.make_client("a", "dc")
397 self.build_tree({'dc/trunk/afile': "data"})
398 self.client_add("dc/trunk")
399 self.client_commit("dc", "My Message")
400 self.client_copy("dc/trunk", "dc/anotherfile")
401 self.client_commit("dc", "My Message")
403 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
405 self.assertEqual(("trunk", 1), walker.get_previous("anotherfile", 2))
407 def test_get_revision_info_zero(self):
408 repos_url = self.make_client("a", "dc")
410 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
412 info = walker.get_revision_info(0)
414 self.assertEqual(None, info[0])
415 self.assertEqual(None, info[1])
416 self.assertEqual(None, info[2])
418 def test_get_revision_info(self):
419 repos_url = self.make_client("a", "dc")
420 self.build_tree({'dc/trunk/afile': "data"})
421 self.client_add("dc/trunk")
422 self.client_commit("dc", "My Message")
424 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
426 info = walker.get_revision_info(1)
428 self.assertEqual("", info[0])
429 self.assertEqual("My Message", info[1])
431 def test_find_children_empty(self):
432 repos_url = self.make_client("a", "dc")
433 self.build_tree({'dc/trunk': None})
434 self.client_add("dc/trunk")
435 self.client_commit("dc", "My Message")
437 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
439 self.assertEqual([], list(walker.find_children("trunk", 1)))
441 def test_find_children_one(self):
442 repos_url = self.make_client("a", "dc")
443 self.build_tree({'dc/trunk/data': 'foo'})
444 self.client_add("dc/trunk")
445 self.client_commit("dc", "My Message")
447 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
449 self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
451 def test_find_children_nested(self):
452 repos_url = self.make_client("a", "dc")
453 self.build_tree({'dc/trunk/data/bla': 'foo', 'dc/trunk/file': 'bla'})
454 self.client_add("dc/trunk")
455 self.client_commit("dc", "My Message")
457 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
460 set(['trunk/data', 'trunk/data/bla', 'trunk/file']),
461 set(walker.find_children("trunk", 1)))
463 def test_find_children_later(self):
464 repos_url = self.make_client("a", "dc")
465 self.build_tree({'dc/trunk/data/bla': 'foo'})
466 self.client_add("dc/trunk")
467 self.client_commit("dc", "My Message")
468 self.build_tree({'dc/trunk/file': 'bla'})
469 self.client_add("dc/trunk/file")
470 self.client_commit("dc", "My Message")
472 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
474 self.assertEqual(set(['trunk/data', 'trunk/data/bla']),
475 set(walker.find_children("trunk", 1)))
476 self.assertEqual(set(['trunk/data', 'trunk/data/bla', 'trunk/file']),
477 set(walker.find_children("trunk", 2)))
479 def test_find_children_copy(self):
480 repos_url = self.make_client("a", "dc")
481 self.build_tree({'dc/trunk/data/bla': 'foo',
482 'dc/trunk/db/f1': 'bloe',
483 'dc/trunk/db/f2': 'bla'})
484 self.client_add("dc/trunk")
485 self.client_commit("dc", "My Message")
486 self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
487 self.client_commit("dc", "My Message")
489 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
491 self.assertEqual(set(['trunk/data', 'trunk/data/bla',
492 'trunk/data/fg', 'trunk/data/fg/f1',
493 'trunk/data/fg/f2', 'trunk/db',
494 'trunk/db/f1', 'trunk/db/f2']),
495 set(walker.find_children("trunk", 2)))
497 def test_find_children_copy_del(self):
498 repos_url = self.make_client("a", "dc")
499 self.build_tree({'dc/trunk/data/bla': 'foo',
500 'dc/trunk/db/f1': 'bloe',
501 'dc/trunk/db/f2': 'bla'})
502 self.client_add("dc/trunk")
503 self.client_commit("dc", "My Message")
504 self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
505 self.client_commit("dc", "My Message")
506 self.client_delete("dc/trunk/data/fg/f2")
507 self.client_commit("dc", "My Message")
509 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
511 self.assertEqual(set(['trunk/data', 'trunk/data/bla',
512 'trunk/data/fg', 'trunk/data/fg/f1', 'trunk/db',
513 'trunk/db/f1', 'trunk/db/f2']),
514 set(walker.find_children("trunk", 3)))