~bzr-pqm/bzr/bzr.dev

1551.12.14 by Aaron Bentley
Get merge-directive command basically working
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
import os
1551.12.42 by Aaron Bentley
Clean up blackbox tests
18
import smtplib
1551.12.16 by Aaron Bentley
Enable signing merge directives
19
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
20
from bzrlib import (
21
    gpg,
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
22
    merge_directive,
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
23
    tests,
24
    workingtree,
25
    )
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
26
1551.12.26 by Aaron Bentley
Get email working, with optional message
27
2625.6.1 by Adeodato Simó
New EmailMessage class, façade around email.Message and MIMEMultipart.
28
EMAIL1 = """From: "J. Random Hacker" <jrandom@example.com>
1551.12.26 by Aaron Bentley
Get email working, with optional message
29
Subject: bar
2625.6.1 by Adeodato Simó
New EmailMessage class, façade around email.Message and MIMEMultipart.
30
To: pqm@example.com
31
User-Agent: Bazaar \(.*\)
1551.12.26 by Aaron Bentley
Get email working, with optional message
32
2687.2.2 by Martin Pool
Fix up other references to 0.19
33
# Bazaar merge directive format 2 \\(Bazaar 0.90\\)
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
34
# revision_id: bar-id
1551.12.26 by Aaron Bentley
Get email working, with optional message
35
# target_branch: ../tree2
36
# testament_sha1: .*
37
# timestamp: .*
1551.12.33 by Aaron Bentley
Take public_branch as a string, not object
38
# source_branch: .
1551.12.26 by Aaron Bentley
Get email working, with optional message
39
#"""
40
41
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
42
class TestMergeDirective(tests.TestCaseWithTransport):
43
1551.12.42 by Aaron Bentley
Clean up blackbox tests
44
    def prepare_merge_directive(self):
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
45
        self.tree1 = self.make_branch_and_tree('tree1')
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
46
        self.build_tree_contents([('tree1/file', 'a\nb\nc\nd\n')])
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
47
        self.tree1.branch.get_config().set_user_option('email',
1551.12.26 by Aaron Bentley
Get email working, with optional message
48
            'J. Random Hacker <jrandom@example.com>')
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
49
        self.tree1.add('file')
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
50
        self.tree1.commit('foo', rev_id='foo-id')
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
51
        self.tree2 = self.tree1.bzrdir.sprout('tree2').open_workingtree()
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
52
        self.build_tree_contents([('tree1/file', 'a\nb\nc\nd\ne\n')])
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
53
        self.tree1.commit('bar', rev_id='bar-id')
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
54
        os.chdir('tree1')
1551.14.7 by Aaron Bentley
test suite fixes
55
        return self.tree1, self.tree2
1551.12.42 by Aaron Bentley
Clean up blackbox tests
56
57
    def test_merge_directive(self):
58
        self.prepare_merge_directive()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
59
        md_text = self.run_bzr('merge-directive ../tree2')[0]
1551.12.42 by Aaron Bentley
Clean up blackbox tests
60
        self.assertContainsRe(md_text, "\\+e")
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
61
        md_text = self.run_bzr('merge-directive -r -2 ../tree2')[0]
1551.12.42 by Aaron Bentley
Clean up blackbox tests
62
        self.assertNotContainsRe(md_text, "\\+e")
2520.4.132 by Aaron Bentley
Merge from bzr.dev
63
        md_text = self.run_bzr('merge-directive -r -1..-2 ../tree2')[0]
2520.4.112 by Aaron Bentley
Make cherry-pick merge directives possible
64
        md2 = merge_directive.MergeDirective.from_lines(
65
            md_text.splitlines(True))
66
        self.assertEqual('foo-id', md2.revision_id)
67
        self.assertEqual('bar-id', md2.base_revision_id)
1551.12.42 by Aaron Bentley
Clean up blackbox tests
68
69
    def test_submit_branch(self):
70
        self.prepare_merge_directive()
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
71
        self.run_bzr_error(('No submit branch',), 'merge-directive', retcode=3)
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
72
        self.run_bzr('merge-directive ../tree2')
1551.12.42 by Aaron Bentley
Clean up blackbox tests
73
74
    def test_public_branch(self):
75
        self.prepare_merge_directive()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
