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