/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
34
1551.12.45 by Aaron Bentley
Change format marker to not experimental
35
OUTPUT2 = """# Bazaar merge directive format 1
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
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
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
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
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
68
class TestMergeDirective(tests.TestCase):
69
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
70
    def test_merge_source(self):
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
71
        time = 500.0
72
        timezone = 5
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')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
78
        merge_directive.MergeDirective('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
79
            'http://example.com', source_branch='http://example.org')
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
80
        md = merge_directive.MergeDirective('null:', 'sha', time, timezone,
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
81
            'http://example.com', patch='blah', patch_type='bundle')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
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 = 5
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
91
        self.assertRaises(errors.PatchMissing, merge_directive.MergeDirective,
1551.12.6 by Aaron Bentley
Force times to be floats
92
            'example:', 'sha', time, timezone, 'http://example.com',
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
93
            patch_type='bundle')
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
94
        md = merge_directive.MergeDirective('example:', 'sha1', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
95
            'http://example.com', source_branch="http://example.org",
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
96
            patch='', patch_type='diff')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
97
        self.assertEqual(md.patch, '')
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
98
99
    def test_serialization(self):
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
100
        time = 501
101
        timezone = 72
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
102
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
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
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
110
    def test_deserialize_junk(self):
111
        self.assertRaises(errors.NotAMergeDirective,
112
                          merge_directive.MergeDirective.from_lines, 'lala')
113
1551.12.59 by Aaron Bentley
Correctly handle empty merge directive texts
114
    def test_deserialize_empty(self):
115
        self.assertRaises(errors.NotAMergeDirective,
116
                          merge_directive.MergeDirective.from_lines, [])
117
1551.12.51 by Aaron Bentley
Allow leading junk before merge directive header
118
    def test_deserialize_leading_junk(self):
119
        md = merge_directive.MergeDirective.from_lines(INPUT1)
120
        self.assertEqual('example:', md.revision_id)
121
        self.assertEqual('sha', md.testament_sha1)
122
        self.assertEqual('http://example.com', md.target_branch)
123
        self.assertEqual('http://example.org', md.source_branch)
124
        self.assertEqual(501, md.time)
125
        self.assertEqual(72, md.timezone)
126
        self.assertEqual('booga', md.patch)
127
        self.assertEqual('diff', md.patch_type)
128
        self.assertEqual('Hi mom!', md.message)
1551.12.49 by Aaron Bentley
Proper error when deserializing junk
129
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
130
    def test_roundtrip(self):
131
        time = 501
132
        timezone = 72
133
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
134
            'http://example.com', source_branch="http://example.org",
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
135
            patch='booga', patch_type='diff')
136
        md2 = merge_directive.MergeDirective.from_lines(md.to_lines())
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
137
        self.assertEqual('example:', md2.revision_id)
1551.12.54 by Aaron Bentley
Decoded revision ids are utf-8
138
        self.assertIsInstance(md2.revision_id, str)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
139
        self.assertEqual('sha', md2.testament_sha1)
1551.12.13 by Aaron Bentley
Rename fields
140
        self.assertEqual('http://example.com', md2.target_branch)
141
        self.assertEqual('http://example.org', md2.source_branch)
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
142
        self.assertEqual(time, md2.time)
143
        self.assertEqual(timezone, md2.timezone)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
144
        self.assertEqual('diff', md2.patch_type)
145
        self.assertEqual('booga', md2.patch)
1551.12.26 by Aaron Bentley
Get email working, with optional message
146
        self.assertEqual(None, md2.message)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
147
        md.patch = "# Bazaar revision bundle v0.9\n#\n"
1551.12.26 by Aaron Bentley
Get email working, with optional message
148
        md.message = "Hi mom!"
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
149
        md3 = merge_directive.MergeDirective.from_lines(md.to_lines())
150
        self.assertEqual("# Bazaar revision bundle v0.9\n#\n", md3.patch)
151
        self.assertEqual("bundle", md3.patch_type)
1551.12.12 by Aaron Bentley
Add format header
152
        self.assertContainsRe(md3.to_lines()[0],
153
            '^# Bazaar merge directive format ')
1551.12.26 by Aaron Bentley
Get email working, with optional message
154
        self.assertEqual("Hi mom!", md3.message)
1551.12.53 by Aaron Bentley
Fix deserialization of merge directives with no patch
155
        md3.patch_type = None
156
        md3.patch = None
157
        md4 = merge_directive.MergeDirective.from_lines(md3.to_lines())
158
        self.assertIs(None, md4.patch_type)
1551.12.26 by Aaron Bentley
Get email working, with optional message
159
160
161
EMAIL1 = """To: pqm@example.com
162
From: J. Random Hacker <jrandom@example.com>
163
Subject: Commit of rev2a
164
1551.12.45 by Aaron Bentley
Change format marker to not experimental
165
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
166
# revision_id: rev2a
167
# target_branch: (.|\n)*
168
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
169
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
170
# source_branch: (.|\n)*
171
"""
172
173
174
EMAIL2 = """To: pqm@example.com
175
From: J. Random Hacker <jrandom@example.com>
176
Subject: Commit of rev2a with special message
177
1551.12.45 by Aaron Bentley
Change format marker to not experimental
178
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
179
# revision_id: rev2a
180
# target_branch: (.|\n)*
181
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
182
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
183
# source_branch: (.|\n)*
184
# message: Commit of rev2a with special message
185
"""
1551.12.4 by Aaron Bentley
Add failing test
186
187
188
class TestMergeDirectiveBranch(tests.TestCaseWithTransport):
189
1551.12.26 by Aaron Bentley
Get email working, with optional message
190
    def make_trees(self):
1551.12.4 by Aaron Bentley
Add failing test
191
        tree_a = self.make_branch_and_tree('tree_a')
1551.12.26 by Aaron Bentley
Get email working, with optional message
192
        tree_a.branch.get_config().set_user_option('email',
193
            'J. Random Hacker <jrandom@example.com>')
1551.12.4 by Aaron Bentley
Add failing test
194
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_b\n')])
195
        tree_a.add('file')
196
        tree_a.commit('message', rev_id='rev1')
197
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
198
        branch_c = tree_a.bzrdir.sprout('branch_c').open_branch()
1551.12.4 by Aaron Bentley
Add failing test
199
        tree_b.commit('message', rev_id='rev2b')
200
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_c\n')])
1551.12.26 by Aaron Bentley
Get email working, with optional message
201
        tree_a.commit('Commit of rev2a', rev_id='rev2a')
202
        return tree_a, tree_b, branch_c
203
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
204
    def test_generate_patch(self):
205
        tree_a, tree_b, branch_c = self.make_trees()
206
        md2 = merge_directive.MergeDirective.from_objects(
207
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
208
            patch_type='diff', public_branch=tree_a.branch.base)
209
        self.assertNotContainsRe(md2.patch, 'Bazaar revision bundle')
210
        self.assertContainsRe(md2.patch, '\\+content_c')
211
        self.assertNotContainsRe(md2.patch, '\\+\\+\\+ b/')
212
        self.assertContainsRe(md2.patch, '\\+\\+\\+ file')
213
214
    def test_public_branch(self):
1551.12.26 by Aaron Bentley
Get email working, with optional message
215
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
216
        self.assertRaises(errors.PublicBranchOutOfDate,
217
            merge_directive.MergeDirective.from_objects,
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
218
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.34 by Aaron Bentley
Check public branch only if not using a bundle
219
            public_branch=branch_c.base, patch_type='diff')
220
        # public branch is not checked if patch format is bundle.
221
        md1 = merge_directive.MergeDirective.from_objects(
222
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.33 by Aaron Bentley
Take public_branch as a string, not object
223
            public_branch=branch_c.base)
1551.12.34 by Aaron Bentley
Check public branch only if not using a bundle
224
        # public branch is provided with a bundle, despite possibly being out
225
        # of date, because it's not required if a bundle is present.
226
        self.assertEqual(md1.source_branch, branch_c.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
227
        # Once we update the public branch, we can generate a diff.
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
228
        branch_c.pull(tree_a.branch)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
229
        md3 = merge_directive.MergeDirective.from_objects(
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
230
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
231
            patch_type=None, public_branch=branch_c.base)
232
1551.12.50 by Aaron Bentley
Use public location of submit branch if possible
233
    def test_use_public_submit_branch(self):
234
        tree_a, tree_b, branch_c = self.make_trees()
235
        branch_c.pull(tree_a.branch)
236
        md = merge_directive.MergeDirective.from_objects(
237
             tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
238
             patch_type=None, public_branch=branch_c.base)
239
        self.assertEqual(md.target_branch, tree_b.branch.base)
240
        tree_b.branch.set_public_branch('http://example.com')
241
        md2 = merge_directive.MergeDirective.from_objects(
242
              tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
243
              patch_type=None, public_branch=branch_c.base)
244
        self.assertEqual(md2.target_branch, 'http://example.com')
245
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
246
    def test_message(self):
247
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
248
        md3 = merge_directive.MergeDirective.from_objects(
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
249
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.33 by Aaron Bentley
Take public_branch as a string, not object
250
            patch_type=None, public_branch=branch_c.base,
251
            message='Merge message')
1551.12.7 by Aaron Bentley
Fix use of public location/branch
252
        md3.to_lines()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
253
        self.assertIs(None, md3.patch)
1551.12.27 by Aaron Bentley
support custom message everywhere
254
        self.assertEqual('Merge message', md3.message)
1551.12.16 by Aaron Bentley
Enable signing merge directives
255
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
256
    def test_generate_bundle(self):
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
257
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
258
        md1 = merge_directive.MergeDirective.from_objects(
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
259
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
260
            public_branch=branch_c.base)
261
        self.assertContainsRe(md1.patch, 'Bazaar revision bundle')
262
        self.assertContainsRe(md1.patch, '\\+content_c')
263
        self.assertNotContainsRe(md1.patch, '\\+content_a')
264
        self.assertContainsRe(md1.patch, '\\+content_c')
265
        self.assertNotContainsRe(md1.patch, '\\+content_a')
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
266
1551.12.16 by Aaron Bentley
Enable signing merge directives
267
    def test_signing(self):
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
268
        time = 501
269
        timezone = 72
1551.12.16 by Aaron Bentley
Enable signing merge directives
270
        class FakeBranch(object):
271
            def get_config(self):
272
                return self
273
            def gpg_signing_command(self):
274
                return 'loopback'
275
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
276
            'http://example.com', source_branch="http://example.org",
277
            patch='booga', patch_type='diff')
278
        old_strategy = gpg.GPGStrategy
279
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
280
        try:
281
            signed = md.to_signed(FakeBranch())
282
        finally:
283
            gpg.GPGStrategy = old_strategy
284
        self.assertContainsRe(signed, '^-----BEGIN PSEUDO-SIGNED CONTENT')
285
        self.assertContainsRe(signed, 'example.org')
286
        self.assertContainsRe(signed, 'booga')
1551.12.26 by Aaron Bentley
Get email working, with optional message
287
288
    def test_email(self):
289
        tree_a, tree_b, branch_c = self.make_trees()
290
        md = merge_directive.MergeDirective.from_objects(
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
291
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
1551.12.33 by Aaron Bentley
Take public_branch as a string, not object
292
            patch_type=None, public_branch=tree_a.branch.base)
1551.12.26 by Aaron Bentley
Get email working, with optional message
293
        message = md.to_email('pqm@example.com', tree_a.branch)
294
        self.assertContainsRe(message.as_string(), EMAIL1)
295
        md.message = 'Commit of rev2a with special message'
296
        message = md.to_email('pqm@example.com', tree_a.branch)
297
        self.assertContainsRe(message.as_string(), EMAIL2)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
298
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
299
    def test_install_revisions_branch(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
300
        tree_a, tree_b, branch_c = self.make_trees()
301
        md = merge_directive.MergeDirective.from_objects(
302
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
303
            patch_type=None, public_branch=tree_a.branch.base)
304
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
305
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
306
        self.assertEqual('rev2a', revision)
307
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
308
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
309
    def test_install_revisions_bundle(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
310
        tree_a, tree_b, branch_c = self.make_trees()
311
        md = merge_directive.MergeDirective.from_objects(
312
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
313
            patch_type='bundle', public_branch=tree_a.branch.base)
314
        self.assertFalse(tree_b.branch.repository.has_revision('rev2a'))
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
315
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
316
        self.assertEqual('rev2a', revision)
317
        self.assertTrue(tree_b.branch.repository.has_revision('rev2a'))
318
319
    def test_get_target_revision_nofetch(self):
320
        tree_a, tree_b, branch_c = self.make_trees()
321
        tree_b.branch.fetch(tree_a.branch)
322
        md = merge_directive.MergeDirective.from_objects(
323
            tree_a.branch.repository, 'rev2a', 500, 36, tree_b.branch.base,
324
            patch_type=None, public_branch=tree_a.branch.base)
325
        md.source_branch = '/dev/null'
1551.14.9 by Aaron Bentley
rename get_target_revision to install_revisions
326
        revision = md.install_revisions(tree_b.branch.repository)
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
327
        self.assertEqual('rev2a', revision)