/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
2520.4.136 by Aaron Bentley
Fix format strings
34
OUTPUT1_2 = """# Bazaar merge directive format 2 (Bazaar 0.19)
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
2520.4.136 by Aaron Bentley
Fix format strings
54
OUTPUT2_2 = """# Bazaar merge directive format 2 (Bazaar 0.19)
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
2520.4.136 by Aaron Bentley
Fix format strings
99
# Bazaar merge directive format 2 (Bazaar 0.19)\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
112
class TestMergeDirective(object):
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
113
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
114
    def test_merge_source(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
115
        time = 500000.0
116
        timezone = 5 * 3600
2520.4.73 by Aaron Bentley
Implement new merge directive format
117
        self.assertRaises(errors.NoMergeSource, self.make_merge_directive,
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
118
            'example:', 'sha', time, timezone, 'http://example.com')
2520.4.73 by Aaron Bentley
Implement new merge directive format
119
        self.assertRaises(errors.NoMergeSource, self.make_merge_directive,
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
120
            'example:', 'sha', time, timezone, 'http://example.com',
121
            patch_type='diff')
2520.4.73 by Aaron Bentley
Implement new merge directive format
122
        self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
123
            'http://example.com', source_branch='http://example.org')
2520.4.73 by Aaron Bentley
Implement new merge directive format
124
        md = self.make_merge_directive('null:', 'sha', time, timezone,
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
125
            'http://example.com', patch='blah', patch_type='bundle')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
126
        self.assertIs(None, md.source_branch)
2520.4.73 by Aaron Bentley
Implement new merge directive format
127
        md2 = self.make_merge_directive('null:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
128
            'http://example.com', patch='blah', patch_type='bundle',
129
            source_branch='bar')
130
        self.assertEqual('bar', md2.source_branch)
131
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
132
    def test_serialization(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
133
        time = 453
134
        timezone = 120
2520.4.73 by Aaron Bentley
Implement new merge directive format
135
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
136
            'http://example.com', patch='booga', patch_type='bundle')
2520.4.73 by Aaron Bentley
Implement new merge directive format
137
        self.assertEqualDiff(self.OUTPUT1, ''.join(md.to_lines()))
138
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
139
            'http://example.com', source_branch="http://example.org",
140
            patch='booga', patch_type='diff', message="Hi mom!")
