/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2338.4.2 by Marien Zwart
Move the workingtree-related inventory tests to a separate file.
1
# Copyright (C) 2007 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
"""Tests for interface conformance of XXX TOADD"""
18
19
20
from cStringIO import StringIO
21
import os
22
import time
23
24
from bzrlib import (
25
    errors,
26
    inventory,
27
    )
28
from bzrlib.diff import internal_diff
29
from bzrlib.osutils import (
30
    has_symlinks,
31
    )
32
from bzrlib.tests import TestCaseWithTransport
33
from bzrlib.uncommit import uncommit
34
35
36
class TestEntryDiffing(TestCaseWithTransport):
37
38
    def setUp(self):
39
        super(TestEntryDiffing, self).setUp()
40
        self.wt = self.make_branch_and_tree('.')
41
        self.branch = self.wt.branch
42
        print >> open('file', 'wb'), 'foo'
43
        print >> open('binfile', 'wb'), 'foo'
44
        self.wt.add(['file'], ['fileid'])
45
        self.wt.add(['binfile'], ['binfileid'])
46
        if has_symlinks():
47
            os.symlink('target1', 'symlink')
48
            self.wt.add(['symlink'], ['linkid'])
49
        self.wt.commit('message_1', rev_id = '1')
50
        print >> open('file', 'wb'), 'bar'
51
        print >> open('binfile', 'wb'), 'x' * 1023 + '\x00'
52
        if has_symlinks():
53
            os.unlink('symlink')
54
            os.symlink('target2', 'symlink')
55
        self.tree_1 = self.branch.repository.revision_tree('1')
56
        self.inv_1 = self.branch.repository.get_inventory('1')
57
        self.file_1 = self.inv_1['fileid']
58
        self.file_1b = self.inv_1['binfileid']
59
        self.tree_2 = self.wt
60
        self.tree_2.lock_read()
61
        self.addCleanup(self.tree_2.unlock)
62
        self.inv_2 = self.tree_2.read_working_inventory()
63
        self.file_2 = self.inv_2['fileid']
64
        self.file_2b = self.inv_2['binfileid']
65
        if has_symlinks():
66
            self.link_1 = self.inv_1['linkid']
67
            self.link_2 = self.inv_2['linkid']
68
69
    def test_file_diff_deleted(self):
70
        output = StringIO()
71
        self.file_1.diff(internal_diff, 
72
                          "old_label", self.tree_1,
73
                          "/dev/null", None, None,
74
                          output)
75
        self.assertEqual(output.getvalue(), "--- old_label\n"
76
                                            "+++ /dev/null\n"
77
                                            "@@ -1,1 +0,0 @@\n"
78
                                            "-foo\n"
79
                                            "\n")
80
81
    def test_file_diff_added(self):
82
        output = StringIO()
83
        self.file_1.diff(internal_diff, 
84
                          "new_label", self.tree_1,
85
                          "/dev/null", None, None,
86
                          output, reverse=True)
87
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
88
                                            "+++ new_label\n"
89
                                            "@@ -0,0 +1,1 @@\n"
90
                                            "+foo\n"
91
                                            "\n")
92
93
    def test_file_diff_changed(self):
94
        output = StringIO()
95
        self.file_1.diff(internal_diff, 
96
                          "/dev/null", self.tree_1, 
97
                          "new_label", self.file_2, self.tree_2,
98
                          output)
99
        self.assertEqual(output.getvalue(), "--- /dev/null\n"
100
                                            "+++ new_label\n"
101
                                            "@@ -1,1 +1,1 @@\n"
102
                                            "-foo\n"
103
                                            "+bar\n"
104
                                            "\n")
105
        
106
    def test_file_diff_binary(self):
107
        output = StringIO()
108
        self.file_1.diff(internal_diff, 
109
                          "/dev/null", self.tree_1, 
110
                          "new_label", self.file_2b, self.tree_2,
111
                          output)
112
        self.assertEqual(output.getvalue(), 
113
                         "Binary files /dev/null and new_label differ\n")
114
    def test_link_diff_deleted(self):
115
        if not has_symlinks():
116
            return
117
        output = StringIO()
118
        self.link_1.diff(internal_diff, 
119
                          "old_label", self.tree_1,
120
                          "/dev/null", None, None,
121
                          output)
122
        self.assertEqual(output.getvalue(),
123
                         "=== target was 'target1'\n")
124
125
    def test_link_diff_added(self):
126
        if not has_symlinks():
127
            return
128
        output = StringIO()
