/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/tests/test_merge_directive.py

  • Committer: Martin Pool
  • Date: 2007-05-04 08:46:39 UTC
  • mto: (2483.1.1 jam-integration)
  • mto: This revision was merged to the branch mainline in revision 2484.
  • Revision ID: mbp@sourcefrog.net-20070504084639-8v8mzetmr1y74xer
Rename push/pull back to 'run_hooks' (jameinel)

Reorganize Branch.push into some template methods: public push,
_push_with_bound_branches, and _basic_push.  This fixes the case 
where the destination of push is bound, but the source branch
format doesn't support binding.

Run push and pull hook tests with a local branch that does support binding,
rather than skipping if the branch can't be bound to another of the same
format.

(broken) because the hooks are given the wrong parameters when 
pushing into something bound to a remote branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
 
 
18
from bzrlib import (
 
19
    errors,
 
20
    gpg,
 
21
    merge_directive,
 
22
    tests,
 
23
    )
 
24
 
 
25
 
 
26
OUTPUT1 = """# Bazaar merge directive format 1
 
27
# revision_id: example:
 
28
# target_branch: http://example.com
 
29
# testament_sha1: sha
 
30
# timestamp: 1970-01-01 00:09:33 +0002
 
31
#\x20
 
32
booga"""
 
33
 
 
34
 
 
35
OUTPUT2 = """# Bazaar merge directive format 1
 
36
# revision_id: example:
 
37
# target_branch: http://example.com
 
38
# testament_sha1: sha
 
39
# timestamp: 1970-01-01 00:09:33 +0002
 
40
# source_branch: http://example.org
 
41
# message: Hi mom!
 
42
#\x20
 
43
booga"""
 
44
 
 
45
 
 
46
INPUT1 = """
 
47
I was thinking today about creating a merge directive.
 
48
 
 
49
So I did.
 
50
 
 
51
Here it is.
 
52
 
 
53
(I've pasted it in the body of this message)
 
54
 
 
55
Aaron
 
56
 
 
57
# Bazaar merge directive format 1\r
 
58
# revision_id: example:
 
59
# target_branch: http://example.com
 
60
# testament_sha1: sha
 
61
# timestamp: 1970-01-01 00:09:33 +0002
 
62
# source_branch: http://example.org
 
63
# message: Hi mom!
 
64
#\x20
 
65
booga""".splitlines(True)
 
66
 
 
67
 
 
68
class TestMergeDirective(tests.TestCase):
 
69
 
 
70
    def test_merge_source(self):
 
71
        time = 500000.0
 
72
        timezone = 5 * 3600
 
73
        self.assertRaises(errors.NoMergeSource, merge_directive.MergeDirective,
 
74
            'example:', 'sha', time, timezone, 'http://example.com')
 
75
        self.assertRaises(errors.NoMergeSource, merge_directive.MergeDirective,
 
76
            'example:', 'sha', time, timezone, 'http://example.com',
 
77
            patch_type='diff')
 
78
        merge_directive.MergeDirective('example:', 'sha', time, timezone,
 
79
            'http://example.com', source_branch='http://example.org')
 
80
        md = merge_directive.MergeDirective('null:', 'sha', time, timezone,
 
81
            'http://example.com', patch='blah', patch_type='bundle')
 
82
        self.assertIs(None, md.source_branch)
 
83
        md2 = merge_directive.MergeDirective('null:', 'sha', time, timezone,
 
84
            'http://example.com', patch='blah', patch_type='bundle',
 
85
            source_branch='bar')
 
86
        self.assertEqual('bar', md2.source_branch)
 
87
 
 
88
    def test_require_patch(self):
 
89
        time = 500.0
 
90
        timezone = 120
 
91
        self.assertRaises(errors.PatchMissing, merge_directive.MergeDirective,
 
92
            'example:', 'sha', time, timezone, 'http://example.com',
 
93
            patch_type='bundle')
 
94
        md = merge_directive.MergeDirective('example:', 'sha1', time, timezone,
 
95
            'http://example.com', source_branch="http://example.org",
 
96
            patch='', patch_type='diff')
 