2520.4.73 by Aaron Bentley
Implement new merge directive format
141
        self.assertEqualDiff(self.OUTPUT2, ''.join(md.to_lines()))
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
142
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
143
    def test_deserialize_junk(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
144
        time = 501
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
145
        self.assertRaises(errors.NotAMergeDirective,
146
                          merge_directive.MergeDirective.from_lines, 'lala')
147
1551.12.59 by Aaron Bentley
Correctly handle empty merge directive texts
148
    def test_deserialize_empty(self):
149
        self.assertRaises(errors.NotAMergeDirective,
150
                          merge_directive.MergeDirective.from_lines, [])
151
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
152
    def test_deserialize_leading_junk(self):
2520.4.73 by Aaron Bentley
Implement new merge directive format
153
        md = merge_directive.MergeDirective.from_lines(self.INPUT1)
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
154
        self.assertEqual('example:', md.revision_id)
155
        self.assertEqual('sha', md.testament_sha1)
156
        self.assertEqual('http://example.com', md.target_branch)
157
        self.assertEqual('http://example.org', md.source_branch)
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
158
        self.assertEqual(453, md.time)
159
        self.assertEqual(120, md.timezone)
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
160
        self.assertEqual('booga', md.patch)
161
        self.assertEqual('diff', md.patch_type)
162
        self.assertEqual('Hi mom!', md.message)
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
163
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
164
    def test_roundtrip(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
165
        time = 500000
166
        timezone = 7.5 * 3600
2520.4.73 by Aaron Bentley
Implement new merge directive format
167
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
168
            'http://example.com', source_branch="http://example.org",
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
169
            patch='booga', patch_type='diff')
170
        md2 = merge_directive.MergeDirective.from_lines(md.to_lines())
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
171
        self.assertEqual('example:', md2.revision_id)
1551.12.54 by Aaron Bentley
Decoded revision ids are utf-8
172
        self.assertIsInstance(md2.revision_id, str)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
173
        self.assertEqual('sha', md2.testament_sha1)
1551.12.13 by Aaron Bentley
Rename fields
174
        self.assertEqual('http://example.com', md2.target_branch)
175
        self.assertEqual('http://example.org', md2.source_branch)
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
176
        self.assertEqual(time, md2.time)
177
        self.assertEqual(timezone, md2.timezone)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
178
        self.assertEqual('diff', md2.patch_type)
179
        self.assertEqual('booga', md2.patch)
1551.12.26 by Aaron Bentley
Get email working, with optional message
180
        self.assertEqual(None, md2.message)
2520.4.73 by Aaron Bentley
Implement new merge directive format
181
        self.set_bundle(md, "# Bazaar revision bundle v0.9\n#\n")
1551.12.26 by Aaron Bentley
Get email working, with optional message
182
        md.message = "Hi mom!"
2520.4.73 by Aaron Bentley
Implement new merge directive format
183
        lines = md.to_lines()
184
        md3 = merge_directive.MergeDirective.from_lines(lines)
185
        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
186
        self.assertEqual("bundle", md3.patch_type)
1551.12.12 by Aaron Bentley
Add format header
187
        self.assertContainsRe(md3.to_lines()[0],
188
            '^# Bazaar merge directive format ')
1551.12.26 by Aaron Bentley
Get email working, with optional message
189
        self.assertEqual("Hi mom!", md3.message)
2520.4.73 by Aaron Bentley
Implement new merge directive format
190
        md3.clear_payload()
2520.4.80 by Aaron Bentley
Improve merge directive tests
191
        self.assertIs(None, md3.get_raw_bundle())
1551.12.53 by Aaron Bentley
Fix deserialization of merge directives with no patch
192
        md4 = merge_directive.MergeDirective.from_lines(md3.to_lines())
193
        self.assertIs(None, md4.patch_type)
1551.12.26 by Aaron Bentley
Get email working, with optional message
194
195
2520.4.73 by Aaron Bentley
Implement new merge directive format
196
class TestMergeDirective1(tests.TestCase, TestMergeDirective):
197
    """Test merge directive format 1"""
198
199
    INPUT1 = INPUT1
200
201
    OUTPUT1 = OUTPUT1
202
203
    OUTPUT2 = OUTPUT2
204
205
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
206
                 target_branch, patch=None, patch_type=None,
207
                 source_branch=None, message=None):
208
        return merge_directive.MergeDirective(revision_id, testament_sha1,
209
                 time, timezone, target_branch, patch, patch_type,
210
                 source_branch, message)
211
212
    @staticmethod
213
    def set_bundle(md, value):
214
        md.patch = value
215
216
    def test_require_patch(self):
217
        time = 500.0
218
        timezone = 120
219
        self.assertRaises(errors.PatchMissing, merge_directive.MergeDirective,
220
            'example:', 'sha', time, timezone, 'http://example.com',
221
            patch_type='bundle')
222
        md = merge_directive.MergeDirective('example:', 'sha1', time, timezone,
223
            'http://example.com', source_branch="http://example.org",
224
            patch='', patch_type='diff')
225
        self.assertEqual(md.patch, '')
226
227
228
class TestMergeDirective2(tests.TestCase, TestMergeDirective):
229
    """Test merge directive format 2"""
230
231
    INPUT1 = INPUT1_2
232
233
    OUTPUT1 = OUTPUT1_2
234
235
    OUTPUT2 = OUTPUT2_2
236
237
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
238
                 target_branch, patch=None, patch_type=None,
2520.4.105 by Aaron Bentley
Implement patch verification
239
                 source_branch=None, message=None, base_revision_id='null:'):
