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 """Log walker tests."""
19 from bzrlib.errors import NoSuchRevision
23 from tests import TestCaseWithSubversionRepository
24 from transport import SvnRaTransport
26 class TestLogWalker(TestCaseWithSubversionRepository):
28 super(TestLogWalker, self).setUp()
30 logwalker.cache_dir = os.path.join(self.test_dir, "cache-dir")
32 def test_create(self):
33 repos_url = self.make_client("a", "ac")
34 logwalker.LogWalker(transport=SvnRaTransport(repos_url))
36 def test_get_branch_log(self):
37 repos_url = self.make_client("a", "dc")
38 self.build_tree({'dc/foo': "data"})
39 self.client_add("dc/foo")
40 self.client_commit("dc", "My Message")
42 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
44 self.assertEqual(2, len(list(walker.follow_path("", 1))))
46 def test_get_branch_follow_branch(self):
47 repos_url = self.make_client("a", "dc")
48 self.build_tree({'dc/trunk/foo': "data"})
49 self.client_add("dc/trunk")
50 self.client_commit("dc", "My Message")
51 self.client_update("dc")
53 os.mkdir("dc/branches")
54 self.client_add("dc/branches")
55 self.client_commit("dc", "Add branches")
56 self.client_update("dc")
58 self.client_copy("dc/trunk", "dc/branches/foo")
59 self.client_commit("dc", "Copy")
61 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
63 self.assertEqual(2, len(list(walker.follow_path("branches/foo", 3))))
65 def test_get_branch_follow_branch_changing_parent(self):
66 repos_url = self.make_client("a", "dc")
67 self.build_tree({'dc/trunk/foo': "data"})
68 self.client_add("dc/trunk")
69 self.client_commit("dc", "My Message")
70 self.client_update("dc")
72 os.mkdir("dc/branches")
73 self.client_add("dc/branches")
74 self.client_commit("dc", "Add branches")
75 self.client_update("dc")
77 self.client_copy("dc/trunk", "dc/branches/abranch")
78 self.client_commit("dc", "Copy")
80 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
83 ("branches/abranch/foo", {"branches/abranch": ('A', 'trunk', 2)}, 3),
84 ("trunk/foo", {"trunk/foo": ('A', None, -1),
85 "trunk": ('A', None, -1)}, 1)
86 ], list(walker.follow_path("branches/abranch/foo", 3)))
88 def test_get_revision_paths(self):
89 repos_url = self.make_client("a", "dc")
90 self.build_tree({'dc/foo': "data"})
91 self.client_add("dc/foo")
92 self.client_commit("dc", "My Message")
93 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
94 self.assertEqual({"foo": ('A', None, -1)}, walker.get_revision_paths(1))
95 self.assertEqual({"foo": ('A', None, -1)}, walker.get_revision_paths(1, "foo"))
96 self.assertEqual({"": ('A', None, -1)}, walker.get_revision_paths(0, ""))
98 def test_get_revision_paths_zero(self):
99 repos_url = self.make_client("a", "dc")
100 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
101 self.assertEqual({'': ('A', None, -1)}, walker.get_revision_paths(0))
103 def test_get_revision_paths_invalid(self):
104 repos_url = self.make_client("a", "dc")
105 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
106 self.assertRaises(NoSuchRevision, lambda: walker.get_revision_paths(42))
108 def test_get_branch_invalid_revision(self):
109 repos_url = self.make_client("a", "dc")
110 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
111 self.assertRaises(NoSuchRevision, list,
112 walker.follow_path("/", 20))
114 def test_branch_log_all(self):
115 repos_url = self.make_client("a", "dc")
116 self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
117 self.client_add("dc/trunk")
118 self.client_add("dc/foo")
119 self.client_commit("dc", "My Message")
121 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
123 self.assertEqual(2, len(list(walker.follow_path("", 1))))
125 def test_branch_log_specific(self):
126 repos_url = self.make_client("a", "dc")
129 'dc/branches/brancha': None,
130 'dc/branches/branchab': None,
131 'dc/branches/brancha/data': "data",
132 "dc/branches/branchab/data":"data"})
133 self.client_add("dc/branches")
134 self.client_commit("dc", "My Message")
136 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
138 self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
141 def test_follow_path_ignore_unchanged(self):
142 repos_url = self.make_client("a", "dc")
143 self.build_tree({'dc/branches': None})
144 self.client_add("dc/branches")
146 'dc/branches/brancha': None,
147 'dc/branches/branchab': None,
148 'dc/branches/brancha/data': "data",
149 "dc/branches/branchab/data":"data"})
150 self.client_add("dc/branches/brancha")
151 self.client_commit("dc", "My Message")
153 self.client_add("dc/branches/branchab")
154 self.client_commit("dc", "My Message2")
156 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
158 self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
161 def test_find_latest_none(self):
162 repos_url = self.make_client("a", "dc")
163 self.build_tree({'dc/branches': None})
164 self.client_add("dc/branches")
165 self.client_commit("dc", "My Message")
167 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
169 self.assertEqual(0, walker.find_latest_change("", 1, include_parents=True))
171 def test_find_latest_children_root(self):
172 repos_url = self.make_client("a", "dc")
173 self.build_tree({'dc/branches': "bla"})
174 self.client_add("dc/branches")
175 self.client_commit("dc", "My Message")
177 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
180 walker.find_latest_change("", 1, include_children=True))
182 def test_find_latest_parent(self):
183 repos_url = self.make_client("a", "dc")
184 self.build_tree({'dc/branches/tmp/foo': None, 'dc/tags': None})
185 self.client_add("dc/branches")
186 self.client_add("dc/tags")
187 self.client_commit("dc", "My Message")
188 self.client_copy("dc/branches/tmp", "dc/tags/tmp")
189 self.client_commit("dc", "My Message2")
191 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
193 self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 2,
194 include_parents=True))
196 def test_find_latest_parent_just_modify(self):
197 repos_url = self.make_client("a", "dc")
198 self.build_tree({'dc/branches/tmp/foo': None, 'dc/tags': None})
199 self.client_add("dc/branches")
200 self.client_add("dc/tags")
201 self.client_commit("dc", "My Message")
202 self.client_copy("dc/branches/tmp", "dc/tags/tmp")
203 self.client_commit("dc", "My Message2")
204 self.client_update("dc")
205 self.client_set_prop("dc/tags", "myprop", "mydata")
206 self.client_commit("dc", "My Message3")
208 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
209 self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 3,
210 include_parents=True))
212 def test_find_latest_parentmoved(self):
213 repos_url = self.make_client("a", "dc")
214 self.build_tree({'dc/branches/tmp': None})
215 self.client_add("dc/branches")
216 self.client_commit("dc", "My Message")
218 self.client_copy("dc/branches", "dc/bla")
219 self.client_commit("dc", "My Message")
221 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
223 self.assertIs(2, walker.find_latest_change("bla/tmp", 2,
224 include_parents=True))
226 def test_find_latest_nonexistant(self):
227 repos_url = self.make_client("a", "dc")
228 self.build_tree({'dc/branches/tmp': None})
229 self.client_add("dc/branches")
230 self.client_commit("dc", "My Message")
232 self.client_copy("dc/branches", "dc/bla")
233 self.client_commit("dc", "My Message")
235 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
237 self.assertIs(None, walker.find_latest_change("bloe", 2, include_parents=True))
238 self.assertIs(None, walker.find_latest_change("bloe/bla", 2, include_parents=True))
240 def test_find_latest_change(self):
241 repos_url = self.make_client("a", "dc")
242 self.build_tree({'dc/branches': None})
243 self.client_add("dc/branches")
244 self.client_commit("dc", "My Message")
246 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
248 self.assertEqual(1, walker.find_latest_change("branches", 1, include_parents=True))
250 def test_find_latest_change_children(self):
251 repos_url = self.make_client("a", "dc")
252 self.build_tree({'dc/branches': None})
253 self.client_add("dc/branches")
254 self.client_commit("dc", "My Message")
255 self.build_tree({'dc/branches/foo': 'data'})
256 self.client_add("dc/branches/foo")
257 self.client_commit("dc", "My Message2")
259 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
261 self.assertEqual(1, walker.find_latest_change("branches", 2, include_parents=True))
263 def test_find_latest_change_prop(self):
264 repos_url = self.make_client("a", "dc")
265 self.build_tree({'dc/branches': None})
266 self.client_add("dc/branches")
267 self.client_commit("dc", "My Message")
268 self.build_tree({'dc/branches/foo': 'data'})
269 self.client_set_prop("dc/branches", "myprop", "mydata")
270 self.client_commit("dc", "propchange")
271 self.client_add("dc/branches/foo")
272 self.client_commit("dc", "My Message2")
274 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
276 self.assertEqual(2, walker.find_latest_change("branches", 3, include_parents=True))
278 def test_find_latest_change_file(self):
279 repos_url = self.make_client("a", "dc")
280 self.build_tree({'dc/branches': None})
281 self.client_add("dc/branches")
282 self.client_commit("dc", "My Message")
283 self.build_tree({'dc/branches/foo': 'data'})
284 self.client_add("dc/branches/foo")
285 self.client_commit("dc", "propchange")
286 self.build_tree({'dc/branches/foo': 'data4'})
287 self.client_commit("dc", "My Message2")
289 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
291 self.assertEqual(3, walker.find_latest_change("branches/foo", 3, include_parents=True))
293 def test_find_latest_change_newer(self):
294 repos_url = self.make_client("a", "dc")
295 self.build_tree({'dc/branches': None})
296 self.client_add("dc/branches")
297 self.client_commit("dc", "My Message")
298 self.build_tree({'dc/branches/foo': 'data'})
299 self.client_add("dc/branches/foo")
300 self.client_commit("dc", "propchange")
301 self.build_tree({'dc/branches/foo': 'data4'})
302 self.client_commit("dc", "My Message2")
304 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
306 self.assertEqual(2, walker.find_latest_change("branches/foo", 2, include_parents=True))
308 def test_follow_history_branch_replace(self):
309 repos_url = self.make_client("a", "dc")
311 self.build_tree({'dc/trunk/data': "data"})
312 self.client_add("dc/trunk")
313 self.client_commit("dc", "Cm1")
315 self.client_delete("dc/trunk")
316 self.client_commit("dc", "Cm1")
318 self.build_tree({'dc/trunk/data': "data"})
319 self.client_add("dc/trunk")
320 self.client_commit("dc", "Cm1")
322 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
323 self.assertEqual([("trunk", {"trunk/data": ('A', None, -1),
324 "trunk": ('A', None, -1)}, 3)],
325 list(walker.follow_path("trunk", 3)))
327 def test_follow_history(self):
328 repos_url = self.make_client("a", "dc")
329 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
331 self.build_tree({'dc/foo': "data"})
332 self.client_add("dc/foo")
333 self.client_commit("dc", "My Message")
335 for (branch, paths, rev) in walker.follow_path("", 1):
336 self.assertEqual(branch, "")
337 self.assertTrue(rev == 0 or paths.has_key("foo"))
338 self.assertTrue(rev in (0,1))
340 def test_follow_history_nohist(self):
341 repos_url = self.make_client("a", "dc")
342 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
344 self.assertEqual([], list(walker.follow_path("", 0)))
346 def test_later_update(self):
347 repos_url = self.make_client("a", "dc")
349 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
351 self.build_tree({'dc/foo': "data"})
352 self.client_add("dc/foo")
353 self.client_commit("dc", "My Message")
355 for (branch, paths, rev) in walker.follow_path("", 1):
356 self.assertEqual(branch, "")
357 self.assertTrue(rev == 0 or paths.has_key("foo"))
358 self.assertTrue(rev in (0,1))
360 iter = walker.follow_path("", 2)
361 self.assertRaises(NoSuchRevision, list, iter)
363 def test_get_branch_log_follow(self):
364 repos_url = self.make_client("a", "dc")
365 self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
366 self.client_add("dc/trunk")
367 self.client_add("dc/branches")
368 self.client_commit("dc", "My Message")
370 self.client_copy("dc/trunk", "dc/branches/abranch")
371 self.client_commit("dc", "Create branch")
373 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
375 items = list(walker.follow_path("branches/abranch", 2))
376 self.assertEqual([('branches/abranch', {'branches/abranch': ('A', 'trunk', 1)}, 2),
377 ('trunk', {'trunk/afile': ('A', None, -1),
378 'trunk': (u'A', None, -1)}, 1)], items)
380 def test_touches_path(self):
381 repos_url = self.make_client("a", "dc")
382 self.build_tree({'dc/trunk/afile': "data"})
383 self.client_add("dc/trunk")
384 self.client_commit("dc", "My Message")
386 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
388 self.assertTrue(walker.touches_path("trunk", 1))
390 def test_touches_path_null(self):
391 repos_url = self.make_client("a", "dc")
392 self.build_tree({'dc/trunk/afile': "data"})
393 self.client_add("dc/trunk")
394 self.client_commit("dc", "My Message")
396 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
398 self.assertTrue(walker.touches_path("", 0))
400 def test_touches_path_not(self):
401 repos_url = self.make_client("a", "dc")
402 self.build_tree({'dc/trunk/afile': "data"})
403 self.client_add("dc/trunk")
404 self.client_commit("dc", "My Message")
406 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
408 self.assertFalse(walker.touches_path("", 1))
410 def test_touches_path_child(self):
411 repos_url = self.make_client("a", "dc")
412 self.build_tree({'dc/trunk/afile': "data"})
413 self.client_add("dc/trunk")
414 self.client_commit("dc", "My Message")
415 self.build_tree({'dc/trunk/afile': "data2"})
416 self.client_commit("dc", "My Message")
418 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
420 self.assertFalse(walker.touches_path("trunk", 2))
422 def test_get_previous_root(self):
423 repos_url = self.make_client("a", "dc")
425 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
427 self.assertEqual((None, -1), walker.get_previous("", 0))
429 def test_get_previous_simple(self):
430 repos_url = self.make_client("a", "dc")
431 self.build_tree({'dc/trunk/afile': "data"})
432 self.client_add("dc/trunk")
433 self.client_commit("dc", "My Message")
434 self.build_tree({'dc/trunk/afile': "data2"})
435 self.client_set_prop("dc/trunk", "myprop", "mydata")
436 self.client_commit("dc", "My Message")
438 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
440 self.assertEqual(("trunk", 1), walker.get_previous("trunk", 2))
442 def test_get_previous_added(self):
443 repos_url = self.make_client("a", "dc")
444 self.build_tree({'dc/trunk/afile': "data"})
445 self.client_add("dc/trunk")
446 self.client_commit("dc", "My Message")
447 self.build_tree({'dc/trunk/afile': "data2"})
448 self.client_set_prop("dc/trunk", "myprop", "mydata")
449 self.client_commit("dc", "My Message")
451 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
453 self.assertEqual((None, -1), walker.get_previous("trunk", 1))
455 def test_get_previous_copy(self):
456 repos_url = self.make_client("a", "dc")
457 self.build_tree({'dc/trunk/afile': "data"})
458 self.client_add("dc/trunk")
459 self.client_commit("dc", "My Message")
460 self.client_copy("dc/trunk", "dc/anotherfile")
461 self.client_commit("dc", "My Message")
463 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
465 self.assertEqual(("trunk", 1), walker.get_previous("anotherfile", 2))
467 def test_get_revision_info_zero(self):
468 repos_url = self.make_client("a", "dc")
470 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
472 info = walker.get_revision_info(0)
474 self.assertEqual(None, info[0])
475 self.assertEqual(None, info[1])
476 self.assertEqual(None, info[2])
478 def test_get_revision_info(self):
479 repos_url = self.make_client("a", "dc")
480 self.build_tree({'dc/trunk/afile': "data"})
481 self.client_add("dc/trunk")
482 self.client_commit("dc", "My Message")
484 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
486 info = walker.get_revision_info(1)
488 self.assertEqual("", info[0])
489 self.assertEqual("My Message", info[1])
491 def test_find_children_empty(self):
492 repos_url = self.make_client("a", "dc")
493 self.build_tree({'dc/trunk': None})
494 self.client_add("dc/trunk")
495 self.client_commit("dc", "My Message")
497 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
499 self.assertEqual([], list(walker.find_children("trunk", 1)))
501 def test_find_children_one(self):
502 repos_url = self.make_client("a", "dc")
503 self.build_tree({'dc/trunk/data': 'foo'})
504 self.client_add("dc/trunk")
505 self.client_commit("dc", "My Message")
507 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
509 self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
511 def test_find_children_nested(self):
512 repos_url = self.make_client("a", "dc")
513 self.build_tree({'dc/trunk/data/bla': 'foo', 'dc/trunk/file': 'bla'})
514 self.client_add("dc/trunk")
515 self.client_commit("dc", "My Message")
517 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
520 set(['trunk/data', 'trunk/data/bla', 'trunk/file']),
521 set(walker.find_children("trunk", 1)))
523 def test_find_children_later(self):
524 repos_url = self.make_client("a", "dc")
525 self.build_tree({'dc/trunk/data/bla': 'foo'})
526 self.client_add("dc/trunk")
527 self.client_commit("dc", "My Message")
528 self.build_tree({'dc/trunk/file': 'bla'})
529 self.client_add("dc/trunk/file")
530 self.client_commit("dc", "My Message")
532 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
534 self.assertEqual(set(['trunk/data', 'trunk/data/bla']),
535 set(walker.find_children("trunk", 1)))
536 self.assertEqual(set(['trunk/data', 'trunk/data/bla', 'trunk/file']),
537 set(walker.find_children("trunk", 2)))
539 def test_find_children_copy(self):
540 repos_url = self.make_client("a", "dc")
541 self.build_tree({'dc/trunk/data/bla': 'foo',
542 'dc/trunk/db/f1': 'bloe',
543 'dc/trunk/db/f2': 'bla'})
544 self.client_add("dc/trunk")
545 self.client_commit("dc", "My Message")
546 self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
547 self.client_commit("dc", "My Message")
549 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
551 self.assertEqual(set(['trunk/data', 'trunk/data/bla',
552 'trunk/data/fg', 'trunk/data/fg/f1',
553 'trunk/data/fg/f2', 'trunk/db',
554 'trunk/db/f1', 'trunk/db/f2']),
555 set(walker.find_children("trunk", 2)))
557 def test_find_children_copy_del(self):
558 repos_url = self.make_client("a", "dc")
559 self.build_tree({'dc/trunk/data/bla': 'foo',
560 'dc/trunk/db/f1': 'bloe',
561 'dc/trunk/db/f2': 'bla'})
562 self.client_add("dc/trunk")
563 self.client_commit("dc", "My Message")
564 self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
565 self.client_commit("dc", "My Message")
566 self.client_delete("dc/trunk/data/fg/f2")
567 self.client_commit("dc", "My Message")
569 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
571 self.assertEqual(set(['trunk/data', 'trunk/data/bla',
572 'trunk/data/fg', 'trunk/data/fg/f1', 'trunk/db',
573 'trunk/db/f1', 'trunk/db/f2']),
574 set(walker.find_children("trunk", 3)))
576 def test_fetch_property_change_only_trunk(self):
577 repos_url = self.make_client('d', 'dc')
578 self.build_tree({'dc/trunk/bla': "data"})
579 self.client_add("dc/trunk")
580 self.client_commit("dc", "My Message")
581 self.client_set_prop("dc/trunk", "some:property", "some data\n")
582 self.client_commit("dc", "My 3")
583 self.client_set_prop("dc/trunk", "some2:property", "some data\n")
584 self.client_commit("dc", "My 2")
585 self.client_set_prop("dc/trunk", "some:property", "some data4\n")
586 self.client_commit("dc", "My 4")
587 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
588 self.assertEquals({'trunk': ('M', None, -1)}, walker.get_revision_paths(3))