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
19 from bzrlib.branch import Branch
20 from bzrlib.bzrdir import BzrDir
21 from bzrlib.errors import NoSuchFile, NoSuchRevision, NotBranchError
22 from bzrlib.repository import Repository
23 from bzrlib.trace import mutter
26 from unittest import TestCase
28 from branch import FakeControlFiles, SvnBranchFormat
29 from convert import load_dumpfile
30 from fileids import generate_svn_file_id
31 from repository import MAPPING_VERSION, generate_svn_revision_id, SVN_PROP_BZR_REVISION_ID
32 from tests import TestCaseWithSubversionRepository
34 class WorkingSubversionBranch(TestCaseWithSubversionRepository):
35 def test_last_rev_rev_hist(self):
36 repos_url = self.make_client("a", "dc")
37 branch = Branch.open(repos_url)
38 branch.revision_history()
39 self.assertEqual(branch.generate_revision_id(0), branch.last_revision())
41 def test_get_branch_path_root(self):
42 repos_url = self.make_client("a", "dc")
43 branch = Branch.open(repos_url)
44 self.assertEqual("", branch.get_branch_path())
46 def test_get_branch_path_subdir(self):
47 repos_url = self.make_client("a", "dc")
48 self.build_tree({"dc/trunk": None})
49 self.client_add("dc/trunk")
50 self.client_commit("dc", "Add branch")
51 branch = Branch.open(repos_url+"/trunk")
52 self.assertEqual("trunk", branch.get_branch_path())
54 def test_open_nonexistant(self):
55 repos_url = self.make_client("a", "dc")
56 self.assertRaises(NotBranchError, Branch.open, repos_url + "/trunk")
58 def test_last_rev_rev_info(self):
59 repos_url = self.make_client("a", "dc")
60 branch = Branch.open(repos_url)
61 self.assertEqual((1, branch.generate_revision_id(0)),
62 branch.last_revision_info())
63 branch.revision_history()
64 self.assertEqual((1, branch.generate_revision_id(0)),
65 branch.last_revision_info())
67 def test_lookup_revision_id_unknown(self):
68 repos_url = self.make_client("a", "dc")
69 branch = Branch.open(repos_url)
70 self.assertRaises(NoSuchRevision,
71 lambda: branch.lookup_revision_id("bla"))
73 def test_lookup_revision_id(self):
74 repos_url = self.make_client("a", "dc")
75 branch = Branch.open(repos_url)
77 branch.lookup_revision_id(branch.last_revision()))
79 def test_set_parent(self):
80 repos_url = self.make_client('a', 'dc')
81 branch = Branch.open(repos_url)
82 branch.set_parent("foobar")
84 def test_num_revnums(self):
85 repos_url = self.make_client('a', 'dc')
86 bzrdir = BzrDir.open("svn+"+repos_url)
87 branch = bzrdir.open_branch()
88 self.assertEqual(branch.generate_revision_id(0),
89 branch.last_revision())
91 self.build_tree({'dc/foo': "data"})
92 self.client_add("dc/foo")
93 self.client_commit("dc", "My Message")
94 self.client_update("dc")
96 bzrdir = BzrDir.open("svn+"+repos_url)
97 branch = bzrdir.open_branch()
98 repos = bzrdir.find_repository()
100 self.assertEqual(repos.generate_revision_id(1, "", "none"),
101 branch.last_revision())
103 self.build_tree({'dc/foo': "data2"})
104 self.client_commit("dc", "My Message")
106 branch = Branch.open("svn+"+repos_url)
107 repos = Repository.open("svn+"+repos_url)
109 self.assertEqual(repos.generate_revision_id(2, "", "none"),
110 branch.last_revision())
112 def test_set_revision_history(self):
113 repos_url = self.make_client('a', 'dc')
114 branch = Branch.open("svn+"+repos_url)
115 self.assertRaises(NotImplementedError, branch.set_revision_history, [])
117 def test_break_lock(self):
118 repos_url = self.make_client('a', 'dc')
119 branch = Branch.open("svn+"+repos_url)
120 branch.control_files.break_lock()
123 repos_url = self.make_client('a', 'dc')
124 branch = Branch.open("svn+"+repos_url)
125 self.assertEqual("SvnBranch('svn+%s')" % repos_url, branch.__repr__())
127 def test_get_physical_lock_status(self):
128 repos_url = self.make_client('a', 'dc')
129 branch = Branch.open("svn+"+repos_url)
130 self.assertFalse(branch.get_physical_lock_status())
132 def test_set_push_location(self):
133 repos_url = self.make_client('a', 'dc')
134 branch = Branch.open("svn+"+repos_url)
135 self.assertRaises(NotImplementedError, branch.set_push_location, [])
137 def test_get_parent(self):
138 repos_url = self.make_client('a', 'dc')
139 branch = Branch.open("svn+"+repos_url)
140 self.assertEqual("svn+"+repos_url, branch.get_parent())
142 def test_append_revision(self):
143 repos_url = self.make_client('a', 'dc')
144 branch = Branch.open("svn+"+repos_url)
145 branch.append_revision([])
147 def test_get_push_location(self):
148 repos_url = self.make_client('a', 'dc')
149 branch = Branch.open("svn+"+repos_url)
150 self.assertIs(None, branch.get_push_location())
152 def test_revision_history(self):
153 repos_url = self.make_client('a', 'dc')
155 branch = Branch.open("svn+"+repos_url)
156 self.assertEqual([branch.generate_revision_id(0)],
157 branch.revision_history())
159 self.build_tree({'dc/foo': "data"})
160 self.client_add("dc/foo")
161 self.client_set_prop("dc", SVN_PROP_BZR_REVISION_ID+"none",
163 self.client_commit("dc", "My Message")
164 self.client_update("dc")
166 branch = Branch.open("svn+"+repos_url)
167 repos = Repository.open("svn+"+repos_url)
169 self.assertEqual([repos.generate_revision_id(0, "", "none"),
170 repos.generate_revision_id(1, "", "none")],
171 branch.revision_history())
173 self.build_tree({'dc/foo': "data34"})
174 self.client_commit("dc", "My Message")
176 branch = Branch.open("svn+"+repos_url)
177 repos = Repository.open("svn+"+repos_url)
180 repos.generate_revision_id(0, "", "none"),
182 repos.generate_revision_id(2, "", "none")],
183 branch.revision_history())
185 def test_revision_id_to_revno_none(self):
186 """The None revid should map to revno 0."""
187 repos_url = self.make_client('a', 'dc')
188 branch = Branch.open(repos_url)
189 self.assertEquals(0, branch.revision_id_to_revno(None))
191 def test_revision_id_to_revno_nonexistant(self):
192 """revision_id_to_revno() should raise NoSuchRevision if
193 the specified revision did not exist in the branch history."""
194 repos_url = self.make_client('a', 'dc')
195 branch = Branch.open(repos_url)
196 self.assertRaises(NoSuchRevision, branch.revision_id_to_revno, "bla")
198 def test_revision_id_to_revno_simple(self):
199 repos_url = self.make_client('a', 'dc')
200 self.build_tree({'dc/foo': "data"})
201 self.client_add("dc/foo")
202 self.client_set_prop("dc", "bzr:revision-id:v%d-none" % MAPPING_VERSION,
204 self.client_commit("dc", "My Message")
205 branch = Branch.open(repos_url)
206 self.assertEquals(2, branch.revision_id_to_revno("myrevid"))
208 def test_revision_id_to_revno_older(self):
209 repos_url = self.make_client('a', 'dc')
210 self.build_tree({'dc/foo': "data"})
211 self.client_add("dc/foo")
212 self.client_set_prop("dc", "bzr:revision-id:v%d-none" % MAPPING_VERSION,
214 self.client_commit("dc", "My Message")
215 self.build_tree({'dc/foo': "someotherdata"})
216 self.client_set_prop("dc", "bzr:revision-id:v%d-none" % MAPPING_VERSION,
217 "2 myrevid\n3 mysecondrevid\n")
218 self.client_commit("dc", "My Message")
219 branch = Branch.open(repos_url)
220 self.assertEquals(3, branch.revision_id_to_revno("mysecondrevid"))
221 self.assertEquals(2, branch.revision_id_to_revno("myrevid"))
223 def test_get_nick_none(self):
224 repos_url = self.make_client('a', 'dc')
226 self.build_tree({'dc/foo': "data"})
227 self.client_add("dc/foo")
228 self.client_commit("dc", "My Message")
230 branch = Branch.open("svn+"+repos_url)
232 self.assertIs(None, branch.nick)
234 def test_get_nick_path(self):
235 repos_url = self.make_client('a', 'dc')
237 self.build_tree({'dc/trunk': None})
238 self.client_add("dc/trunk")
239 self.client_commit("dc", "My Message")
241 branch = Branch.open("svn+"+repos_url+"/trunk")
243 self.assertEqual("trunk", branch.nick)
245 def test_get_revprops(self):
246 repos_url = self.make_client('a', 'dc')
248 self.build_tree({'dc/foo': "data"})
249 self.client_add("dc/foo")
250 self.client_set_prop("dc", "bzr:revision-info",
251 "properties: \n\tbranch-nick: mybranch\n")
252 self.client_commit("dc", "My Message")
254 branch = Branch.open("svn+"+repos_url)
256 rev = branch.repository.get_revision(branch.last_revision())
258 self.assertEqual("mybranch", rev.properties["branch-nick"])
260 def test_fetch_replace(self):
261 filename = os.path.join(self.test_dir, "dumpfile")
262 open(filename, 'w').write("""SVN-fs-dump-format-version: 2
264 UUID: 6f95bc5c-e18d-4021-aca8-49ed51dbcb75
267 Prop-content-length: 56
273 2006-07-30T12:41:25.270824Z
277 Prop-content-length: 94
291 2006-07-30T12:41:26.117512Z
297 Prop-content-length: 10
303 Node-path: trunk/hosts
306 Prop-content-length: 10
307 Text-content-length: 4
308 Text-content-md5: 771ec3328c29d17af5aacf7f895dd885
315 Prop-content-length: 94
329 2006-07-30T12:41:27.130044Z
332 Node-path: trunk/hosts
335 Text-content-length: 4
336 Text-content-md5: 6c2479dbb342b8df96d84db7ab92c412
342 Prop-content-length: 94
356 2006-07-30T12:41:28.114350Z
359 Node-path: trunk/hosts
362 Text-content-length: 4
363 Text-content-md5: 368cb8d3db6186e2e83d9434f165c525
369 Prop-content-length: 94
383 2006-07-30T12:41:29.129563Z
389 Prop-content-length: 10
396 Prop-content-length: 94
410 2006-07-30T12:41:31.130508Z
413 Node-path: branches/foobranch
417 Node-copyfrom-path: trunk
421 Prop-content-length: 94
435 2006-07-30T12:41:33.129149Z
438 Node-path: branches/foobranch/hosts
442 Node-path: branches/foobranch/hosts
446 Node-copyfrom-path: trunk/hosts
452 Prop-content-length: 94
466 2006-07-30T12:41:34.136423Z
469 Node-path: branches/foobranch/hosts
472 Text-content-length: 8
473 Text-content-md5: 0e328d3517a333a4879ebf3d88fd82bb
480 load_dumpfile("dumpfile", "old")
482 url = "old/branches/foobranch"
483 mutter('open %r' % url)
484 olddir = BzrDir.open(url)
486 newdir = olddir.sprout("new")
488 newbranch = newdir.open_branch()
490 uuid = "6f95bc5c-e18d-4021-aca8-49ed51dbcb75"
491 tree = newbranch.repository.revision_tree(
492 generate_svn_revision_id(uuid, 7, "branches/foobranch",
495 weave = newbranch.repository.weave_store.get_weave(
496 tree.inventory.path2id("hosts"),
497 newbranch.repository.get_transaction())
499 generate_svn_revision_id(uuid, 6, "branches/foobranch", "trunk0"),
500 generate_svn_revision_id(uuid, 7, "branches/foobranch", "trunk0")],
504 def test_fetch_odd(self):
505 repos_url = self.make_client('d', 'dc')
507 self.build_tree({'dc/trunk': None,
508 'dc/trunk/hosts': 'hej1'})
509 self.client_add("dc/trunk")
510 self.client_commit("dc", "created trunk and added hosts") #1
512 self.build_tree({'dc/trunk/hosts': 'hej2'})
513 self.client_commit("dc", "rev 2") #2
515 self.build_tree({'dc/trunk/hosts': 'hej3'})
516 self.client_commit("dc", "rev 3") #3
518 self.build_tree({'dc/branches': None})
519 self.client_add("dc/branches")
520 self.client_commit("dc", "added branches") #4
522 self.client_copy("dc/trunk", "dc/branches/foobranch")
523 self.client_commit("dc", "added branch foobranch") #5
525 self.build_tree({'dc/branches/foobranch/hosts': 'foohosts'})
526 self.client_commit("dc", "foohosts") #6
530 url = "svn+"+repos_url+"/branches/foobranch"
531 mutter('open %r' % url)
532 olddir = BzrDir.open(url)
534 newdir = olddir.sprout("new")
536 newbranch = newdir.open_branch()
538 uuid = olddir.find_repository().uuid
539 tree = newbranch.repository.revision_tree(
540 generate_svn_revision_id(uuid, 6, "branches/foobranch", "trunk0"))
542 weave = newbranch.repository.weave_store.get_weave(
543 tree.inventory.path2id("hosts"),
544 newbranch.repository.get_transaction())
546 generate_svn_revision_id(uuid, 1, "trunk", "trunk0"),
547 generate_svn_revision_id(uuid, 2, "trunk", "trunk0"),
548 generate_svn_revision_id(uuid, 3, "trunk", "trunk0"),
549 generate_svn_revision_id(uuid, 6, "branches/foobranch", "trunk0")],
552 def test_check(self):
553 self.make_client('d', 'dc')
554 branch = Branch.open('d')
555 result = branch.check()
556 self.assertEqual(branch, result.branch)
558 def test_generate_revision_id(self):
559 self.make_client('d', 'dc')
560 self.build_tree({'dc/bla/bloe': None})
561 self.client_add("dc/bla")
562 self.client_commit("dc", "bla")
563 branch = Branch.open('d')
564 self.assertEqual("svn-v%d-none:%s::1" % (MAPPING_VERSION, branch.repository.uuid), branch.generate_revision_id(1))
566 def test_create_checkout(self):
567 repos_url = self.make_client('d', 'dc')
569 self.build_tree({'dc/trunk': None, 'dc/trunk/hosts': 'hej1'})
570 self.client_add("dc/trunk")
571 self.client_commit("dc", "created trunk and added hosts") #1
573 url = "svn+"+repos_url+"/trunk"
574 oldbranch = Branch.open(url)
576 newtree = self.create_checkout(oldbranch, "e")
577 self.assertTrue(newtree.branch.repository.has_revision(
578 oldbranch.generate_revision_id(1)))
580 self.assertTrue(os.path.exists("e/.bzr"))
581 self.assertFalse(os.path.exists("e/.svn"))
583 def test_create_checkout_lightweight(self):
584 repos_url = self.make_client('d', 'dc')
586 self.build_tree({'dc/trunk': None,
587 'dc/trunk/hosts': 'hej1'})
588 self.client_add("dc/trunk")
589 self.client_commit("dc", "created trunk and added hosts") #1
591 url = "svn+"+repos_url+"/trunk"
592 oldbranch = Branch.open(url)
594 newtree = self.create_checkout(oldbranch, "e", lightweight=True)
595 self.assertEqual(oldbranch.generate_revision_id(1), newtree.base_revid)
596 self.assertTrue(os.path.exists("e/.svn"))
597 self.assertFalse(os.path.exists("e/.bzr"))
599 def test_create_checkout_lightweight_stop_rev(self):
600 repos_url = self.make_client('d', 'dc')
602 self.build_tree({'dc/trunk': None,
603 'dc/trunk/hosts': 'hej1'})
604 self.client_add("dc/trunk")
605 self.client_commit("dc", "created trunk and added hosts") #1
607 self.build_tree({'dc/trunk/hosts': 'bloe'})
608 self.client_commit("dc", "added another revision")
610 url = "svn+"+repos_url+"/trunk"
611 oldbranch = Branch.open(url)
613 newtree = self.create_checkout(oldbranch, "e", revision_id=
614 oldbranch.generate_revision_id(1), lightweight=True)
615 self.assertEqual(oldbranch.generate_revision_id(1),
617 self.assertTrue(os.path.exists("e/.svn"))
618 self.assertFalse(os.path.exists("e/.bzr"))
620 def test_fetch_branch(self):
621 self.make_client('d', 'sc')
623 self.build_tree({'sc/foo/bla': "data"})
624 self.client_add("sc/foo")
625 self.client_commit("sc", "foo")
627 olddir = self.open_checkout_bzrdir("sc")
631 newdir = olddir.sprout('dc')
634 olddir.open_branch().last_revision(),
635 newdir.open_branch().last_revision())
637 def test_fetch_dir_upgrade(self):
638 repos_url = self.make_client('d', 'sc')
640 self.build_tree({'sc/trunk/mylib/bla': "data", "sc/branches": None})
641 self.client_add("sc/trunk")
642 self.client_add("sc/branches")
643 self.client_commit("sc", "foo")
645 self.client_copy("sc/trunk/mylib", "sc/branches/abranch")
646 self.client_commit("sc", "Promote mylib")
648 olddir = self.open_checkout_bzrdir("sc/branches/abranch")
652 newdir = olddir.sprout('dc')
655 olddir.open_branch().last_revision(),
656 newdir.open_branch().last_revision())
658 def test_fetch_branch_downgrade(self):
659 repos_url = self.make_client('d', 'sc')
661 self.build_tree({'sc/trunk': None, "sc/branches/abranch/bla": 'foo'})
662 self.client_add("sc/trunk")
663 self.client_add("sc/branches")
664 self.client_commit("sc", "foo")
666 self.client_copy("sc/branches/abranch", "sc/trunk/mylib")
667 self.client_commit("sc", "Demote mylib")
669 olddir = self.open_checkout_bzrdir("sc/trunk")
673 newdir = olddir.sprout('dc')
676 olddir.open_branch().last_revision(),
677 newdir.open_branch().last_revision())
681 def test_ghost_workingtree(self):
682 # Looks like bazaar has trouble creating a working tree of a
683 # revision that has ghost parents
684 self.make_client('d', 'sc')
686 self.build_tree({'sc/foo/bla': "data"})
687 self.client_add("sc/foo")
688 self.client_set_prop("sc", "bzr:ancestry:v3-none", "some-ghost\n")
689 self.client_commit("sc", "foo")
691 olddir = self.open_checkout_bzrdir("sc")
695 newdir = olddir.sprout('dc')
696 newdir.find_repository().get_revision(
697 newdir.open_branch().last_revision())
698 newdir.find_repository().get_revision_inventory(
699 newdir.open_branch().last_revision())
701 class TestFakeControlFiles(TestCase):
702 def test_get_utf8(self):
703 f = FakeControlFiles()
704 self.assertRaises(NoSuchFile, f.get_utf8, "foo")
708 f = FakeControlFiles()
709 self.assertRaises(NoSuchFile, f.get, "foobla")
711 class BranchFormatTests(TestCase):
713 self.format = SvnBranchFormat()
715 def test_initialize(self):
716 self.assertRaises(NotImplementedError, self.format.initialize, None)
718 def test_get_format_string(self):
719 self.assertEqual("Subversion Smart Server",
720 self.format.get_format_string())
722 def test_get_format_description(self):
723 self.assertEqual("Subversion Smart Server",
724 self.format.get_format_description())