]>
Commit | Line | Data |
---|---|---|
6e87ae1c SG |
1 | # -*- coding: utf-8 -*- |
2 | # | |
3 | # Copyright 2017 Google, Inc | |
4 | # | |
5 | # SPDX-License-Identifier: GPL-2.0+ | |
6 | # | |
7 | ||
8 | import contextlib | |
9 | import os | |
10 | import re | |
11 | import shutil | |
12 | import sys | |
13 | import tempfile | |
14 | import unittest | |
15 | ||
16 | import gitutil | |
17 | import patchstream | |
18 | import settings | |
19 | ||
20 | ||
21 | @contextlib.contextmanager | |
22 | def capture(): | |
23 | import sys | |
24 | from cStringIO import StringIO | |
25 | oldout,olderr = sys.stdout, sys.stderr | |
26 | try: | |
27 | out=[StringIO(), StringIO()] | |
28 | sys.stdout,sys.stderr = out | |
29 | yield out | |
30 | finally: | |
31 | sys.stdout,sys.stderr = oldout, olderr | |
32 | out[0] = out[0].getvalue() | |
33 | out[1] = out[1].getvalue() | |
34 | ||
35 | ||
36 | class TestFunctional(unittest.TestCase): | |
37 | def setUp(self): | |
38 | self.tmpdir = tempfile.mkdtemp(prefix='patman.') | |
39 | ||
40 | def tearDown(self): | |
41 | shutil.rmtree(self.tmpdir) | |
42 | ||
43 | @staticmethod | |
44 | def GetPath(fname): | |
45 | return os.path.join(os.path.dirname(os.path.realpath(sys.argv[0])), | |
46 | 'test', fname) | |
47 | ||
48 | @classmethod | |
49 | def GetText(self, fname): | |
50 | return open(self.GetPath(fname)).read() | |
51 | ||
52 | @classmethod | |
53 | def GetPatchName(self, subject): | |
54 | fname = re.sub('[ :]', '-', subject) | |
55 | return fname.replace('--', '-') | |
56 | ||
57 | def CreatePatchesForTest(self, series): | |
58 | cover_fname = None | |
59 | fname_list = [] | |
60 | for i, commit in enumerate(series.commits): | |
61 | clean_subject = self.GetPatchName(commit.subject) | |
62 | src_fname = '%04d-%s.patch' % (i + 1, clean_subject[:52]) | |
63 | fname = os.path.join(self.tmpdir, src_fname) | |
64 | shutil.copy(self.GetPath(src_fname), fname) | |
65 | fname_list.append(fname) | |
66 | if series.get('cover'): | |
67 | src_fname = '0000-cover-letter.patch' | |
68 | cover_fname = os.path.join(self.tmpdir, src_fname) | |
69 | fname = os.path.join(self.tmpdir, src_fname) | |
70 | shutil.copy(self.GetPath(src_fname), fname) | |
71 | ||
72 | return cover_fname, fname_list | |
73 | ||
74 | def testBasic(self): | |
75 | """Tests the basic flow of patman | |
76 | ||
77 | This creates a series from some hard-coded patches build from a simple | |
78 | tree with the following metadata in the top commit: | |
79 | ||
80 | Series-to: u-boot | |
81 | Series-prefix: RFC | |
82 | Series-cc: Stefan Brüns <stefan.bruens@rwth-aachen.de> | |
83 | Cover-letter-cc: Lord Mëlchett <clergy@palace.gov> | |
84 | Series-version: 2 | |
85 | Series-changes: 4 | |
86 | - Some changes | |
87 | ||
88 | Cover-letter: | |
89 | test: A test patch series | |
90 | This is a test of how the cover | |
91 | leter | |
92 | works | |
93 | END | |
94 | ||
95 | and this in the first commit: | |
96 | ||
97 | Series-notes: | |
98 | some notes | |
99 | about some things | |
100 | from the first commit | |
101 | END | |
102 | ||
103 | Commit-notes: | |
104 | Some notes about | |
105 | the first commit | |
106 | END | |
107 | ||
108 | with the following commands: | |
109 | ||
110 | git log -n2 --reverse >/path/to/tools/patman/test/test01.txt | |
111 | git format-patch --subject-prefix RFC --cover-letter HEAD~2 | |
112 | mv 00* /path/to/tools/patman/test | |
113 | ||
114 | It checks these aspects: | |
115 | - git log can be processed by patchstream | |
116 | - emailing patches uses the correct command | |
117 | - CC file has information on each commit | |
118 | - cover letter has the expected text and subject | |
119 | - each patch has the correct subject | |
120 | - dry-run information prints out correctly | |
121 | - unicode is handled correctly | |
122 | - Series-to, Series-cc, Series-prefix, Cover-letter | |
123 | - Cover-letter-cc, Series-version, Series-changes, Series-notes | |
124 | - Commit-notes | |
125 | """ | |
126 | process_tags = True | |
127 | ignore_bad_tags = True | |
128 | stefan = u'Stefan Brüns <stefan.bruens@rwth-aachen.de>' | |
129 | rick = 'Richard III <richard@palace.gov>' | |
130 | mel = u'Lord Mëlchett <clergy@palace.gov>' | |
131 | ed = u'Lond Edmund Blackaddër <weasel@blackadder.org' | |
132 | fred = 'Fred Bloggs <f.bloggs@napier.net>' | |
133 | add_maintainers = [stefan, rick] | |
134 | dry_run = True | |
135 | in_reply_to = mel | |
136 | count = 2 | |
137 | settings.alias = { | |
138 | 'fdt': ['simon'], | |
139 | 'u-boot': ['u-boot@lists.denx.de'], | |
140 | 'simon': [ed], | |
141 | 'fred': [fred], | |
142 | } | |
143 | ||
144 | text = self.GetText('test01.txt') | |
145 | series = patchstream.GetMetaDataForTest(text) | |
146 | cover_fname, args = self.CreatePatchesForTest(series) | |
147 | with capture() as out: | |
148 | patchstream.FixPatches(series, args) | |
149 | if cover_fname and series.get('cover'): | |
150 | patchstream.InsertCoverLetter(cover_fname, series, count) | |
151 | series.DoChecks() | |
152 | cc_file = series.MakeCcFile(process_tags, cover_fname, | |
153 | not ignore_bad_tags, add_maintainers) | |
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: u-boot@lists.denx.de', 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 "u-boot@lists.denx.de" ' | |
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 | |
213 | fdt: Correct cast for sandbox in fdtdec_setup_memory_size() | |
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]) |