~bzr-pqm/bzr/bzr.dev

1246 by Martin Pool
- add very simple commit tests
1
# Copyright (C) 2005 by Canonical Ltd
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
18
import os
19
20
from bzrlib.selftest import TestCaseInTempDir
21
from bzrlib.branch import Branch
22
from bzrlib.commit import Commit
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
23
from bzrlib.config import BranchConfig
1292 by Martin Pool
- add check that revision ids cannot be committed twice
24
from bzrlib.errors import PointlessCommit, BzrError
1246 by Martin Pool
- add very simple commit tests
25
26
1257 by Martin Pool
doc
27
# TODO: Test commit with some added, and added-but-missing files
28
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
29
class MustSignConfig(BranchConfig):
30
31
    def signature_needed(self):
32
        return True
33
34
    def gpg_signing_command(self):
35
        return ['cat', '-']
36
37
1246 by Martin Pool
- add very simple commit tests
38
class TestCommit(TestCaseInTempDir):
1390 by Robert Collins
pair programming worx... merge integration and weave
39
1246 by Martin Pool
- add very simple commit tests
40
    def test_simple_commit(self):
41
        """Commit and check two versions of a single file."""
1390 by Robert Collins
pair programming worx... merge integration and weave
42
        b = Branch.initialize('.')
1246 by Martin Pool
- add very simple commit tests
43
        file('hello', 'w').write('hello world')
44
        b.add('hello')
45
        b.commit(message='add hello')
46
        file_id = b.working_tree().path2id('hello')
47
48
        file('hello', 'w').write('version 2')
49
        b.commit(message='commit 2')
50
51
        eq = self.assertEquals
52
        eq(b.revno(), 2)
53
        rh = b.revision_history()
54
        rev = b.get_revision(rh[0])
55
        eq(rev.message, 'add hello')
56
57
        tree1 = b.revision_tree(rh[0])
58
        text = tree1.get_file_text(file_id)
59
        eq(text, 'hello world')
60
61
        tree2 = b.revision_tree(rh[1])
62
        eq(tree2.get_file_text(file_id), 'version 2')
63
64
    def test_delete_commit(self):
65
        """Test a commit with a deleted file"""
1390 by Robert Collins
pair programming worx... merge integration and weave
66
        b = Branch.initialize('.')
1247 by Martin Pool
- tests for deletion and removal of files in commits
67
        file('hello', 'w').write('hello world')
68
        b.add(['hello'], ['hello-id'])
69
        b.commit(message='add hello')
70
71
        os.remove('hello')
72
        b.commit('removed hello', rev_id='rev2')
73
74
        tree = b.revision_tree('rev2')
75
        self.assertFalse(tree.has_id('hello-id'))
76
1246 by Martin Pool
- add very simple commit tests
77
1253 by Martin Pool
- test that pointless commits are trapped
78
    def test_pointless_commit(self):
79
        """Commit refuses unless there are changes or it's forced."""
1390 by Robert Collins
pair programming worx... merge integration and weave
80
        b = Branch.initialize('.')
1253 by Martin Pool
- test that pointless commits are trapped
81
        file('hello', 'w').write('hello')
82
        b.add(['hello'])
83
        b.commit(message='add hello')
84
        self.assertEquals(b.revno(), 1)
85
        self.assertRaises(PointlessCommit,
86
                          b.commit,
87
                          message='fails',
88
                          allow_pointless=False)
89
        self.assertEquals(b.revno(), 1)
90
        
91
92
1252 by Martin Pool
- add test for commit of an empty tree
93
    def test_commit_empty(self):
1253 by Martin Pool
- test that pointless commits are trapped
94
        """Commiting an empty tree works."""
1390 by Robert Collins
pair programming worx... merge integration and weave
95
        b = Branch.initialize('.')
1252 by Martin Pool
- add test for commit of an empty tree
96
        b.commit(message='empty tree', allow_pointless=True)
1253 by Martin Pool
- test that pointless commits are trapped
97
        self.assertRaises(PointlessCommit,
98
                          b.commit,
99
                          message='empty tree',
100
                          allow_pointless=False)
1252 by Martin Pool
- add test for commit of an empty tree
101
        b.commit(message='empty tree', allow_pointless=True)
102
        self.assertEquals(b.revno(), 2)
103
104
105
    def test_selective_delete(self):
106
        """Selective commit in tree with deletions"""
1390 by Robert Collins
pair programming worx... merge integration and weave
107
        b = Branch.initialize('.')
1254 by Martin Pool
- fix handling of selective commit with deleted files
108
        file('hello', 'w').write('hello')
109
        file('buongia', 'w').write('buongia')
1255 by Martin Pool
- more tests for selective commit of deletion
110
        b.add(['hello', 'buongia'],
111
              ['hello-id', 'buongia-id'])
112
        b.commit(message='add files',
113
                 rev_id='test@rev-1')
1254 by Martin Pool
- fix handling of selective commit with deleted files
114
        
