blob: 5b589b4940651e0903eb3d2267e370a0a02b2ebd [file] [log] [blame]
Mike Frysinger69cb41d2013-08-11 20:08:19 -04001# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
Don Garrett25f309a2014-03-19 14:02:12 -07005"""Test cros_generate_breakpad_symbols."""
6
Mike Frysinger69cb41d2013-08-11 20:08:19 -04007import ctypes
Mike Frysinger374ba4f2019-11-14 23:45:15 -05008import io
Mike Frysinger69cb41d2013-08-11 20:08:19 -04009import os
Mike Frysinger166fea02021-02-12 05:30:33 -050010from unittest import mock
Mike Frysinger69cb41d2013-08-11 20:08:19 -040011
Mike Frysinger69cb41d2013-08-11 20:08:19 -040012from chromite.lib import cros_test_lib
13from chromite.lib import osutils
14from chromite.lib import parallel
15from chromite.lib import parallel_unittest
16from chromite.lib import partial_mock
17from chromite.scripts import cros_generate_breakpad_symbols
18
Mike Frysinger69cb41d2013-08-11 20:08:19 -040019
20class FindDebugDirMock(partial_mock.PartialMock):
21 """Mock out the DebugDir helper so we can point it to a tempdir."""
22
23 TARGET = 'chromite.scripts.cros_generate_breakpad_symbols'
24 ATTRS = ('FindDebugDir',)
25 DEFAULT_ATTR = 'FindDebugDir'
26
Mike Frysingerc15efa52013-12-12 01:13:56 -050027 def __init__(self, path, *args, **kwargs):
Mike Frysinger69cb41d2013-08-11 20:08:19 -040028 self.path = path
Jae Hoon Kimad176b82021-07-26 19:29:29 +000029 super().__init__(*args, **kwargs)
Mike Frysinger69cb41d2013-08-11 20:08:19 -040030
Mike Frysinger3f571af2016-08-31 23:56:53 -040031 # pylint: disable=unused-argument
32 def FindDebugDir(self, _board, sysroot=None):
Mike Frysinger69cb41d2013-08-11 20:08:19 -040033 return self.path
34
35
Mike Frysinger3ef6d972019-08-24 20:07:42 -040036# This long decorator triggers a false positive in the docstring test.
37# https://github.com/PyCQA/pylint/issues/3077
38# pylint: disable=bad-docstring-quotes
Mike Frysinger69cb41d2013-08-11 20:08:19 -040039@mock.patch('chromite.scripts.cros_generate_breakpad_symbols.'
40 'GenerateBreakpadSymbol')
41class GenerateSymbolsTest(cros_test_lib.MockTempDirTestCase):
Don Garrettf8bf7842014-03-20 17:03:42 -070042 """Test GenerateBreakpadSymbols."""
Mike Frysinger69cb41d2013-08-11 20:08:19 -040043
44 def setUp(self):
45 self.board = 'monkey-board'
46 self.board_dir = os.path.join(self.tempdir, 'build', self.board)
47 self.debug_dir = os.path.join(self.board_dir, 'usr', 'lib', 'debug')
48 self.breakpad_dir = os.path.join(self.debug_dir, 'breakpad')
49
50 # Generate a tree of files which we'll scan through.
51 elf_files = [
52 'bin/elf',
53 'iii/large-elf',
54 # Need some kernel modules (with & without matching .debug).
55 'lib/modules/3.10/module.ko',
56 'lib/modules/3.10/module-no-debug.ko',
57 # Need a file which has an ELF only, but not a .debug.
58 'usr/bin/elf-only',
59 'usr/sbin/elf',
60 ]
61 debug_files = [
62 'bin/bad-file',
63 'bin/elf.debug',
64 'iii/large-elf.debug',
Stephen Boydfc1c8032021-10-06 20:58:37 -070065 'boot/vmlinux.debug',
Mike Frysinger69cb41d2013-08-11 20:08:19 -040066 'lib/modules/3.10/module.ko.debug',
67 # Need a file which has a .debug only, but not an ELF.
68 'sbin/debug-only.debug',
69 'usr/sbin/elf.debug',
70 ]
71 for f in ([os.path.join(self.board_dir, x) for x in elf_files] +
72 [os.path.join(self.debug_dir, x) for x in debug_files]):
73 osutils.Touch(f, makedirs=True)
74
75 # Set up random build dirs and symlinks.
76 buildid = os.path.join(self.debug_dir, '.build-id', '00')
77 osutils.SafeMakedirs(buildid)
78 os.symlink('/asdf', os.path.join(buildid, 'foo'))
79 os.symlink('/bin/sh', os.path.join(buildid, 'foo.debug'))
80 os.symlink('/bin/sh', os.path.join(self.debug_dir, 'file.debug'))
81 osutils.WriteFile(os.path.join(self.debug_dir, 'iii', 'large-elf.debug'),
82 'just some content')
83
84 self.StartPatcher(FindDebugDirMock(self.debug_dir))
85
86 def testNormal(self, gen_mock):
87 """Verify all the files we expect to get generated do"""
88 with parallel_unittest.ParallelMock():
89 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
90 self.board, sysroot=self.board_dir)
Mike Frysinger2d589a12019-08-25 14:15:12 -040091 self.assertEqual(ret, 0)
Stephen Boydfc1c8032021-10-06 20:58:37 -070092 self.assertEqual(gen_mock.call_count, 5)
Mike Frysinger69cb41d2013-08-11 20:08:19 -040093
94 # The largest ELF should be processed first.
95 call1 = (os.path.join(self.board_dir, 'iii/large-elf'),
96 os.path.join(self.debug_dir, 'iii/large-elf.debug'))
Mike Frysinger2d589a12019-08-25 14:15:12 -040097 self.assertEqual(gen_mock.call_args_list[0][0], call1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -040098
99 # The other ELFs can be called in any order.
100 call2 = (os.path.join(self.board_dir, 'bin/elf'),
101 os.path.join(self.debug_dir, 'bin/elf.debug'))
102 call3 = (os.path.join(self.board_dir, 'usr/sbin/elf'),
103 os.path.join(self.debug_dir, 'usr/sbin/elf.debug'))
Stephen Boydeecacc22021-09-29 18:52:36 -0700104 call4 = (os.path.join(self.board_dir, 'lib/modules/3.10/module.ko'),
105 os.path.join(self.debug_dir, 'lib/modules/3.10/module.ko.debug'))
Stephen Boydfc1c8032021-10-06 20:58:37 -0700106 call5 = (os.path.join(self.board_dir, 'boot/vmlinux'),
107 os.path.join(self.debug_dir, 'boot/vmlinux.debug'))
108 exp_calls = set((call2, call3, call4, call5))
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400109 actual_calls = set((gen_mock.call_args_list[1][0],
Stephen Boydeecacc22021-09-29 18:52:36 -0700110 gen_mock.call_args_list[2][0],
Stephen Boydfc1c8032021-10-06 20:58:37 -0700111 gen_mock.call_args_list[3][0],
112 gen_mock.call_args_list[4][0]))
Mike Frysinger2d589a12019-08-25 14:15:12 -0400113 self.assertEqual(exp_calls, actual_calls)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400114
Prathmesh Prabhu9995e9b2013-10-31 16:43:55 -0700115 def testFileList(self, gen_mock):
116 """Verify that file_list restricts the symbols generated"""
117 with parallel_unittest.ParallelMock():
118 call1 = (os.path.join(self.board_dir, 'usr/sbin/elf'),
119 os.path.join(self.debug_dir, 'usr/sbin/elf.debug'))
120
121 # Filter with elf path.
122 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
123 self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
124 file_list=[os.path.join(self.board_dir, 'usr', 'sbin', 'elf')])
Mike Frysinger2d589a12019-08-25 14:15:12 -0400125 self.assertEqual(ret, 0)
126 self.assertEqual(gen_mock.call_count, 1)
127 self.assertEqual(gen_mock.call_args_list[0][0], call1)
Prathmesh Prabhu9995e9b2013-10-31 16:43:55 -0700128
129 # Filter with debug symbols file path.
130 gen_mock.reset_mock()
131 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
132 self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
133 file_list=[os.path.join(self.debug_dir, 'usr', 'sbin', 'elf.debug')])
Mike Frysinger2d589a12019-08-25 14:15:12 -0400134 self.assertEqual(ret, 0)
135 self.assertEqual(gen_mock.call_count, 1)
136 self.assertEqual(gen_mock.call_args_list[0][0], call1)
Prathmesh Prabhu9995e9b2013-10-31 16:43:55 -0700137
138
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400139 def testGenLimit(self, gen_mock):
140 """Verify generate_count arg works"""
141 with parallel_unittest.ParallelMock():
142 # Generate nothing!
143 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
144 self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
145 generate_count=0)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400146 self.assertEqual(ret, 0)
147 self.assertEqual(gen_mock.call_count, 0)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400148
149 # Generate just one.
150 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
151 self.board, sysroot=self.board_dir, breakpad_dir=self.breakpad_dir,
152 generate_count=1)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400153 self.assertEqual(ret, 0)
154 self.assertEqual(gen_mock.call_count, 1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400155
156 # The largest ELF should be processed first.
157 call1 = (os.path.join(self.board_dir, 'iii/large-elf'),
158 os.path.join(self.debug_dir, 'iii/large-elf.debug'))
Mike Frysinger2d589a12019-08-25 14:15:12 -0400159 self.assertEqual(gen_mock.call_args_list[0][0], call1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400160
161 def testGenErrors(self, gen_mock):
162 """Verify we handle errors from generation correctly"""
Mike Frysingerc15efa52013-12-12 01:13:56 -0500163 def _SetError(*_args, **kwargs):
164 kwargs['num_errors'].value += 1
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400165 return 1
166 gen_mock.side_effect = _SetError
167 with parallel_unittest.ParallelMock():
168 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
169 self.board, sysroot=self.board_dir)
Stephen Boydfc1c8032021-10-06 20:58:37 -0700170 self.assertEqual(ret, 5)
171 self.assertEqual(gen_mock.call_count, 5)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400172
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400173 def testCleaningTrue(self, gen_mock):
174 """Verify behavior of clean_breakpad=True"""
175 with parallel_unittest.ParallelMock():
176 # Dir does not exist, and then does.
177 self.assertNotExists(self.breakpad_dir)
178 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
179 self.board, sysroot=self.board_dir, generate_count=1,
180 clean_breakpad=True)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400181 self.assertEqual(ret, 0)
182 self.assertEqual(gen_mock.call_count, 1)
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400183 self.assertExists(self.breakpad_dir)
184
185 # Dir exists before & after.
186 # File exists, but then doesn't.
Mike Frysingera5c6e792022-03-15 23:42:12 -0400187 stub_file = os.path.join(self.breakpad_dir, 'fooooooooo')
188 osutils.Touch(stub_file)
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400189 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
190 self.board, sysroot=self.board_dir, generate_count=1,
191 clean_breakpad=True)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400192 self.assertEqual(ret, 0)
193 self.assertEqual(gen_mock.call_count, 2)
Mike Frysingera5c6e792022-03-15 23:42:12 -0400194 self.assertNotExists(stub_file)
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400195
196 def testCleaningFalse(self, gen_mock):
197 """Verify behavior of clean_breakpad=False"""
198 with parallel_unittest.ParallelMock():
199 # Dir does not exist, and then does.
200 self.assertNotExists(self.breakpad_dir)
201 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
202 self.board, sysroot=self.board_dir, generate_count=1,
203 clean_breakpad=False)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400204 self.assertEqual(ret, 0)
205 self.assertEqual(gen_mock.call_count, 1)
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400206 self.assertExists(self.breakpad_dir)
207
208 # Dir exists before & after.
209 # File exists before & after.
Mike Frysingera5c6e792022-03-15 23:42:12 -0400210 stub_file = os.path.join(self.breakpad_dir, 'fooooooooo')
211 osutils.Touch(stub_file)
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400212 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
213 self.board, sysroot=self.board_dir, generate_count=1,
214 clean_breakpad=False)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400215 self.assertEqual(ret, 0)
216 self.assertEqual(gen_mock.call_count, 2)
Mike Frysingera5c6e792022-03-15 23:42:12 -0400217 self.assertExists(stub_file)
Mike Frysinger9a628bb2013-10-24 15:51:37 -0400218
Shawn Nematbakhsh2c169cb2013-10-29 16:23:58 -0700219 def testExclusionList(self, gen_mock):
220 """Verify files in directories of the exclusion list are excluded"""
221 exclude_dirs = ['bin', 'usr', 'fake/dir/fake']
222 with parallel_unittest.ParallelMock():
223 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbols(
224 self.board, sysroot=self.board_dir, exclude_dirs=exclude_dirs)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400225 self.assertEqual(ret, 0)
Stephen Boydfc1c8032021-10-06 20:58:37 -0700226 self.assertEqual(gen_mock.call_count, 3)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400227
Benjamin Gordon121a2aa2018-05-04 16:24:45 -0600228class GenerateSymbolTest(cros_test_lib.RunCommandTempDirTestCase):
Don Garrettf8bf7842014-03-20 17:03:42 -0700229 """Test GenerateBreakpadSymbol."""
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400230
231 def setUp(self):
232 self.elf_file = os.path.join(self.tempdir, 'elf')
233 osutils.Touch(self.elf_file)
234 self.debug_dir = os.path.join(self.tempdir, 'debug')
235 self.debug_file = os.path.join(self.debug_dir, 'elf.debug')
236 osutils.Touch(self.debug_file, makedirs=True)
237 # Not needed as the code itself should create it as needed.
238 self.breakpad_dir = os.path.join(self.debug_dir, 'breakpad')
239
Don Garrett1d1209d2017-02-28 13:42:57 -0800240 self.rc.SetDefaultCmdResult(output='MODULE OS CPU ID NAME')
241 self.assertCommandContains = self.rc.assertCommandContains
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400242 self.sym_file = os.path.join(self.breakpad_dir, 'NAME/ID/NAME.sym')
243
244 self.StartPatcher(FindDebugDirMock(self.debug_dir))
245
246 def assertCommandArgs(self, i, args):
247 """Helper for looking at the args of the |i|th call"""
Don Garrett1d1209d2017-02-28 13:42:57 -0800248 self.assertEqual(self.rc.call_args_list[i][0][0], args)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400249
250 def testNormal(self):
251 """Normal run -- given an ELF and a debug file"""
252 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
Don Garrette548cff2015-09-23 14:36:21 -0700253 self.elf_file, self.debug_file, self.breakpad_dir)
Don Garrettc9de3ac2015-10-01 15:40:10 -0700254 self.assertEqual(ret, self.sym_file)
Don Garrett1d1209d2017-02-28 13:42:57 -0800255 self.assertEqual(self.rc.call_count, 1)
Joshua Peraza09fc19b2022-05-18 20:24:11 -0700256 self.assertCommandArgs(0, ['dump_syms', '-v', '-d', self.elf_file,
Mike Frysinger2808deb2016-01-28 01:22:13 -0500257 self.debug_dir])
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400258 self.assertExists(self.sym_file)
259
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400260 def testNormalNoCfi(self):
261 """Normal run w/out CFI"""
262 # Make sure the num_errors flag works too.
263 num_errors = ctypes.c_int()
264 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
Don Garrette548cff2015-09-23 14:36:21 -0700265 self.elf_file, breakpad_dir=self.breakpad_dir,
266 strip_cfi=True, num_errors=num_errors)
Don Garrettc9de3ac2015-10-01 15:40:10 -0700267 self.assertEqual(ret, self.sym_file)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400268 self.assertEqual(num_errors.value, 0)
Mike Frysinger2808deb2016-01-28 01:22:13 -0500269 self.assertCommandArgs(0, ['dump_syms', '-v', '-c', self.elf_file])
Don Garrett1d1209d2017-02-28 13:42:57 -0800270 self.assertEqual(self.rc.call_count, 1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400271 self.assertExists(self.sym_file)
272
273 def testNormalElfOnly(self):
274 """Normal run -- given just an ELF"""
Don Garrette548cff2015-09-23 14:36:21 -0700275 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
276 self.elf_file, breakpad_dir=self.breakpad_dir)
Don Garrettc9de3ac2015-10-01 15:40:10 -0700277 self.assertEqual(ret, self.sym_file)
Mike Frysinger2808deb2016-01-28 01:22:13 -0500278 self.assertCommandArgs(0, ['dump_syms', '-v', self.elf_file])
Don Garrett1d1209d2017-02-28 13:42:57 -0800279 self.assertEqual(self.rc.call_count, 1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400280 self.assertExists(self.sym_file)
281
282 def testNormalSudo(self):
283 """Normal run where ELF is readable only by root"""
284 with mock.patch.object(os, 'access') as mock_access:
285 mock_access.return_value = False
Don Garrette548cff2015-09-23 14:36:21 -0700286 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
287 self.elf_file, breakpad_dir=self.breakpad_dir)
Don Garrettc9de3ac2015-10-01 15:40:10 -0700288 self.assertEqual(ret, self.sym_file)
Mike Frysinger2808deb2016-01-28 01:22:13 -0500289 self.assertCommandArgs(0, ['sudo', '--', 'dump_syms', '-v', self.elf_file])
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400290
291 def testLargeDebugFail(self):
292 """Running w/large .debug failed, but retry worked"""
Joshua Peraza09fc19b2022-05-18 20:24:11 -0700293 self.rc.AddCmdResult(['dump_syms', '-v', '-d', self.elf_file,
294 self.debug_dir],
Don Garrett1d1209d2017-02-28 13:42:57 -0800295 returncode=1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400296 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
Don Garrette548cff2015-09-23 14:36:21 -0700297 self.elf_file, self.debug_file, self.breakpad_dir)
Don Garrettc9de3ac2015-10-01 15:40:10 -0700298 self.assertEqual(ret, self.sym_file)
Don Garrett1d1209d2017-02-28 13:42:57 -0800299 self.assertEqual(self.rc.call_count, 2)
Joshua Peraza09fc19b2022-05-18 20:24:11 -0700300 self.assertCommandArgs(0, ['dump_syms', '-v', '-d', self.elf_file,
Mike Frysinger2808deb2016-01-28 01:22:13 -0500301 self.debug_dir])
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400302 self.assertCommandArgs(
Mike Frysinger2808deb2016-01-28 01:22:13 -0500303 1, ['dump_syms', '-v', '-c', '-r', self.elf_file, self.debug_dir])
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400304 self.assertExists(self.sym_file)
305
306 def testDebugFail(self):
307 """Running w/.debug always failed, but works w/out"""
Joshua Peraza09fc19b2022-05-18 20:24:11 -0700308 self.rc.AddCmdResult(['dump_syms', '-v', '-d', self.elf_file,
309 self.debug_dir],
Don Garrett1d1209d2017-02-28 13:42:57 -0800310 returncode=1)
311 self.rc.AddCmdResult(['dump_syms', '-v', '-c', '-r', self.elf_file,
312 self.debug_dir],
313 returncode=1)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400314 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
Don Garrette548cff2015-09-23 14:36:21 -0700315 self.elf_file, self.debug_file, self.breakpad_dir)
Don Garrettc9de3ac2015-10-01 15:40:10 -0700316 self.assertEqual(ret, self.sym_file)
Don Garrett1d1209d2017-02-28 13:42:57 -0800317 self.assertEqual(self.rc.call_count, 3)
Joshua Peraza09fc19b2022-05-18 20:24:11 -0700318 self.assertCommandArgs(0, ['dump_syms', '-v', '-d', self.elf_file,
Mike Frysinger2808deb2016-01-28 01:22:13 -0500319 self.debug_dir])
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400320 self.assertCommandArgs(
Mike Frysinger2808deb2016-01-28 01:22:13 -0500321 1, ['dump_syms', '-v', '-c', '-r', self.elf_file, self.debug_dir])
322 self.assertCommandArgs(2, ['dump_syms', '-v', self.elf_file])
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400323 self.assertExists(self.sym_file)
324
325 def testCompleteFail(self):
326 """Running dump_syms always fails"""
Don Garrett1d1209d2017-02-28 13:42:57 -0800327 self.rc.SetDefaultCmdResult(returncode=1)
Don Garrette548cff2015-09-23 14:36:21 -0700328 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
329 self.elf_file, breakpad_dir=self.breakpad_dir)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400330 self.assertEqual(ret, 1)
331 # Make sure the num_errors flag works too.
332 num_errors = ctypes.c_int()
333 ret = cros_generate_breakpad_symbols.GenerateBreakpadSymbol(
Don Garrette548cff2015-09-23 14:36:21 -0700334 self.elf_file, breakpad_dir=self.breakpad_dir, num_errors=num_errors)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400335 self.assertEqual(ret, 1)
336 self.assertEqual(num_errors.value, 1)
337
338
339class UtilsTestDir(cros_test_lib.TempDirTestCase):
Don Garrettf8bf7842014-03-20 17:03:42 -0700340 """Tests ReadSymsHeader."""
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400341
342 def testReadSymsHeaderGoodFile(self):
343 """Make sure ReadSymsHeader can parse sym files"""
344 sym_file = os.path.join(self.tempdir, 'sym')
345 osutils.WriteFile(sym_file, 'MODULE Linux x86 s0m31D chrooome')
346 result = cros_generate_breakpad_symbols.ReadSymsHeader(sym_file)
Mike Frysinger2d589a12019-08-25 14:15:12 -0400347 self.assertEqual(result.cpu, 'x86')
348 self.assertEqual(result.id, 's0m31D')
349 self.assertEqual(result.name, 'chrooome')
350 self.assertEqual(result.os, 'Linux')
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400351
352
353class UtilsTest(cros_test_lib.TestCase):
Don Garrettf8bf7842014-03-20 17:03:42 -0700354 """Tests ReadSymsHeader."""
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400355
356 def testReadSymsHeaderGoodBuffer(self):
357 """Make sure ReadSymsHeader can parse sym file handles"""
358 result = cros_generate_breakpad_symbols.ReadSymsHeader(
Mike Frysinger374ba4f2019-11-14 23:45:15 -0500359 io.BytesIO(b'MODULE Linux arm MY-ID-HERE blkid'))
Mike Frysinger2d589a12019-08-25 14:15:12 -0400360 self.assertEqual(result.cpu, 'arm')
361 self.assertEqual(result.id, 'MY-ID-HERE')
362 self.assertEqual(result.name, 'blkid')
363 self.assertEqual(result.os, 'Linux')
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400364
365 def testReadSymsHeaderBadd(self):
366 """Make sure ReadSymsHeader throws on bad sym files"""
367 self.assertRaises(ValueError, cros_generate_breakpad_symbols.ReadSymsHeader,
Mike Frysinger374ba4f2019-11-14 23:45:15 -0500368 io.BytesIO(b'asdf'))
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400369
370 def testBreakpadDir(self):
371 """Make sure board->breakpad path expansion works"""
372 expected = '/build/blah/usr/lib/debug/breakpad'
373 result = cros_generate_breakpad_symbols.FindBreakpadDir('blah')
Mike Frysinger2d589a12019-08-25 14:15:12 -0400374 self.assertEqual(expected, result)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400375
376 def testDebugDir(self):
377 """Make sure board->debug path expansion works"""
378 expected = '/build/blah/usr/lib/debug'
379 result = cros_generate_breakpad_symbols.FindDebugDir('blah')
Mike Frysinger2d589a12019-08-25 14:15:12 -0400380 self.assertEqual(expected, result)
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400381
382
Mike Frysingerea838d12014-12-08 11:55:32 -0500383def main(_argv):
Mike Frysinger27e21b72018-07-12 14:20:21 -0400384 # pylint: disable=protected-access
Mike Frysinger69cb41d2013-08-11 20:08:19 -0400385 # Set timeouts small so that if the unit test hangs, it won't hang for long.
386 parallel._BackgroundTask.STARTUP_TIMEOUT = 5
387 parallel._BackgroundTask.EXIT_TIMEOUT = 5
388
389 # Run the tests.
Mike Frysingerba167372015-01-21 10:37:03 -0500390 cros_test_lib.main(level='info', module=__name__)