~bzr-pqm/bzr/bzr.dev

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.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
46
class TestMergeDirective(tests.TestCase):
47
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
48
    def test_merge_source(self):
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
49
        time = 500.0
50
        timezone = 5
51
        self.assertRaises(errors.NoMergeSource, merge_directive.MergeDirective,
52
            'example:', 'sha', time, timezone, 'http://example.com')
53
        self.assertRaises(errors.NoMergeSource, merge_directive.MergeDirective,
54
            'example:', 'sha', time, timezone, 'http://example.com',
55
            patch_type='diff')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
56
        merge_directive.MergeDirective('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
57
            'http://example.com', source_branch='http://example.org')
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
58
        md = merge_directive.MergeDirective('null:', 'sha', time, timezone,
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
59
            'http://example.com', patch='blah', patch_type='bundle')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
60
        self.assertIs(None, md.source_branch)
61
        md2 = merge_directive.MergeDirective('null:', 'sha', time, timezone,
62
            'http://example.com', patch='blah', patch_type='bundle',
63
            source_branch='bar')
64
        self.assertEqual('bar', md2.source_branch)
65
66
    def test_require_patch(self):
67
        time = 500.0
68
        timezone = 5
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
69
        self.assertRaises(errors.PatchMissing, merge_directive.MergeDirective,
1551.12.6 by Aaron Bentley
Force times to be floats
70
            'example:', 'sha', time, timezone, 'http://example.com',
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
71
            patch_type='bundle')
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
72
        md = merge_directive.MergeDirective('example:', 'sha1', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
73
            'http://example.com', source_branch="http://example.org",
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
74
            patch='', patch_type='diff')
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
75
        self.assertEqual(md.patch, '')
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
76
77
    def test_serialization(self):
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
78
        time = 501
79
        timezone = 72
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
80
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
81
            'http://example.com', patch='booga', patch_type='bundle')
82
        self.assertEqualDiff(OUTPUT1, ''.join(md.to_lines()))
83
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
84
            'http://example.com', source_branch="http://example.org",
85
            patch='booga', patch_type='diff', message="Hi mom!")
86
        self.assertEqualDiff(OUTPUT2, ''.join(md.to_lines()))
87
88
    def test_roundtrip(self):
89
        time = 501
90
        timezone = 72
91
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
1551.12.13 by Aaron Bentley
Rename fields
92
            'http://example.com', source_branch="http://example.org",
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
93
            patch='booga', patch_type='diff')
94
        md2 = merge_directive.MergeDirective.from_lines(md.to_lines())
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
95
        self.assertEqual('example:', md2.revision_id)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
96
        self.assertEqual('sha', md2.testament_sha1)
1551.12.13 by Aaron Bentley
Rename fields
97
        self.assertEqual('http://example.com', md2.target_branch)
98
        self.assertEqual('http://example.org', md2.source_branch)
1551.12.3 by Aaron Bentley
Add timestamps to merge directives
99
        self.assertEqual(time, md2.time)
100
        self.assertEqual(timezone, md2.timezone)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
101
        self.assertEqual('diff', md2.patch_type)
102
        self.assertEqual('booga', md2.patch)
1551.12.26 by Aaron Bentley
Get email working, with optional message
103
        self.assertEqual(None, md2.message)
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
104
        md.patch = "# Bazaar revision bundle v0.9\n#\n"
1551.12.26 by Aaron Bentley
Get email working, with optional message
105
        md.message = "Hi mom!"
1551.12.2 by Aaron Bentley
Got directives round-tripping, with bundles and everything
106
        md3 = merge_directive.MergeDirective.from_lines(md.to_lines())
107
        self.assertEqual("# Bazaar revision bundle v0.9\n#\n", md3.patch)
108
        self.assertEqual("bundle", md3.patch_type)
1551.12.12 by Aaron Bentley
Add format header
109
        self.assertContainsRe(md3.to_lines()[0],
110
            '^# Bazaar merge directive format ')
1551.12.26 by Aaron Bentley
Get email working, with optional message
111
        self.assertEqual("Hi mom!", md3.message)
112
113
114
EMAIL1 = """To: pqm@example.com
115
From: J. Random Hacker <jrandom@example.com>
116
Subject: Commit of rev2a
117
1551.12.45 by Aaron Bentley
Change format marker to not experimental
118
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
119
# revision_id: rev2a
120
# target_branch: (.|\n)*
121
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
122
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
123
# source_branch: (.|\n)*
124
"""
125
126
127
EMAIL2 = """To: pqm@example.com
128
From: J. Random Hacker <jrandom@example.com>
129
Subject: Commit of rev2a with special message
130
1551.12.45 by Aaron Bentley
Change format marker to not experimental
131
# Bazaar merge directive format 1
1551.12.26 by Aaron Bentley
Get email working, with optional message
132
# revision_id: rev2a
133
# target_branch: (.|\n)*
134
# testament_sha1: .*
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
135
# timestamp: 1970-01-01 00:08:56 \\+0001
1551.12.26 by Aaron Bentley
Get email working, with optional message
136
# source_branch: (.|\n)*
137
# message: Commit of rev2a with special message
138
"""
1551.12.4 by Aaron Bentley
Add failing test
139
140
141
class TestMergeDirectiveBranch(tests.TestCaseWithTransport):
142
1551.12.26 by Aaron Bentley
Get email working, with optional message
143
    def make_trees(self):
1551.12.4 by Aaron Bentley
Add failing test
144
        tree_a = self.make_branch_and_tree('tree_a')
1551.12.26 by Aaron Bentley
Get email working, with optional message
145
        tree_a.branch.get_config().set_user_option('email',
146
            'J. Random Hacker <jrandom@example.com>')