115
        os.remove('hello')
116
        file('buongia', 'w').write('new text')
117
        b.commit(message='update text',
118
                 specific_files=['buongia'],
1255 by Martin Pool
- more tests for selective commit of deletion
119
                 allow_pointless=False,
120
                 rev_id='test@rev-2')
1254 by Martin Pool
- fix handling of selective commit with deleted files
121
122
        b.commit(message='remove hello',
123
                 specific_files=['hello'],
1255 by Martin Pool
- more tests for selective commit of deletion
124
                 allow_pointless=False,
125
                 rev_id='test@rev-3')
1254 by Martin Pool
- fix handling of selective commit with deleted files
126
127
        eq = self.assertEquals
128
        eq(b.revno(), 3)
1255 by Martin Pool
- more tests for selective commit of deletion
129
130
        tree2 = b.revision_tree('test@rev-2')
131
        self.assertTrue(tree2.has_filename('hello'))
132
        self.assertEquals(tree2.get_file_text('hello-id'), 'hello')
133
        self.assertEquals(tree2.get_file_text('buongia-id'), 'new text')
134
        
135
        tree3 = b.revision_tree('test@rev-3')
136
        self.assertFalse(tree3.has_filename('hello'))
137
        self.assertEquals(tree3.get_file_text('buongia-id'), 'new text')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
138
139
140
    def test_commit_rename(self):
141
        """Test commit of a revision where a file is renamed."""
1390 by Robert Collins
pair programming worx... merge integration and weave
142
        b = Branch.initialize('.')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
143
        self.build_tree(['hello'])
144
        b.add(['hello'], ['hello-id'])
145
        b.commit(message='one', rev_id='test@rev-1', allow_pointless=False)
146
147
        b.rename_one('hello', 'fruity')
148
        b.commit(message='renamed', rev_id='test@rev-2', allow_pointless=False)
149
1303 by Martin Pool
- commit updates entry_version
150
        eq = self.assertEquals
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
151
        tree1 = b.revision_tree('test@rev-1')
1303 by Martin Pool
- commit updates entry_version
152
        eq(tree1.id2path('hello-id'), 'hello')
153
        eq(tree1.get_file_text('hello-id'), 'contents of hello\n')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
154
        self.assertFalse(tree1.has_filename('fruity'))
1291 by Martin Pool
- add test for moving files between directories
155
        self.check_inventory_shape(tree1.inventory, ['hello'])
1303 by Martin Pool
- commit updates entry_version
156
        ie = tree1.inventory['hello-id']
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
157
        eq(ie.revision, 'test@rev-1')
1285 by Martin Pool
- fix bug in committing files that are renamed but not modified
158
159
        tree2 = b.revision_tree('test@rev-2')
1303 by Martin Pool
- commit updates entry_version
160
        eq(tree2.id2path('hello-id'), 'fruity')
161
        eq(tree2.get_file_text('hello-id'), 'contents of hello\n')
1291 by Martin Pool
- add test for moving files between directories
162
        self.check_inventory_shape(tree2.inventory, ['fruity'])
1303 by Martin Pool
- commit updates entry_version
163
        ie = tree2.inventory['hello-id']
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
164
        eq(ie.revision, 'test@rev-2')
1291 by Martin Pool
- add test for moving files between directories
165
166
167
    def test_reused_rev_id(self):
1292 by Martin Pool
- add check that revision ids cannot be committed twice
168
        """Test that a revision id cannot be reused in a branch"""
1390 by Robert Collins
pair programming worx... merge integration and weave
169
        b = Branch.initialize('.')
1292 by Martin Pool
- add check that revision ids cannot be committed twice
170
        b.commit('initial', rev_id='test@rev-1', allow_pointless=True)
171
        self.assertRaises(Exception,
172
                          b.commit,
173
                          message='reused id',
174
                          rev_id='test@rev-1',
175
                          allow_pointless=True)
176
                          
1291 by Martin Pool
- add test for moving files between directories
177
178
179
    def test_commit_move(self):
180
        """Test commit of revisions with moved files and directories"""
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
181
        eq = self.assertEquals
1390 by Robert Collins
pair programming worx... merge integration and weave
182
        b = Branch.initialize('.')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
183
        r1 = 'test@rev-1'
1291 by Martin Pool
- add test for moving files between directories
184
        self.build_tree(['hello', 'a/', 'b/'])
185
        b.add(['hello', 'a', 'b'], ['hello-id', 'a-id', 'b-id'])
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
186
        b.commit('initial', rev_id=r1, allow_pointless=False)
1291 by Martin Pool
- add test for moving files between directories
187
188
        b.move(['hello'], 'a')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
189
        r2 = 'test@rev-2'
190
        b.commit('two', rev_id=r2, allow_pointless=False)
1291 by Martin Pool
- add test for moving files between directories
191
        self.check_inventory_shape(b.inventory,
192
                                   ['a', 'a/hello', 'b'])
