/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
1551.12.36 by Aaron Bentley
Fix failing tests
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
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
18
from bzrlib import (
19
    errors,
1551.12.16 by Aaron Bentley
Enable signing merge directives
20
    gpg,
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
21
    merge_directive,
22
    tests,
23
    )
24
1551.12.4 by Aaron Bentley
Add failing test
25
1551.12.45 by Aaron Bentley
Change format marker to not experimental
26
OUTPUT1 = """# Bazaar merge directive format 1
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
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
2687.2.2 by Martin Pool
Fix up other references to 0.19
34
OUTPUT1_2 = """# Bazaar merge directive format 2 (Bazaar 0.90)
2520.4.73 by Aaron Bentley
Implement new merge directive format
35
# revision_id: example:
36
# target_branch: http://example.com
37
# testament_sha1: sha
38
# timestamp: 1970-01-01 00:09:33 +0002
2520.4.105 by Aaron Bentley
Implement patch verification
39
# base_revision_id: null:
2520.4.73 by Aaron Bentley
Implement new merge directive format
40
#\x20
41
# Begin bundle
42
booga"""
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
43
1551.12.45 by Aaron Bentley
Change format marker to not experimental
44
OUTPUT2 = """# Bazaar merge directive format 1
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
45
# revision_id: example:
46
# target_branch: http://example.com
47
# testament_sha1: sha
48
# timestamp: 1970-01-01 00:09:33 +0002
49
# source_branch: http://example.org
50
# message: Hi mom!
51
#\x20
52
booga"""
53
2687.2.2 by Martin Pool
Fix up other references to 0.19
54
OUTPUT2_2 = """# Bazaar merge directive format 2 (Bazaar 0.90)
2520.4.73 by Aaron Bentley
Implement new merge directive format
55
# revision_id: example:
56
# target_branch: http://example.com
57
# testament_sha1: sha
58
# timestamp: 1970-01-01 00:09:33 +0002
59
# source_branch: http://example.org
60
# message: Hi mom!
2520.4.105 by Aaron Bentley
Implement patch verification
61
# base_revision_id: null:
2520.4.73 by Aaron Bentley
Implement new merge directive format
62
#\x20
63
# Begin patch
64
booga"""
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
65
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
66
INPUT1 = """
67
I was thinking today about creating a merge directive.
68
69
So I did.
70
71
Here it is.
72
73
(I've pasted it in the body of this message)
74
75
Aaron
76
77
# Bazaar merge directive format 1\r
78
# revision_id: example:
79
# target_branch: http://example.com
80
# testament_sha1: sha
81
# timestamp: 1970-01-01 00:09:33 +0002
82
# source_branch: http://example.org
83
# message: Hi mom!
84
#\x20
85
booga""".splitlines(True)
86
87
2520.4.73 by Aaron Bentley
Implement new merge directive format
88
INPUT1_2 = """
89
I was thinking today about creating a merge directive.
90
91
So I did.
92
93
Here it is.
94
95
(I've pasted it in the body of this message)
96
97
Aaron
98
2687.2.2 by Martin Pool
Fix up other references to 0.19
99
# Bazaar merge directive format 2 (Bazaar 0.90)\r
2520.4.73 by Aaron Bentley
Implement new merge directive format
100
# revision_id: example:
101
# target_branch: http://example.com
102
# testament_sha1: sha
103
# timestamp: 1970-01-01 00:09:33 +0002
104
# source_branch: http://example.org
2520.4.105 by Aaron Bentley
Implement patch verification
105
# base_revision_id: null:
2520.4.73 by Aaron Bentley
Implement new merge directive format
106
# message: Hi mom!
107
#\x20
108
# Begin patch
109
booga""".splitlines(True)
110
111
2694.1.1 by Aaron Bentley
Restore support for Merge directive 2 / 0.19
112
INPUT1_2_OLD = """
113
I was thinking today about creating a merge directive.
114
115
So I did.
116
117
Here it is.
118
119
(I've pasted it in the body of this message)
120
121
Aaron
122
123
# Bazaar merge directive format 2 (Bazaar 0.19)\r
124
# revision_id: example:
125
# target_branch: http://example.com
126
# testament_sha1: sha
127
# timestamp: 1970-01-01 00:09:33 +0002
128
# source_branch: http://example.org
129
# base_revision_id: null:
130
# message: Hi mom!
131
#\x20
132
# Begin patch
133
booga""".splitlines(True)
134
2694.1.2 by Aaron Bentley
Fix whitespace
135
2694.1.1 by Aaron Bentley
Restore support for Merge directive 2 / 0.19
136
OLD_DIRECTIVE_2 = """# Bazaar merge directive format 2 (Bazaar 0.19)
137
# revision_id: abentley@panoramicfeedback.com-20070807234458-\
138
#   nzhkoyza56lan7z5
139
# target_branch: http://panoramicfeedback.com/opensource/bzr/repo\
140
#   /bzr.ab
141
# testament_sha1: d825a5cdb267a90ec2ba86b00895f3d8a9bed6bf
142
# timestamp: 2007-08-10 16:15:02 -0400
143
# source_branch: http://panoramicfeedback.com/opensource/bzr/repo\
144
#   /bzr.ab
145
# base_revision_id: abentley@panoramicfeedback.com-20070731163346-\
146
#   623xwcycwij91xen
147
#
148
""".splitlines(True)
149
150
2520.4.73 by Aaron Bentley
Implement new merge directive format
151
class TestMergeDirective(object):
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
152
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
153
    def test_merge_source(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
154
        time = 500000.0
155
        timezone = 5 * 3600
2520.4.73 by Aaron Bentley
Implement new merge directive format
156
        self.assertRaises(errors.NoMergeSource, self.make_merge_directive,
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
157
            'example:', 'sha', time, timezone, 'http://example.com')
2520.4.73 by Aaron Bentley
Implement new merge directive format
158
        self.assertRaises(errors.NoMergeSource, self.make_merge_directive,
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
159
            'example:', 'sha', time, timezone, 'http://example.com',
160
            patch_type='diff')
2520.4.73 by Aaron Bentley
Implement new merge directive format
161
        self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
162
            'http://example.com', source_branch='http://example.org')
2520.4.73 by Aaron Bentley
Implement new merge directive format
163
        md = self.make_merge_directive('null:', 'sha', time, timezone,
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
164
            'http://example.com', patch='blah', patch_type='bundle')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
165
        self.assertIs(None, md.source_branch)
2520.4.73 by Aaron Bentley
Implement new merge directive format
166
        md2 = self.make_merge_directive('null:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
167
            'http://example.com', patch='blah', patch_type='bundle',
168
            source_branch='bar')
169
        self.assertEqual('bar', md2.source_branch)
170
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
171
    def test_serialization(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
172
        time = 453
173
        timezone = 120
2520.4.73 by Aaron Bentley
Implement new merge directive format
174
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
175
            'http://example.com', patch='booga', patch_type='bundle')
2520.4.73 by Aaron Bentley
Implement new merge directive format
176
        self.assertEqualDiff(self.OUTPUT1, ''.join(md.to_lines()))
177
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
178
            'http://example.com', source_branch="http://example.org",
179
            patch='booga', patch_type='diff', message="Hi mom!")
2520.4.73 by Aaron Bentley
Implement new merge directive format
180
        self.assertEqualDiff(self.OUTPUT2, ''.join(md.to_lines()))
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
181
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
182
    def test_deserialize_junk(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
183
        time = 501
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
184
        self.assertRaises(errors.NotAMergeDirective,
185
                          merge_directive.MergeDirective.from_lines, 'lala')
186
1551.12.59 by Aaron Bentley
Correctly handle empty merge directive texts
187
    def test_deserialize_empty(self):
188
        self.assertRaises(errors.NotAMergeDirective,
189
                          merge_directive.MergeDirective.from_lines, [])
190
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
191
    def test_deserialize_leading_junk(self):
2520.4.73 by Aaron Bentley
Implement new merge directive format
192
        md = merge_directive.MergeDirective.from_lines(self.INPUT1)
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
193
        self.assertEqual('example:', md.revision_id)
194
        self.assertEqual('sha', md.testament_sha1)
195
        self.assertEqual('http://example.com', md.target_branch)
196
        self.assertEqual('http://example.org', md.source_branch)
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
197
        self.assertEqual(453, md.time)
198
        self.assertEqual(120, md.timezone)
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
199
        self.assertEqual('booga', md.patch)
200
        self.assertEqual('diff', md.patch_type)
201
        self.assertEqual('Hi mom!', md.message)
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
202
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
203
    def test_roundtrip(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
204
        time = 500000
205
        timezone = 7.5 * 3600
2520.4.73 by Aaron Bentley
Implement new merge directive format
206
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
207
            'http://example.com', source_branch="http://example.org",
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
208
            patch='booga', patch_type='diff')
209
        md2 = merge_directive.MergeDirective.from_lines(md.to_lines())
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
210
        self.assertEqual('example:', md2.revision_id)
1551.12.54 by Aaron Bentley
Decoded revision ids are utf-8
211
        self.assertIsInstance(md2.revision_id, str)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
212
        self.assertEqual('sha', md2.testament_sha1)
1551.12.13 by Aaron Bentley
Rename fields
213
        self.assertEqual('http://example.com', md2.target_branch)
214
        self.assertEqual('http://example.org', md2.source_branch)
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
215
        self.assertEqual(time, md2.time)
216
        self.assertEqual(timezone, md2.timezone)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
217
        self.assertEqual('diff', md2.patch_type)
218
        self.assertEqual('booga', md2.patch)
1551.12.26 by Aaron Bentley
Get email working, with optional message
219
        self.assertEqual(None, md2.message)
2520.4.73 by Aaron Bentley
Implement new merge directive format
220
        self.set_bundle(md, "# Bazaar revision bundle v0.9\n#\n")
1551.12.26 by Aaron Bentley
Get email working, with optional message
221
        md.message = "Hi mom!"
2520.4.73 by Aaron Bentley
Implement new merge directive format
222
        lines = md.to_lines()
223
        md3 = merge_directive.MergeDirective.from_lines(lines)
224
        self.assertEqual("# Bazaar revision bundle v0.9\n#\n", md3.bundle)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
225
        self.assertEqual("bundle", md3.patch_type)
1551.12.12 by Aaron Bentley
Add format header
226
        self.assertContainsRe(md3.to_lines()[0],
227
            '^# Bazaar merge directive format ')
1551.12.26 by Aaron Bentley
Get email working, with optional message
228
        self.assertEqual("Hi mom!", md3.message)
2520.4.73 by Aaron Bentley
Implement new merge directive format
229
        md3.clear_payload()
2520.4.80 by Aaron Bentley
Improve merge directive tests
230
        self.assertIs(None, md3.get_raw_bundle())
1551.12.53 by Aaron Bentley
Fix deserialization of merge directives with no patch
231
        md4 = merge_directive.MergeDirective.from_lines(md3.to_lines())
232
        self.assertIs(None, md4.patch_type)
1551.12.26 by Aaron Bentley
Get email working, with optional message
233
234
2520.4.73 by Aaron Bentley
Implement new merge directive format
235
class TestMergeDirective1(tests.TestCase, TestMergeDirective):
236
    """Test merge directive format 1"""
237
238
    INPUT1 = INPUT1
239
240
    OUTPUT1 = OUTPUT1
241
242
    OUTPUT2 = OUTPUT2
243
244
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
245
                 target_branch, patch=None, patch_type=None,
246
                 source_branch=None, message=None):
247
        return merge_directive.MergeDirective(revision_id, testament_sha1,
248
                 time, timezone, target_branch, patch, patch_type,
249
                 source_branch, message)
250
251
    @staticmethod
252
    def set_bundle(md, value):
253
        md.patch = value
254
255
    def test_require_patch(self):
256
        time = 500.0
257
        timezone = 120
258
        self.assertRaises(errors.PatchMissing, merge_directive.MergeDirective,
259
            'example:', 'sha', time, timezone, 'http://example.com',
260
            patch_type='bundle')
261
        md = merge_directive.MergeDirective('example:', 'sha1', time, timezone,
262
            'http://example.com', source_branch="http://example.org",
263
            patch='', patch_type='diff')
264
        self.assertEqual(md.patch, '')
265
266
267
class TestMergeDirective2(tests.TestCase, TestMergeDirective):
268
    """Test merge directive format 2"""
269
270
    INPUT1 = INPUT1_2
271
272
    OUTPUT1 = OUTPUT1_2
273
274
    OUTPUT2 = OUTPUT2_2
275
276
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
277
                 target_branch, patch=None, patch_type=None,
2520.4.105 by Aaron Bentley
Implement patch verification
278
                 source_branch=None, message=None, base_revision_id='null:'):
2520.4.73 by Aaron Bentley
Implement new merge directive format
279
        if patch_type == 'bundle':
280
            bundle = patch
281
            patch = None
282
        else:
283
            bundle = None
284
        return merge_directive.MergeDirective2(revision_id, testament_sha1,
285
            time, timezone, target_branch, patch, source_branch, message,
2520.4.105 by Aaron Bentley
Implement patch verification
286
            bundle, base_revision_id)
2520.4.73 by Aaron Bentley
Implement new merge directive format
287
288
    @staticmethod
289
    def set_bundle(md, value):
290
        md.bundle = value
291
292
2625.6.1 by Adeodato Simó
New EmailMessage class, façade around email.Message and MIMEMultipart.
293
EMAIL1 = """From: "J. Random Hacker" <jrandom@example.com>
1551.12.26 by Aaron Bentley
Get email working, with optional message
294
Subject: Commit of rev2a
2625.6.1 by Adeodato Simó
New EmailMessage class, façade around email.Message and MIMEMultipart.
295
To: pqm@example.com
296
User-Agent: Bazaar \(.*\)
1551.12.26 by Aaron Bentley
Get email working, with optional message
297
1551.12.45 by Aaron Bentley
Change format marker to not experimental
298
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
299
# revision_id: rev2a
300
# target_branch: (.|\n)*
301
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
302
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
303
# source_branch: (.|\n)*
304
"""
305
306
2625.6.2 by Adeodato Simó
Merge bzr.dev, resolving conflicts and updating test_merge_directive.py.
307
EMAIL1_2 = """From: "J. Random Hacker" <jrandom@example.com>
2520.4.80 by Aaron Bentley
Improve merge directive tests
308
Subject: Commit of rev2a
2625.6.2 by Adeodato Simó
Merge bzr.dev, resolving conflicts and updating test_merge_directive.py.
309
To: pqm@example.com
310
User-Agent: Bazaar \(.*\)
2520.4.80 by Aaron Bentley
Improve merge directive tests
311
2687.2.2 by Martin Pool
Fix up other references to 0.19
312
# Bazaar merge directive format 2 \\(Bazaar 0.90\\)
2520.4.80 by Aaron Bentley
Improve merge directive tests
313
# revision_id: rev2a
314
# target_branch: (.|\n)*
315
# testament_sha1: .*
316
# timestamp: 1970-01-01 00:08:56 \\+0001
317
# source_branch: (.|\n)*
318
"""
319
320
2625.6.1 by Adeodato Simó
New EmailMessage class, façade around email.Message and MIMEMultipart.
321
EMAIL2 = """From: "J. Random Hacker" <jrandom@example.com>
1551.12.26 by Aaron Bentley
Get email working, with optional message
322
Subject: Commit of rev2a with special message
2625.6.1 by Adeodato Simó
New EmailMessage class, façade around email.Message and MIMEMultipart.
323
To: pqm@example.com
324
User-Agent: Bazaar \(.*\)
1551.12.26 by Aaron Bentley
Get email working, with optional message
325
1551.12.45 by Aaron Bentley
Change format marker to not experimental
326
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
327
# revision_id: rev2a
328
# target_branch: (.|\n)*
329
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
330
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
331
# source_branch: (.|\n)*
332
# message: Commit of rev2a with special message
333
"""
1551.12.4 by Aaron Bentley
Add failing test
334
2625.6.2 by Adeodato Simó
Merge bzr.dev, resolving conflicts and updating test_merge_directive.py.
335
EMAIL2_2 = """From: "J. Random Hacker" <jrandom@example.com>
2520.4.80 by Aaron Bentley
Improve merge directive tests
336
Subject: Commit of rev2a with special message
2625.6.2 by Adeodato Simó
Merge bzr.dev, resolving conflicts and updating test_merge_directive.py.
337
To: pqm@example.com
338
User-Agent: Bazaar \(.*\)
2520.4.80 by Aaron Bentley
Improve merge directive tests
339
2687.2.2 by Martin Pool
Fix up other references to 0.19
340
# Bazaar merge directive format 2 \\(Bazaar 0.90\\)
2520.4.80 by Aaron Bentley
Improve merge directive tests
341
# revision_id: rev2a
342
# target_branch: (.|\n)*
343
# testament_sha1: .*
344
# timestamp: 1970-01-01 00:08:56 \\+0001
345
# source_branch: (.|\n)*
346
# message: Commit of rev2a with special message
347
"""
1551.12.4 by Aaron Bentley
Add failing test
348
2520.4.73 by Aaron Bentley
Implement new merge directive format
349
class TestMergeDirectiveBranch(object):
1551.12.4 by Aaron Bentley
Add failing test
350
1551.12.26 by Aaron Bentley
Get email working, with optional message
351
    def make_trees(self):
1551.12.4 by Aaron Bentley
Add failing test
352
        tree_a = self.make_branch_and_tree('tree_a')
1551.12.26 by Aaron Bentley
Get email working, with optional message
353
        tree_a.branch.get_config().set_user_option('email',
354
            'J. Random Hacker <jrandom@example.com>')
1551.12.4 by Aaron Bentley
Add failing test
355
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_b\n')])
356
        tree_a.add('file')
357
        tree_a.commit('message', rev_id='rev1')
358
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
359
        branch_c = tree_a.bzrdir.sprout('branch_c').open_branch()
1551.12.4 by Aaron Bentley
Add failing test
360
        tree_b.commit('message', rev_id='rev2b')
2520.4.105 by Aaron Bentley
Implement patch verification
361
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_c \n')])
1551.12.26 by Aaron Bentley
Get email working, with optional message
362
        tree_a.commit('Commit of rev2a', rev_id='rev2a')
363
        return tree_a, tree_b, branch_c
364
2490.2.28 by Aaron Bentley
Fix handling of null revision
365
    def test_empty_target(self):
366
        tree_a, tree_b, branch_c = self.make_trees()
367
        tree_d = self.make_branch_and_tree('tree_d')
2520.4.73 by Aaron Bentley
Implement new merge directive format
368
        md2 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
369
            tree_d.branch.base, patch_type='diff',
370
            public_branch=tree_a.branch.base)
2490.2.28 by Aaron Bentley
Fix handling of null revision
371
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
372
    def test_generate_patch(self):
373
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.73 by Aaron Bentley
Implement new merge directive format
374
        md2 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
375
            tree_b.branch.base, patch_type='diff',
376
            public_branch=tree_a.branch.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
377
        self.assertNotContainsRe(md2.patch, 'Bazaar revision bundle')
378
        self.assertContainsRe(md2.patch, '\\+content_c')
379
        self.assertNotContainsRe(md2.patch, '\\+\\+\\+ b/')
380
        self.assertContainsRe(md2.patch, '\\+\\+\\+ file')
381
382
    def test_public_branch(self):
1551.12.26 by Aaron Bentley
Get email working, with optional message
383
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
384
        self.assertRaises(errors.PublicBranchOutOfDate,
2520.4.73 by Aaron Bentley
Implement new merge directive format
385
            self.from_objects, tree_a.branch.repository, 'rev2a', 500, 144,
386
            tree_b.branch.base, public_branch=branch_c.base, patch_type='diff')
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
387
        self.assertRaises(errors.PublicBranchOutOfDate,
388
            self.from_objects, tree_a.branch.repository, 'rev2a', 500, 144,
389
            tree_b.branch.base, public_branch=branch_c.base, patch_type=None)
1551.12.34 by Aaron Bentley
Check public branch only if not using a bundle
390
        # public branch is not checked if patch format is bundle.
2520.4.73 by Aaron Bentley
Implement new merge directive format
391
        md1 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 144,
392
            tree_b.branch.base, public_branch=branch_c.base)
1551.12.34 by Aaron Bentley
Check public branch only if not using a bundle
393
        # public branch is provided with a bundle, despite possibly being out
394
        # of date, because it's not required if a bundle is present.
395
        self.assertEqual(md1.source_branch, branch_c.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
396
        # Once we update the public branch, we can generate a diff.
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
397
        branch_c.pull(tree_a.branch)
2520.4.73 by Aaron Bentley
Implement new merge directive format
398
        md3 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 144,
399
            tree_b.branch.base, patch_type=None, public_branch=branch_c.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
400
1551.12.50 by Aaron Bentley
Use public location of submit branch if possible
401
    def test_use_public_submit_branch(self):
402
        tree_a, tree_b, branch_c = self.make_trees()
403
        branch_c.pull(tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
404
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 144,
405
            tree_b.branch.base, patch_type=None, public_branch=branch_c.base)
1551.12.50 by Aaron Bentley
Use public location of submit branch if possible
406
        self.assertEqual(md.target_branch, tree_b.branch.base)
407
        tree_b.branch.set_public_branch('http://example.com')
2520.4.80 by Aaron Bentley
Improve merge directive tests
408
        md2 = self.from_objects(
1551.12.50 by Aaron Bentley
Use public location of submit branch if possible
409
              tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
410
              patch_type=None, public_branch=branch_c.base)
411
        self.assertEqual(md2.target_branch, 'http://example.com')
412
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
413
    def test_message(self):
414
        tree_a, tree_b, branch_c = self.make_trees()
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
415
        md3 = self.from_objects(tree_a.branch.repository, 'rev1', 500, 120,
2520.4.80 by Aaron Bentley
Improve merge directive tests
416
            tree_b.branch.base, patch_type=None, public_branch=branch_c.base,
1551.12.33 by Aaron Bentley
Take public_branch as a string, not object
417
            message='Merge message')
1551.12.7 by Aaron Bentley
Fix use of public location/branch
418
        md3.to_lines()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
419
        self.assertIs(None, md3.patch)
1551.12.27 by Aaron Bentley
support custom message everywhere
420
        self.assertEqual('Merge message', md3.message)
1551.12.16 by Aaron Bentley
Enable signing merge directives
421
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
422
    def test_generate_bundle(self):
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
423
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
424
        md1 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
425
            tree_b.branch.base, public_branch=branch_c.base)
426
427
        self.assertContainsRe(md1.get_raw_bundle(), 'Bazaar revision bundle')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
428
        self.assertContainsRe(md1.patch, '\\+content_c')
429
        self.assertNotContainsRe(md1.patch, '\\+content_a')
430
        self.assertContainsRe(md1.patch, '\\+content_c')
431
        self.assertNotContainsRe(md1.patch, '\\+content_a')
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
432
1551.15.29 by Aaron Bentley
Make merge directives robust against broken bundles
433
    def test_broken_bundle(self):
434
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.73 by Aaron Bentley
Implement new merge directive format
435
        md1 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
436
            tree_b.branch.base, public_branch=branch_c.base)
1551.15.29 by Aaron Bentley
Make merge directives robust against broken bundles
437
        lines = md1.to_lines()
438
        lines = [l.replace('\n', '\r\n') for l in lines]
439
        md2 = merge_directive.MergeDirective.from_lines(lines)
440
        self.assertEqual('rev2a', md2.revision_id)
441
1551.12.16 by Aaron Bentley
Enable signing merge directives
442
    def test_signing(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
443
        time = 453
444
        timezone = 7200
1551.12.16 by Aaron Bentley
Enable signing merge directives
445
        class FakeBranch(object):
446
            def get_config(self):
447
                return self
448
            def gpg_signing_command(self):
449
                return 'loopback'
2520.4.80 by Aaron Bentley
Improve merge directive tests
450
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.16 by Aaron Bentley
Enable signing merge directives
451
            'http://example.com', source_branch="http://example.org",
452
            patch='booga', patch_type='diff')
453
        old_strategy = gpg.GPGStrategy
454
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
455
        try:
456
            signed = md.to_signed(FakeBranch())
457
        finally:
458
            gpg.GPGStrategy = old_strategy
459
        self.assertContainsRe(signed, '^-----BEGIN PSEUDO-SIGNED CONTENT')
460
        self.assertContainsRe(signed, 'example.org')
461
        self.assertContainsRe(signed, 'booga')
1551.12.26 by Aaron Bentley
Get email working, with optional message
462
463
    def test_email(self):
464
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
465
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 476, 60,
466
            tree_b.branch.base, patch_type=None,
467
            public_branch=tree_a.branch.base)
1551.12.26 by Aaron Bentley
Get email working, with optional message
468
        message = md.to_email('pqm@example.com', tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
469
        self.assertContainsRe(message.as_string(), self.EMAIL1)
1551.12.26 by Aaron Bentley
Get email working, with optional message
470
        md.message = 'Commit of rev2a with special message'
471
        message = md.to_email('pqm@example.com', tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
472
        self.assertContainsRe(message.as_string(), self.EMAIL2)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
473
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
474
    def test_install_revisions_branch(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
475
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
476
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
477
            tree_b.branch.base, patch_type=None,
478
            public_branch=tree_a.branch.base)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
479
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
480
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
481
        self.assertEqual('rev2a', revision)
482
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
483
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
484
    def test_get_merge_request(self):
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
485
        tree_a, tree_b, branch_c = self.make_trees()
486
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
487
            tree_b.branch.base, patch_type='bundle',
488
            public_branch=tree_a.branch.base)
489
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
490
        md.install_revisions(tree_b.branch.repository)
491
        base, revision, verified = md.get_merge_request(
492
            tree_b.branch.repository)
493
        if isinstance(md, merge_directive.MergeDirective):
494
            self.assertIs(None, base)
495
            self.assertEqual('inapplicable', verified)
496
        else:
497
            self.assertEqual('rev1', base)
498
            self.assertEqual('verified', verified)
499
        self.assertEqual('rev2a', revision)
500
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
501
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
502
            tree_b.branch.base, patch_type=None,
503
            public_branch=tree_a.branch.base)
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
504
        base, revision, verified = md.get_merge_request(
505
            tree_b.branch.repository)
506
        if isinstance(md, merge_directive.MergeDirective):
507
            self.assertIs(None, base)
508
            self.assertEqual('inapplicable', verified)
509
        else:
510
            self.assertEqual('rev1', base)
511
            self.assertEqual('inapplicable', verified)
512
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
513
            tree_b.branch.base, patch_type='diff',
514
            public_branch=tree_a.branch.base)
515
        base, revision, verified = md.get_merge_request(
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
516
            tree_b.branch.repository)
517
        if isinstance(md, merge_directive.MergeDirective):
518
            self.assertIs(None, base)
519
            self.assertEqual('inapplicable', verified)
520
        else:
521
            self.assertEqual('rev1', base)
522
            self.assertEqual('verified', verified)
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
523
        md.patch='asdf'
524
        base, revision, verified = md.get_merge_request(
525
            tree_b.branch.repository)
526
        if isinstance(md, merge_directive.MergeDirective):
527
            self.assertIs(None, base)
528
            self.assertEqual('inapplicable', verified)
529
        else:
530
            self.assertEqual('rev1', base)
2694.3.1 by Aaron Bentley
Disable patch verification (broken for CRLF files)
531
            self.expectFailure('Patch verification is disabled',
532
                               self.assertEqual, 'failed', verified)
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
533
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
534
    def test_install_revisions_bundle(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
535
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
536
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
537
            tree_b.branch.base, patch_type='bundle',
538
            public_branch=tree_a.branch.base)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
539
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
540
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
541
        self.assertEqual('rev2a', revision)
542
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
543
544
    def test_get_target_revision_nofetch(self):
545
        tree_a, tree_b, branch_c = self.make_trees()
546
        tree_b.branch.fetch(tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
547
        md = self.from_objects( tree_a.branch.repository, 'rev2a', 500, 36,
548
            tree_b.branch.base, patch_type=None,
549
            public_branch=tree_a.branch.base)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
550
        md.source_branch = '/dev/null'
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
551
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
552
        self.assertEqual('rev2a', revision)
2520.4.73 by Aaron Bentley
Implement new merge directive format
553
554
555
class TestMergeDirective1Branch(tests.TestCaseWithTransport,
556
    TestMergeDirectiveBranch):
557
    """Test merge directive format 1 with a branch"""
2520.4.80 by Aaron Bentley
Improve merge directive tests
558
559
    EMAIL1 = EMAIL1
560
561
    EMAIL2 = EMAIL2
562
2520.4.73 by Aaron Bentley
Implement new merge directive format
563
    def from_objects(self, repository, revision_id, time, timezone,
564
        target_branch, patch_type='bundle', local_target_branch=None,
565
        public_branch=None, message=None):
566
        return merge_directive.MergeDirective.from_objects(
567
            repository, revision_id, time, timezone, target_branch,
568
            patch_type, local_target_branch, public_branch, message)
569
2520.4.80 by Aaron Bentley
Improve merge directive tests
570
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
571
                 target_branch, patch=None, patch_type=None,
572
                 source_branch=None, message=None):
573
        return merge_directive.MergeDirective(revision_id, testament_sha1,
574
                 time, timezone, target_branch, patch, patch_type,
575
                 source_branch, message)
576
2520.4.73 by Aaron Bentley
Implement new merge directive format
577
578
class TestMergeDirective2Branch(tests.TestCaseWithTransport,
579
    TestMergeDirectiveBranch):
580
    """Test merge directive format 2 with a branch"""
581
2520.4.80 by Aaron Bentley
Improve merge directive tests
582
    EMAIL1 = EMAIL1_2
583
584
    EMAIL2 = EMAIL2_2
585
2520.4.73 by Aaron Bentley
Implement new merge directive format
586
    def from_objects(self, repository, revision_id, time, timezone,
587
        target_branch, patch_type='bundle', local_target_branch=None,
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
588
        public_branch=None, message=None, base_revision_id=None):
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
589
        include_patch = (patch_type in ('bundle', 'diff'))
590
        include_bundle = (patch_type == 'bundle')
591
        assert patch_type in ('bundle', 'diff', None)
2520.4.73 by Aaron Bentley
Implement new merge directive format
592
        return merge_directive.MergeDirective2.from_objects(
593
            repository, revision_id, time, timezone, target_branch,
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
594
            include_patch, include_bundle, local_target_branch, public_branch,
595
            message, base_revision_id)
2520.4.80 by Aaron Bentley
Improve merge directive tests
596
597
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
598
                 target_branch, patch=None, patch_type=None,
2520.4.105 by Aaron Bentley
Implement patch verification
599
                 source_branch=None, message=None, base_revision_id='null:'):
2520.4.80 by Aaron Bentley
Improve merge directive tests
600
        if patch_type == 'bundle':
601
            bundle = patch
602
            patch = None
603
        else:
604
            bundle = None
605
        return merge_directive.MergeDirective2(revision_id, testament_sha1,
606
            time, timezone, target_branch, patch, source_branch, message,
2520.4.105 by Aaron Bentley
Implement patch verification
607
            bundle, base_revision_id)
608
609
    def test_base_revision(self):
610
        tree_a, tree_b, branch_c = self.make_trees()
611
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 60,
612
            tree_b.branch.base, patch_type='bundle',
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
613
            public_branch=tree_a.branch.base, base_revision_id=None)
2520.4.105 by Aaron Bentley
Implement patch verification
614
        self.assertEqual('rev1', md.base_revision_id)
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
615
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 60,
616
            tree_b.branch.base, patch_type='bundle',
617
            public_branch=tree_a.branch.base, base_revision_id='null:')
618
        self.assertEqual('null:', md.base_revision_id)
2520.4.105 by Aaron Bentley
Implement patch verification
619
        lines = md.to_lines()
620
        md2 = merge_directive.MergeDirective.from_lines(lines)
621
        self.assertEqual(md2.base_revision_id, md.base_revision_id)
622
623
    def test_patch_verification(self):
624
        tree_a, tree_b, branch_c = self.make_trees()
625
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 60,
626
            tree_b.branch.base, patch_type='bundle',
627
            public_branch=tree_a.branch.base)
628
        lines = md.to_lines()
629
        md2 = merge_directive.MergeDirective.from_lines(lines)
630
        md2._verify_patch(tree_a.branch.repository)
631
        # Stript trailing whitespace
632
        md2.patch = md2.patch.replace(' \n', '\n')
633
        md2._verify_patch(tree_a.branch.repository)
634
        # Convert to Mac line-endings
635
        md2.patch = md2.patch.replace('\n', '\r')
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
636
        self.assertTrue(md2._verify_patch(tree_a.branch.repository))
2520.4.105 by Aaron Bentley
Implement patch verification
637
        # Convert to DOS line-endings
638
        md2.patch = md2.patch.replace('\r', '\r\n')
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
639
        self.assertTrue(md2._verify_patch(tree_a.branch.repository))
2520.4.105 by Aaron Bentley
Implement patch verification
640
        md2.patch = md2.patch.replace('content_c', 'content_d')
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
641
        self.assertFalse(md2._verify_patch(tree_a.branch.repository))
2694.1.1 by Aaron Bentley
Restore support for Merge directive 2 / 0.19
642
643
644
class TestParseOldMergeDirective2(tests.TestCase):
645
646
    def test_parse_old_merge_directive(self):
647
        md = merge_directive.MergeDirective.from_lines(INPUT1_2_OLD)
648
        self.assertEqual('example:', md.revision_id)
649
        self.assertEqual('sha', md.testament_sha1)
650
        self.assertEqual('http://example.com', md.target_branch)
651
        self.assertEqual('http://example.org', md.source_branch)
652
        self.assertEqual(453, md.time)
653
        self.assertEqual(120, md.timezone)
654
        self.assertEqual('booga', md.patch)
655
        self.assertEqual('diff', md.patch_type)
656
        self.assertEqual('Hi mom!', md.message)