Merge tag 'xilinx-for-v2021.01' of https://gitlab.denx.de/u-boot/custodians/u-boot...
[platform/kernel/u-boot.git] / tools / buildman / test.py
1 # SPDX-License-Identifier: GPL-2.0+
2 # Copyright (c) 2012 The Chromium OS Authors.
3 #
4
5 import os
6 import shutil
7 import sys
8 import tempfile
9 import time
10 import unittest
11
12 from buildman import board
13 from buildman import bsettings
14 from buildman import builder
15 from buildman import control
16 from buildman import toolchain
17 from patman import commit
18 from patman import command
19 from patman import terminal
20 from patman import test_util
21 from patman import tools
22
23 use_network = True
24
25 settings_data = '''
26 # Buildman settings file
27
28 [toolchain]
29 main: /usr/sbin
30
31 [toolchain-alias]
32 x86: i386 x86_64
33 '''
34
35 migration = '''===================== WARNING ======================
36 This board does not use CONFIG_DM. CONFIG_DM will be
37 compulsory starting with the v2020.01 release.
38 Failure to update may result in board removal.
39 See doc/driver-model/migration.rst for more info.
40 ====================================================
41 '''
42
43 errors = [
44     '''main.c: In function 'main_loop':
45 main.c:260:6: warning: unused variable 'joe' [-Wunused-variable]
46 ''',
47     '''main.c: In function 'main_loop2':
48 main.c:295:2: error: 'fred' undeclared (first use in this function)
49 main.c:295:2: note: each undeclared identifier is reported only once for each function it appears in
50 make[1]: *** [main.o] Error 1
51 make: *** [common/libcommon.o] Error 2
52 Make failed
53 ''',
54     '''arch/arm/dts/socfpga_arria10_socdk_sdmmc.dtb: Warning \
55 (avoid_unnecessary_addr_size): /clocks: unnecessary #address-cells/#size-cells \
56 without "ranges" or child "reg" property
57 ''',
58     '''powerpc-linux-ld: warning: dot moved backwards before `.bss'
59 powerpc-linux-ld: warning: dot moved backwards before `.bss'
60 powerpc-linux-ld: u-boot: section .text lma 0xfffc0000 overlaps previous sections
61 powerpc-linux-ld: u-boot: section .rodata lma 0xfffef3ec overlaps previous sections
62 powerpc-linux-ld: u-boot: section .reloc lma 0xffffa400 overlaps previous sections
63 powerpc-linux-ld: u-boot: section .data lma 0xffffcd38 overlaps previous sections
64 powerpc-linux-ld: u-boot: section .u_boot_cmd lma 0xffffeb40 overlaps previous sections
65 powerpc-linux-ld: u-boot: section .bootpg lma 0xfffff198 overlaps previous sections
66 ''',
67    '''In file included from %(basedir)sarch/sandbox/cpu/cpu.c:9:0:
68 %(basedir)sarch/sandbox/include/asm/state.h:44:0: warning: "xxxx" redefined [enabled by default]
69 %(basedir)sarch/sandbox/include/asm/state.h:43:0: note: this is the location of the previous definition
70 %(basedir)sarch/sandbox/cpu/cpu.c: In function 'do_reset':
71 %(basedir)sarch/sandbox/cpu/cpu.c:27:1: error: unknown type name 'blah'
72 %(basedir)sarch/sandbox/cpu/cpu.c:28:12: error: expected declaration specifiers or '...' before numeric constant
73 make[2]: *** [arch/sandbox/cpu/cpu.o] Error 1
74 make[1]: *** [arch/sandbox/cpu] Error 2
75 make[1]: *** Waiting for unfinished jobs....
76 In file included from %(basedir)scommon/board_f.c:55:0:
77 %(basedir)sarch/sandbox/include/asm/state.h:44:0: warning: "xxxx" redefined [enabled by default]
78 %(basedir)sarch/sandbox/include/asm/state.h:43:0: note: this is the location of the previous definition
79 make: *** [sub-make] Error 2
80 '''
81 ]
82
83
84 # hash, subject, return code, list of errors/warnings
85 commits = [
86     ['1234', 'upstream/master, migration warning', 0, []],
87     ['5678', 'Second commit, a warning', 0, errors[0:1]],
88     ['9012', 'Third commit, error', 1, errors[0:2]],
89     ['3456', 'Fourth commit, warning', 0, [errors[0], errors[2]]],
90     ['7890', 'Fifth commit, link errors', 1, [errors[0], errors[3]]],
91     ['abcd', 'Sixth commit, fixes all errors', 0, []],
92     ['ef01', 'Seventh commit, fix migration, check directory suppression', 1,
93      [errors[4]]],
94 ]
95
96 boards = [
97     ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 1', 'board0',  ''],
98     ['Active', 'arm', 'armv7', '', 'Tester', 'ARM Board 2', 'board1', ''],
99     ['Active', 'powerpc', 'powerpc', '', 'Tester', 'PowerPC board 1', 'board2', ''],
100     ['Active', 'powerpc', 'mpc83xx', '', 'Tester', 'PowerPC board 2', 'board3', ''],
101     ['Active', 'sandbox', 'sandbox', '', 'Tester', 'Sandbox board', 'board4', ''],
102 ]
103
104 BASE_DIR = 'base'
105
106 OUTCOME_OK, OUTCOME_WARN, OUTCOME_ERR = range(3)
107
108 class Options:
109     """Class that holds build options"""
110     pass
111
112 class TestBuild(unittest.TestCase):
113     """Test buildman
114
115     TODO: Write tests for the rest of the functionality
116     """
117     def setUp(self):
118         # Set up commits to build
119         self.commits = []
120         sequence = 0
121         for commit_info in commits:
122             comm = commit.Commit(commit_info[0])
123             comm.subject = commit_info[1]
124             comm.return_code = commit_info[2]
125             comm.error_list = commit_info[3]
126             if sequence < 6:
127                  comm.error_list += [migration]
128             comm.sequence = sequence
129             sequence += 1
130             self.commits.append(comm)
131
132         # Set up boards to build
133         self.boards = board.Boards()
134         for brd in boards:
135             self.boards.AddBoard(board.Board(*brd))
136         self.boards.SelectBoards([])
137
138         # Add some test settings
139         bsettings.Setup(None)
140         bsettings.AddFile(settings_data)
141
142         # Set up the toolchains
143         self.toolchains = toolchain.Toolchains()
144         self.toolchains.Add('arm-linux-gcc', test=False)
145         self.toolchains.Add('sparc-linux-gcc', test=False)
146         self.toolchains.Add('powerpc-linux-gcc', test=False)
147         self.toolchains.Add('gcc', test=False)
148
149         # Avoid sending any output
150         terminal.SetPrintTestMode()
151         self._col = terminal.Color()
152
153         self.base_dir = tempfile.mkdtemp()
154         if not os.path.isdir(self.base_dir):
155             os.mkdir(self.base_dir)
156
157     def tearDown(self):
158         shutil.rmtree(self.base_dir)
159
160     def Make(self, commit, brd, stage, *args, **kwargs):
161         result = command.CommandResult()
162         boardnum = int(brd.target[-1])
163         result.return_code = 0
164         result.stderr = ''
165         result.stdout = ('This is the test output for board %s, commit %s' %
166                 (brd.target, commit.hash))
167         if ((boardnum >= 1 and boardnum >= commit.sequence) or
168                 boardnum == 4 and commit.sequence == 6):
169             result.return_code = commit.return_code
170             result.stderr = (''.join(commit.error_list)
171                 % {'basedir' : self.base_dir + '/.bm-work/00/'})
172         elif commit.sequence < 6:
173             result.stderr = migration
174
175         result.combined = result.stdout + result.stderr
176         return result
177
178     def assertSummary(self, text, arch, plus, boards, outcome=OUTCOME_ERR):
179         col = self._col
180         expected_colour = (col.GREEN if outcome == OUTCOME_OK else
181                            col.YELLOW if outcome == OUTCOME_WARN else col.RED)
182         expect = '%10s: ' % arch
183         # TODO(sjg@chromium.org): If plus is '', we shouldn't need this
184         expect += ' ' + col.Color(expected_colour, plus)
185         expect += '  '
186         for board in boards:
187             expect += col.Color(expected_colour, ' %s' % board)
188         self.assertEqual(text, expect)
189
190     def _SetupTest(self, echo_lines=False, **kwdisplay_args):
191         """Set up the test by running a build and summary
192
193         Args:
194             echo_lines: True to echo lines to the terminal to aid test
195                 development
196             kwdisplay_args: Dict of arguemnts to pass to
197                 Builder.SetDisplayOptions()
198
199         Returns:
200             Iterator containing the output lines, each a PrintLine() object
201         """
202         build = builder.Builder(self.toolchains, self.base_dir, None, 1, 2,
203                                 checkout=False, show_unknown=False)
204         build.do_make = self.Make
205         board_selected = self.boards.GetSelectedDict()
206
207         # Build the boards for the pre-defined commits and warnings/errors
208         # associated with each. This calls our Make() to inject the fake output.
209         build.BuildBoards(self.commits, board_selected, keep_outputs=False,
210                           verbose=False)
211         lines = terminal.GetPrintTestLines()
212         count = 0
213         for line in lines:
214             if line.text.strip():
215                 count += 1
216
217         # We should get two starting messages, an update for every commit built
218         # and a summary message
219         self.assertEqual(count, len(commits) * len(boards) + 3)
220         build.SetDisplayOptions(**kwdisplay_args);
221         build.ShowSummary(self.commits, board_selected)
222         if echo_lines:
223             terminal.EchoPrintTestLines()
224         return iter(terminal.GetPrintTestLines())
225
226     def _CheckOutput(self, lines, list_error_boards=False,
227                      filter_dtb_warnings=False,
228                      filter_migration_warnings=False):
229         """Check for expected output from the build summary
230
231         Args:
232             lines: Iterator containing the lines returned from the summary
233             list_error_boards: Adjust the check for output produced with the
234                --list-error-boards flag
235             filter_dtb_warnings: Adjust the check for output produced with the
236                --filter-dtb-warnings flag
237         """
238         def add_line_prefix(prefix, boards, error_str, colour):
239             """Add a prefix to each line of a string
240
241             The training \n in error_str is removed before processing
242
243             Args:
244                 prefix: String prefix to add
245                 error_str: Error string containing the lines
246                 colour: Expected colour for the line. Note that the board list,
247                     if present, always appears in magenta
248
249             Returns:
250                 New string where each line has the prefix added
251             """
252             lines = error_str.strip().splitlines()
253             new_lines = []
254             for line in lines:
255                 if boards:
256                     expect = self._col.Color(colour, prefix + '(')
257                     expect += self._col.Color(self._col.MAGENTA, boards,
258                                               bright=False)
259                     expect += self._col.Color(colour, ') %s' % line)
260                 else:
261                     expect = self._col.Color(colour, prefix + line)
262                 new_lines.append(expect)
263             return '\n'.join(new_lines)
264
265         col = terminal.Color()
266         boards01234 = ('board0 board1 board2 board3 board4'
267                        if list_error_boards else '')
268         boards1234 = 'board1 board2 board3 board4' if list_error_boards else ''
269         boards234 = 'board2 board3 board4' if list_error_boards else ''
270         boards34 = 'board3 board4' if list_error_boards else ''
271         boards4 = 'board4' if list_error_boards else ''
272
273         # Upstream commit: migration warnings only
274         self.assertEqual(next(lines).text, '01: %s' % commits[0][1])
275
276         if not filter_migration_warnings:
277             self.assertSummary(next(lines).text, 'arm', 'w+',
278                                ['board0', 'board1'], outcome=OUTCOME_WARN)
279             self.assertSummary(next(lines).text, 'powerpc', 'w+',
280                                ['board2', 'board3'], outcome=OUTCOME_WARN)
281             self.assertSummary(next(lines).text, 'sandbox', 'w+', ['board4'],
282                                outcome=OUTCOME_WARN)
283
284             self.assertEqual(next(lines).text,
285                 add_line_prefix('+', boards01234, migration, col.RED))
286
287         # Second commit: all archs should fail with warnings
288         self.assertEqual(next(lines).text, '02: %s' % commits[1][1])
289
290         if filter_migration_warnings:
291             self.assertSummary(next(lines).text, 'arm', 'w+',
292                                ['board1'], outcome=OUTCOME_WARN)
293             self.assertSummary(next(lines).text, 'powerpc', 'w+',
294                                ['board2', 'board3'], outcome=OUTCOME_WARN)
295             self.assertSummary(next(lines).text, 'sandbox', 'w+', ['board4'],
296                                outcome=OUTCOME_WARN)
297
298         # Second commit: The warnings should be listed
299         self.assertEqual(next(lines).text,
300             add_line_prefix('w+', boards1234, errors[0], col.YELLOW))
301
302         # Third commit: Still fails
303         self.assertEqual(next(lines).text, '03: %s' % commits[2][1])
304         if filter_migration_warnings:
305             self.assertSummary(next(lines).text, 'arm', '',
306                                ['board1'], outcome=OUTCOME_OK)
307         self.assertSummary(next(lines).text, 'powerpc', '+',
308                            ['board2', 'board3'])
309         self.assertSummary(next(lines).text, 'sandbox', '+', ['board4'])
310
311         # Expect a compiler error
312         self.assertEqual(next(lines).text,
313                          add_line_prefix('+', boards234, errors[1], col.RED))
314
315         # Fourth commit: Compile errors are fixed, just have warning for board3
316         self.assertEqual(next(lines).text, '04: %s' % commits[3][1])
317         if filter_migration_warnings:
318             expect = '%10s: ' % 'powerpc'
319             expect += ' ' + col.Color(col.GREEN, '')
320             expect += '  '
321             expect += col.Color(col.GREEN, ' %s' % 'board2')
322             expect += ' ' + col.Color(col.YELLOW, 'w+')
323             expect += '  '
324             expect += col.Color(col.YELLOW, ' %s' % 'board3')
325             self.assertEqual(next(lines).text, expect)
326         else:
327             self.assertSummary(next(lines).text, 'powerpc', 'w+',
328                                ['board2', 'board3'], outcome=OUTCOME_WARN)
329         self.assertSummary(next(lines).text, 'sandbox', 'w+', ['board4'],
330                                outcome=OUTCOME_WARN)
331
332         # Compile error fixed
333         self.assertEqual(next(lines).text,
334                          add_line_prefix('-', boards234, errors[1], col.GREEN))
335
336         if not filter_dtb_warnings:
337             self.assertEqual(
338                 next(lines).text,
339                 add_line_prefix('w+', boards34, errors[2], col.YELLOW))
340
341         # Fifth commit
342         self.assertEqual(next(lines).text, '05: %s' % commits[4][1])
343         if filter_migration_warnings:
344             self.assertSummary(next(lines).text, 'powerpc', '', ['board3'],
345                                outcome=OUTCOME_OK)
346         self.assertSummary(next(lines).text, 'sandbox', '+', ['board4'])
347
348         # The second line of errors[3] is a duplicate, so buildman will drop it
349         expect = errors[3].rstrip().split('\n')
350         expect = [expect[0]] + expect[2:]
351         expect = '\n'.join(expect)
352         self.assertEqual(next(lines).text,
353                          add_line_prefix('+', boards4, expect, col.RED))
354
355         if not filter_dtb_warnings:
356             self.assertEqual(
357                 next(lines).text,
358                 add_line_prefix('w-', boards34, errors[2], col.CYAN))
359
360         # Sixth commit
361         self.assertEqual(next(lines).text, '06: %s' % commits[5][1])
362         if filter_migration_warnings:
363             self.assertSummary(next(lines).text, 'sandbox', '', ['board4'],
364                                outcome=OUTCOME_OK)
365         else:
366             self.assertSummary(next(lines).text, 'sandbox', 'w+', ['board4'],
367                                outcome=OUTCOME_WARN)
368
369         # The second line of errors[3] is a duplicate, so buildman will drop it
370         expect = errors[3].rstrip().split('\n')
371         expect = [expect[0]] + expect[2:]
372         expect = '\n'.join(expect)
373         self.assertEqual(next(lines).text,
374                          add_line_prefix('-', boards4, expect, col.GREEN))
375         self.assertEqual(next(lines).text,
376                          add_line_prefix('w-', boards4, errors[0], col.CYAN))
377
378         # Seventh commit
379         self.assertEqual(next(lines).text, '07: %s' % commits[6][1])
380         if filter_migration_warnings:
381             self.assertSummary(next(lines).text, 'sandbox', '+', ['board4'])
382         else:
383             self.assertSummary(next(lines).text, 'arm', '', ['board0', 'board1'],
384                                outcome=OUTCOME_OK)
385             self.assertSummary(next(lines).text, 'powerpc', '',
386                                ['board2', 'board3'], outcome=OUTCOME_OK)
387             self.assertSummary(next(lines).text, 'sandbox', '+', ['board4'])
388
389         # Pick out the correct error lines
390         expect_str = errors[4].rstrip().replace('%(basedir)s', '').split('\n')
391         expect = expect_str[3:8] + [expect_str[-1]]
392         expect = '\n'.join(expect)
393         if not filter_migration_warnings:
394             self.assertEqual(
395                 next(lines).text,
396                 add_line_prefix('-', boards01234, migration, col.GREEN))
397
398         self.assertEqual(next(lines).text,
399                          add_line_prefix('+', boards4, expect, col.RED))
400
401         # Now the warnings lines
402         expect = [expect_str[0]] + expect_str[10:12] + [expect_str[9]]
403         expect = '\n'.join(expect)
404         self.assertEqual(next(lines).text,
405                          add_line_prefix('w+', boards4, expect, col.YELLOW))
406
407     def testOutput(self):
408         """Test basic builder operation and output
409
410         This does a line-by-line verification of the summary output.
411         """
412         lines = self._SetupTest(show_errors=True)
413         self._CheckOutput(lines, list_error_boards=False,
414                           filter_dtb_warnings=False)
415
416     def testErrorBoards(self):
417         """Test output with --list-error-boards
418
419         This does a line-by-line verification of the summary output.
420         """
421         lines = self._SetupTest(show_errors=True, list_error_boards=True)
422         self._CheckOutput(lines, list_error_boards=True)
423
424     def testFilterDtb(self):
425         """Test output with --filter-dtb-warnings
426
427         This does a line-by-line verification of the summary output.
428         """
429         lines = self._SetupTest(show_errors=True, filter_dtb_warnings=True)
430         self._CheckOutput(lines, filter_dtb_warnings=True)
431
432     def testFilterMigration(self):
433         """Test output with --filter-migration-warnings
434
435         This does a line-by-line verification of the summary output.
436         """
437         lines = self._SetupTest(show_errors=True,
438                                 filter_migration_warnings=True)
439         self._CheckOutput(lines, filter_migration_warnings=True)
440
441     def _testGit(self):
442         """Test basic builder operation by building a branch"""
443         options = Options()
444         options.git = os.getcwd()
445         options.summary = False
446         options.jobs = None
447         options.dry_run = False
448         #options.git = os.path.join(self.base_dir, 'repo')
449         options.branch = 'test-buildman'
450         options.force_build = False
451         options.list_tool_chains = False
452         options.count = -1
453         options.git_dir = None
454         options.threads = None
455         options.show_unknown = False
456         options.quick = False
457         options.show_errors = False
458         options.keep_outputs = False
459         args = ['tegra20']
460         control.DoBuildman(options, args)
461
462     def testBoardSingle(self):
463         """Test single board selection"""
464         self.assertEqual(self.boards.SelectBoards(['sandbox']),
465                          ({'all': ['board4'], 'sandbox': ['board4']}, []))
466
467     def testBoardArch(self):
468         """Test single board selection"""
469         self.assertEqual(self.boards.SelectBoards(['arm']),
470                          ({'all': ['board0', 'board1'],
471                           'arm': ['board0', 'board1']}, []))
472
473     def testBoardArchSingle(self):
474         """Test single board selection"""
475         self.assertEqual(self.boards.SelectBoards(['arm sandbox']),
476                          ({'sandbox': ['board4'],
477                           'all': ['board0', 'board1', 'board4'],
478                           'arm': ['board0', 'board1']}, []))
479
480
481     def testBoardArchSingleMultiWord(self):
482         """Test single board selection"""
483         self.assertEqual(self.boards.SelectBoards(['arm', 'sandbox']),
484                          ({'sandbox': ['board4'],
485                           'all': ['board0', 'board1', 'board4'],
486                           'arm': ['board0', 'board1']}, []))
487
488     def testBoardSingleAnd(self):
489         """Test single board selection"""
490         self.assertEqual(self.boards.SelectBoards(['Tester & arm']),
491                          ({'Tester&arm': ['board0', 'board1'],
492                            'all': ['board0', 'board1']}, []))
493
494     def testBoardTwoAnd(self):
495         """Test single board selection"""
496         self.assertEqual(self.boards.SelectBoards(['Tester', '&', 'arm',
497                                                    'Tester' '&', 'powerpc',
498                                                    'sandbox']),
499                          ({'sandbox': ['board4'],
500                           'all': ['board0', 'board1', 'board2', 'board3',
501                                   'board4'],
502                           'Tester&powerpc': ['board2', 'board3'],
503                           'Tester&arm': ['board0', 'board1']}, []))
504
505     def testBoardAll(self):
506         """Test single board selection"""
507         self.assertEqual(self.boards.SelectBoards([]),
508                          ({'all': ['board0', 'board1', 'board2', 'board3',
509                                   'board4']}, []))
510
511     def testBoardRegularExpression(self):
512         """Test single board selection"""
513         self.assertEqual(self.boards.SelectBoards(['T.*r&^Po']),
514                          ({'all': ['board2', 'board3'],
515                           'T.*r&^Po': ['board2', 'board3']}, []))
516
517     def testBoardDuplicate(self):
518         """Test single board selection"""
519         self.assertEqual(self.boards.SelectBoards(['sandbox sandbox',
520                                                    'sandbox']),
521                          ({'all': ['board4'], 'sandbox': ['board4']}, []))
522     def CheckDirs(self, build, dirname):
523         self.assertEqual('base%s' % dirname, build._GetOutputDir(1))
524         self.assertEqual('base%s/fred' % dirname,
525                          build.GetBuildDir(1, 'fred'))
526         self.assertEqual('base%s/fred/done' % dirname,
527                          build.GetDoneFile(1, 'fred'))
528         self.assertEqual('base%s/fred/u-boot.sizes' % dirname,
529                          build.GetFuncSizesFile(1, 'fred', 'u-boot'))
530         self.assertEqual('base%s/fred/u-boot.objdump' % dirname,
531                          build.GetObjdumpFile(1, 'fred', 'u-boot'))
532         self.assertEqual('base%s/fred/err' % dirname,
533                          build.GetErrFile(1, 'fred'))
534
535     def testOutputDir(self):
536         build = builder.Builder(self.toolchains, BASE_DIR, None, 1, 2,
537                                 checkout=False, show_unknown=False)
538         build.commits = self.commits
539         build.commit_count = len(self.commits)
540         subject = self.commits[1].subject.translate(builder.trans_valid_chars)
541         dirname ='/%02d_g%s_%s' % (2, commits[1][0], subject[:20])
542         self.CheckDirs(build, dirname)
543
544     def testOutputDirCurrent(self):
545         build = builder.Builder(self.toolchains, BASE_DIR, None, 1, 2,
546                                 checkout=False, show_unknown=False)
547         build.commits = None
548         build.commit_count = 0
549         self.CheckDirs(build, '/current')
550
551     def testOutputDirNoSubdirs(self):
552         build = builder.Builder(self.toolchains, BASE_DIR, None, 1, 2,
553                                 checkout=False, show_unknown=False,
554                                 no_subdirs=True)
555         build.commits = None
556         build.commit_count = 0
557         self.CheckDirs(build, '')
558
559     def testToolchainAliases(self):
560         self.assertTrue(self.toolchains.Select('arm') != None)
561         with self.assertRaises(ValueError):
562             self.toolchains.Select('no-arch')
563         with self.assertRaises(ValueError):
564             self.toolchains.Select('x86')
565
566         self.toolchains = toolchain.Toolchains()
567         self.toolchains.Add('x86_64-linux-gcc', test=False)
568         self.assertTrue(self.toolchains.Select('x86') != None)
569
570         self.toolchains = toolchain.Toolchains()
571         self.toolchains.Add('i386-linux-gcc', test=False)
572         self.assertTrue(self.toolchains.Select('x86') != None)
573
574     def testToolchainDownload(self):
575         """Test that we can download toolchains"""
576         if use_network:
577             with test_util.capture_sys_output() as (stdout, stderr):
578                 url = self.toolchains.LocateArchUrl('arm')
579             self.assertRegexpMatches(url, 'https://www.kernel.org/pub/tools/'
580                     'crosstool/files/bin/x86_64/.*/'
581                     'x86_64-gcc-.*-nolibc[-_]arm-.*linux-gnueabi.tar.xz')
582
583     def testGetEnvArgs(self):
584         """Test the GetEnvArgs() function"""
585         tc = self.toolchains.Select('arm')
586         self.assertEqual('arm-linux-',
587                          tc.GetEnvArgs(toolchain.VAR_CROSS_COMPILE))
588         self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_PATH))
589         self.assertEqual('arm',
590                          tc.GetEnvArgs(toolchain.VAR_ARCH))
591         self.assertEqual('', tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS))
592
593         self.toolchains.Add('/path/to/x86_64-linux-gcc', test=False)
594         tc = self.toolchains.Select('x86')
595         self.assertEqual('/path/to',
596                          tc.GetEnvArgs(toolchain.VAR_PATH))
597         tc.override_toolchain = 'clang'
598         self.assertEqual('HOSTCC=clang CC=clang',
599                          tc.GetEnvArgs(toolchain.VAR_MAKE_ARGS))
600
601     def testPrepareOutputSpace(self):
602         def _Touch(fname):
603             tools.WriteFile(os.path.join(base_dir, fname), b'')
604
605         base_dir = tempfile.mkdtemp()
606
607         # Add various files that we want removed and left alone
608         to_remove = ['01_g0982734987_title', '102_g92bf_title',
609                      '01_g2938abd8_title']
610         to_leave = ['something_else', '01-something.patch', '01_another']
611         for name in to_remove + to_leave:
612             _Touch(name)
613
614         build = builder.Builder(self.toolchains, base_dir, None, 1, 2)
615         build.commits = self.commits
616         build.commit_count = len(commits)
617         result = set(build._GetOutputSpaceRemovals())
618         expected = set([os.path.join(base_dir, f) for f in to_remove])
619         self.assertEqual(expected, result)
620
621 if __name__ == "__main__":
622     unittest.main()