2520.4.73 by Aaron Bentley
Implement new merge directive format
240
        if patch_type == 'bundle':
241
            bundle = patch
242
            patch = None
243
        else:
244
            bundle = None
245
        return merge_directive.MergeDirective2(revision_id, testament_sha1,
246
            time, timezone, target_branch, patch, source_branch, message,
2520.4.105 by Aaron Bentley
Implement patch verification
247
            bundle, base_revision_id)
2520.4.73 by Aaron Bentley
Implement new merge directive format
248
249
    @staticmethod
250
    def set_bundle(md, value):
251
        md.bundle = value
252
253
1551.12.26 by Aaron Bentley
Get email working, with optional message
254
EMAIL1 = """To: pqm@example.com
255
From: J. Random Hacker <jrandom@example.com>
256
Subject: Commit of rev2a
257
1551.12.45 by Aaron Bentley
Change format marker to not experimental
258
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
259
# revision_id: rev2a
260
# target_branch: (.|\n)*
261
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
262
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
263
# source_branch: (.|\n)*
264
"""
265
266
2520.4.80 by Aaron Bentley
Improve merge directive tests
267
EMAIL1_2 = """To: pqm@example.com
268
From: J. Random Hacker <jrandom@example.com>
269
Subject: Commit of rev2a
270
2520.4.136 by Aaron Bentley
Fix format strings
271
# Bazaar merge directive format 2 \\(Bazaar 0.19\\)
2520.4.80 by Aaron Bentley
Improve merge directive tests
272
# revision_id: rev2a
273
# target_branch: (.|\n)*
274
# testament_sha1: .*
275
# timestamp: 1970-01-01 00:08:56 \\+0001
276
# source_branch: (.|\n)*
277
"""
278
279
1551.12.26 by Aaron Bentley
Get email working, with optional message
280
EMAIL2 = """To: pqm@example.com
281
From: J. Random Hacker <jrandom@example.com>
282
Subject: Commit of rev2a with special message
283
1551.12.45 by Aaron Bentley
Change format marker to not experimental
284
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
285
# revision_id: rev2a
286
# target_branch: (.|\n)*
287
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
288
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
289
# source_branch: (.|\n)*
290
# message: Commit of rev2a with special message
291
"""
1551.12.4 by Aaron Bentley
Add failing test
292
2520.4.80 by Aaron Bentley
Improve merge directive tests
293
EMAIL2_2 = """To: pqm@example.com
294
From: J. Random Hacker <jrandom@example.com>
295
Subject: Commit of rev2a with special message
296
2520.4.136 by Aaron Bentley
Fix format strings
297
# Bazaar merge directive format 2 \\(Bazaar 0.19\\)
2520.4.80 by Aaron Bentley
Improve merge directive tests
298
# revision_id: rev2a
299
# target_branch: (.|\n)*
300
# testament_sha1: .*
301
# timestamp: 1970-01-01 00:08:56 \\+0001
302
# source_branch: (.|\n)*
303
# message: Commit of rev2a with special message
304
"""
1551.12.4 by Aaron Bentley
Add failing test
305
2520.4.73 by Aaron Bentley
Implement new merge directive format
306
class TestMergeDirectiveBranch(object):
1551.12.4 by Aaron Bentley
Add failing test
307
1551.12.26 by Aaron Bentley
Get email working, with optional message
308
    def make_trees(self):
1551.12.4 by Aaron Bentley
Add failing test
309
        tree_a = self.make_branch_and_tree('tree_a')
1551.12.26 by Aaron Bentley
Get email working, with optional message
310
        tree_a.branch.get_config().set_user_option('email',
311
            'J. Random Hacker <jrandom@example.com>')
1551.12.4 by Aaron Bentley
Add failing test
312
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_b\n')])
313
        tree_a.add('file')
314
        tree_a.commit('message', rev_id='rev1')
315
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
316
        branch_c = tree_a.bzrdir.sprout('branch_c').open_branch()
1551.12.4 by Aaron Bentley
Add failing test
317
        tree_b.commit('message', rev_id='rev2b')
