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.errors import NoSuchRevision
21 from tests import TestCaseWithSubversionRepository
22 from transport import SvnRaTransport
24 class TestLogWalker(TestCaseWithSubversionRepository):
26 super(TestLogWalker, self).setUp()
28 logwalker.cache_dir = os.path.join(self.test_dir, "cache-dir")
30 def test_create(self):
31 repos_url = self.make_client("a", "ac")
32 logwalker.LogWalker(transport=SvnRaTransport(repos_url))
34 def test_get_branch_log(self):
35 repos_url = self.make_client("a", "dc")
36 self.build_tree({'dc/foo': "data"})
37 self.client_add("dc/foo")
38 self.client_commit("dc", "My Message")
40 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
42 self.assertEqual(1, len(list(walker.follow_path("", 1))))
44 def test_get_revision_paths(self):
45 repos_url = self.make_client("a", "dc")
46 self.build_tree({'dc/foo': "data"})
47 self.client_add("dc/foo")
48 self.client_commit("dc", "My Message")
49 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
50 self.assertEqual({"foo": ('A', None, -1)}, walker.get_revision_paths(1))
51 self.assertEqual({"foo": ('A', None, -1)}, walker.get_revision_paths(1, "foo"))
52 self.assertEqual({"": ('A', None, -1)}, walker.get_revision_paths(0, "foo"))
54 def test_get_revision_paths_zero(self):
55 repos_url = self.make_client("a", "dc")
56 walker = logwalker.LogWalker(SvnRaTransport(repos_url))
57 self.assertEqual({'': ('A', None, -1)}, walker.get_revision_paths(0))
59 def test_get_branch_invalid_revision(self):
60 repos_url = self.make_client("a", "dc")
61 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
62 self.assertRaises(NoSuchRevision, list,
63 walker.follow_path("/", 20))
65 def test_branch_log_all(self):
66 repos_url = self.make_client("a", "dc")
67 self.build_tree({'dc/trunk/file': "data", "dc/foo/file":"data"})
68 self.client_add("dc/trunk")
69 self.client_add("dc/foo")
70 self.client_commit("dc", "My Message")
72 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
74 self.assertEqual(1, len(list(walker.follow_path("", 1))))
76 def test_branch_log_specific(self):
77 repos_url = self.make_client("a", "dc")
80 'dc/branches/brancha': None,
81 'dc/branches/branchab': None,
82 'dc/branches/brancha/data': "data",
83 "dc/branches/branchab/data":"data"})
84 self.client_add("dc/branches")
85 self.client_commit("dc", "My Message")
87 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
89 self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
92 def test_follow_path_ignore_unchanged(self):
93 repos_url = self.make_client("a", "dc")
94 self.build_tree({'dc/branches': None})
95 self.client_add("dc/branches")
97 'dc/branches/brancha': None,
98 'dc/branches/branchab': None,
99 'dc/branches/brancha/data': "data",
100 "dc/branches/branchab/data":"data"})
101 self.client_add("dc/branches/brancha")
102 self.client_commit("dc", "My Message")
104 self.client_add("dc/branches/branchab")
105 self.client_commit("dc", "My Message2")
107 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
109 self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
112 def test_find_latest_none(self):
113 repos_url = self.make_client("a", "dc")
114 self.build_tree({'dc/branches': None})
115 self.client_add("dc/branches")
116 self.client_commit("dc", "My Message")
118 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
120 self.assertEqual(0, walker.find_latest_change("", 1))
122 def test_find_latest_parent(self):
123 repos_url = self.make_client("a", "dc")
124 self.build_tree({'dc/branches/tmp/foo': None, 'dc/tags': None})
125 self.client_add("dc/branches")
126 self.client_add("dc/tags")
127 self.client_commit("dc", "My Message")
128 self.client_copy("dc/branches/tmp", "dc/tags/tmp")
129 self.client_commit("dc", "My Message2")
131 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
133 self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 2))
135 def test_find_latest_parent_just_modify(self):
136 repos_url = self.make_client("a", "dc")
137 self.build_tree({'dc/branches/tmp/foo': None, 'dc/tags': None})
138 self.client_add("dc/branches")
139 self.client_add("dc/tags")
140 self.client_commit("dc", "My Message")
141 self.client_copy("dc/branches/tmp", "dc/tags/tmp")
142 self.client_commit("dc", "My Message2")
143 self.client_update("dc")
144 self.client_set_prop("dc/tags", "myprop", "mydata")
145 self.client_commit("dc", "My Message3")
147 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
148 self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 3))
150 def test_find_latest_parentmoved(self):
151 repos_url = self.make_client("a", "dc")
152 self.build_tree({'dc/branches/tmp': None})
153 self.client_add("dc/branches")
154 self.client_commit("dc", "My Message")
156 self.client_copy("dc/branches", "dc/bla")
157 self.client_commit("dc", "My Message")
159 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
161 self.assertIs(2, walker.find_latest_change("bla/tmp", 2))
163 def test_find_latest_nonexistant(self):
164 repos_url = self.make_client("a", "dc")
165 self.build_tree({'dc/branches/tmp': None})
166 self.client_add("dc/branches")
167 self.client_commit("dc", "My Message")
169 self.client_copy("dc/branches", "dc/bla")
170 self.client_commit("dc", "My Message")
172 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
174 self.assertIs(None, walker.find_latest_change("bloe", 2))
175 self.assertIs(None, walker.find_latest_change("bloe/bla", 2))
177 def test_find_latest_change(self):
178 repos_url = self.make_client("a", "dc")
179 self.build_tree({'dc/branches': None})
180 self.client_add("dc/branches")
181 self.client_commit("dc", "My Message")
183 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
185 self.assertEqual(1, walker.find_latest_change("branches", 1))
187 def test_find_latest_change_children(self):
188 repos_url = self.make_client("a", "dc")
189 self.build_tree({'dc/branches': None})
190 self.client_add("dc/branches")
191 self.client_commit("dc", "My Message")
192 self.build_tree({'dc/branches/foo': 'data'})
193 self.client_add("dc/branches/foo")
194 self.client_commit("dc", "My Message2")
196 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
198 self.assertEqual(1, walker.find_latest_change("branches", 2))
200 def test_find_latest_change_prop(self):
201 repos_url = self.make_client("a", "dc")
202 self.build_tree({'dc/branches': None})
203 self.client_add("dc/branches")
204 self.client_commit("dc", "My Message")
205 self.build_tree({'dc/branches/foo': 'data'})
206 self.client_set_prop("dc/branches", "myprop", "mydata")
207 self.client_commit("dc", "propchange")
208 self.client_add("dc/branches/foo")
209 self.client_commit("dc", "My Message2")
211 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
213 self.assertEqual(2, walker.find_latest_change("branches", 3))
215 def test_find_latest_change_file(self):
216 repos_url = self.make_client("a", "dc")
217 self.build_tree({'dc/branches': None})
218 self.client_add("dc/branches")
219 self.client_commit("dc", "My Message")
220 self.build_tree({'dc/branches/foo': 'data'})
221 self.client_add("dc/branches/foo")
222 self.client_commit("dc", "propchange")
223 self.build_tree({'dc/branches/foo': 'data4'})
224 self.client_commit("dc", "My Message2")
226 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
228 self.assertEqual(3, walker.find_latest_change("branches/foo", 3))
230 def test_find_latest_change_newer(self):
231 repos_url = self.make_client("a", "dc")
232 self.build_tree({'dc/branches': None})
233 self.client_add("dc/branches")
234 self.client_commit("dc", "My Message")
235 self.build_tree({'dc/branches/foo': 'data'})
236 self.client_add("dc/branches/foo")
237 self.client_commit("dc", "propchange")
238 self.build_tree({'dc/branches/foo': 'data4'})
239 self.client_commit("dc", "My Message2")
241 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
243 self.assertEqual(2, walker.find_latest_change("branches/foo", 2))
245 def test_follow_history_branch_replace(self):
246 repos_url = self.make_client("a", "dc")
248 self.build_tree({'dc/trunk/data': "data"})
249 self.client_add("dc/trunk")
250 self.client_commit("dc", "Cm1")
252 self.client_delete("dc/trunk")
253 self.client_commit("dc", "Cm1")
255 self.build_tree({'dc/trunk/data': "data"})
256 self.client_add("dc/trunk")
257 self.client_commit("dc", "Cm1")
259 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
260 self.assertEqual([("trunk", {"trunk/data": ('A', None, -1),
261 "trunk": ('A', None, -1)}, 3)],
262 list(walker.follow_path("trunk", 3)))
264 def test_follow_history(self):
265 repos_url = self.make_client("a", "dc")
266 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
268 self.build_tree({'dc/foo': "data"})
269 self.client_add("dc/foo")
270 self.client_commit("dc", "My Message")
272 for (branch, paths, rev) in walker.follow_path("", 1):
273 self.assertEqual(branch, "")
274 self.assertTrue(paths.has_key("foo"))
275 self.assertEqual(rev, 1)
277 def test_follow_history_nohist(self):
278 repos_url = self.make_client("a", "dc")
279 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
281 self.assertEqual([], list(walker.follow_path("", 0)))
283 def test_later_update(self):
284 repos_url = self.make_client("a", "dc")
286 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
288 self.build_tree({'dc/foo': "data"})
289 self.client_add("dc/foo")
290 self.client_commit("dc", "My Message")
292 for (branch, paths, rev) in walker.follow_path("", 1):
293 self.assertEqual(branch, "")
294 self.assertTrue(paths.has_key("foo"))
295 self.assertEqual(rev, 1)
297 iter = walker.follow_path("", 2)
298 self.assertRaises(NoSuchRevision, list, iter)
300 def test_get_branch_log_follow(self):
301 repos_url = self.make_client("a", "dc")
302 self.build_tree({'dc/trunk/afile': "data", "dc/branches": None})
303 self.client_add("dc/trunk")
304 self.client_add("dc/branches")
305 self.client_commit("dc", "My Message")
307 self.client_copy("dc/trunk", "dc/branches/abranch")
308 self.client_commit("dc", "Create branch")
310 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
312 items = list(walker.follow_path("branches/abranch", 2))
313 self.assertEqual([('branches/abranch', {'branches/abranch': ('A', 'trunk', 1)}, 2),
314 ('trunk', {'trunk/afile': ('A', None, -1),
315 'trunk': (u'A', None, -1)}, 1)], items)
317 def test_touches_path(self):
318 repos_url = self.make_client("a", "dc")
319 self.build_tree({'dc/trunk/afile': "data"})
320 self.client_add("dc/trunk")
321 self.client_commit("dc", "My Message")
323 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
325 self.assertTrue(walker.touches_path("trunk", 1))
327 def test_touches_path_null(self):
328 repos_url = self.make_client("a", "dc")
329 self.build_tree({'dc/trunk/afile': "data"})
330 self.client_add("dc/trunk")
331 self.client_commit("dc", "My Message")
333 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
335 self.assertTrue(walker.touches_path("", 0))
337 def test_touches_path_not(self):
338 repos_url = self.make_client("a", "dc")
339 self.build_tree({'dc/trunk/afile': "data"})
340 self.client_add("dc/trunk")
341 self.client_commit("dc", "My Message")
343 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
345 self.assertFalse(walker.touches_path("", 1))
347 def test_touches_path_child(self):
348 repos_url = self.make_client("a", "dc")
349 self.build_tree({'dc/trunk/afile': "data"})
350 self.client_add("dc/trunk")
351 self.client_commit("dc", "My Message")
352 self.build_tree({'dc/trunk/afile': "data2"})
353 self.client_commit("dc", "My Message")
355 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
357 self.assertFalse(walker.touches_path("trunk", 2))
359 def test_get_previous_root(self):
360 repos_url = self.make_client("a", "dc")
362 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
364 self.assertEqual((None, -1), walker.get_previous("", 0))
366 def test_get_previous_simple(self):
367 repos_url = self.make_client("a", "dc")
368 self.build_tree({'dc/trunk/afile': "data"})
369 self.client_add("dc/trunk")
370 self.client_commit("dc", "My Message")
371 self.build_tree({'dc/trunk/afile': "data2"})
372 self.client_set_prop("dc/trunk", "myprop", "mydata")
373 self.client_commit("dc", "My Message")
375 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
377 self.assertEqual(("trunk", 1), walker.get_previous("trunk", 2))
379 def test_get_previous_added(self):
380 repos_url = self.make_client("a", "dc")
381 self.build_tree({'dc/trunk/afile': "data"})
382 self.client_add("dc/trunk")
383 self.client_commit("dc", "My Message")
384 self.build_tree({'dc/trunk/afile': "data2"})
385 self.client_set_prop("dc/trunk", "myprop", "mydata")
386 self.client_commit("dc", "My Message")
388 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
390 self.assertEqual((None, -1), walker.get_previous("trunk", 1))
392 def test_get_previous_copy(self):
393 repos_url = self.make_client("a", "dc")
394 self.build_tree({'dc/trunk/afile': "data"})
395 self.client_add("dc/trunk")
396 self.client_commit("dc", "My Message")
397 self.client_copy("dc/trunk", "dc/anotherfile")
398 self.client_commit("dc", "My Message")
400 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
402 self.assertEqual(("trunk", 1), walker.get_previous("anotherfile", 2))
404 def test_get_revision_info(self):
405 repos_url = self.make_client("a", "dc")
406 self.build_tree({'dc/trunk/afile': "data"})
407 self.client_add("dc/trunk")
408 self.client_commit("dc", "My Message")
410 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
412 info = walker.get_revision_info(1)
414 self.assertEqual("", info[0])
415 self.assertEqual("My Message", info[1])
417 def test_find_children_empty(self):
418 repos_url = self.make_client("a", "dc")
419 self.build_tree({'dc/trunk': None})
420 self.client_add("dc/trunk")
421 self.client_commit("dc", "My Message")
423 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
425 self.assertEqual([], list(walker.find_children("trunk", 1)))
427 def test_find_children_one(self):
428 repos_url = self.make_client("a", "dc")
429 self.build_tree({'dc/trunk/data': 'foo'})
430 self.client_add("dc/trunk")
431 self.client_commit("dc", "My Message")
433 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
435 self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
437 def test_find_children_nested(self):
438 repos_url = self.make_client("a", "dc")
439 self.build_tree({'dc/trunk/data/bla': 'foo', 'dc/trunk/file': 'bla'})
440 self.client_add("dc/trunk")
441 self.client_commit("dc", "My Message")
443 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
446 set(['trunk/data', 'trunk/data/bla', 'trunk/file']),
447 set(walker.find_children("trunk", 1)))
449 def test_find_children_later(self):
450 repos_url = self.make_client("a", "dc")
451 self.build_tree({'dc/trunk/data/bla': 'foo'})
452 self.client_add("dc/trunk")
453 self.client_commit("dc", "My Message")
454 self.build_tree({'dc/trunk/file': 'bla'})
455 self.client_add("dc/trunk/file")
456 self.client_commit("dc", "My Message")
458 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
460 self.assertEqual(set(['trunk/data', 'trunk/data/bla']),
461 set(walker.find_children("trunk", 1)))
462 self.assertEqual(set(['trunk/data', 'trunk/data/bla', 'trunk/file']),
463 set(walker.find_children("trunk", 2)))
465 def test_find_children_copy(self):
466 repos_url = self.make_client("a", "dc")
467 self.build_tree({'dc/trunk/data/bla': 'foo',
468 'dc/trunk/db/f1': 'bloe',
469 'dc/trunk/db/f2': 'bla'})
470 self.client_add("dc/trunk")
471 self.client_commit("dc", "My Message")
472 self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
473 self.client_commit("dc", "My Message")
475 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
477 self.assertEqual(set(['trunk/data', 'trunk/data/bla',
478 'trunk/data/fg', 'trunk/data/fg/f1',
479 'trunk/data/fg/f2', 'trunk/db',
480 'trunk/db/f1', 'trunk/db/f2']),
481 set(walker.find_children("trunk", 2)))
483 def test_find_children_copy_del(self):
484 repos_url = self.make_client("a", "dc")
485 self.build_tree({'dc/trunk/data/bla': 'foo',
486 'dc/trunk/db/f1': 'bloe',
487 'dc/trunk/db/f2': 'bla'})
488 self.client_add("dc/trunk")
489 self.client_commit("dc", "My Message")
490 self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
491 self.client_commit("dc", "My Message")
492 self.client_delete("dc/trunk/data/fg/f2")
493 self.client_commit("dc", "My Message")
495 walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
497 self.assertEqual(set(['trunk/data', 'trunk/data/bla',
498 'trunk/data/fg', 'trunk/data/fg/f1', 'trunk/db',
499 'trunk/db/f1', 'trunk/db/f2']),
500 set(walker.find_children("trunk", 3)))