]>
Commit | Line | Data |
---|---|---|
6e87ae1c | 1 | # -*- coding: utf-8 -*- |
83d290c5 | 2 | # SPDX-License-Identifier: GPL-2.0+ |
6e87ae1c SG |
3 | # |
4 | # Copyright 2017 Google, Inc | |
5 | # | |
6e87ae1c SG |
6 | |
7 | import contextlib | |
8 | import os | |
9 | import re | |
10 | import shutil | |
11 | import sys | |
12 | import tempfile | |
13 | import unittest | |
14 | ||
15 | import gitutil | |
16 | import patchstream | |
17 | import settings | |
18 | ||
19 | ||
20 | @contextlib.contextmanager | |
21 | def capture(): | |
22 | import sys | |
23 | from cStringIO import StringIO | |
24 | oldout,olderr = sys.stdout, sys.stderr | |
25 | try: | |
26 | out=[StringIO(), StringIO()] | |
27 | sys.stdout,sys.stderr = out | |
28 | yield out | |
29 | finally: | |
30 | sys.stdout,sys.stderr = oldout, olderr | |
31 | out[0] = out[0].getvalue() | |
32 | out[1] = out[1].getvalue() | |
33 | ||
34 | ||
35 | class TestFunctional(unittest.TestCase): | |
36 | def setUp(self): | |
37 | self.tmpdir = tempfile.mkdtemp(prefix='patman.') | |
38 | ||
39 | def tearDown(self): | |
40 | shutil.rmtree(self.tmpdir) | |
41 | ||
42 | @staticmethod | |
43 | def GetPath(fname): | |
44 | return os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), | |
45 | 'test', fname) | |
46 | ||
47 | @classmethod | |
48 | def GetText(self, fname): | |
49 | return open(self.GetPath(fname)).read() | |
50 | ||
51 | @classmethod | |
52 | def GetPatchName(self, subject): | |
53 | fname = re.sub('[ :]', '-', subject) | |
54 | return fname.replace('--', '-') | |
55 | ||
56 | def CreatePatchesForTest(self, series): | |
57 | cover_fname = None | |
58 | fname_list = [] | |
59 | for i, commit in enumerate(series.commits): | |
60 | clean_subject = self.GetPatchName(commit.subject) | |
61 | src_fname = '%04d-%s.patch' % (i + 1, clean_subject[:52]) | |
62 | fname = os.path.join(self.tmpdir, src_fname) | |
63 | shutil.copy(self.GetPath(src_fname), fname) | |
64 | fname_list.append(fname) | |
65 | if series.get('cover'): | |
66 | src_fname = '0000-cover-letter.patch' | |
67 | cover_fname = os.path.join(self.tmpdir, src_fname) | |
68 | fname = os.path.join(self.tmpdir, src_fname) | |
69 | shutil.copy(self.GetPath(src_fname), fname) | |
70 | ||
71 | return cover_fname, fname_list | |
72 | ||
73 | def testBasic(self): | |
74 | """Tests the basic flow of patman | |
75 | ||
76 | This creates a series from some hard-coded patches build from a simple | |
77 | tree with the following metadata in the top commit: | |
78 | ||
79 | Series-to: u-boot | |
80 | Series-prefix: RFC | |
81 | Series-cc: Stefan Brüns <[email protected]> | |
82 | Cover-letter-cc: Lord Mëlchett <[email protected]> | |
83 | Series-version: 2 | |
84 | Series-changes: 4 | |
85 | - Some changes | |
86 | ||
87 | Cover-letter: | |
88 | test: A test patch series | |
89 | This is a test of how the cover | |
90 | leter | |
91 | works | |
92 | END | |
93 | ||
94 | and this in the first commit: | |
95 | ||
96 | Series-notes: | |
97 | some notes | |
98 | about some things | |
99 | from the first commit | |
100 | END | |
101 | ||
102 | Commit-notes: | |
103 | Some notes about | |
104 | the first commit | |
105 | END | |
106 | ||
107 | with the following commands: | |
108 | ||
109 | git log -n2 --reverse >/path/to/tools/patman/test/test01.txt | |
110 | git format-patch --subject-prefix RFC --cover-letter HEAD~2 | |
111 | mv 00* /path/to/tools/patman/test | |
112 | ||
113 | It checks these aspects: | |
114 | - git log can be processed by patchstream | |
115 | - emailing patches uses the correct command | |
116 | - CC file has information on each commit | |
117 | - cover letter has the expected text and subject | |
118 | - each patch has the correct subject | |
119 | - dry-run information prints out correctly | |
120 | - unicode is handled correctly | |
121 | - Series-to, Series-cc, Series-prefix, Cover-letter | |
122 | - Cover-letter-cc, Series-version, Series-changes, Series-notes | |
123 | - Commit-notes | |
124 | """ | |
125 | process_tags = True | |
126 | ignore_bad_tags = True | |
127 | stefan = u'Stefan Brüns <[email protected]>' | |
128 | rick = 'Richard III <[email protected]>' | |
129 | mel = u'Lord Mëlchett <[email protected]>' | |
130 | ed = u'Lond Edmund Blackaddër <[email protected]' | |
131 | fred = 'Fred Bloggs <[email protected]>' | |
132 | add_maintainers = [stefan, rick] | |
133 | dry_run = True | |
134 | in_reply_to = mel | |
135 | count = 2 | |
136 | settings.alias = { | |
137 | 'fdt': ['simon'], | |
138 | 'u-boot': ['[email protected]'], | |
139 | 'simon': [ed], | |
140 | 'fred': [fred], | |
141 | } | |
142 | ||
143 | text = self.GetText('test01.txt') | |
144 | series = patchstream.GetMetaDataForTest(text) | |
145 | cover_fname, args = self.CreatePatchesForTest(series) | |
146 | with capture() as out: | |
147 | patchstream.FixPatches(series, args) | |
148 | if cover_fname and series.get('cover'): | |
149 | patchstream.InsertCoverLetter(cover_fname, series, count) | |
150 | series.DoChecks() | |
151 | cc_file = series.MakeCcFile(process_tags, cover_fname, | |
4fb35029 CP |
152 | not ignore_bad_tags, add_maintainers, |
153 | None) | |
6e87ae1c SG |
154 | cmd = gitutil.EmailPatches(series, cover_fname, args, |
155 | dry_run, not ignore_bad_tags, cc_file, | |
156 | in_reply_to=in_reply_to, thread=None) | |
157 | series.ShowActions(args, cmd, process_tags) | |
158 | cc_lines = open(cc_file).read().splitlines() | |
159 | os.remove(cc_file) | |
160 | ||
161 | lines = out[0].splitlines() | |
162 | #print '\n'.join(lines) | |
163 | self.assertEqual('Cleaned %s patches' % len(series.commits), lines[0]) | |
164 | self.assertEqual('Change log missing for v2', lines[1]) | |
165 | self.assertEqual('Change log missing for v3', lines[2]) | |
166 | self.assertEqual('Change log for unknown version v4', lines[3]) | |
167 | self.assertEqual("Alias 'pci' not found", lines[4]) | |
168 | self.assertIn('Dry run', lines[5]) | |
169 | self.assertIn('Send a total of %d patches' % count, lines[7]) | |
170 | line = 8 | |
171 | for i, commit in enumerate(series.commits): | |
172 | self.assertEqual(' %s' % args[i], lines[line + 0]) | |
173 | line += 1 | |
174 | while 'Cc:' in lines[line]: | |
175 | line += 1 | |
176 | self.assertEqual('To: [email protected]', lines[line]) | |
177 | self.assertEqual('Cc: %s' % stefan.encode('utf-8'), lines[line + 1]) | |
178 | self.assertEqual('Version: 3', lines[line + 2]) | |
179 | self.assertEqual('Prefix:\t RFC', lines[line + 3]) | |
180 | self.assertEqual('Cover: 4 lines', lines[line + 4]) | |
181 | line += 5 | |
182 | self.assertEqual(' Cc: %s' % mel.encode('utf-8'), lines[line + 0]) | |
183 | self.assertEqual(' Cc: %s' % rick, lines[line + 1]) | |
184 | self.assertEqual(' Cc: %s' % fred, lines[line + 2]) | |
185 | self.assertEqual(' Cc: %s' % ed.encode('utf-8'), lines[line + 3]) | |
186 | expected = ('Git command: git send-email --annotate ' | |
187 | '--in-reply-to="%s" --to "[email protected]" ' | |
188 | '--cc "%s" --cc-cmd "%s --cc-cmd %s" %s %s' | |
189 | % (in_reply_to, stefan, sys.argv[0], cc_file, cover_fname, | |
190 | ' '.join(args))).encode('utf-8') | |
191 | line += 4 | |
192 | self.assertEqual(expected, lines[line]) | |
193 | ||
194 | self.assertEqual(('%s %s, %s' % (args[0], rick, stefan)) | |
195 | .encode('utf-8'), cc_lines[0]) | |
196 | self.assertEqual(('%s %s, %s, %s, %s' % (args[1], fred, rick, stefan, | |
197 | ed)).encode('utf-8'), cc_lines[1]) | |
198 | ||
199 | expected = ''' | |
200 | This is a test of how the cover | |
201 | leter | |
202 | works | |
203 | ||
204 | some notes | |
205 | about some things | |
206 | from the first commit | |
207 | ||
208 | Changes in v4: | |
209 | - Some changes | |
210 | ||
211 | Simon Glass (2): | |
212 | pci: Correct cast for sandbox | |
12308b12 | 213 | fdt: Correct cast for sandbox in fdtdec_setup_mem_size_base() |
6e87ae1c SG |
214 | |
215 | cmd/pci.c | 3 ++- | |
216 | fs/fat/fat.c | 1 + | |
217 | lib/efi_loader/efi_memory.c | 1 + | |
218 | lib/fdtdec.c | 3 ++- | |
219 | 4 files changed, 6 insertions(+), 2 deletions(-) | |
220 | ||
221 | --\x20 | |
222 | 2.7.4 | |
223 | ||
224 | ''' | |
225 | lines = open(cover_fname).read().splitlines() | |
226 | #print '\n'.join(lines) | |
227 | self.assertEqual( | |
228 | 'Subject: [RFC PATCH v3 0/2] test: A test patch series', | |
229 | lines[3]) | |
230 | self.assertEqual(expected.splitlines(), lines[7:]) | |
231 | ||
232 | for i, fname in enumerate(args): | |
233 | lines = open(fname).read().splitlines() | |
234 | #print '\n'.join(lines) | |
235 | subject = [line for line in lines if line.startswith('Subject')] | |
236 | self.assertEqual('Subject: [RFC %d/%d]' % (i + 1, count), | |
237 | subject[0][:18]) | |
238 | if i == 0: | |
239 | # Check that we got our commit notes | |
240 | self.assertEqual('---', lines[17]) | |
241 | self.assertEqual('Some notes about', lines[18]) | |
242 | self.assertEqual('the first commit', lines[19]) |