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