# Copyright 2021 The Pigweed Authors # # Licensed under the Apache License, Version 2.0 (the "License"); you may not # use this file except in compliance with the License. You may obtain a copy of # the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations under # the License. """Tests for pw_build_info's GNU build ID support.""" import subprocess import tempfile import unittest from pathlib import Path from pw_cli import env from pw_build_info import build_id # Since build_id.cc depends on pw_preprocessor, we have to use the in-tree path. _MODULE_DIR = Path(env.pigweed_environment().PW_ROOT) / 'pw_build_info' _MODULE_PY_DIR = Path(__file__).parent.resolve() _SHA1_BUILD_ID_LENGTH = 20 class TestGnuBuildId(unittest.TestCase): """Unit tests for GNU build ID parsing.""" def test_build_id_correctness(self): """Tests to ensure GNU build IDs are read/written correctly.""" with tempfile.TemporaryDirectory() as exe_dir: exe_file = Path(exe_dir) / 'print_build_id.elf' # Compiles a binary that prints the embedded GNU build id. cmd = [ 'clang++', 'build_id.cc', _MODULE_PY_DIR / 'print_build_id.cc', '-Ipublic', '-I../pw_preprocessor/public', '-std=c++20', '-fuse-ld=lld', '-Wl,-Tadd_build_id_to_default_linker_script.ld', '-Wl,--build-id=sha1', '-o', exe_file, ] process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=_MODULE_DIR) self.assertEqual(process.returncode, 0) # Run the compiled binary so the printed build ID can be read. process = subprocess.run([exe_file], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=_MODULE_DIR) self.assertEqual(process.returncode, 0) with open(exe_file, 'rb') as elf: expected = build_id.read_build_id_from_section(elf) self.assertEqual(len(expected), _SHA1_BUILD_ID_LENGTH) self.assertEqual(process.stdout.decode().rstrip(), expected.hex()) # Test method that parses using symbol information. expected = build_id.read_build_id_from_symbol(elf) self.assertEqual(len(expected), _SHA1_BUILD_ID_LENGTH) self.assertEqual(process.stdout.decode().rstrip(), expected.hex()) # Test the user-facing method. expected = build_id.read_build_id(elf) self.assertEqual(len(expected), _SHA1_BUILD_ID_LENGTH) self.assertEqual(process.stdout.decode().rstrip(), expected.hex()) if __name__ == '__main__': unittest.main()