Merge two trivial fixes from the 0.3 branch.
[jelmer/subvertpy.git] / tests / test_logwalker.py
1 # Copyright (C) 2006-2007 Jelmer Vernooij <jelmer@samba.org>
2
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.
7
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.
12
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
16
17 from bzrlib.bzrdir import BzrDir
18 from bzrlib.errors import NoSuchRevision
19 from bzrlib.inventory import Inventory
20
21 import os
22 import logwalker
23 from scheme import NoBranchingScheme, TrunkBranchingScheme
24 from tests import TestCaseWithSubversionRepository
25 from transport import SvnRaTransport
26
27 class TestLogWalker(TestCaseWithSubversionRepository):
28     def setUp(self):
29         super(TestLogWalker, self).setUp()
30
31         logwalker.cache_dir = os.path.join(self.test_dir, "cache-dir")
32
33     def test_create(self):
34         repos_url = self.make_client("a", "ac")
35         logwalker.LogWalker(transport=SvnRaTransport(repos_url))
36
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")
42
43         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
44
45         self.assertEqual(2, len(list(walker.follow_path("", 1))))
46
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"))
56
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))
61
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))
67
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")
74
75         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
76
77         self.assertEqual(2, len(list(walker.follow_path("", 1))))
78
79     def test_branch_log_specific(self):
80         repos_url = self.make_client("a", "dc")
81         self.build_tree({
82             'dc/branches': None,
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")
89
90         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
91
92         self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
93             1))))
94
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")
99         self.build_tree({
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")
106
107         self.client_add("dc/branches/branchab")
108         self.client_commit("dc", "My Message2")
109
110         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
111
112         self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
113             2))))
114
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")
120
121         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
122
123         self.assertEqual(0, walker.find_latest_change("", 1))
124
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")
133
134         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
135
136         self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 2))
137
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")
149
150         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
151         self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 3))
152
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")
158
159         self.client_copy("dc/branches", "dc/bla")
160         self.client_commit("dc", "My Message")
161
162         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
163
164         self.assertIs(2, walker.find_latest_change("bla/tmp", 2))
165
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")
171
172         self.client_copy("dc/branches", "dc/bla")
173         self.client_commit("dc", "My Message")
174
175         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
176
177         self.assertIs(None, walker.find_latest_change("bloe", 2))
178         self.assertIs(None, walker.find_latest_change("bloe/bla", 2))
179
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")
185
186         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
187
188         self.assertEqual(1, walker.find_latest_change("branches", 1))
189
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")
198
199         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
200
201         self.assertEqual(1, walker.find_latest_change("branches", 2))
202
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")
213
214         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
215
216         self.assertEqual(2, walker.find_latest_change("branches", 3))
217
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")
228
229         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
230
231         self.assertEqual(3, walker.find_latest_change("branches/foo", 3))
232
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")
243
244         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
245
246         self.assertEqual(2, walker.find_latest_change("branches/foo", 2))
247
248     def test_follow_history_branch_replace(self):
249         repos_url = self.make_client("a", "dc")
250
251         self.build_tree({'dc/trunk/data': "data"})
252         self.client_add("dc/trunk")
253         self.client_commit("dc", "Cm1")
254
255         self.client_delete("dc/trunk")
256         self.client_commit("dc", "Cm1")
257
258         self.build_tree({'dc/trunk/data': "data"})
259         self.client_add("dc/trunk")
260         self.client_commit("dc", "Cm1")
261
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)))
266
267     def test_follow_history(self):
268         repos_url = self.make_client("a", "dc")
269         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
270
271         self.build_tree({'dc/foo': "data"})
272         self.client_add("dc/foo")
273         self.client_commit("dc", "My Message")
274
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))
279
280     def test_follow_history_nohist(self):
281         repos_url = self.make_client("a", "dc")
282         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
283
284         self.assertEqual([], list(walker.follow_path("", 0)))
285
286     def test_later_update(self):
287         repos_url = self.make_client("a", "dc")
288
289         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
290
291         self.build_tree({'dc/foo': "data"})
292         self.client_add("dc/foo")
293         self.client_commit("dc", "My Message")
294
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))
299
300         iter = walker.follow_path("", 2)
301         self.assertRaises(NoSuchRevision, list, iter)
302
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")
309
310         self.client_copy("dc/trunk", "dc/branches/abranch")
311         self.client_commit("dc", "Create branch")
312
313         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
314
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)
319
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")
325
326         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
327
328         self.assertTrue(walker.touches_path("trunk", 1))
329
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")
335
336         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
337
338         self.assertTrue(walker.touches_path("", 0))
339
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")
345
346         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
347
348         self.assertFalse(walker.touches_path("", 1))
349
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")
357
358         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
359
360         self.assertFalse(walker.touches_path("trunk", 2))
361
362     def test_get_previous_root(self):
363         repos_url = self.make_client("a", "dc")
364
365         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
366
367         self.assertEqual((None, -1), walker.get_previous("", 0))
368
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")
377
378         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
379
380         self.assertEqual(("trunk", 1), walker.get_previous("trunk", 2))
381
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")
390
391         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
392
393         self.assertEqual((None, -1), walker.get_previous("trunk", 1))
394
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")
402
403         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
404
405         self.assertEqual(("trunk", 1), walker.get_previous("anotherfile", 2))
406
407     def test_get_revision_info_zero(self):
408         repos_url = self.make_client("a", "dc")
409
410         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
411
412         info = walker.get_revision_info(0)
413
414         self.assertEqual(None, info[0])
415         self.assertEqual(None, info[1])
416         self.assertEqual(None, info[2])
417
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")
423
424         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
425
426         info = walker.get_revision_info(1)
427
428         self.assertEqual("", info[0])
429         self.assertEqual("My Message", info[1])
430
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")
436
437         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
438
439         self.assertEqual([], list(walker.find_children("trunk", 1)))
440
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")
446
447         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
448
449         self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
450
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")
456
457         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
458
459         self.assertEqual(
460                 set(['trunk/data', 'trunk/data/bla', 'trunk/file']), 
461                 set(walker.find_children("trunk", 1)))
462
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")
471
472         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
473
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)))
478
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")
488
489         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
490
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)))
496
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")
508
509         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
510
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)))