129
        self.link_1.diff(internal_diff, 
130
                          "new_label", self.tree_1,
131
                          "/dev/null", None, None,
132
                          output, reverse=True)
133
        self.assertEqual(output.getvalue(),
134
                         "=== target is 'target1'\n")
135
136
    def test_link_diff_changed(self):
137
        if not has_symlinks():
138
            return
139
        output = StringIO()
140
        self.link_1.diff(internal_diff, 
141
                          "/dev/null", self.tree_1, 
142
                          "new_label", self.link_2, self.tree_2,
143
                          output)
144
        self.assertEqual(output.getvalue(),
145
                         "=== target changed 'target1' => 'target2'\n")
146
147
148
class TestRevert(TestCaseWithTransport):
149
150
    def test_dangling_id(self):
151
        wt = self.make_branch_and_tree('b1')
152
        wt.lock_tree_write()
153
        self.addCleanup(wt.unlock)
154
        self.assertEqual(len(wt.inventory), 1)
155
        open('b1/a', 'wb').write('a test\n')
156
        wt.add('a')
157
        self.assertEqual(len(wt.inventory), 2)
158
        wt.flush() # workaround revert doing wt._write_inventory for now.
159
        os.unlink('b1/a')
160
        wt.revert([])
161
        self.assertEqual(len(wt.inventory), 1)
162
163
164
class TestPreviousHeads(TestCaseWithTransport):
165
166
    def setUp(self):
167
        # we want several inventories, that respectively
168
        # give use the following scenarios:
169
        # A) fileid not in any inventory (A),
170
        # B) fileid present in one inventory (B) and (A,B)
171
        # C) fileid present in two inventories, and they
172
        #   are not mutual descendents (B, C)
173
        # D) fileid present in two inventories and one is
174
        #   a descendent of the other. (B, D)
175
        super(TestPreviousHeads, self).setUp()
176
        self.wt = self.make_branch_and_tree('.')
177
        self.branch = self.wt.branch
178
        self.build_tree(['file'])
179
        self.wt.commit('new branch', allow_pointless=True, rev_id='A')
180
        self.inv_A = self.branch.repository.get_inventory('A')
181
        self.wt.add(['file'], ['fileid'])
182
        self.wt.commit('add file', rev_id='B')
183
        self.inv_B = self.branch.repository.get_inventory('B')
184
        uncommit(self.branch, tree=self.wt)
185
        self.assertEqual(self.branch.revision_history(), ['A'])
186
        self.wt.commit('another add of file', rev_id='C')
187
        self.inv_C = self.branch.repository.get_inventory('C')
188
        self.wt.add_parent_tree_id('B')
189
        self.wt.commit('merge in B', rev_id='D')
190
        self.inv_D = self.branch.repository.get_inventory('D')
191
        self.wt.lock_read()
192
        self.addCleanup(self.wt.unlock)
193
        self.file_active = self.wt.inventory['fileid']
194
        self.weave = self.branch.repository.weave_store.get_weave('fileid',
195
            self.branch.repository.get_transaction())
196
        
197
    def get_previous_heads(self, inventories):
198
        return self.file_active.find_previous_heads(
199
            inventories, 
200
            self.branch.repository.weave_store,
201
            self.branch.repository.get_transaction())
202
        
203
    def test_fileid_in_no_inventory(self):
204
        self.assertEqual({}, self.get_previous_heads([self.inv_A]))
205
206
    def test_fileid_in_one_inventory(self):
207
        self.assertEqual({'B':self.inv_B['fileid']},
208
                         self.get_previous_heads([self.inv_B]))
209
        self.assertEqual({'B':self.inv_B['fileid']},
210
                         self.get_previous_heads([self.inv_A, self.inv_B]))
211
        self.assertEqual({'B':self.inv_B['fileid']},
212
                         self.get_previous_heads([self.inv_B, self.inv_A]))
213
214
    def test_fileid_in_two_inventories_gives_both_entries(self):
215
        self.assertEqual({'B':self.inv_B['fileid'],
216
                          'C':self.inv_C['fileid']},
217
                          self.get_previous_heads([self.inv_B, self.inv_C]))
218
        self.assertEqual({'B':self.inv_B['fileid'],
219
                          'C':self.inv_C['fileid']},
220
                          self.get_previous_heads([self.inv_C, self.inv_B]))
221
222
    def test_fileid_in_two_inventories_already_merged_gives_head(self):
223
        self.assertEqual({'D':self.inv_D['fileid']},
224
                         self.get_previous_heads([self.inv_B, self.inv_D]))