97
        self.assertEqual(md.patch, '')
 
98
 
 
99
    def test_serialization(self):
 
100
        time = 453
 
101
        timezone = 120
 
102
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
 
103
            'http://example.com', patch='booga', patch_type='bundle')
 
104
        self.assertEqualDiff(OUTPUT1, ''.join(md.to_lines()))
 
105
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
 
106
            'http://example.com', source_branch="http://example.org",
 
107
            patch='booga', patch_type='diff', message="Hi mom!")
 
108
        self.assertEqualDiff(OUTPUT2, ''.join(md.to_lines()))
 
109
 
 
110
    def test_deserialize_junk(self):
 
111
        time = 501
 
112
        self.assertRaises(errors.NotAMergeDirective,
 
113
                          merge_directive.MergeDirective.from_lines, 'lala')
 
114
 
 
115
    def test_deserialize_empty(self):
 
116
        self.assertRaises(errors.NotAMergeDirective,
 
117
                          merge_directive.MergeDirective.from_lines, [])
 
118
 
 
119
    def test_deserialize_leading_junk(self):
 
120
        md = merge_directive.MergeDirective.from_lines(INPUT1)
 
121
        self.assertEqual('example:', md.revision_id)
 
122
        self.assertEqual('sha', md.testament_sha1)
 
123
        self.assertEqual('http://example.com', md.target_branch)
 
124
        self.assertEqual('http://example.org', md.source_branch)
 
125
        self.assertEqual(453, md.time)
 
126
        self.assertEqual(120, md.timezone)
 
127
        self.assertEqual('booga', md.patch)
 
128
        self.assertEqual('diff', md.patch_type)
 
129
        self.assertEqual('Hi mom!', md.message)
 
130
 
 
131
    def test_roundtrip(self):
 
132
        time = 500000
 
133
        timezone = 7.5 * 3600
 
134
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
 
135
            'http://example.com', source_branch="http://example.org",
 
136
            patch='booga', patch_type='diff')
 
137
        md2 = merge_directive.MergeDirective.from_lines(md.to_lines())
 
138
        self.assertEqual('example:', md2.revision_id)
 
139
        self.assertIsInstance(md2.revision_id, str)
 
140
        self.assertEqual('sha', md2.testament_sha1)
 
141
        self.assertEqual('http://example.com', md2.target_branch)
 
142
        self.assertEqual('http://example.org', md2.source_branch)
 
143
        self.assertEqual(time, md2.time)
 
144
        self.assertEqual(timezone, md2.timezone)
 
145
        self.assertEqual('diff', md2.patch_type)
 
146
        self.assertEqual('booga', md2.patch)
 
147
        self.assertEqual(None, md2.message)
 
148
        md.patch = "# Bazaar revision bundle v0.9\n#\n"
 
149
        md.message = "Hi mom!"
 
150
        md3 = merge_directive.MergeDirective.from_lines(md.to_lines())
 
151
        self.assertEqual("# Bazaar revision bundle v0.9\n#\n", md3.patch)
 
152
        self.assertEqual("bundle", md3.patch_type)
 
153
        self.assertContainsRe(md3.to_lines()[0],
 
154
            '^# Bazaar merge directive format ')
 
155
        self.assertEqual("Hi mom!", md3.message)
 
156
        md3.patch_type = None
 
157
        md3.patch = None
 
158
        md4 = merge_directive.MergeDirective.from_lines(md3.to_lines())
 
159
        self.assertIs(None, md4.patch_type)
 
160
 
 
161
 
 
162
EMAIL1 = """To: pqm@example.com
 
163
From: J. Random Hacker <jrandom@example.com>
 
164
Subject: Commit of rev2a
 
165
 
 
166
# Bazaar merge directive format 1
 
167
# revision_id: rev2a
 
168
# target_branch: (.|\n)*
 
169
# testament_sha1: .*
 
170
# timestamp: 1970-01-01 00:08:56 \\+0001
 
171
# source_branch: (.|\n)*
 
172
"""
 