2520.4.105 by Aaron Bentley
Implement patch verification
318
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_c \n')])
1551.12.26 by Aaron Bentley
Get email working, with optional message
319
        tree_a.commit('Commit of rev2a', rev_id='rev2a')
320
        return tree_a, tree_b, branch_c
321
2490.2.28 by Aaron Bentley
Fix handling of null revision
322
    def test_empty_target(self):
323
        tree_a, tree_b, branch_c = self.make_trees()
324
        tree_d = self.make_branch_and_tree('tree_d')
2520.4.73 by Aaron Bentley
Implement new merge directive format
325
        md2 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
326
            tree_d.branch.base, patch_type='diff',
327
            public_branch=tree_a.branch.base)
2490.2.28 by Aaron Bentley
Fix handling of null revision
328
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
329
    def test_generate_patch(self):
330
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.73 by Aaron Bentley
Implement new merge directive format
331
        md2 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
332
            tree_b.branch.base, patch_type='diff',
333
            public_branch=tree_a.branch.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
334
        self.assertNotContainsRe(md2.patch, 'Bazaar revision bundle')
335
        self.assertContainsRe(md2.patch, '\\+content_c')
336
        self.assertNotContainsRe(md2.patch, '\\+\\+\\+ b/')
337
        self.assertContainsRe(md2.patch, '\\+\\+\\+ file')
338
339
    def test_public_branch(self):
1551.12.26 by Aaron Bentley
Get email working, with optional message
340
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
341
        self.assertRaises(errors.PublicBranchOutOfDate,
2520.4.73 by Aaron Bentley
Implement new merge directive format
342
            self.from_objects, tree_a.branch.repository, 'rev2a', 500, 144,
343
            tree_b.branch.base, public_branch=branch_c.base, patch_type='diff')
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
344
        self.assertRaises(errors.PublicBranchOutOfDate,
345
            self.from_objects, tree_a.branch.repository, 'rev2a', 500, 144,
346
            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
347
        # public branch is not checked if patch format is bundle.
2520.4.73 by Aaron Bentley
Implement new merge directive format
348
        md1 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 144,
349
            tree_b.branch.base, public_branch=branch_c.base)
1551.12.34 by Aaron Bentley
Check public branch only if not using a bundle
350
        # public branch is provided with a bundle, despite possibly being out
351
        # of date, because it's not required if a bundle is present.
352
        self.assertEqual(md1.source_branch, branch_c.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
353
        # Once we update the public branch, we can generate a diff.
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
354
        branch_c.pull(tree_a.branch)
2520.4.73 by Aaron Bentley
Implement new merge directive format
355
        md3 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 144,
356
            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
357
1551.12.50 by Aaron Bentley
Use public location of submit branch if possible
358
    def test_use_public_submit_branch(self):
359
        tree_a, tree_b, branch_c = self.make_trees()
360
        branch_c.pull(tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
361
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 144,
362
            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
363
        self.assertEqual(md.target_branch, tree_b.branch.base)
364
        tree_b.branch.set_public_branch('http://example.com')
2520.4.80 by Aaron Bentley
Improve merge directive tests
365
        md2 = self.from_objects(
1551.12.50 by Aaron Bentley
Use public location of submit branch if possible
366
              tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
367
              patch_type=None, public_branch=branch_c.base)
368
        self.assertEqual(md2.target_branch, 'http://example.com')
369
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
370
    def test_message(self):
371
        tree_a, tree_b, branch_c = self.make_trees()
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
372
        md3 = self.from_objects(tree_a.branch.repository, 'rev1', 500, 120,
2520.4.80 by Aaron Bentley
Improve merge directive tests
373
            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
374
            message='Merge message')
1551.12.7 by Aaron Bentley
Fix use of public location/branch
375
        md3.to_lines()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
376
        self.assertIs(None, md3.patch)
1551.12.27 by Aaron Bentley
support custom message everywhere
377
        self.assertEqual('Merge message', md3.message)
1551.12.16 by Aaron Bentley
Enable signing merge directives
378
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
379
    def test_generate_bundle(self):
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
380
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
381
        md1 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
382
            tree_b.branch.base, public_branch=branch_c.base)
383
384
        self.assertContainsRe(md1.get_raw_bundle(), 'Bazaar revision bundle')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
385
        self.assertContainsRe(md1.patch, '\\+content_c')
386
        self.assertNotContainsRe(md1.patch, '\\+content_a')
387
        self.assertContainsRe(md1.patch, '\\+content_c')
388
        self.assertNotContainsRe(md1.patch, '\\+content_a')
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
389
1551.15.29 by Aaron Bentley
Make merge directives robust against broken bundles
390
    def test_broken_bundle(self):
391
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.73 by Aaron Bentley
Implement new merge directive format
392
        md1 = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 120,
393
            tree_b.branch.base, public_branch=branch_c.base)
