blob: 4c3d497294d198eec76d3f773e1445cb1bddcbfb [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001# SPDX-License-Identifier: GPL-2.0+
Simon Glassed098bb2014-09-05 19:00:13 -06002# Copyright (c) 2014 Google, Inc
3#
Simon Glassed098bb2014-09-05 19:00:13 -06004
5import os
6import shutil
7import sys
8import tempfile
9import unittest
10
Simon Glasscbd36582014-09-05 19:00:16 -060011import board
Simon Glass5e0441d2014-09-05 19:00:15 -060012import bsettings
Simon Glassed098bb2014-09-05 19:00:13 -060013import cmdline
14import command
15import control
16import gitutil
17import terminal
18import toolchain
19
Simon Glass5e0441d2014-09-05 19:00:15 -060020settings_data = '''
21# Buildman settings file
22
23[toolchain]
24
25[toolchain-alias]
26
27[make-flags]
28src=/home/sjg/c/src
29chroot=/home/sjg/c/chroot
Masahiro Yamada72e545a2018-08-06 20:47:38 +090030vboot=VBOOT_DEBUG=1 MAKEFLAGS_VBOOT=DEBUG=1 CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS VBOOT_SOURCE=${src}/platform/vboot_reference
Simon Glass5e0441d2014-09-05 19:00:15 -060031chromeos_coreboot=VBOOT=${chroot}/build/link/usr ${vboot}
32chromeos_daisy=VBOOT=${chroot}/build/daisy/usr ${vboot}
33chromeos_peach=VBOOT=${chroot}/build/peach_pit/usr ${vboot}
34'''
35
Simon Glasscbd36582014-09-05 19:00:16 -060036boards = [
37 ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 1', 'board0', ''],
38 ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 2', 'board1', ''],
39 ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', 'board2', ''],
Simon Glasscbd36582014-09-05 19:00:16 -060040 ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', 'board4', ''],
41]
42
Simon Glass8e959562014-09-05 19:00:20 -060043commit_shortlog = """4aca821 patman: Avoid changing the order of tags
4439403bb patman: Use --no-pager' to stop git from forking a pager
45db6e6f2 patman: Remove the -a option
46f2ccf03 patman: Correct unit tests to run correctly
471d097f9 patman: Fix indentation in terminal.py
48d073747 patman: Support the 'reverse' option for 'git log
49"""
50
51commit_log = ["""commit 7f6b8315d18f683c5181d0c3694818c1b2a20dcd
52Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
53Date: Fri Aug 22 19:12:41 2014 +0900
54
55 buildman: refactor help message
56
57 "buildman [options]" is displayed by default.
58
59 Append the rest of help messages to parser.usage
60 instead of replacing it.
61
62 Besides, "-b <branch>" is not mandatory since commit fea5858e.
63 Drop it from the usage.
64
65 Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
66""",
67"""commit d0737479be6baf4db5e2cdbee123e96bc5ed0ba8
68Author: Simon Glass <sjg@chromium.org>
69Date: Thu Aug 14 16:48:25 2014 -0600
70
71 patman: Support the 'reverse' option for 'git log'
72
73 This option is currently not supported, but needs to be, for buildman to
74 operate as expected.
75
76 Series-changes: 7
77 - Add new patch to fix the 'reverse' bug
78
Simon Glass359b55a62014-09-05 19:00:23 -060079 Series-version: 8
Simon Glass8e959562014-09-05 19:00:20 -060080
81 Change-Id: I79078f792e8b390b8a1272a8023537821d45feda
82 Reported-by: York Sun <yorksun@freescale.com>
83 Signed-off-by: Simon Glass <sjg@chromium.org>
84
85""",
86"""commit 1d097f9ab487c5019152fd47bda126839f3bf9fc
87Author: Simon Glass <sjg@chromium.org>
88Date: Sat Aug 9 11:44:32 2014 -0600
89
90 patman: Fix indentation in terminal.py
91
92 This code came from a different project with 2-character indentation. Fix
93 it for U-Boot.
94
95 Series-changes: 6
96 - Add new patch to fix indentation in teminal.py
97
98 Change-Id: I5a74d2ebbb3cc12a665f5c725064009ac96e8a34
99 Signed-off-by: Simon Glass <sjg@chromium.org>
100
101""",
102"""commit f2ccf03869d1e152c836515a3ceb83cdfe04a105
103Author: Simon Glass <sjg@chromium.org>
104Date: Sat Aug 9 11:08:24 2014 -0600
105
106 patman: Correct unit tests to run correctly
107
108 It seems that doctest behaves differently now, and some of the unit tests
109 do not run. Adjust the tests to work correctly.
110
111 ./tools/patman/patman --test
112 <unittest.result.TestResult run=10 errors=0 failures=0>
113
114 Series-changes: 6
115 - Add new patch to fix patman unit tests
116
117 Change-Id: I3d2ca588f4933e1f9d6b1665a00e4ae58269ff3b
118
119""",
120"""commit db6e6f2f9331c5a37647d6668768d4a40b8b0d1c
121Author: Simon Glass <sjg@chromium.org>
122Date: Sat Aug 9 12:06:02 2014 -0600
123
124 patman: Remove the -a option
125
126 It seems that this is no longer needed, since checkpatch.pl will catch
127 whitespace problems in patches. Also the option is not widely used, so
128 it seems safe to just remove it.
129
130 Series-changes: 6
131 - Add new patch to remove patman's -a option
132
133 Suggested-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
134 Change-Id: I5821a1c75154e532c46513486ca40b808de7e2cc
135
136""",
137"""commit 39403bb4f838153028a6f21ca30bf100f3791133
138Author: Simon Glass <sjg@chromium.org>
139Date: Thu Aug 14 21:50:52 2014 -0600
140
141 patman: Use --no-pager' to stop git from forking a pager
142
143""",
144"""commit 4aca821e27e97925c039e69fd37375b09c6f129c
145Author: Simon Glass <sjg@chromium.org>
146Date: Fri Aug 22 15:57:39 2014 -0600
147
148 patman: Avoid changing the order of tags
149
150 patman collects tags that it sees in the commit and places them nicely
151 sorted at the end of the patch. However, this is not really necessary and
152 in fact is apparently not desirable.
153
154 Series-changes: 9
155 - Add new patch to avoid changing the order of tags
156
Simon Glass359b55a62014-09-05 19:00:23 -0600157 Series-version: 9
158
Simon Glass8e959562014-09-05 19:00:20 -0600159 Suggested-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
160 Change-Id: Ib1518588c1a189ad5c3198aae76f8654aed8d0db
161"""]
162
163TEST_BRANCH = '__testbranch'
164
Simon Glassed098bb2014-09-05 19:00:13 -0600165class TestFunctional(unittest.TestCase):
166 """Functional test for buildman.
167
168 This aims to test from just below the invocation of buildman (parsing
169 of arguments) to 'make' and 'git' invocation. It is not a true
170 emd-to-end test, as it mocks git, make and the tool chain. But this
171 makes it easier to detect when the builder is doing the wrong thing,
172 since in many cases this test code will fail. For example, only a
173 very limited subset of 'git' arguments is supported - anything
174 unexpected will fail.
175 """
176 def setUp(self):
177 self._base_dir = tempfile.mkdtemp()
Tom Rinie95eddc2019-10-07 17:17:36 -0400178 self._output_dir = tempfile.mkdtemp()
Simon Glassed098bb2014-09-05 19:00:13 -0600179 self._git_dir = os.path.join(self._base_dir, 'src')
180 self._buildman_pathname = sys.argv[0]
Simon Glass5d4a7872016-07-27 20:33:00 -0600181 self._buildman_dir = os.path.dirname(os.path.realpath(sys.argv[0]))
Simon Glassed098bb2014-09-05 19:00:13 -0600182 command.test_result = self._HandleCommand
Simon Glass8e959562014-09-05 19:00:20 -0600183 self.setupToolchains()
184 self._toolchains.Add('arm-gcc', test=False)
185 self._toolchains.Add('powerpc-gcc', test=False)
Simon Glass5e0441d2014-09-05 19:00:15 -0600186 bsettings.Setup(None)
187 bsettings.AddFile(settings_data)
Simon Glasscbd36582014-09-05 19:00:16 -0600188 self._boards = board.Boards()
189 for brd in boards:
190 self._boards.AddBoard(board.Board(*brd))
Simon Glassed098bb2014-09-05 19:00:13 -0600191
Simon Glass8e959562014-09-05 19:00:20 -0600192 # Directories where the source been cloned
193 self._clone_dirs = []
194 self._commits = len(commit_shortlog.splitlines()) + 1
195 self._total_builds = self._commits * len(boards)
196
197 # Number of calls to make
198 self._make_calls = 0
199
200 # Map of [board, commit] to error messages
201 self._error = {}
202
Simon Glass4aeceb92014-09-05 19:00:22 -0600203 self._test_branch = TEST_BRANCH
204
Simon Glass8e959562014-09-05 19:00:20 -0600205 # Avoid sending any output and clear all terminal output
206 terminal.SetPrintTestMode()
207 terminal.GetPrintTestLines()
208
Simon Glassed098bb2014-09-05 19:00:13 -0600209 def tearDown(self):
210 shutil.rmtree(self._base_dir)
Tom Rinie95eddc2019-10-07 17:17:36 -0400211 shutil.rmtree(self._output_dir)
Simon Glassed098bb2014-09-05 19:00:13 -0600212
Simon Glass8e959562014-09-05 19:00:20 -0600213 def setupToolchains(self):
214 self._toolchains = toolchain.Toolchains()
215 self._toolchains.Add('gcc', test=False)
216
Simon Glassed098bb2014-09-05 19:00:13 -0600217 def _RunBuildman(self, *args):
218 return command.RunPipe([[self._buildman_pathname] + list(args)],
219 capture=True, capture_stderr=True)
220
Simon Glass8e959562014-09-05 19:00:20 -0600221 def _RunControl(self, *args, **kwargs):
Simon Glassed098bb2014-09-05 19:00:13 -0600222 sys.argv = [sys.argv[0]] + list(args)
223 options, args = cmdline.ParseArgs()
Simon Glass8e959562014-09-05 19:00:20 -0600224 result = control.DoBuildman(options, args, toolchains=self._toolchains,
225 make_func=self._HandleMake, boards=self._boards,
226 clean_dir=kwargs.get('clean_dir', True))
227 self._builder = control.builder
228 return result
Simon Glassed098bb2014-09-05 19:00:13 -0600229
230 def testFullHelp(self):
231 command.test_result = None
232 result = self._RunBuildman('-H')
233 help_file = os.path.join(self._buildman_dir, 'README')
Tom Rinic3c0b6d2018-01-16 15:29:50 -0500234 # Remove possible extraneous strings
235 extra = '::::::::::::::\n' + help_file + '\n::::::::::::::\n'
236 gothelp = result.stdout.replace(extra, '')
237 self.assertEqual(len(gothelp), os.path.getsize(help_file))
Simon Glassed098bb2014-09-05 19:00:13 -0600238 self.assertEqual(0, len(result.stderr))
239 self.assertEqual(0, result.return_code)
240
241 def testHelp(self):
242 command.test_result = None
243 result = self._RunBuildman('-h')
244 help_file = os.path.join(self._buildman_dir, 'README')
245 self.assertTrue(len(result.stdout) > 1000)
246 self.assertEqual(0, len(result.stderr))
247 self.assertEqual(0, result.return_code)
248
249 def testGitSetup(self):
250 """Test gitutils.Setup(), from outside the module itself"""
251 command.test_result = command.CommandResult(return_code=1)
252 gitutil.Setup()
253 self.assertEqual(gitutil.use_no_decorate, False)
254
255 command.test_result = command.CommandResult(return_code=0)
256 gitutil.Setup()
257 self.assertEqual(gitutil.use_no_decorate, True)
258
259 def _HandleCommandGitLog(self, args):
Simon Glass642e9a62016-03-12 18:50:31 -0700260 if args[-1] == '--':
261 args = args[:-1]
Simon Glassed098bb2014-09-05 19:00:13 -0600262 if '-n0' in args:
263 return command.CommandResult(return_code=0)
Simon Glass4aeceb92014-09-05 19:00:22 -0600264 elif args[-1] == 'upstream/master..%s' % self._test_branch:
Simon Glass8e959562014-09-05 19:00:20 -0600265 return command.CommandResult(return_code=0, stdout=commit_shortlog)
266 elif args[:3] == ['--no-color', '--no-decorate', '--reverse']:
Simon Glass4aeceb92014-09-05 19:00:22 -0600267 if args[-1] == self._test_branch:
Simon Glass8e959562014-09-05 19:00:20 -0600268 count = int(args[3][2:])
269 return command.CommandResult(return_code=0,
270 stdout=''.join(commit_log[:count]))
Simon Glassed098bb2014-09-05 19:00:13 -0600271
272 # Not handled, so abort
Simon Glassc78ed662019-10-31 07:42:53 -0600273 print('git log', args)
Simon Glassed098bb2014-09-05 19:00:13 -0600274 sys.exit(1)
275
Simon Glass8e959562014-09-05 19:00:20 -0600276 def _HandleCommandGitConfig(self, args):
277 config = args[0]
278 if config == 'sendemail.aliasesfile':
279 return command.CommandResult(return_code=0)
280 elif config.startswith('branch.badbranch'):
281 return command.CommandResult(return_code=1)
Simon Glass4aeceb92014-09-05 19:00:22 -0600282 elif config == 'branch.%s.remote' % self._test_branch:
Simon Glass8e959562014-09-05 19:00:20 -0600283 return command.CommandResult(return_code=0, stdout='upstream\n')
Simon Glass4aeceb92014-09-05 19:00:22 -0600284 elif config == 'branch.%s.merge' % self._test_branch:
Simon Glass8e959562014-09-05 19:00:20 -0600285 return command.CommandResult(return_code=0,
286 stdout='refs/heads/master\n')
287
288 # Not handled, so abort
Simon Glassc78ed662019-10-31 07:42:53 -0600289 print('git config', args)
Simon Glass8e959562014-09-05 19:00:20 -0600290 sys.exit(1)
291
Simon Glassed098bb2014-09-05 19:00:13 -0600292 def _HandleCommandGit(self, in_args):
293 """Handle execution of a git command
294
295 This uses a hacked-up parser.
296
297 Args:
298 in_args: Arguments after 'git' from the command line
299 """
300 git_args = [] # Top-level arguments to git itself
301 sub_cmd = None # Git sub-command selected
302 args = [] # Arguments to the git sub-command
303 for arg in in_args:
304 if sub_cmd:
305 args.append(arg)
306 elif arg[0] == '-':
307 git_args.append(arg)
308 else:
Simon Glass8e959562014-09-05 19:00:20 -0600309 if git_args and git_args[-1] in ['--git-dir', '--work-tree']:
310 git_args.append(arg)
311 else:
312 sub_cmd = arg
Simon Glassed098bb2014-09-05 19:00:13 -0600313 if sub_cmd == 'config':
Simon Glass8e959562014-09-05 19:00:20 -0600314 return self._HandleCommandGitConfig(args)
Simon Glassed098bb2014-09-05 19:00:13 -0600315 elif sub_cmd == 'log':
316 return self._HandleCommandGitLog(args)
Simon Glass8e959562014-09-05 19:00:20 -0600317 elif sub_cmd == 'clone':
318 return command.CommandResult(return_code=0)
319 elif sub_cmd == 'checkout':
320 return command.CommandResult(return_code=0)
Simon Glassed098bb2014-09-05 19:00:13 -0600321
322 # Not handled, so abort
Simon Glassc78ed662019-10-31 07:42:53 -0600323 print('git', git_args, sub_cmd, args)
Simon Glassed098bb2014-09-05 19:00:13 -0600324 sys.exit(1)
325
326 def _HandleCommandNm(self, args):
327 return command.CommandResult(return_code=0)
328
329 def _HandleCommandObjdump(self, args):
330 return command.CommandResult(return_code=0)
331
Alex Kiernanf07ed232018-05-31 04:48:33 +0000332 def _HandleCommandObjcopy(self, args):
333 return command.CommandResult(return_code=0)
334
Simon Glassed098bb2014-09-05 19:00:13 -0600335 def _HandleCommandSize(self, args):
336 return command.CommandResult(return_code=0)
337
338 def _HandleCommand(self, **kwargs):
339 """Handle a command execution.
340
341 The command is in kwargs['pipe-list'], as a list of pipes, each a
342 list of commands. The command should be emulated as required for
343 testing purposes.
344
345 Returns:
346 A CommandResult object
347 """
348 pipe_list = kwargs['pipe_list']
Simon Glass8e959562014-09-05 19:00:20 -0600349 wc = False
Simon Glassed098bb2014-09-05 19:00:13 -0600350 if len(pipe_list) != 1:
Simon Glass8e959562014-09-05 19:00:20 -0600351 if pipe_list[1] == ['wc', '-l']:
352 wc = True
353 else:
Simon Glassc78ed662019-10-31 07:42:53 -0600354 print('invalid pipe', kwargs)
Simon Glass8e959562014-09-05 19:00:20 -0600355 sys.exit(1)
Simon Glassed098bb2014-09-05 19:00:13 -0600356 cmd = pipe_list[0][0]
357 args = pipe_list[0][1:]
Simon Glass8e959562014-09-05 19:00:20 -0600358 result = None
Simon Glassed098bb2014-09-05 19:00:13 -0600359 if cmd == 'git':
Simon Glass8e959562014-09-05 19:00:20 -0600360 result = self._HandleCommandGit(args)
Simon Glassed098bb2014-09-05 19:00:13 -0600361 elif cmd == './scripts/show-gnu-make':
362 return command.CommandResult(return_code=0, stdout='make')
Simon Glass8e959562014-09-05 19:00:20 -0600363 elif cmd.endswith('nm'):
Simon Glassed098bb2014-09-05 19:00:13 -0600364 return self._HandleCommandNm(args)
Simon Glass8e959562014-09-05 19:00:20 -0600365 elif cmd.endswith('objdump'):
Simon Glassed098bb2014-09-05 19:00:13 -0600366 return self._HandleCommandObjdump(args)
Alex Kiernanf07ed232018-05-31 04:48:33 +0000367 elif cmd.endswith('objcopy'):
368 return self._HandleCommandObjcopy(args)
Simon Glass8e959562014-09-05 19:00:20 -0600369 elif cmd.endswith( 'size'):
Simon Glassed098bb2014-09-05 19:00:13 -0600370 return self._HandleCommandSize(args)
371
Simon Glass8e959562014-09-05 19:00:20 -0600372 if not result:
373 # Not handled, so abort
Simon Glassc78ed662019-10-31 07:42:53 -0600374 print('unknown command', kwargs)
Simon Glass8e959562014-09-05 19:00:20 -0600375 sys.exit(1)
376
377 if wc:
378 result.stdout = len(result.stdout.splitlines())
379 return result
Simon Glassed098bb2014-09-05 19:00:13 -0600380
381 def _HandleMake(self, commit, brd, stage, cwd, *args, **kwargs):
382 """Handle execution of 'make'
383
384 Args:
385 commit: Commit object that is being built
386 brd: Board object that is being built
387 stage: Stage that we are at (mrproper, config, build)
388 cwd: Directory where make should be run
389 args: Arguments to pass to make
390 kwargs: Arguments to pass to command.RunPipe()
391 """
Simon Glass8e959562014-09-05 19:00:20 -0600392 self._make_calls += 1
Simon Glassed098bb2014-09-05 19:00:13 -0600393 if stage == 'mrproper':
394 return command.CommandResult(return_code=0)
395 elif stage == 'config':
396 return command.CommandResult(return_code=0,
397 combined='Test configuration complete')
398 elif stage == 'build':
Simon Glass8e959562014-09-05 19:00:20 -0600399 stderr = ''
400 if type(commit) is not str:
401 stderr = self._error.get((brd.target, commit.sequence))
402 if stderr:
403 return command.CommandResult(return_code=1, stderr=stderr)
Simon Glassed098bb2014-09-05 19:00:13 -0600404 return command.CommandResult(return_code=0)
405
406 # Not handled, so abort
Simon Glassc78ed662019-10-31 07:42:53 -0600407 print('make', stage)
Simon Glassed098bb2014-09-05 19:00:13 -0600408 sys.exit(1)
409
Simon Glass8e959562014-09-05 19:00:20 -0600410 # Example function to print output lines
411 def print_lines(self, lines):
Simon Glassc78ed662019-10-31 07:42:53 -0600412 print(len(lines))
Simon Glass8e959562014-09-05 19:00:20 -0600413 for line in lines:
Simon Glassc78ed662019-10-31 07:42:53 -0600414 print(line)
Simon Glass8e959562014-09-05 19:00:20 -0600415 #self.print_lines(terminal.GetPrintTestLines())
416
Simon Glasscbd36582014-09-05 19:00:16 -0600417 def testNoBoards(self):
418 """Test that buildman aborts when there are no boards"""
419 self._boards = board.Boards()
420 with self.assertRaises(SystemExit):
421 self._RunControl()
422
Simon Glassed098bb2014-09-05 19:00:13 -0600423 def testCurrentSource(self):
424 """Very simple test to invoke buildman on the current source"""
Simon Glass8e959562014-09-05 19:00:20 -0600425 self.setupToolchains();
Tom Rinie95eddc2019-10-07 17:17:36 -0400426 self._RunControl('-o', self._output_dir)
Simon Glassed098bb2014-09-05 19:00:13 -0600427 lines = terminal.GetPrintTestLines()
Simon Glass8e959562014-09-05 19:00:20 -0600428 self.assertIn('Building current source for %d boards' % len(boards),
429 lines[0].text)
430
431 def testBadBranch(self):
432 """Test that we can detect an invalid branch"""
433 with self.assertRaises(ValueError):
434 self._RunControl('-b', 'badbranch')
435
436 def testBadToolchain(self):
437 """Test that missing toolchains are detected"""
438 self.setupToolchains();
Tom Rinie95eddc2019-10-07 17:17:36 -0400439 ret_code = self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600440 lines = terminal.GetPrintTestLines()
441
442 # Buildman always builds the upstream commit as well
443 self.assertIn('Building %d commits for %d boards' %
444 (self._commits, len(boards)), lines[0].text)
445 self.assertEqual(self._builder.count, self._total_builds)
446
447 # Only sandbox should succeed, the others don't have toolchains
448 self.assertEqual(self._builder.fail,
449 self._total_builds - self._commits)
450 self.assertEqual(ret_code, 128)
451
452 for commit in range(self._commits):
453 for board in self._boards.GetList():
454 if board.arch != 'sandbox':
455 errfile = self._builder.GetErrFile(commit, board.target)
456 fd = open(errfile)
457 self.assertEqual(fd.readlines(),
458 ['No tool chain for %s\n' % board.arch])
459 fd.close()
460
461 def testBranch(self):
462 """Test building a branch with all toolchains present"""
Tom Rinie95eddc2019-10-07 17:17:36 -0400463 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600464 self.assertEqual(self._builder.count, self._total_builds)
465 self.assertEqual(self._builder.fail, 0)
466
467 def testCount(self):
468 """Test building a specific number of commitst"""
Tom Rinie95eddc2019-10-07 17:17:36 -0400469 self._RunControl('-b', TEST_BRANCH, '-c2', '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600470 self.assertEqual(self._builder.count, 2 * len(boards))
471 self.assertEqual(self._builder.fail, 0)
472 # Each board has a mrproper, config, and then one make per commit
473 self.assertEqual(self._make_calls, len(boards) * (2 + 2))
474
475 def testIncremental(self):
476 """Test building a branch twice - the second time should do nothing"""
Tom Rinie95eddc2019-10-07 17:17:36 -0400477 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600478
479 # Each board has a mrproper, config, and then one make per commit
480 self.assertEqual(self._make_calls, len(boards) * (self._commits + 2))
481 self._make_calls = 0
Tom Rinie95eddc2019-10-07 17:17:36 -0400482 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir, clean_dir=False)
Simon Glass8e959562014-09-05 19:00:20 -0600483 self.assertEqual(self._make_calls, 0)
484 self.assertEqual(self._builder.count, self._total_builds)
485 self.assertEqual(self._builder.fail, 0)
486
487 def testForceBuild(self):
488 """The -f flag should force a rebuild"""
Tom Rinie95eddc2019-10-07 17:17:36 -0400489 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600490 self._make_calls = 0
Tom Rinie95eddc2019-10-07 17:17:36 -0400491 self._RunControl('-b', TEST_BRANCH, '-f', '-o', self._output_dir, clean_dir=False)
Simon Glass8e959562014-09-05 19:00:20 -0600492 # Each board has a mrproper, config, and then one make per commit
493 self.assertEqual(self._make_calls, len(boards) * (self._commits + 2))
494
495 def testForceReconfigure(self):
496 """The -f flag should force a rebuild"""
Tom Rinie95eddc2019-10-07 17:17:36 -0400497 self._RunControl('-b', TEST_BRANCH, '-C', '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600498 # Each commit has a mrproper, config and make
499 self.assertEqual(self._make_calls, len(boards) * self._commits * 3)
500
501 def testErrors(self):
502 """Test handling of build errors"""
503 self._error['board2', 1] = 'fred\n'
Tom Rinie95eddc2019-10-07 17:17:36 -0400504 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir)
Simon Glass8e959562014-09-05 19:00:20 -0600505 self.assertEqual(self._builder.count, self._total_builds)
506 self.assertEqual(self._builder.fail, 1)
507
508 # Remove the error. This should have no effect since the commit will
509 # not be rebuilt
510 del self._error['board2', 1]
511 self._make_calls = 0
Tom Rinie95eddc2019-10-07 17:17:36 -0400512 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir, clean_dir=False)
Simon Glass8e959562014-09-05 19:00:20 -0600513 self.assertEqual(self._builder.count, self._total_builds)
514 self.assertEqual(self._make_calls, 0)
515 self.assertEqual(self._builder.fail, 1)
516
517 # Now use the -F flag to force rebuild of the bad commit
Tom Rinie95eddc2019-10-07 17:17:36 -0400518 self._RunControl('-b', TEST_BRANCH, '-o', self._output_dir, '-F', clean_dir=False)
Simon Glass8e959562014-09-05 19:00:20 -0600519 self.assertEqual(self._builder.count, self._total_builds)
520 self.assertEqual(self._builder.fail, 0)
521 self.assertEqual(self._make_calls, 3)
Simon Glass4aeceb92014-09-05 19:00:22 -0600522
523 def testBranchWithSlash(self):
524 """Test building a branch with a '/' in the name"""
525 self._test_branch = '/__dev/__testbranch'
526 self._RunControl('-b', self._test_branch, clean_dir=False)
527 self.assertEqual(self._builder.count, self._total_builds)
528 self.assertEqual(self._builder.fail, 0)
Lothar Waßmannce6df922018-04-08 05:14:11 -0600529
530 def testBadOutputDir(self):
531 """Test building with an output dir the same as out current dir"""
532 self._test_branch = '/__dev/__testbranch'
533 with self.assertRaises(SystemExit):
534 self._RunControl('-b', self._test_branch, '-o', os.getcwd())
535 with self.assertRaises(SystemExit):
536 self._RunControl('-b', self._test_branch, '-o',
537 os.path.join(os.getcwd(), 'test'))