173
 
 
174
 
 
175
EMAIL2 = """To: pqm@example.com
 
176
From: J. Random Hacker <jrandom@example.com>
 
177
Subject: Commit of rev2a with special message
 
178
 
 
179
# Bazaar merge directive format 1
 
180
# revision_id: rev2a
 
181
# target_branch: (.|\n)*
 
182
# testament_sha1: .*
 
183
# timestamp: 1970-01-01 00:08:56 \\+0001
 
184
# source_branch: (.|\n)*
 
185
# message: Commit of rev2a with special message
 
186
"""
 
187
 
 
188
 
 
189
class TestMergeDirectiveBranch(tests.TestCaseWithTransport):
 
190
 
 
191
    def make_trees(self):
 
192
        tree_a = self.make_branch_and_tree('tree_a')
 
193
        tree_a.branch.get_config().set_user_option('email',
 
194
            'J. Random Hacker <jrandom@example.com>')
 
195
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_b\n')])
 
196
        tree_a.add('file')
 
197
        tree_a.commit('message', rev_id='rev1')
 
198
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
 
199
        branch_c = tree_a.bzrdir.sprout('branch_c').open_branch()
 
200
        tree_b.commit('message', rev_id='rev2b')
 
201
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_c\n')])
 
202
        tree_a.commit('Commit of rev2a', rev_id='rev2a')
 
203
        return tree_a, tree_b, branch_c
 
204
 
 
205
    def test_generate_patch(self):
 
206
        tree_a, tree_b, branch_c = self.make_trees()
 
207
        md2 = merge_directive.MergeDirective.from_objects(
 
208
            tree_a.branch.repository, 'rev2a', 500, 120, tree_b.branch.base,
 
209
            patch_type='diff', public_branch=tree_a.branch.base)
 
210
        self.assertNotContainsRe(md2.patch, 'Bazaar revision bundle')
 
211
        self.assertContainsRe(md2.patch, '\\+content_c')
 
212
        self.assertNotContainsRe(md2.patch, '\\+\\+\\+ b/')
 
213
        self.assertContainsRe(md2.patch, '\\+\\+\\+ file')
 
214
 
 
215
    def test_public_branch(self):
 
216
        tree_a, tree_b, branch_c = self.make_trees()
 
217
        self.assertRaises(errors.PublicBranchOutOfDate,
 
218
            merge_directive.MergeDirective.from_objects,
 
219
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
 
220
            public_branch=branch_c.base, patch_type='diff')
 
221
        # public branch is not checked if patch format is bundle.
 
222
        md1 = merge_directive.MergeDirective.from_objects(
 
223
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
 
224
            public_branch=branch_c.base)
 
225
        # public branch is provided with a bundle, despite possibly being out
 
226
        # of date, because it's not required if a bundle is present.
 
227
        self.assertEqual(md1.source_branch, branch_c.base)
 
228
        # Once we update the public branch, we can generate a diff.
 
229
        branch_c.pull(tree_a.branch)
 
230
        md3 = merge_directive.MergeDirective.from_objects(
 
231
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
 
232
            patch_type=None, public_branch=branch_c.base)
 
233
 
 
234
    def test_use_public_submit_branch(self):
 
235
        tree_a, tree_b, branch_c = self.make_trees()
 
236
        branch_c.pull(tree_a.branch)
 
237
        md = merge_directive.MergeDirective.from_objects(
 
238
             tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
 
239
             patch_type=None, public_branch=branch_c.base)
 
240
        self.assertEqual(md.target_branch, tree_b.branch.base)
 
241
        tree_b.branch.set_public_branch('http://example.com')
 
242
        md2 = merge_directive.MergeDirective.from_objects(
 
243
              tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
 
244
              patch_type=None, public_branch=branch_c.base)
 
245
        self.assertEqual(md2.target_branch, 'http://example.com')
 
246
 
 
247
    def test_message(self):
 
248
        tree_a, tree_b, branch_c = self.make_trees()
 
