mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	Tags like Series-version are normally expected to appear once, and with a unique value. But buildman doesn't actually look at these tags. So ignore conflicts. This allows bulidman to build a branch containing multiple patman series. Reported-by: Steve Rae <srae@broadcom.com> Signed-off-by: Simon Glass <sjg@chromium.org>
		
			
				
	
	
		
			520 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			520 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#
 | 
						|
# Copyright (c) 2014 Google, Inc
 | 
						|
#
 | 
						|
# SPDX-License-Identifier:      GPL-2.0+
 | 
						|
#
 | 
						|
 | 
						|
import os
 | 
						|
import shutil
 | 
						|
import sys
 | 
						|
import tempfile
 | 
						|
import unittest
 | 
						|
 | 
						|
import board
 | 
						|
import bsettings
 | 
						|
import cmdline
 | 
						|
import command
 | 
						|
import control
 | 
						|
import gitutil
 | 
						|
import terminal
 | 
						|
import toolchain
 | 
						|
 | 
						|
settings_data = '''
 | 
						|
# Buildman settings file
 | 
						|
 | 
						|
[toolchain]
 | 
						|
 | 
						|
[toolchain-alias]
 | 
						|
 | 
						|
[make-flags]
 | 
						|
src=/home/sjg/c/src
 | 
						|
chroot=/home/sjg/c/chroot
 | 
						|
vboot=USE_STDINT=1 VBOOT_DEBUG=1 MAKEFLAGS_VBOOT=DEBUG=1 CFLAGS_EXTRA_VBOOT=-DUNROLL_LOOPS VBOOT_SOURCE=${src}/platform/vboot_reference
 | 
						|
chromeos_coreboot=VBOOT=${chroot}/build/link/usr ${vboot}
 | 
						|
chromeos_daisy=VBOOT=${chroot}/build/daisy/usr ${vboot}
 | 
						|
chromeos_peach=VBOOT=${chroot}/build/peach_pit/usr ${vboot}
 | 
						|
'''
 | 
						|
 | 
						|
boards = [
 | 
						|
    ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 1', 'board0',  ''],
 | 
						|
    ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 2', 'board1', ''],
 | 
						|
    ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', 'board2', ''],
 | 
						|
    ['Active', 'powerpc', 'mpc5xx', '', 'Tester', 'PowerPC board 2', 'board3', ''],
 | 
						|
    ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', 'board4', ''],
 | 
						|
]
 | 
						|
 | 
						|
commit_shortlog = """4aca821 patman: Avoid changing the order of tags
 | 
						|
39403bb patman: Use --no-pager' to stop git from forking a pager
 | 
						|
db6e6f2 patman: Remove the -a option
 | 
						|
f2ccf03 patman: Correct unit tests to run correctly
 | 
						|
1d097f9 patman: Fix indentation in terminal.py
 | 
						|
d073747 patman: Support the 'reverse' option for 'git log
 | 
						|
"""
 | 
						|
 | 
						|