1551.12.4 by Aaron Bentley
Add failing test
147
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_b\n')])
148
        tree_a.add('file')
149
        tree_a.commit('message', rev_id='rev1')
150
        tree_b = tree_a.bzrdir.sprout('tree_b').open_workingtree()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
151
        branch_c = tree_a.bzrdir.sprout('branch_c').open_branch()
1551.12.4 by Aaron Bentley
Add failing test
152
        tree_b.commit('message', rev_id='rev2b')
153
        self.build_tree_contents([('tree_a/file', 'content_a\ncontent_c\n')])
1551.12.26 by Aaron Bentley
Get email working, with optional message
154
        tree_a.commit('Commit of rev2a', rev_id='rev2a')
155
        return tree_a, tree_b, branch_c
156
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
157
    def test_generate_patch(self):
158
        tree_a, tree_b, branch_c = self.make_trees()
159
        md2 = merge_directive.MergeDirective.from_objects(
160
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
161
            patch_type='diff', public_branch=tree_a.branch.base)
162
        self.assertNotContainsRe(md2.patch, 'Bazaar revision bundle')
163
        self.assertContainsRe(md2.patch, '\\+content_c')
164
        self.assertNotContainsRe(md2.patch, '\\+\\+\\+ b/')
165
        self.assertContainsRe(md2.patch, '\\+\\+\\+ file')
166
167
    def test_public_branch(self):
1551.12.26 by Aaron Bentley
Get email working, with optional message
168
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
169
        self.assertRaises(errors.PublicBranchOutOfDate,
170
            merge_directive.MergeDirective.from_objects,
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
171
            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
172
            public_branch=branch_c.base, patch_type='diff')
173
        # public branch is not checked if patch format is bundle.
174
        md1 = merge_directive.MergeDirective.from_objects(
175
            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
176
            public_branch=branch_c.base)
1551.12.34 by Aaron Bentley
Check public branch only if not using a bundle
177
        # public branch is provided with a bundle, despite possibly being out
178
        # of date, because it's not required if a bundle is present.
179
        self.assertEqual(md1.source_branch, branch_c.base)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
180
        # Once we update the public branch, we can generate a diff.
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
181
        branch_c.pull(tree_a.branch)
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
182
        md3 = merge_directive.MergeDirective.from_objects(
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
183
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
184
            patch_type=None, public_branch=branch_c.base)
185
186
    def test_message(self):
187
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
188
        md3 = merge_directive.MergeDirective.from_objects(
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
189
            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
190
            patch_type=None, public_branch=branch_c.base,
191
            message='Merge message')
1551.12.7 by Aaron Bentley
Fix use of public location/branch
192
        md3.to_lines()
1551.12.5 by Aaron Bentley
Get MergeDirective.from_objects working
193
        self.assertIs(None, md3.patch)
1551.12.27 by Aaron Bentley
support custom message everywhere
194
        self.assertEqual('Merge message', md3.message)
1551.12.16 by Aaron Bentley
Enable signing merge directives
195
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
196
    def test_generate_bundle(self):
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
197
        tree_a, tree_b, branch_c = self.make_trees()
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
198
        md1 = merge_directive.MergeDirective.from_objects(
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
199
            tree_a.branch.repository, 'rev2a', 500, 144, tree_b.branch.base,
1551.12.41 by Aaron Bentley
Clean up tests, add serialization text test
200
            public_branch=branch_c.base)
201
        self.assertContainsRe(md1.patch, 'Bazaar revision bundle')
202
        self.assertContainsRe(md1.patch, '\\+content_c')
203
        self.assertNotContainsRe(md1.patch, '\\+content_a')
204
        self.assertContainsRe(md1.patch, '\\+content_c')
205
        self.assertNotContainsRe(md1.patch, '\\+content_a')
1551.12.40 by Aaron Bentley
Do not show prefixes in diffs
206
1551.12.16 by Aaron Bentley
Enable signing merge directives
207
    def test_signing(self):
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
208
        time = 501
209
        timezone = 72
1551.12.16 by Aaron Bentley
Enable signing merge directives
210
        class FakeBranch(object):
211
            def get_config(self):
212
                return self
213
            def gpg_signing_command(self):
214
                return 'loopback'
215
        md = merge_directive.MergeDirective('example:', 'sha', time, timezone,
216
            'http://example.com', source_branch="http://example.org",
217
            patch='booga', patch_type='diff')
218
        old_strategy = gpg.GPGStrategy
219
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
220
        try:
221
            signed = md.to_signed(FakeBranch())
222
        finally:
223
            gpg.GPGStrategy = old_strategy
224
        self.assertContainsRe(signed, '^-----BEGIN PSEUDO-SIGNED CONTENT')
225
        self.assertContainsRe(signed, 'example.org')
226
        self.assertContainsRe(signed, 'booga')
1551.12.26 by Aaron Bentley
Get email working, with optional message
227
228
    def test_email(self):
229
        tree_a, tree_b, branch_c = self.make_trees()
230
        md = merge_directive.MergeDirective.from_objects(
1551.12.30 by Aaron Bentley
Use patch-style dates for timestamps in merge directives
231
            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
232
            patch_type=None, public_branch=tree_a.branch.base)
1551.12.26 by Aaron Bentley
Get email working, with optional message
233
        message = md.to_email('pqm@example.com', tree_a.branch)
234
        self.assertContainsRe(message.as_string(), EMAIL1)
235
        md.message = 'Commit of rev2a with special message'
236
        message = md.to_email('pqm@example.com', tree_a.branch)
237
        self.assertContainsRe(message.as_string(), EMAIL2)