| # -*- coding: utf-8 -*- |
| # Copyright 2017 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Test cros_generate_android_breakpad_symbols.""" |
| |
| from __future__ import print_function |
| |
| import sys |
| import tempfile |
| |
| from chromite.lib import cros_build_lib |
| from chromite.lib import cros_test_lib |
| from chromite.lib import osutils |
| from chromite.scripts import cros_generate_android_breakpad_symbols |
| from chromite.scripts import cros_generate_breakpad_symbols |
| |
| |
| assert sys.version_info >= (3, 6), 'This module requires Python 3.6+' |
| |
| |
| # Unitests often need access to internals of the thing they test. |
| # pylint: disable=protected-access |
| |
| class AdjustOffsetsTest(cros_test_lib.TestCase): |
| """Test breakpad symbol file offset adjustments.""" |
| |
| def testFinaExpansionOffset(self): |
| """Make sure we get the correct offset.""" |
| output = """ |
| INFO: Relocations : RELA |
| INFO: Packed : 9544 bytes |
| INFO: Unpacked : 66888 bytes |
| INFO: Relocations : 2787 entries |
| INFO: Expansion : 57344 bytes |
| """ |
| cmd_result = cros_build_lib.CommandResult( |
| cmd=None, error=None, output=output, returncode=0) |
| |
| result = cros_generate_android_breakpad_symbols.FindExpansionOffset( |
| cmd_result) |
| self.assertEqual(result, -57344) |
| |
| def testFinaExpansionOffsetNoUnpack(self): |
| """Make sure we get an offset of zero, if the file wasn't unpacked.""" |
| |
| cmd_result = cros_build_lib.CommandResult( |
| cmd=None, error=None, output=None, returncode=1) |
| |
| result = cros_generate_android_breakpad_symbols.FindExpansionOffset( |
| cmd_result) |
| self.assertEqual(result, 0) |
| |
| def testFinaExpansionOffsetBadOutput(self): |
| """Make sure we get an error without expected output.""" |
| |
| cmd_result = cros_build_lib.CommandResult( |
| cmd=None, error=None, output='foo', returncode=0) |
| |
| with self.assertRaises( |
| cros_generate_android_breakpad_symbols.OffsetDiscoveryError): |
| cros_generate_android_breakpad_symbols.FindExpansionOffset(cmd_result) |
| |
| def testAdjustLineSymbolOffset(self): |
| """Test _AdjustLineSymbolOffset.""" |
| |
| offset = 42 |
| line_expected = ( |
| ('', ''), |
| ('\n', '\n'), |
| ('noise\n', 'noise\n'), |
| ('MODULE Linux arm64 E3D562057466309CED960047D474EBF00 libssl.so\n', |
| 'MODULE Linux arm64 E3D562057466309CED960047D474EBF00 libssl.so\n'), |
| ('FUNC dcfc a8 0 dtls1_discard_fragment_body\n', |
| 'FUNC dd26 a8 0 dtls1_discard_fragment_body\n'), |
| ('dd18 c 403 1\n', |
| 'dd42 c 403 1\n'), |
| ('PUBLIC f9b0 0 DTLSv1_get_timeout\n', |
| 'PUBLIC f9da 0 DTLSv1_get_timeout\n'), |
| ('STACK CFI INIT dcfc a8 .cfa: sp 0 + .ra: x30\n', |
| 'STACK CFI INIT dd26 a8 .cfa: sp 0 + .ra: x30\n'), |
| ('STACK CFI dd04 .cfa: x29 336 +\n', |
| 'STACK CFI dd2e .cfa: x29 336 +\n'), |
| ('0 c 403 1\n', |
| '0 c 403 1\n'), |
| ('FUNC 0 a8 0 dtls1_discard_fragment_body\n', |
| 'FUNC 0 a8 0 dtls1_discard_fragment_body\n'), |
| ) |
| |
| for line, expected in line_expected: |
| result = cros_generate_android_breakpad_symbols._AdjustLineSymbolOffset( |
| line, offset) |
| self.assertEqual(result, expected) |
| |
| def testAdjustSymbolOffsetEmpty(self): |
| """Test ability to adjust an empty file.""" |
| with tempfile.NamedTemporaryFile() as sym_file: |
| osutils.WriteFile(sym_file.name, '') |
| cros_generate_android_breakpad_symbols._AdjustSymbolOffset( |
| sym_file.name, 42) |
| self.assertEqual(osutils.ReadFile(sym_file.name), '') |
| |
| def testAdjustSymbolOffset(self): |
| """Test ability to adjust an empty file.""" |
| unadjusted = """ |
| MODULE Linux arm64 E3D562057466309CED960047D474EBF00 libssl.so |
| FILE 0 /testfile.h |
| FILE 1 /usr/testfile.c |
| dcfc 1c 403 1 |
| dd18 c 403 1 |
| dd30 10 405 1 |
| dd4c 14 407 1 |
| 2d65c 8 1218 27 |
| 2d664 c 1226 27 |
| FUNC dda4 140 0 dtls1_hm_fragment_new |
| dda4 10 151 1 |
| PUBLIC 2c474 0 SSL_early_callback_ctx_extension_get |
| PUBLIC 2f0bc 0 SSL_get_shared_sigalgs |
| STACK CFI INIT dcfc a8 .cfa: sp 0 + .ra: x30 |
| STACK CFI dd00 .cfa: sp 336 + .ra: .cfa -328 + ^ x29: .cfa -336 + ^ |
| STACK CFI dd04 .cfa: x29 336 + |
| STACK CFI dd08 x23: .cfa -288 + ^ x24: .cfa -280 + ^ |
| """ |
| expected = """ |
| MODULE Linux arm64 E3D562057466309CED960047D474EBF00 libssl.so |
| FILE 0 /testfile.h |
| FILE 1 /usr/testfile.c |
| dd26 1c 403 1 |
| dd42 c 403 1 |
| dd5a 10 405 1 |
| dd76 14 407 1 |
| 2d686 8 1218 27 |
| 2d68e c 1226 27 |
| FUNC ddce 140 0 dtls1_hm_fragment_new |
| ddce 10 151 1 |
| PUBLIC 2c49e 0 SSL_early_callback_ctx_extension_get |
| PUBLIC 2f0e6 0 SSL_get_shared_sigalgs |
| STACK CFI INIT dd26 a8 .cfa: sp 0 + .ra: x30 |
| STACK CFI dd2a .cfa: sp 336 + .ra: .cfa -328 + ^ x29: .cfa -336 + ^ |
| STACK CFI dd2e .cfa: x29 336 + |
| STACK CFI dd32 x23: .cfa -288 + ^ x24: .cfa -280 + ^ |
| """ |
| with tempfile.NamedTemporaryFile() as sym_file: |
| osutils.WriteFile(sym_file.name, unadjusted) |
| cros_generate_android_breakpad_symbols._AdjustSymbolOffset( |
| sym_file.name, 42) |
| after = osutils.ReadFile(sym_file.name) |
| self.assertEqual(after, expected) |
| |
| |
| class MockTests(cros_test_lib.RunCommandTestCase): |
| """Tests that need mocks & RunCommand mocks.""" |
| |
| def testUnpackGenerateBreakpad(self): |
| """Test UnpackGenerateBreakpad call.""" |
| output = """ |
| INFO: Relocations : RELA |
| INFO: Packed : 9544 bytes |
| INFO: Unpacked : 66888 bytes |
| INFO: Relocations : 2787 entries |
| INFO: Expansion : 0 bytes |
| """ |
| self.PatchObject(cros_generate_breakpad_symbols, 'GenerateBreakpadSymbol', |
| return_value='/foo.sym') |
| self.rc.AddCmdResult(['relocation_packer', '-u', '/foo'], stdout=output) |
| cros_generate_android_breakpad_symbols._UnpackGenerateBreakpad('/foo') |