commit_log = ["""commit 7f6b8315d18f683c5181d0c3694818c1b2a20dcd
 | 
						|
Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
 | 
						|
Date:   Fri Aug 22 19:12:41 2014 +0900
 | 
						|
 | 
						|
    buildman: refactor help message
 | 
						|
 | 
						|
    "buildman [options]" is displayed by default.
 | 
						|
 | 
						|
    Append the rest of help messages to parser.usage
 | 
						|
    instead of replacing it.
 | 
						|
 | 
						|
    Besides, "-b <branch>" is not mandatory since commit fea5858e.
 | 
						|
    Drop it from the usage.
 | 
						|
 | 
						|
    Signed-off-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
 | 
						|
""",
 | 
						|
"""commit d0737479be6baf4db5e2cdbee123e96bc5ed0ba8
 | 
						|
Author: Simon Glass <sjg@chromium.org>
 | 
						|
Date:   Thu Aug 14 16:48:25 2014 -0600
 | 
						|
 | 
						|
    patman: Support the 'reverse' option for 'git log'
 | 
						|
 | 
						|
    This option is currently not supported, but needs to be, for buildman to
 | 
						|
    operate as expected.
 | 
						|
 | 
						|
    Series-changes: 7
 | 
						|
    - Add new patch to fix the 'reverse' bug
 | 
						|
 | 
						|
    Series-version: 8
 | 
						|
 | 
						|
    Change-Id: I79078f792e8b390b8a1272a8023537821d45feda
 | 
						|
    Reported-by: York Sun <yorksun@freescale.com>
 | 
						|
    Signed-off-by: Simon Glass <sjg@chromium.org>
 | 
						|
 | 
						|
""",
 | 
						|
"""commit 1d097f9ab487c5019152fd47bda126839f3bf9fc
 | 
						|
Author: Simon Glass <sjg@chromium.org>
 | 
						|
Date:   Sat Aug 9 11:44:32 2014 -0600
 | 
						|
 | 
						|
    patman: Fix indentation in terminal.py
 | 
						|
 | 
						|
    This code came from a different project with 2-character indentation. Fix
 | 
						|
    it for U-Boot.
 | 
						|
 | 
						|
    Series-changes: 6
 | 
						|
    - Add new patch to fix indentation in teminal.py
 | 
						|
 | 
						|
    Change-Id: I5a74d2ebbb3cc12a665f5c725064009ac96e8a34
 | 
						|
    Signed-off-by: Simon Glass <sjg@chromium.org>
 | 
						|
 | 
						|
""",
 | 
						|
"""commit f2ccf03869d1e152c836515a3ceb83cdfe04a105
 | 
						|
Author: Simon Glass <sjg@chromium.org>
 | 
						|
Date:   Sat Aug 9 11:08:24 2014 -0600
 | 
						|
 | 
						|
    patman: Correct unit tests to run correctly
 | 
						|
 | 
						|
    It seems that doctest behaves differently now, and some of the unit tests
 | 
						|
    do not run. Adjust the tests to work correctly.
 | 
						|
 | 
						|
     ./tools/patman/patman --test
 | 
						|
    <unittest.result.TestResult run=10 errors=0 failures=0>
 | 
						|
 | 
						|
    Series-changes: 6
 | 
						|
    - Add new patch to fix patman unit tests
 | 
						|
 | 
						|
    Change-Id: I3d2ca588f4933e1f9d6b1665a00e4ae58269ff3b
 | 
						|
 | 
						|
""",
 | 
						|
"""commit db6e6f2f9331c5a37647d6668768d4a40b8b0d1c
 | 
						|
Author: Simon Glass <sjg@chromium.org>
 | 
						|
Date:   Sat Aug 9 12:06:02 2014 -0600
 | 
						|
 | 
						|
    patman: Remove the -a option
 | 
						|
 | 
						|
    It seems that this is no longer needed, since checkpatch.pl will catch
 | 
						|
    whitespace problems in patches. Also the option is not widely used, so
 | 
						|
    it seems safe to just remove it.
 | 
						|
 | 
						|
    Series-changes: 6
 | 
						|
    - Add new patch to remove patman's -a option
 | 
						|
 | 
						|
    Suggested-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
 | 
						|
    Change-Id: I5821a1c75154e532c46513486ca40b808de7e2cc
 | 
						|
 | 
						|
""",
 | 
						|
"""commit 39403bb4f838153028a6f21ca30bf100f3791133
 | 
						|
Author: Simon Glass <sjg@chromium.org>
 | 
						|
Date:   Thu Aug 14 21:50:52 2014 -0600
 | 
						|
 | 
						|
    patman: Use --no-pager' to stop git from forking a pager
 | 
						|
 | 
						|
""",
 | 
						|
"""commit 4aca821e27e97925c039e69fd37375b09c6f129c
 | 
						|
Author: Simon Glass <sjg@chromium.org>
 | 
						|
Date:   Fri Aug 22 15:57:39 2014 -0600
 | 
						|
 | 
						|
    patman: Avoid changing the order of tags
 | 
						|
 | 
						|
    patman collects tags that it sees in the commit and places them nicely
 | 
						|
    sorted at the end of the patch. However, this is not really necessary and
 | 
						|
    in fact is apparently not desirable.
 | 
						|
 | 
						|
    Series-changes: 9
 | 
						|
    - Add new patch to avoid changing the order of tags
 | 
						|
 | 
						|
    Series-version: 9
 | 
						|
 | 
						|
    Suggested-by: Masahiro Yamada <yamada.m@jp.panasonic.com>
 | 
						|
    Change-Id: Ib1518588c1a189ad5c3198aae76f8654aed8d0db
 | 
						|
"""]
 | 
						|
 | 
						|
TEST_BRANCH = '__testbranch'
 | 
						|
 | 
						|
