Merge dev tree.
[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(1, 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(1, 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(paths.has_key("foo"))
278            self.assertEqual(rev, 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(paths.has_key("foo"))
298            self.assertEqual(rev, 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(self):
408         repos_url = self.make_client("a", "dc")
409         self.build_tree({'dc/trunk/afile': "data"})
410         self.client_add("dc/trunk")
411         self.client_commit("dc", "My Message")
412
413         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
414
415         info = walker.get_revision_info(1)
416
417         self.assertEqual("", info[0])
418         self.assertEqual("My Message", info[1])
419
420     def test_find_children_empty(self):
421         repos_url = self.make_client("a", "dc")
422         self.build_tree({'dc/trunk': None})
423         self.client_add("dc/trunk")
424         self.client_commit("dc", "My Message")
425
426         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
427
428         self.assertEqual([], list(walker.find_children("trunk", 1)))
429
430     def test_find_children_one(self):
431         repos_url = self.make_client("a", "dc")
432         self.build_tree({'dc/trunk/data': 'foo'})
433         self.client_add("dc/trunk")
434         self.client_commit("dc", "My Message")
435
436         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
437
438         self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
439
440     def test_find_children_nested(self):
441         repos_url = self.make_client("a", "dc")
442         self.build_tree({'dc/trunk/data/bla': 'foo', 'dc/trunk/file': 'bla'})
443         self.client_add("dc/trunk")
444         self.client_commit("dc", "My Message")
445
446         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
447
448         self.assertEqual(
449                 set(['trunk/data', 'trunk/data/bla', 'trunk/file']), 
450                 set(walker.find_children("trunk", 1)))
451
452     def test_find_children_later(self):
453         repos_url = self.make_client("a", "dc")
454         self.build_tree({'dc/trunk/data/bla': 'foo'})
455         self.client_add("dc/trunk")
456         self.client_commit("dc", "My Message")
457         self.build_tree({'dc/trunk/file': 'bla'})
458         self.client_add("dc/trunk/file")
459         self.client_commit("dc", "My Message")
460
461         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
462
463         self.assertEqual(set(['trunk/data', 'trunk/data/bla']), 
464                 set(walker.find_children("trunk", 1)))
465         self.assertEqual(set(['trunk/data', 'trunk/data/bla', 'trunk/file']), 
466                 set(walker.find_children("trunk", 2)))
467
468     def test_find_children_copy(self):
469         repos_url = self.make_client("a", "dc")
470         self.build_tree({'dc/trunk/data/bla': 'foo',
471                          'dc/trunk/db/f1': 'bloe',
472                          'dc/trunk/db/f2': 'bla'})
473         self.client_add("dc/trunk")
474         self.client_commit("dc", "My Message")
475         self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
476         self.client_commit("dc", "My Message")
477
478         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
479
480         self.assertEqual(set(['trunk/data', 'trunk/data/bla', 
481                           'trunk/data/fg', 'trunk/data/fg/f1', 
482                           'trunk/data/fg/f2', 'trunk/db',
483                           'trunk/db/f1', 'trunk/db/f2']), 
484                 set(walker.find_children("trunk", 2)))
485
486     def test_find_children_copy_del(self):
487         repos_url = self.make_client("a", "dc")
488         self.build_tree({'dc/trunk/data/bla': 'foo',
489                          'dc/trunk/db/f1': 'bloe',
490                          'dc/trunk/db/f2': 'bla'})
491         self.client_add("dc/trunk")
492         self.client_commit("dc", "My Message")
493         self.client_copy("dc/trunk/db", "dc/trunk/data/fg")
494         self.client_commit("dc", "My Message")
495         self.client_delete("dc/trunk/data/fg/f2")
496         self.client_commit("dc", "My Message")
497
498         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
499
500         self.assertEqual(set(['trunk/data', 'trunk/data/bla', 
501                           'trunk/data/fg', 'trunk/data/fg/f1', 'trunk/db',
502                           'trunk/db/f1', 'trunk/db/f2']), 
503                 set(walker.find_children("trunk", 3)))