1551.15.29 by Aaron Bentley
Make merge directives robust against broken bundles
394
        lines = md1.to_lines()
395
        lines = [l.replace('\n', '\r\n') for l in lines]
396
        md2 = merge_directive.MergeDirective.from_lines(lines)
397
        self.assertEqual('rev2a', md2.revision_id)
398
1551.12.16 by Aaron Bentley
Enable signing merge directives
399
    def test_signing(self):
2425.6.1 by Martin Pool
Fix formatting of timezones in bundles and merge directives.
400
        time = 453
401
        timezone = 7200
1551.12.16 by Aaron Bentley
Enable signing merge directives
402
        class FakeBranch(object):
403
            def get_config(self):
404
                return self
405
            def gpg_signing_command(self):
406
                return 'loopback'
2520.4.80 by Aaron Bentley
Improve merge directive tests
407
        md = self.make_merge_directive('example:', 'sha', time, timezone,
1551.12.16 by Aaron Bentley
Enable signing merge directives
408
            'http://example.com', source_branch="http://example.org",
409
            patch='booga', patch_type='diff')
410
        old_strategy = gpg.GPGStrategy
411
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
412
        try:
413
            signed = md.to_signed(FakeBranch())
414
        finally:
415
            gpg.GPGStrategy = old_strategy
416
        self.assertContainsRe(signed, '^-----BEGIN PSEUDO-SIGNED CONTENT')
417
        self.assertContainsRe(signed, 'example.org')
418
        self.assertContainsRe(signed, 'booga')
1551.12.26 by Aaron Bentley
Get email working, with optional message
419
420
    def test_email(self):
421
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
422
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 476, 60,
423
            tree_b.branch.base, patch_type=None,
424
            public_branch=tree_a.branch.base)
1551.12.26 by Aaron Bentley
Get email working, with optional message
425
        message = md.to_email('pqm@example.com', tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
426
        self.assertContainsRe(message.as_string(), self.EMAIL1)
1551.12.26 by Aaron Bentley
Get email working, with optional message
427
        md.message = 'Commit of rev2a with special message'
428
        message = md.to_email('pqm@example.com', tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
429
        self.assertContainsRe(message.as_string(), self.EMAIL2)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
430
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
431
    def test_install_revisions_branch(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
432
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
433
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
434
            tree_b.branch.base, patch_type=None,
435
            public_branch=tree_a.branch.base)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
436
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
437
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
438
        self.assertEqual('rev2a', revision)
439
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
440
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
441
    def test_get_merge_request(self):
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
442
        tree_a, tree_b, branch_c = self.make_trees()
443
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
444
            tree_b.branch.base, patch_type='bundle',
445
            public_branch=tree_a.branch.base)
446
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
447
        md.install_revisions(tree_b.branch.repository)
448
        base, revision, verified = md.get_merge_request(
449
            tree_b.branch.repository)
450
        if isinstance(md, merge_directive.MergeDirective):
451
            self.assertIs(None, base)
452
            self.assertEqual('inapplicable', verified)
453
        else:
454
            self.assertEqual('rev1', base)
455
            self.assertEqual('verified', verified)
456
        self.assertEqual('rev2a', revision)
457
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
458
        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
459
            tree_b.branch.base, patch_type=None,
460
            public_branch=tree_a.branch.base)
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
461
        base, revision, verified = md.get_merge_request(
462
            tree_b.branch.repository)