76
        self.run_bzr_error(('No public branch',),
77
                           'merge-directive --diff ../tree2', retcode=3)
78
        md_text = self.run_bzr('merge-directive ../tree2')[0]
1551.12.42 by Aaron Bentley
Clean up blackbox tests
79
        self.assertNotContainsRe(md_text, 'source_branch:')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
80
        self.run_bzr('merge-directive --diff ../tree2 .')
81
        self.run_bzr('merge-directive --diff')[0]
1551.12.42 by Aaron Bentley
Clean up blackbox tests
82
        self.assertNotContainsRe(md_text, 'source_branch:')
83
84
    def test_patch_types(self):
85
        self.prepare_merge_directive()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
86
        md_text = self.run_bzr('merge-directive ../tree2')[0]
2520.4.81 by Aaron Bentley
Fix blackbox tests
87
        self.assertContainsRe(md_text, "# Begin bundle")
1551.12.42 by Aaron Bentley
Clean up blackbox tests
88
        self.assertContainsRe(md_text, "\\+e")
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
89
        md_text = self.run_bzr('merge-directive ../tree2 --diff .')[0]
2520.4.81 by Aaron Bentley
Fix blackbox tests
90
        self.assertNotContainsRe(md_text, "# Begin bundle")
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
91
        self.assertContainsRe(md_text, "\\+e")
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
92
        md_text = self.run_bzr('merge-directive --plain')[0]
1551.12.14 by Aaron Bentley
Get merge-directive command basically working
93
        self.assertNotContainsRe(md_text, "\\+e")
1551.12.42 by Aaron Bentley
Clean up blackbox tests
94
95
    def test_message(self):
96
        self.prepare_merge_directive()
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
97
        md_text = self.run_bzr('merge-directive ../tree2')[0]
1551.12.27 by Aaron Bentley
support custom message everywhere
98
        self.assertNotContainsRe(md_text, 'message: Message for merge')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
99
        md_text = self.run_bzr('merge-directive -m Message_for_merge')[0]
100
        self.assertContainsRe(md_text, 'message: Message_for_merge')
1551.12.42 by Aaron Bentley
Clean up blackbox tests
101
102
    def test_signing(self):
103
        self.prepare_merge_directive()
1551.12.16 by Aaron Bentley
Enable signing merge directives
104
        old_strategy = gpg.GPGStrategy
105
        gpg.GPGStrategy = gpg.LoopbackGPGStrategy
106
        try:
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
107
            md_text = self.run_bzr('merge-directive --sign ../tree2')[0]
1551.12.16 by Aaron Bentley
Enable signing merge directives
108
        finally:
109
            gpg.GPGStrategy = old_strategy
110
        self.assertContainsRe(md_text, '^-----BEGIN PSEUDO-SIGNED CONTENT')
1551.12.42 by Aaron Bentley
Clean up blackbox tests
111
1551.12.57 by Aaron Bentley
Ensure server default works, too
112
    def run_bzr_fakemail(self, *args, **kwargs):
1551.12.26 by Aaron Bentley
Get email working, with optional message
113
        sendmail_calls = []
114
        def sendmail(self, from_, to, message):
115
            sendmail_calls.append((self, from_, to, message))
2338.2.1 by Marien Zwart
Make the merge directive tests work if there is no smtpd running on localhost.
116
        connect_calls = []
117
        def connect(self, host='localhost', port=0):
118
            connect_calls.append((self, host, port))
2898.2.3 by James Henstridge
* Fix merge-directive blackbox test.
119
        def has_extn(self, extension):
120
            return False
121
        def ehlo(self):
122
            return (200, 'Ok')
1551.12.26 by Aaron Bentley
Get email working, with optional message
123
        old_sendmail = smtplib.SMTP.sendmail
124
        smtplib.SMTP.sendmail = sendmail
2338.2.1 by Marien Zwart
Make the merge directive tests work if there is no smtpd running on localhost.
125
        old_connect = smtplib.SMTP.connect
126
        smtplib.SMTP.connect = connect
2898.2.3 by James Henstridge
* Fix merge-directive blackbox test.
127
        old_ehlo = smtplib.SMTP.ehlo
128
        smtplib.SMTP.ehlo = ehlo
129
        old_has_extn = smtplib.SMTP.has_extn
130
        smtplib.SMTP.has_extn = has_extn
