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