463
        if isinstance(md, merge_directive.MergeDirective):
464
            self.assertIs(None, base)
465
            self.assertEqual('inapplicable', verified)
466
        else:
467
            self.assertEqual('rev1', base)
468
            self.assertEqual('inapplicable', verified)
469
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
470
            tree_b.branch.base, patch_type='diff',
471
            public_branch=tree_a.branch.base)
472
        base, revision, verified = md.get_merge_request(
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
473
            tree_b.branch.repository)
474
        if isinstance(md, merge_directive.MergeDirective):
475
            self.assertIs(None, base)
476
            self.assertEqual('inapplicable', verified)
477
        else:
478
            self.assertEqual('rev1', base)
479
            self.assertEqual('verified', verified)
2520.4.109 by Aaron Bentley
start work on directive cherry-picking
480
        md.patch='asdf'
481
        base, revision, verified = md.get_merge_request(
482
            tree_b.branch.repository)
483
        if isinstance(md, merge_directive.MergeDirective):
484
            self.assertIs(None, base)
485
            self.assertEqual('inapplicable', verified)
486
        else:
487
            self.assertEqual('rev1', base)
488
            self.assertEqual('failed', verified)
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
489
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
490
    def test_install_revisions_bundle(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
491
        tree_a, tree_b, branch_c = self.make_trees()
2520.4.80 by Aaron Bentley
Improve merge directive tests
492
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 36,
493
            tree_b.branch.base, patch_type='bundle',
494
            public_branch=tree_a.branch.base)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
495
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
496
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
497
        self.assertEqual('rev2a', revision)
498
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
499
500
    def test_get_target_revision_nofetch(self):
501
        tree_a, tree_b, branch_c = self.make_trees()
502
        tree_b.branch.fetch(tree_a.branch)
2520.4.80 by Aaron Bentley
Improve merge directive tests
503
        md = self.from_objects( tree_a.branch.repository, 'rev2a', 500, 36,
504
            tree_b.branch.base, patch_type=None,
505
            public_branch=tree_a.branch.base)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
506
        md.source_branch = '/dev/null'
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
507
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
508
        self.assertEqual('rev2a', revision)
2520.4.73 by Aaron Bentley
Implement new merge directive format
509
510
511
class TestMergeDirective1Branch(tests.TestCaseWithTransport,
512
    TestMergeDirectiveBranch):
513
    """Test merge directive format 1 with a branch"""
2520.4.80 by Aaron Bentley
Improve merge directive tests
514
515
    EMAIL1 = EMAIL1
516
517
    EMAIL2 = EMAIL2
518
2520.4.73 by Aaron Bentley
Implement new merge directive format
519
    def from_objects(self, repository, revision_id, time, timezone,
520
        target_branch, patch_type='bundle', local_target_branch=None,
521
        public_branch=None, message=None):
522
        return merge_directive.MergeDirective.from_objects(
523
            repository, revision_id, time, timezone, target_branch,
524
            patch_type, local_target_branch, public_branch, message)
525
2520.4.80 by Aaron Bentley
Improve merge directive tests
526
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
527
                 target_branch, patch=None, patch_type=None,
528
                 source_branch=None, message=None):
529
        return merge_directive.MergeDirective(revision_id, testament_sha1,
530
                 time, timezone, target_branch, patch, patch_type,
531
                 source_branch, message)
532
2520.4.73 by Aaron Bentley
Implement new merge directive format
533
534
class TestMergeDirective2Branch(tests.TestCaseWithTransport,
535
    TestMergeDirectiveBranch):
536
    """Test merge directive format 2 with a branch"""
