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