249
        md3 = merge_directive.MergeDirective.from_objects(
 
250
            tree_a.branch.repository, 'rev2a', 500, 120, tree_b.branch.base,
 
251
            patch_type=None, public_branch=branch_c.base,
 
252
            message='Merge message')
 
253
        md3.to_lines()
 
254
        self.assertIs(None, md3.patch)
 
255
        self.assertEqual('Merge message', md3.message)
 
256
 
 
257
    def test_generate_bundle(self):
 
258
        tree_a, tree_b, branch_c = self.make_trees()
 
259
        md1 = merge_directive.MergeDirective.from_objects(
 
260
            tree_a.branch.repository, 'rev2a', 500, 120, tree_b.branch.base,
 
261
            public_branch=branch_c.base)
 
262
        self.assertContainsRe(md1.patch, 'Bazaar revision bundle')
 
263
        self.assertContainsRe(md1.patch, '\\+content_c')
 
264
        self.assertNotContainsRe(md1.patch, '\\+content_a')
 
265
        self.assertContainsRe(md1.patch, '\\+content_c')
 
266
        self.assertNotContainsRe(md1.patch, '\\+content_a')
 
267
 
 
268
    def test_signing(self):
 
269
        time = 453
 
270
        timezone = 7200
 
271
        class FakeBranch(object):
 
272
            def get_config(self):
 
273
                return self
 
274
            def gpg_signing_command(self):
 
275
                return 'loopback'
 
276
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
 
277
            'http://example.com', source_branch="http://example.org",
 
278
            patch='booga', patch_type='diff')
 
279
        old_strategy = gpg.GPGStrategy
 
280
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
 
281
        try:
 
282
            signed = md.to_signed(FakeBranch())
 
283
        finally:
 
284
            gpg.GPGStrategy = old_strategy
 
285
        self.assertContainsRe(signed, '^-----BEGIN PSEUDO-SIGNED CONTENT')
 
286
        self.assertContainsRe(signed, 'example.org')
 
287
        self.assertContainsRe(signed, 'booga')
 
288
 
 
289
    def test_email(self):
 
290
        tree_a, tree_b, branch_c = self.make_trees()
 
291
        md = merge_directive.MergeDirective.from_objects(
 
292
            tree_a.branch.repository, 'rev2a', 476, 60, tree_b.branch.base,
 
293
            patch_type=None, public_branch=tree_a.branch.base)
 
294
        message = md.to_email('pqm@example.com', tree_a.branch)
 
295
        self.assertContainsRe(message.as_string(), EMAIL1)
 
296
        md.message = 'Commit of rev2a with special message'
 
297
        message = md.to_email('pqm@example.com', tree_a.branch)
 
298
        self.assertContainsRe(message.as_string(), EMAIL2)
 
299
 
 
300
    def test_install_revisions_branch(self):
 
301
        tree_a, tree_b, branch_c = self.make_trees()
 
302
        md = merge_directive.MergeDirective.from_objects(
 
303
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
 
304
            patch_type=None, public_branch=tree_a.branch.base)
 
305
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
 
306
        revision = md.install_revisions(tree_b.branch.repository)
 
307
        self.assertEqual('rev2a', revision)
 
308
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
 
309
 
 
310
    def test_install_revisions_bundle(self):
 
311
        tree_a, tree_b, branch_c = self.make_trees()
 
312
        md = merge_directive.MergeDirective.from_objects(
 
313
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
 
314
            patch_type='bundle', public_branch=tree_a.branch.base)
 
315
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
 
316
        revision = md.install_revisions(tree_b.branch.repository)
 
317
        self.assertEqual('rev2a', revision)
 
318
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
 
319
 
 
320
    def test_get_target_revision_nofetch(self):
 
321
        tree_a, tree_b, branch_c = self.make_trees()
 
322
        tree_b.branch.fetch(tree_a.branch)
 
323
        md = merge_directive.MergeDirective.from_objects(
 
324
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
 
325
            patch_type=None, public_branch=tree_a.branch.base)
 
326
        md.source_branch = '/dev/null'
 
327
        revision = md.install_revisions(tree_b.branch.repository)
 
328
        self.assertEqual('rev2a', revision)