Add test for bug #91641
[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.errors import NoSuchRevision
18
19 import os
20 import logwalker
21 from tests import TestCaseWithSubversionRepository
22 from transport import SvnRaTransport
23
24 class TestLogWalker(TestCaseWithSubversionRepository):
25     def setUp(self):
26         super(TestLogWalker, self).setUp()
27
28         logwalker.cache_dir = os.path.join(self.test_dir, "cache-dir")
29
30     def test_create(self):
31         repos_url = self.make_client("a", "ac")
32         logwalker.LogWalker(transport=SvnRaTransport(repos_url))
33
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")
39
40         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
41
42         self.assertEqual(1, len(list(walker.follow_path("", 1))))
43
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"))
53
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))
58
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))
64
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")
71
72         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
73
74         self.assertEqual(1, len(list(walker.follow_path("", 1))))
75
76     def test_branch_log_specific(self):
77         repos_url = self.make_client("a", "dc")
78         self.build_tree({
79             'dc/branches': None,
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")
86
87         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
88
89         self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
90             1))))
91
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")
96         self.build_tree({
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")
103
104         self.client_add("dc/branches/branchab")
105         self.client_commit("dc", "My Message2")
106
107         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
108
109         self.assertEqual(1, len(list(walker.follow_path("branches/brancha",
110             2))))
111
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")
117
118         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
119
120         self.assertEqual(0, walker.find_latest_change("", 1))
121
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")
130
131         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
132
133         self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 2))
134
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")
146
147         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
148         self.assertEqual(2, walker.find_latest_change("tags/tmp/foo", 3))
149
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")
155
156         self.client_copy("dc/branches", "dc/bla")
157         self.client_commit("dc", "My Message")
158
159         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
160
161         self.assertIs(2, walker.find_latest_change("bla/tmp", 2))
162
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")
168
169         self.client_copy("dc/branches", "dc/bla")
170         self.client_commit("dc", "My Message")
171
172         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
173
174         self.assertIs(None, walker.find_latest_change("bloe", 2))
175         self.assertIs(None, walker.find_latest_change("bloe/bla", 2))
176
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")
182
183         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
184
185         self.assertEqual(1, walker.find_latest_change("branches", 1))
186
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")
195
196         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
197
198         self.assertEqual(1, walker.find_latest_change("branches", 2))
199
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")
210
211         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
212
213         self.assertEqual(2, walker.find_latest_change("branches", 3))
214
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")
225
226         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
227
228         self.assertEqual(3, walker.find_latest_change("branches/foo", 3))
229
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")
240
241         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
242
243         self.assertEqual(2, walker.find_latest_change("branches/foo", 2))
244
245     def test_follow_history_branch_replace(self):
246         repos_url = self.make_client("a", "dc")
247
248         self.build_tree({'dc/trunk/data': "data"})
249         self.client_add("dc/trunk")
250         self.client_commit("dc", "Cm1")
251
252         self.client_delete("dc/trunk")
253         self.client_commit("dc", "Cm1")
254
255         self.build_tree({'dc/trunk/data': "data"})
256         self.client_add("dc/trunk")
257         self.client_commit("dc", "Cm1")
258
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)))
263
264     def test_follow_history(self):
265         repos_url = self.make_client("a", "dc")
266         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
267
268         self.build_tree({'dc/foo': "data"})
269         self.client_add("dc/foo")
270         self.client_commit("dc", "My Message")
271
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)
276
277     def test_follow_history_nohist(self):
278         repos_url = self.make_client("a", "dc")
279         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
280
281         self.assertEqual([], list(walker.follow_path("", 0)))
282
283     def test_later_update(self):
284         repos_url = self.make_client("a", "dc")
285
286         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
287
288         self.build_tree({'dc/foo': "data"})
289         self.client_add("dc/foo")
290         self.client_commit("dc", "My Message")
291
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)
296
297         iter = walker.follow_path("", 2)
298         self.assertRaises(NoSuchRevision, list, iter)
299
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")
306
307         self.client_copy("dc/trunk", "dc/branches/abranch")
308         self.client_commit("dc", "Create branch")
309
310         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
311
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)
316
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")
322
323         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
324
325         self.assertTrue(walker.touches_path("trunk", 1))
326
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")
332
333         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
334
335         self.assertTrue(walker.touches_path("", 0))
336
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")
342
343         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
344
345         self.assertFalse(walker.touches_path("", 1))
346
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")
354
355         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
356
357         self.assertFalse(walker.touches_path("trunk", 2))
358
359     def test_get_previous_root(self):
360         repos_url = self.make_client("a", "dc")
361
362         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
363
364         self.assertEqual((None, -1), walker.get_previous("", 0))
365
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")
374
375         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
376
377         self.assertEqual(("trunk", 1), walker.get_previous("trunk", 2))
378
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")
387
388         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
389
390         self.assertEqual((None, -1), walker.get_previous("trunk", 1))
391
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")
399
400         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
401
402         self.assertEqual(("trunk", 1), walker.get_previous("anotherfile", 2))
403
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")
409
410         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
411
412         info = walker.get_revision_info(1)
413
414         self.assertEqual("", info[0])
415         self.assertEqual("My Message", info[1])
416
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")
422
423         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
424
425         self.assertEqual([], list(walker.find_children("trunk", 1)))
426
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")
432
433         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
434
435         self.assertEqual(['trunk/data'], list(walker.find_children("trunk", 1)))
436
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")
442
443         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
444
445         self.assertEqual(
446                 set(['trunk/data', 'trunk/data/bla', 'trunk/file']), 
447                 set(walker.find_children("trunk", 1)))
448
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")
457
458         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
459
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)))
464
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")
474
475         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
476
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)))
482
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")
494
495         walker = logwalker.LogWalker(transport=SvnRaTransport(repos_url))
496
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)))