193
194
        b.move(['b'], 'a')
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
195
        r3 = 'test@rev-3'
196
        b.commit('three', rev_id=r3, allow_pointless=False)
1291 by Martin Pool
- add test for moving files between directories
197
        self.check_inventory_shape(b.inventory,
198
                                   ['a', 'a/hello', 'a/b'])
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
199
        self.check_inventory_shape(b.get_revision_inventory(r3),
1291 by Martin Pool
- add test for moving files between directories
200
                                   ['a', 'a/hello', 'a/b'])
201
202
        b.move([os.sep.join(['a', 'hello'])],
203
               os.sep.join(['a', 'b']))
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
204
        r4 = 'test@rev-4'
205
        b.commit('four', rev_id=r4, allow_pointless=False)
1291 by Martin Pool
- add test for moving files between directories
206
        self.check_inventory_shape(b.inventory,
207
                                   ['a', 'a/b/hello', 'a/b'])
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
208
209
        inv = b.get_revision_inventory(r4)
1092.2.21 by Robert Collins
convert name_version to revision in inventory entries
210
        eq(inv['hello-id'].revision, r4)
211
        eq(inv['a-id'].revision, r1)
212
        eq(inv['b-id'].revision, r3)
1306 by Martin Pool
- tests that name_version is updated properly in renames/moves
213
214
        
1246 by Martin Pool
- add very simple commit tests
215
    def test_removed_commit(self):
216
        """Test a commit with a removed file"""
1390 by Robert Collins
pair programming worx... merge integration and weave
217
        b = Branch.initialize('.')
1247 by Martin Pool
- tests for deletion and removal of files in commits
218
        file('hello', 'w').write('hello world')
219
        b.add(['hello'], ['hello-id'])
220
        b.commit(message='add hello')
221
222
        b.remove('hello')
223
        b.commit('removed hello', rev_id='rev2')
224
225
        tree = b.revision_tree('rev2')
226
        self.assertFalse(tree.has_id('hello-id'))
1246 by Martin Pool
- add very simple commit tests
227
228
1256 by Martin Pool
- test that commits append to the tree's ancestry
229
    def test_committed_ancestry(self):
230
        """Test commit appends revisions to ancestry."""
1390 by Robert Collins
pair programming worx... merge integration and weave
231
        b = Branch.initialize('.')
1256 by Martin Pool
- test that commits append to the tree's ancestry
232
        rev_ids = []
233
        for i in range(4):
234
            file('hello', 'w').write((str(i) * 4) + '\n')
235
            if i == 0:
236
                b.add(['hello'], ['hello-id'])
237
            rev_id = 'test@rev-%d' % (i+1)
238
            rev_ids.append(rev_id)
239
            b.commit(message='rev %d' % (i+1),
240
                     rev_id=rev_id)
241
        eq = self.assertEquals
242
        eq(b.revision_history(), rev_ids)
243
        for i in range(4):
244
            anc = b.get_ancestry(rev_ids[i])
1390 by Robert Collins
pair programming worx... merge integration and weave
245
            eq(anc, [None] + rev_ids[:i+1])
1416 by Robert Collins
when committing a specific file, include all its parents
246
247
    def test_commit_new_subdir_child_selective(self):
248
        b = Branch.initialize('.')
249
        self.build_tree(['dir/', 'dir/file1', 'dir/file2'])
250
        b.add(['dir', 'dir/file1', 'dir/file2'],
251
              ['dirid', 'file1id', 'file2id'])
252
        b.commit('dir/file1', specific_files=['dir/file1'], rev_id='1')
253
        inv = b.get_inventory('1')
254
        self.assertEqual('1', inv['dirid'].revision)
255
        self.assertEqual('1', inv['file1id'].revision)
256
        # FIXME: This should raise a KeyError I think, rbc20051006
257
        self.assertRaises(BzrError, inv.__getitem__, 'file2id')
1442.1.60 by Robert Collins
gpg sign commits if the policy says we need to
258
259
    def test_signed_commit(self):
260
        import bzrlib.gpg
261
        import bzrlib.commit as commit
262
        oldstrategy = bzrlib.gpg.GPGStrategy
263
        branch = Branch.initialize('.')
264
        branch.commit("base", allow_pointless=True, rev_id='A')
265
        self.failIf(branch.revision_store.has_id('A', 'sig'))
266
        try:
267
            from bzrlib.testament import Testament
268
            # monkey patch gpg signing mechanism
269
            bzrlib.gpg.GPGStrategy = bzrlib.gpg.LoopbackGPGStrategy
270
            commit.Commit(config=MustSignConfig(branch)).commit(branch, "base",
271
                                                      allow_pointless=True,
272
                                                      rev_id='B')
273
            self.assertEqual(Testament.from_revision(branch,'B').as_short_text(),
274
                             branch.revision_store.get('B', 'sig').read())
275
        finally:
276
            bzrlib.gpg.GPGStrategy = oldstrategy