225
        self.assertEqual({'D':self.inv_D['fileid']},
226
                         self.get_previous_heads([self.inv_D, self.inv_B]))
227
228
    # TODO: test two inventories with the same file revision 
229
230
231
class TestSnapshot(TestCaseWithTransport):
232
233
    def setUp(self):
234
        # for full testing we'll need a branch
235
        # with a subdir to test parent changes.
236
        # and a file, link and dir under that.
237
        # but right now I only need one attribute
238
        # to change, and then test merge patterns
239
        # with fake parent entries.
240
        super(TestSnapshot, self).setUp()
241
        self.wt = self.make_branch_and_tree('.')
242
        self.branch = self.wt.branch
243
        self.build_tree(['subdir/', 'subdir/file'], line_endings='binary')
244
        self.wt.add(['subdir', 'subdir/file'],
245
                                       ['dirid', 'fileid'])
246
        if has_symlinks():
247
            pass
248
        self.wt.commit('message_1', rev_id = '1')
249
        self.tree_1 = self.branch.repository.revision_tree('1')
250
        self.inv_1 = self.branch.repository.get_inventory('1')
251
        self.file_1 = self.inv_1['fileid']
252
        self.wt.lock_write()
253
        self.addCleanup(self.wt.unlock)
254
        self.file_active = self.wt.inventory['fileid']
255
        self.builder = self.branch.get_commit_builder([], timestamp=time.time(), revision_id='2')
256
257
    def test_snapshot_new_revision(self):
258
        # This tests that a simple commit with no parents makes a new
259
        # revision value in the inventory entry
260
        self.file_active.snapshot('2', 'subdir/file', {}, self.wt, self.builder)
261
        # expected outcome - file_1 has a revision id of '2', and we can get
262
        # its text of 'file contents' out of the weave.
263
        self.assertEqual(self.file_1.revision, '1')
264
        self.assertEqual(self.file_active.revision, '2')
265
        # this should be a separate test probably, but lets check it once..
266
        lines = self.branch.repository.weave_store.get_weave(
267
            'fileid', 
268
            self.branch.get_transaction()).get_lines('2')
269
        self.assertEqual(lines, ['contents of subdir/file\n'])
270
271
    def test_snapshot_unchanged(self):
272
        #This tests that a simple commit does not make a new entry for
273
        # an unchanged inventory entry
274
        self.file_active.snapshot('2', 'subdir/file', {'1':self.file_1},
275
                                  self.wt, self.builder)
276
        self.assertEqual(self.file_1.revision, '1')
277
        self.assertEqual(self.file_active.revision, '1')
278
        vf = self.branch.repository.weave_store.get_weave(
279
            'fileid', 
280
            self.branch.repository.get_transaction())
281
        self.assertRaises(errors.RevisionNotPresent,
282
                          vf.get_lines,
283
                          '2')
284
285
    def test_snapshot_merge_identical_different_revid(self):
286
        # This tests that a commit with two identical parents, one of which has
287
        # a different revision id, results in a new revision id in the entry.
288
        # 1->other, commit a merge of other against 1, results in 2.
289
        other_ie = inventory.InventoryFile('fileid', 'newname', self.file_1.parent_id)
290
        other_ie = inventory.InventoryFile('fileid', 'file', self.file_1.parent_id)
291
        other_ie.revision = '1'
292
        other_ie.text_sha1 = self.file_1.text_sha1
293
        other_ie.text_size = self.file_1.text_size
294
        self.assertEqual(self.file_1, other_ie)
295
        other_ie.revision = 'other'
296
        self.assertNotEqual(self.file_1, other_ie)
297
        versionfile = self.branch.repository.weave_store.get_weave(
298
            'fileid', self.branch.repository.get_transaction())
299
        versionfile.clone_text('other', '1', ['1'])
300
        self.file_active.snapshot('2', 'subdir/file', 
301
                                  {'1':self.file_1, 'other':other_ie},
302
                                  self.wt, self.builder)
303
        self.assertEqual(self.file_active.revision, '2')
304
305
    def test_snapshot_changed(self):
306
        # This tests that a commit with one different parent results in a new
307
        # revision id in the entry.
308
        self.wt.rename_one('subdir/file', 'subdir/newname')
309
        self.file_active = self.wt.inventory['fileid']
310
        self.file_active.snapshot('2', 'subdir/newname', {'1':self.file_1}, 
311
                                  self.wt, self.builder)
312
        # expected outcome - file_1 has a revision id of '2'
313
        self.assertEqual(self.file_active.revision, '2')