class TestFunctional(unittest.TestCase):
 | 
						|
    """Functional test for buildman.
 | 
						|
 | 
						|
    This aims to test from just below the invocation of buildman (parsing
 | 
						|
    of arguments) to 'make' and 'git' invocation. It is not a true
 | 
						|
    emd-to-end test, as it mocks git, make and the tool chain. But this
 | 
						|
    makes it easier to detect when the builder is doing the wrong thing,
 | 
						|
    since in many cases this test code will fail. For example, only a
 | 
						|
    very limited subset of 'git' arguments is supported - anything
 | 
						|
    unexpected will fail.
 | 
						|
    """
 | 
						|
    def setUp(self):
 | 
						|
        self._base_dir = tempfile.mkdtemp()
 | 
						|
        self._git_dir = os.path.join(self._base_dir, 'src')
 | 
						|
        self._buildman_pathname = sys.argv[0]
 | 
						|
        self._buildman_dir = os.path.dirname(sys.argv[0])
 | 
						|
        command.test_result = self._HandleCommand
 | 
						|
        self.setupToolchains()
 | 
						|
        self._toolchains.Add('arm-gcc', test=False)
 | 
						|
        self._toolchains.Add('powerpc-gcc', test=False)
 | 
						|
        bsettings.Setup(None)
 | 
						|
        bsettings.AddFile(settings_data)
 | 
						|
        self._boards = board.Boards()
 | 
						|
        for brd in boards:
 | 
						|
            self._boards.AddBoard(board.Board(*brd))
 | 
						|
 | 
						|
        # Directories where the source been cloned
 | 
						|
        self._clone_dirs = []
 | 
						|
        self._commits = len(commit_shortlog.splitlines()) + 1
 | 
						|
        self._total_builds = self._commits * len(boards)
 | 
						|
 | 
						|
        # Number of calls to make
 | 
						|
        self._make_calls = 0
 | 
						|
 | 
						|
        # Map of [board, commit] to error messages
 | 
						|
        self._error = {}
 | 
						|
 | 
						|
        self._test_branch = TEST_BRANCH
 | 
						|
 | 
						|
        # Avoid sending any output and clear all terminal output
 | 
						|
        terminal.SetPrintTestMode()
 | 
						|
        terminal.GetPrintTestLines()
 | 
						|
 | 
						|
    def tearDown(self):
 | 
						|
        shutil.rmtree(self._base_dir)
 | 
						|
 | 
						|
    def setupToolchains(self):
 | 
						|
        self._toolchains = toolchain.Toolchains()
 | 
						|
        self._toolchains.Add('gcc', test=False)
 | 
						|
 | 
						|
    def _RunBuildman(self, *args):
 | 
						|
        return command.RunPipe([[self._buildman_pathname] + list(args)],
 | 
						|
                capture=True, capture_stderr=True)
 | 
						|
 | 
						|
    def _RunControl(self, *args, **kwargs):
 | 
						|
        sys.argv = [sys.argv[0]] + list(args)
 | 
						|
        options, args = cmdline.ParseArgs()
 | 
						|
        result = control.DoBuildman(options, args, toolchains=self._toolchains,
 | 
						|
                make_func=self._HandleMake, boards=self._boards,
 | 
						|
                clean_dir=kwargs.get('clean_dir', True))
 | 
						|
        self._builder = control.builder
 | 
						|
        return result
 | 
						|
 | 
						|
    def testFullHelp(self):
 | 
						|
        command.test_result = None
 | 
						|
        result = self._RunBuildman('-H')
 | 
						|
        help_file = os.path.join(self._buildman_dir, 'README')
 | 
						|
        self.assertEqual(len(result.stdout), os.path.getsize(help_file))
 | 
						|
        self.assertEqual(0, len(result.stderr))
 | 
						|
        self.assertEqual(0, result.return_code)
 | 
						|
 | 
						|
    def testHelp(self):
 | 
						|
        command.test_result = None
 | 
						|
        result = self._RunBuildman('-h')
 | 
						|
        help_file = os.path.join(self._buildman_dir, 'README')
 | 
						|
        self.assertTrue(len(result.stdout) > 1000)
 | 
						|
        self.assertEqual(0, len(result.stderr))
 | 
						|
        self.assertEqual(0, result.return_code)
 | 
						|
 | 
						|
    def testGitSetup(self):
 | 
						|
        """Test gitutils.Setup(), from outside the module itself"""
 | 
						|
        command.test_result = command.CommandResult(return_code=1)
 | 
						|
        gitutil.Setup()
 | 
						|
        self.assertEqual(gitutil.use_no_decorate, False)
 | 
						|
 | 
						|
        command.test_result = command.CommandResult(return_code=0)
 | 
						|
        gitutil.Setup()
 | 
						|
        self.assertEqual(gitutil.use_no_decorate, True)
 | 
						|
 | 
						|
    def _HandleCommandGitLog(self, args):
 | 
						|
        if '-n0' in args:
 | 
						|
            return command.CommandResult(return_code=0)
 | 
						|
        elif args[-1] == 'upstream/master..%s' % self._test_branch:
 | 
						|
            return command.CommandResult(return_code=0, stdout=commit_shortlog)
 | 
						|
        elif args[:3] == ['--no-color', '--no-decorate', '--reverse']:
 | 
						|
            if args[-1] == self._test_branch:
 | 
						|
                count = int(args[3][2:])
 | 
						|
                return command.CommandResult(return_code=0,
 | 
						|
                                            stdout=''.join(commit_log[:count]))
 | 
						|
 | 
						|
        # Not handled, so abort
 | 
						|
        print 'git log', args
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
    def _HandleCommandGitConfig(self, args):
 | 
						|
        config = args[0]
 | 
						|
        if config == 'sendemail.aliasesfile':
 | 
						|
            return command.CommandResult(return_code=0)
 | 
						|
        elif config.startswith('branch.badbranch'):
 | 
						|
            return command.CommandResult(return_code=1)
 | 
						|
        elif config == 'branch.%s.remote' % self._test_branch:
 | 
						|
            return command.CommandResult(return_code=0, stdout='upstream\n')
 | 
						|
        elif config == 'branch.%s.merge' % self._test_branch:
 | 
						|
            return command.CommandResult(return_code=0,
 | 
						|
                                         stdout='refs/heads/master\n')
 | 
						|
 | 
						|
        # Not handled, so abort
 | 
						|
        print 'git config', args
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
    def _HandleCommandGit(self, in_args):
 | 
						|
        """Handle execution of a git command
 | 
						|
 | 
						|
        This uses a hacked-up parser.
 | 
						|
 | 
						|
        Args:
 | 
						|
            in_args: Arguments after 'git' from the command line
 | 
						|
        """
 | 
						|
        git_args = []           # Top-level arguments to git itself
 | 
						|
        sub_cmd = None          # Git sub-command selected
 | 
						|
        args = []               # Arguments to the git sub-command
 | 
						|
        for arg in in_args:
 | 
						|
            if sub_cmd:
 | 
						|
                args.append(arg)
 | 
						|
            elif arg[0] == '-':
 | 
						|
                git_args.append(arg)
 | 
						|
            else:
 | 
						|
                if git_args and git_args[-1] in ['--git-dir', '--work-tree']:
 | 
						|
                    git_args.append(arg)
 | 
						|
                else:
 | 
						|
                    sub_cmd = arg
 | 
						|
        if sub_cmd == 'config':
 | 
						|
            return self._HandleCommandGitConfig(args)
 | 
						|
        elif sub_cmd == 'log':
 | 
						|
            return self._HandleCommandGitLog(args)
 | 
						|
        elif sub_cmd == 'clone':
 | 
						|
            return command.CommandResult(return_code=0)
 | 
						|
        elif sub_cmd == 'checkout':
 | 
						|
            return command.CommandResult(return_code=0)
 | 
						|
 | 
						|
        # Not handled, so abort
 | 
						|
        print 'git', git_args, sub_cmd, args
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
    def _HandleCommandNm(self, args):
 | 
						|
        return command.CommandResult(return_code=0)
 | 
						|
 | 
						|
    def _HandleCommandObjdump(self, args):
 | 
						|
        return command.CommandResult(return_code=0)
 | 
						|
 | 
						|
    def _HandleCommandSize(self, args):
 | 
						|
        return command.CommandResult(return_code=0)
 | 
						|
 | 
						|
    def _HandleCommand(self, **kwargs):
 | 
						|
        """Handle a command execution.
 | 
						|
 | 
						|
        The command is in kwargs['pipe-list'], as a list of pipes, each a
 | 
						|
        list of commands. The command should be emulated as required for
 | 
						|
        testing purposes.
 | 
						|
 | 
						|
        Returns:
 | 
						|
            A CommandResult object
 | 
						|
        """
 | 
						|
        pipe_list = kwargs['pipe_list']
 | 
						|
        wc = False
 | 
						|
        if len(pipe_list) != 1:
 | 
						|
            if pipe_list[1] == ['wc', '-l']:
 | 
						|
                wc = True
 | 
						|
            else:
 | 
						|
                print 'invalid pipe', kwargs
 | 
						|
                sys.exit(1)
 | 
						|
        cmd = pipe_list[0][0]
 | 
						|
        args = pipe_list[0][1:]
 | 
						|
        result = None
 | 
						|
        if cmd == 'git':
 | 
						|
            result = self._HandleCommandGit(args)
 | 
						|
        elif cmd == './scripts/show-gnu-make':
 | 
						|
            return command.CommandResult(return_code=0, stdout='make')
 | 
						|
        elif cmd.endswith('nm'):
 | 
						|
            return self._HandleCommandNm(args)
 | 
						|
        elif cmd.endswith('objdump'):
 | 
						|
            return self._HandleCommandObjdump(args)
 | 
						|
        elif cmd.endswith( 'size'):
 | 
						|
            return self._HandleCommandSize(args)
 | 
						|
 | 
						|
        if not result:
 | 
						|
            # Not handled, so abort
 | 
						|
            print 'unknown command', kwargs
 | 
						|
            sys.exit(1)
 | 
						|
 | 
						|
        if wc:
 | 
						|
            result.stdout = len(result.stdout.splitlines())
 | 
						|
        return result
 | 
						|
 | 
						|
    def _HandleMake(self, commit, brd, stage, cwd, *args, **kwargs):
 | 
						|
        """Handle execution of 'make'
 | 
						|
 | 
						|
        Args:
 | 
						|
            commit: Commit object that is being built
 | 
						|
            brd: Board object that is being built
 | 
						|
            stage: Stage that we are at (mrproper, config, build)
 | 
						|
            cwd: Directory where make should be run
 | 
						|
            args: Arguments to pass to make
 | 
						|
            kwargs: Arguments to pass to command.RunPipe()
 | 
						|
        """
 | 
						|
        self._make_calls += 1
 | 
						|
        if stage == 'mrproper':
 | 
						|
            return command.CommandResult(return_code=0)
 | 
						|
        elif stage == 'config':
 | 
						|
            return command.CommandResult(return_code=0,
 | 
						|
                    combined='Test configuration complete')
 | 
						|
        elif stage == 'build':
 | 
						|
            stderr = ''
 | 
						|
            if type(commit) is not str:
 | 
						|
                stderr = self._error.get((brd.target, commit.sequence))
 | 
						|
            if stderr:
 | 
						|
                return command.CommandResult(return_code=1, stderr=stderr)
 | 
						|
            return command.CommandResult(return_code=0)
 | 
						|
 | 
						|
        # Not handled, so abort
 | 
						|
        print 'make', stage
 | 
						|
        sys.exit(1)
 | 
						|
 | 
						|
    # Example function to print output lines
 | 
						|
    def print_lines(self, lines):
 | 
						|
        print len(lines)
 | 
						|
        for line in lines:
 | 
						|
            print line
 | 
						|
        #self.print_lines(terminal.GetPrintTestLines())
 | 
						|
 | 
						|
    def testNoBoards(self):
 | 
						|
        """Test that buildman aborts when there are no boards"""
 | 
						|
        self._boards = board.Boards()
 | 
						|
        with self.assertRaises(SystemExit):
 | 
						|
            self._RunControl()
 | 
						|
 | 
						|
    def testCurrentSource(self):
 | 
						|
        """Very simple test to invoke buildman on the current source"""
 | 
						|
        self.setupToolchains();
 | 
						|
        self._RunControl()
 | 
						|
        lines = terminal.GetPrintTestLines()
 | 
						|
        self.assertIn('Building current source for %d boards' % len(boards),
 | 
						|
                      lines[0].text)
 | 
						|
 | 
						|
    def testBadBranch(self):
 | 
						|
        """Test that we can detect an invalid branch"""
 | 
						|
        with self.assertRaises(ValueError):
 | 
						|
            self._RunControl('-b', 'badbranch')
 | 
						|
 | 
						|
    def testBadToolchain(self):
 | 
						|
        """Test that missing toolchains are detected"""
 | 
						|
        self.setupToolchains();
 | 
						|
        ret_code = self._RunControl('-b', TEST_BRANCH)
 | 
						|
        lines = terminal.GetPrintTestLines()
 | 
						|
 | 
						|
        # Buildman always builds the upstream commit as well
 | 
						|
        self.assertIn('Building %d commits for %d boards' %
 | 
						|
                (self._commits, len(boards)), lines[0].text)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
 | 
						|
        # Only sandbox should succeed, the others don't have toolchains
 | 
						|
        self.assertEqual(self._builder.fail,
 | 
						|
                         self._total_builds - self._commits)
 | 
						|
        self.assertEqual(ret_code, 128)
 | 
						|
 | 
						|
        for commit in range(self._commits):
 | 
						|
            for board in self._boards.GetList():
 | 
						|
                if board.arch != 'sandbox':
 | 
						|
                  errfile = self._builder.GetErrFile(commit, board.target)
 | 
						|
                  fd = open(errfile)
 | 
						|
                  self.assertEqual(fd.readlines(),
 | 
						|
                          ['No tool chain for %s\n' % board.arch])
 | 
						|
                  fd.close()
 | 
						|
 | 
						|
    def testBranch(self):
 | 
						|
        """Test building a branch with all toolchains present"""
 | 
						|
        self._RunControl('-b', TEST_BRANCH)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
        self.assertEqual(self._builder.fail, 0)
 | 
						|
 | 
						|
    def testCount(self):
 | 
						|
        """Test building a specific number of commitst"""
 | 
						|
        self._RunControl('-b', TEST_BRANCH, '-c2')
 | 
						|
        self.assertEqual(self._builder.count, 2 * len(boards))
 | 
						|
        self.assertEqual(self._builder.fail, 0)
 | 
						|
        # Each board has a mrproper, config, and then one make per commit
 | 
						|
        self.assertEqual(self._make_calls, len(boards) * (2 + 2))
 | 
						|
 | 
						|
    def testIncremental(self):
 | 
						|
        """Test building a branch twice - the second time should do nothing"""
 | 
						|
        self._RunControl('-b', TEST_BRANCH)
 | 
						|
 | 
						|
        # Each board has a mrproper, config, and then one make per commit
 | 
						|
        self.assertEqual(self._make_calls, len(boards) * (self._commits + 2))
 | 
						|
        self._make_calls = 0
 | 
						|
        self._RunControl('-b', TEST_BRANCH, clean_dir=False)
 | 
						|
        self.assertEqual(self._make_calls, 0)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
        self.assertEqual(self._builder.fail, 0)
 | 
						|
 | 
						|
    def testForceBuild(self):
 | 
						|
        """The -f flag should force a rebuild"""
 | 
						|
        self._RunControl('-b', TEST_BRANCH)
 | 
						|
        self._make_calls = 0
 | 
						|
        self._RunControl('-b', TEST_BRANCH, '-f', clean_dir=False)
 | 
						|
        # Each board has a mrproper, config, and then one make per commit
 | 
						|
        self.assertEqual(self._make_calls, len(boards) * (self._commits + 2))
 | 
						|
 | 
						|
    def testForceReconfigure(self):
 | 
						|
        """The -f flag should force a rebuild"""
 | 
						|
        self._RunControl('-b', TEST_BRANCH, '-C')
 | 
						|
        # Each commit has a mrproper, config and make
 | 
						|
        self.assertEqual(self._make_calls, len(boards) * self._commits * 3)
 | 
						|
 | 
						|
    def testErrors(self):
 | 
						|
        """Test handling of build errors"""
 | 
						|
        self._error['board2', 1] = 'fred\n'
 | 
						|
        self._RunControl('-b', TEST_BRANCH)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
        self.assertEqual(self._builder.fail, 1)
 | 
						|
 | 
						|
        # Remove the error. This should have no effect since the commit will
 | 
						|
        # not be rebuilt
 | 
						|
        del self._error['board2', 1]
 | 
						|
        self._make_calls = 0
 | 
						|
        self._RunControl('-b', TEST_BRANCH, clean_dir=False)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
        self.assertEqual(self._make_calls, 0)
 | 
						|
        self.assertEqual(self._builder.fail, 1)
 | 
						|
 | 
						|
        # Now use the -F flag to force rebuild of the bad commit
 | 
						|
        self._RunControl('-b', TEST_BRANCH, '-F', clean_dir=False)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
        self.assertEqual(self._builder.fail, 0)
 | 
						|
        self.assertEqual(self._make_calls, 3)
 | 
						|
 | 
						|
    def testBranchWithSlash(self):
 | 
						|
        """Test building a branch with a '/' in the name"""
 | 
						|
        self._test_branch = '/__dev/__testbranch'
 | 
						|
        self._RunControl('-b', self._test_branch, clean_dir=False)
 | 
						|
        self.assertEqual(self._builder.count, self._total_builds)
 | 
						|
        self.assertEqual(self._builder.fail, 0)
 |