1551.12.26 by Aaron Bentley
Get email working, with optional message
131
        try:
1551.12.57 by Aaron Bentley
Ensure server default works, too
132
            result = self.run_bzr(*args, **kwargs)
1551.12.26 by Aaron Bentley
Get email working, with optional message
133
        finally:
134
            smtplib.SMTP.sendmail = old_sendmail
2338.2.1 by Marien Zwart
Make the merge directive tests work if there is no smtpd running on localhost.
135
            smtplib.SMTP.connect = old_connect
2898.2.3 by James Henstridge
* Fix merge-directive blackbox test.
136
            smtplib.SMTP.ehlo = old_ehlo
137
            smtplib.SMTP.has_extn = old_has_extn
1551.12.57 by Aaron Bentley
Ensure server default works, too
138
        return result + (connect_calls, sendmail_calls)
139
140
    def test_mail_default(self):
141
        tree1, tree2 = self.prepare_merge_directive()
142
        md_text, errr, connect_calls, sendmail_calls =\
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
143
            self.run_bzr_fakemail(['merge-directive', '--mail-to',
144
                                   'pqm@example.com', '--plain', '../tree2',
145
                                   '.'])
1551.12.26 by Aaron Bentley
Get email working, with optional message
146
        self.assertEqual('', md_text)
2338.2.1 by Marien Zwart
Make the merge directive tests work if there is no smtpd running on localhost.
147
        self.assertEqual(1, len(connect_calls))
148
        call = connect_calls[0]
1551.12.57 by Aaron Bentley
Ensure server default works, too
149
        self.assertEqual(('localhost', 0), call[1:3])
1551.12.26 by Aaron Bentley
Get email working, with optional message
150
        self.assertEqual(1, len(sendmail_calls))
151
        call = sendmail_calls[0]
2535.2.1 by Adeodato Simó
New SMTPConnection class, a reduced version of that in bzr-email.
152
        self.assertEqual(('jrandom@example.com', ['pqm@example.com']),
153
                call[1:3])
1551.12.26 by Aaron Bentley
Get email working, with optional message
154
        self.assertContainsRe(call[3], EMAIL1)
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
155
1551.14.10 by Aaron Bentley
Remove 'manual' from test names
156
    def test_pull_raw(self):
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
157
        self.prepare_merge_directive()
158
        self.tree1.commit('baz', rev_id='baz-id')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
159
        md_text = self.run_bzr(['merge-directive', self.tree2.basedir,
160
                                '-r', '2', self.tree1.basedir, '--plain'])[0]
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
161
        self.build_tree_contents([('../directive', md_text)])
162
        os.chdir('../tree2')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
163
        self.run_bzr('pull ../directive')
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
164
        wt = workingtree.WorkingTree.open('.')
165
        self.assertEqual('bar-id', wt.last_revision())