537
2520.4.80 by Aaron Bentley
Improve merge directive tests
538
    EMAIL1 = EMAIL1_2
539
540
    EMAIL2 = EMAIL2_2
541
2520.4.73 by Aaron Bentley
Implement new merge directive format
542
    def from_objects(self, repository, revision_id, time, timezone,
543
        target_branch, patch_type='bundle', local_target_branch=None,
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
544
        public_branch=None, message=None, base_revision_id=None):
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
545
        include_patch = (patch_type in ('bundle', 'diff'))
546
        include_bundle = (patch_type == 'bundle')
547
        assert patch_type in ('bundle', 'diff', None)
2520.4.73 by Aaron Bentley
Implement new merge directive format
548
        return merge_directive.MergeDirective2.from_objects(
549
            repository, revision_id, time, timezone, target_branch,
2520.5.4 by Aaron Bentley
Replace 'bundle-revisions' with 'submit' command
550
            include_patch, include_bundle, local_target_branch, public_branch,
551
            message, base_revision_id)
2520.4.80 by Aaron Bentley
Improve merge directive tests
552
553
    def make_merge_directive(self, revision_id, testament_sha1, time, timezone,
554
                 target_branch, patch=None, patch_type=None,
2520.4.105 by Aaron Bentley
Implement patch verification
555
                 source_branch=None, message=None, base_revision_id='null:'):
2520.4.80 by Aaron Bentley
Improve merge directive tests
556
        if patch_type == 'bundle':
557
            bundle = patch
558
            patch = None
559
        else:
560
            bundle = None
561
        return merge_directive.MergeDirective2(revision_id, testament_sha1,
562
            time, timezone, target_branch, patch, source_branch, message,
2520.4.105 by Aaron Bentley
Implement patch verification
563
            bundle, base_revision_id)
564
565
    def test_base_revision(self):
566
        tree_a, tree_b, branch_c = self.make_trees()
567
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 60,
568
            tree_b.branch.base, patch_type='bundle',
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
569
            public_branch=tree_a.branch.base, base_revision_id=None)
2520.4.105 by Aaron Bentley
Implement patch verification
570
        self.assertEqual('rev1', md.base_revision_id)
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
571
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 60,
572
            tree_b.branch.base, patch_type='bundle',
573
            public_branch=tree_a.branch.base, base_revision_id='null:')
574
        self.assertEqual('null:', md.base_revision_id)
2520.4.105 by Aaron Bentley
Implement patch verification
575
        lines = md.to_lines()
576
        md2 = merge_directive.MergeDirective.from_lines(lines)
577
        self.assertEqual(md2.base_revision_id, md.base_revision_id)
578
579
    def test_patch_verification(self):
580
        tree_a, tree_b, branch_c = self.make_trees()
581
        md = self.from_objects(tree_a.branch.repository, 'rev2a', 500, 60,
582
            tree_b.branch.base, patch_type='bundle',
583
            public_branch=tree_a.branch.base)
584
        lines = md.to_lines()
585
        md2 = merge_directive.MergeDirective.from_lines(lines)
586
        md2._verify_patch(tree_a.branch.repository)
587
        # Stript trailing whitespace
588
        md2.patch = md2.patch.replace(' \n', '\n')
589
        md2._verify_patch(tree_a.branch.repository)
590
        # Convert to Mac line-endings
591
        md2.patch = md2.patch.replace('\n', '\r')
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
592
        self.assertTrue(md2._verify_patch(tree_a.branch.repository))
2520.4.105 by Aaron Bentley
Implement patch verification
593
        # Convert to DOS line-endings
594
        md2.patch = md2.patch.replace('\r', '\r\n')
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
595
        self.assertTrue(md2._verify_patch(tree_a.branch.repository))
2520.4.105 by Aaron Bentley
Implement patch verification
596
        md2.patch = md2.patch.replace('content_c', 'content_d')
2520.4.108 by Aaron Bentley
Start work on using merge base from directives
597
        self.assertFalse(md2._verify_patch(tree_a.branch.repository))