166
1551.14.10 by Aaron Bentley
Remove 'manual' from test names
167
    def test_pull_user_r(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
168
        """If the user supplies -r, an error is emitted"""
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
169
        self.prepare_merge_directive()
170
        self.tree1.commit('baz', rev_id='baz-id')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
171
        md_text = self.run_bzr(['merge-directive', self.tree2.basedir,
172
                                self.tree1.basedir, '--plain'])[0]
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
173
        self.build_tree_contents([('../directive', md_text)])
174
        os.chdir('../tree2')
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
175
        self.run_bzr_error(
176
            ('Cannot use -r with merge directives or bundles',),
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
177
            'pull -r 2 ../directive')
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
178
1551.14.10 by Aaron Bentley
Remove 'manual' from test names
179
    def test_pull_bundle(self):
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
180
        self.prepare_merge_directive()
181
        self.tree1.commit('baz', rev_id='baz-id')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
182
        md_text = self.run_bzr(['merge-directive', self.tree2.basedir,
183
                                '-r', '2', '/dev/null', '--bundle'])[0]
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
184
        self.build_tree_contents([('../directive', md_text)])
185
        os.chdir('../tree2')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
186
        self.run_bzr('pull ../directive')
1551.14.1 by Aaron Bentley
Allow pull from a merge directive
187
        wt = workingtree.WorkingTree.open('.')
188
        self.assertEqual('bar-id', wt.last_revision())
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
189
1551.14.10 by Aaron Bentley
Remove 'manual' from test names
190
    def test_merge_raw(self):
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
191
        self.prepare_merge_directive()
192
        self.tree1.commit('baz', rev_id='baz-id')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
193
        md_text = self.run_bzr(['merge-directive', self.tree2.basedir,
194
                                '-r', '2', self.tree1.basedir, '--plain'])[0]
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
195
        self.build_tree_contents([('../directive', md_text)])
196
        os.chdir('../tree2')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
197
        self.run_bzr('merge ../directive')
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
198
        wt = workingtree.WorkingTree.open('.')
199
        self.assertEqual('bar-id', wt.get_parent_ids()[1])
200
1551.14.10 by Aaron Bentley
Remove 'manual' from test names
201
    def test_merge_user_r(self):
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
202
        """If the user supplies -r, an error is emitted"""
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
203
        self.prepare_merge_directive()
204
        self.tree1.commit('baz', rev_id='baz-id')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
205
        md_text = self.run_bzr(['merge-directive', self.tree2.basedir,
206
                                self.tree1.basedir, '--plain'])[0]
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
207
        self.build_tree_contents([('../directive', md_text)])
208
        os.chdir('../tree2')
1551.14.4 by Aaron Bentley
Change bundle reader and merge directive to both be 'mergeables'
209
        self.run_bzr_error(
210
            ('Cannot use -r with merge directives or bundles',),
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
211
            'merge -r 2 ../directive')
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
212
1551.14.10 by Aaron Bentley
Remove 'manual' from test names
213
    def test_merge_bundle(self):
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
214
        self.prepare_merge_directive()
215
        self.tree1.commit('baz', rev_id='baz-id')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
216
        md_text = self.run_bzr(['merge-directive', self.tree2.basedir,
217
                               '-r', '2', '/dev/null', '--bundle'])[0]
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
218
        self.build_tree_contents([('../directive', md_text)])
219
        os.chdir('../tree2')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
220
        self.run_bzr('merge ../directive')
1551.14.2 by Aaron Bentley
Support manual merge from merge directives
221
        wt = workingtree.WorkingTree.open('.')
222
        self.assertEqual('bar-id', wt.get_parent_ids()[1])
1551.14.6 by Aaron Bentley
Merge bzr.dev
223
1551.12.57 by Aaron Bentley
Ensure server default works, too
224
    def test_mail_uses_config(self):
225
        tree1, tree2 = self.prepare_merge_directive()
226
        tree1.branch.get_config().set_user_option('smtp_server', 'bogushost')
227
        md_text, errr, connect_calls, sendmail_calls =\
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
228
            self.run_bzr_fakemail('merge-directive --mail-to'
229
                                  ' pqm@example.com --plain ../tree2 .')
1551.12.57 by Aaron Bentley
Ensure server default works, too
230
        call = connect_calls[0]
231
        self.assertEqual(('bogushost', 0), call[1:3])
2490.2.28 by Aaron Bentley
Fix handling of null revision
232
233
    def test_no_common_ancestor(self):
234
        foo = self.make_branch_and_tree('foo')
235
        foo.commit('rev1')
236
        bar = self.make_branch_and_tree('bar')
237
        os.chdir('foo')
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
238
        self.run_bzr('merge-directive ../bar')
2490.2.28 by Aaron Bentley
Fix handling of null revision
239
240
    def test_no_commits(self):
241
        foo = self.make_branch_and_tree('foo')
242
        bar = self.make_branch_and_tree('bar')
243
        os.chdir('foo')
244
        self.run_bzr_error(('No revisions to bundle.', ),
2552.2.3 by Vincent Ladeuil
Deprecate the varargs syntax and fix the tests.
245
                            'merge-directive ../bar')
2552.1.1 by John Arbash Meinel
(Adeodato Simó) fix bug #120591 by using exact encoding for merge directives.
246
2530.2.1 by Adeodato Simó
Add encoding_type = 'exact' to cmd_merge_directive. (LP #120591)
247
    def test_encoding_exact(self):
248
        tree1, tree2 = self.prepare_merge_directive()
249
        tree1.commit(u'messag\xe9')
2581.1.5 by Martin Pool
merge trunk and fix run_bzr call in merge_directive tests
250
        self.run_bzr('merge-directive ../tree2') # no exception raised